1

I have modified a function from CKolkey's dotfiles - ToggleTerminalDrawer (line 230) so that it works for Vim8.2 (instead of neovim). Here is my modified function now in my vimrc:

nnoremap <silent><leader>/           :call ToggleTerminalDrawer()<CR>
tnoremap <silent><leader>/ <C-\><C-n>:call ToggleTerminalDrawer()<CR>

let g:terminal_drawer = { 'win_id': v:null, 'buffer_id': v:null }
function! ToggleTerminalDrawer() abort
  if win_gotoid(g:terminal_drawer.win_id)
    hide
    set laststatus=2 showmode ruler
  else
    botright new
    if !g:terminal_drawer.buffer_id
      call term_start($SHELL)
      let g:terminal_drawer.buffer_id = bufnr("")
    else
      exec "buffer" g:terminal_drawer.buffer_id
      call RemoveEmptyBuffers()
    endif

    exec "resize" float2nr(&lines * 0.25)
    setlocal laststatus=0 noshowmode noruler
    setlocal nobuflisted
    startinsert!
    let g:terminal_drawer.win_id = win_getid()

  endif
endfunction

function! RemoveEmptyBuffers()
  let buffers = filter(range(1, bufnr('$')), 'buflisted(v:val) && empty(bufname(v:val)) && bufwinnr(v:val)<0 && !getbufvar(v:val, "&mod")')
  if !empty(buffers)
      silent exe 'bw ' . join(buffers, ' ')
  endif
endfunction

This works great most of the time. It toggles a terminal pane at the bottom of the editor, and always uses the same terminal buffer.

However, when the toggle is run and a Terminal buffer doesn't yet exist, it creates one terminal buffer (good, intended) and an extra blank buffer editor which I can write in - this is unintended. When this happens I always have to do :q to get rid of it. How do I modify this function to not cause that side effect?

2
  • 2
    I'm wondering if it's because of botright new in the else?
    – D. Ben Knoble
    Apr 10 '20 at 20:59
  • 1
    @D.BenKnoble your comment pointed me along the right lines - removing botright new and replacing with direct botright calls when the Terminal is created/toggled fixed it. Thanks.
    – Tom Oakley
    Apr 12 '20 at 13:28
1

Fixed by removing botright new and then calling botright call term_start($SHELL) (to start a Terminal buffer if one doesn't exist) or execute 'botright sbuffer' . g:terminal_drawer.buffer_id (to show the buffer) fixed it. Here is the full function now:

let g:terminal_drawer = { 'win_id': v:null, 'buffer_id': v:null }
function! ToggleTerminalDrawer() abort
  if win_gotoid(g:terminal_drawer.win_id)
    hide
    set laststatus=2 showmode ruler
  else
    if !g:terminal_drawer.buffer_id
      botright call term_start($SHELL)
      let g:terminal_drawer.buffer_id = bufnr("$")
    else
      execute 'botright sbuffer' . g:terminal_drawer.buffer_id
      exec 'normal! i'
    endif

    exec "resize" float2nr(&lines * 0.25)
    setlocal laststatus=0 noshowmode noruler
    setlocal nobuflisted
    let g:terminal_drawer.win_id = win_getid()

  endif
endfunction

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.