As you seem to have already noticed, a function need the interactive
form before it can be bound to a key. interactive
doesn't just tell Emacs the function is a command, it is also tells Emacs where to get the functions arguments from. From C-h f interactive
:
Specify a way of parsing arguments for interactive use of a function.
For example, write
(defun foo (arg buf) "Doc string" (interactive "P\nbbuffer: ") .... )
to make ARG be the raw prefix argument, and set BUF to an existing buffer,
when ‘foo’ is called as a command.
A typical case is (interactive c)
where c
is a single-letter string describe the type of argument you expect. "f" means "existing file".
An example function would then be
(defun test-command (file)
(interactive "f")
(message file))
Or to run a shell command foo
on a file:
(defun foo-file (file)
(interactive "f")
(shell-command (format "foo %s" (shell-quote-argument file))))
Notice that we wrap the file name with shell-quote-argument
which will quote the file name so that it's safer to call shell commands on it in case your file names have spaces or special shell characters. Safety First. (thanks @YoungFrog for the suggestion)
Bind it to a key and call it. Emacs will prompt you for a file name in the usual way, using whatever kind of completion you have set up, and then pass the name (as a string) into the function as file
.
(interactive)
form