How do I navigate buffers in vim? - vim

I normally work with more than 5 files at a time. I use buffers to open different files.
I use commands such as :buf file1, :buf file2 etc.
Is there a faster way to move to different files?

What I use:
Go to the previous buffer: :b# or :bp
Go to the next buffer: :bn
If you know your file is loaded in buffer 5: :b5
To get a list of buffers: :buffers or shorter: :ls
And have a short look on :he buffer
And the wiki entry on Easier Buffer Switching on the Vim Wiki: http://vim.wikia.com/wiki/Easier_buffer_switching
SO already has a question regarding yours: How do you prefer to switch between buffers in Vim?

A few mappings can make your life a lot easier.
This one lists your buffers and prompts you for a number:
nnoremap gb :buffers<CR>:buffer<Space>
This one lists your buffers in the "wildmenu". Depends on the 'wildcharm' option as well as 'wildmenu' and 'wildmode':
nnoremap <leader>b :buffer <C-z>
These ones allow you to cycle between all your buffers without much thinking:
nnoremap <PageUp> :bprevious<CR>
nnoremap <PageDown> :bnext<CR>
Also, don't forget <C-^> which allows you to alternate between two buffers.

Below I describe some excerpts from sections of my .vimrc. It includes mapping the leader key, setting wilds tab completion, and finally my buffer nav key choices (all mostly inspired by folks on the interweb, including romainl). Edit: Then I ramble on about my shortcuts for windows and tabs.
" easier default keys {{{1
let mapleader=','
nnoremap <leader>2 :#"<CR>
The leader key is a prefix key for mostly user-defined key commands (some plugins also use it). The default is \, but many people suggest the easier to reach ,.
The second line there is a command to # execute from the " clipboard, in case you'd like to quickly try out various key bindings (without relying on :so %). (My nmeumonic is that Shift-2 is #.)
" wilds {{{1
set wildmenu wildmode=list:full
set wildcharm=<C-z>
set wildignore+=*~ wildignorecase
For built-in completion, wildmenu is probably the part that shows up yellow on your Vim when using tab completion on command-line. wildmode is set to a comma-separated list, each coming up in turn on each tab completion (that is, my list is simply one element, list:full). list shows rows and columns of candidates. full's meaning includes maintaining existence of the wildmenu. wildcharm is the way to include Tab presses in your macros. The *~ is for my use in :edit and :find commands.
" nav keys {{{1
" windows, buffers and tabs {{{2
" buffers {{{3
nnoremap <leader>bb :b <C-z><S-Tab>
nnoremap <leader>bh :ls!<CR>:b<Space>
nnoremap <leader>bw :ls!<CR>:bw<Space>
nnoremap <leader>bt :TSelectBuffer<CR>
nnoremap <leader>be :BufExplorer<CR>
nnoremap <leader>bs :BufExplorerHorizontalSplit<CR>
nnoremap <leader>bv :BufExplorerVerticalSplit<CR>
nnoremap <leader>3 :e#<CR>
nmap <C-n> :bn<cr>
nmap <C-p> :bp<cr>
The ,3 is for switching between the "two" last buffers (Easier to reach than built-in Ctrl-6). Nmeuonic is Shift- 3 is #, and # is the register symbol for last buffer. (See :marks.)
,bh is to select from hidden buffers (!).
,bw is to bwipeout buffers by number or name. For instance, you can wipeout several while looking at the list, with ,bw 1 3 4 8 10 <CR>. Note that wipeout is more destructive than :bdelete. They have their pros and cons. For instance, :bdelete leaves the buffer in the hidden list, while :bwipeout removes global marks (see :help marks, and the description of uppercase marks).
I haven't settled on these keybindings, I would sort of prefer that my ,bb was simply ,b (simply defining while leaving the others defined makes Vim pause to see if you'll enter more).
Those shortcuts for :BufExplorer are actually the defaults for that plugin, but I have it written out so I can change them if I want to start using ,b without a hang.
You didn't ask for this:
If you still find Vim buffers a little awkward to use, try to combine the functionality with tabs and windows (until you get more comfortable?).
" windows {{{3
" window nav
nnoremap <leader>w <C-w>
nnoremap <M-h> <C-w>h
nnoremap <M-j> <C-w>j
nnoremap <M-k> <C-w>k
nnoremap <M-l> <C-w>l
" resize window
nnoremap <C-h> <C-w><
nnoremap <C-j> <C-w>+
nnoremap <C-k> <C-w>-
nnoremap <C-l> <C-w>>
Notice how nice ,w is for a prefix. Also, I reserve Ctrl key for resizing, because Alt (M-) is hard to realize in all environments, and I don't have a better way to resize. I'm fine using ,w to switch windows.
" tabs {{{3
nnoremap <leader>t :tab
nnoremap <M-n> :tabn<cr>
nnoremap <M-p> :tabp<cr>
nnoremap <C-Tab> :tabn<cr>
nnoremap <C-S-Tab> :tabp<cr>
nnoremap tn :tabe<CR>
nnoremap te :tabe<Space><C-z><S-Tab>
nnoremap tf :tabf<Space>
nnoremap tc :tabc<CR>
nnoremap to :tabo<CR>
nnoremap tm :tabm<CR>
nnoremap ts :tabs<CR>
nnoremap th :tabr<CR>
nnoremap tj :tabn<CR>
nnoremap tk :tabp<CR>
nnoremap tl :tabl<CR>
" or, it may make more sense to use
" nnoremap th :tabp<CR>
" nnoremap tj :tabl<CR>
" nnoremap tk :tabr<CR>
" nnoremap tl :tabn<CR>
In summary of my window and tabs keys, I can navigate both of them with Alt, which is actually pretty easy to reach. In other words:
" (modifier) key choice explanation {{{3
"
" KEYS CTRL ALT
" hjkl resize windows switch windows
" np switch buffer switch tab
"
" (resize windows is hard to do otherwise, so we use ctrl which works across
" more environments. i can use ',w' for windowcmds o.w.. alt is comfortable
" enough for fast and gui nav in tabs and windows. we use np for navs that
" are more linear, hjkl for navs that are more planar.)
"
This way, if the Alt is working, you can actually hold it down while you find your "open" buffer pretty quickly, amongst the tabs and windows.

Once the buffers are already open, you can just type :b partial_filename to switch
So if :ls shows that i have my ~./vimrc open, then I can just type :b vimr or :b rc to switch to that buffer

There are many ways to solve. The best is the best that WORKS for YOU. You have lots of fuzzy match plugins that help you navigate. The 2 things that impress me most are
1) CtrlP or Unite's fuzzy buffer search
2) LustyExplorer and/or LustyJuggler
And the simplest :
:map <F5> :ls<CR>:e #
Pressing F5 lists all buffer, just type number.

Related

How do I map CMD (Command ⌘) to shift MacVim window

I know that I can use ctrl+w to shift between different Vim windows. But how do I remap the CMD-key to replace ctrl+w in various way? I'm specifically looking to bind cmd with the arrow keys, so that I can shift to NERDTree easily with CMD+LeftArrow. Appreciate the assistance.
I've tried to add the following to $MYVIMRC...
nmap <silent> <D-h> :wincmd h<CR> // For going to NERDTree
nmap <silent> <D-l> :wincmd l<CR> // For going back to file I'm working on.
In the left-hand side of a mapping, Command+Left is written <D-Left>. With this and other issues fixed (see below), your mappings should look like this:
nnoremap <D-Left> <Cmd>wincmd h<CR>
nnoremap <D-Right> <Cmd>wincmd l<CR>
or, simply, like this:
nnoremap <D-Left> <C-w>h
nnoremap <D-Right> <C-w>l
Other issues:
Recursive mappings (nmap) should be reserved to the rare situations where you want to use another mapping in your mapping. This is not the case, here, so nnoremap is the best choice.
The mapped commands don't echo anything so <silent> is useless.
Vim's comment leader is ", not //.
You can't have comments on the same line as a mapping anyway, see :help map-comments.
The newish :help <Cmd> is cleaner than using : in the right-hand side of a mapping.
Note that these mappings only work in the MacVim GUI.

switching between tabs in vim with vim-airline

I am using vim-airline plugin which works pretty good however, the only way to switch between tabs is to user :bp or :bn which is shortcuts for :bprevious or :bnext. The problem with this is that if I am on first tab and want to switch to the last tab i.e. 10th tab then I have to type :bn ten times to get there. How can I switch directly? Maybe something pressing arrow keys would be beneficial.
Your problem is that you installed a plugin designed to obfuscate Vim's regular commands and workflows without even knowing those regular ways. The shortcut you took lead you to a dead-end so your only reasonable solution is to go back to the main road and learn Vim properly, without training wheels and crutches.
So… from your question, it seems you are using Airline's so-called "smarter tabline" which displays your open buffers in a fake tabline.
If it was a real tabline, they would actually be tab pages and you would move between them with their own set of commands.
But they are buffers and yes, you are supposed to move between them with these commands:
:bnext
:bprevious
:bfirst
:blast
:b10
:b <buffer-name>
which can all be mapped for your convenience, of course.
But… that plugin doesn't show buffer numbers, so you can't use :b10 to jump reliably to the tenth buffer in your fake "tabline" so that's one less tool in your tool-belt.
And some special buffers, like the quickfix list, can be reached with :bn/:bn without — probably — being listed in your fake "tabline" so that makes your fake "tabline" a rather poor abstraction, even without considering the glaring limitations of tabs in general.
And there's the idiosyncratic behavior of that fake "tabline" which becomes a semi-real "tabline" when you actually use tab pages.
Conflating two very different — and powerful in their own ways — concepts into a single bastardized one is not really a good idea.
I suggest you disable that option and use buffers and tab pages as they are meant to be used.
Reference:
:help buffers
:help tab-page
Agree with #romainl but you can always map your +tab to :bn or :bp for your ease.
" Tab navigation like Firefox.
nnoremap <C-S-tab> :bprevious<CR>
nnoremap <C-tab> :bnext<CR>
In addition to Rafi's answer, put this in your .vimrc to get direct access to a buffer / airline tab.
nmap <leader>1 :bfirst<CR>
nmap <leader>2 :bfirst<CR>:bn<CR>
nmap <leader>3 :bfirst<CR>:2bn<CR>
nmap <leader>4 :bfirst<CR>:3bn<CR>
...
Alternatively, you can double down on airline with
let g:airline#extensions#tabline#buffer_idx_mode = 1
nmap <leader>1 <Plug>AirlineSelectTab1
nmap <leader>2 <Plug>AirlineSelectTab2
if you are using vim-airline, I'm strongly suggested that to using AirlineSelectTab command, you can see it via :help airline, below is the configuration.
let g:airline#extensions#tabline#buffer_idx_mode = 1
nmap <leader>1 <Plug>AirlineSelectTab1
nmap <leader>2 <Plug>AirlineSelectTab2
nmap <leader>3 <Plug>AirlineSelectTab3
nmap <leader>4 <Plug>AirlineSelectTab4
nmap <leader>5 <Plug>AirlineSelectTab5
nmap <leader>6 <Plug>AirlineSelectTab6
nmap <leader>7 <Plug>AirlineSelectTab7
nmap <leader>8 <Plug>AirlineSelectTab8
nmap <leader>9 <Plug>AirlineSelectTab9
nmap <leader>0 <Plug>AirlineSelectTab0
nmap <leader>- <Plug>AirlineSelectPrevTab
nmap <leader>+ <Plug>AirlineSelectNextTab
If you are using tabs instead of buffers
" Tab navigation (works only in gvim, not in console)
nnoremap <C-tab> gt
nnoremap <C-S-tab> gT
I have configured vim to switch between tabs using Ctrl + arrow keys.
Ctrl + ← will switch to tab that is on the left of current tab.
Ctrl + → will switch to tab that is on the right of current tab.
Ctrl + ↑ will switch to first tab.
Ctrl + ↓ will switch to last tab.
To achieve above behaviour update your vimrc with following lines:
nnoremap <C-Left> :tabprevious<CR>
nnoremap <C-Right> :tabnext<CR>
nnoremap <C-Up> :tabfirst<CR>
nnoremap <C-Down> :tablast<CR>
This works with vim-airline plugin as well.
Reference: Using vim tab pages

Vim mappings/command not working

I am working with split windows in vim, but I am having trouble navigating and resizing split windows.
I have added these mappings to my .vimrc text file:
nmap <silent> <A-Up> :wincmd k<CR>
nmap <silent> <A-Down> :wincmd j<CR>
nmap <silent> <A-Left> :wincmd h<CR>
nmap <silent> <A-Right> :wincmd l<CR>
But still, when pressing <A-Left> it does not move window. Also I am using <C-w> +, but the windows do not resize! I also tried <C-w> <, but it resizes like 1 pixel at a time! Is there any faster way to resize split windows?
10 Ctrl-W+ increases the window size by 10 lines. To resize all Windows to the same size, you can use CTRL-W = and to increase a window to its maximum size, use Ctrl-W _.
To resize in different steps, you can create maps that will adjust the window size differently. For example to increase the window size by a factor of 1.5 and decrease the window size by 0.67, you can map this:
nnoremap <silent> <Leader>+ :exe "resize " . (winheight(0) * 3/2)<CR>
nnoremap <silent> <Leader>- :exe "resize " . (winheight(0) * 2/3)<CR>
Alternatively you can use the :resize command to change the height of the window, to change the window width, use the :vertical modifier. So to resize by 10 lines, use:
:res +10
:res -10
as for navigation try
nnoremap <C-h> <C-w>h
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-l> <C-w>l
The <C-W> commands resize by individual lines / columns (pixels wouldn't even be possible in console Vim), but you are supposed to prepend a number before them to change larger amounts at once. (A lot of Vim commands take such a [count], as it's called in the help.)
For the <A-Up> mappings, do they work in graphical GVIM, but not in the console?! The mapping definitions look fine (but you should use :nnoremap).
Due to the way that the keyboard input is handled internally, some key combinations, like Ctrl + non-alphabetic cannot be mapped, and Ctrl + letter vs. Ctrl + Shift + letter cannot be distinguished. (Unless your terminal sends a distinct termcap code for it, which most don't.) In insert or command-line mode, try typing the key combination. If nothing happens / is inserted, you cannot use that key combination. This is a known pain point, and the subject of various discussions on vim_dev and the #vim IRC channel.
Some people (foremost Paul LeoNerd Evans) want to fix that (even for console Vim in terminals that support this), and have floated various proposals, cp. http://groups.google.com/group/vim_dev/browse_thread/thread/626e83fa4588b32a/bfbcb22f37a8a1f8
But as of today, no patches or volunteers have yet come forward, though many have expressed a desire to have this in a future Vim 8 major release.

VIM auto resize focused window

I am slowly learning vim and its powerful capabilities.
I have a question in regards to splitting windows (mainly horizontal splits).
Is there a way to automatically resize the currently selected (focused) window? Let's say, for example, a setting so that the focused window will always take up 70% of the screen.
Using Ctrl-w (number) +/- every time is not really efficient, especially when I am jumping between a few files constantly.
Also it would be cool if there was a way to restrict it to only horizontally splitted windows.
The 'winheight' setting determines the minimal number of lines for the current window. Some users set this to 999 for "Rolodex mode". The following sets this to 70%:
:let &winheight = &lines * 7 / 10
For anything fancier, you can hook into the WinEnter event via an :autocmd, and then set the window height to N via :Nwincmd _. Stupid example:
:autocmd WinEnter * execute winnr() * 2 . 'wincmd _'
Sounds like you want golden-ratio : Resize windows automatically using the Golden Ratio.
Once I found out you could disable the "automatic" part of golden-ratio, I started using it myself with these settings:
" Don't resize automatically.
let g:golden_ratio_autocommand = 0
" Mnemonic: - is next to =, but instead of resizing equally, all windows are
" resized to focus on the current.
nmap <C-w>- <Plug>(golden_ratio_resize)
" Fill screen with current window.
nnoremap <C-w>+ <C-w><Bar><C-w>_
I use these mapping for split screens:
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-h> <C-w>h
nnoremap <C-l> <C-w>l
nnoremap c<C-j> :bel sp new<cr>
nnoremap c<C-k> :abo sp new<cr>
nnoremap c<C-h> :lefta vsp new<cr>
nnoremap c<C-l> :rightb vsp new<cr>
nnoremap g<C-j> <C-w>j<C-w>_
nnoremap g<C-k> <C-w>k<C-w>_
nnoremap g<C-h> <C-w>h<C-w>_
nnoremap g<C-l> <C-w>l<C-w>_
nnoremap d<C-j> <C-w>j<C-w>c
nnoremap d<C-k> <C-w>k<C-w>c
nnoremap d<C-h> <C-w>h<C-w>c
nnoremap d<C-l> <C-w>l<C-w>c
This way if you want to jump between splits you can use C-hjkl. If you want to "create" a split you can use cC-hjkl. If you want to maximize a split you can use gC-hjkl. And if you want to delete a split you can use dC-hjkl.
If you want specifically 70% instead of maximized that you could use
nnoremap g<C-j> <C-w>j:let &winheight = &lines * 7 / 10<cr>
for example.

easier way to navigate between vim split panes

I am using NERDTree on vim and usually open files with i
Is there an easy way to switch between different panes? Currently I use CTRL+W+W to move from one pane to another.
Long ago I found a tip (once on vim.org, now on wikia, apparently) that I've stuck with. Remap ctrl-[hjkl] to navigate splits. It has served me well.
" Use ctrl-[hjkl] to select the active split!
nmap <silent> <c-k> :wincmd k<CR>
nmap <silent> <c-j> :wincmd j<CR>
nmap <silent> <c-h> :wincmd h<CR>
nmap <silent> <c-l> :wincmd l<CR>
I prefer hitting single keys over hitting key-chords. The following maps pane movement to arrow keys:
" Smart way to move between panes
map <up> <C-w><up>
map <down> <C-w><down>
map <left> <C-w><left>
map <right> <C-w><right>
I know this is an old question, but I have a perfect way. Using the number of the split.
split_number C-w C-w
The panes are numbered from top-left to bottom-right with the first one getting the number 1.
for example to go to split number 3 do this 3 C-w C-w, press Ctrl-w twice.
Key mappings are definitely the way to go. I use the mappings mentioned by overthink. I also include the following mappings in my vimrc to move the splits themselves.
" Move the splits arround!
nmap <silent> <c-s-k> <C-W>k
nmap <silent> <c-s-j> <C-W>j
nmap <silent> <c-s-h> <C-W>h
nmap <silent> <c-s-l> <C-W>l
This makes it so that if the split opens in the wrong spot (lets say the left side and I want it on the right) I go to that split and hit <C-S-l> and the split moves where I want it to.
In order to be consistent with changing tabs via gt & gT, I'm currently trying out the g mappings for changing splits. I tend to hit the shift key as I go for the Ctrl key so this helps me avoid that mistake until I get better at not doing so.
nnoremap gh <C-W><C-H>
nnoremap gj <C-W><C-J>
nnoremap gk <C-W><C-K>
nnoremap gl <C-W><C-L>
I have mapped ctrl+w ctrl+w to <tab> (under normal mode as in normal mode tab does not have any use)and that's have made my life easier as now I can switch between panes easily by pressing <tab>.
For switching to a particular pane, I can press <i> + <tab> to switch between panes as split window panes also got their own number which can replace i.
Ex. i = 1,2...n.
Very easy way of achieving it. Type this shortcut twice, and that should work
ctrl+w ctrl+w

Resources