【问题标题】:String converted to a function command for global-set-key (elisp)字符串转换为 global-set-key (elisp) 的函数命令
【发布时间】:2013-02-19 09:25:22
【问题描述】:

我想在函数中调用 global-set-key 并为其提供参数,以创建 global-set-keys。

(defun global-setter (arg1 arg2)
 (global-set-key arg1 '(concat "example" arg1 arg2))
)

(global-setter "*" "^")

这应该创建一个绑定,当按下* 时,函数example-*^ 应该被调用。

我不知道如何获取要作为函数/命令名称传递的字符串。我究竟做错了什么?

到目前为止,我尝试了`',@(intern)(eval)(function) 的组合,但我不知道我应该做什么。

【问题讨论】:

    标签: string emacs elisp


    【解决方案1】:

    您的代码不起作用的一个原因是您引用了 (concat ..) 表达式,因此它从未被评估过。而 global-set-key 需要一个 lambda 或一个符号。

    你可以使用 intern 构造一个符号,然后将这个符号提供给 set-key:

    (defun my-test () (interactive) (message "ok"))
    (global-set-key "\C-c!" (intern (concat "my" "-" "test")))
    

    请注意,通过 global-set-key 和变体调用的任何函数都必须是交互式

    【讨论】:

    • 我只能说我一定是错过了缺少'的这种特定组合。不过,现在看来这确实很有意义。非常感谢!
    【解决方案2】:

    使用lexical-let 定义一个closure,这是一个匿名函数,它引用了定义它的环境中的值:

    (defun global-setter (arg1 arg2)
      (lexical-let ((arg1 arg1) (arg2 arg2))
        (global-set-key arg1 (lambda ()
                               (interactive)
                               (concat "example" arg1 arg2)))))
    

    Emacs 24 natively supports 词法绑定和闭包,因此不再需要 lexical-let

    (defun global-setter (arg1 arg2)
      (global-set-key arg1 (lambda ()
                             (interactive)
                             (concat "example" arg1 arg2))))
    

    为此,请务必在您的.emacs 中将lexical-binding 设置为t,并将其添加到文件末尾以确保将词法绑定用于字节编译:

    ;; Local Variables:
    ;; lexical-binding: t
    ;; End:
    

    【讨论】:

    • 不幸的是,它不起作用。您是否通过创建一个名为example-*^ 的函数对此进行了测试?我怀疑它不起作用,因为一旦您调用该函数,它就不包含 arg1 / arg2 (因此不能连接它们)。如果我错了,请纠正我。
    • @Dualinity 闭包比构造函数名强大得多——你可以在闭包中使用 arg1 和 arg2 做任何事情。 (在我的例子中,我展示了如何调用 concat 函数,因为我知道这就是你想要做的。这个例子没有多大意义,因为 concat 没有副作用。)如果你只是想要动态构造函数的name,Joost的答案就是要走的路。
    猜你喜欢
    • 2011-06-06
    • 2012-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-23
    • 2018-06-08
    • 2014-06-07
    • 2016-12-14
    相关资源
    最近更新 更多