Let's say I make 3 changes, C1, C2, and C3.
Then I undo X3. Then I redo X3. I'm back where I started.
Then I undo X3 again, but then I accidentally type ifoo<Esc>. What can I now do to recover change #3?
Vim is special in that it not just stores a linear history of edits (and undo), but actually all branches! You can use the g- and g+ commands to move through them, and the :earlier command to move to text states by count, seconds, minutes, etc. See :help undo-branches and :help usr_32.txt for details.
Plugin recommendations
Because that kind of navigation is still mentally taxing (and one doesn't want to get lost in a potentially huge undo tree!), the undotree.vim - Display your undo history in a graph and Gundo - Visualize your undo tree plugins provide a much better visualization, including diffs to see what changed in each state.
Given that sequence, you should be able to type g- (g-) one time to get back to change 3. You might want to open another instance of Vim and test it to verify it does what you want.
Type :h undo-branches for more information.
Related
Suppose state A in my document, I make change to B, C then D.
Now I typed 'u', the state goes to C.
I type 'u' again it goes back to D. (the second undo looks like redo to me).
In my understanding, undo means that I undo it once it will return to C, then undo again to it will return to B then undo again it will return to A.
Also, I know 'u3' can work here but in most cases I have no way to keep track of the number of state changes.
How can I achieve unlimited undo in Vim?
You have only 1 level of undo if you are in Vi compatible mode. You are missing out on a number of features by being in 'compatible' mode. Just create a ~/.vimrc file and you will automatically disable 'compatible' mode.
What wonderful undo features do you get by using 'nocompatible'?
Unlimited undo
Persistent undo
Undo branches (like an undo tree)
I like the old vi undo/redo commands which allows undo (u) or redo (CTRL-R) to be pressed multiple times rather than browsing history to figure out the number of changes to undo.
The vi command uses the ~/.exrc file, not ~/.vimrc so just add "set nocompatible" to the file.
Note that I like using a single undo/redo to jump back to the last place in a file that I changed, and "u" followed by CTRL-R does the trick. And I can always hold down the "u" until all changes are undone including those I might have already saved.
Is there a VIM absolute (registers, marks, undo history, tags) bar or tree toggle ?
I mean, like the tag-bar, but with subsections. Having the primary sections to be the followings, custom marks, custom registers, custom records, undo history (as the Gundo plug-in). So undo the bar, we can go to a mark, execute a record, yank or paste a register, etc.....
If there is not, would anyone like to help me build it??? Or just, help me with good starting tutorials for vim plug-in building, since it'll be the first one that I'll make.
No, there's nothing like that, what would be the point of such a monster?
Aren't :marks, :registers, :changes, :undolist… enough?
Anyway, you should start by getting familiar with Vim's built-in documentation: :help eval contains all the raw info you will need.
Steve Losh's Learn Vimscript the Hard Way is a really great third party ressource and the Vim Wiki can be useful, too.
Though plugins like tagbar and Gundo efficiently display information in a side bar, like IDEs, this is mostly a concession to what today's users are used to, but not a fundamental way to use vi(m). Marks and registers are meant to be memorized by their names (a..z), with the :marks, :registers, etc. commands to provide you a refresher after a long break / the next day.
There are many plugins (e.g. for automatic mark management and visualization), but I would recommend to use them sparingly. It's definitely a "smell" if you want to turn Vim into a full-blown IDE. Please don't.
In vim, I would like to undo through all changes in all buffers, in chronological order.
e.g., in a vim session I typically have many tabs open, with many windows in each tab. Using u to undo (or g; / g, to move though the changelist), vim moves through changes made to that buffer, even if there are more recent made changes in other buffers. (Which I admit, is what I want most of the time.)
But is there a way to move back through changes in all buffers in chronological order? (I imagine vim would jump around from tab to tab, which would be ok.)
Why would this be useful? ... mostly so when I resume coding after a break I can remind myself of "where I'm up to", i.e all the changes I made last time.
(Using macvim 7.3)
UPDATE: responses about using git / mercurial make good points (thanks especially for git stash), but I'd still find this feature useful as it steps me back through recent changes, in order, with syntax coloring, inside vim etc.)
You could come a long way with undolist:
:bufdo echo expand('%') | undolist
Results in, e.g. for a simple editing session:
SpiritParser.cpp
number changes when saved
1 1 13:57:51
SpiritParser.h
number changes when saved
1 1 13:57:55
To do this for all visible windows, do windo instead of bufdo. If you have multiple tabs, make that
:tabdo windo echo expand('%') | undolist
You should be using some kind of version control: Git, Mercurial, Subversion, whatever…
Each morning you can read your project's log and go through previous commits to see what changed, you can create branches to work on specific features, you write clean and descriptive commit message in order to better understand your previous changes, etc.
Or you could do something like :windo u. But that sounds messy.
Sometimes I hit the wrong keys on my laptop's small keyboard, and odd navigation or editing occurs (sometimes a feature that's new to me).
Although I can undo the editing (u) or navigation (control-o), I don't know what I did wrong, so it's difficult to avoid it in future. It's also frustrating to not know what just happened. So, I would like to be able to see my last few keystrokes.
A bit like :set showcmd, but to show the literal keystrokes, and (ideally) a short history of them.
I've only found commandline and navigation history in help/google.
To clarify: I'm not looking for commandline history, but keystroke history. e.g. did I press ) accidentally and go to the next sentence? Did I press dd and delete a line? I guess it's similar to a keystroke logger.
Commandline history (:history) only shows commands entered at the : prompt.
A bit old, but I've just found this on reddit:
You can start vim with the -w flag to write all keystrokes in a file. See :h -w
vim -w filename
To my knowledge, the closest you can get is the q command, which records your keystrokes into a register of your choice. Obviously, that has to be set up a priori as it's intended for complex repeats, although you could probably hack something to start recording on every file open. There's the matter of memory usage and that annoying "recording" prompt though.
Probably the most straightforward way would be to install keylogging software. I don't have any personal experience with these, but the security implications are probably mild if you get it from a trustworthy source or build it yourself, set it to only log to memory not a disk, only have a buffer the size of a sentence or so, or only log for vim windows.
More recently I came across a logging plugin for Vim and it reminded me of this question:
http://wolever.net/~wolever/wiki/vim-logging
It basically records everything you do for later analysis, it was intended for getting statistics about command usage but should work perfectly for finding what those magic commands you accidentally entered were.
:history will show your command history - that should help you uncover the new features that we all uncover in vim with misplaced keystrokes.
Gundo - Is probably worth a look, whilst perhaps not exactly what you are looking it will help slightly.
It lets you visualise the Vim undo tree, this means you will be able to see the last edits that happened. For example if you accidentally deleted a line or some such this will show up in the tree, however, it doesn't show you the actual keystrokes that were pushed and will not show things such as cursor movements.
In Vim, is there a way to select a block of text and use undo to only undo changes to that block of text?
Let's say I rewrite a function, then go and make some changes elsewhere in my file. Afterwards, I realize that my first function implementation was indeed better. I'd like to undo the changes I made in that function, but leave my subsequent additions intact.
I don't know if this is even possible, but I often find myself wanting this feature.
Currently... No. Vim 7.3 has undo branches that you can traverse but as far as I know Vim does not pay attention to any selected text during an undo.
Maybe this:
http://sjl.bitbucket.org/gundo.vim/
http://stevelosh.com/blog/2010/09/coming-home-to-vim/
https://github.com/tpope/vim-pathogen