this is my first post, so be gentle please!
So, I have input files (.in) for an in-house program. The syntax is as follows (for example):
$set (code) $end
$run
(code)
$end
$cmt this is a comment
$cmt this is
a block comment
$end
My situation is I want all the $set
and $run
to be red with their corresponding $end
to be red also. Everything in between has to be nominal color (grey).
I simply use the
syntax match inCMD "\$SET"
for that and it works fine.
Where I have a problem is that I want the "$CMT"
to be yellow so i use
syntax match inCMT "/^\$CMT.*$"
The particularity is that $CMT
does not have to have a corresponding $END
. So, if there is no $END
(or that it figures at the end of the same line as $CMT
, i want the line to be yellow, and the line after to be outside the syntax region. However, if i want to do a block comment and that there is a corresponding $END
to this $CMT
, everything inside has to be yellow.
I came up with
but i have a problem on line 14-17 of the 2nd picture: syntax example.
If a $set
is directly under the $cmt
, the text inside the $set will be yellow instead of simply white.
The other problem is that the $end
corresponding to $set
are white and not red.
How can i solve this?
Thanks a lot!
edit: Syntax file:
syntax case ignore
syntax match inCMT /^\$CMT.*$/
syntax match inCMD "\$SET"
syntax match inCMD "\$RUN"
sy region inCMT matchgroup=inCMT start= /^\$CMT.*$/ end=/\(^\$end\)\|\(^\s*$\)/ contains=inCMD
:sy region inCMD matchgroup=inCMD start= /\v($(SET))/ end=/\(^\$end\)\|\(^\s*$\)/ contained
:hi inCMT ctermfg=yellow
:hi inCMD ctermfg=red
Input file:
$cmt eoipwejf
iowejwed
$end
$set
weoifjwef
$end
$set
$end
$cmt
$set ewdiw
efef
$end
$set
effef
$end
$cmt
efoiwef
$end
$cmt
wd
$END
wd
$set
deiuwf = ewoiw
ewofoi we
$end
$cmt fefef
$cmt
efwef
$end
$set
$set
$set
$cmt ewfoief
wdwwd
$end
$set efopwef
fwfewf
eiojf
$end
$set
ere
wd
$cmt
$end
effe
$cmt
wdeoiqwd
$end
edfeef
$run
goto
$cmt
wdqwd
$end
2nd edit: What i want as final result (colors in brackets) (y) yellow (r) red (n) nominal
Block comment:
$cmt foo (y)
bar (y)
$end (y)
$cmt (y)
foo (y)
bar (y)
$end (y)
$cmt (y)
foo (y)
bar(y)
$end (y)
Line comment:
$cmt (y)
$set (r) foo = bar (n) $end (r)
$cmt foo bar (y)
$set (r)
foo = bar (n)
$end (r)
I think these are all the cases.
This worked for me:
syntax clear
syntax case ignore
syntax match inCMD "\$set"
syntax match inCMD "\$cmd"
syntax match inCMD "\$end"
syntax region inCMT start=/^\$cmt/ end=/\$end\|\$\@=/
hi inCMT ctermfg=yellow
hi inCMD ctermfg=red
It seems to match your update indicating which color each line or word should take. Normally only the keywords ($cmd
, $run
and $end
) are red, but for a comment the whole block is yellow, including the final $end
.
The trick to match a comment with or without an $end
was to do a zero-width match on a single $
(that's the \$\@=
part of the regex.) Since regular expressions return the longest match first, whenever $end
is found it will be matched (and highlighted yellow), but if a $
is otherwise matched, it ends the region but it doesn't become part of it, so it won't be highlighted yellow (and it turns out it's still available to be highlighted red if it's one of the other matching commands, which was important in this case.)
I noticed you had an $end
further down one line, so I didn't anchor the commands anywhere. My first instinct was to use ^
to have them at the start of the line and also use a $
to only allow $end
to be by itself on a line. But I removed all that and it turns out it still works as expected. Feel free to add those back if you think they make sense.