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



我试图使用一些函数从paredit,没有加载所有的键绑定。看着父母。我发现唯一的键映射是paredit-mode-map,所以我尝试了这个。

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

它没有改变键绑定(如C-h - k所检查的),但变量parendit -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)))

,然后打开和关闭双引号,结果相同。

以前,直接更改keymap对我来说总是有效的。这是怎么回事?

编辑:

我成功地改变了keymap:

; 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中的键绑定是如何工作的。

Paredit使用另一种定义键映射的方式。虽然大多数次要模式在变量定义中定义keymap,但Paredit在顶层上调用paredit-define-keys,从而强制初始化keymap。

换句话说,您不能阻止Paredit设置它的绑定。您需要使用(define-key paredit-mode-map … nil)删除keymap中的所有键绑定以摆脱这些。

Edit:你不能通过分配一个新的keymap给变量来"重置"keymap。(setq paredit-mode-map …)将改变变量paredit-mode-map,它将而不是改变Paredit模式使用的实际keymap。

该变量的绑定只在定义时间计算一次,即在define-minor-mode求值期间。这个宏在内部调用add-minor-mode,并将keymap变量的当前值传递给该函数。该模式的所有未来使用仅引用此键映射。keymap变量永远不会再被次要模式计算,因此改变它的绑定没有任何影响。

如果你想改变keymap,你必须在 define-minor-mode被评估之前重新绑定变量,即在相应的库被加载之前。因此,以eval-after-load形式更改它是完全无用的。

通常,在加载库之前更改keymap变量效果很好,因为大多数模式在defvar的主体中定义keymap。然而,defvar不会改变一个变量的值,如果它已经有一个值。因此,如果变量已经有一个键映射,它将不会被触摸。

但是,正如我所说,Paredit不尊重这个模式,而是强制将其绑定添加到keymap。因此修改它是没有意义的,因为Paredit无论如何都会添加它的绑定。

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

使用智能父母,真的!它涵盖了所有的Paredit,它是灵活的,强大的,可扩展的,简而言之,它很好。它可以让你选择任何你想要的键绑定

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

你的代码到底出了什么问题

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

对于任何已经加载的模式都不起作用。paredit不特殊。

Paredit对defvar的不尊重意味着它很难解绑定

为什么不创建自己的次要模式呢?Paredit Mode所做的只是提供键绑定,所以如果你修改了它的keymap,它什么也不为你做。无论您是否使用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)))

最新更新