特定于emacs模式的自定义键绑定:local-set-key vs define-key

ffe*_*tte 22 emacs elisp

在定制了我的.emacs文件几年后,我发现我使用了两种不同的结构来设置特定于主模式的键绑定:

1.使用钩子和local-set-key.例如:

(defun my/bindkey-recompile ()
  "Bind <F5> to `recompile'."
  (local-set-key (kbd "<f5>") 'recompile))
(add-hook 'c-mode-common-hook 'my/bindkey-recompile)
Run Code Online (Sandbox Code Playgroud)

我想说这个结构可以很容易地为不同的主模式使用相同的键绑定,方法是将相同的函数添加到所有相关的主模式钩子(换句话说," 我想要的哪个键绑定 "明确地与" 我想要哪些模式 ").但是,我对这种自定义在缓冲级别完成这一事实感到不舒服,而我认为它们属于主要模式.

2.使用define-key(通常与eval-after-load延迟评估相结合,直到加载相关的键映射).例如:

(eval-after-load "cc-mode"
  '(progn
     (define-key c-mode-map   (kbd "C-c o") 'ff-find-other-file)
     (define-key c++-mode-map (kbd "C-c o") 'ff-find-other-file)))
Run Code Online (Sandbox Code Playgroud)

相比之下,这个构造定制了主模式本身,但不太灵活:如果我想为另一个模式使用相同的键绑定,我将不得不为这个模式找到正确的文件和键映射名称,并且几乎复制了eval-after-load表达式(虽然这可能是使用函数/宏自动化).

问题:虽然两种构造类型都能很好地工作并产生我想要的结果,但它们在技术上非常不同,在不同的时间在不同的键盘映射中设置键绑定.所以我的问题是:在这两个结构中,有一种"首选/更好"的方法吗?(或者也许"最好的"构造是我不知道的第三个构造?)

"首选/更好",我的意思是:

  1. 不太容易破坏新的emacs版本
  2. 不太容易受到干扰/被主动小模式干扰
  3. 更加惯用/可读/可与他人共享

phi*_*ils 21

我相信你描述的两种方法与你想的不同.

请注意,local-set-key是否确实评估(define-key map key command)那里map是价值(current-local-map),这通常是由主要模式设置.

所以虽然他们可以做不同的事情; 大多数时候唯一真正的区别是,带有local-set-key调用的钩子函数将重复/冗余地设置相同的键,而另一种方法只设置一次.

您可以通过local-set-key在模式挂钩中使用,在使用它之后删除该挂钩函数,然后在相同的主模式下创建新缓冲区并测试绑定来向自己演示.

不太容易破坏新的emacs版本

我想你可能会争辩说键盘图的名称将来可能会改变,因此不需要知道名称是一个优势,但你可以同样地说模式钩子的名称可能会改变.我不认为任何一个问题都不足以担心.

有一点需要注意的是,local-set-key即使主模式没有建立,也会有效current-local-map,我认为就广义方法而言,它会稍微强一些.

不太容易受到干扰/被主动小模式干扰

没有区别.所有次模式键映射都优先于所有主模式键映射,并且这两种方法都不会对顺序产生任何影响minor-mode-map-alist(这决定了次模式键映射的优先级).

更加惯用/可读/可与他人共享

它们在我的脑海中都是完全可读的,所以我也无法在这方面区分它们.

我说只要在每种情况下使用最适合你的方法.为了代码的一致性,我认为对大多数事情采用标准方法是好的,但我怀疑你选择哪一个很重要.显然,通过不必要地评估相同的代码可以节省几个CPU周期,但这应该是非常重要的,无论如何都无关紧要.

我认为最明显的情况就是你已经提到的那个 - 如果你想使用一个普通的钩子(而不是所有模式)将相同的绑定应用于多个模式 - 为此我完全建议创建一个自定义小模式),然后local-set-key在那个钩子内绝对是要走的路.

  • +1表示当前本地键映射实际上是主模式映射.现在我重新阅读了`current-local-map`的文档,这很清楚,但出于某种原因,我一直认为本地键映射是特定于缓冲区的,并且不会影响使用相同主模式的其他缓冲区. (2认同)