Automatically save a buffer when using bdelete command in Vim - vim

I would like to automatically write a buffer on removing it from the list of open buffers with the bd the same way I use x when I only have one open buffer.
I have set the set hidden option of course.
I have tried to put autocmd BufDelete * w (or ... update or ...w!) but alas it does not work.
I have also tried to set autowrite in my .vimrc although it does more than what I would like but it did not work either :
No matter what vim complains that the changes have not been written.
I did read the manual :h autowrite/hidden/autocmd-events and did not find my answer.
How do I do it or what am I missing ? Is there something wrong with my buffer workflow ?
Thanks in advance.

I think this is the only way:
function! CarefullyDelCurrentBuf()
update
bdelete!
endfunction
command! BD call CarefullyDelCurrentBuf()
Now use :BD instead of :bd.

Related

VIM : syntax highlighting gone after clicking another file

I have a problem with syntax highlighting in gvim.
i have the following command in my vimrc file:
autocmd BufNewFile,BufRead *.v,*.vs,*.va set syntax=verilog
However if i'm in gvim reading a file - "a.txt" and i also have "b.txt" open on split, when i click on b and then return to a , the syntax highlighting is gone after the click.
someone tried to explain to me that the autocmd not always running.
any ideas
The BufRead option only applies when reading a file into a new buffer, so it makes sense that simply switching between splits won't trigger the auto command. The file has already been read into the buffer; it's not read again unless you close and reopen it.
You want the option BufEnter, as it triggers on entering a buffer. Your new command should then look like:
autocmd BufNewFile,BufRead,BufEnter *.v,*.vs,*.va set syntax=verilog
As a side note, it's probably better to use filetype instead of syntax, as syntax won't affect indentation rules, if there are any. Or even better, use a plugin to get everything set up automagically without needing explicit autocommands in your .vimrc. Just from a quick Google, this plugin pops up a bunch.

vim syntax off when one buffer quit?

I have two buffers in my vim session, and I set syntax on in my vimrc , I used minibufexpl to manage bufs.
I used :q to quit the current buf, but the other buf would auto set the syntax off, I have to use :set syntax=on to open the syntax highlight manually. Could someone give me a solution that not set the syntax off automatic after one buf quit? Thanks!! (I tried :bd to quit the buf instead of :q, sometimes it stay the syntax on but sometimes no).
If you're using minibufexpl.vim, add the following to your .vimrc:
let g:miniBufExplForceSyntaxEnable = 1
It appears to be caused by a bug in vim. For the details, refer to the release notes for minibufexpl version 6.3.1
Note that this will work for :bd but not :q
This might be much too late, but I was experiencing the exact same problem and found that adding the line
set hidden
to my .vimrc solves this problem. This makes vim hide buffers rather than closing them when you enter ":q" It also seems to keep my syntax highlighting enabled between files when I navigate with minibufexplorer.
Hope this helps.
You can use syntax enable or syntax on in your vimrc. For more info use :h syntax.
Ok then check that your syntax files are correct, it should looke like this
au BufNewFile,BufRead *.cpp set syntax=cpp11 <-- it's the line I have for cpp files.
Hope this help.
May be you should add this line to gvimrc:
autocmd BufDelete * syntax on
A plugin is misbehaving.
After closing the buffer (and losing syntax highlighting), investigate, by e.g.
:verbose set syntax?
This will show something like
syntax=cpp
Last set from C:\Program Files\Vim\vim73\syntax\syntax.vim
You might also be able to see what goes wrong my doing
:debug quit
If all else fails, try eliminating sources of errors by disabling plugins one-by-one (or removing all, and enabling one-by-one). At some point the problem will appear/disappear and you have found the guilty party.

How can I make Vim autosave files when it loses focus?

I'm used to my editors autosaving files when they lose focus. I recently switched to MacVim, and I can't recreate that behavior. I tried this:
autocmd BufLeave,FocusLost * wall
but if a buffer is unnamed when the window or MacVim loses focus, I get an error like the following:
Error detected while processing BufLeave Auto commands for "*":
E141: No file name for buffer 1
I'm confused, because :wall's documentation says:
Write all changed buffers. Buffers without a file
name or which are readonly are not written.
so I'd expect it to skip unnamed buffers. Is there a better way to do this?
Edit:
I'm pretty sure that the better way to do what I intended by using BufLeave -- saving buffers when I switch between them, so I don't get "No write since last change" -- is to set 'autowriteall'. The question still stands for when MacVim loses focus to other applications (FocusLost).
You don’t care about errors in those circumstances since there is nothing you can reasonably do about them anyway – especially when losing focus. So just swallow them:
autocmd BufLeave,FocusLost * silent! wall
Much simpler than an elaborate dance to figure out where there would be an error in order to avoid it.
I suspect when docs for wall say "without a file name" they may be referring to buffers with buftype=nofile . One way to get what you want would be to have the autocmd have bufdo call a simple function. E.g., some untested code to give the idea:
autocmd BufLeave,FocusLost * bufdo! call WriteFile()
function WriteFile()
if (&buftype=="") && (expand("%:r") > "") && (&readonly==0)
write
endif
endfunction
I think the standard way of getting something like this automatic saving of buffers would be to set the autosave option in Vim.
autocmd BufLeave,FocusLost * bufdo! call WriteFile()
function WriteFile()
if (&buftype=="") && (expand("%:r") > "") && (&readonly==0)
write
endif
endfunction
This method has a side-effect that, you can only open one unamed buffer. If you open the second one, it would automatically be synced to the content of the first unamed buffer.
just put this in .vimrc
set updatetime=1000
autocmd CursorHoldI * silent w

Vim: Delete Buffer When Quitting Split Window

I have this very useful function in my .vimrc:
function! MyGitDiff()
!git cat-file blob HEAD:% > temp/compare.tmp
diffthis
belowright vertical new
edit temp/compare.tmp
diffthis
endfunction
What it does is basically opening the file I am currently working on from repository in a vertical split window, then compare with it. This is very handy, as I can easily compare changes to the original file.
However, there is a problem. After finishing the compare, I remove the split window by typing :q. This however doesn't remove the buffer from the buffer list and I can still see the compare.tmp file in the buffer list. This is annoying because whenever I make new compare, I get this message:
Warning: File "temp/compare.tmp" has changed since editing started.
Is there anyway to delete the file from buffers as well as closing the vertical split window?
Perhaps you need the bwipe command?
:bw[ipeout][!] N1 N2 ...
Like |:bdelete|, but really delete the buffer. Everything
related to the buffer is lost. All marks in this buffer
become invalid, option settings are lost, etc. Don't use this
unless you know what you are doing.
One option would be to define the following:
function! DelBuf(filename)
let bname = bufname(filename)
if l:bname != ""
let bidx = buffer_number(l:bname)
exec = "bw " . l:bidx
endif
endfunction
and add a call to DelBuf("comapre.tmp") at the beginning of your function.
In theory it should be possible to bind DelBuf to the `bufhidden event like this:
autocmd! bufhidden "compare.tmp" call DelTmp("compare.tmp")
... but for some reason it didn't work for me.
You need to use autocmd winleave bd (buffer delete). Be warned that if you have the buffer open in more than one window they will all be removed.
I usually define the following things for diff-buffers:
setlocal bt=nofile bh=wipe nobl noswf ro
nnoremap <buffer> q :bw<cr>
The first line is what will make the difference in your case (:h 'bh' -> no need for a single execution autcocommand), the second line is just a shortcut.
BTW: use r! git instead of producing a temporary file. This way, you won't have to clear that file either.

How can I execute a command when a buffer is closed in vim?

Is there something like a close-window-hook in vim/vimscript, so that I can call a function every time a window is closed?
I want to use it for the following scenario:
I use an extra scratch window to display information about the file, and when I close the file I want the scratch window to be closed automatically so that vim exits.
If you have any ideas how to achieve that without a hook that will be just as fine.
edit:
I know about :qa[ll], but I am lazy and only want to type :q or ZZ.
edit2.71828183:
I accepted the autocommand answer as it was closest to the original question, but found another solution in using a preview window instead of a split window. A preview window is automatically closed when the last "normal" window is closed..
autocommands are amazing! I'm pretty sure that in this case, BufLeave will do the job, but you might want BufWinLeave? Have a look at :help autocmd-events for a full list of events.
The other bit you'll care about is: you can have buffer-local autocommands! (:help autocmd-buflocal)
You can define one for the current buffer using au BufLeave <buffer> .... My best guess is that you could run this in whatever command creates the scratch window. You should be able to cache the scratch window's buffer number in a global variable when you open the scratch window, then your autocommand could just delete that buffer (:help :bdelete).
au BufLeave <buffer> bdelete g:scratch_buffer
call CreateScratchWindow()
function CreateScratchWindow() {
...
let g:scratch_buffer = bufnr("")
}
There's also a function winbufnr, for getting buffer numbers by window. You can use either one - just make sure that the scratch window/buffer is current when you use it! (The "" means current window/buffer).
Add a mapping.
:nnoremap :q :qa
then, if you only want to use :q one day, you can just
:qa<backspace>
and normally, you can just
:q<enter>
and get
:qa<enter>
for free.
Ok, not really a new question, but I found it looking for, what I now know, BufWinLeave. However, the scenario the author is describing is something I have in my vimrc with NerdTree, e.g. when the last buffer is closed, I want vim to close the NerdTree "buffer" and then quit.
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
Replace the NERDTree specific stuff with how the scratch buffer is identified.
You can use
:quitall
or
:qall
to close all windows at once.
add a ! if you want to ignore unsaved changes.
:qall!

Resources