Last active
May 29, 2024 18:07
-
-
Save bfrg/63e49d4a7c2d43fe9206b104e7837aff to your computer and use it in GitHub Desktop.
Toggle the quickfix and location-list windows without scrolling the windows
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" Open/close/toggle the quickfix and location-list windows without changing the | |
" window layout | |
" ------------------------------------------------------------------------------ | |
" File: autoload/qf/window.vim | |
" ------------------------------------------------------------------------------ | |
" Save and restore view of current window | |
function! s:winview(mode) abort | |
if a:mode == 0 | |
let w:qf_winview = winsaveview() | |
elseif a:mode == 1 && exists('w:qf_winview') | |
call winrestview(w:qf_winview) | |
unlet w:qf_winview | |
endif | |
endfunction | |
" Save and restore views of all windows in current tabpage | |
function! s:windo(mode) abort | |
for winnr in range(1, winnr('$')) | |
call win_execute(win_getid(winnr), printf('call s:winview(%d)', a:mode)) | |
endfor | |
endfunction | |
" Toggle quickfix or location-list window | |
function! qf#window#toggle(loclist = 0) | |
" Check if quickfix window is open in current tabpage, or if current | |
" window's location-list window is open | |
let is_open = getwininfo() | |
\ ->filter('v:val.tabnr == tabpagenr()') | |
\ ->filter({_,info -> a:loclist | |
\ ? info.loclist && info.winid == getloclist(0, {'winid': 1}).winid | |
\ : !info.loclist && info.quickfix | |
\ }) | |
\ ->len() | |
" Save current view of all windows | |
call s:windo(0) | |
if is_open | |
execute a:loclist ? 'lclose' : 'cclose' .. (&filetype ==# 'qf' ? '| wincmd p' : '') | |
else | |
let size = a:loclist ? getloclist(0, {'size': 1}).size : getqflist({'size': 1}).size | |
if size | |
" See https://github.com/vim/vim/issues/5037 | |
execute a:loclist ? 'lopen 1' : 'botright copen 1' | |
execute 'resize' min([10, size]) | |
endif | |
endif | |
" Restore views of all windows | |
call s:windo(1) | |
endfunction | |
" Same behavior as cwindow and lwindow but restore views of all windows | |
function! qf#window#open(loclist = 0) | |
call s:windo(0) | |
let size = a:loclist ? getloclist(0, {'size': 1}).size : getqflist({'size': 1}).size | |
if !size | |
execute a:loclist ? 'lclose' : 'cclose' | |
else | |
execute a:loclist ? 'lopen 1' : 'botright copen 1' | |
execute 'resize' min([10, size]) | |
endif | |
call s:windo(1) | |
endfunction | |
function! qf#window#close() | |
call s:windo(0) | |
if getwininfo(win_getid())[0].loclist | |
lclose | |
else | |
cclose | |
" Required only after cclose | |
wincmd p | |
endif | |
call s:windo(1) | |
endfunction | |
" ------------------------------------------------------------------------------ | |
" File: vimrc | |
" ------------------------------------------------------------------------------ | |
" Toggle quickfix and location-list windows | |
nnoremap <silent> goc :<c-u>call qf#window#toggle(0)<cr> | |
nnoremap <silent> gol :<c-u>call qf#window#toggle(1)<cr> | |
augroup quickfix | |
autocmd! | |
autocmd QuickFixCmdPost [^l]* ++nested call qf#window#open(0) | |
autocmd QuickFixCmdPost l* ++nested call qf#window#open(1) | |
autocmd VimEnter * ++nested call qf#window#open(0) | |
augroup END | |
" ------------------------------------------------------------------------------ | |
" File: after/ftplugin/qf.vim | |
" ------------------------------------------------------------------------------ | |
" Close quickfix window | |
nnoremap <silent> <buffer> gq :<c-u>call qf#window#close()<cr> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It's actually explained under
:help :botright
. There's also:h :topleft
in case you want to open a window at the top.