From years of "finger memory" my hands know that F2 is save and F3 is quit (leftovers from years of IBM editors). Consequently my first vim key mappings were to get F2 and F3 doing what they're supposed to do. In particular for F3:
:map <F3> :q<CR>
:map! <ESC>:q<CR>
If I quit a file that has edits I still get the E37: No write since last change (add ! to override)
. What I'd prefer is more a function that would emit E37: No write since last change. Press F3 again to really quit.)
How would I code this?
Updated Solution Suggestion
It was pointed out to me that I could have used confirm
to accomplist this task. I "knew" I'd seen some built-in solution before but i couldn't remember it. Note, however, confirm
's sense is sense is inverted from the macro's, i.e. it offers "Yes, keep changes" while the macro offers "yes, discard changes." I'd have settled for confirm` if only it had been suggested earlier.
What I Actually Did
First, thanks @Jamie Schembri for the starting example. Always good to have an example when learning a new scripting language.
Here is the macro as I finally used it. Yes, it does not quite parallel the requirements. I replaced the second F3 with a Yes|No|Write choice which just felt better. I also had to add a nr2char() so the test for letters would work. I also had to delete one of the CR's from the :map
.
UPDATE see this question for a solution using this macro with added functionality to handle tagstack
files. If you quit
from a file in the tagstack
, vim closes all your files.
function! QuitF3()
try
quit
catch /E37:/
" Unwritten changes.
echo "E37: Discard changes? Y|y = Yes, N|n = No, W|w = Write"
let ans = nr2char( getchar() )
if ans == "y" || ans == "Y"
quit!
elseif ans == "w" || ans == "W"
write
else
call feedkeys('\<ESC>')
endif
endtry
endfunction
Referring to pandubear's answer, I wrote a quirky little function which seems to do what you want.
function! QuitF3()
try
quit
catch /E37:/
" Unwritten changes.
echo "E37: No write since last change. Press F3 again to really quit."
if getchar() == "\<F3>"
quit!
else
" Close prompt.
call feedkeys('\<ESC>')
endif
endtry
endfunction
map <F3> :call QuitF3()<CR><CR>