💾 Archived View for republic.circumlunar.space › users › johngodlee › posts › 2021-05-15-nnn_mutt.gm… captured on 2023-06-14 at 14:50:27. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-03-20)
-=-=-=-=-=-=-
DATE: 2021-05-15
AUTHOR: John L. Godlee
In a previous post I talked about using vifm[1] as a filepicker within vim to choose files to attach to an email sent by the neomutt[2] email client.
I got an email from someone who had read that post, asking a few questions to get the system running properly. I hadn't actually used that workflow for some time, and when I tried to get it to run I found that it didn't work anymore. After some light debugging I realised that the problem was that I had switched to neovim[3], a fork of vim which aims to improve on vim in some areas where it has stagnated. One major difference between neovim and vim is that neovim can't do interactive 'bang' commands[4]. Instead everything has to be done through the :terminal buffer.
4: https://github.com/neovim/neovim/issues/1496
This problem led me down a rabbit hole to construct a better attachment picker for neovim.
I don't actually use vifm anymore. I find that I rarely need its split-panel capabilities. I generally use basic ls, mv, etc, and on the occasion I need to move multiple files with regex or whatever, I use vimv[5], a very simple bash script.
5: https://github.com/thameera/vimv
I do keep a version of the nnn file manager[6] on my system however, just in case. nnn is fast and minimal enough in its un-patched out of the box state that I never have to think about it. I found out that there is a nnn.vim plugin](https://github.com/mcchrish/nnn.vim[7]) that works very similar to the fzf.vim plugin[8] that I already use for quickly navigating files in vim. With some help from the maintainer of nnn.vim ([ see this issue
6: https://github.com/jarun/nnn
7: https://github.com/mcchrish/nnn.vim
8: https://github.com/junegunn/fzf.vim
First the nnn.vim plugin must be installed, for example with vim-plug: Plug 'mcchrish/nnn.vim'.
Then write a function to format the output of nnn.vim:
function! s:mutt_attach(lines) let prettylines = '' for i in a:lines let prettylines .= 'Attach: ' . fnameescape(i) . "\n" endfor 6put =prettylines endfunction
This function will get the filenames returned by nnn.vim, escape any special characters in those filenames with fnameescape(i), wrap the filenames with Attach: before the name and a newline after the name, then paste all the lines at the 6th line of the vim buffer, which is where the mutt headers are located by default.
Then, to call this function, it's necessary to write a custom nnn#pick function that itself can handle an external function as the edit command:
function! s:nnncall(...) let l:dir = get(a:, 1, '') let l:opts = get(a:, 2, { 'edit': 'edit' }) let l:keypress = get(a:, 3, '') call nnn#pick(l:dir, l:opts) if strlen(l:keypress) > 0 call feedkeys(l:keypress) endif endfunction
This is the bit I got from @mcchrish.
And finally write a file type specific mapping that only works in mail filetypes:
autocmd Filetype mail nnoremap <silent> <Leader>A :call <SID>nnncall('/Users/johngodlee', { 'edit': function('<SID>mutt_attach') })<CR>