Undo
Nvim:help pages,generated fromsource using thetree-sitter-vimdoc parser.
Undo and redo
The basics are explained in section
02.5 of the user manual.
:u[ndo]!Undo one change and remove it from undo history.
E5767:u[ndo]!
{N}Like ":u[ndo]
{N}", but forget all changes in thecurrent undo branch up until
{N}. You may only use":undo!
{N}" to move backwards in the same undobranch, not to redo or switch to a different undobranch.
CTRL-RCTRL-RRedo [count] changes which were undone.
UUUndo all latest changes on one line, the line wherethe latest change was made.
U itself also counts asa change, and thus
U undoes a previous
U.
The last changes are remembered. You can use the undo and redo commands aboveto revert the text to how it was before each change. You can also apply thechanges again, getting back the text before the undo.
The "U" command is treated by undo/redo just like any other command. Thus a"u" command undoes a "U" command and a 'CTRL-R' command redoes it again. Whenmixing "U", "u" and 'CTRL-R' you will notice that the "U" command willrestore the situation of a line to before the previous "U" command. This maybe confusing. Try it out to get used to it.The "U" command will always mark the buffer as changed. When "U" changes thebuffer back to how it was without changes, it is still considered changed.Use "u" to undo changes until the buffer becomes unchanged.
How undo and redo commands work depends on the 'u' flag in
'cpoptions'.There is the Vim way ('u' excluded) and the Vi-compatible way ('u' included).In the Vim way, "uu" undoes two changes. In the Vi-compatible way, "uu" doesnothing (undoes an undo).
'u' excluded, the Vim way:You can go back in time with the undo command. You can then go forward againwith the redo command. If you make a new change after the undo command,the redo will not be possible anymore.
'u' included, the Vi-compatible way:The undo command undoes the previous change, and also the previous undocommand. The redo command repeats the previous undo command. It does NOTrepeat a change command, use "." for that.
ExamplesVim wayVi-compatible way
"uu"two times undono-op"u
CTRL-R"no-optwo times undo
Rationale: Nvi uses the "." command instead ofCTRL-R. Unfortunately, this is not Vi compatible. For example "dwdwu." in Vi deletes two words, in Nvi it does nothing.
One undo command normally undoes a typed command, no matter how many changesthat command makes. This sequence of undo-able changes forms an undo block.Thus if the typed key(s) call a function, all the commands in the function areundone together.
If you want to write a function or script that doesn't create a new undoablechange but joins in with the previous change use this command:
:undoj:undojoinE790:undoj[oin]Join further changes with the previous undo block.
Warning: Use with care, it may prevent the user fromproperly undoing changes. Don't use this after undoor redo.
This is most useful when you need to prompt the user halfway through a change.For example in a function that calls
getchar(). Do make sure that there wasa related change before this that you must join with.
This doesn't work by itself, because the next key press will start a newchange again. But you can do something like this:
:undojoin | delete
After this a "u" command will undo the delete command and the previouschange.
undo-breakundo-close-blockTo do the opposite, use a new undo block for the next change, in Insert modeuse
CTRL-G u. This is useful if you want an insert command to be undoable inparts. E.g., for each sentence.
i_CTRL-G_uSetting the value of
'undolevels' also closes the undo block. Even when thenew value is equal to the old value. Use
g:undolevels to explicitly readand write only the global value of
'undolevels'.
let &g:undolevels = &g:undolevels
Note that the similar-looking assignment
let &undolevels=&undolevels does notpreserve the global option value of
'undolevels' in the event that the localoption has been set to a different value. For example:
" Start with different global and local values for 'undolevels'.let &g:undolevels = 1000let &l:undolevels = 2000" This assignment changes the global option to 2000:let &undolevels = &undolevels
Above we only discussed one line of undo/redo. But it is also possible tobranch off. This happens when you undo a few changes and then make a newchange. The undone changes become a branch. You can go to that branch withthe following commands. The undo-tree of a file can be visualized andinteractively applied using
undotree-plugin.
:undol:undolist:undol[ist]List the leafs in the tree of changes. Example:
number changes when saved
88 88 2010/01/04 14:25:53 108 107 08/07 12:47:51 136 46 13:33:01 7 166 164 3 seconds ago
The "number" column is the change number. This numbercontinuously increases and can be used to identify aspecific undo-able change, see
:undo.The "changes" column is the number of changes to thisleaf from the root of the tree.The "when" column is the date and time when thischange was made. The four possible formats are: N seconds ago HH:MM:SS hour, minute, seconds MM/DD HH:MM:SS idem, with month and day YYYY/MM/DD HH:MM:SS idem, with yearThe "saved" column specifies, if this change waswritten to disk and which file write it was. This canbe used with the
:later and
:earlier commands.For more details use the
undotree() function.
g-g-Go to older text state. With a count repeat that manytimes.
:ea:earlier:ea[rlier]
{count}Go to older text state
{count} times.:ea[rlier]
{N}sGo to older text state about
{N} seconds before.:ea[rlier]
{N}mGo to older text state about
{N} minutes before.:ea[rlier]
{N}hGo to older text state about
{N} hours before.:ea[rlier]
{N}dGo to older text state about
{N} days before.
:ea[rlier]{N}fGo to older text state{N} file writes before.When changes were made since the last write":earlier 1f" will revert the text to the state whenit was written. Otherwise it will go to the writebefore that.When at the state of the first file write, or whenthe file was not written, ":earlier 1f" will go tobefore the first change.
g+g+Go to newer text state. With a count repeat that manytimes.
:lat:later:lat[er]
{count}Go to newer text state
{count} times.:lat[er]
{N}sGo to newer text state about
{N} seconds later.:lat[er]
{N}mGo to newer text state about
{N} minutes later.:lat[er]
{N}hGo to newer text state about
{N} hours later.:lat[er]
{N}dGo to newer text state about
{N} days later.
:lat[er]{N}fGo to newer text state{N} file writes later.When at the state of the last file write, ":later 1f"will go to the newest text state.
Note that text states will become unreachable when undo information is clearedfor
'undolevels'.
Don't be surprised when moving through time shows multiple changes to takeplace at a time. This happens when moving through the undo tree and thenmaking a new change.
EXAMPLE
Start with this text:
one two three
Delete the first word by pressing "x" three times:
ne two three
e two three
two three
Now undo that by pressing "u" three times:
e two three
ne two three
one two three
Delete the second word by pressing "x" three times:
one wo three
one o three
one three
Now undo that by using "g-" three times:
one o three
one wo three
two three
You are now back in the first undo branch, after deleting "one". Repeating"g-" will now bring you back to the original text:
e two three
ne two three
one two three
Jump to the last change with ":later 1h":
one three
And back to the start again with ":earlier 1h":
one two three
Note that using "u" andCTRL-R will not get you to all possible text stateswhile repeating "g-" and "g+" does.
When unloading a buffer Vim normally destroys the tree of undos created forthat buffer. By setting the
'undofile' option, Vim will automatically saveyour undo history when you write a file and restore undo history when you editthe file again.
The
'undofile' option is checked after writing a file, before the BufWritePostautocommands. If you want to control what files to write undo informationfor, you can use a BufWritePre autocommand:
au BufWritePre /tmp/* setlocal noundofile
Vim saves undo trees in a separate undo file, one for each edited file, usinga simple scheme that maps filesystem paths directly to undo files. Vim willdetect if an undo file is no longer synchronized with the file it was writtenfor (with a hash of the file contents) and ignore it when the file was changedafter the undo file was written, to prevent corruption. An undo file is alsoignored if its owner differs from the owner of the edited file, except whenthe owner of the undo file is the current user. Set
'verbose' to get amessage about that when opening a file.
Location of the undo files is controlled by the
'undodir' option, by defaultthey are saved to the dedicated directory in the application data folder.
You can also save and restore undo histories by using ":wundo" and ":rundo"respectively:
:wu:wundo:wu[ndo][!]
{file}Write undo history to
{file}.When
{file} exists and it does not look like an undo file(the magic number at the start of the file is wrong), thenthis fails, unless the ! was added.If it exists and does look like an undo file it isoverwritten. If there is no undo-history, nothing will bewritten.Implementation detail: Overwriting happens by first deletingthe existing file and then creating a new file with the samename. So it is not possible to overwrite an existing undofilein a write-protected directory.
You can use these in autocommands to explicitly specify the name of thehistory file. E.g.:
au BufReadPost * call ReadUndo()au BufWritePost * call WriteUndo()func ReadUndo() if filereadable(expand('%:h') .. '/UNDO/' .. expand('%:t')) rundo %:h/UNDO/%:t endifendfuncfunc WriteUndo() let dirname = expand('%:h') .. '/UNDO' if !isdirectory(dirname) call mkdir(dirname) endif wundo %:h/UNDO/%:tendfuncYou should keep
'undofile' off, otherwise you end up with two undo files forevery write.
You can use the
undofile() function to find out the file name that Vim woulduse.
Note that while reading/writing files and
'undofile' is set most errors willbe silent, unless
'verbose' is set. With :wundo and :rundo you will get moreerror messages, e.g., when the file cannot be read or written.
NOTE: undo files are never deleted by Vim. You need to delete them yourself.
Reading an existing undo file may fail for several reasons:
E822 It cannot be opened, because the file permissions don't allow it.
E823 The magic number at the start of the file doesn't match. This usuallymeans it is not an undo file.
E824 The version number of the undo file indicates that it's written by anewer version of Vim. You need that newer version to open it. Don'twrite the buffer if you want to keep the undo info in the file."File contents changed, cannot use undo info"The file text differs from when the undo file was written. This meansthe undo file cannot be used, it would corrupt the text. This alsohappens when
'encoding' differs from when the undo file was written.
E825 The undo file does not contain valid contents and cannot be used."Not reading undo file, owner differs"The undo file is owned by someone else than the owner of the textfile. For safety the undo file is not used.
Writing an undo file may fail for these reasons:
E828 The file to be written cannot be created. Perhaps you do not havewrite permissions in the directory."Cannot write undo file in any directory in
'undodir'"None of the directories in
'undodir' can be used."Will not overwrite with undo file, cannot read"A file exists with the name of the undo file to be written, but itcannot be read. You may want to delete this file or rename it."Will not overwrite, this is not an undo file"A file exists with the name of the undo file to be written, but itdoes not start with the right magic number. You may want to deletethis file or rename it."Skipping undo file write, nothing to undo"There is no undo information to be written, nothing has been changedor
'undolevels' is negative.
E829 An error occurred while writing the undo file. You may want to tryagain.
The number of changes that are remembered is set with the
'undolevels' option.If it is zero, the Vi-compatible way is always used. If it is negative noundo is possible. Use this if you are running out of memory.
clear-undoWhen you set
'undolevels' to -1 the undo information is not immediatelycleared, this happens at the next change. To force clearing the undoinformation you can use these commands:
:let old_undolevels = &l:undolevels:setlocal undolevels=-1:exe "normal a \<BS>\<Esc>":let &l:undolevels = old_undolevels:unlet old_undolevels
Note use of
&l:undolevels to explicitly read the local value of
'undolevels'and the use of
:setlocal to change only the local option (which takesprecedence over the corresponding global option value). Saving the optionvalue via the use of
&undolevels is unpredictable; it reads either the localvalue (if one has been set) or the global value (otherwise). Also, if a localvalue has been set, changing the option via
:set undolevels will change boththe global and local values, requiring extra work to save and restore bothvalues.
Marks for the buffer ('a to 'z) are also saved and restored, together with thetext.
When all changes have been undone, the buffer is not considered to be changed.It is then possible to exit Vim with ":q" instead of ":q!".Note that this is relative to the last write of the file. Typing "u" after":w" actually changes the buffer, compared to what was written, so the bufferis considered changed then.
When manual
folding is being used, the folds are not saved and restored.Only changes completely within a fold will keep the fold as it was, becausethe first and last line of the fold don't change.
The numbered registers can also be used for undoing deletes. Each time youdelete text, it is put into register "1. The contents of register "1 areshifted to "2, etc. The contents of register "9 are lost. You can now getback the most recent deleted text with the put command: '"1P'. (also, if thedeleted text was the result of the last delete or copy operation, 'P' or 'p'also works as this puts the contents of the unnamed register). You can getback the text of three deletes ago with '"3P'.
redo-registerIf you want to get back more than one part of deleted text, you can use aspecial feature of the repeat command ".". It will increase the number of theregister used. So if you first do '"1P', the following "." will result in a'"2P'. Repeating this will result in all numbered registers being inserted.
Example:If you deleted text with 'dd....' it can be restored with'"1P....'.
If you don't know in which register the deleted text is, you can use the:display command. An alternative is to try the first register with '"1P', andif it is not what you want do 'u.'. This will remove the contents of thefirst put, and repeat the put command for the second register. Repeat the'u.' until you got what you want.