[英]How to call interactive Emacs Lisp function with a prefix argument, from another Emacs Lisp function?
我想编写一个Emacs Lisp函数,无论flyspell-mode
的当前状态如何,都会打开flyspell-mode
模式。 函数flyspell-mode-on
已弃用。 文档表明,正前缀参数将变为flyspell-mode
,但遗憾的是运行
(flyspell-mode 1)
导致错误消息:
Wrong number of arguments: (lambda (flyspell-mode 1)), 0
如果我能弄清楚如何使用前缀参数调用flyspell-mode
,我相信我可以解决这个问题。
我在Emacs Lisp手册中可以找到的最相关的部分是标题为“交互式呼叫”的部分,它将这些命令描述为call-interactively
。 这显然不是我想要的。
(我试图解决的最终问题是创建一个模式挂钩,无论当前状态如何,都会打开模式。)
NB问题的标题emacs lisp调用函数带有前缀参数以编程方式使其看起来是相关的,但该问题是询问如何创建交互式命令,并且问题最终通过call-interactively
解决。
编辑 :这个问题没有实际意义; 我找到了原始问题的替代解决方案:
(add-hook 'text-mode-hook
(function (lambda ()
(require 'flyspell)
(if flyspell-mode nil (flyspell-mode)))))
但我仍然想知道如何从另一个Emacs Lisp函数调用带有前缀参数的Emacs Lisp函数, 没有任何交互。
更新 :也许我应该问为什么我收到错误消息...
看起来您的Flyspell模式版本不遵循次要模式约定 ,这要求您可以使用(name-of-mode t)
或任何正前缀参数打开次要模式,将其关闭(name-of-mode 0)
任何负前缀参数,并用(name-of-mode nil)
切换它。
如果你有最新版本的Flyspell,可能会有错误报告。 我在我的机器上有GNU Emacs 23.2附带的版本,它遵守惯例。 我的版本还定义了两个函数turn-on-flyspell
和turn-off-flyspell
,这两个函数都是关于flyspell-mode
简单包装器; 具有此类名称的函数很常见,但不是官方惯例。 flyspell-mode-on
和flyspell-mode-off
功能显然是供内部使用的。
一般来说,命令从current-prefix-arg
变量中读取当前前缀参数。 不要将它与prefix-arg
混淆,后者是下一个命令的值(只有几个命令,如universal-argument
touch this变量)。 因此,如果在调用函数时需要传递前缀参数,请绑定或设置current-prefix-arg
。
(let ((current-prefix-arg t))
(flyspell-mode))
如果不是以交互方式调用函数,则不使用(interactive)
声明来获取参数。
在绝大多数情况下,您无需担心参数是否可以成为非交互式调用的“前缀参数”; 只需检查功能文档,并传递您想要做的任何事情所需的值。
如果出于某种原因,您确实需要复制在非交互式上下文中发送前缀参数,则需要检查该函数的(interactive)
声明并确定它是如何使用该参数的,并确保为此复制该行为。你通过的论点。
有关详细信息,请参阅:
interactive
RET (info "(elisp) Prefix Command Arguments")
RET 在更复杂的情况下,函数根据current-prefix-arg
变量更改其行为,您可以直接设置该变量。
(let ((current-prefix-arg '(4)))
(foo current-prefix-arg))
我能想到这个......应该会更好
(call-interactively (lambda ()
(interactive)
(flyspell-mode '(4))))
更新:我可以直接运行这个问题。我在问题中缺少什么。
(flyspell-mode '(4))
EDITED:删除了lambda表达式的引用(我添加了这个注释,因为SX强制编辑长度至少为六个字符,因此可以删除)。
请参阅我的评论以解决您的问题来源。 至于你的问题的答案,前缀arg转换成某种Lisp参数的方式取决于interactive
规范,所以唯一的方法是可靠地做到这一点(即没有先验知识,例如它是一个小模式函数的事实)是以交互方式调用函数:
(let ((current-prefix-arg '(4)))
(call-interactively 'flyspell-mode))
FWIW,`flyspell-mode'函数已经接受了一个参数(如“(flyspell-mode 1)”),至少从Emacs-21开始,所以我不知道你是怎么得到那个错误的。
但是当我在这里时,我不妨指出(add-hook'text-mode-hook'flyspell-mode)在Emacs-24中改变了意义:而不是意味着“在文本模式中切换flyspell-mode”它现在意味着“在文本模式下启用flyspell-mode”。 这是一个向后不兼容的变化,但我相信它会修复比它引入的更多潜在错误。
我不是Emacs和Elisp的主人( 还有 ))但我认为在这种情况下你可以使用 Ctrl - u 1
Alt - x flyspell-mode
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.