From 787455068f56f29493cc1e33d4e5c2986ea25577 Mon Sep 17 00:00:00 2001 From: Tom Dalziel <33435574+tomdl89@users.noreply.github.com> Date: Wed, 2 Feb 2022 14:51:51 +0100 Subject: Handle charwise >1 line deleting as linewise (#1578) --- evil-commands.el | 66 ++++++++++++++++++++++++++++++++------------------------ evil-tests.el | 7 +++++- 2 files changed, 44 insertions(+), 29 deletions(-) diff --git a/evil-commands.el b/evil-commands.el index a0aa0c0..3584616 100644 --- a/evil-commands.el +++ b/evil-commands.el @@ -1488,34 +1488,44 @@ or line COUNT to the top of the window." "Delete text from BEG to END with TYPE. Save in REGISTER or in the kill-ring with YANK-HANDLER." (interactive "") - (unless register - (let ((text (filter-buffer-substring beg end))) - (unless (string-match-p "\n" text) - ;; set the small delete register - (evil-set-register ?- text)))) - (let ((evil-was-yanked-without-register nil)) - (evil-yank beg end type register yank-handler)) - (cond - ((eq type 'block) - (evil-apply-on-block #'delete-region beg end nil)) - ((and (eq type 'line) - (= end (point-max)) - (or (= beg end) - (/= (char-before end) ?\n)) - (/= beg (point-min)) - (= (char-before beg) ?\n)) - (delete-region (1- beg) end)) - (t - (delete-region beg end))) - (when (and (called-interactively-p 'any) - (eq type 'line)) - (evil-first-non-blank) - (when (and (not evil-start-of-line) - evil-operator-start-col - ;; Special exceptions to ever saving column: - (not (memq evil-this-motion '(evil-forward-word-begin - evil-forward-WORD-begin)))) - (move-to-column evil-operator-start-col)))) + (if (and (memq type '(inclusive exclusive)) + (not (evil-visual-state-p)) + (eq 'evil-delete evil-this-operator) + (save-excursion (goto-char beg) (bolp)) + (save-excursion (goto-char end) (eolp)) + (<= 1 (evil-count-lines beg end))) + ;; Imitate Vi strangeness: if motion meets above criteria, + ;; delete linewise. Not for change operator or visual state. + (let ((new-range (evil-expand beg end 'line))) + (evil-delete (nth 0 new-range) (nth 1 new-range) 'line register yank-handler)) + (unless register + (let ((text (filter-buffer-substring beg end))) + (unless (string-match-p "\n" text) + ;; set the small delete register + (evil-set-register ?- text)))) + (let ((evil-was-yanked-without-register nil)) + (evil-yank beg end type register yank-handler)) + (cond + ((eq type 'block) + (evil-apply-on-block #'delete-region beg end nil)) + ((and (eq type 'line) + (= end (point-max)) + (or (= beg end) + (/= (char-before end) ?\n)) + (/= beg (point-min)) + (= (char-before beg) ?\n)) + (delete-region (1- beg) end)) + (t + (delete-region beg end))) + (when (and (called-interactively-p 'any) + (eq type 'line)) + (evil-first-non-blank) + (when (and (not evil-start-of-line) + evil-operator-start-col + ;; Special exceptions to ever saving column: + (not (memq evil-this-motion '(evil-forward-word-begin + evil-forward-WORD-begin)))) + (move-to-column evil-operator-start-col))))) (evil-define-operator evil-delete-line (beg end type register yank-handler) "Delete to end of line." diff --git a/evil-tests.el b/evil-tests.el index 113e1c8..73eed9e 100644 --- a/evil-tests.el +++ b/evil-tests.el @@ -2025,7 +2025,12 @@ then enter the text in that file's own buffer.")) "a\n[b]\nc\nd\ne\nf\n" (":delete r 3") "a\ne\nf\n" - (should (string= (substring-no-properties (evil-get-register ?r)) "b\nc\nd\n"))))) + (should (string= (substring-no-properties (evil-get-register ?r)) "b\nc\nd\n")))) + (ert-info ("Charwise multiple whole line delete becomes linewise") + (evil-test-buffer + "1\n[2]\n3\n4" + ("d2w") + "1\n[4]"))) (ert-deftest evil-test-delete-line () "Test `evil-delete-line'" -- cgit v1.0