Elisp: Interactive Form

By Xah Lee. Date: . Last updated: .

The most basic way of getting user input is by the “interactive” form:

(interactive "code_letter_and_promp_string")

The interactive 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 s in "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 n in "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))

Note the (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

The interactive has 2 purposes.

  1. Make elisp function callable as interactive command.
  2. 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】).

Ways to Call Interactive

There are 3 forms of interactive:

  1. (interactive) → No argument. This simply makes the function as command, and does not pass any argument to the function.
  2. (interactive string) → The first character (or first few character in same cases) in string 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, …)
  3. (interactive (list …)) → This is the most general way to fill function arguments from user input. 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.

The (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 string codes for interactive string , the most useful are the following:

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))
Like my tutorial? Put $5 at patreon

Or Buy Xah Emacs Tutorial

Or buy a nice keyboard: Best Keyboard for Emacs

Ask me question on patreon