Vim file navigation

VimEditorNavigation

Vim Problem Overview


I'm trying really hard to learn vim after using TextMate for the last few years.

I've started to commit some of the in-file navigation to memory but I'm struggling with navigating between multiple files.

In my workflow it is pretty common that I'm flipping between a handful of files pretty regularly (enough files such that split-pane windows become too small).

I'm currently using NERDTree but find drilling down into directories cumbersome as well as constantly using CTRL+W h/CTRL+W l to hop back and forth.

I think I would do better with tabs I can easily toggle between but maybe I need to use a different workflow.

I'd also like a "Go to File..." shortcut like CMD+T in TextMate. I've found fuzzy_file_finder but it requires vim to be built with Ruby bindings which isn't the case the native installs I've worked on.

While I could rebuild the main reason I want to switch to vim is so I can have one editor environment that I know will easily work across any platform.

The options out there are overwhelming any ideas are much appreciated!

Vim Solutions


Solution 1 - Vim

An easy way to browse the file system is the command:

:Sex

I'm not making this up :)

Solution 2 - Vim

I don't find drilling down into subdirectories via plain old :e to be that cumbersome given a decent configuration for tab-completion.

Look into the 'wildmenu' option to have Vim show a list of completions (filenames) in the modeline above the commandline. You can change the 'wildmode' option to further configure the kind of tab-completion Vim will do.

Personally I use :set wildmode=full.

My workflow is like this:

  1. :cd into the toplevel directory of my project.

  2. To open file foo/bar/baz:

    • Simplest scenario: type :e f<tab>b<tab>b<tab><enter>.

    • If there are more than one file starting with b in one of those directories you might have to do a <left> or <right> or another <tab> on the keyboard to jump between them (or type a few more letters to disambiguate).

    • Worst-case scenario there are files and directories that share a name and you need to drill down into the directory. In this case tab-complete the directory name and then type *<tab> to drill down.

  3. Open 2 or 3 windows and open files in all of them as needed.

  4. Once a file is open in a buffer, don't kill the buffer. Leave it open in the background when you open new files. Just :e a new file in the same window.

  5. Then, use :b <tab> to cycle through buffers that are already open in the background. If you type :b foo<tab> it will match only against currently-open files that match foo.

I also use these mappings to make it easier to open new windows and to jump between them because it's something I do so often.

" Window movements; I do this often enough to warrant using up M-arrows on this"
nnoremap <M-Right> <C-W><Right>
nnoremap <M-Left> <C-W><Left>
nnoremap <M-Up> <C-W><Up>
nnoremap <M-Down> <C-W><Down>

" Open window below instead of above"
nnoremap <C-W>N :let sb=&sb<BAR>set sb<BAR>new<BAR>let &sb=sb<CR>

" Vertical equivalent of C-w-n and C-w-N"
nnoremap <C-w>v :vnew<CR>
nnoremap <C-w>V :let spr=&spr<BAR>set nospr<BAR>vnew<BAR>let &spr=spr<CR>

" I open new windows to warrant using up C-M-arrows on this"
nmap <C-M-Up> <C-w>n
nmap <C-M-Down> <C-w>N
nmap <C-M-Right> <C-w>v
nmap <C-M-Left> <C-w>V

It takes me a matter of seconds to open Vim, set up some windows and open a few files in them. Personally I have never found any of the third-party file-browsing scripts to be very useful.

Solution 3 - Vim

:Sex,:Vex, :Tex and :Ex are all useful commands for ex(ploring) the files on your system if you want to use something different from :e

(where S/V/T are short for Split/Vertical/Tab)

Solution 4 - Vim

If you haven't found them already, you might want to check out:

  • the original fuzzy finder plugin -- which IIRC doesn't have the Ruby binding issues
  • the Project plugin -- similar to NERDTree
  • the buffer explorer plugin -- shows a list of open buffers

Also bear in mind that you can remap key shortcuts in your .vimrc to make them less cumbersome. I do use split windows a lot; I've found the following make dealing with them much easier:

" set your own personal modifier key to something handy
let mapleader = "," 

" use ,v to make a new vertical split, ,s for horiz, ,x to close a split
noremap <leader>v <c-w>v<c-w>l
noremap <leader>s <c-w>s<c-w>j
noremap <leader>x <c-w>c

" use ctrl-h/j/k/l to switch between splits
map <c-j> <c-w>j
map <c-k> <c-w>k
map <c-l> <c-w>l
map <c-h> <c-w>h

Solution 5 - Vim

By far the best and fastest plugin I found for file navigation is fzf.vim. You can very quickly fuzzy search all your files, the open buffers and even the files contents.

Since we have a very large codebase at work I specified a couple of directories I use most as the directories fzf searches. Fzf even has a rich git integration. So you can search only tracked files.

This is how the file search looks: enter image description here

and his is how the content search looks:
enter image description here

Solution 6 - Vim

It is surprising to see that :find command has not been mentioned in any of the answers. I usually work with rails projects where I need to drill down deep into the directory hierarchy. So for a file application.css, located in app/assets/stylesheets/ all I have to type is :find applica and then press tab to autocomplete and enter to open.

Solution 7 - Vim

> I think I would do better with tabs I > can easily toggle between, but maybe I > need to use a different workflow.

Are you aware of Vim's tabs? Not sure if you were referring to Vim's own tabs there, or pining for TextMate's. It's unclear what Vim version you're using but it's had tabs since at least 7.0 (which seems to be installed everywhere I look lately), and they're awesome.

:tabe opens a new one (short for "tab edit", so e.g. :tabe for empty or :tabe path/to/file for opening a file in a new tab,) you can move between adjacent tabs with gt/gT, and there's a bunch of other tab-related nav commands too, as you might expect from Vim (:help tabs)

My workflow for large projects tends to involve a bunch of tabs, each with between 1 and 3 windows depending on what sort of context I need. This works even better if I have a doublewide terminal window since I can vertically split with :vs, so then a single tab can easily show me 4 files at once with plenty of room for each.

Final tip: I sometimes use the "switch buffer" command (:sb <partial_buf_name>) which is sorta-kinda like TM's fuzzy finding, in that it works pretty well but only for already-open buffers. Still great for when I have a dozen or more files open at once. (N.B. I needed to :set switchbuf=usetab in my vimrc for this to work across tabs, but once that's set it's great.)

Solution 8 - Vim

I find LustyExplorer the best so far.

You can open a file by typing only a part of its name.

You can open a file from the directory of the current file, or the current pwd, or from the buffer list.

If you open a file from the buffer list, you don't have to navigate through the directory tree, though unfortunately for the other two modes, you still have to navigate through the tree. The good thing is you don't have to start from the first character.

If you have:

dir_a/
    ...
dir_b/
    file.js
    file.html

and you want to open dir_b/file.html you can generally find it by typing b<Tab>h

Solution 9 - Vim

Check out the plugin ctrlp as an alternative to the plugin Command-T. It's better than this in that it is a 'native' Vim script and doesnt need Vim to be compiled with ruby (or other support) while it runs very fast and unobtrusive.

Solution 10 - Vim

If the file that you want is already loaded into a buffer (which is likely if you are flipping between a handful of files regularly) then you can quickly switch to the buffer with the :b[uffer] command.

:b can either take a buffer number as a parameter, or (more usefully) a string that matches part of the path/filename. If there are multiple matches you can use tab to cycle through them.

If you want to split the window and open the buffer in the new window then use :sb name

If you want to open the buffer in a new tab then use :tab b name

You can also use the :ls command to see a list of currently loaded buffers.

Solution 11 - Vim

I use this function for finding files in subdirectories, I didn't write it though. It's from the http://vim.wikia.com/wiki/Find_files_in_subdirectories">vim wiki:

function! Find(name)
let l:list=system("find . -name '".a:name."' | grep -v ".svn/" | perl -ne 'print "$.\t$_"'")
let l:num=strlen(substitute(l:list, "[^\n]", "", "g"))
if l:num < 1
echo "'".a:name."' not found"
return
endif
if l:num != 1
echo l:list
let l:input=input("Which ? (CR=nothing)\n")
if strlen(l:input)==0
return
endif
if strlen(substitute(l:input, "[0-9]", "", "g"))>0
echo "Not a number"
return
endif
if l:input<1 || l:input>l:num
echo "Out of range"
return
endif
let l:line=matchstr("\n".l:list, "\n".l:input."\t[^\n]")
else
let l:line=l:list
endif
let l:line=substitute(l:line, "^[^\t]\t./", "", "")
execute ":e ".l:line
endfunction

command! -nargs=1 Find :call Find("")

One thing I like is it has support for wildcards (*). It's also well behaved for multiple matches.

Solution 12 - Vim

In addition to the wildmenu answers, I use BufExplorer plugin, and the following mappings to quickly jump buffers:

nmap <A-1> :b 1<CR>
nmap <A-2> :b 2<CR>
nmap <A-3> :b 3<CR>
...
nmap <A-0> :b 10<CR>
nmap <A-=> \bs

Or you can just replace the buffer explorer with the :ls command, which basically display the same thing.

The last one maps the Alt-= to show the buffer explorer.

I don't use Windows that much, as I generally have one or two windows only.

I also modified the statusline to include the buffer number %2n, so that the I always know which buffer is being edited. See :h statusline

Solution 13 - Vim

do you know MacVim application? It is VIM polished for OS X, and one of its feature is support for tabs (CMD+T to open new tab), it have drawer, etc... (read this: http://zerokspot.com/weblog/2008/08/03/macvim-as-textmate-replacement/)

Try it!

Regards Michal

Solution 14 - Vim

NerdTree is best for file navigation in vim.

The link below is a good introduction to nerdtree.

http://www.catonmat.net/blog/vim-plugins-nerdtree-vim/

Solution 15 - Vim

Here's something fairly trivial that I stick in my .vimrc. It will load a file from any subdirectory.

" load from an unspecified subdirectory 
function! LoadFromSubdirectory(filespec) 
  let filename = glob("`find . -name '" . a:filespec . "' -print`") 
  exe ':e '.filename 
endfunction 
:command -nargs=1 Er :call LoadFromSubdirectory(<f-args>) 

So I can just say:

:Er Main.java

and it will search subdirectories, find Main.java and load it. It's not well behaved for multiple files of the same name, but it's quick and simple.

The other tool I use is VTreeExplorer, which provides a tree-based window of files/directories, and doesn't require any special build options from VIM (i.e. it's a vanilla plugin).

Solution 16 - Vim

My workflow for finding files is the wildmenu, autocwd and :e.

Relevant parts in the .vimrc:

set wildmenu
set wildignore=*.dll,*.o,*.pyc,*.bak,*.exe,*.jpg,*.jpeg,*.png,*.gif
set wildmode=list:full
set autochdir
let g:netrw_list_hide='^\.,.\(pyc\|pyo\|o\)$'

And how to use it:

:e myf^D

That gives all the files in the current directory that start with myf. You can also <Tab> through them. Use return to open :)

^D will always give you all the matches. Because autocmd always goes to the folder of the current file it's easy to work with. If you are in foo/bar.py and you want to go to foo/baz.py you only do :e baz.py and you're there. That also works with buffers (:b foo^D lists all buffers starting with foo)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPeteView Question on Stackoverflow
Solution 1 - Vimuser286754View Answer on Stackoverflow
Solution 2 - VimBrian CarperView Answer on Stackoverflow
Solution 3 - VimEmil RehhnbergView Answer on Stackoverflow
Solution 4 - VimdlimebView Answer on Stackoverflow
Solution 5 - VimeclipseView Answer on Stackoverflow
Solution 6 - VimImran AliView Answer on Stackoverflow
Solution 7 - VimbitprophetView Answer on Stackoverflow
Solution 8 - VimhasenView Answer on Stackoverflow
Solution 9 - VimnikolaView Answer on Stackoverflow
Solution 10 - VimDave KirbyView Answer on Stackoverflow
Solution 11 - Vimuniquesnowflake8View Answer on Stackoverflow
Solution 12 - VimAymanView Answer on Stackoverflow
Solution 13 - VimmsgreView Answer on Stackoverflow
Solution 14 - VimxinghuaView Answer on Stackoverflow
Solution 15 - VimBrian AgnewView Answer on Stackoverflow
Solution 16 - VimArmin RonacherView Answer on Stackoverflow