[英]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.