СПРАВОЧНИК ПО VIM - Брам Мооленаар

Основы рассматриваемой здесь темы обсуждаются в разделе 02.5 Руководства Пользователя.

  1. Команды отмены и восстановления
  2. Два способа выполнения отмены
  3. Замечания об отмене

1. Команды отмены и восстановление

<Undo> или
u
Отменить заданное [число] изменений.  
Vi: позволяет отменять только одно изменение.
:u[ndo] Отменить одно изменение.
Vi: позволяет отменять только одно изменение.
CTRL-R Заново внести заданное [число] раннее отменённых изменений.  
Vi: обновить экран.
:red[o] Заново внести одно раннее отменённое изменение.
Vi: redo отсутствует.
U Отменить все последние изменения на одной строке.
Vi: работает только до тех пор, пока курсор не сместился со строки.

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

Команда "U" воспринимается командами отмены/повтора как любая другая команда. Поэтому, команда "u" может отменять действие команды "U", а команда CTRL-R заново применять эту команду. При совместном использовании команд "U", "u" и 'CTRL-R' вы заметите, что по команде "U" будет восстанавливаться ситуация на строке на тот момент, когда была использована предыдущая команда "U". Это может быть не сразу ясно, поэтому вам следует немного потренироваться, чтобы привыкнуть к этой команде. Команда "U" всегда оставляет буфер в состоянии внесённых несохранённых изменений. Даже если по команде "U" текст возвращается к тому же самому состоянию, что и перед этим, буфер все равно будет переведён в состояние несохранённых изменений. Чтобы вернуть буфер к сохранённому состоянию можно пользоваться командой "u".

2. Два способа выполнения отмены

Принцип действия команд отмены и повтора зависит от флага 'u' в значении опции 'cpoptions'. Существует способ, который принят в Vim (флаг 'u' опущен), и Vi-совместимый способ (флаг 'u' присутствует). В способе Vim команда "uu" выполняет отмену двух последних действий. В Vi-совместимом способе "uu" ничего не делает (точнее, отменяет отмену).

флаг 'u' отсутствует, способ Vim: При помощи команды отмены можно откатываться назад по времени на несколько уровней. Для восстановления изменений используется команда повтора. Если какие-либо изменения были внесены после выполнения команда отмены, то команда повтора работать не будет.

флаг 'u' присутствует, Vi-совместимый способ: Команда отмены отменяет предыдущее изменение, в том числе предыдущую команду отмены. Команда повтора повторяет предыдущую команду отмены. Эта команда НЕ повторяет предыдущую команду изменения, для этого используется команда ".".

Примеры способ Vim Vi-совместимый способ
"uu" двойная отмена без изменений
"u CTRL-R" без изменений двойная отмена

Логика, стоящая за этим, следующая: Nvi использует вместо CTRL-R команду ".". К сожалению, такое поведение не совместимо с Vi. Например, команда "dwdwu." в Vi удаляет два слова, а в Nvi не вызывает изменений в тексте.

3. Замечания об отмене

Количество изменений, которые сохраняются для отмены, устанавливается с помощью опции 'undolevels'. Если значение этой опции равно 0, то всегда используется Vi-совместимая отмена. Если значение этой опции - отрицательное число,то отмена невозможна. Этим можно пользоваться, если вы испытываете нехватку памяти.

Отметки буфера (от 'a до 'z) также сохраняются и могут быть восстановлены, вместе с текстом.
Vi делает это несколько иначе.

Если все внесённые изменения были отменены, то буфер считается неизменённым. В этом случае возможен выход из редактора по команде ":q"  вместо ":q!" {Vi не имеет такой возможности}.

Обратите внимание, что изменения учитываются относительно последней записи файла. Ввод команды "u" после команды ":w" приводит к изменениям буфера по сравнению с сохранённым вариантом -- в этом случае буфер считается изменённым.

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

Для отмены удаления можно также использовать нумерованные регистры. Каждый раз, когда происходит удаление текста, он помещается в регистр "1. Предыдущее содержимое регистра "1 перемещается в регистр "2 и т.д., при этом содержимое регистра "9 утрачивается. Восстановить текст, удалённый в последнюю очередь, можно по команде вклейки, '"1P'. (Кроме того, если удалённый текст является результатом последней операции удаления или копирования, команда 'P' или 'p' также выполняет те же самые действия, вклеивая текст из безымянного регистра.) Текст, удалённый три операции удаления тому назад, можно вклеить по команде '"3P'.

Если вы хотите восстановить более одного фрагмента удалённого текста, то можно воспользоваться специальной особенностью команды повтора ".". Эта команда увеличивает номер использованного регистра. Таким образом, если сначала выполнить команда ""1P", то последующая команда "." приведёт к выполнению команды ""2P". Таким образом можно последовательно вставить содержимое всех нумерованных регистров по очереди.

Пример:   при удалении текста с помощью 'dd....', он может быть восстановлен по команде '"1P....'.

Если вы не знаете, в каком регистре находится удалённый текст, то можно пользоваться командой :display. В качестве альтернативы можно попытаться сначала использовать содержимое первого регистра ('"1P'), а затем при необходимости отменить вставку и продолжить перебор при помощи команды 'u.'. В этом случае операция первой вклейки будет отменена и будет выполнена операция вклейки из второго регистра. Команду 'u.'можно повторять до тех пор, пока не будет достигнут требуемый результат.