Emacs如何将命令绑定(bind)到所有键,有几个键除外?

标签 emacs elisp mode key-bindings

我想制作一个具有其键盘映射(foo-mode-map)的次要模式(foo-mode),但是当用户按下任何不在(foo-mode-map)中的键时,次要模式应该退出。如何绑定(bind) turn-off-foo-mode所有其他键?

编辑:这是我根据所选答案提出的解决方案。它也接受数字输入。

(defalias 'foo-electric-delete 'backward-kill-word)

(defun foo-mode-quit (&optional arg)
  (interactive)
  (let ((global-binding (lookup-key (current-global-map)
                                    (single-key-description last-input-event))))
    (unless (eq last-input-event ?\C-g)
      (push last-input-event unread-command-events))
    (unless (memq global-binding
                  '(negative-argument digit-argument))
      (foo-mode -1))))

(defvar foo-mode-map
  (let ((map (make-keymap)))
    (set-char-table-range (nth 1 map) t 'foo-mode-quit)
    (define-key map "-" 'negative-argument)
    (dolist (k (number-sequence ?0 ?9))
      (define-key map (char-to-string k) 'digit-argument))
    (define-key map [backspace] 'foo-electric-delete)
    map))

(define-minor-mode foo-mode
  "Toggle Foo mode.
     With no argument, this command toggles the mode.
     Non-null prefix argument turns on the mode.
     Null prefix argument turns off the mode.

     When Foo mode is enabled, the control delete key
     gobbles all preceding whitespace except the last.
     See the command \\[foo-electric-delete]."
  ;; The initial value.
  :init-value nil
  ;; The indicator for the mode line.
  :lighter " Foo"
  ;; The minor mode bindings.
  :keymap foo-mode-map
  :group 'foo)

最佳答案

我已经包含了一个完整的工作示例,用于创建具有您想要的行为类型的次要模式;关键是使用set-char-table-rangemake-keymap 创建的键盘映射上它创建了一个具有完整 char-table 的密集键映射;在使用 make-sparse-keymap 创建的稀疏键盘映射上使用它不管用。

(defalias 'foo-electric-delete 'backward-kill-word)

(defun foo-mode-quit (&optional arg)
  (interactive)
  (foo-mode -1))

(defvar foo-mode-map
  (let (map (make-keymap))
    (set-char-table-range (nth 1 map) t 'foo-mode-quit)
    (define-key map [backspace] 'foo-electric-delete)
    map))

(define-minor-mode foo-mode
  "Toggle Foo mode.
     With no argument, this command toggles the mode.
     Non-null prefix argument turns on the mode.
     Null prefix argument turns off the mode.

     When Foo mode is enabled, the control delete key
     gobbles all preceding whitespace except the last.
     See the command \\[foo-electric-delete]."
  ;; The initial value.
  :init-value nil
  ;; The indicator for the mode line.
  :lighter " Foo"
  ;; The minor mode bindings.
  :keymap foo-mode-map
  :group 'foo)

(defvar major-baz-mode-map '(keymap (t . major-baz-mode-default-function)))

为主要模式映射设置默认绑定(bind)更容易,我在此处包含此示例,但如上所述,这种备用键映射不适用于次要模式:
(defvar major-baz-mode-map '(keymap (t . major-baz-mode-default-function)))

这在 Format of Keymaps 的文档中进行了讨论。它说:
(t . binding)

This specifies a default key binding; any event not bound by other
elements of the keymap is given binding as its binding. Default
bindings allow a keymap to bind all possible event types without
having to enumerate all of them. A keymap that has a default binding
completely masks any lower-precedence keymap, except for events
explicitly bound to nil (see below).

关于Emacs如何将命令绑定(bind)到所有键,有几个键除外?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8553432/

相关文章:

emacs - Hook 一些 Emacs 事件以改进 org-mode/MobileOrg 集成

emacs - 如果窗口失去焦点隐藏光标?

emacs - Emacs 启动时菜单栏闪烁片刻

emacs - 在具有指定标签的条目上的 org-after-todo-state-change-hook 上执行代码

mysql - 使用 2 个工作表在 sql 中计算

emacs - 如何在 emacs 的 verilog 模式下禁用自动换行

Emacs -- 测试以确定正在运行的钩子(Hook)类型

emacs - 如何从 jedi :complete? 解除绑定(bind) C-tab

emacs 单词中第一个字符的位置

internet-explorer - 禁用 IE 中的调整大小控件