修复 `evil-delete-marks` 失效的问题

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)))
1 个赞

:joy::joy::joy::joy::joy:局部26个,全局又26个mark,这个删除的功能真的有人用?
而且我又想起来。。。想换一个地方用同一个mark可以直接覆盖啊。。。。

主要是我用了 evil-visual-mark-mode ,不用的mark放在那里太碍眼_(:зゝ∠)_

现在这个bug已经被修复了,更新到最新的evil就能解决这个问题。