I use NERDTree with the setting:
""""
" NerdTree
"
Bundle 'scrooloose/nerdtree'
Bundle 'jistr/vim-nerdtree-tabs'
map <F2> :NERDTreeTabsToggle<CR>
I can open any number of tabs with the same file by pressing 't'. For example:
|foo.txt|bar.txt|foo.txt|foo.txt|
How to prevent the opening of duplicate files? I want to open an existing buffer by pressing 't'.
I found the solution here https://github.com/scrooloose/nerdtree/issues/439
Grab the latest version and stick this in
~/.vim/nerdtree_plugin/override_tab_mapping.vim
https://gist.github.com/scrooloose/0495cade24f1f2ebb602
Thanks #moeabdol
From what I understand NerdTree does not have such a behavior. I believe however what you are looking for is either :tab drop like #Ben mentioned or using :sb to switch buffers with the following setting: set swb=useopen,usetabe.
Personally I would suggest you use NerdTree for more of a File Explorer and less of a file/buffer manager. By leveraging Vim's buffer commands you can easily switch between buffers. Additionally by using Vim's buffer commands you can avoid the "one-to-one: file-to-tab relationship trap" that so many new vimmers get stuck on.
Aside about NerdTree
NerdTree is very helpful to explore a complex or unfamiliar file structure, but it comes at the cost of taking up screen real estate and disrupting buffer and window/split workflows. See Oil and vinegar - split windows and the project drawer for more. Using a nice fuzzyfinder plugin like CtrlP often takes the place of NerdTree for many people.
I have a nice post about NerdTree that might be of value: Files, Buffers, and Splits Oh My!
Aside about tabs
Vim's tabs are not like most text editors tab. They are more like viewports into a group of windows/splits. Additionally, Vim is buffer centric, not tab centric like most editors. Therefore using features like the quickfix list is often easier without tabs (See :h 'switchbuf if you must use tabs). Vim's tabs often get in the way of using a splits as there are better window and buffer navigation commands available. I personally have many files open (sometimes 100+) use no tabs and use on average 1-2 splits without any issue. Bottom line: read the following posts:
Why do Vim experts prefer buffers over tabs?
Use buffers effectively
Best practices with Vim mappings
Supply a mode. So :map becomes :nmap
Unless using a <Plug> or <SID> mapping you should probably be using :noremap
By following these 2 rules your mapping will become:
nnoremap <f2> :NERDTreeTabsToggle<cr>
to open a new buffer, just press o
I have NERDTree and MiniBufExplorer open at the launch of vim, so I have three windows. Whenever I use the aforementioned plugins the files/buffers are presented in the correct window, which is the initial one. However whenever I use a command such as :e ~/.vimrc the command works on the window which contains the cursor. This means I have to always remember to move the cursor over to the window used for editing. I was wondering if there was a way to have commands work on that window regardless of where the cursor is, or if file buffers would automatically present themselves in that window?
I was looking at a way to have the cursor move over to the right window when : (or some other key I could use) is pressed, but I couldn't figure out a way as there is no way to identify windows (or is there?).
Files, Buffers, and Splits Oh My!
You are asking Vim to change how every single file and buffer command to change to accommodate your plugin choice and workflow. You are going against the vim way here and it will hinder your use of Vim's splits.
First things first is to realize that Vim has no concept of Project drawers, only splits/windows. This means that NerdTree and other plugins go to great lengths to emulate Project Drawer behavior and ultimately fail.
Lets look at problems with using NerdTree and MiniBufExplorer as always open windows:
NerdTree:
Wasted space. How often do you look at your file structure? 10% of the time? Less?
Splits - open up a few split now switch to the bottom right most split via <c-w>b. Open up a file via NerdTree in this window. Did you use <c-w>t to go to the top left most window? Feels like quite a nuance to use so many window commands just to open a file
NerdTree doesn't play well when rearranging splits. Create some splits then do <c-w>J or <c-w>H. See how it messed up your layout
MiniBufExplorer
Scale - MiniBufExplorer just doesn't scale with the number of buffers. I have opened up over a hundred buffers without issue. I can not imagine the waste of space this would cause with MiniBufExplorer
There is little to be gained by seeing all your open buffers all the time. You only need to see them when you are switching to a different buffer
Switching buffers - You can switch buffers just as easily by mapping the :bnext and :bprev commands
More on switching buffers - Moving to the MiniBufExplorer window is tedious and annoy if that is how you want to switch buffers
Rearranging windows - Same as NerdTree
MiniBufExplorer is akin to using Vim's tabs for each file in vim see: Use buffer effectively
The Vim Way
As laid out in the Vimcast post, Oil and vinegar - split windows and the project drawer, Vim prefers to just open a file explorer when you need it then switch away from it when it isn't needed. You can user NerdTree in this fashion too, just forget the alway on file explorer bit. There are other ways of opening files in vim:
Use file completion, via <tab>, with commands like :e and :sp
Use <c-d> instead of <tab> to get a list of completions
:e and :sp commands take globs. e.g. :e *.c and :e foo/**/bar.c
:find and setup 'path' and 'suffix' options
Ctags or cscope to jump to tags
gf will go to a file under the cursor
Look into fuzzy finders like CtrlP or Command-T
Create project specific navigation via Projectile (Rails is a good example of this)
There are plenty of ways to switch buffers in Vim:
:b and :sb take buffer numbers but also names that will complete and glob
Use :ls to see a list of your buffers then use :b to switch directly
<c-6> will go the the previous buffer
Map :bnext and :bprev example [b and ]b are Unimpaired.vim mappings
set hidden make switching buffers easier. Don't worry vim will let you know if you have unwritten buffer before exiting
Once again look into fuzzy finder plugsin like CtrlP and Command-T to switch buffers
Vim is split happy. Make sure you use splits as effectively as you can. There are many split commmands, see :h opening-window. Better yet read the whole :h window help file, there are many treasure in there.
The core of a solution can be found in the NERDTree source via s:Opener._firstUsableWindow, which I then edited some to get the id and include modified buffers:
" Returns the first window ID containing a file buffer
"
" Iterates through window numbers until the last (winnr('$')),
" Skipping special buffer types & preview windows
function! FirstFileWindowID()
let i = 1
while i <= winnr('$')
let bnum = winbufnr(i)
if bnum !=# -1 && getbufvar(bnum, '&buftype') ==# ''
\ && !getwinvar(i, '&previewwindow')
" TODO I don't know what excluding &hidden does in the original,
" but may be desirable for correctness
return win_getid(i)
endif
let i += 1
endwhile
return -1
endfunction
This can then be used with win_execute to target recent file buffers, gaining tab-like behavior with buffers:
"tab movement (ctrl-n for next tab, ctrl-p for previous)
map <c-n> :call win_execute(FirstFileWindowID(), 'bnext')<CR>
map <c-p> :call win_execute(FirstFileWindowID(), 'bprev')<CR>
I use tmux for all my pane management, so while I'm sure leveraging the full range of vim's tab / window / buffer paradigm is best for many, I personally don't use it to is fullest extent.
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.
Sometimes when I'm working on a project I want to play around with some data. Often times the data is on one line and is huge (>25k characters). I understand I could set nowrap and have this line just run off the screen, but I tend to like set wrap for other reasons. So, as a workaround I want to hide these long lines in a marker fold (e.g. {{{ long line }}}). This works fine but I run into a problem with synmaxcol for some reason. If the folded line exceeds synmaxcol then when I open the file, the syntax highlighting runs over. For example:
However, as soon as I open the fold the syntax corrects itself:
Having to open the fold every time is annoying though. As you can see in this example the line is not actually all that long -- it just exceeds synmaxcol. Since synmaxcol is exceeded at a "string" element, the rest of the file is highlighted as a string (so nothing but a singular double quote will stop it).
Why is this happening and how can I fix it? I've tried this with different syntax files and filetypes and it still occurs. I've also tried it with no plugins, a minimal vimrc (containing only syn on) and a modeline to set fdm=marker:synmaxcol=60 and it still happens.
You can manually enter :syntax sync fromstart to force Vim to rescan the syntax from the beginning of the opened file.
I would suggest defining a hotkey for convenience:
noremap <F5> <Esc>:syntax sync fromstart<CR>
inoremap <F5> <C-o>:syntax sync fromstart<CR>
Now you can press F5 to clean up most syntax highlighting problems.
Also, have a look at Vim's fixing syntax highlighting - wiki page
Moreover reading :help :syn-sync-first might shed some more light on the issue.
UPDATE:
I was able to reproduce this behavior on my machine (I'm running Vim 7.3.429).
However, when I wrapped the fold markers {{{ and }}} in block comments, vim correctly rendered the syntax. You can create appropriately wrapped fold-markers using the zf command. See Vim tips: Folding fun.
Normally Vim picks the correct blockcomment string based on the currently active syntax. However, my Vim is pretty vanilla and didn't recognize Ruby syntax. I could specify autocmd FileType ruby set commentstring==begin%s=end in my .vimrc file to set the proper block comment. See :fold-create-marker for more details.
Another solution is to set synmaxcol=0, which will effectively set it to infinity. This causes Vim to check the syntax of the entire line, no matter how long it is. However, I'm not sure what kind of performance penalty you'll have to pay for that.
I've recently return to ViM, after several years in Emacs, and something I'm missing is the ability to set filetype-local keybindings: e.g. I want to make _ underline the current word in Markdown-type files, but do something completely different in, say, Python. Is there a way to do this other than just autocmds that override each other?
You can use map <buffer> ... to make a mapping local to a buffer rather than global. Then set up an autocommand to load that mapping only for certain filetypes, or put the mapping into a ftplugin file for that filetype. Luckily, local mappings aren't cleared when a buffer is hidden, only when a buffer is destroyed, so the mappings will stick around as you switch between buffers.
See :h :map-local.