Undo changes in Emacs with
‘C-x u’ or `
Quoting the EmacsManual,
‘C-/’(or its aliases) undo earlier and earlier changes in the current buffer. If all the recorded changes have already been undone, the undo command signals an error.
‘C-f’or any other command that harmlessly breaks the sequence of undoing; then type
‘C-/’to undo the undo command.
‘M-x undo-only’. This is like
‘undo’, but will not redo changes you have just undone.
When there is an active region, SelectiveUndo is performed on the region.
By default, Emacs only keeps a few dozen undo entries. Increase it by adding the following to your InitFile.
(setq undo-limit 3600)
Having once undone a change with
‘C-x u’ or `
C-_’, you can repeat the undo command by pressing
‘C-x z’, which is
‘repeat’. So the overall sequence of
‘C-x u C-x z z z z z’ undoes changes back through time, and may be easier to type than `
C-_ C-_ …’.
It works with GnuEmacs, yet it does not work with xemacs. Is there any similar trick in it?
Try adding something like
(global-unset-key “\C-z”) (global-set-key “\C-z” ‘advertised-undo)
to your .emacs, now undo (for me much more important than iconifying emacs) will be one of the easiest commands to reach, and iconifying is still bound to C-xz - very convenient I think.
C-/ is also bound to undo. – DavidHouse?
Some people have trouble with the lack of redo or a way to browse the undo tree. There is no built-in way to do these things (aside from mentally trying to keep track of a long string of changes including undos, which some people find very difficult).
Since this is Emacs, it ought to be possible to fix this using a library. Yet every library intended to address the problem so far (e.g. redo.el, undo-browse.el) corrupts the buffer, fails to work on both emacs and xemacs, is out of date and might not even run, is hosted on an obsolete web site, etc. Does anybody know of a good solution here? Thanks!
I think the lack of a natural-feeling undo/redo solution is a big stumbling block for people who would otherwise use emacs – whatever the merits of the built in way.
(I conclude from the lack of response to the above that there is no solution at present, that nobody cares, or that nobody uses this wiki. :( :( :(. Is this true? I find it strange, either way.)
I use the emacswiki, but have no solution for you.
I use the wiki, and to prove that someone cares, I’ve written the UndoTree package to address this :)
Is there an undo at the point level ? I would like to undo point movement too. Right now it’s very hard to tell what is about to be undone.
‘C-u C-SPC’ do what you want? It’s not clear what you’re looking for.
To me it sounds like GotoLastChange is the answer being sought.
(defun undo-all () "Undo all edits." (interactive) (when (listp pending-undo-list) (undo)) (while (listp pending-undo-list) (undo-more 1)) (message "Buffer was completely undone"))
See also RevertBuffer.
(defmacro temporary-invisible-change (&rest forms) "Executes FORMS with a temporary buffer-undo-list, undoing on return. The changes you make within FORMS are undone before returning. But more importantly, the buffer's buffer-undo-list is not affected. This allows you to temporarily modify read-only buffers too." `(let* ((buffer-undo-list) (modified (buffer-modified-p)) (inhibit-read-only t)) (save-excursion (unwind-protect (progn ,@forms) (primitive-undo (length buffer-undo-list) buffer-undo-list) (set-buffer-modified-p modified))) ()))
You would use this either with some kind of delay or read-event so a user sees what happened, or for operations like inserting form feed characters in before printing but having them removed again without a trace afterwords.
(temporary-invisible-change (insert "try this") (forward-line) (insert "try that") (read-key-sequence-vector "Any event:"))
This add-hook eliminates the undo trail that update-file-header creates and M-x undo tracks back through, as well as the narrow-to-buffer, edit, save, undo sequence error: “Changes to be undone are outside visible portion of buffer” message from undo-more. Comments?
(add-hook 'write-file-hooks '(lambda nil (when (buffer-modified-p) (let ((my-buffer-undo buffer-undo-list)) (buffer-disable-undo) ;; flushes buffer-undo-list (update-file-header) (time-stamp) (setq buffer-undo-list my-buffer-undo) (buffer-enable-undo)))))