繁体   English   中英

如何从另一个Emacs Lisp函数调用具有前缀参数的交互式Emacs Lisp函数?

[英]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-flyspellturn-off-flyspell ,这两个函数都是关于flyspell-mode简单包装器; 具有此类名称的函数很常见,但不是官方惯例。 flyspell-mode-onflyspell-mode-off功能显然是供内部使用的。

一般来说,命令从current-prefix-arg变量中读取当前前缀参数。 不要将它与prefix-arg混淆,后者是下一个命令的值(只有几个命令,如universal-argument touch this变量)。 因此,如果在调用函数时需要传递前缀参数,请绑定或设置current-prefix-arg

(let ((current-prefix-arg t))
  (flyspell-mode))

如果不是以交互方式调用函数,则不使用(interactive)声明来获取参数。

在绝大多数情况下,您无需担心参数是否可以成为非交互式调用的“前缀参数”; 只需检查功能文档,并传递您想要做的任何事情所需的值。

如果出于某种原因,您确实需要复制在非交互式上下文中发送前缀参数,则需要检查该函数的(interactive)声明并确定它是如何使用该参数的,并确保为此复制该行为。你通过的论点。

有关详细信息,请参阅:

  • CH˚F interactive RET
  • M- :( (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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM