8

I want to check file before quitinq vim with custom functions, everything seems fine with QuitPre autocommand except using ZZ to exit. In this case the output is missing.

Consider following function declaration and autocommand in file function.vim

au QuitPre * call CheckBeforeQuit()

function CheckBeforeQuit()
  echo 'Hello'
  echo 'World'
  call input('Press enter')
endfunction

And now when I open file tmp with this command

vim tmp -u NONE -c 'source function.vim'

and then type :x, the output Hello\nWord along with prompt message is visible. If I use ZZ instead, the message from echo is missing. According to help ZZ is the same as :x.

Of course I could remap ZZ to :x and everything is fine now. But anyway I would like to know what is causing this difference and how I could deal with that in my function.

  • 2
    Interesting, from the source code, we can see that it's calling directly the :x normal command: github.com/vim/vim/blob/… It will require more investigation because AFAIK it shouldn't remove the messages. – nobe4 Jan 16 '17 at 17:27
  • 2
    I don't think it has anything to do with differences between ZZ and :x, but rather it's a difference between how normal and ex-mode commands show output. With ex-mode (command mode), you see the whole output. With normal command, you only see the last line (unless your mapping also enters command mode). – Thunderbeef Oct 9 '19 at 23:14
0

Thunderbeef explained in the comments that this is caused by the difference in the way normal and command-line commands show output. With a command-line command, you see the whole output, but with a normal command, you only see the last line.

You can work around this limitation by displaying all the desired output from your call to input(), which allows you to include newlines in its prompt:

function CheckBeforeQuit()
  call input("Hello\nWorld\nPress enter")
endfunction

If your Hello and World strings are not hard-coded, but are actually generated within the function, you can instead build a string to pass to input():

function CheckBeforeQuit()
  let quit_notification = 'Hello'
  let quit_notification .= "\n" . 'World'
  let quit_notification .= "\n" . 'Press enter'

  call input(quit_notification)
endfunction

If your Hello and World aren't actually strings at all, but instead result from the output of other commands, then you can capture these in your message by using the execute() function:

function CheckBeforeQuit()
  let quit_notification = execute('echo "Hello"')
  let quit_notification .= execute('echo "World"')
  let quit_notification .= "\n" . 'Press enter'

  call input(quit_notification)
endfunction
  • thank you Rich and @Thunderbeef for replying to question which hanged out for quite long time. – mrajner Jan 24 at 0:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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