วิธีการสร้างการเลิกทำแบบเส้นต้นไม้ - undo-tree-undo / redo


10

เมื่อรันคำสั่งundo-tree-undo/redoอย่างต่อเนื่องสิ่งต่าง ๆ จะถูกเลิกทำ / ทำซ้ำตามสาขาที่ใช้งานอยู่ในปัจจุบัน แม้ว่าผู้ใช้จะได้รับข้อความจุดสาขาตลอดทางสาขาก่อนหน้านี้จะถูกละเว้นเว้นแต่ผู้ใช้เลือกสาขาอื่นด้วยตนเอง

ฉันเข้าใจว่าฉันสามารถเปิดวิชวลไลเซอร์และเลือกสาขาอื่นได้ แต่มันจะมีประโยชน์มากในการกดปุ่มเลิกทำ / ทำซ้ำและดูทุกอย่างที่เกิดขึ้นตามลำดับตรงกันข้าม โดยหลักการแล้วสิ่งนี้ควรจะทำงานโดยไม่คำนึงว่าvisualizerบัฟเฟอร์นั้นเปิดอยู่หรือไม่นั่นคือการคำนวณคำสั่งจากโปรแกรมจนจบโดยทางโปรแกรมและตั้งแต่ต้นจนจบ

ถาม : นี่คือการร้องขอคุณสมบัติเพื่อขยายundo-treeเพื่ออนุญาตให้ยกเลิก / ทำซ้ำแบบเชิงเส้นต่อเนื่องโดยไม่คำนึงว่าบัฟเฟอร์ Visualizer เปิดอยู่หรือไม่ [ฟังก์ชั่นใหม่และแป้นพิมพ์ลัดสำหรับคุณสมบัติใหม่นี้เป็นที่ยอมรับอย่างแน่นอน]


รหัสของundo-treeดูเหมือนว่ามันเป็นส่วนหนึ่งของแนวคิดที่ว่าคุณสามารถเปลี่ยนได้อย่างอิสระระหว่างbuffer-undo-treeและด้วยการสลับbuffer-undo-list undo-tree-modeเมื่อฉันเข้าใจคำถามของคุณการจัดการแบบเดิมbuffer-undo-listจะทำในสิ่งที่คุณต้องการ ดังนั้นจึงแนะนำตัวเองให้ปิดเครื่องชั่วคราวundo-tree-modeเพื่อวัตถุประสงค์ของคุณ น่าเสียดายที่การสลับไปมาระหว่างbuffer-undo-treeและbuffer-undo-listดูเหมือนว่าจะเป็นรถ (อย่างน้อยสำหรับฉัน) undo-treeดังนั้นบางทีวิธีที่จะไปจะเป็นเพียงข้อผิดพลาดที่รายงานไปยังผู้ดูแลของ แต่บางทีฉันเดาเกี่ยวกับแนวคิดดั้งเดิมที่ผิด
โทเบียส

ฉันคิดว่าทางออกที่ดีที่สุดสำหรับปัญหาของคุณคือการซ่อมแซมundo-tree-modeเช่นนั้นระหว่างการสลับbuffer-undo-treeและbuffer-undo-listทำงานได้อย่างไร้ที่ติ คุณได้พิจารณาที่จะออกรายงานข้อผิดพลาดที่ `toby-undo-tree @ dr-qubit.org` หรือไม่?
โทเบียส

@Tobias - ฉันต้องการดูและใช้ visualizer undo-treeในขณะที่ใช้linearคุณสมบัติใหม่ และฉันต้องการlinearคุณสมบัติใหม่ในการทำงานโดยไม่ต้องบัฟเฟอร์ visualizer จำเป็นต้องมองเห็นได้ โดยทั่วไปฉันใช้การปรับปรุง / แก้ไขของฉันเองกับ Emacs ทั้งในตัวและในตัวเลือกของห้องสมุดบุคคลที่สาม เมื่อฉันติดขัดหรือเห็นอะไรบางอย่างที่ซับซ้อนเหมือนundoคุณสมบัติฉันขอความช่วยเหลือ คำขอคุณลักษณะสำหรับผู้ดูแลไม่สามารถทำร้ายได้ แต่ฉันต้องการจัดการที่นี่
กฎหมาย

@Tobias - ในการดูundo-tree.elรหัสวันนี้ฉันเห็นว่ามีคุณลักษณะการประทับเวลาของโหนด ฉันไม่แน่ใจว่าแต่ละโหนดมีการประทับเวลาที่ถูกต้องหรือไม่และโหนดเหล่านั้นจะอยู่รอดในเซสชั่น Emacs ถัดไป (เมื่อเรียกคืนประวัติ) แต่ฟังดูเหมือนว่าอาจเป็นทางลัดในการแก้ไขคำขอคุณลักษณะใหม่นี้ ก่อนหน้าหรือถัดไปในเวลา ฉันยังไม่เห็นว่าการวางผังของที่ดินจะมีลักษณะเป็นอย่างไร ณ จุดสาขา แต่ ... นั่นคือความคิดเบื้องต้นของฉัน . . .
ลิสต์กฎหมาย

undo-list-rebuild-from-treeผมคิดว่ากุญแจสำคัญในการเดินเท้าเส้นตรงผ่านยกเลิกต้นไม้เป็น หนึ่งควรletผูกตัวแปรbuffer-undo-listและปล่อยให้undo-list-rebuild-from-treeมันทำงาน หลังจากนั้นคัดลอกค่าที่เป็นตัวแปรท้องถิ่นอื่นพูดmy-undo-listและออกจากlet-form buffer-undo-listผูกพัน ตัวแปรคำสั่งเส้นทางเชิงเส้นผ่านmy-undo-list undo-treeลองดูที่undo-list-rebuild-from-treeคุณเห็นว่าฟังก์ชั่นนี้ใช้การประทับเวลาด้วย ก่อนหน้านี้ฉันถือว่าใช้การประทับเวลา แต่ฉันรู้สึกว่าการเปลี่ยนแปลงเหล่านั้นบ่อยเกินไป
โทเบียส

คำตอบ:


7

ต่อไปนี้คือการนำต้นแบบไปใช้โดยประมาณของสิ่งที่คุณต้องการ มันใช้ประโยชน์จากความจริงที่ว่าสาขาใหม่ใน undo-tree ถูกเพิ่มที่ด้านซ้ายมือของโหนดปัจจุบัน

ลำดับคีย์C-M-_ถูกผูกไว้กับundo-tree-walkที่เดินส่วนบนขวาของต้นไม้เลิกทำเริ่มต้นที่โหนดปัจจุบัน

พฤติกรรมแตกต่างจากสิ่งที่คุณต้องการหากสาขาย่อยที่ใช้งานอยู่ของทรีย่อยทางด้านขวามือของโหนดปัจจุบันไม่ใช่สาขาซ้ายสุดในทรีย่อยนั้น

คุณสามารถเข้าสู่สถานะดังกล่าวได้โดยการลบลำดับการยกเลิก / การทำซ้ำซ้ำ

ลองใช้ด้วยตัวคุณเองเพื่อดูว่าใบสมัครของคุณเพียงพอหรือไม่

(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)

หมายเหตุที่ผมเพิ่มundo-tree-visualizeไปยังจุดสิ้นสุดของการแสดงผลของการเดินยกเลิกต้นไม้ด้วยundo-tree-walk undo-tree-walkอย่าลังเลที่จะแก้ไขโค้ดตามที่คุณต้องการ

โปรดทราบว่าฉันต้องเลือกวิธีแก้ปัญหาที่ง่ายที่สุดสำหรับปัญหาของคุณเนื่องจากข้อ จำกัด ด้านเวลา


ฉันได้เพิ่มสิ่งต่อไปนี้เพื่อเริ่มundo-tree-walkรับข้อผิดพลาดเบื้องต้นบางครั้งอาจเป็นเพราะฉันไม่มีโหมดนี้ใช้งานทั่วโลก (when (eq buffer-undo-list t) (user-error "No undo information.")) (undo-list-transfer-to-tree) นั่นทำให้ข้อผิดพลาดเริ่มแรกของฉันในบัฟเฟอร์ใหม่ในขณะที่ลองตอบคำถามนี้ การสังเกตครั้งต่อไปของฉันคือundo-tree-walkถึงจุดสาขาแล้วสลับไปที่สาขาด้านขวา แต่ลงไปที่สาขาหนึ่งรอย / ปมก่อนที่จะกลับสาขาเพื่อลำต้น การตั้งค่าที่ฉันต้องการสร้างรอย / ปมสำหรับทุกจังหวะที่สำคัญ
ฏหมาย

มีวิธีแก้ปัญหาไม่รีบร้อน โปรดอย่าลังเลที่จะใช้เวลาตลอดเวลาที่คุณต้องการ เมื่อนำมาใช้ฉันมั่นใจว่าฉันจะใช้คุณลักษณะนี้เป็นประจำทุกวันเพื่ออนาคตที่คาดการณ์ไว้และตัดสินโดย upvotes จนถึงขณะนี้คนอื่น ๆ ก็ต้องการใช้คุณลักษณะนี้เช่นกัน
ฏหมาย

@lawlist น่าเสียดายที่เวลาของฉันถูก จำกัด ถ้าเป็นไปได้ฉันจะเขียนคำตอบนี้แทนความคิดเห็นมากกว่าคำตอบ หวังว่าจะมีคนอื่นมาพร้อมกับสิ่งที่ดีกว่าก่อนที่ช่วงเวลาความโปรดปรานจะสิ้นสุดลง
โทเบียส

@lawlist ฉันเพิ่มundo-list-transfer-to-treeตามที่คุณเสนอ ก่อนหน้านี้ฉันทดสอบว่าundo-tree-modeมีการใช้งานอย่างอื่นundo-list-transfer-to-treeอาจถึงแก่ชีวิต
โทเบียส

มอบรางวัลล่าสุดสำหรับคำตอบในหัวข้อที่เกี่ยวข้อง: emacs.stackexchange.com/a/32415/2287และemacs.stackexchange.com/a/32416/2287เนื่องจากเป็นส่วนประกอบสำคัญในการใช้คุณลักษณะใหม่ สรุปแต่ละโหนดจะมีรายการของการประทับเวลา - หนึ่งสำหรับแต่ละครั้งที่โหนดกลายเป็นปัจจุบันหลังจากที่ประสบความสำเร็จในการเลิกทำ / ทำซ้ำและเมื่อเริ่มนำเข้า ฉันคิดไอเดียในการสร้างภาพด้วยการแสดงการประทับเวลาในแนวตั้งภายใต้แต่ละโหนดและขยายสาขาให้ยาวขึ้น - มันจะใช้เวลาสักครู่ในการคิดเชิงโปรแกรม
ฏหมาย

3

ขอขอบคุณเป็นพิเศษกับ @Tobias สำหรับการเขียนฟังก์ชันเพื่อค้นหาการประทับเวลาถัดไป / ก่อนหน้าในประวัติเลิกทำ / ทำซ้ำ: https://emacs.stackexchange.com/a/32415/2287 ; และสำหรับยังเขียนถึงชุดของฟังก์ชั่นเพื่อคัดลอกยกเลิกต้นไม้: https://emacs.stackexchange.com/a/32230/2287

เนื่องจากผู้อ่านบางคนอาจทราบแล้วส้อมได้รับการยอมรับจาก MELPA ในสถานการณ์ที่รุนแรงเท่านั้น การสร้างแอดออนอาจเป็นไปได้ แต่ดูเหมือนจะไม่สามารถนำไปใช้ได้จริงเนื่องจากปริมาณของการเปลี่ยนแปลงที่ทำโดย @lawlist - ซึ่งรวมถึง แต่ไม่ จำกัด เพียงการเพิ่มองค์ประกอบให้กับเวกเตอร์โครงสร้างข้อมูลพื้นฐานและการเปลี่ยนชื่อของหลาย ๆ ฟังก์ชั่น / ตัวแปรที่ไม่สอดคล้องกับundo-tree-...แบบแผนการตั้งชื่อนำหน้า ฯลฯ @lawlist ได้นำเสนอให้กับผู้แต่งดั้งเดิมแล้ว (Dr. Cubitt) เพื่อเสนอคุณสมบัติใหม่นี้รวมถึงการแก้ไขข้อบกพร่องและการปรับปรุงต่างๆ

หากใครสนใจโปรดอย่าลังเลที่จะมอบฟีเจอร์ใหม่นี้ให้กับคุณ ข้อคิดเห็นประกอบด้วยแบบฟอร์มการส่งรายงานข้อผิดพลาดตัวอย่างเริ่มต้นจากemacs -qในกรณีที่ทุกคนมีปัญหา

รหัสที่มา:   https://github.com/lawlist/undo_tree

ความเห็น:

;;; 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:
;;;
;;;   ;;; https://stackoverflow.com/a/41560712/2112489
;;;   (advice-add 'undo-auto--last-boundary-amalgamating-number :override #'ignore)
;;;
;;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27214
;;; https://emacs.stackexchange.com/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.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.