Close vim if no "unhidden" buffers open - vim

Is there any script that closes vim if there are only utility buffers open? I have seen some scrips for NERDTree (Close vim NERDtree on close of file), but none that is more general.
An example, because I am unsure if it is clear what I mean.
Tagbar, Magit and a file are open
I close the file
only utility buffers are open (both buffers are hidden from :ls) -> vim closes
Is there an easy way to do this?

You can use the following script to do what you want:
augroup auto_close_win
autocmd!
autocmd BufEnter * call s:quit_current_win()
augroup END
" Quit Nvim if we have only one window, and its filetype match our pattern.
function! s:quit_current_win() abort
let quit_filetypes = ['qf', 'vista']
let buftype = getbufvar(bufnr(), '&filetype')
if winnr('$') == 1 && index(quit_filetypes, buftype) != -1
quit
endif
endfunction
We use autocmd BufEnter to check if we have only one window left and the filetype of the current buffer is in the blacklist.
Update the list quit_filetypes to include the filetypes you have in mind.

Related

Autoload netrw when starting vim

I want netrw to autoload when I launch vim using the terminal. Completely new to linux/ubuntu. Is there any way of doing that?
Adding the following to your .vimrc (Vim's configuration file, located in the root of your home directory) will cause Vim to automatically load Netrw after starting up.
" Open Netrw after Vim starts up
augroup InitNetrw
autocmd!
autocmd VimEnter * :silent! Explore
augroup END
A problem with the preceding approach, as implemented, is that Netrw will also load when you use Vim with an argument to open a specific file. A workaround is to use the following modification, based on the suggested approach in Netrw's documentation (:help netrw-activate).
" Checks if there is a file open after Vim starts up,
" and if not, open the current working directory in Netrw.
augroup InitNetrw
autocmd!
autocmd VimEnter * if expand("%") == "" | edit . | endif
augroup END
The following pages have more details on autocommands and the .vimrc configuration file.
https://learnvimscriptthehardway.stevelosh.com/chapters/12.html
https://learnvimscriptthehardway.stevelosh.com/chapters/14.html
https://learnvimscriptthehardway.stevelosh.com/chapters/07.html
And the following code block in your vimrc:
set autochdir
let g:netrw_browse_split=4
augroup InitNetrw
autocmd!
autocmd VimEnter * if argc() == 0 | Lexplore! | endif
augroupend
Kind of does what #dannyadam suggested. But opens the netrw pane as a side bar on the right. If you want to be on the right use Lexplore without the bang(!).

Can VIM automatically close NERDTree when deleting a buffer?

Problem:
In VIM, open NERDTree
Select a file and open it in a new buffer (Enter)
Do some work on buffer and save it
Delete buffer with :bd
Now NERDTree takes up the whole window - this isn't a problem per se, but...
Go to next buffer with :bnext
Continue working
Now try opening NERDTree again by hitting Ctrl-N
You see, NERDTree stays "maximised" and you have to resize it.
My attempt at solving this issue:
My approach was what is stated in the title: close NERDTree automatically when deleting a buffer, then reopen it when entering another.
function! g:CloseNERDTree()
if exists("g:NERDTree") && g:NERDTree.IsOpen()
NERDTreeClose
else
echo "already closed"
endif
endfunction
autocmd BufDelete * call CloseNERDTree()
function! g:OpenNERDTree()
if exists("g:NERDTree") && g:NERDTree.IsOpen()
echo "already open"
else
NERDTree
endif
endfunction
autocmd BufEnter * call OpenNERDTree()
This causes VIM to become unusable and my VimScript knowledge isn't enough to know what's going on.
I cannot reproduce your particular problem (for me, NERDTree always opens in a sidebar), but I think the (or one) problem with your approach is with the BufDelete event. :help BufDelete has the following caveat:
Don't change to another buffer, it will cause problems.
I think it would be better to trigger on WinEnter, and use the number of visible windows (winnr('$')) for the check, like this (untested):
function! OnWinEnter()
if winnr('$') == 1
if exists("g:NERDTree") && g:NERDTree.IsOpen()
NERDTreeClose
endif
else
if ! (exists("g:NERDTree") && g:NERDTree.IsOpen())
NERDTreeOpen
endif
endif
endfunction
autocmd WinEnter * call OnWinEnter()

How do I run an autocommand on every filetype but one?

I have my vim set up to save files whenever I change buffers and on checktime. The problem is that I use Netrw and end up saving Netrw buffers. Can I run an autocommand on every type of file except netrw?
You can use an :if in your autocmd to guard against netrw files. e.g.
autocmd FileType * if &ft != 'netrw' | echo "do something" | endif
However this still isn't quite right. You have stopped from saving netrw buffers, but there are other buffers that shouldn't be saved. I would suggest checking 'buftype' and looking for files that start with a protocol e.g. foo://.
Here is an example of auto creating intermediary directories using such an approach:
" create parent directories
" https://stackoverflow.com/questions/4292733/vim-creating-parent-directories-on-save
function! s:MkNonExDir(file, buf)
if empty(getbufvar(a:buf, '&buftype')) && a:file!~#'\v^\w+\:\/'
let dir=fnamemodify(a:file, ':h')
if !isdirectory(dir)
call mkdir(dir, 'p')
endif
endif
endfunction
augroup BWCCreateDir
autocmd!
autocmd BufWritePre * :call s:MkNonExDir(expand('<afile>'), +expand('<abuf>'))
augroup END

How can I make NERDTree to open on the same drive that the file that I'm editing?

NERDTree shows in viewport disk c: regardless from which disk do I open the file.
When I use gvim in windows I open files using:
gvim.exe --remote-tab-silent [FILE]
I'm loading NERDTree with this line in _vimrc:
au VimEnter * NERDTree
Can NERDTree automaticaly change drive to correct drive somehow?
Actually, my last answer does not work because once the NERDTree have been opened, it does not open again in the new buffer dir. It must work similarly to NERDTreeFind but it does not have a Toggle feature.
I made a function and mapped it to my key and now it works perfectly even opening the Ruby project if you have the vim-rails plugin.
Add this to your vimrc:
function! NTFinderP()
"" Check if NERDTree is open
if exists("t:NERDTreeBufName")
let s:ntree = bufwinnr(t:NERDTreeBufName)
else
let s:ntree = -1
endif
if (s:ntree != -1)
"" If NERDTree is open, close it.
:NERDTreeClose
else
"" Try to open a :Rtree for the rails project
if exists(":Rtree")
"" Open Rtree (using rails plugin, it opens in project dir)
:Rtree
else
"" Open NERDTree in the file path
:NERDTreeFind
endif
endif
endfunction
"" Toggles NERDTree
map <silent> <F1> :call NTFinderP()<CR>
It should work now.
Previous answer below:
You could map the key you use to open
NERDTree like this(in .vimrc):
map <silent> <F1> :NERDTreeToggle %:p:h<CR>
This maps my F1 key to
toggle(open/close) NERDTree using the
path of the currently active buffer.
If no buffer is open, it opens in the
currently launched Macvim directory.
NERDTree provides several Ex commands to manipulate its buffer (see
:help NERDTreeGlobalCommands). Among them there is the :NERDTreeFind
command which behaves the same way as the :NERDTree command except it opens
the NERDTree buffer in the directory containing currently opened file.
So, in order to achieve the desired effect described in the question, you can
simply change the auto-command to read
:autocmd VimEnter * NERDTreeFind
I use mapping for NERDTree and in this way when I open it always opens in current dir
" NERDTree mappings
nnoremap <silent> <F9> :NERDTreeToggle <cr>
inoremap <silent> <F9> <Esc>:NERDTreeToggle <cr>
But if you open a file like gvim ~/other/dir/file NERDTree will open current dir from where gvim was called. So this is not a real solution to your problem.
Perhaps if you cd in working dir before calling gvim will solve your problem. In this case even your au VimEnter * NERDTree in _vimrc must work as you espect .
About changing directory and setting working dir set autochdir read here
Add
au VimEnter,BufWinEnter * NERDTreeFind
to your .vimrc.
VimEnter part makes it work on load.
BufWinEnter makes it happen you open a new file.
* tells it to do this with all files
NERDTreeFind is the command to run
srcs:
http://vimdoc.sourceforge.net/htmldoc/autocmd.html

Automatically quit vim if NERDTree is last and only buffer

I have the following in my .vimrc:
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Open NERDTree by default
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
autocmd VimEnter * NERDTree
autocmd VimEnter * wincmd p
So,
% vim file.txt
opens NERDTree and focuses the cursor in the file.txt buffer. I make my edits, and hit :q on the buffer, and I'm left with . . . NERDTree. This is annoying.
I could use :qa to close all buffers, and exit vim, but I'm used to the :q trope. So I'm wondering if there's a way to detect that the only remaining buffer is NERDTree, and "unify" the two buffers, for purposes of :q
Edit
Ask and ye shall receive: https://github.com/scrooloose/nerdtree/issues#issue/21
A script to do exactly this has been posted on the NERDTree issue list. Checkout issue-21 on GitHub for nerdtree.
This leads to the single line command for your vimrc here:
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
function! s:CloseIfOnlyControlWinLeft()
if winnr("$") != 1
return
endif
if (exists("t:NERDTreeBufName") && bufwinnr(t:NERDTreeBufName) != -1)
\ || &buftype == 'quickfix'
q
endif
endfunction
augroup CloseIfOnlyControlWinLeft
au!
au BufEnter * call s:CloseIfOnlyControlWinLeft()
augroup END
From my vimrc, based on a version from janus repo.
Enhancements: also close if only a quickfix window is left.
It uses the BufEnter autocommand instead, which is required for &bt to work properly.
An idea in need of implementation:
You could write a function which, when called, checks if the only buffer remaining (or perhaps the only non-help buffer, if you prefer) is a NERDTree buffer and, if so, deletes it (or just quits).
Then have an autocmd run it whenever a buffer is deleted / hidden / whatever actually happens when you :q (it shames me to admit I'm not entirely sure!).
You could :cabbrv q qa but I'd advise against that because you'll forget about it when you actually want q.
I like to do this: cmap bq :bufdo q<CR> to close all buffers with two keystrokes in command mode.

Resources