如何将键绑定到“由以下键序列表示的函数”?

时间:2010-12-26 22:25:30

标签: emacs elisp key-bindings

我刚刚开始学习emacs(哇哇!)而且我一直在我的.emacs中愉快地捣乱。不幸的是,我还不知道Lisp,所以我遇到了基础问题。

我已经重新设置了几把钥匙,直到我修好肌肉记忆:

(global-set-key (kbd "<f9>") 'recompile)

没关系。但是,如何判断“模拟按几个键”键?例如,我不知道,使<f1>C-u 2 C-x }做同样的事情(用两个字符加宽缓冲区)。

一种方法是查找C-x }调用shrink-window-horizontally,然后执行某种lambda操作。这当然是整洁而优雅的方式(你怎么做?)。但肯定有一种方法可以定义<f1>来发送击键C-u 2 C-x }吗?

4 个答案:

答案 0 :(得分:18)

当然有,而且这是显而易见的方式:

(global-set-key (kbd "<f1>") (kbd "C-u 2 C-x }"))

答案 1 :(得分:8)

我将使用shrink-window-horizontally作为示例函数,但您可以将该想法概括为您要定义的任何绑定。

如果您想使用两个作为缩小窗口的默认数量而不是一个,请尝试以下操作:

(global-set-key [f9]
  (lambda (&optional n)
    (interactive "P")
    (shrink-window-horizontally (or n 2))))

F9 键绑定到接受前缀参数的交互式函数。如果你只是按 F9 you'll pass no argument,它会取消默认值2,因为参数n将接收nil作为参数。但是,如果你按下 C-u 10 F9 ,你将把10作为n的参数。这使您可以更灵活地使用绑定。

答案 2 :(得分:8)

对于任何长期的事情,我都会推荐seh所示的方法,因为在大多数情况下这种方法自然会更强大。当然,它需要更多的工作和技术诀窍,但这一切都是值得的:)

'angus'方法类似于键盘宏功能的简化版本,它为Emacs提供了名称(并且使用的宏比使用宏的宏更简单)。你肯定应该知道宏 - 但是它们非常有用,而且对于任何更复杂的东西,动态记录动态比手动写出所有单独的键要快得多。

以下是我自己写的关于最重要部分的摘要:

;;;; * Keyboard macros
;;   C-x (          or F3  Begin recording.
;;                     F3  Insert counter (if recording has already commenced).
;;   C-u <n> C-x (  or F3  Begin recording with an initial counter value <n>.
;;   C-x )          or F4  End recording.
;;   C-u <n> C-x )  or F4  End recording, then execute the macro <n>-1 times.
;;   C-x e          or F4  Execute the last recorded keyboard macro.
;;       e          or F4  Additional e or F4 presses repeat the macro.
;;   C-u <n> C-x e  or F4  Execute the last recorded keyboard macro <n> times.
;;   C-x C-k r             Apply the last macro to each line of the region.
;;   C-x C-k e             Edit a keyboard macro (RET for most recent).
;;   C-x C-k b             Set a key-binding.
;;
;; If you find yourself using lots of macros, you can even name them
;; for later use, and save them to your init file.
;;   M-x name-last-kbd-macro RET (name) RET
;;   M-x insert-kbd-macro RET (name) RET
;;
;; For more documentation:
;;   C-h k C-x (
;;   M-: (info "(emacs) Keyboard Macros") RET

如果我们使用问题的例子,你会看到其中一些事情是如何结合在一起的......

首先,您可以使用 F3 Cu 2 Cx } <来定义宏/ KBD> F4

然后你可以将它暂时绑定到 F1 Cx Ck b F1 (实际上,如果F1当前是现有键映射的前缀键,则不是这样,因为以交互方式键入它只会提示其余部分。您可以在(global-set-key (kbd "<f1>") ...)的代码中绕过它,但我建议坚持{ {3}})。

如果您然后使用describe-key Ch k )来检查绑定到该键的内容,Emacs将显示(lambda)表达式如果您愿意,可以将其复制到初始文件中。

或者,您可以命名宏并要求Emacs将代码插入当前缓冲区:

M-x name-last-kbd-macro RET (姓名) RET
M-x insert-kbd-macro RET RET

此代码与describe-key显示的lambda表达式看起来不同,但如果您评估插入的宏,则会看到等价。您同样可以显示(kbd "...")表达式也计算为相同的值,因此这些只是执行相同操作的替代方法。

(您可以使用* scratch *缓冲区通过在表达式结束后移动点来评估代码,并键入 Cx Ce 以显示值迷你缓冲区,或 Cj 将值插入缓冲区。)

请注意,“插入”代码使用fset将宏指定给符号。您可以通过执行(fset)然后将该符号绑定到具有(global-set-key)的键,将宏绑定到键,或者您可以忽略(fset)并直接分配宏值。当然,这直接等同于安格斯的回答。

编辑:我刚注意到有一个kmacro-name-last-macro函数绑定到 Cx Ck n 这个函数几乎相同形式为name-last-kbd-macro,但生成使用kmacro-bind-to-key时所见的lambda表达式( Cx Ck b describe-key

答案 3 :(得分:0)

来自general-simulate-key

general.el效果更好(在我的情况下是一个弹出窗口和更改键盘图的序列,我无法使用宏):https://github.com/noctuid/general.el#simulating-keypresses