如何在Emacs中为自定义次要模式创建键绑定

时间:2010-06-25 02:02:54

标签: emacs keyboard-shortcuts elisp minor-mode

问题:

如何为次要模式创建自定义键绑定? Something like this

这是我到目前为止所拥有的。我试图让一个自定义键绑定工作:

(define-minor-mode num-mode
       "Toggle the Num pad keys.
     With no argument, this command toggles the mode.
     Non-null prefix argument turns on the mode.
     Null prefix argument turns off the mode.

     When Num mode is enabled, the num pad inserts the
     keys you see on the pad. This may over ried existing
     definitions, and is probably only usefule if you aref
     running Emacs through a terminal."
      ;; The initial value.
      nil
      ;; The indicator for the mode line.
      " NumPad"
      ;; The minor mode bindings.
      ;; This doesn't work right now!!!!
       '(((kbd "<kp-1>") . "a"))
      :global 1
)

当我在调用自定义次要模式后点击数字键盘上的“1”时,“num-mode”并在迷你缓冲区中验证它是否已启用,我收到错误<kp-1> is undefined。我想要发生的是a打印出当我点击<kp-1>时指针所在的位置。 (只是一个测试)

上下文

所以,我通常使用我的数字键盘在缓冲区之间移动(箭头键移动我适当的方向)。这是全球设定的。我想创建一个次要模式,当我想使用我的数字键盘输入数字时,我可以调用它。

默认情况下,我的num-pad上的键未定义。我使用<kp-0><kp-9>来定义小键盘键的键绑定。

我可以创建一个可以调用的次要模式,但是我无法附加任何键绑定。对于所有键绑定都是如此,包括未在其他地方定义的键绑定。

感谢您的帮助!

3 个答案:

答案 0 :(得分:20)

简答

问题专栏:

'(((kbd "<kp-1>") . "a"))

解决方案(强制评估宏):

;; Single quote changed to back-quote and added a comma
`((,(kbd "<kp-1>") . "a"))

长答案

define-minor-mode宏允许您相对轻松地创建次模式(就Emacs而言)。

首先,我将展示它是如何完成的,然后我将解释它是如何工作的:

一般形式:

(define-minor-mode NAME-mode
  "DOCUMENTATION"
  INIT-VALUE
  "LIGHTER"
  ;; keymap
  '(
    (KEY-SEQUENCE . DEFINITION)
    (KEY-SEQUENCE . DEFINITION)
    ... ETC ...
   )
  ;; other options
  :KEYWORD-ARG VALUE
  :KEYWORD-ARG VALUE
  ... ETC ...       
)

在alist中强制评估宏的具体示例:

;; Custom Minor Mode
(define-minor-mode custom-mode
  "Doc description, yada yada yada."
  ;; The initial value - Set to 1 to enable by default
  nil
  ;; The indicator for the mode line.
  " CustomMode"
  ;; The minor mode keymap
  `(
    (,(kbd "C-c C-a") . some-command)
    (,(kbd "C-c C-b") . other-command)
    ("\C-c\C-c" . "This works too")
   )
   ;; Make mode global rather than buffer local
   :global 1
)

另一种方法,如果你想为keymap使用一个变量,那就是定义keymap变量,并在之前定义keyfile 这样的次要模式声明:

(defvar custom-mode-keymap (make-keymap) "num-mode keymap.")
(define-key custom-mode-keymap (kbd "C-c C-a") 'some-command)

然后,在您的次要模式定义中,简单列出您的keymap的变量名称,而不是alist

(define-key custom-mode-keymap (kbd "C-c C-b") 'other-command)
;; Num pad enable
(define-minor-mode custom-mode
...

      ;; The minor mode bindings.
      custom-mode-keymap

一切如何运作

从上到下,在define-minor-mode之后,我们定义一个命令名来切换次要模式。在这种情况下custom-modeM-x custom-mode切换模式)。这也定义了同名变量。

在命令名称后面,我们在引号中列出次要模式的文档字符串。这可以和你想要的一样长。

接下来我们有几个选择。最简单的选择是简单列出三件事,然后列出任何其他选项。这三件事必须按以下顺序列出。这三件事是:

  1. 次要模式变量的初始化值。 nil默认情况下会关闭该模式。除nil以外的其他内容默认情况下会启用它。

  2. 打火机。打火机就是当您的次要模式打开时底部模式行中显示的内容。这应该很简短,在格式化方面,它通常会帮助用空格开始。

  3. 键盘映射。键映射可以定义为变量或alist(关联列表)。由于使用alist更简单,更短,这就是我在示例中使用的内容。 alist的格式应为(key-sequence . definition)

  4. 如果将keymap定义为alist,则需要注意一些事项,特别是如果您习惯于定义全局键绑定。首先,不引用命令名称。其次,如果你想使用宏,你必须force it to evaluateand on SO。这是通过反引号(不是单引号)和逗号的组合来完成的。您可以在使用kbd宏的示例中看到这是如何完成的。如果你不使用kbd宏,我还包括一个击键定义。如果您只是在键盘映射中引用一个字符串,那么在按下定义的键组合时会打印出来(就像定义全局键绑定一样)。

    如果不强制使用后引号和逗号的组合来评估kbd宏,则键映射将无法与kbd宏一起使用。像这样:

    `((,(kbd "C-c C-a") . some-command))
    

    最后,您可以使用:blah形式的keyword-args添加其他选项。在我使用:global的示例中。我们可以使用keyword-args定义整个模式,但只需按正确的顺序列出init值,light和keymap就可以了。

答案 1 :(得分:3)

您需要在次要模式定义中使用这样的代码:

(defvar your-mode-map
  (let ((map (make-sparse-keymap)))
    (set-keymap-parent map parent-mode-shared-map)
    (define-key map "\C-c\C-a" 'some-defun)
    (define-key map "\C-c\C-b" 'some-other-sexp)
    map)

(use-local-map your-mode-map)

您可以查看EmacsWiki中提供的众多模式以供参考。

答案 2 :(得分:2)

看看这个(只是关于键绑定的信息):

http://www.gnu.org/software/emacs/manual/html_node/emacs/Key-Bindings.html#Key-Bindings

http://www.gnu.org/software/emacs/manual/html_node/emacs/Local-Keymaps.html#Local-Keymaps

来自http://xahlee.org/emacs/reclaim_keybindings.html

写得好的主要模式将在最后运行。因此,您可以使用钩子来定义键绑定。次要模式通常没有钩子。在这种情况下,您可以先调用“(require )”,然后定义键绑定。

你也可以看看: http://www.cs.utah.edu/dept/old/texinfo/emacs19/emacs_35.html#SEC347

也许接受的答案here也可以帮到你。