簡體   English   中英

如何在 Emacs-LISP 中將(非交互式)function 變成命令(交互式功能)?

[英]How to turn a (non-interactive) function into a command (interactive function) in Emacs-LISP?

我想在 Emacs 的 Markdown 模式中調用 function markdown-back-to-heading 我知道interactive將非交互式功能變成交互式的,或者正式的功能變成命令

特殊形式:交互式arg-descriptor

這種特殊形式聲明 function 是一個命令,因此可以交互調用它(通過 Mx 或通過輸入綁定到它的鍵序列)。

我試過了:

(define-key markdown-mode-map (kbd "C-c C-h") 'markdown-back-to-heading)

這會引發錯誤: Wrong type argument: commandp, markdown-back-to-heading

所以我用交互式 function 包裝它,它可以工作:

(defun my-markdown-back-to-heading ()
  "Wrap function to be called interactively."
  (interactive)
  (markdown-back-to-heading))

(define-key markdown-mode-map (kbd "C-c C-h") 'my-markdown-back-to-heading)

有沒有更好的方法將原生 function 變成交互式命令?

如果想讓markdown-back-to-heading交互,你有幾個不同的好選擇:

  • 提交錯誤報告以獲取上游以使其成為現實。 在錯誤報告中包含一個補丁可以幫助加快這個過程。
  • 使用以下建議:

     (advice-add 'markdown-back-to-heading:before (lambda () (interactive "^") nil))

相反,如果您想提高 function 的交互性,例如,如果您想支持shift-selection ,您可以使用(interactive "^")而不是(interactive)添加交互代碼^ ,以便 Emacs 知道這是一個導航命令(因此,如果您將它與移位綁定一起使用,它將 select 相應的文本)。 這是一個手冊頁,其中包含交互式代碼列表,以及您提到的手冊頁上的其他交互選項。

您也可以使用interactive-form符號屬性。

有關詳細信息,請參閱Ch i g (elisp)Using Interactive

這是一個簡單的例子:

;; Enable M-x kill-process (to kill the current buffer's process).
;; (This is not normally a command, but it is useful as one.)
(put 'kill-process 'interactive-form '(interactive))

我實際使用的更復雜的版本是:

(put 'kill-process 'interactive-form
     '(interactive
       (let ((proc (get-buffer-process (current-buffer))))
         (if (process-live-p proc)
             (unless (yes-or-no-p (format "Kill %S? " proc))
               (error "Process not killed"))
           (error (format "Buffer %s has no process" (buffer-name))))
         (list proc))))

根據@Stefan 的建議,我提交了一個 Github 問題提交了一個補丁,在源代碼中添加了一行(interactive "P")

(defun markdown-back-to-heading (&optional invisible-ok)
  "Move to previous heading line, or beg of this line if it's a heading.
Only visible heading lines are considered, unless INVISIBLE-OK is non-nil."
  (interactive "P")
  (markdown-move-heading-common #'outline-back-to-heading invisible-ok))

現在我可以將它與

(define-key markdown-mode-map (kbd "C-c C-h") 'markdown-back-to-heading)

我已經從 MELPA 安裝了markdown-mode ,因此此更改需要卸載 package ,然后從 repo README中執行這些步驟。 分叉了回購並在本地克隆了回購:

git clone git@github.com:miguelmorin/markdown-mode

並將這些行添加到 Emacs 初始化:

(add-to-list 'load-path (expand-file-name "~/code/markdown-mode"))

(autoload 'markdown-mode "markdown-mode"
   "Major mode for editing Markdown files" t)
(add-to-list 'auto-mode-alist '("\\.markdown\\'" . markdown-mode))
(add-to-list 'auto-mode-alist '("\\.md\\'" . markdown-mode))

(autoload 'gfm-mode "markdown-mode"
   "Major mode for editing GitHub Flavored Markdown files" t)
(add-to-list 'auto-mode-alist '("README\\.md\\'" . gfm-mode))

(require 'markdown-mode)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM