4

The below dummy foo describes how I need the prefix variable setting to work.

I'd like the read-number prompt to show up only if the user entered C-u as prefix. In all other cases, the prefix will be read as (interactive "p") would usually do.

(defun foo (prefix)
  ;; (interactive "p") ??
  ;; (interactive (list (read-number "Num: "))) ??
  ;; Only if `C-u' prefix is used, show the prompt for user entry
  ;; else set PREFIX to user entered numeric prefix using
  ;; the C-0/C-1 or M-0/M-1 style.
  (message "prefix = %0d" prefix))
;; Desired outcome
;;  C-0 M-x foo => prefix = 0 (no prompt)
;;  M-6 M-x foo => prefix = 6 (no prompt)
;;  C-u M-x foo => Prompt appears => User enters 7 => prefix = 7
1

2 Answers 2

6

Here's a more elegant way of doing it:

(defun foo (arg)
  (interactive
   (list (if (consp current-prefix-arg)
             (read-number "Number: ")
           (prefix-numeric-value current-prefix-arg))))
  (message "prefix = %0d" arg))

current-prefix-arg holds the value you'd get from (interactive "P"). You can convert it to what (interactive "p") would return with prefix-numeric-value. Finally, the universal argument is represented as (4), (16), (64), etc., depending on the times you've hit C-u. It's tempting to use the listp predicate to detect it, but that would return t for no argument as nil and () are the same, so I'm using consp instead to explicitly test whether we've got a cons cell there.

1
  • Nice :) Learned something new!
    – clemera
    Oct 9, 2015 at 0:45
1

I'm not sure if this is the most elegant way but it does the job:

(defun foo (prefix)
  (interactive "P")
  (cond ((null prefix)
         (setq prefix 1))
        ((listp prefix)
         (setq prefix (read-number "Num: "))))
  (message "prefix = %0d" prefix))

The capital "P" in the interactive form means pass the prefix arg in it's raw form. This means it is nil without a prefix, a non empty list if you call it with C-u (called universal-argument) or numeric if you call it with C-1,M-3 and friends.

1
  • Thanks! This works. If we don't discover an inbuilt solution to handle such cases more elegantly, I will accept this as an answer. :) Oct 8, 2015 at 18:31

Your Answer

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

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