I've noticed that using FZF commands in NeoVim will mess with the window layout after being closed, especially if there's a location list / quickfix window involved (at the bottom).
Given a window layout of:
| | |
| | |
| | |
| | |
+------------------------ +
| | |
| | |
| | |
| | |
|-----------------------| |
| | |
| location list | |
+-------------------------------------------+
After opening FZF:
| | |
| | |
| | |
+------------------------ +
| | |
| | |
|-----------------------| |
| location list | |
+-------------------------------------------+
| |
| FZF |
| |
+-------------------------------------------+
After closing FZF:
| | |
| | |
| | |
+------------------------ +
| | |
| | |
|-----------------------| |
| location list | |
| | |
| | |
| | |
| | |
+-------------------------------------------+
I've tried this with just nvim -u vimrc.minimal.
It gets worse on a second invocation, probably because of the winfixheight setting of quickfix/location list windows.
It would be nice, if fzf would restore the window layout from before it was invoked.
Very similar to https://github.com/junegunn/fzf.vim/issues/42
There is an issue I'm Neovim repo for augmenting window API to support this. Though I guess mkview could be abused somehow...
Yeah, this is an issue with vim plugins that create temporary splits.
botright 10newbotright newcloseUnfortunately I can't think of a simple solution to this problem. Suggestions are welcome.
Is there a reason exe (tabpagenr()-1).'tabedit|term ...' is not the default? That would preserve layout. It also wasn't obvious how to switch to this mode using g:fzf_layout. (Note that I suggest (tabpagenr()-1) so that closing the tabpage automatically returns to the previous tab without any hassle. vim-fugitive uses this approach for cvc.)
IMO https://github.com/neovim/neovim/issues/3933 is the general solution to this problem.
@justinmk
What are you using for g:fzf_layout exactly? I've found let g:fzf_layout = {} in your vimrc?! (makes it really not obvious then)
It seems to be a good workaround for now - also providing more space.. ;)
@blueyed let g:fzf_layout = {} makes fzf use a tab instead of a split (had to dig around the code; not documented). However, it opens in the next tab slot instead of the previous, so it doesn't return to the original tabpage on cancel.
Note that g:fzf_layout is only used by the commands in fzf.vim project.
https://github.com/junegunn/fzf.vim/blob/master/plugin/fzf.vim#L27-L31
This map is eventually passed to fzf#run() function, and it is supposed to contain down/up/left/right or window attribute. window attribute, which only works in neovim unlike the others, holds the ex command to create the terminal window. So what @justinmk suggested above can be done like follows:
let g:fzf_layout = { 'window': 'execute (tabpagenr()-1)."tabnew"' }
(There was a bug though, see 3073ca3.)
Should the above solution load the searched for and selected file in the split you executed it from?
@CrashyBang
You are probably hitting #559 there (wincmd p messes things up).
Would be great if you could try #559 and provide feedback there.
As a workaround, we could tell users to use tmux instead of terminal mode even inside neovim. I would like to test that, but I don't think that there is an option to force fzf to use tmux inside neovim. Is they one ?
@edi9999 I would just note that the terminal mode of neovim and freedom from tmux is one of the main reasons for me using neovim instead of vim.
This commit to Vim (from today) may fix the window layout issue: https://github.com/vim/vim/commit/991dea3ab185fb35e577ab0bdfd443cd4b43ccc6
edit: oops, that's for status height. never mind...
You can now prefer to use tmux with the following option :
let g:fzf_prefer_tmux = 1
I recently discovered the VimL function winrestcmd() which gives an ex command that can be executed to restore window layout for the current tabpage.
let save_win_layout = winrestcmd()
" ... show fzf split window; user selects item
execute save_win_layout " restore window layout
There are some limitations (e.g. it won't work if new splits are opened) but I think this would solve the common case. winrestcmd() works well for a "zoom" mapping I recently hacked up.
Derp, I just noticed that https://github.com/junegunn/fzf/commit/f025602841384fb10cc80d37492ec44c2b872860 uses winrestcmd().
@justinmk
Derp, I just noticed that f025602 uses winrestcmd().
It's a shame that we didn't know about it when the great ctrlp has been using it for like 5 years :)
Incidentally, I also have a zoom mapping. It uses :tab split, like Goyo.
" Zoom
function! s:zoom()
if winnr('$') > 1
tab split
elseif len(filter(map(range(tabpagenr('$')), 'tabpagebuflist(v:val + 1)'),
\ 'index(v:val, '.bufnr('').') >= 0')) > 1
tabclose
endif
endfunction
nnoremap <silent> <leader>z :call <sid>zoom()<cr>
Most helpful comment
You can now prefer to use tmux with the following option :
let g:fzf_prefer_tmux = 1