为什么我不能改变paredit键绑定

时间:2013-05-17 09:21:01

标签: emacs keyboard-shortcuts elisp paredit

我正在尝试使用paredit中的一些函数,而不加载所有的键绑定。看看paredit.el,我找到的唯一的键盘映射是paredit-mode-map,所以我尝试了这个。

(setq paredit-mode-map (make-sparse-keymap))
(define-key paredit-mode-map (kbd "<C-M-left>") 'paredit-backward)

它没有改变键绑定(用C-h k检查),但是变量paredit-mode-map被改变了。

我也试过

(eval-after-load "paredit"
  '(progn
     (setq paredit-mode-map (make-sparse-keymap))
     (define-key paredit-mode-map (kbd "<C-M-left>") 'paredit-backward)))

然后打开和关闭paredit,结果相同。

以前,直接更改键盘图一直对我有用。这是怎么回事?

编辑:

我成功地通过这样做来改变键映射:

; Remove old paredit bindings
(defun take-from-list (condp list)
  "Returns elements in list satisfying condp"
  (delq nil
    (mapcar (lambda (x) (and (funcall condp x) x)) list)))
(setq minor-mode-map-alist 
      (take-from-list 
        (lambda (x) (not (eq (car x) 'paredit-mode))) 
        minor-mode-map-alist))

; Create new paredit-mode-map
(setq paredit-mode-map (make-sparse-keymap))
(define-key paredit-mode-map (kbd "<C-kp-enter>") 'paredit-backward)

; Add the new paredit-mode-map to minor-mode-map-alist
(setq minor-mode-map-alist (append
                (list (append (list 'paredit-mode) paredit-mode-map))
                minor-mode-map-alist))

因此,似乎minor-mode-map-alist是用于查找的变量。我确信有更优雅的方法来更改键绑定,但我想更多地了解键绑定在emacs中的工作原理。

3 个答案:

答案 0 :(得分:4)

Paredit使用不同的方式来定义键映射。虽然大多数次要模式在变量定义中定义了键映射,但Paredit在顶级上调用paredit-define-keys,因此强制初始化键映射。

换句话说,您无法阻止Paredit设置其绑定。您需要使用(define-key paredit-mode-map … nil)删除键映射中的所有键绑定以删除它们。

编辑:您无法通过为变量指定新的键盘映射来“重置”键盘映射。 (setq paredit-mode-map …)会更改变量paredit-mode-map不会更改Paredit模式使用的实际键映射。

此变量的绑定仅在定义时间时评估一次,即在评估define-minor-mode期间。此宏在内部调用add-minor-mode,并将keymap变量的当前值传递给此函数。此模式的所有未来使用仅涉及此键映射。 keymap变量是永远不会再次由次模式评估,因此更改其绑定无论如何都没有效果。

如果要更改键映射,则必须在评估 define-minor-mode之前重新绑定变量,即在加载相应的库之前。因此,以eval-after-load形式更改它是完全没用的。

通常,在加载库之前更改keymap变量效果很好,因为大多数模式在defvar的主体内定义了键映射。但是,defvar如果已经有一个值,则不会更改变量的值。因此,如果变量已经有一个键映射,则不会触及它。

然而,正如我所说,Paredit并不尊重这种模式,而是强行将其绑定添加到键映射中。因此改变它是没有意义的,因为Paredit无论如何都会添加它的绑定。

正如我所说,你必须通过取消定义每一个键来手动清除现有的键盘。

TL; DR:真的使用Smartparens!它涵盖了Paredit的全部内容,它具有灵活性,功能强大,可扩展性,简而言之就是好的。它可以让你选择你想要的任何键绑定。

答案 1 :(得分:3)

首先阅读lunaryorn的回答。这只是一个澄清。

你的代码究竟是什么破坏了

(setq paredit-mode-map (make-sparse-keymap))

这不适用于任何已加载的模式。 paredit并不特别。

Paredit对defvar的不尊重意味着解开很难 所有按键都可以。

答案 2 :(得分:3)

为什么不创建自己的次要模式? Paredit Mode所做的就是提供键绑定,所以如果你破坏它的键盘映射,它对你没有任何作用。无论您是否使用Paredit模式,都可以使用paredit命令。 (没有人强迫你绑定钥匙!)

(defvar snowape-mode-map (make-sparse-keymap))
(define-minor-mode snowape-mode
  "Minor mode for snowape's favorite pareditoid key bindings.
\\<snowape-mode-map>"
  :lighter " Snowape")
(define-key snowape-mode-map (kbd "C-M-<left>") 'paredit-backward)
...

或者,你可以在你喜欢的模式钩子中使用local-set-key

(add-hook 'lisp-mode-hook
  (defun lisp-mode-snowape-setup ()
    (local-set-key (kbd "C-M-<left>") 'paredit-backward)))