Vim: C++ symbols' color - vim

VIM: Is it possible to change the color of these symbols:
~!%^&*()-+=[]{},.<>?:/;
like Visual Studio does?

The C/C++ syntaxes are defined in syntax/c.vim and syntax/cpp.vim. If you're using Linux, the main syntax directory is in /usr/share/vimXX/, where XX is the version (e.g. mine are in vim72). I don't know about installation directories on other OSes, but I'm sure you can find it. I'd suggest making a copy of these and placing them in your user vim directory (for example, in Linux, $HOME/.vim/syntax/c.vim and so on). You can then add whatever you like.
The C++ syntax sources the C syntax, so any symbols you want highlighted in both should go in c.vim, and anything for C++ only should be in cpp.vim.
To get syntax highlighting for specific symbols, you'll need to use a syntax match statement, something like:
syn match cUserSpecialCharacter display "[~!%^&*()-+=[\]{},.<>?:;]"
syn match cUserSpecialCharacter display "/[^*/]"me=e-1
syn match cUserSpecialCharacter display "/$"
I called it cUserSpecialCharacter since cCharacter and cSpecialCharacter are already used. The second and third matches are a bit of a kludge to highlight '/' without it matching comment prefixes, which would then override the comment highlighting and break everything. The "display" option tells Vim that it doesn't need to look for this match if it's not going to be displayed - see :help syn-display for an explanation if you like!
Once you've defined a syntax match, you can link it to a highlight group, for example:
hi def link cUserSpecialCharacter cCharacter
This will put it in with the already defined cCharacter group, so it'll get whatever highlighting that gets - in this case, Character. You can see a nice list of highlight groups at the bottom of c.vim for examples. If you really want, you can also hardcode a highlight by doing something like:
hi cUserSpecialCharacter term=reverse ctermfg=15 ctermbg=1 guifg=#ffffff guibg=#800000
(Arbitrary example - my current highlighting for the Error group.) See :help hi for more information on this, or simply :hi to see the list of defined highlighting - plenty of examples. I'd recommend against doing this, though, since it won't change with color schemes.

Yes, you need to edit the C color theme in vimfiles/colors/c.vim I don't know all the theme options one can use, but I'm sure they are documented on http://vim.org/

Related

Color highlight function calls in VIM

Does anyone know a way to color highlight function calls in Vim?
I know that some plugins could do something like that by keeping record of tags, but with what I've found online, I could not figure out how to make it work.
I've tried using easy tags (which, by the way, doesn't seem to be maintained anymore) and gutentags, but to be quite honest, I haven't come much close to make any of them to work.
On the other hand, I imagine that it would be quite simple to implement a script to highlight anything that lies between a dot and a left parentheses or a blank space and a left parentheses (as in .anyCodeAtAll(), anotherCode()), but I have no idea how to do it. It would be a incomplete solution of course, but it would be good enough for my purposes at the moment.
Does anyone know how to make that work?
I have something like that in my configuration, but it's quite language specific. For example for Golang, I have a ~/.vim/after/go.vim which contains:
syntax match goCustomParen "(" contains=cParen
syntax match goCustomFuncDef "func\s\+\w\+\s*(" contains=goDeclaration,goCustomParen
" Exclude import as function name, for multi-line imports
syntax match goCustomFunc "import\s\+(\|\(\w\+\s*\)(" contains=goCustomParen,goImport
syntax match goCustomScope "\."
syntax match goCustomAttribute "\.\w\+" contains=goCustomScope
syntax match goCustomMethod "\.\w\+\s*(" contains=goCustomScope,goCustomParen
highlight def link goCustomMethod Function
highlight def link goCustomAttribute Identifier
highlight goCustomFuncDef ctermfg=13
highlight goCustomFunc ctermfg=43
highlight goCustomAttribute ctermfg=247
highlight goCustomMethod ctermfg=33
And for Python, I have a ~/.vim/after/python.vim:
syntax match pyCustomParen "(" contains=cParen
syntax match pyCustomFunc "\w\+\s*(" contains=pyCustomParen
syntax match pyCustomScope "\."
syntax match pyCustomAttribute "\.\w\+" contains=pyCustomScope
syntax match pyCustomMethod "\.\w\+\s*(" contains=pyCustomScope,pyCustomParen
highlight def link pyCustomFunc Function
highlight def link pyCustomMethod Function
highlight def link pyCustomAttribute Identifier
highlight pyCustomFunc ctermfg=43
highlight pyCustomAttribute ctermfg=247
highlight pyCustomMethod ctermfg=33
In each case, the first block defines what is a function, a method, an attribute, and so on, the second block link these custom definition to the generic classes "Function, Identifier..." and the 3rd block defines the colors.
The files need to be in the after directory to be executed after the colorscheme and highlights definitions.
Here's a side by side comparison of with and without these settings (look on the last 3 lines):
Unless someone has a better solution, you could adapt the above for the language you need it.
It might be that you have not installed your plug-in correctly.
Try following these steps (or retrace your steps) and see if it works / missed any steps out:
cd ~ Go to home directory.
vim .vimrc open .vimrc
Insert:
call plug#begin()
Plug 'xolox/vim-easytags'
call plug#end()
easytags#Options states easytags should work out of the box, but you could add option here in the
.vimrc file now or later,
e.g. put:
let g:easytags_syntax_keyword = 'always'
afer the call plug block.
Anyway.
:wq write quit the .vimrc
source ~/.vimrc unsure if required as will do later
vim test.js open vim with test.whatever language you know.
:PlugInstall in vim
Here might take a bit of time.
Then :q out of that window.
:source ~/.vimrc this is needed
Then test out to see if you have syntax highlighting.
I'm pretty sure this is along the right lines. Might be misspelled plugin name.

vim automatic hard wrap for fortran with line-continuation

I'm a Fortran programmer who uses both free-form and fixed form. Since I have to mix them, usually I write code in a common form between free and fixed format, so in this way I can tell to vim that all my files are in the free format.
Vim is great in doing things like autoindentation, but I would like to type and let vim automatically wrap my code, and placing the Fortran continuation character & at column 73 (or greater), and at column 6 in the new line. Is it possible, or does it exist a plugin for this?
Currently I'm using textwidth=72 in fortran files to hard wrap the lines.
Thanks in advance.
One way to make vim insert text when going to a new line is to use formatexpr. Set it so to capture the line and replace it with itself with & and new line appended, when at/beyond a given column. In this case you are handling line breaks and textwidth does not apply. I didn't yet get to test some simple code for it, but here is a related example.
Another way would be to write general code so that when in a given column it inserts & and <CR>.
However, making any such approach respect Fortran-specific exclusions (comments, for one thing) will make it more complicated. The best solution would be to find suitable existing option(s) for Fortran, but I haven't so far.
This is a comment on indentation in general. It should allow you to directly set up a desired rule for a new line. Here is one standard set of files that set up a lot of indentation rules and features.
The usual entry point is this vim script, which requires another standard set of files. The link given on that page for the other files is broken though, so here is where to find them: unpack this zip file (found on this page), right into your ~/.vim/ directory. It will create subdirectories indent/, syntax/, and ftpplugin/, or put files into them if they exist, so be careful if you have stuff there already.
Then you can put the first script linked above into .vim/after/indent/. In this file, there are specific calculations of where to put the cursor when a new line is entered. Find the right place(s) and change to your desired indent, or preferably set up a snippet from it in another file (so not to change this file). In this case you also need to set things up so that it overrides settings from the first file.
A useful resource is indentexpr (or :help indentexpr).
Here is also a tutorial on that.
These are comments on syntax in general, posted initially. They contain items of help related to what you want and should be generally useful, but probably have not much to say about adding &.
There are plugins for fortran. Here is the syntax file, with many things to tweak.
This may already be on your system. (It was on mine.) Thus I would go through and pick and choose things to add to your .vimrc. Here are a few options that are directly related
syn match fortranContinueMark display "&"
syn sync linecont "&" minlines=20
Here are paragraphs that seem to me relevant in their entirety
if (b:fortran_fixed_source == 1)
if !exists("fortran_have_tabs")
"Flag items beyond column 72
syn match fortranSerialNumber excludenl "^.\{73,}$"lc=72
"Flag left margin errors
syn match fortranLabelError "^.\{-,4}[^0-9 ]" contains=fortranTab
syn match fortranLabelError "^.\{4}\d\S"
endif
syn match fortranComment excludenl "^[!c*].*$" contains=#fortranCommentGroup
syn match fortranLeftMargin transparent "^ \{5}"
syn match fortranContinueMark display "^.\{5}\S"lc=5
else
syn match fortranContinueMark display "&"
endif
if b:fortran_dialect != "f77"
syn match fortranComment excludenl "!.*$" contains=#fortranCommentGroup,#spell
endif
Then a block of syn match statements follow for common cpp-like settings, and then
"Synchronising limits assume that comment and continuation lines are not mixed
if exists("fortran_fold") || exists("fortran_more_precise")
syn sync fromstart
elseif (b:fortran_fixed_source == 0)
syn sync linecont "&" minlines=20
else
syn sync minlines=20
endif
By your question it appears that you know how to set up .vimrc but here are a few comments.
Syntax support need be enabled with appropriate enable and autogroup statements, for example
syntax enable
" au BufRead,BufNewFile *.f90 FileType=fortran
au FileType fortran setlocal ...
Here are some common formatting options that I have for fortran
autocmd FileType fortran setlocal formatoptions=croql comments=:/!/
There can also be a t among options, for textwidth
Here are some specific settings I have, which I see in this syntax file with far more sophistication
let fortran_free_source=1
" Said to need fortran.vim and/or fortran support packages (they work)
let fortran_do_enddo=1
let fortran_more_precise=1
Standard vim help is of course extensive, but try :help fortran -- it has a number of useful settings right up front and is not overwhelming at all. Also see ft-fortran-syntax from help.
See this post with some troubleshooting if things aren't working right. Here is another useful post, even as it appears unrelated by its title.

Making a Vim theme that disables highlighting except for some special keywords

Inspired by several posts, like Your syntax highlighter is wrong, Coding in color and A case against syntax highlighting and some others, I decided making a Vim theme that applied some of these concepts would be a good idea.
The thing is I'm not exactly sure how.
From what I can tell, in order to make a Vim theme you need to basically link a color with a syntax identifier or name. And repeat this hundreds or dozens of time in order to have in your lap a theme.
Like for example linking the color #ff0000 (red) and the syntax identifier, or key, Error. As an example. Not sure if that's actually the syntax key.
This would work fine, except that, every syntax that I don't consider important I have to define as just a default foreground value.
And let's say I wanted to add a new syntax keyword, I'd have to do it with ftsyntax and stuff (I believe) and that would be filetype specific etc.
So the first question is:
What would be the best way to give everything a default foreground color and only pick the exceptions to have some colors?
And the second, perhaps more important question is:
How do I syntax highlight a specific piece of text without having to add a syntax rule? For example have a regex that finds any = and highlights them green, without having to add a syntax rule specific for that.
Any help is appreciated. Of course if the approach I'm taking to this is not ideal or sucks I am open to suggestions to alternatives. Thank you. :)
See the example syntax file below:
syn keyword myKeywords We Are Important Keywords
syn match myEquals '='
hi link myKeywords Special
hi link myEquals Operator
This will put We, Are, Important and Keywords into the myKeywords syntax group and = into the myEquals syntax group.
Then we specify how we want to highlight them, by linking it to the Special and Operator highlight groups.
See: :help group-name for a list of the highlight groups and what the colors look like with your color-scheme.
In my color-scheme, Special is Red and Operator is green.
By default, everything else is set to the default foreground color.
I saved this to ~/.vim/syntax/greduan.vim and tested with :set syntax=greduan
Your question touches two domains:
syntax definition
syntax highlighting
Syntax definition, as in Caek's answer, is simple for the first 10 minutes but grows very quickly into a major PITA because it is a core aspect of Vim's architecture with ramifications far beyond syntax highlighting.
Syntax highlighting has its pitfalls but it is a lot simpler than syntax definition.
I think that you can tackle the problem described in those blog posts with syntax highlighting first and, if needed, graduate to syntax definition.
Grab a simple colorscheme like Busybee.
Link all the highlight groups you don't need to Normal while leaving the ones you want to keep:
hi link Foo Normal
What would be the best way to give everything a default foreground
color and only pick the exceptions to have some colors?
What is best depends ... for me the best, because quickest way was clearing unwanted highlighting in ~/.vimrc:
sy on
hi c Constant|hi c Error|hi c PreProc|hi c Special|hi c Statement|hi c Type
hi c Identifier
How do I syntax highlight a specific piece of text without having to
add a syntax rule?
If by syntax rule you mean syntax item, I'd say you cannot have syntax highlighting without defining syntax items.

How to get vim spell check to mark bad words inside of Latex math equations?

Spell check in vim is nice enough to not highlight things inside of a math environment when writing LaTeX. This is convenient, but I make some very common typos like "theat" instead of "theta" that would be nice to catch automatically. Is there a way to get the words in the explicit list of 'bad words' to be highlighted regardless of their context?
Note that I still don't want to check whether everything is good within a math environment, just that it is not explicitly bad.
To enable spell checking for a syntax group, you'd have to add contains=#Spell, e.g. for the texStatement group, that would be:
:syn match texStatement "\\\a\+" contains=#Spell
But with that, you'd still have to add all "good" statements to your spell file. If you just want to highlight certain "bad" words, you can define a contained match:
:syn match texBadStatement "theat" containedin=texStatement
And then link to the error or bad spell highlighting:
:hi link texBadStatement SpellBad
Put those commands into ~/.vim/after/syntax/tex.vim to make them persistent.
I'm not a Latex specialist. If the texStatement group is wrong, you need to find out which syntax group causes the highlighting. :syn list shows all active groups, but it's easier when you install the SyntaxAttr.vim - Show syntax highlighting attributes of character under cursor plugin.

highlight sub-match in vim

I'm trying to figure out how to highlight a specific portion of a match in vim.
Given the following example rule (taken from the coffeescript syntax file source):
syn match coffeeExtendedOp /\%(\S\s*\)\#<=[+\-*/%&|\^=!<>?.]\+\|[-=]>\|--\|++\|:/ display
This regular expression matches various coffeescript operators. The operators are highlighted (in my vimrc) like this:
hi Operator guifg=#ff0000
For example, since coffeeExtendedOp is linked to coffeeOperator which is linked to Operator, in the above source file. This all works, but I'm wondering how to specifically highlight the ++ operator matched in the above syn match with a different color, say blue, within my vimrc (that is, without altering the original source file above). I'm simply wondering if this is possible.
EDIT: I think the rules are placed under a cluster, so perhaps that's why it's not affecting anything. Is there a way to access the rule within the cluster?
EDIT: Question was clarified.
Solution:
syn match plusplus /++/ contained containedin=coffeeExtendedOp display
hi plusplus guifg=#0000ff
The problem now is that this only works when I run them as commands in vim, but not when I put it in my vimrc file. Any ideas? Could it be that the stuff is hidden behind the cluster? But then why is it visible in vim through a command? I tried including the syntax file but it didn't seem to have any effect.
Looking at the coffee.vim you linked to it seems like the dot belongs to the coffeeDotAccess syntax item. So you can highlight it just by doing this:
:hi coffeeDotAccess ctermfg=blue
I'm going to guess a bit at what you need. (I don't speak Coffeescript and your sample regex is way too complicated for me to start reading at the moment).
Transparent syntax items
You could have a look at transparent syntax rules: (http://vimdoc.sourceforge.net/htmldoc/usr_44.html)
In a C language file you would like to highlight the () text after a "while"
differently from the () text after a "for". In both of these there can be
nested () items, which should be highlighted in the same way. You must make
sure the () highlighting stops at the matching ). This is one way to do this:
:syntax region cWhile matchgroup=cWhile start=/while\s*(/ end=/)/
\ contains=cCondNest
:syntax region cFor matchgroup=cFor start=/for\s*(/ end=/)/
\ contains=cCondNest
:syntax region cCondNest start=/(/ end=/)/ contained transparent
Partial matches in regex
If you really just meant highlighting submatches, have a look at the the
\zs start match
\ze end match
In short,
:match Error /foo\zsbar\zered/
would highlight only 'bar' in 'foobarred'

Resources