Vim: мы круче колорера
Mar. 17th, 2009 04:28 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Как я говорил в прошлый раз, Vim умеет раскрашивать синтаксис и умеет подсвечивать парные скобки, но не умеет подсвечивать конструкции наподобие begin–end. Задавшись целью настроить такую подсветку, я полез в документацию и к большому своему удивлению обнаружил, что подсветка синтаксиса и скобок — две совершенно разные вещи. Первая обеспечивается собственно Vimом на основе syntax-файлов, а второй занимается отдельностоящий (хотя и стандартный) плагин, никак не завязанный на тип файла. Документация радостно сообщает, что currently only single byte character pairs are allowed. Эх.
Но раз он плагин, то никто не мешает в него заглянуть. Всех-то дел 150 строчек кода на внутреннем скриптовом языке Vimа (весьма симпатичный, кстати говоря, оказался язык). И — о, чудо! — оказалось, что в Vimе есть прекрасная встроенная функция searchpair(), которая мало того, что ищет парные слова с учётом вложенности, но и позволяет задать их регэкспами, а ещё — вот ведь! — понимает конструкции типа if–else–fi, подсветки которых мне так не хватало в Фаре. Условно говоря, задавшись некоторой конструкцией и начальным словом, мы можем получить все слова, находящиеся с ним на одном уровне вложенности:
if
if
else
fi
else
...
else
...
fi
С такой-то функцией да не написать свой плагин? Сказано — сделано. Сложности в основном были вызваны тем, что я сначала пытался обойтись без регэкспов (по аналогии со стандартным плагином, типа поберечь ресурсы), но потом одумался и сделал всё по-человечески.
Интересный момент: как привязать подсветку к типу файла (а делать это, очевидно, надо: в разных языках используются разные конструкции)? Оказывается, в Vim можно на определённое событие повесить обработчик (автокоманду в его терминологии), причём поддерживается очередь таких обработчиков. Вполне удобно. Таким образом, сам плагин висит на событиях перемещения курсора, а по событию изменения типа файла можно подключать соответствующие языковые конструкции.
А теперь, на закуску, самая большая засада. Как, собственно, описать те слова, которые должны быть парными? В PL/SQL для счастья нужно, вроде бы, немного: begin–end, case–end, loop–end loop, if–end if. Но нельзя, например, просто сделать пару if–end if, поскольку получим такое:
if ...
if ...
end if;
end if;
Аналогично, могут не поделить друг друга пары begin–end и if–end if:
begin
if ...
end if;
end;
А ещё begin и case могут поспорить из-за endа:
begin
if case ... end then ... end if;
end;
Конкретно эти примеры, конечно, с помощью регэкспов легко решаются. Но вот как при этом сделать, чтобы if и case не отнимали друг у друга else? До сих пор ничего хорошего не придумал.
Резюме. За прошедшее время Vim прочно вытеснил Фаровский редактор, и вряд ли я теперь от него откажусь. Жизнь потихоньку налаживается, дальше буду ковырять dbext.
Особенно хочется отметить качество документации. Всё, что нужно, находится быстро и информация оказывается исчерпывающей, с хорошими жизненными примерами использования. И в очередной раз стали видны преимущества открытого, интерпретируемого кода. Фаром я пользуюсь уже очень давно, раза три порывался написать плагин, но необходимость где-то искать документацию и что-то компилировать меня останавливала. А в Vim всё под рукой: и хелп, и интерпретатор, и сам редактор в одном флаконе. Отлично.
Да, если кому интересно, вот он плагин. В vimrc полезно добавить строчку «:let loaded_matchparen = 1», чтобы стандартный плагин не путался под ногами.
no subject
Date: 2010-07-03 01:32 pm (UTC)no subject
Date: 2010-07-04 09:50 pm (UTC)no subject
Date: 2010-07-05 07:45 am (UTC)