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

Рубрика "Секреты Вим". Деревья правок

Привет, коллеги. Мы уже обсуждали отмену действий и возврат их. В vi отмена была одношаговой и сама считалась действием, то есть повторная отмена отменяла предыдущую, а третья отменяла отмену, возвращая правку обратно. В Вим тоже так можно, но вообще отмена многошаговая, можно отменить много правок с помощью команды u. Можно и вернуть их сочетанием <C-R>. Получается линейная отмена: последовательность правок, которые можно отменять или возвращать обратно. Это удобно, но есть одна тонкость. Прежде чем обсудить ее, давайте уточним понятие правки/действия. Это изменение, совершенное командной нормального режима или из командной строки, а также сеанс режима вставки целиком. Если вы вошли в режим вставки и напечатали целую главу романа, то это одна правка! Допустим, что вы сделали несколько правок, отменили одну или более, и сделали новое изменение. У вас появилась развилка, к которой вы можете вернуться... но вторая ветвь для обычной обратимой отмены потеряна! Например. Вы вошли в режим в

Привет, коллеги. Мы уже обсуждали отмену действий и возврат их. В vi отмена была одношаговой и сама считалась действием, то есть повторная отмена отменяла предыдущую, а третья отменяла отмену, возвращая правку обратно. В Вим тоже так можно, но вообще отмена многошаговая, можно отменить много правок с помощью команды u. Можно и вернуть их сочетанием <C-R>.

Получается линейная отмена: последовательность правок, которые можно отменять или возвращать обратно. Это удобно, но есть одна тонкость.

В vi отмена одношаговая и отменяет сама себя. В Вим есть линейная отмена и возврат. Но если после отмены вы совершли изменение - вы начали новую ветвь. Линейная замена так не умеет, но Вим позволяет работать с деревьями правок (справа). Три ветви: сначала сделаны зеленые правки, потом красные, потом красные отменены и сделаны синие, потом синие и две зеленые отменены и сделаны рыжие. Возврат через g- будет возвращать правки в порядке, указанном в рамочке. Обратите внимание на прыжки с точек ветвления на концы ветвей! Обход в хронологиескиом порядке!
В vi отмена одношаговая и отменяет сама себя. В Вим есть линейная отмена и возврат. Но если после отмены вы совершли изменение - вы начали новую ветвь. Линейная замена так не умеет, но Вим позволяет работать с деревьями правок (справа). Три ветви: сначала сделаны зеленые правки, потом красные, потом красные отменены и сделаны синие, потом синие и две зеленые отменены и сделаны рыжие. Возврат через g- будет возвращать правки в порядке, указанном в рамочке. Обратите внимание на прыжки с точек ветвления на концы ветвей! Обход в хронологиескиом порядке!

Прежде чем обсудить ее, давайте уточним понятие правки/действия. Это изменение, совершенное командной нормального режима или из командной строки, а также сеанс режима вставки целиком.

Если вы вошли в режим вставки и напечатали целую главу романа, то это одна правка!

Допустим, что вы сделали несколько правок, отменили одну или более, и сделали новое изменение. У вас появилась развилка, к которой вы можете вернуться... но вторая ветвь для обычной обратимой отмены потеряна!

Например. Вы вошли в режим вставки и набрали там "сорок два". Вышли. Скопировали строку в регистр (yy) и вставили: p. Вставили еще раз. Выполнили команду :%s/$/ (42)/

У вас такой текст:

сорок два (42)
сорок два (42)
сорок два (42)

Отменив действие (u), вы уберете скобки на все строках. Теперь вы решили сделать отступ: :%s/^/ /

Отступ-то вы получили, но возврата к скобочкам нет! Отмена приведет к "сорок два" от начала каждой строки. Возврат вернет отступ. Всё.

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

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

Но Вим поддерживает деревья правок. Давайте обсудим.

Гулять по дереву можно разными способами. Вим упорядочивает все правки по времени и дает к ним линейный доступ, по времени или по номеру или по порядку.

Команда нормального режима g- идет в прошлое, отменяя правки по порядку. g+ идет вперед, возвращая правки. Пример: создайте новый буфер (:tabnew) и выполните команды

iправка 1<esc>
<C-A>
r3
s4<esc>
u
r5
u
3<C-A>
r7

Это семь правок. Вы напечатали текст "правка 1", увеличили число на 1, получив 2, изменили 2 на 3, потом 3 на 4, вернулись к 3, заменили на 5. Отменили опять к 3, увеличили сразу на 3 до 6, и заменили на 7. Номера правок от 1 до 7, эти же номера стоят после слова "правка" (но это мы специально так устроили).

Команда g- последовательно вернет текст "правка 6", "правка 5" и так далее до "правка 1". А g+ последовательно вернет обратно. Сравните с поведением u: она пропустит "4" и "5", эти ветви для нее утеряны: от "6" перейдем к "3", потом к "2" и "1". Команда <C-R> вернет обратно "2", потом "3", потом "6" и "7".

Если вы знаете номер правки, к которой хотели бы вернуться, можете прыгнуть сразу на нее, командой :undo N, где N - номер правки.

Команды g- и g+ могут принимать повторители.

Есть возможность посмотреть дерево правок. Точнее, не дерево, а линейную последовательность правок во времени. Это команда :undolist.

Три листа у дерева. Один лист - "правка 4", в этот момент мы сделали отмену. Сделали правку-5 и опять отменили: это второй лист. Ну и создали третью ветвь.
Три листа у дерева. Один лист - "правка 4", в этот момент мы сделали отмену. Сделали правку-5 и опять отменили: это второй лист. Ну и создали третью ветвь.

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

Каждый листик имеет номер, это первый столбец. Во втором столбце - число правок от начала дерева до листика, то есть длина линейной цепи правок, если бы других ветвей не было. Указано в третьем столбце время правки, в удобном формате: "6 секунд назад", время, время и дата, возможно, с годом. Есть еще столбец, в котором написано, было ли сохранено это состояние в файл.

Вы можете вернуться не только к листу дерева, но и к промежуточным состояниями командой :undo N. В нашем примере текст имеет вид "правка N" и это и есть правка номер N.

Вы можете перемещаться не по номерам правок, а прямо по времени. Для этого есть команды :earlier и :later. Например, :earlier 10s

Просто число показывает номер правки, а суффикс s (секунды), m(минуты), h(часы), d(сутки) позволяет откатываться к состоянию на данный момент в прошлом.

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

Можно еще путешествовать по состояниям на момент записи. :earlier Nf откатывает на N записей в файл назад.

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

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

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

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

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

Леса
8465 интересуются