Привет, коллеги. Фолдинг мы уже обсуждали: это сворачивание строк текста так, что видна только первая (и полное количество). На сам текст это не влияет, но позволяет улучшить обозримость. Выглядит это так:
3 +-- 14 строк: Чтобы любая девушка сразу соглашалась на всё, достаточно выполнить одно простое---------------------------
Есть разные методы фолдинга: ручной, когда можно свернуть выделенные строки командой zf; по синтаксису, когда сворачиваются тела функций, блоки кода и всё в таком роде; по отступам; по маркерам; по различиям. В том числе есть и фолдинг по выражению, то есть вы сами устанавливаете правила. Вот его и обсудим.
Выбор метода осуществляется опцией foldmethod с вариантами manual, indent, syntax, expr, marker, diff. Нам нужен expr.
Нужно задать и само выражение: это опция foldexpr. По умолчанию там нуль. А подразумевается там выражение, которое вычисляется на каждой строке и задает уровень вложенности фолдинга. Нуль означает, что фолдинга нет.
Вот пример, мой собственный:
set foldexpr=getline(v:lnum)=~'^http' ? 1 : 0
Выражение берет строку (getline) с указанным номером v:lnum - это которая проверяется; сравнивает ее с регулярным выражением (оператором =~) и, если совпадение есть, выставляет единичку, а если нет, то нуль (оператор ?:). Сворачиваются идущие подряд url-ссылки.
Вот пример из Справки:
:set foldexpr=getline(v:lnum)[0]==\"\\t\"
Сворачиваются строки, начинающиеся с табуляции
Можно вызывать любую функцию, и делать там что угодно. Номер текущей строки доступен в переменной v:lnum.
Помимо чисел, есть и еще особые значения выражения. Числа трактуются так: 0 - нет фолда; число больше нуля - строка входит в фолд данного уровня вложенности. Число -1 означает, что фолд надо определять по строке выше и строке ниже, который из двух меньше.
Может быть символ '=', означающий "тот же фолд, что на предыдущей строке".
Есть любопытная арифметика: значения a1, a2 и т.д. предписывают прибавить указанное число к уровню фолда предыдущей строки и это будет уровень данной. Аналогично s1, s2 и т.д. позволяют вычесть число из уровня фолдинга предыдущей строки.
Варианты =, a и s могут быть медленными, так как Виму придется идти назад по тексту, и иногда далеко. Но это бывает полезно, например, для фолдинга по синтаксису (если вы решили его сами сделать). Скажем, комментарии в стиле Си: от /* до */ должны быть на уровень выше. Найдя /*, возвращаем a1; найдя */, возвращаем s1. А в остальных случаях возвращаем =.
Можно положить конец безобразию, задав значение "<1", "<2" и т.п.: это предписывает закончить фолдинг данной вложенности на данной строке.
Но можно и начать, указав ">1", ">2" и т.д.
Недостаточно просто начать фолдинг: в него войдет одна строка. Остальные должны войти в фолд сами, то есть тоже соответствовать выражению: оно должно на них дать = или ненулевое число. Другое дело, что если, скажем, все строки имеют фолд 2, то можно сделать не один большой фолд, а два, идущих подряд: просто начав новый фолд.
С другой стороны, не обязательно отмечать начало и конец фолда: только если вам это надо. Можете выставить число 1 на нужных строках, и всё. Как я сделал с URL.
Если выражение выполнилось с ошибкой или результат не распознается, он считается нулем. А побочные эффекты запрещены. Для отладки надо выставить опцию debug в значение msg: тогда сообщения об ошибке будут выводиться.
Есть функция foldlevel(), которая возвращает уровень вложенности, то есть его можно узнать.
Чего делать не следует? Не пытайтесь сделать фолдинг по синтаксису через выражение! Либо у вас и так есть фолдинг по синтаксису (и его можно настраивать через переменные), либо это надо делать через описание синтаксиса.
Ещё не надо пытаться придумать какие-то метки в тексте, чтобы потом выражение их находило и устанавливало фолдинг. Это можно только для обучения:
:set foldexpr=getline(v:lnum)[0:1]
и ставьте желаемое значение в первые два символа строки, чтобы поиграться.
Дело в том, что есть особый метод фолдинга: по маркерам. Это именно это: специальные метки в тексте, замаскированные под комментарии. Они позволяют делать произвольный фолдинг, но автоматически. Об этом методе в другой раз расскажу.
До встречи!