Файл на полторы тысячи строк - не редкость в реальном проекте. Прокручивать его, выискивая нужную функцию среди десятков других, утомительно: глаз тонет в подробностях, а курсор пролетает мимо цели. Хотелось бы видеть структуру целиком, как оглавление, сворачивая то, что сейчас не нужно, и разворачивая интересующее. Ровно это умеет механизм сворачивания в редакторе vim - он прячет блоки кода под одну строку-заголовок, оставляя на виду лишь каркас, и разворачивает их по требованию.

Сворачивание держится на двух вещах: способе, которым редактор определяет, что считать сворачиваемым блоком, и наборе команд, открывающих и закрывающих свёртки. Способов несколько, но для кода с отступами проще всего сворачивание по уровню отступа. Команды же построены на запоминающейся логике, где буква, похожая на сложенный лист бумаги, ведёт всё семейство. Разберём, как настроить сворачивание по отступам, какие команды им управляют, и где у этого способа граница.

Способ сворачивания определяет, что редактор считает блоком

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

Ручной способ отдаёт решение пользователю: он сам отмечает участки, которые хочет сворачивать. Сворачивание по отступу собирает в свёртку строки одного уровня отступа - идеально для языков, где отступ и так несёт смысл. Сворачивание по синтаксису опирается на правила подсветки и хорошо подходит для программирования. Способ через выражение позволяет задать собственную логику свёрток, часто на регулярных выражениях. Сворачивание по маркерам ищет особые символы-метки, расставленные в тексте.

:set foldmethod=indent     сворачивание по уровню отступа
:set foldmethod=syntax     по правилам синтаксиса
:set foldmethod=manual     вручную помеченные участки

Для большинства кода с осмысленными отступами сворачивание по отступу - самый простой и быстрый выбор. Оно не требует ни ручной разметки, ни настройки синтаксических правил: редактор сам видит, что строки с большим отступом вложены в строку с меньшим, и сворачивает их вместе. Эта настройка локальна для каждого окна, так что в разных файлах можно держать разные способы.

Команды открытия и закрытия строятся на наглядной мнемонике

Управляют свёртками команды, начинающиеся с буквы, которая визуально напоминает сложенный лист бумаги. Это намеренная мнемоника, облегчающая запоминание всего семейства. Базовых команд три, и они работают с одной свёрткой под курсором.

Команда открытия разворачивает закрытую свёртку, делая её содержимое видимым. Команда закрытия сворачивает открытую, пряча содержимое под заголовок. А команда переключения открывает закрытую и закрывает открытую - часто она удобнее всего, потому что не надо помнить текущее состояние свёртки.

zo      открыть свёртку под курсором
zc      закрыть свёртку под курсором
za      переключить свёртку: открыть закрытую, закрыть открытую

Мнемоника прозрачна: буква-лист, затем буква открытия, буква закрытия. Команда переключения избавляет от размышлений о состоянии - одно нажатие приводит свёртку в противоположный вид. Многие назначают её на пробел или функциональную клавишу, чтобы сворачивать и разворачивать одним касанием.

Заглавные варианты и уровневые команды охватывают вложенность

Свёртки бывают вложенными: функция внутри класса, цикл внутри функции. Отступ порождает многоуровневую структуру, и для работы с ней есть расширенные команды. Заглавные варианты базовых команд действуют не на один уровень, а на все вложенные под курсором сразу.

zO      открыть все вложенные свёртки под курсором
zC      закрыть все вложенные свёртки под курсором
zA      переключить все вложенные свёртки под курсором

Если курсор стоит внутри свёртки, вложенной в другую свёртку, заглавная команда закрытия схлопнет их все разом, тогда как строчная закрыла бы лишь ближайший уровень. Это разница между точечным управлением одним уровнем и оптовым - всей цепочкой вложенности.

Отдельное семейство команд работает не у курсора, а по всему файлу, управляя глубиной раскрытия. Команды полного раскрытия и полного сворачивания приводят весь файл к одному из крайних состояний - всё открыто или всё закрыто.

zR      раскрыть все свёртки во всём файле
zM      закрыть все свёртки во всём файле

А парные команды постепенного раскрытия и сворачивания меняют глубину на один уровень во всём файле, не трогая позицию курсора. Они дают плавно регулировать степень детализации: с каждым нажатием либо ещё один уровень вложенности раскрывается, либо ещё один сворачивается.

zr      раскрыть на один уровень глубже по всему файлу
zm      свернуть на один уровень по всему файлу

Именно команды полного сворачивания и постепенного раскрытия превращают файл в оглавление. Свернуть всё командой полного сворачивания - и на экране останется лишь каркас из заголовков верхнего уровня. Затем постепенным раскрытием можно опускаться вглубь ровно настолько, насколько нужно для текущей задачи.

Навигация между свёртками ускоряет перемещение по файлу

Свёртки полезны не только для сокрытия кода, но и как опорные точки для перемещения. Когда файл свёрнут до каркаса, прыжки между свёртками заменяют долгую прокрутку. Команды перехода к следующей и предыдущей свёртке двигают курсор по структуре, а не по строкам.

zj      перейти к началу следующей свёртки
zk      перейти к концу предыдущей свёртки

Это смещение от навигации по строкам к навигации по смыслу. Вместо отсчёта строк или прокрутки курсор перемещается по логическим блокам - от функции к функции, от блока к блоку. В большом файле это ощутимо быстрее, потому что опорными точками служат осмысленные границы кода, а не безликие номера строк.

Настройка уровня раскрытия и включение сворачивания

Несколько настроек тонко управляют поведением свёрток. Уровень раскрытия задаёт, насколько глубоко файл развёрнут при открытии. Нулевое значение сворачивает всё, кроме верхнего уровня, превращая файл в оглавление сразу при загрузке. Большее значение оставляет открытыми и более глубокие уровни.

:set foldlevel=0     при открытии файла свёрнуто всё, кроме верха

Само сворачивание управляется отдельным переключателем включения. Когда он выключен, все свёртки автоматически раскрываются, и файл выглядит обычным. Это удобно, когда сворачивание временно мешает. Есть и быстрая команда переключения этого состояния - двухклавишная, чтобы одним движением то прятать структуру, то возвращать сплошной текст.

zi      быстро переключить сворачивание целиком вкл/выкл

Полностью отключить свёртки можно и в конфигурации редактора, выставив переключатель включения в выключенное положение, либо разово командой для текущего окна.

Граница способа сворачивания по отступам

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

Поэтому для языков со строгими, осмысленными отступами сворачивание по отступу работает безупречно и почти не требует настройки. А для языков, где блоки очерчены фигурными скобками, а не отступом, или где отступы непоследовательны, лучше подходит сворачивание по синтаксису, опирающееся на правила подсветки, либо способ через выражение с собственной логикой. Существуют и сторонние дополнения, определяющие свёртки по отступам произвольной величины и понимающие фигурные скобки как часть блока, но они заметно медленнее встроенного способа и на больших файлах могут снижать отзывчивость редактора.

Что складывается в рабочий приём

Картина выстраивается ясно. Способ сворочивания по отступу - простой и быстрый выбор для кода с осмысленными отступами, не требующий ни разметки, ни настройки правил. Базовые команды у курсора - открытие, закрытие и особенно удобное переключение - работают с одной свёрткой, а их заглавные варианты охватывают всю вложенность под курсором.

Команды по всему файлу превращают его в оглавление: полное сворачивание оставляет каркас заголовков, постепенное раскрытие опускает вглубь на нужную глубину. Навигация между свёртками заменяет прокрутку прыжками по логическим блокам. Уровень раскрытия задаёт стартовое состояние, а переключатель включения позволяет временно убрать свёртки вовсе.

Главная мысль: сворачивание превращает плоскую простыню кода в навигируемую структуру, где видна архитектура, а подробности прячутся до востребования. Граница способа по отступам проходит по последовательности отступов - там, где они кратны и осмысленны, он безупречен, а где код выровнен причудливо, на смену приходят синтаксический способ или дополнения. Стоит освоить мнемонику команд и команды полного сворачивания, и большой файл перестаёт быть стеной текста, становясь оглавлением, по которому удобно перемещаться.