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)
Or to run a shell command
foo on a file:
(defun foo-file (file)
(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