Найти в Дзене
Блокнот математика

Рубрика "Секреты Вим". Тонкости фолдинга

Мы уже несколько раз обсуждали фолдинг: визуальное сворачивания нескольких строк текста. Можно свернуть главы, блоки кода, комментарии, синтаксические конструкции, списки и т.п. Имеется несколько методов для определения фолдов: ручной, которому посвящен отдельный материал, по отступам, по синтаксису, по различиям, по собственному выражению (оно определяет для строки уровень фолда), по меткам в тексте. Теперь обсудим несколько моментов, которые остались нами не изучены.

Это не те, но заметка про специальные функции фолдинга в Вим))
Это не те, но заметка про специальные функции фолдинга в Вим))

Фолды по отступам хороши для списков, а также для языков программирования, если описания синтаксиса нет или вас оно почему-то не устраивает. Отступ строки делится на значение shiftwidth и округляется, и это уровень фолда. Так что новый уровень отступа создает вложенный фолд. Глубину можно ограничить, задав опцию foldnestmax, которая по умолчанию 20. Пустые строки входят в фолд строки выше или ниже, который менее глубокий. Так же ведут себя строки, которые начинаются с содержимого foldignore (перед ним могут идти пробелы). По умолчанию там решетка, что удобно для Си и препроцессорных директив. Эта опция содержит текст, а не регулярное выражение.

Очень полезной бывает возможность выполнить команду на открытых или закрытых фолдах. Для этого есть команды: :folddoopen и :folddoclosed. Обе могут работать на диапазоне строк или на выделении и принимают команду, которую выполняют, соответственно, на открытых фолдах и на закрытых. Работают команды как фильтры строк :g: сначала выбирают строки, потом выполняют на каждой команду.

Теперь тонкая настройка.

Можно изменить цветовое выделение фолдов: для этого есть группа hl-folded. Столбец слева, в котором показаны фолды, тоже можно перекрасить: hk-FoldColumn.

Пример из Справки:

highlight Folded ctermfg=red ctermbg=white
:highlight FoldColumn ctermbg=darkgrey ctermfg=white

Можно изменить сам текст, которым показан свернутый фолд. Обычно там что-то вроде

+ 1 +-- 6 lines: текст текст текст-------------

Но вы можете определить по-своему. Для этого есть опция foldtext, в которой надо указать выражение. Оно будет вычисляться (в песочнице), и результат показываться как закрытый фолд. По умолчанию вызывается функция foldtext(). Вам доступны следующие переменные:

  • v:foldstart — номер первой строки в фолде.
  • v:foldend — номер последней строки в фолде.
  • v:folddashes — серия черточек, показывающая глубину фолда.
  • v:foldlevel — глубина фолда числом.

Например:

:set foldtext=v:folddashes.substitute(getline(v:foldstart),'/\\*\\\|\\*/\\\','','g')

Здесь мы к черточкам приклеиваем (оператор "точка") первую строку фолда (getline), в которой удалили комментарии в стиле Си (между /* и */).

Символ табуляции заменяется на пробел, а невидимые символы заменяются видимыми. Строка обрезается, чтобы уместиться в окно.

А если в окне остается место, оно заполняется символом, указанным в опции fillchars. В ней через запятую заданы пары идентификатор:символ, есть среди прочих и идентификатор fold. По умолчанию символ -.

Опция foldminlines задает минимальное число экранных строк, допустимое для закрытого фолда. Если в фолде меньше строк, он закрываться не будет. Обратите внимание, что строки экранные, то есть та часть, которая влезает в окно. Даже если выключен wrap, но строка длинная, она считается как несколько экранных. По умолчанию значение 1, то есть сворачивать можно фолды, занимающие на экране хотя бы две строки. Это разумно, так как для одной строки нет никакой экономии. Но если вы хотите, для единообразия или еще почему, сворачивать фолды и в одну строку, то выставьте нуль. Можно задавать и значения больше, чтобы, например, фолды из двух строк не закрывались. Это полезно, если вам мешают большие блоки, но вы хотели бы видеть как можно больше.

Можно настроить фолды так, чтобы они автоматически закрывались, когда курсор покидает фолд. Это может быть очень удобно, а может быть неудобно, в зависимости от задачи. Так что решать вам. По умолчанию опция foldclose содержит пустую строку, то есть возможность отключена. Задайте строку all, и фолд будт закрываться, когда вы из него выходите (совсем или в фолд менее глубокий).

С автоматическим открытием фолдов тоже есть варианты. Если курсор вошел в фолд, то иногда уместно его раскрыть, а иногда достаточно поместить курсор на свернутый фолд. Вариантов (когда открывать, а когда нет) много, и их можно через запятую перечислить в опции foldopen:

  • all — всегда открывать фолд
  • block — команды типа "(", "{", "[[", "[{", и т.п.
  • hor — команды движения по строке: "l", "w", "f", и т.п.
  • insert — любая команда в режиме вставки
  • jump — дальные прыжки по тексту: "G", "gg", и т.п.
  • mark — переходна метку-закладку: "'m", CTRL-O, и все такое.
  • percent — команды "%"; мы помним, что их две: это переход на парную скобку И перемотка нужного процента текста (80% перейдет на такую строку, что выше будет 80% текста).
  • quickfix — команды списка QuickFix: ":cn", ":crew", ":make", etc.
  • search — поиск по выражению: "/", "n", "*", "gd" и т.д.
  • tag — переход по меткам: ":ta", CTRL-T, и т.п.
  • undo — отмена или повтор действия: "u" и CTRL-R

Не забывайте про возможность безопасно снимать/вставлять значения опций с помощью

:set foldopen-=undo

По умолчанию не входят только insert и mark (и, естественно, all).

При работе с оператором (как dG, например) опция не используется! Оператор подействует на весь фолд. Это может быть опасно: скажем, если вы удалили текст до метки m (d`m), то удален будет весь фолд.

В режиме вставки фолд всегда откроется, если вы начнете печатать. Что и правильно, вслепую набирать текст не следует.

Команда zv позволяет увидеть строку, на которой курсор. Если фолд не открылся при перемещении в него курсора (так вы настроили), то можно, конечно, открыть вручную. Но это может быть неудобно, если фолдов много вложенных. Можно начать печатать, но это не всегда уместно. Вот тут и поможет zv: она откроет столько вложенных фолдов, сколько надо, чтобы увидеть строку под курсором.

Команда zx обновляет фолды. Это полезно, если вы вручную задаете глубину через опцию foldlevel или если включен фолдинг по выражению, а буфер изменился снаружи.

Если вы применили к закрытому фолду команду "с двоеточием", за исключением специальных, описанных выше, то применяются они ко всем строкам фолда. Например,

:s/Оля/Юля/g

на свернутом фолде осуществит замену именно на этих строках.

Удачи, коллеги.

Научно-популярные каналы на Дзене: путеводитель
Новости популярной науки12 марта 2022