13

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?

3 Answers 3

11

Hard to believe that people described this here without also giving you links to Emacs's own descriptions of this:

"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.

10

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.
5
  • Thanks. I get that sometimes it is better to get nil than 1, but never that having a wrapped int is preferable to an unwrapped int. (Can't upvote until I get 15 points, btw). Jul 10, 2015 at 20:37
  • @24HrRevengeTherapist: just up-voted ya', taking you past the magic 15 point threshold. Go out and do some up-voting on items that help you!
    – Dan
    Jul 10, 2015 at 21:29
  • 1
    It's not about wrapped vs unwrapped ints. It's not about ints at all. And +1 to @kaushalmodi for emphasizing that you can tell whether the user used a prefix arg only by using the raw arg (by checking whether the value is nil or not).
    – Drew
    Jul 10, 2015 at 22:38
  • What's the rationale for the C-u default argument being (4) and not, uhm, (42), 42, or perhaps -23? I ask because the (4) is often dutifully mentioned but rarely explained. My working hypothesis is that Stallman happened to have four bits of toilet paper left when he came up with it.
    – Christian
    Mar 11, 2022 at 18:16
  • My best guess is that 4 just hit the sweet spot for the use cases you might not be aware of: C-u is equal to (4), C-u C-u gives (16) and C-u C-u C-u gives (64) and so on. This number might be empirically derived where the early emacs dev found 3^2 = 9 to be too small a number and 5^2 = 25 too large. E.g. C-u C-u C-n will move the cursor down by 16 lines, which could be roughly half the screen height in olden times. Mar 11, 2022 at 22:23
7

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.