Как в Vim используется дерево отмены?

Этот ответ говорит:

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

Я впервые об этом слышу. Как я могу вернуться назад по дереву?


person Nathan Fellman    schedule 06.07.2009    source источник
comment
Завистливые пользователи Emacs могут захотеть узнать о дереве отмены- режим.   -  person Aaron Miller    schedule 05.08.2013


Ответы (8)


См. Также :h undo-redo, в котором перечислены все команды и их использование.

Есть два способа пройти по дереву отмены. Один - вернуться «в прошлое». g+ и g- будут проходить все узлы в дереве в хронологическом или обратном хронологическом порядке (что может немного сбивать с толку, потому что оно может произвольно прыгать между ветвями отмены, но если вы делаете g- достаточно долго, вы всегда попадете туда, где вы нужно ехать в конце концов). :earlier и :later принимают дескриптор времени, например 7m или 1h; опять же, это может произвольно переключать вас между ветвями отмены.

Другой способ - перейти к определенным узлам в дереве, используя :undo n, где n - номер действия. (Все действия, т. Е. Добавления текста, удаления, замены, нумеруются последовательно по мере их выполнения.) Вы можете посмотреть количество действий на листьях дерева отмены с помощью :undolist. Это позволит вам легко перепрыгивать между ветками. Затем вы можете использовать u и Ctrl-R для перемещения вверх и вниз по этой ветке.

В справке по Vim есть несколько хороших примеров. Лучший способ понять, как это работает, - немного поиграть с этим.

person Brian Carper    schedule 06.07.2009
comment
Можете ли вы объединить ветки? (Я шучу) - person he_the_great; 09.02.2010
comment
Своего рода из. Посмотрите вверх: h undojoin - person Pod; 19.02.2011
comment
Vim настолько классный, что даже реализует способы, которыми мы шутим над тем, насколько он крутой! - person andyortlieb; 10.11.2011
comment
Я не знала, как пользоваться этим деревом отмены, но знала, что когда-нибудь оно спасет мне жизнь. Что ж, день настал. Спасибо!! - person ndvo; 30.01.2013
comment
@Pod Похоже, undojoin не имеет ничего общего с ветвями; фактически, следующий раздел справки начинается с того, что выше мы обсуждали только одну строку отмены / повтора. Но также возможно разветвление. Есть ли способ использовать undojoin с ветками, которые я просто не вижу? - person Kyle Strand; 08.11.2013
comment
persistent-undo потрясающе. - person alpha_989; 31.01.2018
comment
Нет смысла присоединяться к веткам отмены, потому что они могут состоять из противоречащих друг другу изменений. undojoin может помочь объединить ряд предстоящих изменений в один блок отмены, чтобы их можно было отменить одной отменой позже в файле. - person elig; 13.03.2019

Я немного опоздал на вечеринку,
но подумал, что упомянул, что написал плагин для визуализации дерева отмены для Vim:
https://github.com/sjl/gundo.vim

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

person Steve Losh    schedule 18.10.2010
comment
Более современный репозиторий git существует по адресу github.com/sjl/gundo.vim. . С помощью vim-plug плагин можно установить с помощью Plug 'sjl/gundo.vim', а затем nnoremap <F5> :GundoToggle<CR> (заменяя <F5> любой последовательностью клавиш, которую вы хотите привязать) - person ewen-lbh; 20.06.2020

На этой странице объясняется все, что вам нужно знать:

http://vimdoc.sourceforge.net/htmldoc/usr_32.html

person SolutionYogi    schedule 06.07.2009

Если вы используете vim, вы можете перемещаться по дереву отмены, используя:

  • u: (отменить) вернуться в дерево отмены
  • Ctrl+R: (повторить) двигаться вперед в дереве отмены

Другие способы вернуть документ назад или вперед во времени:

  • :earlier 15m: вернуться во времени на 15 минут
  • :later 15m: двигаться вперед во времени 15 минут
person Wadih M.    schedule 06.07.2009
comment
Этот ответ объясняет только, как двигаться вперед и назад по одной ветке. Не как перемещаться между ветками. - person Jonathan Hartley; 03.08.2016
comment
Это будет перемещаться по всем веткам, сортируя все точки по времени. См. Ответ @BrianCarper. - person Holloway; 25.04.2017
comment
@JonathanHartley, если вы используете earlier и later, он не перемещается по веткам. Я ожидал, что большинству людей все равно и они не помнят различные ветки, которые они создали. Но просто хочу вернуться в прошлое. Если вы хотите создавать ветки и называть их, возможно, git или система контроля версий будет лучшим вариантом. - person alpha_989; 31.01.2018
comment
@ alpha_989 Ваши комментарии по поводу контроля версий не имеют смысла. Контроль версий предназначен для состояния именованных файлов на диске. Мы говорим о дереве отмены Vim, которое представляет собой просто структуры данных в памяти. Оба они используют слово «ветвь», но это не одно и то же. - person Jonathan Hartley; 05.02.2018
comment
Спасибо всем, кто указывал на то, что раньше / позже ДЕЙСТВИТЕЛЬНО перемещайтесь по веткам! - person Jonathan Hartley; 05.02.2018
comment
@JonathanHartley .. вы правы .. Когда вы используете _1 _ / _ 2_, вы перемещаетесь по ветвям постоянной отмены. Я использовал branch в контексте git. по моему ограниченному мнению, постоянная отмена - это своего рода контроль версий, потому что вы можете создать определенную ветку и продолжать работать с этой веткой этого файла. Затем вы можете создать новую ветку и работать над тем, что будет имитировать ветки git. Я говорил, что вы не должны использовать vim ветки вместо git-branches. - person alpha_989; 05.02.2018
comment
Если вы определяете undodir, persistent-undo сохраняет отмены ветвей на диске. Дело не только в памяти. - person alpha_989; 05.02.2018
comment
Спасибо, что объяснили свои мысли. - person Jonathan Hartley; 06.02.2018
comment
u и Ctrl-r перемещаются не в дереве отмены, а в стеке отмены. g+ и g- также перемещаются в дереве через ветви. - person elig; 13.03.2019

Я знаю, что на этот вопрос был дан ответ, но я подумал, что добавлю пример.

Создайте новый файл и введите:

this is a line

undol отобразит дерево отмены. На данный момент вы ничего не отменили

:undol

number changes  when               saved
     1       1  14:50:36

теперь нажмите ESC и измените строку на:

this is a old line

переключитесь в нормальный режим и нажмите u (отменить), это должно удалить "старый". Если вы отметите undol, на данный момент у вас все еще есть только одна ветка.

теперь измените строку так, чтобы она говорила:

this is a new line

Теперь :undol показывает:

number changes  when               saved
     2       2  87 seconds ago
     3       2  3 seconds ago

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

:u 2

это переместит вас в конец ветки, связанной с номером 2. Вы можете перемещаться по этой ветке с помощью g+ и g-. В этот момент g+ ничего не будет делать (вы на листе). Если вы нажмете g-, «старый» будет удален (вы проходите по первому дереву отмены). То есть, если вы удалите «старый» с помощью g- и снова нажмете g+, «старый» будет восстановлен.

Если вы наберете

:u 3

Вы перепрыгнете к листу второй ветки отмены, и на нем будет написано:

this is a new line
person Alexander    schedule 25.05.2014

Здесь многое из этого резюмируется:

http://vim.wikia.com/wiki/Using_undo_branches

person Ben Fritz    schedule 16.01.2012

Помимо использования gundo.vim я хотел бы упомянуть g+ и g-

person vbd    schedule 30.01.2014

Пакет undotree написан на чистом vimscript, поэтому нет необходимости.

И добавьте это в свой vimrc, пока не стало слишком поздно:

  set nobackup
  set noswapfile
  set nowritebackup
  set undolevels=10000         " use many levels of undo
  set history=10000    " After nocompatible

  if has('persistent_undo')
    set undodir=$HOME/.vim/undo
    set undofile 
  endif 

введите здесь описание изображения

person Tinmarino    schedule 10.12.2019