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

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

Команда снимка сохраняет состояние в обычный файл

Снимок состояния делает команда создания сеанса. Она записывает текущую обстановку редактора в файл, который по сути является скриптом восстановления.

:mksession сеанс.vim     сохранить состояние в файл сеанс.vim
:mks сеанс.vim           то же самое, сокращённо

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

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

:mks! сеанс.vim          перезаписать существующий файл сеанса

Файл сеанса - не какой-то особый формат, а обычный скрипт редактора. Его можно открыть и посмотреть, а при желании и поправить вручную, хотя обычно в этом нет нужды.

Восстановление разворачивает обстановку двумя путями

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

vim -S сеанс.vim     запустить редактор с восстановлением сеанса

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

:source сеанс.vim    восстановить сеанс из открытого редактора
:so сеанс.vim        сокращённо

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

Настройка определяет, что именно попадёт в снимок

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

:set sessionoptions     посмотреть, что сейчас сохраняется в сеанс

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

" пример настройки состава сеанса
set sessionoptions=buffers,curdir,folds,tabpages,winsize

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

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

Автоматизация через события входа и выхода

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

Автоматическое правило на событие выхода вызывает снимок сеанса перед закрытием редактора. Тогда обстановка сохраняется сама, без команды.

" автоматически сохранять сеанс при выходе
autocmd VimLeave * mksession! ~/.vim/сеанс.vim

Парное правило на событие входа подключает сохранённый сеанс при запуске, разворачивая прошлую обстановку. Так редактор сам поднимается там, где был закрыт.

" автоматически загружать сеанс при запуске без аргументов
autocmd VimEnter * nested if argc() == 0 | source ~/.vim/сеанс.vim | endif

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

Привязка сеанса к проекту через рабочий каталог

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

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

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

Что складывается в практику

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

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

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