branch: elpa/evil commit 2a80de388f05af10edd24aecd0de2f514f75d1ff Author: Axel Forsman <axels...@gmail.com> Commit: GitHub <nore...@github.com>
Fix pasting in visual block mode (#1786) Co-authored-by: Tom Dalziel <tom...@hotmail.com> --- evil-commands.el | 38 +++++++++++++++++++------------------- evil-states.el | 7 +++---- evil-tests.el | 11 +++++++---- 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/evil-commands.el b/evil-commands.el index f8cf142625..0e9a4183bf 100644 --- a/evil-commands.el +++ b/evil-commands.el @@ -2273,45 +2273,45 @@ leave the cursor just after the new text." (yank-handler (car-safe (get-text-property 0 'yank-handler text))) (dir (evil-visual-direction)) - beg end paste-eob) + beg end type) (evil-with-undo (let ((kill-ring-yank-pointer (when kill-ring (list (current-kill 0))))) (when (evil-visual-state-p) (setq beg evil-visual-beginning - end evil-visual-end) + end evil-visual-end + type (evil-visual-type)) (evil-visual-rotate 'upper-left) - ;; if we replace the last buffer line that does not end in a - ;; newline, we use `evil-paste-after' because `evil-delete' - ;; will move point to the line above - (when (and (= evil-visual-end (point-max)) - (/= (char-before (point-max)) ?\n)) - (setq paste-eob t)) - (evil-delete beg end (evil-visual-type) (unless evil-kill-on-visual-paste ?_)) + (evil-delete beg end type (unless evil-kill-on-visual-paste ?_)) (when (and (eq yank-handler #'evil-yank-line-handler) - (not (memq (evil-visual-type) '(line block))) - (not (= evil-visual-end (point-max)))) + (not (memq type '(line block))) + (/= end (point-max))) (insert "\n")) (evil-normal-state) (when kill-ring (current-kill 1))) ;; Effectively memoize `evil-get-register' because it can be ;; side-effecting (e.g. for the `=' register)... - (cl-letf (((symbol-function 'evil-get-register) + (cl-letf (((symbol-function #'evil-get-register) (lambda (&rest _) text))) (cond - ((eq 'block (evil-visual-type)) - (when (eq yank-handler #'evil-yank-line-handler) - (setq text (concat "\n" text))) - (evil-set-marker ?\[ beg) + ;; When replacing the last buffer line and it does not end + ;; in a newline, use `evil-paste-after' because + ;; `evil-delete' will have moved point to the line above. + ((cond ((eq type 'line) (= end (point-max))) + ((eq type 'block) (eq yank-handler #'evil-yank-line-handler))) + (goto-char end) + (evil-paste-after count register)) + ((and (eq type 'block) + (not (eq yank-handler #'evil-yank-block-handler)) + (not (string-match-p "\n" text))) (evil-apply-on-block #'evil-insert-for-yank-at-col beg end t text count)) - (paste-eob (evil-paste-after count register)) (t (evil-paste-before count register))))) (when evil-kill-on-visual-paste (current-kill -1)) ;; Ensure that gv can restore visually pasted area... (setq evil-visual-previous-mark evil-visual-mark - evil-visual-mark (evil-get-marker (if (<= 0 dir) ?\[ ?\]) t) + evil-visual-mark (evil-get-marker (if (< 0 dir) ?\[ ?\]) t) evil-visual-previous-point evil-visual-point - evil-visual-point (evil-get-marker (if (<= 0 dir) ?\] ?\[) t)) + evil-visual-point (evil-get-marker (if (< 0 dir) ?\] ?\[) t)) ;; mark the last paste as visual-paste (setq evil-last-paste (list (nth 0 evil-last-paste) diff --git a/evil-states.el b/evil-states.el index 73d51cab10..abade4c6df 100644 --- a/evil-states.el +++ b/evil-states.el @@ -759,10 +759,9 @@ the direction of the last selection." (defun evil-visual-type (&optional selection) "Return the type of the Visual selection. If SELECTION is specified, return the type of that instead." - (if (and (null selection) (evil-visual-state-p)) - (or evil-this-type (evil-visual-type evil-visual-selection)) - (setq selection (or selection evil-visual-selection)) - (symbol-value (cdr-safe (assq selection evil-visual-alist))))) + (or (and (null selection) (evil-visual-state-p) evil-this-type) + (symbol-value (cdr (assq (or selection evil-visual-selection) + evil-visual-alist))))) (defun evil-visual-goto-end () "Go to the last line of the Visual selection. diff --git a/evil-tests.el b/evil-tests.el index da479386fb..f3e928f541 100644 --- a/evil-tests.el +++ b/evil-tests.el @@ -3039,10 +3039,13 @@ word3[]")) ("gv") ;; Test point & mark are stored correctly "abc\n1<abcabc3\n1abcabc3\n1abcab[c]>3")) (ert-info ("Blockwise visual paste of linewise text") - (evil-test-buffer - "[a]bc\n123\n123\n123" - ("yy" "jl" "\C-vG" "p") - "abc\n1\nabc\n3\n1\nabc\n3\n1\nabc\n3"))) + (evil-test-buffer "[a]bc\n123\n123" + ("yy" "jl" "\C-vj" "p") + "abc\n13\n13\nabc")) + (ert-info ("Blockwise visual paste of blockwise text") + (evil-test-buffer "xy\n[z]\n123\n123" + ("\C-vkly2jl\C-vjp") + "xy\nz\n1xy3\n1z 3"))) (ert-deftest evil-test-visual-paste-pop () "Test `evil-paste-pop' after visual paste."