8

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

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

它没有更改键绑定(与 Ch 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 中的工作方式。

4

3 回答 3

5

Paredit 使用不同的方式来定义键盘映射。尽管大多数次要模式在变量定义中定义了键映射,但 Paredit 调用paredit-define-keys顶层从而强制初始化键映射。

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

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

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

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

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

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

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

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

于 2013-05-17T16:42:26.863 回答
4

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

您的代码到底有什么问题

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

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

Paredit 对 defvar 的不尊重确实意味着很难按照您的意愿取消绑定所有键。

于 2013-05-18T04:06:39.420 回答
3

为什么不创建自己的次要模式?Paredit 模式所做的只是提供键绑定,所以如果你破坏它的键映射,它对你没有任何作用。无论您是否使用 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)))
于 2013-06-13T14:14:54.843 回答