大多数 emacs 模式都包含某种前缀来激活它们的功能。例如,当使用 GUD 时,“next”是“C-c C-n”。在这些模式中,许多模式提供了特殊的缓冲区,您可以在其中使用单个键来激活某些功能(例如,在 GNUS 中只需使用“n”或“p”即可阅读下一封/上一封邮件)。

然而,并非所有模式都提供这样的缓冲区,并且重复输入前缀可能会令人厌烦。是否有一个众所周知的 elisp 允许在一段时间内将前缀键的临时规范附加到所有输入? (例如,直到按下 ESC 或其他一些认可的键)

最佳答案

我同意 Joe Casadonte 的回答,要走的路是定义你自己的小调(或大调)模式。

话虽如此,你的问题很有趣。

这是一个提示您输入键序列的解决方案,它采用前缀键击并将该键映射提升到顶级。

例如假设以下键盘映射:

M-g ESC         Prefix Command
M-g g           goto-line
M-g n           next-error
M-g p           previous-error

当您运行 M-x semi-modal-minor-mode 时,它会提示您输入一些按键。如果输入 M-g n ,则会设置以下键绑定(bind):
ESC         Prefix Command   (same as M-g ESC)
g           goto-line
n           next-error
p           previous-error

所以现在 n 不会自我插入,而是跳转到下一个错误。请参阅下面的代码。

注意:启用此次要模式时,<f12> 绑定(bind)到禁用次要模式的命令。这是因为键绑定(bind)很可能会禁用您的 Emacs(例如,如果 M-x 有一个新的键绑定(bind)会怎样)。

编辑以添加这些想法:次要模式变量最初是本地缓冲区,但这不起作用,除非您还将次要模式列表变量缓冲区设置为本地(废话)。但是,您也(可能)不希望在迷你缓冲区中进行这些绑定(bind)...所以,我不会对其进行 b/c 测试,这实际上取决于您想要什么,但我已在代码中添加了注释反射(reflect)了这个想法。

无需再费周折:
(defvar semi-modal-minor-mode-keymap (make-sparse-keymap)
  "keymap holding the prefix key's keymapping, not really used")
(defvar semi-modal-minor-mode-disable-key (kbd "<f12>")
  "key to disable the minor mode")
(defun semi-modal-minor-mode-disable ()
  "disable the minor mode"
  (interactive)
  (semi-modal-minor-mode 0))

(define-minor-mode semi-modal-minor-mode
  "local minor mode that prompts for a prefix key and promotes that keymap to the toplevel
e.g. If there are bindings like the following:

M-g ESC         Prefix Command
M-g g           goto-line
M-g n           next-error
M-g p           previous-error

And you enter 'M-g n' when prompted,
then the minor mode keymap has the bindings
  g   ->   goto-line
  n   ->   next-error
  p   ->   previous-error
  ESC ->   Prefix Command (same as M-g ESC)

The variable semi-modal-minor-mode-disable-key is bound to disable the minor mode map.
This is provided because often the mappings make the keyboard unusable.
Use at your own risk."
  nil " Semi" semi-modal-minor-mode-keymap
  (make-local-variable 'semi-modal-minor-mode)
  (make-local-variable 'minor-mode-map-alist)
  (let ((pair-holding-keymap-to-modify (assq 'semi-modal-minor-mode minor-mode-map-alist)))
    (setcdr pair-holding-keymap-to-modify (make-sparse-keymap))
    (if semi-modal-minor-mode
        (let (key
              keymap)
          ;; all but last (b/c we want a prefix
          (setq key (substring (read-key-sequence "Enter a full key combination, the prefix will be used: ") 0 -1))
          (if (and (not (equal "" key))
                   (not (equal (kbd "C-g") key))
                   (let ((semi-modal-minor-mode nil))
                     (keymapp (setq keymap (key-binding key)))))
              (progn
                (setcdr pair-holding-keymap-to-modify (copy-keymap keymap))
                (when semi-modal-minor-mode-disable-key
                  (define-key (cdr pair-holding-keymap-to-modify)
                    semi-modal-minor-mode-disable-key 'semi-modal-minor-mode-disable)))
            (semi-modal-minor-mode 0))))))

关于emacs - 半模态编辑/自动前缀键,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/555470/

10-15 01:04