Elisp: Get universal-argument

By Xah Lee. Date: . Last updated: .

This page shows you how to make your emacs command accept universal-argumentCtrl+u】 given by user.

Problem

You have written a emacs command. You want the command's behavior to be different if user presses 【Ctrl+u】 before calling your command.

Detail

Emacs has a mechanism for a command to have variant behavior if user calls universal-argumentCtrl+u】.

The purpose of universal-argument is:

  1. A convenient way to let user pass numerical argument to a command. (What the command do with number argument depends on the command.)
  2. To simply have a alternate behavior of a command. (e.g. copy file name normally, or copy full path.)

For example:

Solution

To make your command aware of universal argument, there are 3 simple ways:

  1. The global variable current-prefix-arg holds the value of universal argument.
  2. Add (interactive "P") to your function. It passes the value of current-prefix-arg as your function's first parameter.
  3. Add (interactive "p") to your function. It passes converted numerical value of current-prefix-arg to your function's first argument.

[see Elisp: Interactive Form]

Example:

(defun f (x)
  "print argument received"
  (interactive "P")
  (message "%s" x)
  ;; value of x is from universal argument, or nil if universal-argument isn't called
)

Possible Values of Universal Argument

Here's the possible values of current-prefix-arg.

Key InputValue of current-prefix-argNumerical Value
No universal arg called.nil1
Ctrl+u -Symbol --1
Ctrl+u - 2Number -2-2
Ctrl+u 1Number 11
Ctrl+u 4Number 44
Ctrl+uList '(4)4
Ctrl+u Ctrl+uList '(16)16
(defun g ()
  "print `current-prefix-arg'"
  (interactive )
  (message "%s" current-prefix-arg))

;; try
;; M-x g
;; C-u M-x g
;; C-u C-u M-x g
;; C-u 1 M-x g
;; C-u 2 M-x g

(info "(elisp) Prefix Command Arguments")

Checking current-prefix-arg

Here's a example that expect all possible use of universal-argument values, by manually checking the value of current-prefix-arg, and feed it to the function's arguments.

(defun utest (arg1 &optional arg2 arg3)
  "Sample command to test `universal-argument'."
  (interactive
   (cond
    ((equal current-prefix-arg nil) ; no C-u
     (list 1 nil nil))
    ((equal current-prefix-arg '(4)) ; C-u
     (list 1 2 nil))
    ((equal current-prefix-arg 2) ; C-u 2
     (list 1 2 3))
    ;; more special case here

    (t ; all other cases, prompt
     (list
      (read-string "arg1:" )
      (read-string "arg2:" )
      (read-string "arg3:" )))))

  ;; now, all the parameters of your function is filled.
  ;; code body here

  (message "args are: %s %s %s" arg1 arg2 arg3)
  ;;
  )

The (interactive …) is used to fill out the parameters.

[see Elisp: Interactive Form]

The read-string is to prompt user for input.

[see Elisp: Get User Input]

Elisp: Writing Command

  1. Writing Command, Basics
  2. Mark and Region
  3. Get Buffer String
  4. Work with Lines
  5. Copy Cut Paste kill-ring
  6. Get User Input
  7. Interactive Form
  8. Get universal-argument
  9. Find Replace Text
  10. thing-at-point
Patreon me $5 patreon

Or Buy Xah Emacs Tutorial

Or buy a nice keyboard: Best Keyboard for Emacs

If you have a question, put $5 at patreon and message me.