-1

I wish to close windows and wipe out the associated buffers with <c-w>q but at the same time I want to prevent to quit Vim when there is only one window left.

My attempt is as follows:

vim9script
def QuitWindow()
    # Close window and wipe buffer but prevent Vim to quit if one window is
    # left.
   if winnr('$') != 1
      quit
   endif
enddef

nnoremap <c-w>q <Cmd>call QuitWindow()<cr>
nnoremap <c-w><c-q> <Cmd>call QuitWindow()<cr>

but then QuitWindow() is correctly not recognised and I am not sure how to do for recognising a function when it is defined in .vimrc and is not defined as global.

Perhaps this is not the right direction for achieving my goal?

11
  • Simple. If you don't want Vim to quit when you press <C-w>q and there's only one window… don't press <C-w>q when there is only one window. Also, the RHS of a normal mode mapping is a normal mode macro: use :call … or <Cmd>call ….
    – romainl
    May 31, 2023 at 15:19
  • Please re-read :help <Cmd>.
    – romainl
    May 31, 2023 at 15:25
  • The first part of your comment is of no utility at all. The second part makes more sense and I realised that I missed a <Cmd> but then another problem arise and therefore I updated my question as the objective is not reached yet.
    – Barzi2001
    May 31, 2023 at 15:27
  • Again, :help <Cmd>.
    – romainl
    May 31, 2023 at 15:30
  • 1
    For a solution, how about scrolling a little bit downward to :help <ScriptCmd>?
    – romainl
    May 31, 2023 at 15:41

2 Answers 2

2

For the sake of completeness and as requested by a user, here is the solution that I am currently using (based on a user comment):

vim9script
def QuitWindow()
    # Close window and wipe buffer but prevent Vim to quit if one window is
    # left.
   if winnr('$') != 1
      quit
   endif
enddef

nnoremap <c-w>q <ScriptCmd>call QuitWindow()<cr>
nnoremap <c-w><c-q> <ScriptCmd>call QuitWindow()<cr>

The trick was in using :h <ScriptCmd> that allow you to define mappings in the context of scripts. Note that in my case a QuitWindow() has script scope. Alternatively, I could have used a global scope for QuitWindow(), i.e. g:QuitWindow() but that would have polluted the global namespace.

1

I would do:

vim9script

def g:QuitWindow()
    # Close window and wipe buffer but prevent Vim to quit if one window is
    # left.
   if winnr('$') != 1
      quit
   endif
enddef

nnoremap <c-w>q <Cmd>call g:QuitWindow()<CR>
4
  • That is what I was thinking to do, but I would avoid polluting the global namespace :) But perhaps it is the only way?
    – Barzi2001
    May 31, 2023 at 15:37
  • 1
    For the mapping to work they need a global function unless you put the function statements into the mapping. May 31, 2023 at 15:39
  • 2
    <ScriptCmd> is another solution (actually the one I prefer) as someone pointed out in another comment. Thanks for your effort anyways :)
    – Barzi2001
    May 31, 2023 at 15:53
  • 1
    You are welcome :-) Publish your solution. I'll be happy to read it. May 31, 2023 at 16:40

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.