8

我刚开始学习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

4 回答 4

18

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

(global-set-key (kbd "<f1>") (kbd "C-u 2 C-x }"))
于 2010-12-26T23:14:16.953 回答
8

我将shrink-window-horizontally用作示例函数,但您可以将这个想法推广到您想要定义的任何绑定。

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

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

这将F9键绑定到接受前缀参数的交互式函数。如果您只是按F9您将不传递任何参数,这会调用默认值 2,因为参数nnil作为参数接收。但是,如果您按下 ,例如C-u 10 F9,您将传递 10 作为 的参数n。这使您可以更灵活地使用绑定。

于 2010-12-26T23:49:57.177 回答
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

如果我们使用问题中的示例,您会看到其中一些东西是如何联系在一起的......

首先,您可以定义宏F3C-u2C-x}F4

然后,您可以将其临时绑定到F1with C-xC-kbF1(实际上,如果 F1 当前是现有键盘映射的前缀键,则不是这样,因为交互式键入它只会提示输入其余部分。您可以在代码中使用 来规避这一点(global-set-key (kbd "<f1>") ...),但我建议坚持保留的绑定)。

如果您随后使用describe-key( C-hk) 检查绑定到该键的内容,Emacs 将向您显示一个(lambda)表达式,如果您愿意,您可以将其复制到您的 init 文件中。

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

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

此代码看起来与 显示的 lambda 表达式不同describe-key,但如果您评估插入的宏,您将看到等价性。您同样可以证明(kbd "...")表达式的计算结果也相同,因此这些都只是做同样事情的替代方法。

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

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

编辑:我刚刚注意到有一个kmacro-name-last-macro绑定到的函数C-xC-kn在形式上与 几乎相同name-last-kbd-macro,但它生成使用kmacro-bind-to-key( C-xC-kb) 和describe-key.

于 2010-12-27T05:12:20.880 回答
0

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

于 2018-03-26T21:38:31.390 回答