Highlight unwanted spaces in Vim, except for those in help buffers - vim

I am using these lines in my .vimrc file, to highlight leading whitespace (which includes spaces):
highlight ExtraWhitespace ctermbg=darkgreen guibg=darkcyan
autocmd BufWinEnter * match ExtraWhitespace /^\s* \s*\|\s\+$
So, this works fine in most cases. Except in help buffers, where it highlights a lot of indentation from the help files. I find this annoying, so I tried this as a workaround:
autocmd FileType help highlight clear ExtraWhitespace
But unfortunately, as soon as a help buffer is opened, it seems that the highlighting in all my buffers disappears.
Any ideas on how to improve this?

This seems to be working:
highlight ExtraWhitespace ctermbg=darkgreen guibg=darkcyan
autocmd BufEnter * if &ft != 'help' | match ExtraWhitespace /\s\+$/ | endif
autocmd BufEnter * if &ft == 'help' | match none /\s\+$/ | endif
[edit] The above code works for trailing spaces since my Vim couldn't understand your pattern. So just :%s/ubstitute the pattern to fit your needs.

If you only need the whitespace errors for C/C++ files you can always use:
let c_space_errors=1
There are other languages that have similar support.
Worst case, if you need it for other types of files, you could always switch your file type to C and fix your errors then.

Change the autocommand disabling custom highlighting in help buffers
as follows:
:autocmd FileType help match none

Related

in vimrc apply certain highlighting rules only for certain filetype

in my vimrc I have a script that transform a text in bold when banded between * * double stars * * (like it does in this editor actually), but i don't want it to apply on my js or c or any programming files of course, so i tried to make it run only when it's a .txt file :
if (&filetype=='text')
set concealcursor=n
set conceallevel=3
hi AsteriskBold ctermfg=Green cterm=bold
autocmd BufEnter * syn match Asterisks contained "**" conceal
autocmd BufEnter * syn match AsteriskBold "\*\*.*\*\*" contains=Asterisks
endif
but obviously the condition of the "if" doesn't work since this rules doesn't apply anymore in none of my file, text or not
EDIT => SOLUTION
after reading the answers I choose this solution, in my vimrc (even though it's not the best way vim works as explaind by ingo)
au BufEnter *.txt setf text "(set a filetype unless it already exist)
au filetype text set cocu=n cole=3
au filetype text hi AsteriskBold ctermfg=Green cterm=bold
au filetype text syn match Asterisks contained "**" conceal
au filetype text syn match AsteriskBold "\*\*.*\*\*" contains=Asterisks
Filetypes
Filetype-specific settings go into ~/.vim/after/ftplugin/text.vim. (This requires that you have :filetype plugin on; use of the after directory allows you to override any default filetype settings done by $VIMRUNTIME/ftplugin/text.vim.) Alternatively, you could define an :autocmd FileType text ... directly in your ~/.vimrc, but this tends to become unwieldy once you have many customizations.
Syntaxes
For :syntax commands, there's a corresponding directory ~/.vim/after/syntax/text.vim. (Vim currently doesn't ship with a dedicated text syntax; you could drop the after part, and make your syntax the main one.)
By syntax script convention, your syntax groups should be prefixed with the filetype; e.g. textAsterisks. The :hi group has to be renamed as well; however, usually syntax scripts use :hi def link to link the syntax group to a (more generic) highlight group: hi def link textAsteriskBold AsteriskBold. More information at the end of usr_44.txt.
Highlight groups
These are global, you can put your :hi command(s) directly into your ~/.vimrc and define it just once.
Conceal
The conceal settings are window-local, but filetypes and syntaxes apply to buffers. And by using :set (instead of :setlocal), those settings will be inherited by any new window opened from the one that shows a text file. Depending on your workflow (and whether other filetypes you edit use concealing at all), you may never notice this, and there's no good workaround (only a huge mess of :autocmd could try to adapt those). Just be aware of this.
You're looking for an augroup.
See :help augroup and :help filetype.
For instance:
augroup asteriskbold
au!
au BufNewFile,BufRead *.txt,*.md,*.mkd,*.markdown,*.mdwn set concealcursor=n conceallevel=3
au BufNewFile,BufRead *.txt,*.md,*.mkd,*.markdown,*.mdwn hi AsteriskBold ctermfg=Green cterm=bold
au BufNewFile,BufRead *.txt,*.md,*.mkd,*.markdown,*.mdwn syn match Asterisks contained "**" conceal
au BufNewFile,BufRead *.txt,*.md,*.mkd,*.markdown,*.mdwn syn match AsteriskBold "\*\*.*\*\*" contains=Asterisks
augroup end

Is there any we can set a default search keyword for vi/vim?

I want to find trailing white spaces(if present) in a file whenever it is opened.For that I want to put default search keyword(pattern to find trailing white space- \s+$)for vi/vim, so that whenever I open any file with vi/vim this default keyword will be searched.Can this be possible ??
To do exactly what you're asking, you can do
au BufReadPost * let #/='\v\s+$'
Note that #/ is global, so it will change the search for all the buffers.
If you only want to highlight trailing spaces, you can do something like that:
hi TrailingSpaces ctermbg=red guibg=red
au BufReadPost * call matchadd('TrailingSpaces', '\v\s+$')
I had once thought of that and came up with trailing space. But it only works in insert mode, and shows up highlighted trailing spaces.
My .vimrc config for extra whitespace
highlight ExtraWhitespace ctermbg=red guibg=red
matchExtraWhitespace /\s\+\%#\#<!$/
:au InsertEnter * match ExtraWhitespace /\s\+\%#\#<!$/
:au InsertLeave * match ExtraWhitespace /\s\+$/
and it highlights like this
To remove white space I am still doing manually by using sed
:%s/[\ \t]*$//gc
(or)
Use BufWritePre to run command to remove trailing spaces.
Ref: http://vim.wikia.com/wiki/Remove_unwanted_spaces (on your own risk)
For this particular use case (find trailing white spaces), you may want to consider my ShowTrailingWhitespace plugin, which is a robust implementation that does not clobber the search pattern. (The plugin page has links to many alternative plugins, too.)

Disable syntax highlighting for certain filenames

I have syntax highlighting enabled in .vimrc, but that makes loading certain files too long. So I need to disable (or, to be precise, not enable... enabling it and then disabling is not a solution) syntax highlighting for these files. I tried
au BufNewFile,BufRead !*.inc syntax enable
but that made just no syntax highlighting applied ever. The solution presented here does not work for me, since I can't make a distinction by filetype. I tried adapting to no avail, which might or might not be connected to the events needed for "syntax enable".
Thanks for any pointers!
The mentioned solution points to the right direction: Define an autocmd for all buffers, and then (instead of 'filetype'), match with the filename via expand('<afile>'):
au BufNewFile,BufRead * if expand('<afile>:e') !=? 'inc' | syntax enable | endif
Here, I've used your example of *.inc extensions in the condition. If you find the matching cumbersome and would rather use the autocmd syntax, you can do that with an intermediate buffer flag, too, using the fact that autocmds are executed in order of definition:
au BufNewFile,BufRead *.inc let b:isOmitSyntax = 1
au BufNewFile,BufRead * if ! exists('b:isOmitSyntax') | syntax enable | endif
If you want to show syntax only for .c files. Put
syntax off
autocmd! bufreadpost *.c syntax on
in your vimrc.
Also you can map a key for enabling syntax (Ctrl+s in this case)
nnoremap <C-S> :syntax on<CR>
In you question you want to disable syntax only for .inc file. Do it like this:
syntax on
autocmd! bufreadpost *.inc set syntax=off
To disable syntax highlighting for files with .inc extension, you can basically use:
syntax on
au BufNewFile,BufRead *.inc setlocal syntax=OFF
To disable it for multiple extensions, e.g. also for py:
au BufNewFile,BufRead *.{inc,py} setlocal syntax=OFF

vim highlight remove overwrite others hi

I my ~/.vimrc I use this syn for long lines
augroup longLines
au!
au! filetype zsh,sh,python,vim,c,cpp
\ syn match ColorColumn /\%>80v.\+/ containedin=ALL
augroup END
but this overwrite other syn, with
without
Why the synoverwrite other highlight?
this is notorious in the last lines
sys.exit(1)
import settings
have different colors, with syn, the lines lost normal highlight
I use the following code:
highlight TooLongLine term=reverse ctermfg=Yellow ctermbg=Red
autocmd BufEnter,WinEnter * if &tw && !exists('b:DO_NOT_2MATCH') |
\ execute '2match TooLongLine /\S\%>'.(&tw+1).'v/' |
\ endif
autocmd BufLeave,WinLeave * 2match
command -nargs=0 -bar Dm let b:DO_NOT_2MATCH=1 | 2match
command -nargs=0 -bar Sm execute '2match TooLongLine /\S\%>'.(&tw+1).'v/' |
\ silent! unlet b:DO_NOT_2MATCH
If you don’t want to be able to remove this highlighting, depend on textwidth and insist on highlighting spaces that go beyond the limit, then you can truncate this to just
2match TooLongLine /.\%>80v/
This solution uses match-highlight that does not scrap syntax highlighting, but always overrides it.
I realize you asked this quite some time ago, but in case if other people ask too, perhaps you could try using the matchadd() function, instead, like this:
hi def longLine gui=reverse "or guibg=pink, or whatever you prefer
augroup longLines
au!
au! filetype zsh,sh,python,vim,c,cpp
\ call matchadd("longLine", "\\%>80v", 0, 9999)
augroup END
Most importantly, make sure that you do NOT set the guifg of whatever highlight group you decide to use. That would overwrite your syntax highlighting.
Another important part (for me, at least) is to use matchadd with 0 as the third parameter so that your Search highlighting remains effective and doesn't get overtaken by the longLine highlighting.
The fourth parameter can be omitted. It's just a constant so that you can :call matchdelete(9999) to easily remove the highlighting again later, if you want.
See :h matchadd and :h matchdelete

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