82

When I open a new tab with different path from the previous file in VIM, NERDTree will still remains the same directory hierarchy of the previous file.

Is there a sync shortcut to change the current root directory to the new opened file's directory?

11 Answers 11

21

I'm not sure if there's a NERDTree-specific way to do that, but you can always configure Vim so that it sets the working directory to the current file's directory:

autocmd BufEnter * lcd %:p:h

Now all what you have to do after opening a file in a new tab is :NERDTreeToggle in the new tab itself.

154

I use the following mapping to view the current buffer in NERDTree:

 map <leader>r :NERDTreeFind<cr>
7
  • 4
    I find this very usefull, and i went to my .vimrc. I wanted to use some other binding to make it easier to me to remember. And i found out that there is already a binding for this with NERDTree <Leader>f
    – benzen
    Feb 18, 2015 at 18:16
  • 1
    Awesome! Example what I was looking for.
    – mawaldne
    Apr 28, 2015 at 2:32
  • Can you elaborate on this?
    – jterm
    Aug 14, 2017 at 17:50
  • If you are using this amazing vimrc (not mine), it is mapped to ,nf: github.com/amix/vimrc
    – alpha_989
    Nov 21, 2017 at 15:34
  • 1
    It's funny that I saw this command in NERDTree help like 10 times and didn't bother to read the description for it even once, because the name didn't look like something useful to me: I expected it to do some FS search like UNIX find(1). Turns out it was exactly what I was googling for. Jul 2, 2020 at 22:55
46

throw a % sign on the end like a boss

:NERDTree %

i have this in my .vimrc, it maps Ctrl+o to toggle nerdtree in the dir of the current buffer:

map <C-o> :NERDTreeToggle %<CR>

5
  • 2
    You know I was skeptical. Something in the way you said it :D. But this is the only thing that worked like I needed it to, well done.
    – Hugo
    Nov 25, 2013 at 2:26
  • 1
    Such a boss answer!
    – ecbrodie
    Mar 6, 2017 at 15:14
  • 2
    much boss, such answer
    – mhz
    Jul 12, 2017 at 15:50
  • 2
    The only issue is when starting from a blank file, the toggle won't work as there's no dir of the current buffer.
    – X.Arthur
    Mar 25, 2019 at 14:15
  • Ah, saved me two extra key presses, since I was doing :NERDTree %:h :)
    – Kay
    Oct 25, 2021 at 19:36
40

I found both the existing answers educational, and successfully combined the two so that the behavior is more like many people would expect from an IDE: Click on an open window/buffer, and have that file highlighted in the NERDTree. I put this in my ~/.vimrc:

autocmd BufEnter * if &modifiable | NERDTreeFind | wincmd p | endif

What this does:

  1. autocmd BufEnter - runs every time you focus on a buffer (including the NERDTree window)
  2. if &modifiable - when you do click the NERDTree window, do nothing else (the NERDTree window is not modifiable)
  3. wincmd p - NERDTreeFind leaves the cursor focused on the NERDTree; this switches back to the window you'd originally focused on

Note that this won't work on any other buffer that isn't modifiable -- but that's generally a good thing; otherwise (for example) any time you got :help in vim, NERDTree would find and focus the directory where help files are stored--probably not something you want it to do.

That one-line solution worked great for me at first, but I soon found that it causes NERDTree to activate any time I opened a file--and as a result, it prevents NERDTree from ever being closed! If you don't want to use NERDTree full-time, put this in your .vimrc instead:

" returns true iff is NERDTree open/active
function! rc:isNTOpen()        
  return exists("t:NERDTreeBufName") && (bufwinnr(t:NERDTreeBufName) != -1)
endfunction

" calls NERDTreeFind iff NERDTree is active, current window contains a modifiable file, and we're not in vimdiff
function! rc:syncTree()
  if &modifiable && rc:isNTOpen() && strlen(expand('%')) > 0 && !&diff
    NERDTreeFind
    wincmd p
  endif
endfunction

autocmd BufEnter * call rc:syncTree()
10
  • 1
    What is the purpose of isNTFocused()? Doesn't the &modifiable check cover that case?
    – jrdioko
    Jun 28, 2013 at 19:28
  • 4
    Function name must start with a capital or "s:": rc:isNTOpen() Are you using a plugin extending scopes? Aug 3, 2017 at 20:40
  • 1
    Sorry but I don't know, @BrianHaak. I don't use NerdTree currently, and have misplaced my old .vimrc in which I had written that code. I don't recall why I used the rc:, but I think it was a namespacing thing to avoid name conflicts with other functions. I wasn't using any plugin specifically related to that, as far as I recall. You'll have to study the docs, or just try leaving it out and see if anything breaks. But I think one of the function names conflicted with something in NerdTree or elsewhere. No one else has asked in almost 5 years, so I have a feeling it's something simple. :)
    – Lambart
    Aug 3, 2017 at 20:59
  • 9
    @Lambart I've created a usable config with all problems solved: gist.github.com/avesus/1954d9384d86cc1e39cb2b2eff7017b7 Aug 4, 2017 at 0:10
  • 1
    Cool. I've been meaning for years to git-ify my various .rc files. Some day...
    – Lambart
    Aug 4, 2017 at 17:46
3

I came across this question yesterday, after a few hours of digging, I submited a Pull Request to scrooloose's nerdtree repo introducing a NERDTreeCWDcommand that change NERD tree root to current working directory(Update on 2012-11-12: The PR has been merged into the upstream master,it should be usable on an updated version). With this change, this question can be simply solved by the following code.

autocmd BufEnter * silent! if bufname('%') !~# 'NERD_tree_' | cd %:p:h | NERDTreeCWD | wincmd p | endif

Compare to @shinzui's and @Lambart's NERDTreeFind approach, this does exactly what the question asked. Using NERDTreeFind will change the scroll position of the nerdtree and the result are not always the same(If CWD is in NERD tree root, it just simply expands the node instead changing into it).

Compare to @Yaser Sulaiman's answer, this solution alwys have a NERD tree window opened and can be easily codable. If a NERD tree window has already been opened, using NERDTreeToggle will need to be fired twice(first close the existing one,then open it again), unfortunately, the second openning will skip the whole cwd processing.

3
  • 1
    Doesn't your solution lead to NERDTree always being open? Also I find that if I use the MRU plugin and try to open files, it opens files in the NERDtree window after I use this change. As it stands this modification will cause a lot of issues and conflicts with MRU (github.com/yegappan/mru/wiki/User-Manual), however I don't know why. Maybe other people can check if they have similar issues. I do like that the NERDtree tab is always open..
    – alpha_989
    Nov 21, 2017 at 16:44
  • 1
    Yeah, this results in NERDTree always being open. Sadness.
    – Meredith
    Apr 29, 2018 at 23:09
  • 1
    To add, you can check if the current buffer is modifiable and only then update the CWD. This is useful in case you use terminal inside neovim (using toggleterm maybe) and you don't want this update CWD to run when you switch to the terminal. autocmd BufEnter * silent! if bufname('%') !~# 'NERD_tree_' && &modifiable | cd %:p:h | NERDTreeCWD | wincmd p | endif Nov 24, 2021 at 16:12
3

Check this cool plugin vim-nerdtree-sync

enter image description here

3

This behaves like :NERDTreeToggle but will show the currently opened file in NERDTree. If you haven't opened a file yet (i.e., you just entered vim in your command line) NERDTree shows /home.

Put this in your .vimrc:

" Open NERDTree in the directory of the current file (or /home if no file is open)
nmap <silent> <C-i> :call NERDTreeToggleInCurDir()<cr>
function! NERDTreeToggleInCurDir()
  " If NERDTree is open in the current buffer
  if (exists("t:NERDTreeBufName") && bufwinnr(t:NERDTreeBufName) != -1)
    exe ":NERDTreeClose"
  else
    exe ":NERDTreeFind"
  endif
endfunction
3
  • What's <silent> key? Feb 3, 2020 at 12:02
  • That's not a key, it's a command. Feb 3, 2020 at 15:10
  • Silent just means executed silently. silent just prevents things from being echoed.
    – unrealapex
    Jun 21, 2022 at 2:01
1

I think this plugin is what you want https://github.com/jistr/vim-nerdtree-tabs

2
  • 3
    Welcome to Super User! Whilst having the link is nice, it would be preferable to include a bit of context here, and explain what the plugin does, how it should be used, etc. Thanks!
    – slhck
    Aug 30, 2013 at 5:04
  • Actually this could be a good solution for what was asked..
    – alpha_989
    Nov 21, 2017 at 16:47
1

I apply both solutions from Change current directory using NERDTree: use cd to set the NERDTree working directory to the current directory and C to set the NERDTree root node to the current directory

0

I found the answer that Matthias posted to be a great answer with one problem, it doesn't work well in a couple of edge cases. It works a little better with the change below:

function! NERDTreeToggleInCurDir()
  " If NERDTree is open in the current buffer
  if (exists("t:NERDTreeBufName") && bufwinnr(t:NERDTreeBufName) != -1)
    exe ":NERDTreeClose"
  elseif bufname('%')
    exe ":NERDTreeFind"
  else
    exe ":NERDTreeCWD"
  endif
endfunction
0

Here's an improved version of @weynhamz 's answer that syncs NERDTree without leaving it open and also handles read-only and empty buffers:

" autocommands that call SyncNerdTree() when the buffer is changed or written
" to
augroup nerd_tree_sync_current_dir
  autocmd!
  autocmd BufEnter * call SyncNERDTree()
  autocmd BufWrite * call SyncNERDTree()
augroup end

" sync NERDTree with the current file open
function SyncNERDTree()
  " make sure the buffer isn't a NERDTree buffer, it is not empty, and also
  " make sure the buffer contains a file
  " file
  if stridx(bufname('%'), 'NERD_tree_') == -1 && bufname() != "" && &buftype == "" && &filetype != "" 
    cd %:p:h
    " open a new NERDTree buffer and close it
    NERDTree
    NERDTreeClose
  endif
endfunction

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .