# Is there an easy way to detect how many `C-u`s a command was given?

I have made the following function to count how many `C-u` prefixes a command was given (assuming it is called interactively), but I feel this is a common-enough problem that there should be a built-in function (or a package that solves this problem more robustly). Is there a better way to do this?

``````(defun tmp:how-many (arg)
;; Return zero if `arg' is 1 or nil
(if (or (null arg) (equal arg 1)) 0
;; If `arg' is a list (as it is when called interactively), extract
;; the number.
(when (listp arg)
(setq arg (car arg)))
;; Recurse
(if arg
(1+ (tmp:how-many (/ arg 4)))
0)))

(defun tmp:test (arg)
(interactive "P")
(message "%S" (tmp:how-many arg)))
``````
• I simply use a cl-case statement of 4,16,64,.., t. In absence of prefix, the 't' case will be evaluated. – Kaushal Modi Dec 6 '14 at 18:59
• If you are asking about practical uses then I think it makes little sense to look for handling an arbitrary number of `C-u`s. If you are expecting users to use more than, say, five `C-u`s then you are probably really stretching it. In practice, from zero to three is plenty. And in any case you need to distinguish the cases, whether you test 1, 2, 3 or 4, 16, 64. – Drew Dec 9 '14 at 4:57
• @Drew Absolutely agree on all counts. As with a lot of my questions (here and elsewhere), this one arises from sheer curiosity – not necessarily any overtly practical application. Still, I think the answers below are generally useful :) – Sean Allred Dec 9 '14 at 5:12

I will assume that you want to distinguish only uses of a plain prefix arg, e.g., `C-u`, `C-u C-u`, `C-u C-u C-u`, etc., and not uses of a numeric prefix arg, e.g., `C-u 23`, `C-9`, `C-- 5`.

Test both, in order:

1. Whether the value of `current-prefix-arg` is a cons, using `consp`. If not, then a plain prefix arg was not used.

2. The `prefix-numeric-value` of `current-prefix-arg`, to see which power of 4 it is.

For example:

``````(if (consp current-prefix-arg)
(case (prefix-numeric-value current-prefix-arg)
(4   (do-C-u-stuff))
(16  (do-C-u-C-u-stuff))
(64  (do-C-u-C-u-C-u-stuff))
...)
...) ; Do something for absent prefix arg or non-plain prefix arg
``````

`case` is a macro from the CL libraries. Use `(eval-when-compile '(require 'cl))`. (Or you can use `cl-case`, if your Emacs version has it.)

• Is there an alternative for `case` from `cl-lib`? – Sean Allred Dec 7 '14 at 15:09
• Yes, `cl-case` is the same thing. – Drew Dec 7 '14 at 15:56
• @Sean The hyperlink in my comment to your question takes you to an example of `cl-case` use. – Kaushal Modi Dec 8 '14 at 0:29
• I'm going to accept this answer because it more fully addresses how one would handle prefix args, but I think it should be used in conjunction with my logarithm trick for clarity of code :) thanks! – Sean Allred Dec 9 '14 at 4:01
• Note that an absent prefix argument (`nil`) is returned as `1` by `prefix-argument-numeric-value` – Sean Allred Dec 9 '14 at 4:03

Assuming you only want to understand arguments given using only `C-u`, you can use a base-four logarithm:

``````(defun tmp:how-many (arg)
(when (consp arg)
(truncate
(log (car arg) 4))))
``````

Note that such a function is doomed to fail if a sequence like `C-3 M-x tmp:test` is used; the only appropriate response to such usage is to signal an error or return `nil`, which was what I do here. (Returning `arg` would imply ambiguous results between, e.g., `C-3 M-x tmp:test` and `C-u C-u C-u M-x tmp:test`.)

• +1 for a logarithm with base 4! I wish I could give a +2 for extreme cleverness. Only minor suggestion would be to wrap the `log` in a `truncate`, since `log` returns a float and you probably want an integer. – Dan Dec 6 '14 at 22:14
• @Dan ah, yes! Good idea :) – Sean Allred Dec 6 '14 at 22:15