Elisp: Interactive Form
The most basic way of getting user input is by the “interactive” form:
expression must come right after the doc string.
(defun ask-name (x) "Ask name." (interactive "sEnter your name: ") (message "Name: %s" x))
The first letter
"sEnter your name:" tells emacs to pass what user typed as a string datatype to your function's argument.
Get Number as Argument
(defun ask-age (x) "Ask age." (interactive "nEnter your age: ") (message "Name: %d" x))
The first letter
"sEnter your age:" tells emacs to pass what user typed as a number datatype to your function's argument.
Get Region Begin End Positions as Argument
Here's a function taking region beginning and end positions as argument.
(defun print-region-boundary (x y) "Prints region start and end positions" (interactive "r") (message "Region begin at: %d, end at: %d" x y))
(interactive "r"). The
"r" is a code that tells emacs that the function will receive the buffer's begin/end text selection positions as its argument.
Purpose of interactive form
interactive has 2 purposes.
- Make elisp function callable as interactive command.
- A mechanism for passing arguments to function when called interactively.
A function with the
interactive clause is called a command, and can be called by
execute-extended-command (that is, pressing 【Alt+x】).
There are 3 ways to use
(interactive)→ No argument. This simply makes the function as command, and does not pass any argument to the function.
(interactive "…")→ Pass it a string, with first character (or first few character in same cases) tells emacs how to interpret the user input (such as string, number, file name, directory name, regex, lisp expression, key stroke, region begin/end position, etc) and what datatype it should be converted to as your function's argument. (string, number, …)
(interactive (list …))→ Pass it a list. The most general way for
interactiveto fill function arguments is to pass it list, like this
(interactive (list …)). This list elements will be passed as arguments to your function. Usually, it's like this
(interactive some_lisp_code)where some_lisp_code evaluates to a list.
(interactive string) form takes a single-letter code in the beginning of string to indicate how the function gets its arguments from user.
The prompt text can follow the single-letter code.
There are about 30 codes for
interactive, but the most useful are the following:
(interactive)→ make the function available for interactive use. Pass no argument.
(interactive "s")→ prompt user for input, taken as string, as argument to the function.
(interactive "n")→ prompt user for input, taken as number, as argument to the function.
(interactive "r")→ for commands that takes 2 arguments, the beginning and ending positions of the current region. This form is typically used for commands that act on a text selection.
If your function takes multiple inputs, you can promp user multiple times, using a single
interactive call, with mulitple lines, each line begin with a prompt code.
(defun ask-name-and-age (x y) "Ask name and age" (interactive "sEnter you name: nEnter your age: ") (message "Name is: %s, Age is: %d" x y))
For complete list of interactive code, see (info "(elisp) Defining Commands")
Passing Interactive a List
Here's a example of using interactive and passing it a 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))