Skip to content

Commit

Permalink
Fix Visual Insert affecting one too many lines
Browse files Browse the repository at this point in the history
This fixes a regression caused by commit
004ac4e, where Visual mode "I"
repeated the insertion on one too many lines unless at EOB.
  • Loading branch information
axelf4 committed Apr 21, 2024
1 parent 95ee3ce commit fe44a56
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 71 deletions.
69 changes: 20 additions & 49 deletions evil-commands.el
Original file line number Diff line number Diff line change
Expand Up @@ -2655,20 +2655,19 @@ corner and point in the lower left."
(evil-visual-refresh))))

(evil-define-command evil-visual-rotate (corner &optional beg end type)
"In Visual Block selection, put point in CORNER.
Corner may be one of `upper-left', `upper-right', `lower-left'
and `lower-right':
"Move point to CORNER of the Visual selection.
Corner may be one of `upper-left', `upper-right', `lower-left' and
`lower-right':

upper-left +---+ upper-right
| |
lower-left +---+ lower-right
upper-left +---+ upper-right
| |
lower-left +---+ lower-right

When called interactively, the selection is rotated blockwise."
When called interactively, the selection is rotated clockwise."
:keep-visual t
(interactive
(let ((corners '(upper-left upper-right lower-right lower-left)))
(list (or (cadr (memq (evil-visual-block-corner) corners))
'upper-left))))
(let ((corners '#1=(upper-left upper-right lower-right lower-left . #1#)))
(list (cadr (memq (evil-visual-block-corner) corners)))))
(let* ((beg (or beg (point)))
(end (or end (mark t) beg))
(type (or type evil-this-type))
Expand Down Expand Up @@ -2697,43 +2696,21 @@ When called interactively, the selection is rotated blockwise."

(defun evil-insert (count &optional vcount skip-empty-lines)
"Switch to Insert state just before point.
The insertion will be repeated COUNT times and repeated once for
the next VCOUNT - 1 lines starting at the same column.
The insertion will be repeated COUNT times on the next VCOUNT lines,
starting at the same column.
If SKIP-EMPTY-LINES is non-nil, the insertion will not be performed
on lines on which the insertion point would be after the end of the
lines. This is the default behaviour for Visual-state insertion."
(interactive
(let ((lines+ 0))
(if (not (evil-visual-state-p))
(list (prefix-numeric-value current-prefix-arg))
(evil-visual-rotate 'upper-left)
(list (prefix-numeric-value current-prefix-arg)
(and (evil-visual-state-p)
(memq (evil-visual-type) '(line block))
(save-excursion
(let ((m (mark)))
(evil-visual-rotate 'lower-right)
;; count-lines misses an empty final line, so correct that
(and (bolp) (eolp) (setq lines+ 1))
;; go to upper-left corner temporarily so
;; `count-lines' yields accurate results
(evil-visual-rotate 'upper-left)
(prog1 (+ (count-lines evil-visual-beginning evil-visual-end)
lines+)
(set-mark m)))))
(evil-visual-state-p))))
(if (and (called-interactively-p 'any)
(evil-visual-state-p))
(cond
((eq (evil-visual-type) 'line)
(evil-visual-rotate 'upper-left)
(evil-insert-line count vcount))
((eq (evil-visual-type) 'block)
(let ((column (min (evil-column evil-visual-beginning)
(evil-column evil-visual-end))))
(evil-visual-rotate 'upper-left)
(move-to-column column t)
(evil-insert count vcount skip-empty-lines)))
(t
(evil-visual-rotate 'upper-left)
(evil-insert count vcount skip-empty-lines)))
(when (memq (evil-visual-type) '(line block))
(1+ (evil-count-lines evil-visual-point evil-visual-mark)))
t)))
(if (and (evil-visual-state-p) (eq (evil-visual-type) 'line))
(evil-insert-line count vcount)
(setq evil-insert-count count
evil-insert-lines nil
evil-insert-vcount (and vcount
Expand All @@ -2755,13 +2732,7 @@ the lines."
(list (prefix-numeric-value current-prefix-arg)
(and (evil-visual-state-p)
(memq (evil-visual-type) '(line block))
(save-excursion
(let ((m (mark)))
;; go to upper-left corner temporarily so
;; `count-lines' yields accurate results
(evil-visual-rotate 'upper-left)
(prog1 (count-lines evil-visual-beginning evil-visual-end)
(set-mark m)))))))
(1+ (evil-count-lines evil-visual-point evil-visual-mark)))))
(if (and (called-interactively-p 'any)
(evil-visual-state-p))
(cond
Expand Down
41 changes: 19 additions & 22 deletions evil-tests.el
Original file line number Diff line number Diff line change
Expand Up @@ -679,13 +679,20 @@ Below some empty line"
("aevil rulz " [escape])
";; Tevil rulz[ ]his buffer is for notes you don't want to save"))

(ert-deftest evil-test-visual-insert ()
"Test `evil-insert' in Visual state."
:tags '(evil insert)
(ert-info ("Repeat insert over empty lines")
(evil-test-buffer :visual line "<\n\n[]>"
("IX" [escape])
"X\nX\nX")))

(ert-deftest evil-test-visual-append ()
"Test `evil-append' from visual state"
"Test `evil-append' in Visual state."
:tags '(evil insert)
(evil-test-buffer
";; [T]his buffer is for notes you don't want to save"
("veA_evil rulz " [escape])
";; This_evil rulz[ ] buffer is for notes you don't want to save"))
(evil-test-buffer "<fo[o]> bar"
("A_evil rulz " [escape])
"foo_evil rulz[ ] bar"))

(ert-deftest evil-test-open-above ()
"Test `evil-open-above'"
Expand Down Expand Up @@ -755,10 +762,13 @@ de[f]
(ert-deftest evil-test-insert-line ()
"Test `evil-insert-line'"
:tags '(evil insert)
(evil-test-buffer
";; [T]his buffer is for notes you don't want to save"
(evil-test-buffer "foo [b]ar"
("Ievil rulz " [escape])
"evil rulz[ ];; This buffer is for notes you don't want to save"))
"evil rulz[ ]foo bar")
(ert-info ("With count")
(evil-test-buffer "foo [b]ar"
("2Ievil rulz " [escape])
"evil rulz evil rulz[ ]foo bar")))

(ert-deftest evil-test-append-line ()
"Test `evil-append-line'"
Expand Down Expand Up @@ -1272,14 +1282,6 @@ evil\nrulz\nevil\nrul[z]
evil\nrulz\nevil\nrulz\nevil\nrulz\nevil\nrulz\nevil\nrul[z]
;; and for Lisp evaluation.")))

(ert-deftest evil-test-insert-line-with-count ()
"Test `evil-insert-line' with repeat count"
:tags '(evil repeat)
(evil-test-buffer
";; [T]his buffer is for notes"
("2Ievil rulz " [escape])
"evil rulz evil rulz[ ];; This buffer is for notes"))

(ert-deftest evil-test-repeat-insert-line ()
"Test repeating of `evil-insert-line'"
:tags '(evil repeat)
Expand Down Expand Up @@ -1310,12 +1312,7 @@ evil\nrulz\nevil\nrulz\nevil\nrulz\nevil\nrulz\nevil\nrul[z]
("10IABC" [escape])
"ABCABCABCABCABCABCABCABCABCAB[C];; This buffer is for notes"
("11.")
"ABCABCABCABCABCABCABCABCABCABCAB[C]ABCABCABCABCABCABCABCABCABCABC;; This buffer is for notes"))
(ert-info ("Repeat insert over empty lines")
(evil-test-buffer
""
("i" [return] [return] [return] [return] [return] [return] [escape] "gg\C-vGIX" [escape])
"X\nX\nX\nX\nX\nX\nX")))
"ABCABCABCABCABCABCABCABCABCABCAB[C]ABCABCABCABCABCABCABCABCABCABC;; This buffer is for notes")))

(ert-deftest evil-test-insert-line-vcount ()
"Test `evil-insert-line' with vertical repeating"
Expand Down

0 comments on commit fe44a56

Please sign in to comment.