I have the following python code stored in my $HOME/bin/email-process


from sys import argv

# open up the email contents file
infile = open(argv[1], 'r')

# read it into an array of strings w/o new lines
body = [line.rstrip('\n') for line in infile]

# close the input file

# returns if a line is OK to join with one above it
# all but blank lines,
# those that start with a > (because they are quotes)
# ones starting with space (because they are blocks of code e.g.)
def line_joinable(line):
    if len(line) == 0:
        return False
    if line[0] == '>':
        return False
    if line[0] in [' ', '\t']:
        return False
    return True

# go through each line 
i = 0
while i < (len(body) - 1):
    line = body[i]
    next_line = body[i + 1]

    # if both lines are joinable, join them
    if line_joinable(line) and line_joinable(next_line):
        body[i] = body[i] + ' ' + body[i + 1]
        del body[i + 1]
        i += 1

# open the output file to overwrite it in place
outfile = open(argv[1], 'w')
for line in body:
    outfile.write("%s\n" % line)

What it does is take a file as input argument and remove line-breaks unless the line has an indentation, keyword (pertaining to Subject, From, To, Cc, Bcc, etc). Ideal for typing out an email in nvim that has settings set at say 72 characters, so pleasant to read/edit while typing, because this code converts into free-flowing text for easier reading on all devices. Details are here: https://ianfinlayson.net/posts/10-mutt however, I think that the solution there (to go through every file in /tmp/mutt-*) is unnecessary and (what is worse) does not work with nvim. However, while unncessary, it does work with vim because I have tried it there, and it works.

I use mutt and nvim as editor. What I would like to do is to, after exiting the editor and before it gets saved as an attachment on mutt go through this program. How do I do this? I know that I can edit $HOME/.vim/ftplugin/mail.vim but I can not figure out how to do this with either lua or vimscript. I do know that I have to invoke an autocmd and VimLeave but I can not figure out how to process the particular file that has been saved by :wq to be piped through the email-process code.


I tried the following:

augroup autocom
    "executes the command on quit
     autocmd VimLeave /tmp/mutt-* !/home/finlayson/bin/email-process %
/bin/email-process %
augroup END

This gives, on the mutt window:

Error running "/usr/bin/nvim '/tmp/mutt-localhost-1000-336530-16967570324965601212'"!

But apppears to do the work. But the error message on the window is not relevant and does not pertain to the filename just edited. I guess the problem is that the python script email-process is being run on more files than just the one that has been created and edited. Is it possible to (1) get rid of the error message and (2) more importantly, only restrict the script to the file that was edited?

Instead therefore, I tried the following:

augroup autocom
    "executes the command on write
     autocmd BufWritePost,FileWritePost /tmp/mutt-* !/home/finlayson/bin/email-process %
augroup END

Now, I do not get an error when I do :w (and watch the formatting happen, that is a bit cool) and then :q but I get the error when I do :wq so what is the issue here?

Any suggestions?

  • 1
    I would suggest trying to figure out what doesn’t work in neovim, since it works in Vim.
    – D. Ben Knoble
    Nov 20, 2023 at 15:53
  • Judging from this and your other recent question it seems some of the features that are supposed to work out of the box aren't working in your NeoVim installation. I'm just guessing but they might be symptoms of a bigger problem. Maybe start from a clean installation and add things little by little?
    – Friedrich
    Nov 21, 2023 at 7:01
  • @D.BenKnoble, illustrated with an update on what I have found sort of works, and what does not. Nov 21, 2023 at 14:15
  • If you can write the program to operate on stdin/stdout, you could set it up as a formatprg or just use :%!prog
    – D. Ben Knoble
    Nov 21, 2023 at 17:26
  • @D.BenKnoble, thanks! Can you please point me to how to write a .vimrc to get %!prog work with an external scriipt automatically on write or quit? Nov 22, 2023 at 4:13

1 Answer 1


I suggest a simpler version:

  • write the script as a filter that transforms stdin to stdout
  • establish a BufWritePre autocommand that does the transformation in the usual way (:help :range!)

The autocommand would look like

augroup mail_format | autocmd!
  autocmd BufWritePre /tmp/mutt-* %!/path/to/script
auground end
  • What is the difference between BufWritePre and BufWritePost? I did try this out, btw, but got errors. In the same manner as mentioned above. Dec 23, 2023 at 15:22
  • @user3236841 well, BufWritePre has a chance to make modifications before the write takes place?
    – D. Ben Knoble
    Dec 24, 2023 at 1:16

Your Answer

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

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