diff --git a/evil-commands.el b/evil-commands.el index 83fb9f4e..711c0adc 100644 --- a/evil-commands.el +++ b/evil-commands.el @@ -1477,7 +1477,7 @@ be joined with the previous line if and only if `evil-backspace-join-lines'." (interactive "p") (if (or evil-backspace-join-lines (not (bolp))) - (call-interactively 'delete-backward-char) + (delete-char -1) (user-error "Beginning of line"))) (evil-define-command evil-delete-backward-word () @@ -1493,6 +1493,21 @@ be joined with the previous line if and only if (line-beginning-position)) (point)))) +(evil-define-command evil-delete-back-to-indentation () + "Delete back to the first non-whitespace character. +If point is before the first non-whitespace character of a +current line then delete from the point to the beginning of the +current line. If point is on the beginning of the line, behave +according to `evil-backspace-join-lines'." + (if (bolp) + (evil-delete-backward-char-and-join 1) + (delete-region (if (<= (current-column) (current-indentation)) + (line-beginning-position) + (save-excursion + (evil-first-non-blank) + (point))) + (point)))) + (defun evil-ex-delete-or-yank (should-delete beg end type register count yank-handler) "Execute evil-delete or evil-yank on the given region. If SHOULD-DELETE is t, evil-delete will be executed, otherwise diff --git a/evil-maps.el b/evil-maps.el index f28385c2..25455115 100644 --- a/evil-maps.el +++ b/evil-maps.el @@ -379,6 +379,8 @@ ,(if evil-want-C-w-delete '("\C-w" . evil-delete-backward-word) '("\C-w" . evil-window-map)) + ,@(when evil-want-C-u-delete + '(("\C-u" . evil-delete-back-to-indentation))) ([mouse-2] . mouse-yank-primary)) "Evil's bindings for insert state (for `evil-insert-state-map'), excluding , , and diff --git a/evil-tests.el b/evil-tests.el index ed9af7ed..503f12e6 100644 --- a/evil-tests.el +++ b/evil-tests.el @@ -1933,6 +1933,28 @@ ine3 line3 line3 l\n"))) (should-error (execute-kbd-macro (concat "i" (kbd "C-w")))) "abc def\n[k]l\n"))) +(ert-deftest evil-test-delete-back-to-indentation () + "Test `evil-delete-back-to-indentation' in insert state." + :tags '(evil) + (let ((evil-backspace-join-lines t)) + (evil-test-buffer + "abc def\n ghi j[k]l\n" + ("i" (call-interactively #'evil-delete-back-to-indentation)) + "abc def\n [k]l\n" + (execute-kbd-macro (concat (kbd "C-o") "2h")) + "abc def\n [ ] kl\n" + (call-interactively #'evil-delete-back-to-indentation) + "abc def\n[ ] kl\n" + (call-interactively #'evil-delete-back-to-indentation) + "abc def[ ] kl\n")) + (let (evil-backspace-join-lines) + (evil-test-buffer + "abc def\n[k]l\n" + (should-error + (progn (execute-kbd-macro "i") + (call-interactively #'evil-delete-back-to-indentation))) + "abc def\n[k]l\n"))) + (ert-deftest evil-test-change () "Test `evil-change'" :tags '(evil operator) diff --git a/evil-vars.el b/evil-vars.el index 7a0c7947..0fa7ac1a 100644 --- a/evil-vars.el +++ b/evil-vars.el @@ -456,6 +456,22 @@ replicates the default vim behavior." (not (lookup-key evil-motion-state-map (kbd "C-d")))) (define-key evil-motion-state-map (kbd "C-d") 'evil-scroll-down)))))) +(defcustom evil-want-C-u-delete nil + "Whether \\[C-u] deletes back to indentation in insert state." + :type 'boolean + :group 'evil + :set #'(lambda (sym value) + (set-default sym value) + (when (boundp 'evil-insert-state-map) + (cond + ((and (not value) + (eq (lookup-key evil-insert-state-map (kbd "C-u")) + 'evil-delete-back-to-indentation)) + (define-key evil-insert-state-map (kbd "C-u") nil)) + ((and value + (not (lookup-key evil-insert-state-map (kbd "C-u")))) + (define-key evil-insert-state-map (kbd "C-u") 'evil-delete-back-to-indentation)))))) + (defcustom evil-want-C-w-delete t "Whether \"C-w\" deletes a word in Insert state." :type 'boolean