我试图使用一些函数从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)))