【问题标题】:emacs mode-specific custom key bindings: local-set-key vs define-keyemacs 模式特定的自定义键绑定:local-set-key vs define-key
【发布时间】:2012-04-06 18:42:54
【问题描述】:

在定制我的.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)

我想说这种结构可以很容易地使用相同的键绑定 通过向所有相关的主模式添加相同的功能来不同的主模式 钩子(换句话说,“我想要哪些键绑定”明显分开 来自“我想要它们的模式”)。但是,我不习惯 事实上,这种定制是在缓冲区级别完成的,而我会 认为它们属于主要模式。

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)))

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

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

“首选/更好”是指:

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

【问题讨论】:

  • 多年后我发现了同样的事情,当我尝试创建一个处理 minibuffer 窗口的主要模式时,它有自己的键表并且在哪里是强制性的 local--

标签: emacs elisp


【解决方案1】:

我相信你描述的两种方法并没有你想象的那么不同。

请注意,local-set-key 实际上会计算 (define-key map key command),其中 map(current-local-map) 的值,通常由主模式设置。

所以尽管他们可能在做不同的事情;大多数情况下,唯一真正的区别是带有 local-set-key 调用的钩子函数将重复/冗余设置同一个键,而另一种方法只设置一次。

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

较不容易被新的 emacs 版本破坏

我想您可能会争辩说,键映射的名称将来可能会更改,因此不需要知道名称是一个优势,但您同样可以说模式挂钩的名称可能会更改。我认为这两个都不足以让人担心。

需要注意的一点是,即使主要模式没有建立 current-local-maplocal-set-key 也可以工作,我想这使得它就通用方法而言更加健壮。

不太容易受到活跃的次要模式的干扰/干扰

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

更惯用/可读/可与他人分享

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

我说的是在每种情况下使用对您来说最合适的方法。为了代码的一致性,我确实认为对大多数事情采用标准方法是件好事,但我怀疑选择哪一种方法是否重要。显然,通过不必评估相同的代码可以节省一些 CPU 周期,但这应该无关紧要。

我认为一个比另一个最明显的情况是你已经提到的那个 - 如果你想使用一个公共钩子将相同的绑定应用于多个模式(但不是 所有模式-- 为此我彻底推荐creating a custom minor mode),那么在那个钩子中添加local-set-key 绝对是正确的选择。

【讨论】:

  • +1 表示当前本地键盘映射实际上是主要模式映射。现在我重新阅读了current-local-map 的文档,这已经很清楚了,但由于某种原因,我一直认为本地键映射是特定于缓冲区的,并且不会影响使用相同主模式的其他缓冲区。
【解决方案2】:

我有很多自定义键盘命令,我懒得用各种方法在 Emacs 中设置它们,所有这些键盘映射相互覆盖,所以我只是按照 my relevant answer 安装了 John Wiegley 的 bind-key

(require 'bind-key)
(bind-key "C-l" 'goto-line)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-26
    • 2011-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    相关资源
    最近更新 更多