So machen Sie den Undo-Tree linear - Undo-Tree-Undo / Redo

10

Wenn der Befehl undo-tree-undo/redonacheinander ausgeführt wird, werden die Dinge basierend auf dem aktuell aktiven Zweig rückgängig gemacht / wiederholt. Obwohl der Benutzer unterwegs eine Verzweigungspunktnachricht erhält, werden die vorherigen Verzweigungen ignoriert, es sei denn, ein Benutzer wählt manuell eine andere Verzweigung aus.

Ich verstehe, dass ich den Visualizer öffnen und einen anderen Zweig auswählen kann. Es wäre jedoch sehr nützlich, einfach die Rückgängig- / Wiederherstellungs-Taste gedrückt zu halten und zu beobachten, wie alles in genau entgegengesetzter Reihenfolge abläuft. Im Idealfall sollte dies unabhängig davon funktionieren, ob der visualizerPuffer geöffnet ist - dh programmgesteuert die Reihenfolge von Ende bis Anfang und von Anfang bis Ende berechnen.

F : Dies ist im Wesentlichen eine Funktionsanforderung, die erweitert werden muss undo-tree, um ein lineares aufeinanderfolgendes Rückgängigmachen / Wiederherstellen zu ermöglichen, unabhängig davon, ob der Visualisierungspuffer geöffnet ist. [Neue Funktionen und alternative Tastaturkürzel für diese neue Funktion sind sicherlich akzeptabel.]

Gesetzesliste
quelle
Der Code of undo-treesieht so aus, als ob er Teil des Konzepts ist, dass Sie frei zwischen buffer-undo-treeund buffer-undo-listdurch Umschalten wechseln können undo-tree-mode. Soweit ich Ihre Frage verstehe, macht die ursprüngliche Behandlung von buffer-undo-list, was Sie wollen. Es empfiehlt sich daher, undo-tree-modefür Ihren Zweck vorübergehend abzuschalten . Schade, dass das Umschalten zwischen buffer-undo-treeund fehlerhaft buffer-undo-listzu sein scheint (zumindest für mich). Vielleicht wäre der Weg nur ein Fehlerbericht an den Betreuer von undo-tree. Aber vielleicht ist meine Vermutung über das ursprüngliche Konzept falsch.
Tobias
Ich denke, die beste Lösung für Ihr Problem wäre, es so zu reparieren undo-tree-mode, dass das Umschalten zwischen buffer-undo-treeund buffer-undo-listeinwandfrei funktioniert. Haben Sie darüber nachgedacht, einen Fehlerbericht unter "toby-undo-tree @ dr-qubit.org" zu veröffentlichen?
Tobias
@Tobias - Ich möchte den Visualizer von sehen und verwenden, undo-treewährend ich die neue linearFunktion verwende. und ich möchte, dass die neue linearFunktion funktioniert, ohne dass der Visualizer-Puffer unbedingt sichtbar ist. Im Allgemeinen implementiere ich meine eigenen Verbesserungen / Modifikationen an Emacs, sowohl den integrierten als auch den optionalen Bibliotheken von Drittanbietern. Wenn ich nicht weiterkomme oder etwas sehr Komplexes wie die undoFunktion sehe, bitte ich um Hilfe. Eine Funktionsanfrage an den Betreuer konnte nicht schaden, aber ich würde es vorziehen, sie hier zu bearbeiten.
Lawlist
@Tobias - Beim Betrachten des undo-tree.elheutigen Codes habe ich festgestellt , dass es eine Knotenzeitstempelfunktion gibt. Ich bin nicht sicher, ob jeder Knoten einen gültigen Zeitstempel hat und ob diese bis zur nächsten Emacs-Sitzung (beim Wiederherstellen des Verlaufs) überleben, aber das scheint eine Abkürzung zum Auflösen dieser neuen Funktionsanforderung zu sein - dh Sortieren und Auswählen die vorherige oder nächste in der Zeit. Ich habe noch nicht gesehen, wie das Layout des Landes an einem Verzweigungspunkt aussieht, aber ... das sind meine vorläufigen Gedanken. . . .
Lawlist
Ich denke, der Schlüssel zu einem linearen Spaziergang durch den Rückgängig-Baum ist undo-list-rebuild-from-tree. Man sollte letdie Variable binden buffer-undo-listund undo-list-rebuild-from-treeihre Arbeit machen lassen. Kopieren Sie anschließend diesen Wert beispielsweise in eine andere lokale Variable my-undo-listund lassen Sie das letFormular zum Binden buffer-undo-list. Die Variable bestimmt my-undo-listden linearen Pfad durch die undo-tree. Ein Blick darauf zeigt undo-list-rebuild-from-tree, dass diese Funktion auch Zeitstempel verwendet. Ich habe früher überlegt, Zeitstempel zu verwenden. Aber ich hatte den Eindruck, dass sich diese zu oft ändern.
Tobias

Antworten:

7

Das Folgende ist ein Prototyp einer Implementierung einer Annäherung an das, was Sie wollen. Es nutzt die Tatsache aus, dass neue Zweige im Rückgängig-Baum auf der linken Seite des aktuellen Knotens hinzugefügt werden.

Die Tastenfolge C-M-_ist gebunden, an undo-tree-walkdie der rechte obere Teil des Rückgängig-Baums ab dem aktuellen Knoten verläuft.

Das Verhalten unterscheidet sich von dem, was Sie möchten, wenn der aktive Zweig eines Unterbaums auf der rechten Seite des aktuellen Knotens nicht der am weitesten links stehende Zweig in diesem Unterbaum ist.

Sie können in einen solchen Zustand gelangen, indem Sie nicht-trivalente Undo / Redo-Sequenzen ausführen.

Probieren Sie es einfach selbst aus, um zu sehen, ob dies für Ihre Anwendung ausreicht.

(defvar-local undo-tree-walk
  "Possible values:
nil: not in undo/redo-chain
undo: traversing undo tree upwards
redo: traversing undo tree downwards
")

(setq undo-tree-walk nil)

(defun undo-tree-walk ()
  "Walk the right-upper part of the undo-tree starting at the current node."
  (interactive)
  (when (eq buffer-undo-list t)
    (user-error "No undo information."))
  (unless undo-tree-mode
    (user-error "`undo-tree-walk' should only be used with `undo-tree-mode'."))
  (undo-list-transfer-to-tree)
  (set-transient-map undo-tree-walk-map t #'undo-tree-walk-off)
  (let ((num-branches (undo-tree-num-branches)))
    (cond
     ((= num-branches 0) ; arrived at leaf
      (setq undo-tree-walk 'undo))
     ((> num-branches 1) ; 
      (let ((branch (undo-tree-node-branch (undo-tree-current buffer-undo-tree))))
    (setf (undo-tree-node-branch (undo-tree-current buffer-undo-tree))
          (if (>= (1+ branch) (undo-tree-num-branches))
          (progn
            (setq undo-tree-walk 'undo)
            (1- (undo-tree-num-branches)))
        (setq undo-tree-walk 'redo)
        (1+ branch))))
      ;; no state change for (= num-branches 1)
      )
     ))
  (case undo-tree-walk
   (undo
    (undo-tree-undo-1))
   (redo
    (undo-tree-redo-1))
   (t
    (setq undo-tree-walk 'undo)
    (undo-tree-undo-1)))
  (let ((curbuf (current-buffer)))
    (undo-tree-visualize)
    (switch-to-buffer-other-window curbuf)))

(defun undo-tree-walk-off ()
  "Switch `undo-tree-walk' off."
  (setq undo-tree-walk nil))

(defvar undo-tree-walk-map
  (make-sparse-keymap)
  "Keymap active while `undo-tree-walk'.")

(define-key undo-tree-walk-map (kbd "C-M-_") #'undo-tree-walk)

(global-set-key (kbd "C-M-_") #'undo-tree-walk)

Beachten Sie, dass ich undo-tree-visualizeam Ende von hinzugefügt habe undo-tree-walk, um die Konsequenzen des Gehens mit dem Rückgängig-Baum anzuzeigen undo-tree-walk. Fühlen Sie sich frei, den Code nach Ihren Wünschen zu ändern.

Beachten Sie auch, dass ich aus zeitlichen Gründen diese einfachste Annäherung an eine Lösung für Ihr Problem wählen musste.

Tobias
quelle
Ich habe zu Beginn Folgendes hinzugefügt undo-tree-walk, um einige anfängliche Fehler zu überwinden, möglicherweise weil ich diesen Modus nicht global aktiv habe. (when (eq buffer-undo-list t) (user-error "No undo information.")) (undo-list-transfer-to-tree) Dadurch wurden meine anfänglichen Fehler in einem neuen Puffer zum Schweigen gebracht, während diese Antwort ausprobiert wurde. Meine nächste Beobachtung war, dass sie undo-tree-walkden Verzweigungspunkt erreicht und dann zum Zweig rechts wechselt, aber nur eine Kerbe / Knoten den Zweig hinuntergeht, bevor sie den Zweig wieder zum Stamm hinaufgeht. Mein bevorzugtes Setup erstellt für jeden Tastendruck eine Kerbe / einen Knoten.
Lawlist
Es gibt absolut keine Eile bei einer Lösung. Bitte nehmen Sie sich die Zeit, die Sie benötigen - über den Kopfgeldzeitraum hinaus ist dies vollkommen akzeptabel. Nach der Implementierung bin ich sicher, dass ich diese Funktion auf absehbare Zeit täglich nutzen werde. Nach den bisherigen Upvotes zu urteilen, möchten auch andere Personen diese Funktion nutzen.
Lawlist
@lawlist Schade, meine Zeit ist begrenzt. Wenn es möglich wäre, hätte ich diese Antwort eher als Kommentar als als Antwort geschrieben. Hoffentlich hat sich jemand anderes etwas Besseres ausgedacht, bevor die Kopfgeldperiode endet.
Tobias
@lawlist Ich habe hinzugefügt, undo-list-transfer-to-treewie Sie vorgeschlagen haben. Vorher teste ich, ob undo-tree-modesonst aktiv sein undo-list-transfer-to-treekann tödlich sein.
Tobias
Ausgezeichnet mit Kopfgeldern für Antworten in verwandten Themen : emacs.stackexchange.com/a/32415/2287 und emacs.stackexchange.com/a/32416/2287, da sie die Hauptzutaten für die Implementierung der neuen Funktion sind. Kurz gesagt, jeder Knoten verfügt über eine Liste von Zeitstempeln - einen für jedes Mal, wenn ein Knoten nach einem erfolgreichen Rückgängigmachen / Wiederherstellen und auch beim ersten Importieren aktuell wird. Ich hatte eine Idee zur Visualisierung, indem ich Zeitstempel vertikal unter jedem Knoten anzeigte und die Zweige entsprechend verlängerte - es wird einige Zeit dauern, bis ich sie programmgesteuert herausgefunden habe.
Lawlist
3

Besonderer Dank geht an @Tobias für das Schreiben einer Funktion zum Auffinden des nächsten / vorherigen Zeitstempels im Rückgängig / Wiederherstellen-Verlauf: /emacs//a/32415/2287 ; und zum Schreiben einer Reihe von Funktionen zum Kopieren des Rückgängig-Baums: /emacs//a/32230/2287 .

Wie einige Leser vielleicht bereits wissen, werden Gabeln von MELPA nur unter extremen Umständen akzeptiert. Das Erstellen eines Add-Ons ist wahrscheinlich machbar, erscheint jedoch angesichts der Anzahl der von @lawlist vorgenommenen Änderungen nicht praktikabel - einschließlich, aber nicht beschränkt auf das Hinzufügen von Elementen zu den zugrunde liegenden Datenstrukturvektoren und das Ändern der Namen mehrerer Funktionen / Variablen, die nicht der undo-tree-...Präfix-Namenskonvention usw. entsprachen. @lawlist hat sich bereits an den ursprünglichen Autor (Dr. Cubitt) gewandt, um diese neue Funktion sowie verschiedene Fehlerkorrekturen und Verbesserungen anzubieten.

Wenn jemand interessiert ist, können Sie dieser neuen Funktion gerne einen Strudel geben. Der Kommentar enthält ein Beispielformular für die Übermittlung von Fehlerberichten ab emacs -qdem Fall, dass jemand Probleme hat.

Quellcode:   https://github.com/lawlist/undo_tree

Kommentar:

;;; This unofficial modification by @lawlist to the `undo-tree.el` library authored
;;; by Toby Cubitt adds semi-linear undo/redo support and a corresponding visualizer
;;; view accessible with `C-u C-x u` or by using the 3-way toggle with the letter `t`
;;; in the visualization buffer.  This entire library is meant to be a replacement
;;; of the stock version of `undo-tree.el`, which would need to be completely removed
;;; from the `load-path'.  In the visualization buffer, the letters `u` / `r`
;;; or `z` / `Z` are used for semi-linear undo/redo.  In the working buffer,
;;; `super-u` / `super-r` or `super-z`/`super-Z` are used for semi-linear undo/redo.
;;; Semi-linear undo/redo also work in the classic views of the visualization buffer.
;;; All previous keyboard shortcuts remain unchanged.  The mouse can be used to
;;; select semi-linear nodes or branch-point timestamps in the visualization buffer.
;;;
;;; The term `semi-linear` was chosen because the time-line is generally structured
;;; as follows:  When undoing, the movement is in an upward direction from the
;;; leaf to the branch-point and then the previous branch begins undoing from the
;;; leaf.  When redoing, the movement is in a downward direction from the branch-
;;; point to the leaf and then the next branch begins redoing from the branch-point.
;;; It is not a situation where we walk-up and back-down the same branch, or walk-
;;; down and back-up the same branch again.  If that missing feature is useful,
;;; then perhaps it could be implemented someday....
;;;
;;; In a nutshell, the classic version of undo-tree undo/redo limits a user to
;;; the active branch (skipping over inactive branches), unless the user calls
;;; `undo-tree-switch-branch' or `undo-tree-visualize-switch-branch-right' or
;;; `undo-tree-visualize-switch-branch-left' to select an alternative branch.  This
;;; generally means a user must pop-open the visualizer buffer to see what is going
;;; on to make a proper decision.  The new semi-linear feature is essentially
;;; "mindless" where the user can just hold down the forward/reverse button and
;;; go through every node of the tree in chronological order -- i.e., all branches
;;; and nodes are visited in the process (nothing is skipped over).
;;;
;;; The labels in the visualization buffer remain the same:  `o`, `x`, `s`, register.
;;; The branches are labeled consecutively as they are drawn with lowercase letters.
;;; The branch-points are labeled consecutively as they are drawn with uppercase
;;; letters.  The branches coming off of each branch-point are labeled with the nth
;;; numeric position of the branch -- e.g., far left is always nth 0.  The nodes of
;;; each branch are numbered consecutively commencing just after the branch-point.
;;;
;;; The features that are available in `undo-tree.el` version 0.6.6 remain the same;
;;; however, some of the functions have been consolidated and the names have changed.
;;;
;;; `undo-tree-history-save' and `undo-tree-history-restore' support input/output
;;; to/from a string or a file.  The history string/file contains three components:
;;; `buffer-file-name' (if it exists; else `nil`); SHA1 string; the `undo-tree-list'.
;;; Histories created with the unmodified stock version of `undo-tree.el` contained 2
;;; components and those previous versions are no longer supported.  Saving/exporting
;;; excludes all text-properties, yasnippet entries, and multiple-cursors entries.
;;; `read' chokes when encountering #<marker in no buffer> or #<overlay in no buffer>,
;;; that can make their way into the `undo-tree-list' when killing the visualizer
;;; buffer by brute force or when using the yasnippet library.  Those two known
;;; situations have been dealt with programmatically.  However, there are surely
;;; other libraries that use markers and/or overlays that could make their way into
;;; the tree and new ways of dealing with those entries will be required.  If you
;;; encounter an error message when performing `undo-tree-history-save', please
;;; inspect the `*Messages*` buffer for clues such as the above examples.  Inasmuch
;;; as there is now a sanity check at the tail end of `undo-tree-history-save', any
;;; problems should materialize before a user actually tries to restore the history.
;;;
;;; The persistent undo storage has been expanded by adding certain features borrowed
;;; from the built-in `image-dired.el' library:
;;;
;;; `undo-tree-history-autosave':  When non-nil, `undo-tree-mode' will save undo
;;;                                history to a file when a buffer is saved; and,
;;;                                the save/restore functions attached to the
;;;                                following hooks will become active:
;;;                                -  `write-file-functions'
;;;                                -  `find-file-hook'
;;;                                To exclude certain files, users may wish to let-
;;;                                bind this variable to `nil` if it has a global
;;;                                non-nil value.  See also the next variable below.
;;;
;;; `undo-tree-history-file-exclusions':  A list of absolute file names that will be
;;;                                       excluded from the auto save/restore process.
;;;
;;; `undo-tree-history-alist':  Used when `undo-tree-history-storage' is 'classic.
;;;                             See the doc-string for customization tips/tricks.
;;;
;;; `undo-tree-history-directory':  Directory where history files are stored when
;;;                                `undo-tree-history-storage' is 'central.
;;;
;;; `undo-tree-history-storage':  How to store undo-tree history files.
;;;                               'classic:  See `undo-tree-history-alist'.
;;;                               'home (md5):  A folder in the HOME directory.
;;;                               'central (md5):  See `undo-tree-history-directory'.
;;;                               'local:  Create sub-directory in working directory.
;;;
;;; For those users who wish to use Emacs to view the saved/exported history, be
;;; aware that the undo history is one long string, and Emacs has trouble viewing a
;;; buffer with very long lines.  `(setq-default bidi-display-reordering nil)` will
;;; help permit Emacs to view buffers with very long lines without bogging down.
;;;
;;; The primary interactive functions for undo/redo in the working buffer are:
;;;
;;;   M-x undo-tree-classic-undo
;;;   M-x undo-tree-classic-redo
;;;   M-x undo-tree-linear-undo
;;;   M-x undo-tree-linear-redo
;;;
;;; The primary interactive functions for undo/redo in the visualization buffer are:
;;;
;;;   M-x undo-tree-visualize-classic-undo
;;;   M-x undo-tree-visualize-classic-redo
;;;   M-x undo-tree-visualize-linear-undo
;;;   M-x undo-tree-visualize-linear-redo
;;;
;;; If the built-in undo amalgamation business is not to your liking, it can be
;;; disabled to permit undo boundaries after every command:
;;;
;;;   ;;; /programming//a/41560712/2112489
;;;   (advice-add 'undo-auto--last-boundary-amalgamating-number :override #'ignore)
;;;
;;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27214
;;; /emacs//q/33248/2287
;;; GARBAGE COLLECTION:  @lawlist has encountered a few situations where garbage
;;; collection truncates the `undo-tree-canary' in the `buffer-undo-list', which
;;; causes `undo-tree-transfer-list' to replace the existing `undo-tree-list'
;;; with the new tree fragment obtained from the `buffer-undo-list'.  In this
;;; circumstance, the user loses the entire undo-tree saved history!  The internal
;;; function responsible is `truncate_undo_list' in `undo.c`.  @lawlist has added a
;;; programmatic warning when loss of the existing `undo-tree-list' is about to
;;; occur; however, that does not fix the problem.  The relevant section from
;;; `truncate_undo_list' in `undo.c` is as follows:
;;;          /* When we get to a boundary, decide whether to truncate
;;;      either before or after it.  The lower threshold, undo_limit,
;;;      tells us to truncate after it.  If its size pushes past
;;;      the higher threshold undo_strong_limit, we truncate before it.  */
;;;          if (NILP (elt))
;;;     {
;;;       if (size_so_far > undo_strong_limit)
;;;         break;
;;;       last_boundary = prev;
;;;       if (size_so_far > undo_limit)
;;;         break;
;;;     }
;;; @lawlist opines that setting the `undo-limit' to the same value as
;;; `undo-strong-limit' will cause `truncate_undo_list' to preserve the
;;; `undo-tree-canary' in the `buffer-undo-list' by truncating before the boundary.
;;; This workaround is not ideal because a more recent undo would be truncated in
;;; lieu of an older undo.  One idea would be to convince the Emacs team to modify
;;; `truncate_undo_list' to preserve certain user-defined elements; e.g., a symbol
;;; of `undo-tree-canary'.
;;;
;;; The built-in function named `primitive-undo' defined in `simple.el` was used
;;; in the original version of `undo-tree.el`.  @lawlist created a modified
;;; function named `undo-tree--primitive-undo' that serves the same purpose, but
;;; permits setting a window-point in the working buffer while a user is in a
;;; different window such as the visualization buffer.  The revised version also
;;; merely reports a problem with a message instead of throwing an error when it
;;; encounters an `undo-tree-canary' in the wrong location.  This bug was noticed
;;; by @lawlist when performing undo/redo in region, and a Google search revealed
;;; that others too have experienced the same problem.  The bug is fairly easy to
;;; reproduce, but @lawlist has not yet invested the time to look for the cause
;;; and try to come up with a solution.  For anyone who wishes to work on fixing
;;; this and view other mentions of the same problem on the internet, Google:
;;;   "Unrecognized entry in undo list undo-tree-canary"
;;;
;;; The semi-linear visualization buffer view looks like this:
;;;
;;;        o-00001-a-0
;;;        20.34.55.46
;;;             |
;;;        o-br/pt-A-0
;;;        20.47.57.25
;;;        20.34.55.47
;;;         ____|_______________________________
;;;        /                                    \
;;;  o-00001-b-0                            o-00001-c-1
;;;  20.47.57.26                            20.34.55.48
;;;       |                                      |
;;;  o-00002-b-0                            o-00002-c-1
;;;  20.47.57.27                            20.34.55.49
;;;       |                                      |
;;;  o-00003-b-0                            o-00003-c-1
;;;  20.47.57.28                            20.34.55.50
;;;                                              |
;;;                                         o-00004-c-1
;;;                                         20.34.55.51
;;;                                              |
;;;                                         o-br/pt-B-1
;;;                                         21.25.32.05
;;;                                         20.35.06.89
;;;                                         20.35.02.23
;;;                                         20.34.58.43
;;;                                         20.34.55.57
;;;         _____________________________________|________________________
;;;        /            /                        |                        \
;;;  o-00001-d-0  o-00001-e-1               o-br/pt-C-2               o-00001-f-3
;;;  21.25.32.06  20.35.06.90               23.03.45.34               20.34.58.44
;;;                    |                    00.27.40.07                    |
;;;               o-00002-e-1               20.35.02.24               o-00002-f-3
;;;               20.35.06.91         ___________|___________         20.34.58.45
;;;                    |             /           |           \             |
;;;               o-00003-e-1  o-00001-g-0  o-00001-h-1  o-00001-i-2  o-00003-f-3
;;;               20.35.06.92  23.03.45.35  00.27.40.08  20.35.02.25  20.34.58.46
;;;                    |            |            |            |            |
;;;               o-00004-e-1  x-00002-g-0  o-00002-h-1  o-00002-i-2  o-00004-f-3
;;;               20.35.06.93  23:03:45:36  00.27.44.51  20.35.02.26  20.34.58.47
;;;                    |                                      |            |
;;;               o-00005-e-1                            o-00003-i-2  o-00005-f-3
;;;               20.35.06.94                            20.35.02.27  20.34.58.48
;;;                    |                                      |            |
;;;               o-00006-e-1                            o-00004-i-2  o-00006-f-3
;;;               20.35.06.95                            20.35.02.28  20.34.58.49
;;;                    |                                      |            |
;;;               o-00007-e-1                            o-00005-i-2  o-00007-f-3
;;;               20.35.06.96                            20.35.02.29  20.34.58.50
;;;                    |                                      |            |
;;;               o-00008-e-1                            o-00006-i-2  o-00008-f-3
;;;               20.35.06.97                            20.35.02.30  20.34.58.51
;;;
;;; To check for updates, please visit the source-code of the link listed at the
;;; top and also review the "Change Log" at the bottom.
;;;
;;; Bug reports and feature requests may be submitted via email to the address at
;;; the top.  Essentially, if it breaks in half, I can guarantee that you will
;;; have 2 pieces that may not necessarily be the same size.  :)  That being said,
;;; I will certainly make efforts to fix any problem that may arise relating to
;;; the semi-linear undo/redo feature.  A step 1-2-3 recipe starting from emacs -q
;;; would be very helpful so that @lawlist can observe the same behavior described
;;; in the bug report.  Here is an example to get you started:
;;;
;;; 1.  In an internet browser, visit: https://www.lawlist.com/lisp/undo-tree.el
;;;
;;;     Select/highlight all and copy everything to the clipboard.
;;;
;;; 2.  Launch Emacs without any user settings whatsoever:  emacs -q
;;;
;;;     If possible, please use the latest stable public release of Emacs.
;;;     @lawlist is using the GUI version of Emacs 25.2.1 on OSX.
;;;
;;; 3.  Switch to the `*scratch*` buffer.
;;;
;;; 4.  Paste the entire contents of the clpipboard into the `*scratch*` buffer.
;;;
;;; 5.  M-x eval-buffer RET
;;;
;;; 6.  M-x eval-expression RET (setq undo-tree-history-autosave t) RET
;;;
;;; 7.  M-x undo-tree-mode RET
;;;
;;;     The mode-line indicates `UT`, meaning that `undo-tree-mode' is active.
;;;
;;; 8.  M-x save-buffer RET
;;;
;;;     @lawlist chose to save the file to his desktop with the name `foo`, and
;;;     also chose to overwrite the file if it already existed; i.e., `y`.
;;;
;;;     Look at the lower left-hand side of the mode-line and notice that it
;;;     indicates an unmodified state; i.e., U:--- foo ....
;;;
;;; 9.  M-x undo-tree-classic-undo RET
;;;
;;;     Look at the lower left-hand side of the mode-line and notice that it
;;;     indicates we have returned to a modified state; i.e., U:**- foo ....
;;;
;;; 10. M-x undo-tree-classic-undo RET
;;;
;;;     The `undo-tree' library that we had previously pasted to the `*scratch*`
;;;     buffer should now be completely undone; i.e., removed.
;;;
;;; 11. M-x undo-tree-classic-undo RET
;;;
;;;     The buffer should be completely empty at this point; i.e., the initial
;;;     `*scratch*` message has been removed.
;;;
;;; 12. M-x undo-tree-classic-undo RET
;;;
;;;     The following `user-error' appears:
;;;
;;;       "user-error:  undo-tree--undo-or-redo:  No further undo information."
;;;
;;;     This is exactly the behavior that @lawlist expected would happen, so
;;;     everything up to this point appears to be working correctly.
Gesetzesliste
quelle