diff options
| author | Tom Dalziel <tom_dl@hotmail.com> | 2024-06-04 09:38:55 +0200 |
|---|---|---|
| committer | Tom Dalziel <33435574+tomdl89@users.noreply.github.com> | 2024-06-14 18:21:16 +0200 |
| commit | f29ad3c91e06ca1910f326b3b0a41ae59ba2c8b6 (patch) | |
| tree | 5117d95ad9f59d3461a7f303aee59e61228eb9f7 | |
| parent | a32f016536fadf5080be39f239288b76146216ee (diff) | |
Track (and restore) previous visual selection, point, mark for gv
| -rw-r--r-- | evil-commands.el | 34 | ||||
| -rw-r--r-- | evil-states.el | 8 | ||||
| -rw-r--r-- | evil-tests.el | 29 | ||||
| -rw-r--r-- | evil-vars.el | 10 |
4 files changed, 64 insertions, 17 deletions
diff --git a/evil-commands.el b/evil-commands.el index 1278c61..43030c2 100644 --- a/evil-commands.el +++ b/evil-commands.el @@ -2579,20 +2579,26 @@ COUNT is infinite." (evil-define-motion evil-visual-restore () "Restore previous selection." - (let* ((point (point)) - (mark (or (mark t) point)) - (type (evil-visual-type))) - ;; TODO handle swapping selection in visual state... - (unless (evil-visual-state-p) - (cond - ;; No previous selection. - ((or (null evil-visual-selection) - (null evil-visual-mark) - (null evil-visual-point))) - (t - (setq mark evil-visual-mark - point evil-visual-point) - (evil-visual-make-selection mark point type t)))))) + (cond + ;; Called from visual state + ((and (evil-visual-state-p) + evil-prev-visual-mark evil-prev-visual-point evil-prev-visual-selection) + (let ((tmp-visual-mark (marker-position evil-visual-mark)) + (tmp-visual-point (marker-position evil-visual-point)) + (tmp-visual-selection evil-visual-selection)) + (evil-visual-make-selection evil-prev-visual-mark + evil-prev-visual-point + evil-prev-visual-selection + t) + (move-marker evil-prev-visual-mark tmp-visual-mark) + (move-marker evil-prev-visual-point tmp-visual-point) + (setq evil-prev-visual-selection tmp-visual-selection))) + ;; Called from other state + ((and evil-visual-selection evil-visual-mark evil-visual-point) + (evil-visual-make-selection evil-visual-mark + evil-visual-point + (evil-visual-type) + t)))) (evil-define-motion evil-visual-exchange-corners () "Rearrange corners in Visual Block mode. diff --git a/evil-states.el b/evil-states.el index 6b86d9d..26eb844 100644 --- a/evil-states.el +++ b/evil-states.el @@ -421,7 +421,10 @@ If LATER is non-nil, exit after the current command." (setq deactivate-mark t) (when evil-visual-region-expanded (evil-visual-contract-region)) - (setq evil-this-register nil) + (setq evil-this-register nil + evil-prev-visual-selection evil-visual-selection + evil-prev-visual-mark (copy-marker evil-visual-mark) + evil-prev-visual-point (copy-marker evil-visual-point)) (evil-change-to-previous-state))))) (defun evil-visual-tag (&optional selection) @@ -777,7 +780,8 @@ Default to `evil-visual-make-region'." "Return a Visual selection for TYPE." (catch 'done (dolist (selection evil-visual-alist) - (when (eq (symbol-value (cdr selection)) type) + (when (memq (symbol-value (cdr selection)) + (list type (evil-visual-type type))) (throw 'done (car selection)))))) (defun evil-visual-block-corner (&optional corner point mark) diff --git a/evil-tests.el b/evil-tests.el index 8ed12b7..4699108 100644 --- a/evil-tests.el +++ b/evil-tests.el @@ -7584,7 +7584,34 @@ otel"))) echo foxtrot\ngolf hotel" ("2yy" "++" "Vp" "gv") "alpha bravo\ncharlie delta -<alpha bravo\ncharlie delta\n>golf hotel"))) +<alpha bravo\ncharlie delta\n>golf hotel")) + ;; 4 repetitions appears necessary, from manual testing + (ert-info ("Restore previous linewise selection from linewise selection") + (evil-test-buffer + "alpha bravo\nch[a]rlie delta\necho foxtrot\ngolf hotel" + ("V" [escape] "jV") + "alpha bravo\ncharlie delta\n<ec[h]o foxtrot\n>golf hotel" + ("gv") + "alpha bravo\n<ch[a]rlie delta\n>echo foxtrot\ngolf hotel" + ("gv") + "alpha bravo\ncharlie delta\n<ec[h]o foxtrot\n>golf hotel" + ("gv") + "alpha bravo\n<ch[a]rlie delta\n>echo foxtrot\ngolf hotel" + ("gv") + "alpha bravo\ncharlie delta\n<ec[h]o foxtrot\n>golf hotel")) + (ert-info ("Restore between previous charwise selection and linewise selection") + (evil-test-buffer + "alpha bravo\nch[a]rlie delta\necho foxtrot\ngolf hotel" + ("viw" [escape] "jV") + "alpha bravo\ncharlie delta\n<echo f[o]xtrot\n>golf hotel" + ("gv") + "alpha bravo\n<charli[e]> delta\necho foxtrot\ngolf hotel" + ("gv") + "alpha bravo\ncharlie delta\n<echo f[o]xtrot\n>golf hotel" + ("gv") + "alpha bravo\n<charli[e]> delta\necho foxtrot\ngolf hotel" + ("gv") + "alpha bravo\ncharlie delta\n<echo f[o]xtrot\n>golf hotel"))) (ert-deftest evil-test-visual-redefine () "Test redefining a previous selection" diff --git a/evil-vars.el b/evil-vars.el index aea7eee..7adbb60 100644 --- a/evil-vars.el +++ b/evil-vars.el @@ -1740,6 +1740,16 @@ instead of `buffer-undo-list'.") "The kind of Visual selection. This is a selection as defined by `evil-define-visual-selection'.") +(evil-define-local-var evil-prev-visual-point nil + "The previous position of point in Visual state, a marker.") + +(evil-define-local-var evil-prev-visual-mark nil + "The previous position of mark in Visual state, a marker.") + +(evil-define-local-var evil-prev-visual-selection nil + "The previous kind of Visual selection. +This is a selection as defined by `evil-define-visual-selection'.") + ;; we could infer the direction by comparing `evil-visual-mark' ;; and `evil-visual-point', but destructive operations may ;; displace the markers |
