vimdiff: start in second split? - vim

When using vimdiff, I'd like to start in the second pane (my changes), instead of the first.
I've tried adding this to my .vimrc, but it doesn't seem to work. Is there a different event I should be hooking?
if &diff
autocmd BufWinEnter * winc l
endif

The following worked for me
if &diff
autocmd VimEnter * normal ^W^L
endif
Note here that ^W and ^L are single characters. You can enter them using ctrlvctrlwctrlvctrll

Related

Vim plugin : Rainbow parentheses using tab

I'm using vim 7.3 and Rainbow Parentheses plugin. When opening multiple tabs with vim -p file1 file2 or with vim -S session.vim, or even with tabnew file or any other method, my parenthesis are colored in only one file.
I just put this into my .vimrc : au VimEnter * RainbowParenthesesToggle
as said here. I tried to use :RainbowParenthesesToggle on the other tabs once opened but it only toggles in the parenthesis-activated tab.
What should I do to make things work in all tabs ?
I made it work by adding the same instructions as here in my .vimrc, thanks to FDinoff. I replaced the last instruction to make it work using tab, as I intended first.
function! Config_Rainbow()
call rainbow_parentheses#load(0)
call rainbow_parentheses#load(1)
call rainbow_parentheses#load(2)
endfunction
function! Load_Rainbow()
call rainbow_parentheses#activate()
endfunction
augroup TastetheRainbow
autocmd!
autocmd Syntax * call Config_Rainbow()
autocmd VimEnter,BufRead,BufWinEnter,BufNewFile * call Load_Rainbow()
augroup END
The VimEnter flag on the autocommand tells vim to perform the command specified (in this case RainbowParenthesesToggle only when starting the editor, which is in your case when you open the first file.
If you want to extend the functionality to everytime you load a buffer you should do something like:
autocmd BufRead,BufNewFile * RainbowParenthesesToggle

How to select what NERDTree window Vim focuses on depending whether a file is passed

I currently have the following in my .vimrc:
au VimEnter * NERDTree
au BufWinEnter * NERDTreeMirror
This I believe launches NERDTree when I open Vim, as well as when I open a new tab using a plugin. Currently, when I launch Vim using
vim
at the command line, the cursor is sitting in NERDTree ready for me to navigate my files, which is great. However, when I use
vim my-file.txt
the cursor remains in the NERDTree window. I'm aware that I can add this to my .vimrc:
au BufNew * wincmd l
But that means the cursor will always be placed in the window to the right of NERDTree, even if I don't specify a file.
Does anyone have any ideas?
You can make the command conditional on whether arguments were passed to Vim:
:au VimEnter * if argc() > 0 | wincmd l | endif
(I'd use the VimEnter event for that; just make sure this autocmd comes after the one that opens NERDTree.)
PS: There are a couple of related questions here:
Auto-open NERDTree in "EVERY" tab
How do you add NERDTree to your vimrc?

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.

Auto-open NERDTree in "EVERY" tab

Is it possible to open NERDTree in every tab with pressing t or T in NERDTree, if yes, How?
autocmd VimEnter * NERDTree
autocmd BufEnter * NERDTreeMirror
edit: The above command seems to open the new tab in NERDTree's buffer. Instead use this as mentioned by wejrowski in the comment below :
autocmd BufWinEnter * NERDTreeMirror
I wrote a vim plugin that does this and also adds some goodies on top (i.e. keeps all trees in sync, ensures meaningful tab captions - not captions like 'NERD_tree_1' etc.).
It's here on Github: https://github.com/jistr/vim-nerdtree-tabs
autocmd VimEnter * NERDTree
autocmd BufEnter * NERDTreeMirror
autocmd VimEnter * wincmd w
This one is a little better than Dustin's one because it places the cursor directly on the file you are intending to edit for quick edits. Thanks dustin for the original example ^^
A better solution is to open NERDTree only if there are no command line arguments set.
" Open NERDTree in new tabs and windows if no command line args set
autocmd VimEnter * if !argc() | NERDTree | endif
autocmd BufEnter * if !argc() | NERDTreeMirror | endif
NERDTree is e.g. not helpful if you do a git commit or something similiar.
This is probably not the best way, but if you edit plugin/NERDTree.vim and change this:
exec "nnoremap <silent> <buffer> ". g:NERDTreeMapOpenInTab ." :call <SID>openInNewTab(0)<cr>"
to this:
exec "nnoremap <silent> <buffer> ". g:NERDTreeMapOpenInTab ." :call <SID>openInNewTab(0)<cr>:NERDTree<cr>"
it will alter the binding of 't' in the NERDTree view to first open the file and then open NERDTree. Note, that the NERDTree views will not keep in sync.
How about toggling it.
" in .vimrc
" NERDTree, Use F3 for toggle NERDTree
nmap <silent> <F3> :NERDTreeToggle<CR>
In OSX, you just need to fn-F3 to toggle NERDTree.
This problem was actually mentioned in the official Repository's Readme file including three situations related to opening NERDTree automatically:
How can I open a NERDTree automatically when vim starts up?
Stick this in your vimrc: autocmd vimenter * NERDTree
How can I open a NERDTree automatically when vim starts up if no files were specified?
Stick this in your vimrc:
autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif
Note: Now start vim with plain vim, not vim .
How can I open NERDTree automatically when vim starts up on opening a directory?
autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 1 && isdirectory(argv()[0]) && !exists("s:std_in") | exe 'NERDTree' argv()[0] | wincmd p | ene | endif
This window is tab-specific, meaning it's used by all windows in the tab. This trick also prevents NERDTree from hiding when first selecting a file.

How can you automatically remove trailing whitespace in vim

I am getting 'trailing whitespace' errors trying to commit some files in Git.
I want to remove these trailing whitespace characters automatically right before I save Python files.
Can you configure Vim to do this? If so, how?
I found the answer here.
Adding the following to my .vimrc file did the trick:
autocmd BufWritePre *.py :%s/\s\+$//e
The e flag at the end means that the command doesn't issue an error message if the search pattern fails. See :h :s_flags for more.
Compilation of above plus saving cursor position:
function! <SID>StripTrailingWhitespaces()
if !&binary && &filetype != 'diff'
let l:save = winsaveview()
keeppatterns %s/\s\+$//e
call winrestview(l:save)
endif
endfun
autocmd FileType c,cpp,java,php,ruby,python autocmd BufWritePre <buffer> :call <SID>StripTrailingWhitespaces()
If you want to apply this on save to any file, leave out the second autocmd and use a wildcard *:
autocmd BufWritePre,FileWritePre,FileAppendPre,FilterWritePre *
\ :call <SID>StripTrailingWhitespaces()
I also usually have a :
match Todo /\s\+$/
in my .vimrc file, so that end of line whitespace are hilighted.
Todo being a syntax hilighting group-name that is used for hilighting keywords like TODO, FIXME or XXX. It has an annoyingly ugly yellowish background color, and I find it's the best to hilight things you don't want in your code :-)
I both highlight existing trailing whitespace and also strip trailing whitespace.
I configure my editor (vim) to show white space at the end, e.g.
with this at the bottom of my .vimrc:
highlight ExtraWhitespace ctermbg=red guibg=red
match ExtraWhitespace /\s\+$/
autocmd BufWinEnter * match ExtraWhitespace /\s\+$/
autocmd InsertEnter * match ExtraWhitespace /\s\+\%#\#<!$/
autocmd InsertLeave * match ExtraWhitespace /\s\+$/
autocmd BufWinLeave * call clearmatches()
and I 'auto-strip' it from files when saving them, in my case *.rb for ruby files, again in my ~/.vimrc
function! TrimWhiteSpace()
%s/\s\+$//e
endfunction
autocmd BufWritePre *.rb :call TrimWhiteSpace()
Here's a way to filter by more than one FileType.
autocmd FileType c,cpp,python,ruby,java autocmd BufWritePre <buffer> :%s/\s\+$//e
I saw this solution in a comment at
VIM Wikia - Remove unwanted spaces
I really liked it. Adds a . on the unwanted white spaces.
Put this in your .vimrc
" Removes trailing spaces
function TrimWhiteSpace()
%s/\s*$//
''
endfunction
set list listchars=trail:.,extends:>
autocmd FileWritePre * call TrimWhiteSpace()
autocmd FileAppendPre * call TrimWhiteSpace()
autocmd FilterWritePre * call TrimWhiteSpace()
autocmd BufWritePre * call TrimWhiteSpace()
Copied and pasted from http://blog.kamil.dworakowski.name/2009/09/unobtrusive-highlighting-of-trailing.html (the link no longer works, but the bit you need is below)
"This has the advantage of not highlighting each space you type at the end of the line, only when you open a file or leave insert mode. Very neat."
highlight ExtraWhitespace ctermbg=red guibg=red
au ColorScheme * highlight ExtraWhitespace guibg=red
au BufEnter * match ExtraWhitespace /\s\+$/
au InsertEnter * match ExtraWhitespace /\s\+\%#\#<!$/
au InsertLeave * match ExtraWhiteSpace /\s\+$/
This is how I'm doing it. I can't remember where I stole it from tbh.
autocmd BufWritePre * :call <SID>StripWhite()
fun! <SID>StripWhite()
%s/[ \t]\+$//ge
%s!^\( \+\)\t!\=StrRepeat("\t", 1 + strlen(submatch(1)) / 8)!ge
endfun
A solution which simply strips trailing whitespace from the file is not acceptable in all circumstances. It will work in a project which has had this policy from the start, and so there are no such whitespace that you did not just add yourself in your upcoming commit.
Suppose you wish merely not to add new instances of trailing whitespace, without affecting existing whitespace in lines that you didn't edit, in order to keep your commit free of changes which are irrelevant to your work.
In that case, with git, you can can use a script like this:
#!/bin/sh
set -e # bail on errors
git stash save commit-cleanup
git stash show -p | sed '/^\+/s/ *$//' | git apply
git stash drop
That is to say, we stash the changes, and then filter all the + lines in the diff to remove their trailing whitespace as we re-apply the change to the working directory. If this command pipe is successful, we drop the stash.
The other approaches here somehow didn't work for me in MacVim when used in the .vimrc file. So here's one that does and highlights trailing spaces:
set encoding=utf-8
set listchars=trail:ยท
set list
For people who want to run it for specific file types (FileTypes are not always reliable):
autocmd BufWritePre *.c,*.cpp,*.cc,*.h,*.hpp,*.py,*.m,*.mm :%s/\s\+$//e
Or with vim7:
autocmd BufWritePre *.{c,cpp,cc,h,hpp,py,m,mm} :%s/\s\+$//e
If you trim whitespace, you should only do it on files that are already clean. "When in Rome...". This is good etiquette when working on codebases where spurious changes are unwelcome.
This function detects trailing whitespace and turns on trimming only if it was already clean.
The credit for this idea goes to a gem of a comment here: https://github.com/atom/whitespace/issues/10 (longest bug ticket comment stream ever)
autocmd BufNewFile,BufRead *.test call KarlDetectWhitespace()
fun! KarlDetectWhitespace()
python << endpython
import vim
nr_unclean = 0
for line in vim.current.buffer:
if line.rstrip() != line:
nr_unclean += 1
print "Unclean Lines: %d" % nr_unclean
print "Name: %s" % vim.current.buffer.name
cmd = "autocmd BufWritePre <buffer> call KarlStripTrailingWhitespace()"
if nr_unclean == 0:
print "Enabling Whitespace Trimming on Save"
vim.command(cmd)
else:
print "Whitespace Trimming Disabled"
endpython
endfun
fun! KarlStripTrailingWhitespace()
let l = line(".")
let c = col(".")
%s/\s\+$//e
call cursor(l, c)
endfun
autocmd BufWritePre *.py execute 'norm m`' | %s/\s\+$//e | norm g``
This will keep the cursor in the same position as it was just before saving
autocmd BufWritePre * :%s/\s\+$//<CR>:let #/=''<CR>

Resources