Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can i prevent that fzf open files inside NERDtree buffer? #453

Closed
heliohead opened this issue Dec 21, 2015 · 21 comments
Closed

How can i prevent that fzf open files inside NERDtree buffer? #453

heliohead opened this issue Dec 21, 2015 · 21 comments

Comments

@heliohead
Copy link

How can i prevent that fzf open files inside neotree buffer?
I am always do that, find files when neotree buffer is on focus :(

fzf

thanks

@junegunn
Copy link
Owner

Hmm, you'll probably have to use a custom mapping that moves the focus if the cursor is on that window. You mean nerdtree, right? Something like this:

nnoremap <silent> <expr> <Leader><Leader> (expand('%') =~ 'NERD_tree' ? "\<c-w>\<c-w>" : '').":FZF\<cr>"

@heliohead
Copy link
Author

OH Yeah, i mean nerdtree, neotree is a emacs thing :p,
This map works like a charm :) 🏅 🎖
Thank you so much! and also thanks for the great job of your plugins and themes i love it 💫 🤘👍 .

Closing issue in 4...3...2...

@mrleolink
Copy link

Sorry, your command doesn't work for me.
I'm using newest version of both NerdTree and FZF, this problem still happens...

nnoremap <silent> <expr> <Leader><Leader> (expand('%') =~ 'NERD_tree' ? "\<c-w>\<c-w>" : '').":FZF\<cr>"

@junegunn
Copy link
Owner

@mrleolink Works for me. It's probably something in your configuration; some plugin or your own autocmd. Disable everything but fzf and nertree and see if the problem persists.

@mrleolink
Copy link

@junegunn Ok, so I tried to disable everything but the problem still persists.

I'm using neovim, this is my init.vim

execute pathogen#infect()
autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif

"fzf: https://github.com/junegunn/fzf
set rtp+=$FZF_HOME
map <c-p> :FZF<CR>
autocmd! FileType fzf tnoremap <buffer> <leader>q <c-p>
nnoremap <silent> <expr> <Leader><Leader> (expand('%') =~ 'NERD_tree' ? "\<c-w>\<c-w>" : '').":FZF\<cr>"

As you can see, I'm using pathogen to load nerdtree. I don't have anything else in my bundle folder.

@junegunn
Copy link
Owner

I suspect you don't fully understand the lines. The suggested line is a mapping of its own and not a global configuration so it does not affect <c-p> binding you have above. Change <leader><leader> to <c-p>.

@mrleolink
Copy link

It works!!!
Thank you 👍

@dkarter
Copy link

dkarter commented Jan 1, 2018

For anyone still looking for a solution I created the following function and put it in my .vimrc, it will also check the number of buffers and if you open vim like this vim . it will allow you to use your FZF mapping to open a file instead of the nerdtree browser:

function! FZFOpen(command_str)
  if (expand('%') =~# 'NERD_tree' && winnr('$') > 1)
    exe "normal! \<c-w>\<c-w>"
  endif
  exe 'normal! ' . a:command_str . "\<cr>"
endfunction

nnoremap <silent> <C-b> :call FZFOpen(':Buffers')<CR>
nnoremap <silent> <C-g>g :call FZFOpen(':Ag')<CR>
nnoremap <silent> <C-g>c :call FZFOpen(':Commands')<CR>
nnoremap <silent> <C-g>l :call FZFOpen(':BLines')<CR>
nnoremap <silent> <C-p> :call FZFOpen(':Files')<CR>

@junegunn junegunn changed the title How can i prevent that fzf open files inside neotree buffer? How can i prevent that fzf open files inside NERDtree buffer? Jan 8, 2018
@jeromedalbert
Copy link

jeromedalbert commented Feb 17, 2018

My comment has a bigger scope than this issue, but it is still related and this might interest some people. I currently have a more advanced setup that prevents opening any file in NERDTree when NERDtree is focused:

  • files opened with FZF
  • files opened with mappings, for example my VIMRC or the project README
  • files opened with :edit
  • etc.

Plus, if you change your mind and exit FZF, you still have focus on the original NERDTree. You don't need to <c-w><c-w> back, and you don't need wrapper functions.

Here is the code:

let g:fzf_layout = { 'window': 'let g:launching_fzf = 1 | keepalt topleft 100split enew' }

autocmd FileType nerdtree let t:nerdtree_winnr = bufwinnr('%')
autocmd BufWinEnter * call PreventBuffersInNERDTree()

function! PreventBuffersInNERDTree()
  if bufname('#') =~ 'NERD_tree' && bufname('%') !~ 'NERD_tree'
    \ && exists('t:nerdtree_winnr') && bufwinnr('%') == t:nerdtree_winnr
    \ && &buftype == '' && !exists('g:launching_fzf')
    let bufnum = bufnr('%')
    close
    exe 'b ' . bufnum
  endif
  if exists('g:launching_fzf') | unlet g:launching_fzf | endif
endfunction

It's kind of hacky because I do "code injection" by adding the g:launching_fzf variable inside the layout configuration. There may be a more elegant solution but in the meantime it works and I didn't have to change the FZF plugin source code.

mmrwoods added a commit to mmrwoods/dotfiles that referenced this issue Jun 25, 2018
Update ack mapping to avoid opening files in the NERDTree window

Copied from junegunn/fzf#453

Hacky, but does the job. It would be nice to tidy this up and find a
more general solution that will work with CtrlP, Ack, MRU and so on.
@r-glebov
Copy link

r-glebov commented Mar 25, 2019

let g:fzf_layout = { 'window': 'let g:launching_fzf = 1 | keepalt topleft 100split enew' }

autocmd FileType nerdtree let t:nerdtree_winnr = bufwinnr('%')
autocmd BufWinEnter * call PreventBuffersInNERDTree()

function! PreventBuffersInNERDTree()
  if bufname('#') =~ 'NERD_tree' && bufname('%') !~ 'NERD_tree'
    \ && exists('t:nerdtree_winnr') && bufwinnr('%') == t:nerdtree_winnr
    \ && &buftype == '' && !exists('g:launching_fzf')
    let bufnum = bufnr('%')
    close
    exe 'b ' . bufnum
  endif
  if exists('g:launching_fzf') | unlet g:launching_fzf | endif
endfunction

Does this solution still works correctly for anybody?
Have problems with using it:

Error detected while processing function PreventBuffersInNERDTree:
line    5:
E444: Cannot close last window

gko added a commit to gko/vimio that referenced this issue May 25, 2019
First is a <leader><Leader> shortcut that switches buffers before
opening FZF file.
Second is a treatment within NERDTree itself. It closes NERDTree before
opening file. More info here:
junegunn/fzf#453 (comment)
@danielgatis
Copy link

danielgatis commented Jul 20, 2019

try this:

au BufEnter * if bufname('#') =~ 'NERD_tree' && bufname('%') !~ 'NERD_tree' && winnr('$') > 1 | b# | exe "normal! \<c-w>\<c-w>" | :blast | endif

@chrisjune
Copy link

try this:

au BufEnter * if bufname('#') =~ 'NERD_tree' && bufname('%') !~ 'NERD_tree' && winnr('$') > 1 | b# | exe "normal! \<c-w>\<c-w>" | :blast | endif

Thanks!, it's all I wanted

@outaTiME
Copy link

outaTiME commented Oct 18, 2019

try this:

au BufEnter * if bufname('#') =~ 'NERD_tree' && bufname('%') !~ 'NERD_tree' && winnr('$') > 1 | b# | exe "normal! \<c-w>\<c-w>" | :blast | endif

@danielgatis weird things happen when running with neovim 0.4, this automatic command still working?

Original layout without fzf command:

image

After :Files command, nerdtree at bottom, fzf command at top lef and empty buffer at top right:

image

(everything broken at this point)

@wookayin
Copy link

For a future reference: if you are using vim-nerdtree-tabs plugin and want fzf to open in another window (rather than inside the 'pinned' NERDTree buffer), the following would work:

if exists('t:NERDTreeBufName') && bufname('%') == t:NERDTreeBufName
  wincmd w   " move the focus outside nerdtree
endif

Note that in this case fzf will open files in the same buffer if it is not a pinned NERDTree buffer (e.g. e .).

@dreamos82
Copy link

dreamos82 commented Feb 9, 2020

Just to add my 2 cents, i used @jeromedalbert solution and worked pretty well for me, the only thing i didn't liked was that it was closing the nerdtree buffer, so i tried to update it in order to keep it open even when i jump to a file.

Here is my solution:

autocmd FileType nerdtree let t:nerdtree_winnr = bufwinnr('%')
autocmd BufWinEnter * call PreventBuffersInNERDTree()

function! PreventBuffersInNERDTree()
  if bufname('#') =~ 'NERD_tree' && bufname('%') !~ 'NERD_tree'
    \ && exists('t:nerdtree_winnr') && bufwinnr('%') == t:nerdtree_winnr
    \ && &buftype == '' && !exists('g:launching_fzf')
    let bufnum = bufnr('%')
    close
    exe 'b ' . bufnum
    NERDTree
  endif
  if exists('g:launching_fzf') | unlet g:launching_fzf | endif
endfunction

So basically i just reopened it when the new buffer open in the correct window.
Hope this helps!

@mangelozzi
Copy link

mangelozzi commented Sep 29, 2020

I really liked @dkarter's solution, I "improved/customised" it a little, I often have nerdtree on the left, and quickfix window below, so I would like to move a window to the right and up if the buffer is not modifiable or NERDTree or a quickfix window:

" Prevent FZF commands from opening in none modifiable buffers
function! FZFOpen(cmd)
    " If more than 1 window, and buffer is not modifiable or file type is
    " NERD tree or Quickfix type
    if winnr('$') > 1 && (!&modifiable || &ft == 'nerdtree' || &ft == 'qf')
        " Move one window to the right, then up
        wincmd l
        wincmd k
    endif
    exe a:cmd
endfunction

" FZF in Open buffers
nnoremap <silent> <leader><leader> :call FZFOpen(":Buffers")<CR>

" FZF Search for Files
nnoremap <silent> <leader>f :call FZFOpen(":Files")<CR>

" FZF Search for Files in home dir
nnoremap <silent> <leader>~ :call FZFOpen(":Files ~")<CR>

" FZF Search for previous opened Files
nnoremap <silent> <leader>zh :call FZFOpen(":History")<CR>

@ghost-lth
Copy link

try this:

au BufEnter * if bufname('#') =~ 'NERD_tree' && bufname('%') !~ 'NERD_tree' && winnr('$') > 1 | b# | exe "normal! \<c-w>\<c-w>" | :blast | endif

Thanks!, it's all I wanted too

@jkoz
Copy link

jkoz commented Nov 11, 2020

I like danielgatis solution; however if i look for a file which have already in the buffer. It didn't bring it up

@LuisCusihuaman
Copy link

try this:

au BufEnter * if bufname('#') =~ 'NERD_tree' && bufname('%') !~ 'NERD_tree' && winnr('$') > 1 | b# | exe "normal! \<c-w>\<c-w>" | :blast | endif

Works for me, thanks!!!! 🤟

@Rican7
Copy link

Rican7 commented Sep 16, 2021

I also liked @dkarter's and @mangelozzi's solutions, but refined it even more-so:

" Function to prevent FZF commands from opening in functional buffers
"
" See: https://github.com/junegunn/fzf/issues/453
" TODO: Remove once this workaround is no longer necessary.
function! FZFOpen(cmd)
    " Define the functional buffer types that we want to not clobber
    let functional_buf_types = ['quickfix', 'help', 'nofile', 'terminal']

    " If more than 1 window, and buffer type is not one of the functional types
    if winnr('$') > 1 && (index(functional_buf_types, &bt) >= 0)
        " Find all 'normal' (not functional) buffer windows
        let norm_wins = filter(range(1, winnr('$')),
                    \ 'index(functional_buf_types, getbufvar(winbufnr(v:val), "&bt")) == -1')

        " Grab the first one that we can use
        let norm_win = !empty(norm_wins) ? norm_wins[0] : 0

        " Move to that window
        exe norm_win . 'winc w'
    endif

    " Execute the passed command
    exe a:cmd
endfunction

" Map CTRL+P to FZF
nmap <C-P> :call FZFOpen(':FZF')<CR>

(source: https://github.com/Rican7/dotfiles/blob/5e58b3f3839f2f06e7b04d904871dc78c97a09d2/.vim/plugin/fzf.vim#L49-L76)

In fact, I really think that this code should live within fzf. As much of this I actually took from ctrlp.vim, which has this ability/feature built-in.

@alps2006
Copy link

alps2006 commented May 7, 2023

I use coc-explorer as my file navigator, this snippet can resolve my problem.

    " 1st cond: Previous buffer name match pattern `coc-explorer`
    " 2st cond: Excluding when :FZF execute with split window
    " 3st cond: Current buffer name dismatch pattern `coc-explorer`
    " next operation: 
    " 1. Go to previous buffer by `b#` on explorer window
    " 2. Switching to another window by `wincmd w` 
    " 3. Go to last buffer on new window
    au BufEnter * if bufname('#') =~ 'coc-explorer' && bufname('%') != '' && bufname('%') !~ 'coc-explorer' && winnr('$') > 1 | b# | wincmd w | blast | endif

If using NERDtree, replacing the coc-explorer to NERD_tree.

au BufEnter * if bufname('#') =~ 'NERD_tree' && bufname('%') != '' && bufname('%') !~ 'NERD_tree' && winnr('$') > 1 | b# | wincmd w | blast | endif

gko added a commit to gko/vimio that referenced this issue Sep 17, 2023
First is a <leader><Leader> shortcut that switches buffers before
opening FZF file.
Second is a treatment within NERDTree itself. It closes NERDTree before
opening file. More info here:
junegunn/fzf#453 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests