在 Evil-Visual-Mode 中自动输入 Beg End 参数

Enter Beg End parameters automatically in Evil-Visual-Mode

我看到一些函数,如 evil-change 或 evil-delete 是在 evil-visual-state 的视觉区域的开始和结束。 我查看了这些函数的 "evil-commands.el" 中的源代码,但它们的 'beg' 和 'end' 参数似乎不知从何而来。有些(例如下面的)甚至没有交互性。

为什么会这样,我如何用自己的方法做同样的事情?

下面只是我查看的其中一种方法的示例:

;; Defined in ~/.emacs.d/elpa/evil-20170712.2350/evil-commands.el
(evil-define-operator evil-invert-char (beg end type)
  "Invert case of character."
  :motion evil-forward-char
  (if (eq type 'block)
      (evil-apply-on-block #'evil-invert-case beg end nil)
    (evil-invert-case beg end)
    (when evil-this-motion
      (goto-char end)
      (when (and evil-cross-lines
                 evil-move-cursor-back
                 (not evil-move-beyond-eol)
                 (not (evil-visual-state-p))
                 (not (evil-operator-state-p))
                 (eolp) (not (eobp)) (not (bolp)))
        (forward-char)))))

evil-invert-char 不是使用常规 defun 定义的,而是使用宏 evil-define-operator 定义的,可以在 evil-macros.el 中找到。使用 M-x describe-function RET evil-define-operator RET:

evil-define-operator is a Lisp macro in ‘evil-macros.el’.

(evil-define-operator OPERATOR (BEG END ARGS...) DOC [[KEY VALUE]...] BODY...)

Define an operator command OPERATOR.

你可以使用优秀的macrostep模式(在我的Spacemacs中绑定到, d m,当在emacs-lisp-mode中时)扩展evil-define-operator。第一次扩展会将 evil-define-operator-宏重写为 evil-define-command-宏,其中包括对 interactive 的调用。由于此宏扩展由 elisp 解释器完成或在字节编译之前完成,因此可以使用宏插入的 interactive 调用来分配变量 BEGEND