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 at 14:26
  • That may be dangerous as I may errononeously close some non-written buffer, thus losing changes.
    – Barzi2001
    Apr 28 at 15:10

1 Answer 1

0

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 that you have read and understand our privacy policy and code of conduct.

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