簡體   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