tpope / vim-unimpaired

unimpaired.vim: Pairs of handy bracket mappings
https://www.vim.org/scripts/script.php?script_id=1590
3.31k stars 205 forks source link

Toggle quickfix list #97

Open rightaway opened 9 years ago

rightaway commented 9 years ago

Using the co mappings would it be possible to include mappings to toggle the quickfix list, location list, etc? Something like coq for example?

gauteh commented 7 years ago

http://vim.1045645.n5.nabble.com/detecting-whether-the-quickfix-window-is-open-td1155292.html

function! QuickFix_toggle()
    for i in range(1, winnr('$'))
        let bnum = winbufnr(i)
        if getbufvar(bnum, '&buftype') == 'quickfix'
            cclose
            return
        endif
    endfor

    copen
endfunction

nnoremap <silent> coq :call QuickFix_toggle()<cr>
teoljungberg commented 6 years ago

I've been using something similar in my configuration, and I have quite enjoyed it. Any change of getting this merged upstream? I could gladly suggest a PR if we have an implementation that is considered stable enough.

teoljungberg commented 6 years ago

The same approach could probably be used for the location list aswell.

It would be nice if the mappings would be consistent, as [q and ]q traverse the quickfix list. coq (or =oq which is the new style of toggle mappings for unimpaired) could toggle the quickfix list.

That leaves the location list, which acts differently from the quickfix list in that :lopen does not open the window if it's not populated. And that [land ]l currently enable/disable the :list. And col (or =ol is occupied by toggling the list option.

Any thoughts on the matter @tpope? Is this something that you feel go inline with unimpaired?

gauteh commented 6 years ago

Things got more complicated with other plugins, e.g. dispatch or vimtex; currently these functions have evolved to (also for location list):

" Toggle quickfix window
function! QuickFix_toggle(disp)
  for i in range(1, winnr('$'))
    let bnum = winbufnr(i)
    if getbufvar(bnum, '&buftype') == 'quickfix'
      cclose
      return
    endif
  endfor

  if a:disp == 1
    Copen " from dispatch
  else
    if exists("b:vimtex")
      VimtexErrors
    else
      copen
    endif
  endif
endfunction

nnoremap <silent> coq :call QuickFix_toggle(0)<cr>
nnoremap <silent> cod :call QuickFix_toggle(1)<cr>

function! s:BufferCount() abort
    return len(filter(range(1, bufnr('$')), 'buflisted(v:val)'))
endfunction

" Toggle Location List window
function! Location_toggle()
  " https://github.com/Valloric/ListToggle/blob/master/plugin/listtoggle.vim
  let buffer_count_before = s:BufferCount()

  " Location list can't be closed if there's cursor in it, so we need
  " to call lclose twice to move cursor to the main pane
  silent! lclose
  silent! lclose

  if s:BufferCount() == buffer_count_before
    lopen
  endif
endfunction

nnoremap <silent> coe :call Location_toggle()<cr>
tpope commented 6 years ago

I guess my main objection is I'm not sold on the maps. There are some okay compromises for :copen, but l is both a motion and a =o option, nowhere to stick it really.

I'm half tempted to use 1]C and 1]L, since :clast and :llast with counts are identical to :cfirst and :lfirst. But in addition to being weird af, that's almost as hard to type as :cope<CR>. Oh, and it only gives us a toggle, when ideally we'd have an open and close too.

BestFriendChris commented 6 years ago

I personally haven't needed a toggle command since I added these mappings:

][q :copen
[]q :cclose
][l :lopen
[]l :lclose

Having the connection to ]q and [q combined with the new concept of [] meaning close and ][ has worked for me.

tpope commented 6 years ago

FWIW [] and ][ override built-ins.

kiryph commented 5 years ago

Actually

][q :copen
[]q :cclose
][l :lopen
[]l :lclose

add delays and do not override built-ins which I would not want either. I certainly think they are a "suboptimal" choice of mappings.

fprawits commented 3 years ago

Sorry for bumping this old issue, but I was looking exactly for this kind functionality and was actually surprised that it wasn't already part of vim-unimpaired, as it feels like such a good fit. For now I've hacked together a really simple mapping satisfying my needs -- maybe this will be of some help to someone:

function! ToggleQuickFix()
    if getqflist({'winid' : 0}).winid
        cclose
    else
        copen
    endif
endfunction

command! -nargs=0 -bar ToggleQuickFix call ToggleQuickFix()

nnoremap yoq :ToggleQuickFix<CR>