0

I am wondering if there is a way to automatically force-wipe all the running terminals when quitting Vim with :qa.

My attempt (that does not work):

vim9script

def WipeoutTerminals()
    for buf_nr in term_list()
        exe "bw! " .. buf_nr
    endfor
enddef

augroup shoutoff_terminals
    autocmd VimLeave * call WipeoutTerminals()
augroup END
2
  • How about :qa!?
    – romainl
    Apr 28, 2023 at 14:26
  • That may be dangerous as I may errononeously close some non-written buffer, thus losing changes.
    – Barzi2001
    Apr 28, 2023 at 15:10

2 Answers 2

1

use QuitPre or ExitPre instead of VimLeave

Doc says

Can be used to close any non-essential window

vim9script

def WipeoutTerminals()
    for buf_nr in term_list()
        exe "bw! " .. buf_nr
    endfor
enddef

augroup shoutoff_terminals
    autocmd QuitPre * call WipeoutTerminals()
augroup END
1

Here is something I did to leave automatically the "side bar".

Defined here as:

  • The terminal
  • The quickfix window
  • The NERDTree side bar
function! IsSideBar(buf_nr)
" Return 1 if the buffer correspond to a side bar: "
" - A terminal window "
" - The quickfix window "
" - The NERDTree side bar "
" - ... "
  let buf_name = bufname(a:buf_nr)
  let buf_type = getbufvar(a:buf_nr, '&filetype')
  let readonly = getbufvar(a:buf_nr, '&readonly')

  if !has('nvim')
    " Neovim doesn't support the term_list function "
    let term_buffers = term_list()
  else
    let term_buffers = []
  endif

  if buf_type ==# 'qf'
    " QuickFix, LocationList: "
    " Not Read Only "
    echom 'QuickFix'
    return 1

  " There are situation where the only buffer you have is help and you are "
  elseif buf_type ==# 'nerdtree'
    " Read Only "
    " echom 'NerdTree' "
    return 1

  elseif index(term_buffers, a:buf_nr) >= 0
    " echom 'Console' "
    return 1

  else
    return 0

  endif
endfunction

function! LeaveSideBar()
  " Go to a non side bar window "
  let loop = 0
  while 1
    let loop = loop + 1
    let bufnr = bufnr('%')

    if loop > 10
      " Don't search for more than 10 windows "
      " To handle the case all the windows are 'side bars' "
      break
    endif

    if IsSideBar(bufnr)
      wincmd w
    else
      break
    endif

  endwhile
endfunction

command! LeaveSideBar call LeaveSideBar()

function! GetNumWindows()
  let num_windows = 0

  " echom 'winnr($):' .. winnr('$') "

  for win_nr in range(1, winnr('$'))
    let buf_nr = winbufnr(win_nr)
    " echom "Analyze buffer: " . buf_nr "
    if IsSideBar(buf_nr)
      continue
    endif
    let num_windows = num_windows + 1
  endfor

  " echom 'Num Windows: ' . num_windows "
  return num_windows
endfunction

function! KillSideBars()
  let num_windows = GetNumWindows()
  " echom "Num windows: " . num_windows "
  if num_windows > 0
    " If there are non side bar windows do nothing "
    return
  endif

  " Debug "
  " return "

  " Delete the terminal buffers that don't correspond to a window "
  let term_buffers = term_list()
  for buf_nr in term_buffers
    " echom "what about terminal: " . buf_nr "
    if len(win_findbuf(buf_nr)) == 0
      " echom "delete terminal: " . buf_nr "
      execute 'bd! ' . buf_nr
    endif
  endfor

  let term_buffers = term_list()
  let buf_nr = bufnr('%')
  " echom "buffer: " . buf_nr "
  if index(term_buffers, buf_nr) >= 0
    " Kill the terminal buffer and quit "
    " echom "terminal buffer" "
    call feedkeys("\<C-w>:bd!\<CR>:quit\<CR>:\<BS>")
  endif
endfunction

" Close Vim if the last buffer is side bar: "
autocmd BufEnter * call KillSideBars()

I should adapt it for :qa but it quits Vim when the last buffer visible are side bars (it kill the terminals visible or not and the remaining side bars).

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.