The Universal Argument

Over at Wisdom and Wonder, Grant tells us how to move forward several spaces in the minibuffer. That's just 【Ctrl+u 1 0 0 Ctrl+f】, of course but Fuco (who wowed us by doing the last VimGolf in Emacs challenge in only 5 keystrokes) points out that really all you need is 【Ctrl+1+0+0+f】. I've been seeing this misunderstanding a lot lately, both in comments to my posts and in other Emacs-oriented blogs, so perhaps it's worth mentioning how the Universal Argument works.

The most useful thing to know is that you can give numeric arguments to commands by holding down 【Ctrl】 or 【Meta】 and typing the digits. That's why Fuco's method works. Notice how much more convenient it is: you merely hold down the 【Ctrl】 key and type the numeric argument and command. The same thing works with the 【Meta】 key. To delete the next five words, type 【Meta+5+d】. Much easier than 【Ctrl+u 5 Meta+d

The next thing to know is that if you don't type any digits after 【Ctrl+u】 the argument count is increased by a factor of 4. Thus 【Ctrl+u+p】 will move the point up four lines and 【Ctrl+u+u+p】 will move the point up 16 lines and so on.

Finally, the Universal Argument can act as a flag that tells the command to use an alternative behavior. Usually, the command will use

(interactive "P")

to get this behavior. Here's an example from my init.el file:

(defun jcs-datetime (arg)
  "Without argument: insert date as yyyy-mm-dd
With C-u: insert time
With C-u C-u: insert date and time"
  (interactive "P")
  (cond ((equal arg '(4)) (insert (format-time-string "%T")))
        ((equal arg '(16)) (insert (format-time-string "%Y-%m-%d %T")))
        (t (insert (format-time-string "%Y-%m-%d")))))

Notice that in this case the function sees the argument as (4), (16), and so on. Of course, unless you're writing Elisp code you don't have to worry about this case—the function writer has taken care of it for you and you just need to know that you need one or more 【Ctrl+u】 to get the desired alternative behavior.

This entry was posted in General and tagged . Bookmark the permalink.
  • Fuco

    Nice writeup! I'd only expand a bit on the C-u prefix when used as flag. When you execute C-u it sends (4) (a list with car = 4) to the command. However, when you do C-4 it sends just '4' (a number). Usually functions use (interactive "p") which is just short for (setq arg (prefix-numeric-value arg)) so it doesn't make any distinction. But with (interactive "P"), you can use C-u and C-4 as two different arguments.

    That's what I do in my smartparens package. If you supply C-u it is interpreted as "infinity argument" (which with "kill" function would mean "kill all up until the end of current list, however many things there are"), if you supply C-4 it's just good old "kill 4 things".

    So beware that some functions make this distinction. Usually it should be documented, so always check the docs if something weird happens :)

    • Fuco

      And another cool thing is use of "-1" argument. All you need is to hit C-- (that is control and minus sign) instead of C-u - 1 or C-- C-1. For example, to kill backward letter: C-- C-d (of course you can just hit backspace or what not). This is especially usefull for functions like "kill-sexp". While it has a backward version, I don't have a free key to bind it. So C-- M-C-k works just great :)

      Works with any function that accept negative arguments meaning "do stuff backwards".

      I really *love* the argument system. For a long time I haven't used it much but now I can't live without it. It is my humble opinion that it's one of the steps to truly master emacs and all its goodness.

      PS: you should really add an edit button if possible.

      • jcs

        No doubt about it, the argument system is really powerful. That's partly why I'm so surprised that people don't understand it better.

        I, of course, see an edit button but I don't know how to give it to everyone. Perhaps if you sign in? If anyone knows how WordPress handles this, leave a comment and I'll enable it.

  • Adam

    Why 4? Just curious.

    • jcs

      I don't think I've ever seen an explanation for that.

    • Phil

      I don't know the answer, but I suspect it was just selected as a "generally good amount". Fewer than four iterations would be approximately as quick to type without a prefix argument in many cases. It might also be relevant that 4 is a common number of spaces for indentation, and so quickly indenting a region with C-u C-i seemed like a good thing to be able to do. Lastly, if even numbers are more desirable than odd numbers, and if the 'multiplying' effect of additional C-u presses was always part of the mechanism, then the jumps from 4 to 16 to 64 are probably more useful than the much larger jumps from 6 -> 36 -> 216. In that context, 4 does seem like the best value.