I have occasionally had to take over the controls for new emacs users while pair programming because the undo, while logical and consistent, doesn’t work as it does in other software. Each consecutive sequence of undo commands, once interrupted by any command that is not an undo is considered itself to be an atomic undoable change. This means that there is no need for a redo command, just stop undoing and the last undo sequence can be undone. Because emacs has a large undo limit you can keep undoing even past sequences of undos back to the original edit points of the file’s history.
That probably made no sense if you haven’t already mastered it, but another way to think of it is that edits and undos produce a branching tree of all the history of changes being made to the file. The entire tree of changes can be navigated with one command (undo) because that command makes a traversal of the tree, kind of like a post-order tree traversal. This is sufficiently confusing in practice that seeing the nanigation through the tree via the popular undo-tree emacs package helps a lot. I use the undo-tree command when I want to get to a version of the file not on the current main line of edits.
[1] https://www.gnu.org/software/emacs/manual/html_node/emacs/Un...
I'll try binding the undo keystroke to "undo-only", and a redo to normal undo definition, to see if I can get something approximating undo/redo semantics.
Not that Vim is any paragon of UX design. The point is that you can have a powerful undo system without breaking user expectations.
There is an undo-tree implementation for Emacs (based off of Vim), but the default undo described above isn't an undo-tree.
"The only downside to this more advanced yet simpler undo system is that it was inspired by Vim."
As typical in emacs, this is not the only undo behavior you can have. undo-tree behaves very similarly to vim by default, but still preserves the entire editing history (with branching), which is visible graphically with "C-x u".
A big advantage of emacs' tree-like undo is that you never lose any part of your history unlike a naive linear undo sequence. Like in this Firefox edit box for instance, if I type a word, undo it then type an other word I can't go back to the state I was in before I undid the first word. With Emacs I can usually restore any previous state my buffer was in (within the limits of the size of the undo buffer that is).
- Paste 5 time the same line - Press undo 3 times: removes 3 lines - Move the cursor by one character - Press undo 2 times: instead of removing 2 lines it adds back 2
It would be better if the two operations (undo/redo) would be distinct.
E.g. SQL dumps and such.
Emacs' redisplay algorithm is not very efficient if you have very long lines. On the other had on old emacs versions (before 23 IIRC) this was significantly worse as it also had weird UX implications (C-p/C-n working in terms of logical, as opposed to displayed, lines and unability to sanely display lines that are longer than width*height of window).
Other problem is that the gap-buffer data structure is very suboptimal when you start to move the point by multi-MB offsets (which in emacs' case imcludes operations like scrolling to the other end of buffer using scrollbar) as it involves doing memmove() of this multi-MB block of memory.