After making a couple of changes in an xml file opened in Vim I pressed :undolist and got the following output. Is there any way I can see the actual changes? Also what is the difference between number and changes columns? I see the numbers are always the same.
number changes time
2 2 10 seconds ago
if you :h undolist, difference between number and changes is explained. in short, number is a sequence number, changes are how many changes were made on that leaf.
If you want to go back to a earlier state, you could check :h earlier
I recommend a very nice undo plugin: https://github.com/sjl/gundo.vim with this you could view the states in history, without really applying them, until you find the right state.
Related
Vi experts, I have two questions concerning the column editing!
First, I already know how to go to the visual mode and do a column edit. But the point is that after shift+I and type, you can only see the first row changing before esc. My question is this, is it possible to make the editing operation visible in all rows? Or is this still an impossible task with the current vim?
My second question is, I want to insert a column with increasing numbers (0...9) or some user defined increasing items such as (monday...sunday) blahblah, what is the best way to achieve this, can I define a few customized functions and then call them?
"Still an impossible task" exposes a wrong assumption: Vim never wanted to be a WYSIWYG editor; just updating the current row requires less screen updates (which can be significant over slow connections; the whole modal editing of vi was partly born out of that necessity).
There are some attempts at "multiple cursors" plugins; with those, you might achieve this, though.
second question
(Note that it is bad style to ask about two unrelated things in a single question.)
Yes, you can do almost anything in "a few customized functions" (but you'd have to clarify your exact use case to get meaningful answers).
Some of that can be done via the speeddating plugin:
{Visual}<C-A> Increment by [count] the component under the cursor on each line of the linewise visual selection. If a component is absent on a line, it is filled in as being [count] higher than on the line above it. This can be used to create sequences. For example, place a "0" on a line followed by 4 blank lines, visually select all 5 lines, and press <C-A> to get a sequence of 1 through 5. You can use letters in visual mode too: make the first entry Z if you want a list starting with A.
I'd like to have any deleted text always go into the numbered registers, but frequently I go to find something I deleted recently in the numbered registers and it's not there because it was less than one line.
Numbered register 1 contains the text deleted by the most recent
delete or change command, unless the command specified another
register or the text is less than one line (the small delete register
is used then). With each successive deletion or change, Vim shifts the
previous contents of register 1 into register 2, 2 into 3, and so
forth, losing the previous contents of register 9.
It's a fairly rare thing, but when it happens, it's really annoying because I have to undo back to the point where I deleted the text, then either delete into a named register or immediately use the deleted text before it's out of register 0 because I delete something else (stray whitespace, bad comment, whatever) on my way to pasting the small text I just deleted.
I'd like the small delete condition not to matter for text entering the numbered registers 1-9. Anyone know of a way to achieve this?
During another such feature request on Reddit, it was found out that there was a bug in Vim that did exactly that when
:set clipboard^=unnamed
That bug has been fixed in Vim 7.3.649. So, if you use an older version, you could still benefit from the bug :-)
If you really think this is useful behavior, you could raise this enhancement request on the vim_dev mailing list, though in general, additional options are frowned upon. Your chances are higher if you can make a compelling argument and also supply a complete patch with documentation and tests.
Check out the Pull Request into the neovim editor:
[RFC] Add an option to use numbered registers for smaller deletions #8169
I've tried to add the smalldel option, which allows you to configure the minimum number of deleted characters to be pushed into the numbered registers "1.."9
The next neovim release after this PR is merged will contain this option.
I've just changed my 'completeopt' setting back from:
set completeopt = preview,menuone,longest
to the default:
set completeopt = preview,menuone
After a long while of using it as it was, I have decided that I
prefer having the first entry selected by default.
I do have one annoyance though. I would like to be able to try to
complete, if the match I'm looking for isn't in the list then
discard the suggested completion and revert to my original text.
How is this done?
I seem to remember from a distant past that this behaviour exists
but randomly bashing buttons hasn't proved fruitful and searching
isn't working out for me.
Thanks for any help.
You can always type Ctrl-E to return to the original text.
Furthermore, Ctrl-N/Ctrl-P will eventually cycle back to the original text.
See: :help completion for more details:
When completion is active you can use CTRL-E to stop it and go back to the
originally typed text. The CTRL-E will not be inserted.
How can I undo all changes since opening a buffer? I imagine there may be some form of :earlier that does this.
UPDATE: Many are suggesting solutions for traversing to earlier file writes. This isn't what I asked for. I want to return to the original state the file was in when I originally loaded it into a buffer, no matter how many writes were made since then.
To revert the current buffer to the original state prior to the very
first change recorded in its undo list (see :help undo-tree), one
can use the following two consecutive invocations of the :undo
command:
:u1|u
The first command (:undo 1) reverts to the state of the buffer just
after the very first registered change, while the second command
(:undo) reverts that first change itself.
Starting with version 8.1 (see :helpg Patch 8.0.1441), Vim accepts
the change number 0 as a valid argument to the :undo command,
finally providing a way to refer to the state prior to any registered
changes. This makes it possible to achieve the same effect in
a single-command invocation:
:u0
You can use the
:edit!
command to get into the earliest saved state. See :help edit! for more information.
You can also check something like gundo.vim (can be found here), which displays the whole undo tree graphically, and you can easily jump between points. Then there is the histwin plugin which I did not used yet, but offers similar functionality.
In vim 8.1+ as well as in neovim, you can just use :u0
From the documentation
:u[ndo] {N} Jump to after change number {N}. See |undo-branches|
for the meaning of {N}. {not in Vi}
If you type
:u 1
it appears to go to after the first change; pressing u or typing :u will then go back to the change.
Otherwise, you can use a very large count to :earlier or g-
e.g.
:earlier 100000000 or 100000000g-
If you put this into a mapping/command, it could do any of these without too much trouble.
e.g.
:nnoremap <C-F12> :earlier 100000000<CR>
To access previously saved file status, I think the following work :
:earlier 1f
From the documentation :
:earlier {N}f Go 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 when
it was written. Otherwise it will go to the write
before that.
When at the state of the first file write, or when
the file was not written, ":earlier 1f" will go to
before the first change.
:earlier {N}m Go to older text state about {N} minutes before.
That should help... And even you have {N}h which is about {N} hours before.
A graphic solution:
The Gundo plugin allows visual comparison of changes in the undo history.
Open Gundo's "undo history pane", type G go to the last line, then we can back to the original file.
This answer says:
Vim's undo/redo system is unbeatable. Type something, undo, type something else, and you can still get back the first thing you typed because Vim uses an undo tree rather than a stack. In almost every other program, the history of the first thing you typed is lost in this circumstance.
This is the first I hear of this. How can I backtrack along the tree?
See also :h undo-redo, which lists all the commands and their usage.
There are two ways to traverse the undo tree. One is to go "back in time". g+ and g- will traverse all of the nodes in the tree in chronological or reverse-chronological order (which can be a bit confusing, because it can jump arbitrarily between undo branches, but if you do g- long enough you'll always get where you need to go eventually). :earlier and :later take a time descriptor like 7m or 1h; again this can jump you arbitrarily between undo branches.
The other way is to jump to specific nodes in the tree using :undo n where n is a number of an action. (All actions, i.e. text additions, deletions, replacements, are numbered sequentially as you do them.) You can look up the number of the actions on the leaves of the undo tree via :undolist. This will let you jump between branches easily. You can then use u and Ctrl-R to move up and down that branch.
There are some good examples in the Vim help. The best way to figure out how this works is to play with it a bit.
I'm a bit late to the party,
but I figured I'd mention that I wrote an undo tree visualization plugin for Vim :
https://github.com/sjl/gundo.vim
Personally I found that graphing the tree like this was the only way I could make sense of it.
This page explains everything you need to know:
http://vimdoc.sourceforge.net/htmldoc/usr_32.html
If you're using vim, you can navigate through the undo tree using:
u: (undo) move back in the undo tree
Ctrl+R: (redo) move forward in the undo tree
Other ways of bringing document back or forward in time:
:earlier 15m: move back in time 15 minutes
:later 15m: move front in time 15 minutes
I'm aware this question has been answered, but I thought I'd add an example.
Create a new file and type:
this is a line
undol will display the undo tree. At this point you haven't undone anything
:undol
number changes when saved
1 1 14:50:36
now press ESC and modify the line to:
this is a old line
switch to normal mode and press u (undo), this should remove "old". If you check undol, at this point you still have only one branch.
now modify the line so it says:
this is a new line
Now :undol shows:
number changes when saved
2 2 87 seconds ago
3 2 3 seconds ago
You can switch to the first branch by typing
:u 2
this will move you to the end of the branch associated with number 2. You can move along this branch with g+ and g-. At this point g+ will do nothing (you are at the leaf). If you press g- “old" will be removed (you are traversing the first undo tree). That is if you remove “old” with g- and press g+ again, “old" will be redone.
If you type
:u 3
You will jump to the leaf of the second undo branch and it will read:
this is a new line
A lot of this is summed up here:
http://vim.wikia.com/wiki/Using_undo_branches
Besides using gundo.vim I like to mention g+ and g-
The package undotree is written in pure vimscript so no requirement.
And add this to your vimrc before it is too late:
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