evil 有一个函数叫 evil-delete-marks
,用于删除用 m
键标记的 mark。可以使用 :delm a
来删除标记 a,或者使用 :delm!
来删除所有标记。貌似这个功能很冷门的样子,其中的一个bug至今都没有修复。
:delm!
可以正常运行,但是 :delm a
会报错:
Wrong type argument: arrayp, 0
我交了一个PR,但是至今都没有被合并。大家可以在自己的配置文件中用下面的代码来修复这个bug:
(with-eval-after-load 'evil
(defun override-evil-delete-marks (marks &optional force)
"覆盖原函数以修复bug。
在https://bitbucket.org/lyro/evil/pull-requests/72/bugfix/diff 被合并之前会一
直留在这里。"
(cond
;; delete local marks except 0-9
(force
(setq evil-markers-alist
(cl-delete-if (lambda (m)
(not (and (>= (car m) ?0) (<= (car m) ?9))))
evil-markers-alist)))
(t
(let ((i 0)
(n (length marks))
delmarks)
(while (< i n)
(cond
;; skip spaces
((= (aref marks i) ?\ ) (cl-incf i))
;; ranges of marks
((and (< (+ i 2) n)
(= (aref marks (1+ i)) ?-)
(or (and (>= (aref marks i) ?a)
(<= (aref marks i) ?z)
(>= (aref marks (+ 2 i)) ?a)
(<= (aref marks (+ 2 i)) ?z))
(and (>= (aref marks i) ?A)
(<= (aref marks i) ?Z)
(>= (aref marks (+ 2 i)) ?A)
(<= (aref marks (+ 2 i)) ?Z))))
(let ((m (aref marks i)))
(while (<= m (aref marks (+ 2 i)))
(push m delmarks)
(cl-incf m)))
(cl-incf i 2))
;; single marks
(t
(push (aref marks i) delmarks)
(cl-incf i))))
;; now remove all marks
(setq evil-markers-alist
(cl-delete-if (lambda (m) (member (car m) delmarks))
evil-markers-alist))
(set-default 'evil-markers-alist
(cl-delete-if (lambda (m) (member (car m) delmarks))
(default-value 'evil-markers-alist)))))))
(advice-add #'evil-delete-marks :override
#'override-evil-delete-marks)
)
另外,这里附赠一段代码,可以解决删除mark之后 evil-visual-mark-mode
不刷新显示的问题:
(advice-add #'evil-delete-marks :after
#'(lambda (&rest rest)
(evil-visual-mark-mode)
(evil-visual-mark-mode)))