Skip to content

Commit e5ce86a

Browse files
authored
Merge pull request #964 from fukamachi/fix/vi-mode-refactored
Fix new bugs of vi-mode introduced by #952
2 parents 0f3c0a5 + ddf196c commit e5ce86a

File tree

2 files changed

+68
-61
lines changed

2 files changed

+68
-61
lines changed

extensions/vi-mode/commands.lisp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,9 @@
287287

288288
(define-vi-operator vi-delete (start end type) ()
289289
(let ((pos (point-charpos (current-point))))
290-
(with-killring-context (:options (when (eq type :line) :vi-line))
290+
(with-killring-context (:options (when (eq type :line) :vi-line)
291+
:appending (when (eq type :block)
292+
(continue-flag :kill)))
291293
(kill-region start end))
292294
(when (and (eq type :line)
293295
(eq 'vi-delete (command-name (this-command))))
@@ -447,12 +449,12 @@
447449
(redo n)
448450
(fall-within-line (current-point)))
449451

450-
(defun vi-forward-matching-paren (window point &optional (offset *cursor-offset*))
451-
(declare (ignore window offset))
452+
(defun vi-forward-matching-paren (window point &optional (offset -1))
453+
(declare (ignore window))
452454
(with-point ((point point))
453455
(when (syntax-open-paren-char-p (character-at point))
454456
(when (scan-lists point 1 0 t)
455-
(character-offset point *cursor-offset*)))))
457+
(character-offset point offset)))))
456458

457459
(defun vi-backward-matching-paren (window point &optional (offset -1))
458460
(declare (ignore window offset))
@@ -463,7 +465,7 @@
463465
(:type :inclusive
464466
:jump t)
465467
(alexandria:when-let ((p (or (vi-backward-matching-paren (current-window) (current-point))
466-
(vi-forward-matching-paren (current-window) (current-point) *cursor-offset*))))
468+
(vi-forward-matching-paren (current-window) (current-point)))))
467469
(move-point (current-point) p)))
468470

469471
(let ((old-forward-matching-paren)

extensions/vi-mode/commands/utils.lisp

Lines changed: 61 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
(:import-from :lem-vi-mode/visual
77
:visual-p
88
:visual-line-p
9+
:visual-block-p
910
:apply-visual-range
1011
:vi-visual-end)
1112
(:import-from :lem/common/command
@@ -89,7 +90,7 @@
8990
(t (values arg-list '("P") nil))))
9091

9192
(defmacro define-vi-motion (name arg-list (&key type jump) &body body)
92-
(check-type type (or null (member :inclusive :exclusive :line)))
93+
(check-type type (or null (member :inclusive :exclusive :line :block)))
9394
(check-type jump boolean)
9495
(multiple-value-bind (arg-list arg-descriptor default-n-arg)
9596
(parse-vi-motion-arg-list arg-list)
@@ -125,63 +126,67 @@
125126
(if (typep command 'vi-motion)
126127
(vi-motion-type command)
127128
:exclusive)))
128-
(if (visual-p)
129-
(let (start end)
130-
(apply-visual-range
131-
(lambda (vstart vend)
132-
(setf start vstart
133-
end vend)))
134-
(values start
135-
end
136-
(if (visual-line-p) :line :exclusive)))
137-
(with-point ((start (current-point)))
138-
(if motion
139-
(let ((command (get-command motion)))
140-
(call-motion command n)
141-
(values
142-
start
143-
(copy-point (current-point))
144-
(command-motion-type command)))
145-
(let* ((uarg (or (read-universal-argument) n))
146-
(command-name (read-command))
147-
(command (get-command command-name)))
148-
(typecase command
149-
(vi-operator
150-
(if (eq command-name (command-name (this-command)))
151-
;; Recursive call of the operator like 'dd', 'cc'
152-
(with-point ((end (current-point)))
153-
(line-offset end (1- (or uarg 1)))
154-
(values start end :line))
155-
;; Ignore an invalid operator (like 'dJ')
156-
nil))
157-
(otherwise
158-
(call-motion command uarg)
159-
(values start
160-
(copy-point (current-point))
161-
(command-motion-type command))))))))))
129+
(with-point ((start (current-point)))
130+
(if motion
131+
(let ((command (get-command motion)))
132+
(call-motion command n)
133+
(values
134+
start
135+
(copy-point (current-point))
136+
(command-motion-type command)))
137+
(let* ((uarg (or (read-universal-argument) n))
138+
(command-name (read-command))
139+
(command (get-command command-name)))
140+
(typecase command
141+
(vi-operator
142+
(if (eq command-name (command-name (this-command)))
143+
;; Recursive call of the operator like 'dd', 'cc'
144+
(with-point ((end (current-point)))
145+
(line-offset end (1- (or uarg 1)))
146+
(values start end :line))
147+
;; Ignore an invalid operator (like 'dJ')
148+
nil))
149+
(otherwise
150+
(call-motion command uarg)
151+
(values start
152+
(copy-point (current-point))
153+
(command-motion-type command)))))))))
162154

163155
(defun call-vi-operator (n fn &key motion keep-visual restore-point)
164-
(with-point ((*vi-origin-point* (current-point)))
165-
(unwind-protect
166-
(if *vi-operator-arguments*
167-
(apply fn *vi-operator-arguments*)
168-
(multiple-value-bind (start end type)
169-
(vi-operator-region n motion)
170-
(when (point< end start)
171-
(rotatef start end))
172-
(ecase type
173-
(:line (unless (visual-p)
174-
(line-start start)
175-
(line-end end)))
176-
(:inclusive (character-offset end 1))
177-
(:exclusive))
178-
(let ((*vi-operator-arguments* (list start end type)))
179-
(funcall fn start end type))))
180-
(when restore-point
181-
(move-point (current-point) *vi-origin-point*))
182-
(unless keep-visual
183-
(when (visual-p)
184-
(vi-visual-end))))))
156+
(flet ((call-with-region (fn start end type)
157+
(when (point< end start)
158+
(rotatef start end))
159+
(ecase type
160+
(:line (unless (visual-p)
161+
(line-start start)
162+
(line-end end)))
163+
(:block)
164+
(:inclusive
165+
(unless (point= start end)
166+
(character-offset end 1)))
167+
(:exclusive))
168+
(let ((*vi-operator-arguments* (list start end type)))
169+
(funcall fn start end type))))
170+
(with-point ((*vi-origin-point* (current-point)))
171+
(unwind-protect
172+
(if *vi-operator-arguments*
173+
(apply fn *vi-operator-arguments*)
174+
(if (visual-p)
175+
(apply-visual-range
176+
(lambda (start end)
177+
(call-with-region fn start end
178+
(cond
179+
((visual-line-p) :line)
180+
((visual-block-p) :block)
181+
(t :exclusive)))))
182+
(multiple-value-bind (start end type)
183+
(vi-operator-region n motion)
184+
(call-with-region fn start end type))))
185+
(when restore-point
186+
(move-point (current-point) *vi-origin-point*))
187+
(unless keep-visual
188+
(when (visual-p)
189+
(vi-visual-end)))))))
185190

186191
(defmacro define-vi-operator (name arg-list (&key motion keep-visual restore-point) &body body)
187192
(with-gensyms (n extra-args)

0 commit comments

Comments
 (0)