【问题标题】:How do I bind a key to "the function represented by the following key sequence"?如何将键绑定到“以下键序列表示的功能”?
【发布时间】:2011-05-30 22:58:24
【问题描述】:

我刚刚开始学习 emacs(哇哦!),我一直很高兴地在我的 .emacs 中闲逛。不幸的是,我还不知道 Lisp,所以我在基础知识方面遇到了问题。

在我修复肌肉记忆之前,我已经重新映射了几个键:

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

没关系。但是我怎么能告诉一个键“模拟按下几个键”呢?例如,我不知道,让&lt;f1&gt;C-u 2 C-x } 做同样的事情(将缓冲区扩大两个字符)。

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

【问题讨论】:

    标签: emacs elisp key-bindings


    【解决方案1】:

    当然有,而且很明显:

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

    【讨论】:

    • 非常感谢。这远没有你想象的那么明显。 :) 找了很久。
    【解决方案2】:

    对于任何长期的事情,我会推荐 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
    

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

    首先,您可以使用 F3Cu2Cx}F4

    然后您可以使用 CxCkbF1将其临时绑定到 F1 > (实际上,如果 F1 当前是现有键盘映射的前缀键,则情况并非如此,因为交互式键入它只会提示输入其余部分。您可以使用 (global-set-key (kbd "&lt;f1&gt;") ...) 在代码中规避这一点,但我建议坚持使用 reserved bindings )。

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

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

    Mx name-last-kbd-macro RET(名称)RET
    Mx insert-kbd-macro RETRET

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

    (您可以使用 *scratch* 缓冲区通过在表达式末尾移动点来评估代码,并键入 CxCe 以在minibuffer,或 Cj 将值插入缓冲区)。

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

    编辑:我刚刚注意到有一个kmacro-name-last-macro 函数绑定到 CxCkn 形式几乎相同name-last-kbd-macro,但它会生成使用 kmacro-bind-to-key (CxCkb) 和 describe-key 时看到的 lambda 表达式形式。

    【讨论】:

    • 非常感谢! +1 向我展示了做这类事情的一般方法。
    【解决方案3】:

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

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

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

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-10-09
        • 2021-10-09
        • 2011-05-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-24
        相关资源
        最近更新 更多