I want my vim to highlight in red some keywords from the Pouet group like 'if(' in my .c files.
I figured out how to highlight if with:
syn keyword Pouet if
(This is my ~/.vim/syntax/c.vim)
and with
highlight Pouet term=NONE cterm=NONE Ctermfg=160 ctermbg=NONE gui=NONE
(And this is a part of my .vimrc)
The problem is,this code doesn't work with special characters like '(' or maybe a space or many spaces.
My question is: how do I make sentences like 'if(' highlight in red ?
Thanks
:syn keyword only works for keyword characters (as defined by the 'iskeyword' setting), and ( usually is not contained.
You have to use :syn match instead, e.g.:
:syn match Pouet "\<if("
This is fine if you define your syntax all on your own. If you want this in addition to the existing C syntax highlighting, you need to analyze the original syntax groups and add stuff like containedin=cConditional, maybe you even have to modify the original syntax definition.
An alternative is matchadd(), which goes on top of the syntax highlighting:
:call matchadd('Pouet', '\<if(')
The problem here is that these matches are window-local, not bound to the filetype like syntax highlighting, so when you split windows or edit another filetype in the current window, the highlighting will be gone / will persist. These problems can be worked around with autocmds, but now it's getting really complex.
Related
Right now I am trying to write a syntax highlighter for my custom language using Monarch. However, in my language (and many others), sometimes the syntax highlighting could change based on what's on the next line. For example, here is one such case in Javascript:
fn(foo // here, foo is an argument
=> bar)
fn(foo // but here, foo is an identifier
+ bar)
Unfortunately it seems like by default, monarch regexes work line by line. So I can't figure out how I would achieve this. Is there a way to enable multi-line regexes in Monarch? Or is there some other way to solve this?
I want to get syntax highlighting inside of a bash heredoc. In addition, I want bash variable dereference and command substitution highlighting in the heredoc.
Using these instructions as a starting point, I was able to add variable dereferencing by examining sh.vim. I imagine you could accomplish command substitution in a similar fashion.
let s:bcs = b:current_syntax
unlet b:current_syntax
syntax include #YAML syntax/yaml.vim
syntax region hereDocYAML matchgroup=Statement start=/<<-\?\s*\z(YML\)/ end=/^\s*\z1/ contains=#YAML,hereDocDeref,hereDocDerefSimple
syn match hereDocDerefSimple "\$\%(\h\w*\|\d\)"
syn region hereDocDeref matchgroup=PreProc start="\${" end="}" contains=#shDerefList,shDerefVarArray
hi def link hereDocDeref PreProc
hi def link hereDocDerefSimple PreProc
My problem is, this doesn't appear to work in any sort of block (if, function, for, etc.). For example:
The only thing I know is that this is not an indentation problem. Changing indentation has no effect, and using indentation outside of a block works properly.
The contains on the definition of shIf appears to limit the possible highlights to whatever items are in shIfList group.
Adding your item to the group as follows will give you highlighting withing that region:
syn cluster shIfList add=hereDocYAML
The same principle holds for all other blocks. For example:
syn cluster shFunctionList add=hereDocYAML
syn cluster shLoopList add=hereDocYAML
It should be noted that the approach you've outlined is not generally useful. First of all, it requires that the included syntax file use groups for their contains definitions.
In addition, it works for YAML because bash dereference syntax and YAML syntax do not conflict. For more complicated syntaxes like sed or awk, you will have conflicts, and the rules to resolve those conflicts will likely require a new syntax entirely.
I have a custom SPICE (electronics) syntax highlighting for gEdit, it's working, but I would like to modify the highlighting for variables (and I don't know how to). What I have now is this:
<context id="variables" style-ref="string">
<match extended="true">
(\s[^\s><&(){};,=/+\-*\^]+|
(?![({])\s*[^\s><&(){};,=/+\-*\^]+)
\s*(\=)(?!(\s*\=))
</match>
</context>
The parameters (variables) are defined like this:
.param Value=3.14
and, with the above code, "Value=" is highlighted, but I would like to omit the "=" from being coloured. I have tried (?!\=) on the last row, after 's*, plus a few combinations but... nothing.
In a more detailed way:
the parameters are defined by a mandatory first .param or .params (this is solved)
they cannot have spaces or any character like these -- [^\s><&(){};,=/+-*\^] -- inside their namings (solved)
they must have at least one space before to not "mingle" with the previous characters (solved)
the above condition has the "(" and "{" exceptions (solved)
they can have spaces between them and "=" (solved)
Please bear in mind that I have very little knowledge about PCRE, this is probably childish-looking but I don't mind as long as it's working. What I have now is done by too many trials-and-errors.
In the meantime I solved it with the help from jessevdk from #gedit on irc.gimp.org. The line
\s*(\=)(?!(\s*\=))
needs to be changed to
(?=(\s*\=(?!(\s*\=))))
Now I can update the file on https://bugzilla.gnome.org/show_bug.cgi?id=692822 and wait some more for acceptance...
Here is what I got so far:
syntax match cfg_Comment '#.*$' contains=cfg_DocTag
syntax match cfg_DocTag '#\s*\zs[\\#]\l\+' contained
highlight default link cfg_Comment Comment
highlight default link cfg_DocTag SpecialComment
Works perfectly for something like:
##
# #brief The maximum.
# #type number
# #default 1
What I want to do next is to highlight the next word after #type with Type group. So I did the following:
syntax match cfg_Comment '#.*$' contains=cfg_DocTag,cfg_DocField_type
syntax match cfg_DocTag '#\s*\zs[\\#]\l\+' contained
syntax match cfg_DocTag_type '#type' containedin=cfg_DocTag nextgroup=cfg_DocField_type skipwhite
syntax match cfg_DocField_type '\a\+' contained
highlight default link cfg_Comment Comment
highlight default link cfg_DocTag SpecialComment
highlight default link cfg_DocField_type Type
There are 2 issues with this:
Now #type is not highlighted, and I get it because obviously I didn't specify the group for it, but I expected it to sort of inherit the color from its parent container cfg_DocTag.
Of course now everything in comments is of Type color and not just the word after #type, and I get it again because I specified that cfg_Comment is a container of cfg_DocField_type.
I know where the issues stem from, but I don't know how to elegantly solve them and write as less boilerplate code as possible.
Finally, can someone tell me why
syntax match cfg_DocTag_type '#type' containedin=cfg_DocTag nextgroup=cfg_DocField_type skipwhite
and
syntax keyword cfg_DocTag_type #type containedin=cfg_DocTag nextgroup=cfg_DocField_type skipwhite
are not the same? I.e. in the first case it's as I described above: #type is no longer highlighted since the group is not specified, but this is expected. But in the second case, it is highlighted even though the group is not specified, which is unexpected, so it feels like as a keyword it doesn't match at all. And it is easily provable with the simplest test case possible:
Highlighting works:
syntax match Test '#type'
highlight default link Test Keyword
Highlighting doesn't work:
syntax keyword Test #type
highlight default link Test Keyword
Update
Following Ingo's answer the proposed solution indeed works. However what is interesting to me is why this one doesn't?
syntax match cfg_Comment '#.*$' contains=cfg_DocTag
syntax match cfg_DocTag '#\s*\zs[\\#]\l\+' contained
syntax match cfg_DocTag_type '#type' transparent containedin=cfg_DocTag nextgroup=cfg_DocField_type skipwhite
syntax match cfg_DocField_type '\a\+' contained
highlight default link cfg_Comment Comment
highlight default link cfg_DocTag SpecialComment
highlight default link cfg_DocField_type Type
This one would be perfect if only it worked. It frees us from duplication of the comment match, and does the natural inheritance. Omitting # before type does not change anything by the way, i.e. the inheriting effect stays intact. But why cfg_DocField_type is not highlighted? Any ideas?
You're quite close already. Your containment of cfg_DocTag_type in cfg_DocTag doesn't work because they would both match at the same position. Leaving off the leading # from the former would fix it, but the nextgroup=cfg_DocField_type still wouldn't match, because apparently the end of the match for cfg_DocTag (after the tag) makes Vim not apply the nextgroup.
What I've done is putting cfg_DocTag_type on the same level as cfg_DocTag, i.e. not contained in the latter. There's only the duplication of the pre-match #\s*\zs as a downside.
syntax match cfg_Comment '#.*$' contains=cfg_DocTag,cfg_DocTag_type
syntax match cfg_DocTag '#\s*\zs[\\#]\l\+' contained
syntax match cfg_DocTag_type '#\s*\zs#type' nextgroup=cfg_DocField_type skipwhite
syntax match cfg_DocField_type '\a\+' contained
highlight default link cfg_Comment Comment
highlight default link cfg_DocTag SpecialComment
highlight default link cfg_DocTag_type cfg_DocTag
highlight default link cfg_DocField_type Type
Re 1.: It is not contained; only if you leave off the #. Then, adding transparent would get you the inheriting effect.
Re "finally": I suspect that # is not part of 'iskeyword' (it's not by default), but it has to be for :syn keyword.
Protip: Syntax script development is easier when you install the SyntaxAttr.vim - Show syntax highlighting attributes of character under cursor plugin.
I am using vim, and I want to highlight the following construct (which is accepted in ifort, but rejected by xlf)
write(5,*), foo
note the comma before the foo variable. I tried the following
syn match fortranWriteComma "write\s*\(.?*,.?*\),"
This works well as long as instead of "write" I use anything else. Example
syn match fortranWriteComma "whatever\s*\(.?*,.?*\),"
this matches and correctly highlights
whatever(5,*),
If I use write, the keyword recognition of write kicks in and does not perform any highlighting. How can I set vim to have the match prevail over the keyword recognition ?
I partially solved by redefining the keyword as a match
syn clear fortranReadWrite
syn keyword fortranReadWrite backspace close endfile inquire open print read rewind
syn match fortranWrite "write" contained
hi def link fortranWrite Keyword
syn match fortranWriteComma "write\s*(.*,.*)," contains=fortranWrite
hi def link fortranWriteComma Error
Unfortunately, this is still not perfect, as the "write" remains yellow, and only the parenthesized stuff becomes highlighted.
I could not fix this, but it's ok for my purposes. If anyone has a way of getting write in yellow in normal conditions, but everything red if the comma is added, please add it in comments so I can refine it.
Q. If I use write, the keyword recognition of write kicks in and does not perform any highlighting. How can I set vim to have the match prevail over the keyword recognition
A. I believe you should be able to have it both ways using a transparent syntax region:
TRANSPARENT
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
Now you can give cWhile and cFor different highlighting. The cCondNest item
can appear in either of them, but take over the highlighting of the item it is
contained in. The "transparent" argument causes this.
Notice that the "matchgroup" argument has the same group as the item
itself. Why define it then? Well, the side effect of using a matchgroup is
that contained items are not found in the match with the start item then.
This avoids that the cCondNest group matches the ( just after the "while" or
"for". If this would happen, it would span the whole text until the matching
) and the region would continue after it. Now cCondNest only matches after
the match with the start pattern, thus after the first (.