What @lawlist is describing in the comment can be implemented by writing a function to do whatever it it that you want to do and then by modifying the kill-emacs-hook
to execute the function when the hook is run.
TL;DR
Add this to your emacs init file:
;; define a function that runs the given command line
(defun email-cleanup ()
(call-process-shell-command "/home/username/bin/email-process /tmp/mutt-*"))
;; add the above function to the hook
(add-hook 'kill-emacs-hook #'email-cleanup)
Although I copied the path of the executable from your question, you will probably have to modify it (at least the username
part) to fit your setup.
I've tested with a dummy script and it works; but if you run into problems, let me know in a comment and I'll try to sort it.
A more detailed explanation
Hooks are variables whose value is a list of functions. Running the hook
evaluates each function in the hook in sequence. Emacs defines many different hooks for different operations. You can get a list by saying C-h v -hook TAB
(and maybe wait a few seconds: it's a long list). Each of those hooks is run under very specific circumstances. It is one of the most important methods of customizing emacs behavior, so it is worth familiarizing yourself with them.
In this particular case, you want to find a hook that is run when emacs exits. Look in the Exiting Emacs
section of the Emacs manual: the best way to do that is by asking Emacs itself: C-h i g(emacs)Exiting
- learning how to use the built-in documentation is probably the best thing you can do to make your life easier and more pleasant while using Emacs. See where it says
To further customize what happens when Emacs is exiting, see *note
(elisp)Killing Emacs::.
That is a link so you can click on it. You'll see the description of kill-emacs-hook
on that page. That's how you find (or at least that's one way to find) the hook you want.
Once you've found the hook, the next thing is to write a function to do what you want. In this case, you want to write a function that executes a shell command: that's why @lawlist in the comment mentions start-process
and call-process
: they are ways to execute an external program from inside emacs (similar to vi's !
mechanism). In this case however, you will want to run a shell in order to expand the glob in the argument to a full list of matching files. The best function to use then is call-process-shell-command
(see its doc string with C-h f call-process-shell-command
): the more basic ones (call-process
and start-process
exec the program directly, so there is no shell to do the expansion).
So the function email-cleanup
defined above runs a shell and gives it the command line in the function. The shell expands the glob and runs the program with that expanded list of arguments.
Then all we have to do is add the function to the hook.
EDIT: It turns out that the OP's script only handles one file for each invocation, so it cannot be invoked from the shell as email-process /tmp/mutt-*
and expect to handle more that one file. It has to be invoked as for f in /tmp/mutt-* ;do email-process $f ;done
. It also overwrites its input file with its output (which is generally a bad idea IMO, but I'm not addressing that in this comment).
So try with this function:
(defun email-cleanup ()
(call-process-shell-command "for f in /tmp/mutt-* ;do /home/username/bin/email-process $f ;done"))
Personally, I would change the script to loop over its arguments and go back to the first form of the function, but that's out of scope for this question.
If this still does not work, then please tell me the exact form of the command you execute in the shell so that it does what you want. All of this has nothing to do with emacs of course: it is how your script has to be invoked from the shell.
kill-emacs-hook
to which you could attach your own custom command, whether that be a shell script, astart-process
function with custom command, acall-process
function with a custom command, etc. ....file-name
(unless you happen to create one), but there is an accessor function namedbuffer-file-name
. Called with no arguments, like(buffer-file-name)
, it returns the name of the file visited by the current buffer, if the current buffer is visiting a file. I think that you will want your hook function to examine all buffers, so you will want to write code that looks like(dolist (buffer (buffer-list)) (when (string-prefix-p "/tmp/mutt-" (buffer-file-name buffer)) …)
. Once you get this working, make sure you post it as an answer!