Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gv (evil-visual-restore) in visual state #1909

Merged
merged 2 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 20 additions & 14 deletions evil-commands.el
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
8 changes: 6 additions & 2 deletions evil-states.el
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
35 changes: 28 additions & 7 deletions evil-tests.el
Original file line number Diff line number Diff line change
Expand Up @@ -7551,12 +7551,6 @@ otel")))
(ert-deftest evil-test-visual-restore ()
"Test restoring a previous selection"
:tags '(evil visual)
(ert-info ("Start a characterwise selection \
if no previous selection")
(evil-test-buffer
";; [T]his buffer is for notes."
("gv")
";; <[T]>his buffer is for notes."))
(ert-info ("Restore characterwise selection")
(evil-test-buffer
";; <[T]his> buffer is for notes."
Expand Down Expand Up @@ -7590,7 +7584,34 @@ if no previous selection")
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"
Expand Down
10 changes: 10 additions & 0 deletions evil-vars.el
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down