Possible to access the NERDTree buffer in vimscript? - vim

I'm working on a plugin for NERDTree that I asked about here.
I've got a proof of concept plugin working up on Github and a pull request in to NERDTree with the hooks I need to edit the display strings.
The next thing I'd like to get working is refreshing the NERDTree buffer whenever a file is saved. I was thinking that the NERDTree api function "NERDTreeRender()" would be all I needed - something like:
autocmd BufWrite * call NERDTreeRender()
would work, but it called NERDTreeRender() on the buffer that was written, instead of the NERDTree one. Is there any way to have an autocmd run on bufwrite to that specific buffer? Running :buffers in vim doesn't give me any indication that NERDTree has a numbered buffer unfortunately.
Barring firing the autocmd on write to that specific buffer, does anyone have any other suggested ways to go about this?

You can switch to the NERDTree buffer by setting switchbuf to useopen and calling sbuf NERD*
Something like:
autocmd BufWrite * call DoRender()
function! DoRender()
set switchbuf+=useopen
sbuf NERD*
call NERDTreeRender()
endfunction

Related

autocmd event to execute a command on :wq - vimscript?

I want to execute system("cp /home/currently_opened_file.txt /somewhere/else") when I exit vim with :wq. Is there an autocmd event for that? Or any other way to do it?
Update:
The OP noted in comments that this combination did exactly what was wanted (execute the command only on :wq).
:autocmd BufWritePost * :autocmd VimLeave * :!cp % /somewhere/else
Original answer:
You can hook the BufWritePost event. This will run the command on every write, not only when you use :wq to leave the file.
:autocmd BufWritePost * :!cp % /somewhere/else
I suppose you could try hooking the BufDelete event (before deleting a buffer from the buffer list), but that seems like it would be problematic, as buffers are used for more than file editors. They are also used for things like quicklists, the help viewer, etc.
There are some events that take place when you are quitting, which could be an option.
QuitPre when using :quit, before deciding whether to quit
VimLeavePre before exiting Vim, before writing the viminfo file
VimLeave before exiting Vim, after writing the viminfo file
You can see the full list using :help autocmd-events.
Also note that you can restrict what matches the event. For instance, if you only want this to happen for HTML files and CSS files, you could use this:
:autocmd QuitPre *.html,*.css :!cp % /somewhere/else
I suspect you will need to experiment and see what works for you.
It looks like you need to automatically cascade the writing of a file to another location. My DuplicateWrite plugin provides comfortable commands to set up such. (The plugin page has links to alternative plugins.)
:DuplicateWrite /somewhere/else

Vim calling command on save

I am trying to call this autoformatting plugin on save
Here is my autocommand:
autocmd BufWrite *.css,*.html,*.js,*.py :Autoformat<CR>
When I save nothing happens, if I manually call :Autoformat then the autoformatter runs.
What am I doing wrong?
You've already found the solution - here's the explanation:
The <CR> is for mappings, which work like a recorded sequence of typed keys, so you need to start command-line mode with : and conclude with <CR>. An autocmd takes an Ex command, so the <CR> is taken as an (invalid) argument. You also don't need the :, but that doesn't do harm.
As :help BufWrite shows, this is a synonym for BufWritePre.
BufWrite or BufWritePre Before writing the whole buffer to a file.
So, this is the recommended form:
autocmd BufWritePre *.css,*.html,*.js,*.py Autoformat
From what I've experienced, you sometimes need to surround it in an augroup
augroup autoFormat
autocmd BufWrite *.css,*.html,*.js,*.py :Autoformat<CR>
augroup END
I don't know why but it works for me! Technically just the autocmd should work on its own but sometimes it doesn't. Also, on the GitHub page it says to use :Autoformat<CR><CR>, maybe try that.
For some reason i had to get rid of the carriage return and change to BufWritePre (although the CR is the main issue, the BufWritePre just makes sure it gets changed before the buffer is written instead of after so it gets saved):
autocmd BufWritePre *.css,*.html,*.js,*.py :Autoformat
Why, I don't know?

VIM: Open separate help/hint/text file automatically in a vsplit

I have the following problem, or lets say idea, with vim. When I am writing latex documents I want automatically open a file ~/.vim/latex_hints, where I collected some hints, shortcuts, workarounds,..., in vsplit on the right side. The hint file should be loaded read only and automatically closing when I close the latex document.
After a few experiments I added the following commands to my vimrc:
function Handletexfile()
setlocal cc=80
setlocal wrap
setlocal textwidth=80
belowright vsplit +setl\ ro\ nomodifiable ~/.vim/latex_hints
endfunction
autocmd BufRead,BufNewFile *.tex call Handletexfile()
and
function Handletexfileexit()
let tablist = []
call extend(tablist, tabpagebuflist(tabpagenr()))
for b in tablist
echo b . " ". bufname(b)
if bufname(b) =~ "vim/.*_hints"
echo "Close buffer..". b
execute "bdelete! ".b
endif
endfor
endfunction
autocmd BufWinLeave *.* call Handletexfileexit()
When I open a tex file, my hint file is displayed on the right side as read only and not modifiable. But when I close using :q or :wq the buffers open in the current tab are listed and the one matching to the hint file is selected by the if statement. But I get the following output
1 abstract.tex
2 ~/.vim/latex_hints
Close buffer..2
and my vim crashes with an segfault.
The first part of your requirement translates pretty straightforward into Vimscript:
autocmd BufWinEnter <buffer> belowright vsplit +setl\ ro ~/.vim/latex_hints
Put this into ~/.vim/after/ftplugin/tex.vim, or prepend :autocmd FileType tex to the above command.
The latter part is more complex; on BufWinLeave, you'd have to check all other windows for the opened cheat file with bufwinnr(), go to it (:wincmd w), and :close it.
As an alternative use the preview window with your hint file. The preview window gives you some advantages:
It is small and out of the way
Can close it easily via <c-w>z from any other window
Can jump to the preview window from any window easily via <c-w>P (jump back via <c-w>p)
You can do this via the :pedit command. For example:
autocmd BufWinEnter <buffer> pedit +setl\ ro ~/.vim/latex_hints
Personally I feel like it would be better to create command or mapping to open your hints files as you may eventually out grow the file as time goes on. I would also set the 'bufhidden' to wipe and un-list the buffer with 'nobuflisted'.
You may also want to look into getting a nice snippet plugin.

How to set the default to unfolded when you open a file?

In my .vimrc I've put set foldmethod=syntax to enable folding of methods etc. However, I don't like the default that everytime I open a file, the whole thing is folded. Is there a way to enable foldmethod, yet have files unfolded when I open them?
set foldlevel=99
should open all folds, regardless of method used for folding. With foldlevel=0 all folded, foldlevel=1 only somes, ... higher numbers will close fewer folds.
You can put this in your .vimrc:
au BufRead * normal zR
It declares an automatic command (au), triggered when a buffer is read (BufRead), matching all files (*) and executes the zR (opens all folds) command in normal mode.
set nofoldenable
Adding this to your .vimrc will temporarily disable folding when you open the file, but folds can still be restored with zc
In .vimrc add an autocmd for BufWinEnter to open all folds automatically like this:
autocmd BufWinEnter * silent! :%foldopen!
That tell vim to execute the silent :%foldopen! after opening BunWinEnter event (see :h BufWinEnter). The silent %foldopen! will execute foldopen on the whole buffer thanks to the % and will open all folds recursively because of the !. Any eventual error message will be suppressed by silent. (You could get error messages like E490: No fold found if the buffer actually didn't contain any fold yet)
Note: You could use BufRead instead of BufWinEnter but then if the file has a modeline that enables the folding that will override this autocmd. I mean BufRead autocmds run before the modeline is processed and BufWinEnter will run them after. I find the later to be more useful
You can add
set foldlevelstart=99
to your .vimrc file, and it will start editing any new file with all folds open.
If you want a way to have it display unfolded as soon as it is opened, you can use set foldlevelstart=99 as a lot of answers explained.
But, if you just want to see them unfolded, you can just press zi and it will unfold everything. Another, zi will close them back.
You could map it to keys to enable it.
For example,
nmap ,f :set foldmethod=syntax<CR>
Then while in normal mode hit the ",f" key combination
You can open unfolded file when you put set nofoldenable into your .vimrc file.
autocmd BufReadPost * silent! :%foldopen!
This worked best for me. After a buffer gets opened all folds are opened. This opens them to the correct level.
The set foldenable method was not good, because if I choose to close one fold level, it enabled folding again, and folded every thing to 0 level, instead of just going down one level on the one I activated.

Error in Vim with autocmd: No matching autocommands

I'm using the Vim plugin clang_complete and I want to update the compilation errors in the QuickFix window whenever I save the file. So as the doc says, I must call the function g:ClangUpdateQuickFix().
The thing is that the next autocmd gives me the next message whenever it is executed despite it seems to work:
No matching autocommands
The autocmd I use is:
autocmd BufWritePost *.c,*.cpp,*.cxx,*.cc call g:ClangUpdateQuickFix()
What is the meaning of that message?
The displayed message come from clang_complete itself. Some vim plugins (not clang_complete) are reparsing the quickfix window whenever it changes. Fortunately, vim provide an autocmd for that: QuickFixCmdPost, so these plugins are using this to reparse the quickfix messages.
In clang_complete, since we're modifiying the quickfix window and we don't want to break existing plugins, we need to trigger this autocmd manually. What you get is the No matching autocommands message when you don't use those plugins.

Resources