Синтаксис vim с подсветкой комментариев, которые могут быть одной строкой или блоком - PullRequest
1 голос
/ 06 марта 2020

это мой первый пост, поэтому будьте осторожны, пожалуйста!

Итак, у меня есть входные файлы (.in) для собственной программы. Синтаксис следующий (например):

$set (code) $end

$run
(code)
$end

$cmt this is a comment

$cmt this is

a block comment

$end

Моя ситуация такова, что я хочу, чтобы все $set и $run были красными, а их соответствующие $end тоже красными. Все промежуточное должно быть номинального цвета (серого).

Я просто использую

syntax match inCMD "\$SET"

для этого, и он отлично работает.

Когда у меня возникает проблема, я хочу, чтобы "$CMT" был желтым, поэтому я использую

syntax match inCMT "/^\$CMT.*$"

Особенность в том, что $CMT не обязательно должен иметь $END. Итак, если нет $END (или что оно находится в конце той же строки, что и $CMT, я хочу, чтобы строка была желтой, а строка после - за пределами области синтаксиса. Однако, если я хочу чтобы сделать комментарий к блоку и что $END соответствует этому $CMT, все внутри должно быть желтым.

Я придумал

синтаксических команд

, но у меня есть проблема в строке 14-17 2-го изображения: пример синтаксиса .

Если $set находится непосредственно под $cmt, текст внутри набора $ будет желтым, а не просто белым. Другая проблема в том, что $end, соответствующий $set, белый, а не красный.

Как я могу решить эту проблему?

Большое спасибо!

редактировать: файл синтаксиса:

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 

Входной файл:

 $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

2-е редактирование: что я хочу в качестве конечного результата (цвета в скобки) (y) желтый (r) красный (n) номинальный

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)


Я думаю, что это все случаи.

1 Ответ

0 голосов
/ 06 марта 2020

Это сработало для меня:

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

Кажется, оно соответствует вашему обновлению, указывая, какой цвет должна принимать каждая строка или слово. Обычно только ключевые слова ($cmd, $run и $end) являются красными, но для комментария весь блок является желтым, включая заключительный $end.

Трюк для сопоставления комментария с или без $end было бы выполнить сопоставление нулевой ширины для одного $ (это часть \$\@= регулярного выражения). Поскольку регулярные выражения сначала возвращают самое длинное совпадение, всякий раз, когда обнаруживается $end, оно будет совпал (и выделен желтым), но если $ в противном случае совпал, он заканчивает регион, но не становится его частью, поэтому он не будет выделен желтым (и оказывается, что он все еще доступен для выделения красный, если это одна из других совпадающих команд, что было важно в данном случае.)

Я заметил, что на одну строку ниже $end, поэтому я нигде не привязывал команды. Моим первым инстинктом было использовать ^, чтобы они были в начале строки, а также использовать $, чтобы $end мог быть только на линии. Но я удалил все это и оказалось, что он все еще работает, как и ожидалось. Не стесняйтесь добавлять их обратно, если считаете, что они имеют смысл.

...