为什么(commandp'(customize-option'foo))为零?

时间:2012-09-17 13:33:14

标签: emacs lisp elisp

我想将某个变量的customize-option绑定到一个键,因为我需要经常更改它。我有两个选择:

(global-set-key (kbd "<f12>") '(lambda() (interactive) (customize-option 'my-variable) ) )
(global-set-key (kbd "<f12>") '(customize-option 'my-variable )

第一个起作用,第二个起作用,因为commandp抱怨customize-option不是命令。为什么?据我所知,customize-option是一个互动功能,因此commandp应为t

  

customize-option是一个交互式编译的Lisp函数。

     

它必然会。

     

(customize-option SYMBOL)

     

自定义SYMBOL,它必须是用户选项变量。

2 个答案:

答案 0 :(得分:3)

(customize-option 'my-variable)形式不是命令。您不能绑定到任意引用的表单,只能绑定到文字字符串或未绑定的符号。其中一些对于绑定很有用,但解决这些限制并不困难。如果您觉得难以忍受,请写一个宏。 (俗话说,现在你有两个问题。)

答案 1 :(得分:3)

global-set-key的第二个参数必须是命令定义,通常是命名交互式函数的符号。交互式函数是以(interactive)形式开头的函数。例如:

(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

(global-set-key [f12] 'delete-to-end)

如果没有(interactive)行,delete-to-end仍会命名一个可以从Lisp程序调用的函数,但它不是一个“命令”。由于它标记为交互式,(commandp 'delete-to-end)返回true, M-x delete-to-end 有效。

交互式函数不需要绑定到符号,它们可以是匿名的。与任何其他匿名函数一样,它们是使用lambda表单创建的,但对于命令,它还必须包含(interactive)。匿名命令可以作为第二个参数传递给global-set-key而不将它们分配给符号,因此以下定义等同于上面的定义:

(global-set-key [f12]
                (lambda ()
                  "Delete text from point to the end of buffer."
                  (interactive)
                  (delete-region (point) (point-max))))

...除了它的可读性稍差,用 C-h c 进行检查时看起来更丑陋 或 C-h k

在你的情况下,对global-set-key的第一次调用被赋予一个有效的命令(引用的lambda形式本身就是一个有效的函数),但第二个不是,它给了两个 - 既不能被调用也不满足被标记为“交互”的要求的元素列表。