質問

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 quitfrom 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>

他のヒント

I think you could map F3 to a function that does this sort of thing: (pseudocode)

try:
    quit
catch error 37:
    intercept next keystroke
    if it's F3:
        force quit
    else:
        send key back to vim

I don't know all the details, but I'm pretty sure you can do all of those things with :try, :catch, getchar() (iffy on this one, not sure if it'll work for special keys like F3) and feedkeys(). See the :help for each of those things.

Seems a little bit much, though. Why not make a separate mapping for :q!?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top