Reputation: 4406
In ELISP, the documentation for interactive
codes mentions:
P -- Prefix arg in raw form. Does not do I/O. ... s -- Arbitrary text, read in the minibuffer and returned as a string ... Prompt.
I presumed that I could write a function with an optional prefix argument, as in:
(defun some-function (&optional prefix)
(interactive "P")
...
)
or a function with user input, as in:
(defun some-function (user-argument)
(interactive "sProvide an argument: ")
...
)
but not both. Then I found the Org-mode function org-match-sparse-tree
, which I can call with C-u C-c \
, where the prefix argument restricts the match to open org-mode headings and I am still prompted for a match. The source code is below and I cannot find how the variable match
is assigned:
(defun org-match-sparse-tree (&optional todo-only match)
"..."
(interactive "P")
(org-agenda-prepare-buffers (list (current-buffer)))
(let ((org--matcher-tags-todo-only todo-only))
(org-scan-tags 'sparse-tree (cdr (org-make-tags-matcher match))
org--matcher-tags-todo-only)))
How does this function take both prefix argument and user input?
Upvotes: 3
Views: 1146
Reputation: 73274
How does this function [interactively] take both prefix argument and user input?
It doesn't -- the match
argument is not obtained, and is therefore nil
. What you're seeing is the effect of the subsequent call to (org-make-tags-matcher match)
with that nil
value as the argument:
(defun org-make-tags-matcher (match)
"..."
(unless match
;; Get a new match request, with completion against the global
;; tags table and the local tags in current buffer.
(let ((org-last-tags-completion-table
(org-tag-add-to-alist
(org-get-buffer-tags)
(org-global-tags-completion-table))))
(setq match
(completing-read
"Match: "
'org-tags-completion-function nil nil nil 'org-tags-history))))
...)
Functions can take multiple interactive
arguments, though.
See C-hf interactive
To pass several arguments to the command, concatenate the individual strings, separating them by newline characters.
The very first example in that help demonstrates this:
(defun foo (arg buf) "Doc string" (interactive "P\nbbuffer: ") .... )
This is elaborated upon at (elisp)Using Interactive
-- up one level in the documentation you'd linked to:
It may be a string; its contents are a sequence of elements
separated by newlines, one for each argument(1). Each element
consists of a code character (*note Interactive Codes::) optionally
followed by a prompt (which some code characters use and some
ignore). Here is an example:
(interactive "P\nbFrobnicate buffer: ")
The code letter ‘P’ sets the command’s first argument to the raw
command prefix (*note Prefix Command Arguments::). ‘bFrobnicate
buffer: ’ prompts the user with ‘Frobnicate buffer: ’ to enter the
name of an existing buffer, which becomes the second and final
argument.
You should read that documentation fully, though -- there are more sophisticated things you can do, including writing arbitrary elisp to produce the interactive arguments (which may or may not involve prompting the user).
Upvotes: 5