How to delete a buffer in Vim without losing the split window? - vim

When a buffer gets deleted (via the :bd[elete] command), it not only deletes the buffer but also removes the split window that buffer was in.
Is there a way to delete/unload a buffer and keep the window split?

bp|bd # will do it.
Details: The bp command (“buffer previous”) moves us to a different buffer in the current window (bn would work, too), then bd # (“buffer delete” “alternate file”) deletes the buffer we just moved away from. See :help bp, :help bd, and :help alternate-file.

I really like bufkill.vim there is a github repo as well

You can add the following to your .vimrc to have Bd work as bd but without touching the window splits:
command Bd bp\|bd \#
I found this as a useful complement to what Mud answered.

See deleting a buffer without closing the window on VIM tips wiki.

I do something similar to #Mud, but switch to previous view buffer, #, instead of the previous buffer in buffer list. Here is a binding key in my .vimrc:
nnoremap <silent> <leader>q :lclose<bar>b#<bar>bd #<CR>
Close Location windows, if exist, switch to the previous view buffer, and then close the last switched buffer.

My Choice is
:sb # | bd #
:sb 1 | bd #
: <1. Recall Buffer> | <2. Delete Buffer>
Think Like that! /// <1. Recall Buffer> | <2. Delete Buffer>
:vert sb 2 | bd #
:vert sb <tab key~completed file(buffer)name> | bd #
why?! It's easy to remember 3 (+ 1) keyword!
sb split_buffer
bd delete buffer ▶ simple 2 keywords
# or Number of buffer
vert ▶ short_form of vertical (split_buffer or else)
That are easy and very useful in many other many case!
Have a nice Day! :)

I used to use :
:bp<bar>sp<bar>bn<bar>bd<CR>
But I found certain occasions where it closed my window. On top of that the next or previous buffer might not be what you want to be displayed in the split.
Now I do this :
switch to the buffer I want to work on
Delete the alternate buffer
nnoremap <leader>d :bd#<CR>

I actually like the behaviour of :bd some of the time so I use the following combination:
nmap <silent> <Leader>d :enew \| bd#<Return>
nmap <silent> <Leader>w :bd<CR>
This allows me to use <Leader>d to close a buffer whilst maintaining splits and <Leader>w to close a buffer and split simultaneously.
:enew creates a new buffer and switches focus to it
bd # delete the last buffer that was focused

Related

Quickly switch between buffers?

I have a lot of buffers open and to switch between then I Ctrl+w and then Ctrl+[movement key]. Is there a better way? Because this way when I've to do more than one movement I end up having to press 4 keys.
If you want to move between windows, you always can map Ctrl-W, H/J/K/L to anything you want:
map <C-h> <C-w>h
map <C-j> <C-w>j
map <C-k> <C-w>k
map <C-l> <C-w>l
If you want to move between buffers, you can use :buffer command, print a part of the file name you want to go to: pressing Tab will cycle through all files that contains this part in the names. E.g you want to show buffer with filename 'some_long_c_file.c' and you know you don't have any other opened file whose name ends with 'file.c': just type :buffer file.c and press Tab (or even 'ile.c' or shorter), this will complete it to 'some_long_c_file.c'.
For quick switching between the two last buffers, use Ctrl-^
The best way I've found to do this is to install bufexplorer.vim. That let's you quickly switch to a screen in which you can select any buffer. You can also close buffers etc..
Here's a screenshot of my vim with bufexplorer open showing it's help screen:
For me the solution was two-fold:
1) Use unimpaired - so ]b and [b
2) map :b# to switch to previous buffer. I used map <cr> :b#<cr> . (so enter key would toggle back and forth between two open buffers).

how to navigate the opened files in vim?

I opened a files in vim using
gf
command.which opened a file that the current cursor position.
I used
ctrl + ^
is used to toggle between the last two opened files.
But,
How can i go forward and backward opened the files?
:bn & :bp to cycle buffers
To cycle windows I use ctrl+w+w
To cycle opened file :next & :prev
To list opened buffers: :ls
from good old vi :e# reopens previous file ^^ (not using it since ages... well since VIM comes to my systems ^^)
EDIT: a quick test on gvim in windows (set nocp)
map <C-tab> ^[:bn^M
in order to enter escape (^[) and enter (^M) you have to press ctrl+v and then the special char
EDIT 2: a cleaner way to do this is putting this in .vimrc
map <C-tab> <esc>:bn<cr>
but just remember that using mnemonics for the keys depends on some other options (I cannot remember which one).
The best way is IMHO to write a VIM function saving the actual mode, performing switch and then restoring it, then mapping it to in every mode (:[xxx]map commands)
:next to next file
:prev to previous file
Alternatively, you might want to check out any one of the plugins trying to make buffer navigation easier
I myself have reduced it to <leader>bx, x being the number of the buffer.
Selecting the buffer is done via a nice popup list at the bottom.
To get this behavior, you would first install LustyJuggler ( https://github.com/vim-scripts/LustyJuggler ), and then set up the shortcut like so in your vimrc file:
nmap <leader>b :LustyJuggler<CR>
Note that this mapping only works when you are in normal mode.
You can also map the TAB key to quickly cycle through open buffers.
Add the following to your vimrc file:
:nnoremap <Tab> :bnext<CR>
:nnoremap <S-Tab> :bprevious<CR>

Quickly switching buffers in Vim normal mode

Recently I found out that I'm "using tabs incorrectly" in Vim. I've been trying to just use buffers in Vim since, assisted through MiniBufExplorer, but I find it painful because of how many keystrokes it takes to change buffers from normal mode. With tabs, I can just do gt or gT to hop back and forth between tabs in normal mode, and I can also do NUMBERgt to go to a specific tab.
With buffers, I either have to enter command mode with :bn, :bp, or with MiniBufExplorer, use Ctrl + k or Ctrl + Up to hop up to the buffer window, scroll left or right with h and l and then hit Enter to select the buffer I want. Or I can do something involving a leader sequence, but it always requires removing multiple fingers away from home row. That's a real pain.
How can I get something equivalent switching tabs in normal mode to switch buffers in normal mode, so I can do something like gn/gp for :bn/:bp and NUMBERgn for :buf NUMBER?
Add this to your .vimrc
map gn :bnext<cr>
map gp :bprevious<cr>
map gd :bdelete<cr>
" I personally use <leader>
map <leader>n :bnext<cr>
map <leader>p :bprevious<cr>
map <leader>d :bdelete<cr>
Note that you are remapping gp and gd, but maybe you don't care about that (:help gp, :help gd).
For more information on how to map key strokes see :help map-overview and :help map.txt.
Btw, I personally use <leader> instead of g in the mapping. My <leader> is set to ;. This puts my <leader> key on the home row which makes me willing to map all kinds of stuff using <leader>. :help mapleader if you want to change your <leader> key.
The way I usually switch between buffers is to use the :buffer command with the built-in autocompletion, e.g. :b prof<Tab> to switch to folder/path/LoginProfileFactory.php.
You can just start typing any part of the file name of the buffer you need, which is nice.
Less often, I actually remember the numbers of the buffers I want and I use something like :b 3 or :3b.
I see you mention you don't like :buf 3 though, so Rumple Stiltskin has an alternative to the :3b style that you may prefer.
{count}CTRL-^ switches to the count numbered buffer.
I have the following lines in .vimrc:
nnoremap <silent> <tab> :if &modifiable && !&readonly && &modified <CR> :write<CR> :endif<CR>:bnext<CR>
nnoremap <silent> <s-tab> :if &modifiable && !&readonly && &modified <CR> :write<CR> :endif<CR>:bprevious<CR>
Now a Tab let you go to the next buffer and a Shift-Tab to the previous.
This is based on Nick Knowlson's answer, but I wanted to expand on my comment there ...
Type :b <Tab> (note the space), then cycle through the open buffers with Tab or ← / →.
... which gets us closer to the Ctrl + Tab in all the other editors and browsers I use.
It's actually even better in some ways, you can then go backwards and forwards with ← / → arrows. It avoids the thumb + finger fu to type Ctrl + Shift + Tab to go backwards through the tabs in editors and browsers.
N.B. Shift + Tab just does the same as Tab
This is then actually something like Win + Tab in Windows 10, where once you first open up the window and you can then move around using the arrow keys.
Edit: I have two further tricks that I picked up for using buffers:
From this answer I have this in my .vimrc:
nnoremap <leader>bb :buffers<cr>:b<space>
it opens the :ls / :buffers command and pre-types the :b so that you just have to type the buffer number as you'll see a list with all the buffers and their numbers.
I also have
nnoremap <leader><tab> :b#<cr>
which toggles between the current and most recently used buffers, it's a bit like doing cd - when switching back and forth between directories
I use the plugin unimpaired.vim
it defines mappings [b and ]b that jump to the previous and next buffer in the list.
For jumping for a specific buffer the best option I know is the one you mentioned: :b<number>
If you go into another buffer you can came back quickly by typing <c-^>
Expanding on Rumple Stiltskin's answer, if you know that the file you want to get to is in buffer 4, for example, you can get there quickly with
4Ctrl-^
On my UK keyboard, I can actually do 4Ctrl-6, as explained in
:help CTRL-^
By the way, you can see the buffer numbers with
:buffers
or
:ls
I use LustyExplorer: I hit <leader>b to open a list of buffers then a couple of letters from the name of the buffer I want to open then enter. Easy.
But, you are not "using tabs incorrectly", you are using tabs the way you want. If it worked for you why go through the pain of unlearning your way to learn "the right way"?
I use F9 and F10 to move between the previous/next buffer with this mapping:
map <F9> :bprevious<CR>
map <F10> :bnext<CR>
For me this is the fastest way to switch buffers.
fzf.vim is another fast way to changes buffers using fuzzy matching. This plug-in ships with the default command:
:Buffers
which opens the list of all open buffers similar to :ls but a buffer can be (fuzzy) searched and selected.
Opening the buffer in the current window is through enter, but can can also be opened in a new split (h or v) or tab using ^X ^V or ^T respectively.
Noteworthy is also:
:Lines
Which allows to search through the content of all open buffers. This can be handy if you forget the name of a buffer but you know what it should contain.
Here is my solution:
" `<leader><Tab>` - next buffer;
nnoremap <silent> <leader><Tab> :bnext<CR>
" `<leader><S-Tab>` - previous buffer;
nnoremap <silent> <leader><S-Tab> :bprevious<CR>
" `_bufferNumber_ + <Tab>` - go exact the buffer number;
nnoremap <silent> <Tab> <C-^>
By the way, I use 'buftabline' plugin and set let g:buftabline_numbers = 1 to spread my buffer on the tabline.
I make it easier for myself:
In .vimrc :
nnoremap <leader>bf :buffers<CR>:buffer "<- Last spaces is necessary
For example, in normal mode, say your leader key is \(default it is), type \bf, then you have a list of opened buffers, type number of buffer you want and hit enter key.
NOTE: remember that last spaces not necessary at all if you wich type it after :D
Jut like that ;)
More detail:
<C-O> Navigate backward
<C-I> Navigate forward
So there is no need extra remapping, otherwise you remapped them.
I think bufexplorer is a nice plugin to use. <leader>be brings up an interactive buffer explorer that lists all open buffers. You could quickly move through the list and Enter puts you in the selected buffer. Unlike LustyExplorer It has no dependency to ruby.
I prefer navigating between buffers similarly to how I'm navigating between window panes: <alt-h> and <alt-l>. This is to straightforward to set on Mac because <alt>/<option> key binds are bounded to specific characters.
" Buffer navigation
map ˙ :bp<cr>
map ¬ :bn<cr>
map § <c-^>
Here is a good answer that shows how you can see characters maped to <alt-..> combinations

Vim: Close All Buffers But This One

How can I close all buffers in Vim except the one I am currently editing?
I was able to do this pretty easily like this:
:%bd|e#
Try this
bufdo bd
bufdo runs command for all buffers
http://vim.wikia.com/wiki/Run_a_command_in_multiple_buffers
You could use this script from vim.org:
http://www.vim.org/scripts/script.php?script_id=1071
Just put it to your .vim/plugin directory and then use :BufOnly command to close all buffers but the active one. You could also map it elsewhere you like in your .vimrc.
Source on Github (via vim-scripts mirror): https://github.com/vim-scripts/BufOnly.vim/blob/master/plugin/BufOnly.vim
If you don´t care the current one, is more simple to do something like (no script needing):
1,100bd
I do this
:w | %bd | e#
My favorite if I just want my current buffer open and close all others.
How it works: first write current buffer's changes, then close all open buffers, then reopen the buffer I was currently on. In Vim, the | chains the execution of commands together. If your buffer is up to date the above can be shortened to :%bd | e#
Building on juananruiz's answer.
Make a small change in the buffer you want to keep, then
:1,1000bd
The command bd (buffer delete) will not delete any buffers with unsaved changes. This way you can keep the current (changed) file in the buffer list.
Edit: Please notice that this will also delete your NERDTreeBuffer. You can get it back with :NERDTree
Note: As mentioned in the comments, this closes windows and not buffers.
By using
:on[ly][!]
and
:h only
I put this in my .vimrc file
nnoremap <leader>ca :w <bar> %bd <bar> e# <bar> bd# <CR>
then your leader + ca (close all) close all the buffers except the current one.
What it does is
:w - save current buffer
%bd - close all the buffers
e# - open last edited file
bd# - close the unnamed buffer
Here's what I do. So I like to keep my cursor position after removing all buffers and most of the solutions above just ignores this fact. I also think remapping the command is better than typing it so Here I use <leader>bd to remove all buffers and jump back to my original cursor position.
noremap <leader>bd :%bd\|e#\|bd#<cr>\|'"
%bd = delete all buffers.
e# = open the last buffer for editing (Which Is the buffer I'm working on).
bd# to delete the [No Name] buffer that gets created when you use %bd.
The pipe in between just does one command after another. You've gotta escape it though using \|
'" = keep my cursor position.
Closing all open buffers:
silent! execute "1,".bufnr("$")."bd"
Closing all open buffers except for the current one:
function! CloseAllBuffersButCurrent()
let curr = bufnr("%")
let last = bufnr("$")
if curr > 1 | silent! execute "1,".(curr-1)."bd" | endif
if curr < last | silent! execute (curr+1).",".last."bd" | endif
endfunction
Add this function to .vimrc and call it using :call CloseAllBuffersButCurrent().
Convenience map:
nmap <Leader>\c :call CloseAllBuffersButCurrent()<CR>
There's a plugin that does exactly this and a bit more!
Check out close-buffers.vim
so this is an old question but it helped me get some ideas for my project. in order to close all buffers but the one you are currently using, use;
map <leader>o :execute "%bd\|e#"<CR>
The answer with highest votes will reopen the buffer, it will lose the current line we are working on.
Close then reopen will induce a flush on screen
function! CloseOtherBuffer()
let l:bufnr = bufnr()
execute "only"
for buffer in getbufinfo()
if !buffer.listed
continue
endif
if buffer.bufnr == l:bufnr
continue
else
if buffer.changed
echo buffer.name . " has changed, save first"
continue
endif
let l:cmd = "bdelete " . buffer.bufnr
execute l:cmd
endif
endfor
endfunction
let mapleader = ','
nnoremap <leader>o :call CloseOtherBuffer()<CR>
Previous code will take effect when you are on the target buffer and press , + o. It will close all other buffers except current one.
It iterates all the buffers and close all the buffer number which is not equal to current buffer number.
:%bd then Ctrl-o
:%bd to delete all buffers
Ctrl-o to jump back to the last buffer, which would be the "This One" you were referring to.
I like 1,100bd (suggested by juananruiz) which seems to work for me.
I added a quit! to my mapping to give me
nnoremap <leader>bd :1,100bd<CR>
nnoremap <leader>bdq :1,100bd<CR>:q!<CR>
This kills all the buffers and shuts down Vim, which is what I was looking for mostly.
How about just:
ctrl-w o
(thanks to https://thoughtbot.com/blog/vim-splits-move-faster-and-more-naturally)
I combined Alejandro's comment with badteeth's comment:
command! Bonly silent execute "%bd|norm <C-O>"
The norm <C-O> jumps to the last position in the jump list, which means where the cursor was before the %bd.
I used silent instead of silent!. That way, if any open buffers are modified, Vim prints an error message so I know what happened. The modified buffers stay open in my tests.
Unrelated: this is my 500th answer!
nnoremap <leader>x :execute '%bdelete\|edit #\|normal `"'\|bdelete#<CR>
Close all buffers (side-effect creates new empty buffer)
Open last buffer
Jump to last edit position in buffer
Delete empty buffer

Open a buffer as a vertical split in VIM

If you are editing a file in VIM and then you need to open an existing buffer (e.g. from your buffer list: :buffers) how can you open it in a vertical split?
I know that you already can open it with a normal split like:
:sbuffer N
Wehere N is the buffer number you want, however, the above opens that N buffer horizontally, not vertically.
I'm also aware that you can change the window placement after opening and have a Vertical Split like so:
Ctrl-W H
Ctrl-W L
Which will vertically split the window to the right or the left.
It seems to me that if there is a sbuffer there should be a vsbuffer but that doesn't exist (not that I am aware of)
Also, please note that I am not looking for a plugin to solve this question. I know about a wealth of plugins that will allow you to do this.
I am sure I might be missing something that is already there.
EDIT:
In the best spirit of collaboration, I have created a simple Function with a Mapping if someone else stumbles across this issue and do not want to install a plugin:
Function:
" Vertical Split Buffer Function
function VerticalSplitBuffer(buffer)
execute "vert belowright sb" a:buffer
endfunction
Mapping:
" Vertical Split Buffer Mapping
command -nargs=1 Vbuffer call VerticalSplitBuffer(<f-args>)
This accomplishes the task of opening a buffer in a right split, so for buffer 1, you would call it like:
:Vbuffer 1
Try:
:vert sb N
which will open a left vertical split (by default, unless you have modified some options).
To open a split to the right, on the other hand:
:vert belowright sb N
:vsp | b1
1 being some buffer number. Use buffers to list all buffers.
Here's some additional info on splits, if you're interested.
Link
The answer to the OP that I found most useful is embedded deep in Jerinaw's answer and a comment on it, and in Wolfson's answer. But I felt it might be brought out more. (Nor have those been voted most highly, even though they seemed to me the ones that answered OP best.)
The answer to the question, Why is there not :vsbuffer, is that there is. It's called :vsplit and does the trick either as
:vsplit NameOfBuffer
OR
:vsplit #NumberOfBuffer.
(In this second use, take care to note that the hash # is significant. If you want to get to buffer number 3, you need to say :vsplit #3, not just :vsplit 3 which will instead create a new file named "3".)
Again, this answer is embedded above, it's just not brought out clearly enough for the quick scanner, IMV.
You can ease your pain by adding the following to your .vimrc
cabbrev vb vert sb
Now you can use it in the following way.
:vb <buffer>
You can also combine :ls that lists your current buffers and the commands to open the desired buffer in either
current window: :b <N/bufname>
vertical split: :vsp | b <N/bufname>
horizontal split: :sp | b <N/bufname>
For this, I've added the following mappings to my ~/.vimrc (order of mappings represents the above list of desired windows)
nnoremap <leader>b :ls<cr>:b<space>
nnoremap <leader>v :ls<cr>:vsp<space>\|<space>b<space>
nnoremap <leader>s :ls<cr>:sp<space>\|<space>b<space>
Based on this, you can see the buffer list as soon as you hit
<leader>b
<leader>v
<leader>s
and then just enter the desired buffer number N. This will then open the buffer in the desired window. You can of course still use a part of the buffer name bufname as well.
I mapped the <leader> to , based on
let mapleader = ","
For some people (e.g. me) this could even replace plugins like MiniBufExpl and thus save space on the screen.
you can use Neovim,like that:
autocmd FileType python nmap <F5> :rightbelow vertical split <bar> :term python %<cr>

Resources