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.
caps-lock
to ctrl
? It makes most things with ctrl
much nicer... You can use something like gnome-tweaks
or setxkbmap -o ctrl:nocaps
An easy way to browse the file system is the command:
:Sex
I'm not making this up :)
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:
:cd into the toplevel directory of my project. To open file foo/bar/baz: Simplest scenario: type :e f
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.
set path+=**
to your configuration you basically enable fuzzy search as explained here
: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)
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
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.
https://i.stack.imgur.com/KcwmH.gif
https://i.stack.imgur.com/grGuv.gif
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.
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.)
vim-titlecase
screws with the gt/gT mappings, but there is a work-around.
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
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.
I use this function for finding files in subdirectories, I didn't write it though. It's from the 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 0 echo "Not a number" return endif if l:inputl: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.
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
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
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/
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).
models.py
, views.py
, etc.
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)
Success story sharing
:Vex
if you want to split the screen vertically instead of horizontally:Vex
more practical, but:Sex
just made my day.:Se
works too (same for theVe, Te
variants). No need to make it weird :)