And what can they be used for?
(interactive "p")
takes a numerical argument from the universal argument
right? And the universal argument is just an int either way, so what does capital (interactive "P")
do?
And what can they be used for?
(interactive "p")
takes a numerical argument from the universal argument
right? And the universal argument is just an int either way, so what does capital (interactive "P")
do?
Hard to believe that people described this here without also giving you links to Emacs's own descriptions of this:
In the Emacs manual, node Arguments.
In the Elisp manual, node Prefix Command Arguments.
"Ask Emacs!": C-h i
, choose a manual, i prefix argument RET
.
In a nutshell, though this is said well enough by other answers here, and is described in detail in the manual:
The "raw" prefix arg provides Lisp values of different kinds, and in particular it distinguishes whether or not the user actually used a prefix argument (of any kind).
Using it, a program can distinguish whether the user used one of {-
, M--
, C--
} or one of {M-- 1
, C-- 1
, C-u -1
} (both of which have the same numeric prefix value of -1
), and distinguish whether s?he used C-u C-u
or one of {M-16
, C-16
, C-u 16
} (both of which have numeric value 16) - among lots of other distinctions.
But the most important such distinction is nil
vs non-nil
: many commands act differently depending on whether the user uses a prefix arg.
The "numeric" prefix arg is really just the value that function prefix-numeric-value
returns when applied to the raw prefix arg. IOW, it is best thought of as a mapping from the actual raw user interaction to an integer.
It cannot tell you whether the user actually used a prefix argument, because the default of no prefix argument maps to the integer 1, just as does the use of C-u 1
, M-1
, or C-1
.
When raw prefix Interactive Code "P"
is used, the argument is passed on as it is whereas "p"
converts the arg to a number.
After evaluating the below elisp, try out C-u M-x my/fn-with-num-arg
and then C-u M-x my/fn-with-raw-arg
to see the difference because C-u
passes a list argument (4)
.
(defun my/debug-fn (arg)
(let ((msg))
(if (numberp arg)
(setq msg (format "Argument is number %s. " (pp arg)))
(setq msg "Argument is not a number. "))
(if (listp arg)
(setq msg (concat msg (format "Arg is %s." (pp arg))))
(setq msg (concat msg "Argument is not a list.")))
(message msg)))
(defun my/fn-with-num-arg (arg)
(interactive "p")
(my/debug-fn arg))
;; Result of C-u M-x my/fn-with-num-arg :
;; Argument is number 4. Argument is not a list.
(defun my/fn-with-raw-arg (arg)
(interactive "P")
(my/debug-fn arg))
;; Result of C-u M-x my/fn-with-raw-arg :
;; Argument is not a number. Arg is (4)
;; .
Also the argument defaults to 1
for numerical argument ("p"
) but defaults to nil
or ()
for raw argument ("P"
).
My few cents: At times, the deciding factor for whether to use "p"
or "P"
is whether you want the default argument to be 1
or nil
.
;; Result of M-x my/fn-with-num-arg :
;; Argument is number 1. Argument is not a list.
;; Result of M-x my/fn-with-raw-arg :
;; Argument is not a number. Arg is nil.
Just to add a bit more detail to @kaushalmodi's answer (and useful test case):
The raw argument lets you distinguish between arguments provided with universal-argument
and digit-argument
.
With a numeric prefix arg there is no way to distinguish the universal argument C-u
from a prefix arg of 4 (i.e. C-4
). With the raw argument these are different: (4)
vs 4
.
The same applies with negative-argument
. As a raw argument you can distinguish between C--
and C-- 1
: the first will give you -
while the second -1
. When converted to a numeric argument they will both be -1
.
So the benefit of using a raw argument is it gives you more possible values. You can write commands that behave differently depending on how the argument is specified.
As an example, take a look at the doc string for yank
. This command treats C-u
and C-4
differently:
With just C-u as argument, put point at beginning, and mark at end. With argument N, reinsert the Nth most recent kill.