Elisp 中 interactive 总结
Table of Contents
一个例子
在开始之前我们先看一个例子:
(defun say-hello(name)
(message "Hello %s" name))
我们 C-x C-e
执行一下这个代码,然后 M-x say-hello
,
是不是提示没有找到这个命令,这就对了。我们再看看下面的例子。
(defun say-hello(name)
(interactive "sEnter your name: ")
(message "Hello %s" name))
通过 C-x C-e
执行完上面的代码以后,我们输入 M-x
say-hello
, 然后 minibuffer 会提示: Enter your
name:
,你输入一个名称,minibuffer 就会打印出一条消息。
通过 interactive 我们就可以把一个函数变成一个可交互的命令。这样的命令我们可以通过 M-x
来执行。另一方面来说,如果一个函数没有使用 interactive
, 它就不能通过 M-x 来调用,也不能通过 key binding
来使用,只能通过代码来调用。
interactive 使用
语法规则
interactive 的使用主要是:
(interactive arg-descriptor)
关于 arg-descriptor
有很多,下面一一道来。
缺省或 nil
这种情况下的命名不能带参数,如果这个命令要求有参数就会出错。例如:
(interactive)
(interactive nil)
带 string 类型参数
类似(interactive "…"), 然后 emacs 会根据第一个字符来解释用户的输入。 大约有 30 个的这个解释来做这种处理。但是常用的不是太多,这里 可以了解更多。
- P and b
(interactive "P\nbFrobnicate buffer: ")
其中字母
P
会把命令的第一个参数设置为raw command perfix
(this), 'bFrobnicate buffer: '提示用户输入一个 buffer 的名字。这个提示的字符串可以使用 '%' 来包含前一个参数值。例如下面是你读入已经存在的 buffer 名称,然后跟着一个新的名字。
(interactive "bBuffer to rename: \nsRename buffer %s to: ")
P
The raw prefix argument. (Note that this ‘P’ is upper case.)b
The name of an existing buffer. By default, uses the name of the current buffer - n
以一个数字作为参数
(defun ask-age (x) "Ask age." (interactive "nEnter your age: ") (message "Name: %d" x))
- r
这个是表示这个函数要接受当前选中区域的开始和结束位置。这里 有更多的例子。
(defun myMark-elisp-region (rStart rEnd) "Mark region as Elisp source code for org mode export." (interactive "r") (message "Region begin at: %d, end at: %d" rStart rEnd) (save-excursion (goto-char rEnd) (insert "\n#+END_SRC\n") (goto-char rStart) (insert "#+BEGIN_SRC emacs-lisp -n\n")))
- a
函数名称
(defun call-a-func (x) (interactive "aEnter a function:") (funcall x))
- s
字符串
(defun say-hello(name) (message "Hello %s" name))
传递一个 List
(defun do-something (x y)
"Ask name and age"
(interactive
;; complex code here that returns a list
(list "Mary" 22))
(message "Name is: %s, Age is: %d" x y))
(defun ff (name age)
"Prompt user to enter a string, with input history support."
(interactive
(list
(read-string "Enter your name:")
(read-string "Enter your age:")))
(message "Name is %s." name)
(message "Age is: %s" age))