?

Log in

No account? Create an account

Вт, 17 мар, 2009, 16:28
Vim: мы круче колорера

Как я говорил в прошлый раз, 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», чтобы стандартный плагин не путался под ногами.

Сб, 3 июл, 2010 13:32 (UTC)
_pk_sly

hint: для работы с разными типами файлов есть специальная разновидность плагинов ftplugins

Вс, 4 июл, 2010 21:50 (UTC)
egorius

Да-да-да, планирую заюзать при случае, как назреет.

Пн, 5 июл, 2010 07:45 (UTC)
_pk_sly

лучше юзай, пока не забыл, а то придётся опять с чистого листа всё вспоминать и заново придумывать :)