1

I am doing a test with the current prefix argument to perform different tasks depending on the value of the current prefix argument.

I have a few questions.

  1. Does (interactive "P") require use of a function argument?
  2. What happens when one uses just a prefix argument versus having it optional?
  3. When should any conditions for current-prefix-arg be inserted
    inside the interactive expression?

Here is a test

(defun mytest (&optional prefix)
  "Testing prefix argument."

  (interactive "P")

  (cond
    ((equal current-prefix-arg nil)   ; no C-u
     (message "no C-u"))
    ((equal current-prefix-arg '(4))  ; C-u
     (arktika-automated-workbench))
    ((equal current-prefix-arg 1)     ; C-u 1
     (message "C-u 1"))
    ((equal current-prefix-arg 2)     ; C-u 2
     (message "C-u 2")) ))
2
  • Question does not show any research effort...hence a down-vote. Commented Jul 2, 2022 at 22:09
  • Question is highly relevant for a beginner elisp programmer...hence an up-vote. The special form interactive is not intuitive, given that it looks like function call but isn't. Commented Jul 3, 2022 at 10:26

1 Answer 1

3

You should consider that interactive functions can also get called non-interactively. So this is where the 'interactive' form comes in; the arguments passed via interactive are only passed when calling the function (i.e. now a command) interactively (because it is not possible to otherwise pass arguments when calling interactively).

There is no way to optionally pass an argument via the interactive form. When calling a function interactively all 'interactive arguments' always get passed having either a non-nil value, or otherwise the value nil, and it will always be a fixed number of arguments. So if some argument is optional, this is (more or less) only relevant for when calling the function non-interactively.

When calling functions non-interactively, passing optional arguments is, well, optional. If you do not pass the optional arguments then they will get the value nil.

The current-prefix-arg can be used when passing a list as 'arg-descriptor'. If what you'd like to do can be achieved with a string arg-descriptor then that is usually the way to go. Otherwise, you can give a list as arg-descriptor (more info here).

6
  • I had no problems in understanding for non-interactive functions. I wish there was detailed information with a quite comprehensive list examples in the elisp manual.
    – Dilna
    Commented Jul 3, 2022 at 11:05
  • I can tell you about my confusion. You seem to imply that whenever one wants to pass arguments when calling the function interactively, one has to use the interactive call with code characters, or as a list of sorts. Nevertheless, I can also populate the variables outside the interactive call by calling minibuffer selections within the function body and make the function do the same things as if the calls were made within the interactive call. If I call the function non-interactively, calls to completing-read and read-from-minibuffer still work.
    – Dilna
    Commented Jul 3, 2022 at 11:21
  • It is occurring to me that I should not use things like completing-read or read-from-minibuffer outside the interactive expression, even though they would work in non-interactive modes..
    – Dilna
    Commented Jul 3, 2022 at 11:51
  • I am not implying that, but instead it is a statement. One can indeed achieve similar things with setting values of local variables interactively, but in that case you are not passing arguments. So using the interactive form IS the only way to pass arguments, although indeed you achieve more or less the same effect with setting values of local variables. Technically, you should use completing-read and read-from-minibuffer if you'd also like to set values interactively while calling the function non-interactively, but indeed I am not sure if in practice that is ever desired. Commented Jul 4, 2022 at 15:12
  • Right, in that case I am not passing variables. My headache starts when calling the function non-interactively. Because it would still behave as if it was interactive, when called in lisp code. I agree, that it would not be something to be desired. I think that allowing it would be a mistake and the function should be defined an interactive-only. Still, declaring a function interactive-only has no operational effect, and the function would still run, expecting input from the minibuffer nonetheless.
    – Dilna
    Commented Jul 4, 2022 at 19:40

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.