Emacs 为什么(commandp';(customizeoption';foo))为零?
我想将某个变量的Emacs 为什么(commandp';(customizeoption';foo))为零?,emacs,lisp,elisp,Emacs,Lisp,Elisp,我想将某个变量的自定义选项绑定到一个键,因为我需要经常更改它。我有两个选择: (global-set-key (kbd "<f12>") '(lambda() (interactive) (customize-option 'my-variable) ) ) (global-set-key (kbd "<f12>") '(customize-option 'my-variable ) (全局设置键(kbd“”)”(lambda()(交互式)(自定义选项“我的变量”))
自定义选项
绑定到一个键,因为我需要经常更改它。我有两个选择:
(global-set-key (kbd "<f12>") '(lambda() (interactive) (customize-option 'my-variable) ) )
(global-set-key (kbd "<f12>") '(customize-option 'my-variable )
(全局设置键(kbd“”)”(lambda()(交互式)(自定义选项“我的变量”))
(全局设置键(kbd“”)”(自定义选项“我的变量”)
第一个有效,第二个无效,因为commandp
抱怨customize option
不是命令。为什么?据我所知,customize option
是一个交互式功能,所以commandp
应该是t
:
自定义选项是一个交互式编译的Lisp函数
这是必然的
(自定义选项符号)
自定义符号,它必须是用户选项变量
这是一个非命令的表单
(自定义选项“我的变量”)
。您不能绑定到任意带引号的表单,就像绑定到文字字符串或未绑定的符号一样。其中一些绑定可能很有用,但绕过这些限制并不困难。如果您觉得难以接受,请编写宏。(俗话说,现在你有两个问题。)这是形式(自定义选项“我的变量”)
这不是命令。你不能绑定到任意带引号的表单,就像绑定到文字字符串或未绑定的符号一样。绑定到其中一些表单会很有用,但绕过这些限制并不困难。如果你觉得难以使用宏,就编写宏。(俗话说,现在你有两个问题。)全局设置键的第二个参数必须是命令定义,通常是命名交互函数的符号。交互函数是以(交互)
表单开头的函数。例如:
(defun delete-to-end ()
"Delete text from point to the end of buffer."
(interactive)
(delete-region (point) (point-max)))
这定义了一个交互功能,并将其分配给符号delete to end
。之后,delete to end
是一个有效的命令,您可以将其传递给全局设置键
:
(global-set-key [f12] 'delete-to-end)
如果没有(交互式)
行,删除结束
仍将命名一个可从Lisp程序调用的函数,但它将不是“命令”。由于它标记为交互式,(commandp'delete to end)
返回true,并且M-x delete to end工作
交互函数不需要绑定到符号,它们可以是匿名的。与任何其他匿名函数一样,它们是使用lambda
表单创建的,但对于命令,它还必须包含(交互)
。匿名命令可以作为第二个参数传递给全局设置键
,而无需将其分配给符号,因此以下定义与上面的定义等效:
(global-set-key [f12]
(lambda ()
"Delete text from point to the end of buffer."
(interactive)
(delete-region (point) (point-max))))
…只是它的可读性稍差,用C-h C检查时看起来更难看
或者C-hk
在您的情况下,第一次调用
全局设置键
时给出了一个有效的命令(引用的lambda
表单本身就是一个有效的函数),但第二次调用不是,它给出了一个两元素列表,既不能调用也不能满足标记为“交互式”的要求.全局设置键的第二个参数必须是命令定义,通常是命名交互函数的符号。交互函数是以(交互)
表单开头的函数。例如:
(defun delete-to-end ()
"Delete text from point to the end of buffer."
(interactive)
(delete-region (point) (point-max)))
这定义了一个交互功能,并将其分配给符号delete to end
。之后,delete to end
是一个有效的命令,您可以将其传递给全局设置键
:
(global-set-key [f12] 'delete-to-end)
如果没有(交互式)
行,删除结束
仍将命名一个可从Lisp程序调用的函数,但它将不是“命令”。由于它标记为交互式,(commandp'delete to end)
返回true,并且M-x delete to end工作
交互函数不需要绑定到符号,它们可以是匿名的。与任何其他匿名函数一样,它们是使用lambda
表单创建的,但对于命令,它还必须包含(交互)
。匿名命令可以作为第二个参数传递给全局设置键
,而无需将其分配给符号,因此以下定义与上面的定义等效:
(global-set-key [f12]
(lambda ()
"Delete text from point to the end of buffer."
(interactive)
(delete-region (point) (point-max))))
…只是它的可读性稍差,用C-h C检查时看起来更难看
或者C-hk
在您的情况下,第一次调用
全局设置键
时给出了一个有效的命令(引用的lambda
表单本身就是一个有效的函数),但第二次调用不是,它给出了一个两元素列表,既不能调用也不能满足标记为“交互式”的要求.听起来不错。宏解决方案会是什么样子?还是一个elisp新手……在最简单的情况下,类似于(defmacro bind to(key seq)(全局设置键,key(function)(lambda(nil),@seq)))
如果我的宏技能没有严重生锈的话。不过,宏很容易让你陷入沉重的伏都教。好吧,我想我可以坚持我的上述解决方案。至少现在我明白了为什么我不能在没有lambda的情况下绑定它。听起来不错。宏解决方案看起来会是什么样子?还是有点像elisp新手……最简单的情况下,有些类似于(defmacro绑定到(key seq)(全局设置键,key(函数(lambda(nil),@seq)))
如果我的宏技能没有严重生锈的话。但是宏很容易让你陷入沉重的伏都教中。好吧,我想我可以坚持我上面的解决方案。至少现在我明白了为什么没有lambda就不能绑定它。请不要引用lambda表达式。例如,使用(lambda…
而不是(lambda…)
。两者都有效,但添加引号是一个坏习惯。请不要引用lambda表达式。即,使用(lambda…
而不是”(lambda…
。两者都有效,但添加引号是一个坏习惯。