What's the traditional way to navigate a project - vim

Having just moved from textmate to vim I'm curious. To be able to navigate my project efficiently I've installed command-t and ack.vim. These both seem like relatively new projects in the history of vim. What do people traditionally do to move around a project when they work in vim, do they just use the file explorer or is there some old school trick I don't know about?

I set path properly then use find for most things. Sometimes I just rely on the tags. The tags allow tab-completion, but find does not.
in my vimrc:
set path=src/**;c:/work,scripts/**;c:/work
then
:find foobar.cpp
Will turn up foobar.cpp if it exists under a src/ folder somewhere around my current directory (recursing up to find it until c:/work is hit) and then check the scripts hierarchy.
:tag FooBar
just jumps me right to the definition of that class, as I use ctags to tag my C source code and I also wrote a script to generate tags for an in-house DSL.

I use NerdTree and I can manage almost everything with it.

What I'm using generally:
For opening new files: :e with tab-completion, or :Ex (open explorer in the directory of current file).
For jumping between files in the buffer list (:ls): the taglist plugin, or :b and its tab-completion. Note that for :b, tab-completion works for substrings. For example, if you have two files in buffer list: module.h and module.cpp, you can type :b cpp and tab will complete module.cpp. Very handy!
For tab-completion I also recommend the must-have wildmenu (:set wildmenu :set wildmode=full)

Honestly? I rarely open a code file by name. For the most part I use ctags with ctrl-] to navigate around the files (following through to definitions between files), along with ctrl-t, ctrl-i, and ctrl-o. On the rare occasions I want to open a file by name, that's what a shell/explorer window is for.

Many people just use the normal file explorer in the bash command line or Windows Explorer or whatever and open files as necessary. For navigating existing source trees, cscope and ctags are both very useful. I find the project plugin really useful for IDE-like navigation of projects and files: it tends to be the main way I navigate my source tree. Combined with ctags, cscope, command-t and ack, navigation can generally be very fast.

"Traditionally?" I've used :Sex for years. That and tab-completion for file-names doesn't make it that bad. Even in directory nestings 8 or 9 deep, using /mo to jump to the directory "models", hit then o to open it... etc etc.
I have installed Command-T on one machine, which is nice, but nothing beats the reliability of netrw

I also only use the basic file and buffer commands for managing my projects. However, I found the following plugins make things easier as well:
Fuzzy Finder ( makes opening files more pleasant )
NERDTree ( already mentioned, does a nice directory explorer view )
Taglist ( useful for navigating in a file )
alternate.vim ( useful for programming languages such as C++ with corresponding file types .h and .cpp )
MiniBufExplorer ( makes keeping track of buffers easier )
Also, simply remapping :bn and :bp to something easier makes switching buffers more pleasant. For example:
nmap <C-n> :bn<cr>
nmap <C-p> :bp<cr>
Lastly, it wasn't mentioned but it is related to project management type stuff, make sure to check out the built in compile-edit stuff
:help quickfix
I find that a lot people first coming to vim do not notice it right away.

I'm understand that it's may be too late, but I hope this would be useful for someone.
We have relatively large project on work of about thousand files of C/C++ code, php and shell
scripts, configs and other stuff.
To navigate through files I use following options.
First, I use simple grep wrapper, stored in my .vimrc to find specific string in files:
function MyGrep( pattern, path, case, whole )
execute "normal! GoSearch text " . a:pattern . " in " . a:path . " and subdirs, case: " .a:case. " whole: ".a:whole
"E - extended regexp, l - display filenames only, r - search recursively
let l:keys = "Elr"
if a:case == 0
"case-sensitive
let l:keys = l:keys . "i"
endif
if a:whole != 0
"whole words only
let l:keys = l:keys . "w"
endif
let l:cmd = "r!grep -" . keys . " -e \"" . a:pattern ."\" "
let l:cmd2 = a:path . " --exclude=*.ncb --exclude=*.o --exclude=*.d --exclude-dir=.svn --exclude-dir=.d --exclude-dir=rc.d --binary-files=without-match"
echo l:cmd . l:cmd2
execute l:cmd . l:cmd2
endfunction
com -nargs=1 GrepHere call MyGrep( <q-args>, "./", 0, 0)
com -nargs=1 GrepHereCaseWhole call MyGrep( <q-args>, "./", 1, 1)
com -nargs=1 GrepHereCase call MyGrep( <q-args>, "./", 1, 0)
com -nargs=1 GrepHereWhole call MyGrep( <q-args>, "./", 0, 1)
On windows I use vimgrep and changelist with this command (also in .vimrc):
command -nargs=1 VGCodeHere :vimgrep /<args>/j ./**/*.{c,cpp,h,rc} | copen
Both 'greppers' are depend on current working directory, so don't forget to set it properly.
I usually open a new unnamed tab in Vim and use this search commands there to dump there file
names that I'm interested in, search results, logs locations and other info.
Second, a cscope utility and plug-in for Vim - it is Very convenient way to browse files,
functions, symbols in project, but if you dealing with C/C++ sources.
Third, native Vim tricks, such as
:e ./**/filename.cpp to open filename.cpp somewhere in file system subtree. Supports <Tab> filename completion.
:tabe %<.h to open corresponding header file (you can change .h extension to whatever you like)
:Ex to navigate, using built-in file system browser
Ctrl-O, Ctrl-I to go backwards and forward in Vim jump list
And to resume next time from the same Vim state I use sessions.
Save session in Vim with
:mksession sessionname.vis
, and launch vim with session:
vim -S sessionname.vis

Related

vim, switching between files rapidly using vanilla Vim (no plugins)

I understand that limiting myself to vanilla Vim (not using plugins) limits the power of the editor, but as I switch between different machines frequently, it is often too much trouble to move my environment around everywhere. I want to just stay in vanilla Vim.
Something that holds me back is the ability to quickly switch between files.
I (believe at least) have a good understanding of buffers, windows, tabs, as well as netrw (Vex, Ex, etc).
But in an editor such as Sublime Text, I can just type ctrl-p and instantly I am at the file.
I know that I can drop down to the shell, but I wonder if there are any other "hidden" secrets to rapidly switching between files in Vim based off more than just the filename.
The closest equivalent ("closest", not "exact") to ST2's Ctrl+P is a plugin called, get ready… CtrlP. There are other similar plugins like Command-T or FuzzyFinder.
I use CtrlP and I love it but I wholeheartedly support your decision to go "plugin-free". It's not the easiest way to go but it will pay off in the long run.
Opening files
The most basic way to open a file is :e /path/to/filename. Thankfully, you get tab-completion and wildcards: the classic * and a special one, **, which stands for "any subdirectory".
Combining all of that, you can do:
:e **/*foo<Tab>
to choose from all the files containing foo in their name under the working directory or:
:e **/*foo/*bar<Tab>
to choose from all the files containing bar in their name under any subdirectory containing foo in its name, anywhere under the working directory.
Of course, that works for :tabe[dit], :sp[lit] and :vs[plit], too.
Those commands are limited to one file, though. Use :next to open multiple files:
:next **/*.js
and take a look at :help arglist.
Jumping between buffers
:b[uffer] is the basic buffer-switching command:
:b4 " switch to buffer number 4
:bn " switch to next buffer in the buffer list
:bp " switch to previous buffer in the buffer list
:bf " switch to first buffer in the buffer list
:bl " switch to last buffer in the buffer list
:b foo<Tab> " switch by buffer name with tab-completion
:b# " switch to the alternate file
Note that many of these commands and their relatives accept a count.
The :ls command shows you a list of loaded buffers. It is a bit "special", though: buffers are assigned a number when they are created so you can have a list that looks like 1 2 5 if you delete buffers. This is a bit awkward, yes, and that makes switching to a buffer by its number a bit too troublesome. Prefer switching by partial name, :b foo<Tab> or cycling, :bn :bp.
Anyway, here is a cool mapping that lists all loaded buffers and populates the prompt for you, waiting for you to type the number of a buffer and press <enter>:
nnoremap gb :ls<CR>:b<Space>
With this mapping, switching to another buffer is as simple as:
gb
(quickly scanning the list)
3<CR>
or:
gb
(quickly scanning the list)
foo<tab><CR>
The idea comes from this image taken from Bairui's collection of Vim infographics:
Vim also has <C-^> (or <C-6> on some keyboards)—the normal mode equivalent of :b#—to jump between the current buffer and the previous one. Use it if you often alternate between two buffers.
Read all about buffers in :help buffers.
Go to declaration
Within a file, you can use gd or gD.
Within a project, Vim's "tags" feature is your friend but you'll need an external code indexer like ctags or cscope. The most basic commands are :tag foo and <C-]> with the cursor on a method name. Both tools are well integrated into Vim: see :help tags, :help ctags and :help cscope.
For what it's worth, I use tag navigation extensively to move within a project (using CtrlP's :CtrlPTag and :CtrlPBufTag commands, mostly, but the buit-in ones too) and my favorite "generic" buffer switching method is by name.
Deploying your config
A lot of Vim users put their config under version control which makes it very quick and easy to install your own config on a new machine. Think about it.
EDIT
A few months ago, I had to work on a remote machine with an outdated Vim. I could have installed a proper Vim and cloned my own beloved config but I decided to travel light, this time, in order to "sharpen the saw". I quickly built a minimalist .vimrc and revisited a couple of half forgotten native features. After that gig, I decided CtrlP wasn't that necessary and got rid of it: native features and custom mappings are not as sexy but they get the job done without much dependencies.
Juggling with files
set path=.,**
nnoremap <leader>f :find *
nnoremap <leader>s :sfind *
nnoremap <leader>v :vert sfind *
nnoremap <leader>t :tabfind *
:find is a truly great command as soon as you set path correctly. With my settings, ,ffoo<Tab> will find all the files containing foo under the current directory, recursively. It's quick, intuitive and lightweight. Of course, I benefit from the same completion and wildcards as with :edit and friends.
To make the process even quicker, the following mappings allow me to skip entire parts of the project and find files recursively under the directory of the current file:
nnoremap <leader>F :find <C-R>=expand('%:h').'/*'<CR>
nnoremap <leader>S :sfind <C-R>=expand('%:h').'/*'<CR>
nnoremap <leader>V :vert sfind <C-R>=expand('%:h').'/*'<CR>
nnoremap <leader>T :tabfind <C-R>=expand('%:h').'/*'<CR>
WARNING! The path option is extremely powerful. The value above—.,**—works for me, as a default fallback value. In the real world, the exact value of the option will differ from project/language/framework/workflow to project/language/framework/workflow, so the proper value depends entirely on your needs. Don't blindly copy that line and expect it to solve all your problems.
Juggling with buffers
set wildcharm=<C-z>
nnoremap <leader>b :buffer <C-z><S-Tab>
nnoremap <leader>B :sbuffer <C-z><S-Tab>
The mappings above list the available buffers in the "wildmenu" with an empty prompt, allowing me to either navigate the menu with <Tab> or type a few letters and <Tab> again to narrow down the list. Like with the file mappings above, the process is quick and almost friction-less.
nnoremap <PageUp> :bprevious<CR>
nnoremap <PageDown> :bnext<CR>
Those mappings speak for themselves.
Juggling with tags
nnoremap <leader>j :tjump /
This mapping uses regex search instead of whole word search so I can do ,jba<Tab> to find tag foobarbaz().
Yes, fuzzy matching is addictive but you can be just as productive without it. And for a fraction of the cost.
MORE EDIT
A couple of additional tips/tricks…
Wildmenu options
The "wildmenu", enabled with set wildmenu, makes file/buffer navigation easier. Its behavior is governed by a bunch of options that are worth investigating:
wildmode tells Vim how you want the "wildmenu" to behave:
set wildmode=list:full
wildignore filters out all the cruft:
set wildignore=*.swp,*.bak
set wildignore+=*.pyc,*.class,*.sln,*.Master,*.csproj,*.csproj.user,*.cache,*.dll,*.pdb,*.min.*
set wildignore+=*/.git/**/*,*/.hg/**/*,*/.svn/**/*
set wildignore+=tags
set wildignore+=*.tar.*
wildignorecase allows you to search for foo and find Foo:
set wildignorecase
File marks
augroup VIMRC
autocmd!
autocmd BufLeave *.css normal! mC
autocmd BufLeave *.html normal! mH
autocmd BufLeave *.js normal! mJ
autocmd BufLeave *.php normal! mP
augroup END
I recently found this gem in someone else's ~/.vimrc. It creates a file mark at the exact position of the cursor whenever you leave a buffer so that, wherever you are, 'J jumps to the latest JavaScript buffer you edited. Awesome.
The answer depends a lot on your preferences and circumstances. Some examples:
If it's mostly two files (e.g. a C header and implementation file), <C-^> is very handy. In general, the alternate file is an important concept.
If you use a large editor window, window :splits turn the problem of locating a buffer from locating the window (once you've got all buffers opened). You can use [N]<C-w><C-w> to quickly switch to it.
If you can memorize (a few) buffer numbers, the :[N]b[uffer] and :[N]sb[uffer] commands are quite handy; :ls tells you the numbers.
Plugins (or at least custom mappings) can improve things a lot, and there's a whole variety on this topic on vim.org. There are various mechanisms to distribute your config (Pathogen + GitHub, Dropbox, ...), or you could remotely edit server files through the netrw plugin that ships with Vim.
Sometimes it is also handy to go sequentially through a list of files (e.g., if you did something like vim *.php to open several files at once). Then you can use :n[ext] (as well as :prev[ious], :fir[st], and :la[st]) for navigation (in addition to what was suggested in the other answers).
You can do wildcard tab completion on the command line without any plugins. e.g.
:e src/**/foo*<tab>
will let you cycle through all the files starting with 'foo' in the directory tree under ./src and select the one you want to edit.
If you have already edited the file and it is still in a buffer then you can switch to it with:
:b foo<tab>
which will cycle through all the buffers with 'foo' in the path.
You may need to set the wildmode and wildmenu options to get the behaviour you want. I have
wildmode=longest:full
wildmenu
in my .vimrc.
If you are on a filename and want to jump to that file, gf will do it for you. I also like using ctags, which isn't a plugin; you just build the tags and can easily jump around your codebase.
If you want switch between files in vim editor, please see below answer
First press Esc key to exit from edit mode.
Then type :e to check current file path.
if you want to go another file then type :e /path-of-file.txt/ using this you are able to switch.
If you want to go previous file simply type :e# which switch to previous file path.
I had the same issue with Vim.
The last thing I want is to depend on plugins for a task as mundane as file switching.
I added the following lines to .vimrc
set path+=**
set wildmenu
And BAM! I can now :find any/filename/in/any/folder/ as long as vim is in the root directory of the project. Tab completion works. Wildcards work!
Once files are opened already, and there are a ton of buffers in the background (you could use :ls to see all buffers), running :b any/file <TAB> will fuzzy search for all buffers and jumps to the required file. In case it is not unique there will be a wildmenu of tabs (hence the 2nd line in .vimrc) which can be selected using tab.
My answer is coming from this awesome video
https://www.youtube.com/watch?v=XA2WjJbmmoM&feature=youtu.be&t=489
There are more tricks in and I recommend watching it.

VIM 7: How to navigate the code source tree from the root of the code base, in an efficient manner?

I have a system of navigating the code across multiple files in a huge code base, and I want to improve/fix a drawback that it currently has :
My shell is pre-configured to open at the root of my code base - lets call it Dev/.
During syncing/code building, I have a script which automatically stores the relative path of all .h and .c files in a single file to be used by cscope (lets call it cscope.files).
Once I sync, this file is updated - and then I can open any file I want in vim using the following command from Dev/ :
vif "part of file name",
where
vif: aliased to vi `grep !:1 cscope.files`
Provided I give a part of the filename long enough to uniquely identify it, I can immediately open it in vim.
Now, the drawback to this approach is, when I've already opened one file, and jump to another file without exiting vim, the only way I can do so is
:!vif *file2*
This spawns a new shell and then opens the file in a vim launched there. As a result, I can't switch between the two files (using Ctrl-^). I'm unable to come up with a solution that :
a) Lets me open any file from Dev/ instantly
b) Lets me open any other file inside vim (once I've opened an existing file) in the same shell, so that the 2 vim sessions are aware of each other (I can hop between the 2 using Ctrl-^)
I know this is a long question (how does one google this :) ), but I'm betting the solution is simple and obvious to someone more proficient in vim !!
Let me know if any part of the question is fuzzy, and I'll clarify it...
UPDATE:
I ultimately went the cscope way, after customizing using a shortcut (as using 'gf' on cscope.files still prevented me from toggling between 2 source files). See VIM 7 and cscope: Using "cscope find f" inside a keyboard mapping for switching between files for the shortcut.
Use vim's grep in something like this:
:map <F1> :vim <pattern> cscope.files<CR>gf
For example, with this:
vnoremap <F1> "ry:exe ':1vim /'.#r.'/ cscope.files'<CR>gf
you select (visual mode) the pattern you'd like to search for and then press F1. The first file that matches the pattern will open, replacing the current buffer*.
* If this is possible. i.e if current buffer is saved or if hidden is set etc.
If you prefer to get a prompt, use input():
nnoremap <F1> :exe ':1vim /'.input("Enter pattern: ").'/ cscope.files'<CR>
[ but then you have to manually gf because input() consumes the remaining characters of the map. To avoid this, you can use inputsave() and inputrestore() ]
update
... for example like this:
function! GetPat()
call inputsave()
let mypat = input("Enter pattern: ")
call inputrestore()
return mypat
endfunction
nnoremap <F1> :exe ':1vim /'.GetPat().'/ cscope.files'<CR>gf
I think that the Vim Fuzzy Finder plugin is well adapted to your use case.
As the name implies, using the plugin, you can find files using a fuzzy text search.
Additionnaly, it also works for other Vim ressources like buffers, tags, etc.
I don't use cscope myself, but it seems that you can use it to find files, see :help cscope-find.
Otherwise, something like (not tested) this could help:
"Custom function
function! MyFunc(pat)
" Get files list
let filelist = readfile('path/to/cscope.files')
" Filter non matching item out and see if only one item is left
if len(filter(filelist, 'v:var =~? '.a:pat)) == 1
" edit file
exec 'edit '.filelist[0]
else
" Report back
echom 'More than one match:'
for file in filelist
echom file
endfor
endif
endfunction
" Custom command
command! -bar -nargs=1 MyCom call MyFunc(<args>)
Also try using the built-in cscope integration:
:cs find f stdio.h
Cscope tag: stdio.h
# line filename / context / line
1 1 /usr/include/stdio.h <<<unknown>>>
2 1 /usr/include/bits/stdio.h <<<unknown>>>
Type number and <Enter> (empty cancels):
See :help cscope-suggestions for some mappings that may make it easier to use cscope from within vim.

Opening files in Vim using Fuzzy Search

I'm looking for a way to make Vim have the ability to open a file by fuzzy-searching its name.
Basically, I want to be able to define a project once, and then have a shortcut which will give me a place to type a file name, and will match if any letters match up.
This kind of functionality exists in most editors I've seen, but for the life of me I can't understand how to get Vim to do this.
Note that I'm looking for something that won't require me to have any idea where in my directory tree a file is. I just want to be able to open it by the filename, regardless of what directory it's in.
Thanks
There are two great vim plugins for this.
ctrlp:
Written in pure VimL
Works pretty much everywhere
Supports custom finders for improved performance
Most popular fuzzy search plugin for Vim
Command-T:
Written in C, VimL and Ruby
Fast out of the box
Requires +ruby support in Vim
Recommends Vim version >= 7.3
EDIT:
I use CtrlP with ag as my custom finder and it's incredibly quick (even on massive projects) and very portable.
An example of using ag with CtrlP:
if executable('ag')
" Use Ag over Grep
set grepprg=ag\ --nogroup\ --nocolor
" Use ag in CtrlP for listing files. Lightning fast and respects .gitignore
let g:ctrlp_user_command = 'ag %s -l --nocolor -g ""'
endif
CommandT for Vim is very much the comparable feature as in TextMate. My work flow is now
1) open up MacVim
2) :cd ~/my_project
3) (I have this mapped as described in the installation help)
4) C-v the file to open the file in a vertical split, or CR to open a new horizontal split.
5) to close the split, use :bd (buffer delete)
6) to switch to another buffer, I have BufferExplorer installed, so just \be and select
This workflow is comparable to TextMate, it takes a while to get used to, and I'm still learning.
Basic solution
Simply add this to your .vimrc
nnoremap <C-p> :find ./**/*
Pressing Ctrl+p will now allow you to fuzzyfind files in your current working directory and sub-directories thereof. Use the tab key to cycle through options.
Related solution
For those who want to keep it basic i.e. no plugins, this entertaining video shows another way to achieve fuzzy file find in vim.
They actually use
set path+=**
set wildmenu
in their .vimrc to find files in current sub-directories.
For example, with :find *Murph followd by tab, I would find the files KilianMurphy2012Why.R and KilianMurphy2014ROLE.R in subdir code which I can cycle through with the tab key. The first solution above has the advantage that the relative path is also shown.
Note that your current working directory will matter and that other files on your path (:set path?) will also be found with the this type of solution. The wildmenu option adds visual information and is not essential.
For a keyboard shortcut, add
nnoremap <C-p> :find *
to your .vimrc. Now you will be able to quickly search for files inside your project/current dir with Ctrl+p in normal mode.
What about http://www.vim.org/scripts/script.php?script_id=1984 Then there is http://github.com/jamis/fuzzy_file_finder .
Also see these blog posts: http://weblog.jamisbuck.org/2008/10/10/coming-home-to-vim and http://weblog.jamisbuck.org/2009/1/28/the-future-of-fuzzyfinder-textmate
HTH

Vim file navigation

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.
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<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.
Open 2 or 3 windows and open files in all of them as needed.
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.
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.
: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)
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:
and his is how the content search looks:
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
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.)
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
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.
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/
I often do:
:e ./
in NORMAL MODE to see the content of the current folder and then navigate to any other folder or file.
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).
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)

Shortcut to open file in Vim

I want to open a file in Vim like in Eclipse using Ctrl + Shift + R, or via the Ctrl + N option of autofill. Invoke a keyboard shortcut, type the file name/pattern, and choose from all the matching files names.
I know opening it normally like:
:tabe <filepath>
:new <filepath>
:edit <filepath>
The problem here is that I have to specify the whole file path in these cases.
What I normally do is e . (e-space-dot) which gives me a browsable current directory - then I can / - search for name fragments, just like finding a word in a text file. I find that generally good enough, simple and quick.
I recently fell in love with fuzzyfinder.vim
... :-)
:FuzzyFinderFile will let you open files by typing partial names or patterns.
:find is another option.
I open vim from the root of my project and have the path set to there.
Then, I can open files located anywhere in the tree using:
:find **/filena< tab >
Tab will autocomplete through various matches. (** tells it to search recursively through the path).
You can search for a file in the current path by using **:
:tabe **/header.h
Hit tab to see various completions if there is more than one match.
Consider using CtrlP plug-in.
It is included in Janus Distributive.
Allows you to find files in the current directory, open buffers or most recently used files using "fuzzy matching" or regular expression.
unless I'm missing something, :e filename is the fastest way I've found.
You can use tab to autocomplete the filename as well.
I like the :FuzzyFinderTextMate (or Ctrl + F) on my setup.
See http://weblog.jamisbuck.org/2008/10/10/coming-home-to-vim
I use a couple of shortcuts in my .vimrc file (exact syntax below).
They are based on the fact that in 90% of the cases, I want to open another file in the same directory as the file that I am currently editing, or in a directory that is very close in the hierarchy to that edited file.
Here's what the commands do do:
,cd : Change the current working directory to the directory that the current file you are editing is in.
,e : Opens a file with the current working directory already filled in so you have to specify only the filename.
Put these into your .vimrc:
map ,e :e <C-R>=expand("%:p:h") . "/" <CR>
map ,cd :cd %:p:h <CR>
Here's a sequence of events:
You are editing a file called test.java in "/home/prog"
,cd -> Current working directory now
becomes "/home/prog"
,e -> Expands to ":e /home/prog" so
that you can just fill in the file
name, say test.h.
,e -> Expands to ":e /home"
tab -> Cycle through subdirectories of /home
enter -> cd to the directory you
want say /home/prog
,e -> Expands to ":e /home/prog"
There's also command-t which I find to be the best of the bunch (and I've tried them all). It's a minor hassle to install it but, once it's installed, it's a dream to use.
https://wincent.com/products/command-t/
Use tabs, they work when inputting file paths in vim escape mode!
If you've got tags (and you should), you can open a file from the command line just by the name of the class or method or c function, with "vim -t DBPlaylist", and within vim with ":tag ShowList".
If you're editing files in a common directory, you can :cd to that directory, then use :e on just the filename.
For example, rather than:
:e /big/long/path/that/takes/a/while/to/type/or/tab/complete/thingy.rb
:sp /big/long/path/that/takes/a/while/to/type/or/tab/complete/other_thingy.c
:vs /big/long/path/that/takes/a/while/to/type/or/tab/complete/one_more_thingy.java
You can do:
:cd /big/long/path/that/takes/a/while/to/type/or/tab/complete/
:e thingy.rb
:sp other_thingy.c
:vs one_more_thingy.java
Or, if you already have a file in the desired directory open, you can use the % shorthand for the current filename, and trim it to the current directory with the :h modifier (:help :_%:) :
:e /big/long/path/that/takes/a/while/to/type/or/tab/complete/thingy.rb
:cd %:h
:sp other_thingy.c
:vs one_more_thingy.java
And, like others have said, you can tab-complete file names on the ex-line (see :help cmdline-completion for more).
This isn't exactly what you're looking for, but it's good in many cases (though not all).
If you VIM open and there's a name of a file in the buffer, you can put the cursor on that filename and type gf. This opens the file whose name is under the cursor in the same buffer. It's the same as
:e CTRL+r CTRL+w
I know three plugins that permit to open files, support auto-completion, and don't require to enter the full path name of the file(s) to open (as long as the files are under one of the directories from &path vim option):
searchInRuntime that I'm maintaining (the completion is not on :e/:find, but on split actions)
fuzzy finder as it has been already pointed out,
lookupfile.
Lately, I've seen another plugin with a similar feature, but I don't remember the name.
Soon, :find is likely support auto-completion -- patches on this topic are circulating on vim_dev mailing-list these days.
you can use (set wildmenu)
you can use tab to autocomplete filenames
you can also use matching, for example :e p*.dat or something like that (like in old' dos)
you could also :browse confirm e (for a graphical window)
but you should also probably specify what vim version you're using, and how that thing in emacs works. Maybe we could find you an exact vim alternative.
FuzzyFinder has been mentioned, however I love the textmate like behaviour of the FuzzyFinderTextmate plugin which extends the behaviour to include all subdirs.
Make sure you are using version 2.16 of fuzzyfinder.vim - The higher versions break the plugin.
With Exuberant ctags, you can create tag files with file information:
ctags --extra=+f -R *
Then, open file from VIM with
:tag filename
You can also use <tab> to autocomplete file name.
In GVIM, The file can be browsed using open / read / write dialog;
:browse {command}
{command} - open / read / write
open - Opens the file
read - Appends the file
write - SaveAs dialog
I installed FuzzyFinder. However, the limitation is that it only finds files in the current dir. One workaround to that is to add FuzzyFinderTextmate. However, based on the docs and commentary, that doesn't work reliably. You need the right version of FuzzyFinder and you need your copy of Vim to be compiled with Ruby support.
A different workaround I'm trying out now is to open all the files I'm likely to need at the beginning of the editing session. E.g., open all the files in key directories...
:args app/**
:args config/**
:args test/**
etc...
(This means I would have possibly scores of files open, however so far it still seems to work OK.)
After that, I can use FuzzyFinder in buffer mode and it will act somewhat like TextMate's command-o shortcut...
:FuzzyFinderBuffer

Resources