代码之家  ›  专栏  ›  技术社区  ›  Peter Ajtai

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

  •  11
  • Peter Ajtai  · 技术社区  · 14 年前

    问题:

    如何为次要模式创建自定义键绑定? 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
    )
    

    在调用我的自定义次要模式“num mode”并验证它在mini buffer中处于打开状态之后,当我在num pad上点击“1”时,我得到了错误 <kp-1> is undefined a 当我击球时,指针的位置会被打印出来 <kp-1>

    上下文:

    因此,我通常使用num pad在缓冲区之间移动(箭头键将我移动到适当的方向)。这是全局设置的。我想创建一个小模式,我可以调用时,我想使用我的数字键盘简单地输入数字。

    <kp-0> <kp-9>

    我可以创建一个可以调用的次要模式,但不能附加任何键绑定。这适用于所有键绑定,包括其他地方未定义的键绑定。

    谢谢你的帮助!

    3 回复  |  直到 12 年前
        1
  •  20
  •   Community CDub    7 年前

    简短的回答

    问题线:

    '(((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 ...       
    )
    

    ;; 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变量和keymap 之前 次要模式声明如下:

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

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

    (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
    

    它是如何运作的

    custom-mode 在这种情况下( M-x custom-mode 切换模式)。这也定义了一个同名的变量。

    在命令名之后,我们用引号列出次要模式的文档字符串。你想干多久就干多久。

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

    1. 次要模式变量的初始化值。 nil

    2. 打火机。打火机只是什么是显示在底部的模式行时,您的次要模式是。这应该很短,而且在格式方面,用空格开始通常会有帮助。

    3. 钥匙图。keymap可以定义为变量或alist(关联列表)。因为使用了 alist 更简单,更短,这就是我在示例中使用的。列表应该在表单中 (key-sequence . definition)

    如果您将keymap定义为一个列表,那么有几件事需要注意,特别是当您习惯于定义全局键绑定时。首先,命令名不被引用。第二,如果你想用宏, 你必须这样 force it to evaluate ( and on SO ) . 这是通过后引号(不是单引号)和逗号的组合来完成的。您可以在使用kbd宏的示例中看到这是如何实现的。如果不使用kbd宏,我还提供了一个击键定义。如果您只是在keymap中引用一个字符串,那么当按下定义的键组合时,它将打印出来(就像定义全局键绑定一样)。

    如果不强制使用后引号和逗号组合对kbd宏求值,则keymap将不适用于kbd宏。

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

    :blah :global . 我们可以用关键字args来定义整个模式,但是只按正确的顺序列出init值、lighter和keymap要短一些。

        2
  •  3
  •   Bozhidar Batsov    14 年前

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

    (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 供参考。

        3
  •  2
  •   Community CDub    7 年前

    请看一下这个(仅了解有关键绑定的信息):

    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

    好写的主要模式将运行钩子在最后。因此,可以使用钩子来定义keybinding。次要模式通常没有挂钩。在这种情况下,可以先调用(需要次要模式特征符号),然后定义keybinding。

    http://www.cs.utah.edu/dept/old/texinfo/emacs19/emacs_35.html#SEC347

    也许是公认的答案 here

    推荐文章