2

Sometimes it would be useful to be able to pass an expression to a prefix argument, for example

c-u 3*4 c-n

If I try the command above though it will print three asterisks followed by the '4' character then cursor-down.

Is there something I can do so the prefix argument can be the value of an expression?

1
  • 1
    I don't think that is possible without rebind C-u ; according to the documentation : Begin a numeric argument for the following command. Digits or minus sign following C-u make up the numeric argument. C-u following the digits or minus sign ends the argument.
    – flav
    Commented Feb 5, 2021 at 8:17

1 Answer 1

3

There's no convenient interface for that.

For some simple operations, you can make use of two facts:

  • Using C-u with no number gives you powers of 4. C-u C-n moves 4 lines down, C-u c-u C-n moves 16 lines down, etc. (There are rare exceptions with commands that treat the no-number case differently.)
  • The prefix argument is usually a repeat count, so you can do additions by repeating the command.

If you want a complex calculation, you can use M-: (eval-expression) to call the command. First, if you need to, look up the command name by pressing C-h c (or f1 c) and the keyboard shortcut you meant to invoke. To copy-paste the command name, switch to the *Messages* buffer, or alternatively use C-h k rather than C-h c and switch to the *Help* buffer. Then invoke eval-expression with M-: and specify M-: (the-command-name (the-argument-expression)). This assumes that the prefix argument is the sole argument to the function, which is often but not always the case: check the function's documentation.

Another approach, which works regardless of how the command consumes its prefix argument, is to set prefix-arg explicitly. invoke eval-expression with M-: and specify M-: (setq prefix-arg (the-argument-expression)), then immediately invoke the command. Under the hood, commands read the prefix argument from current-prefix-arg. Between each interactive command, Emacs sets current-prefix-arg to the value of prefix-arg and resets prefix-arg to nil.

1
  • This is an excellent solution. Yes, I can make a command such as (goto-line (* 3 4)), or elaborate on that idea as much as I like, eg (goto-line (+(* row 4)5)) to offset the start of the blocked text in the file, for example. Thank you. Commented Feb 6, 2021 at 16:13

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.