emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/macrostep 9cd6742 016/110: Try to be smarter about maintai


From: ELPA Syncer
Subject: [nongnu] elpa/macrostep 9cd6742 016/110: Try to be smarter about maintaining buffer state
Date: Sat, 7 Aug 2021 09:17:54 -0400 (EDT)

branch: elpa/macrostep
commit 9cd674287e39447dbd4bb186a087dab7e38828fe
Author: joddie <jonxfield@gmail.com>
Commit: joddie <jonxfield@gmail.com>

    Try to be smarter about maintaining buffer state
    
    - save and restore buffer-read-only
    
    - exit macrostep-mode correctly if the buffer is made writable again
    
    - save and restore buffer-undo-list, and disable undo recording while
      macrostep is active
    
    - use `with-silent-modifications' to not mark buffer as modified.
      Caveats: This is nicer for the user when inspecting an unmodified
      buffer, but could be dangerous if we somehow manage leave the buffer
      in an inconsistent state without warning. Is there a better way?
---
 macrostep.el | 84 +++++++++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 57 insertions(+), 27 deletions(-)

diff --git a/macrostep.el b/macrostep.el
index 6cae0ec..38f0bc1 100644
--- a/macrostep.el
+++ b/macrostep.el
@@ -190,6 +190,13 @@
   "t if gensyms have been encountered during current level of macro 
expansion.")
 (make-variable-buffer-local 'macrostep-gensyms-this-level)
 
+(defvar macrostep-saved-undo-list nil
+  "Saved value of buffer-undo-list upon entering macrostep mode.")
+(make-variable-buffer-local 'macrostep-saved-undo-list)
+
+(defvar macrostep-saved-read-only nil
+  "Saved value of buffer-read-only upon entering macrostep mode.")
+(make-variable-buffer-local 'macrostep-saved-read-only)
 
 ;;; Faces
 (defgroup macrostep nil
@@ -293,14 +300,34 @@ quit and return to normal editing.
   nil " Macro-Stepper"
   :keymap macrostep-keymap
   :group macrostep
-  (setq buffer-read-only macrostep-mode)
   (if macrostep-mode
-      (message
-       (substitute-command-keys
-        "\\<macrostep-keymap>Entering macro stepper mode. Use 
\\[macrostep-expand] to expand, \\[macrostep-collapse] to collapse, 
\\[macrostep-collapse-all] to exit."))
+      (progn
+        ;; Disable recording of undo information
+        (setq macrostep-saved-undo-list buffer-undo-list
+              buffer-undo-list t)
+        ;; Remember whether buffer was read-only
+        (setq macrostep-saved-read-only buffer-read-only
+              buffer-read-only t)
+        ;; Set up post-command hook to bail out on leaving read-only
+        (add-hook 'post-command-hook 'macrostep-command-hook nil t)
+        (message
+         (substitute-command-keys
+          "\\<macrostep-keymap>Entering macro stepper mode. Use 
\\[macrostep-expand] to expand, \\[macrostep-collapse] to collapse, 
\\[macrostep-collapse-all] to exit.")))
 
     ;; Exiting mode: collapse any remaining overlays
-    (when macrostep-overlays (macrostep-collapse-all))))
+    (when macrostep-overlays (macrostep-collapse-all))
+    :; Restore undo info & read-only state
+    (setq buffer-undo-list macrostep-saved-undo-list
+          buffer-read-only macrostep-saved-read-only
+          macrostep-saved-undo-list nil)
+    ;; Remove our post-command hook
+    (remove-hook 'post-command-hook 'macrostep-command-hook t)))
+
+;; Post-command hook: bail out of macrostep-mode if the user types C-x
+;; C-q to make the buffer writable again.
+(defun macrostep-command-hook ()
+  (if (not buffer-read-only)
+      (macrostep-mode 0)))
 
 
 ;;; Interactive functions
@@ -342,21 +369,22 @@ buffer and expand the next macro form found, if any."
              priority 1
              macrostep-gensym-depth -1))
 
-      (atomic-change-group
-       (macrostep-replace-sexp-at-point expansion)
-       (let ((new-ol
-              (make-overlay (point)
-                            (scan-sexps (point) 1))))
-          ;; move overlay over newline to make it prettier
-          (when (equal (char-after (overlay-end new-ol)) ?\n)
-            (move-overlay new-ol
-                          (overlay-start new-ol) (+ (overlay-end new-ol) 1)))
-          (overlay-put new-ol 'face 'macrostep-expansion-highlight-face)
-         (overlay-put new-ol 'evaporate t)
-         (overlay-put new-ol 'priority priority)
-         (overlay-put new-ol 'macrostep-original-text text)
-         (overlay-put new-ol 'macrostep-gensym-depth macrostep-gensym-depth)
-         (push new-ol macrostep-overlays))))))
+      (with-silent-modifications
+        (atomic-change-group
+          (macrostep-replace-sexp-at-point expansion)
+          (let ((new-ol
+                 (make-overlay (point)
+                               (scan-sexps (point) 1))))
+            ;; move overlay over newline to make it prettier
+            (when (equal (char-after (overlay-end new-ol)) ?\n)
+              (move-overlay new-ol
+                            (overlay-start new-ol) (+ (overlay-end new-ol) 1)))
+            (overlay-put new-ol 'face 'macrostep-expansion-highlight-face)
+            (overlay-put new-ol 'evaporate t)
+            (overlay-put new-ol 'priority priority)
+            (overlay-put new-ol 'macrostep-original-text text)
+            (overlay-put new-ol 'macrostep-gensym-depth macrostep-gensym-depth)
+            (push new-ol macrostep-overlays)))))))
 
 (defun macrostep-collapse ()
   "Collapse the innermost macro expansion near point to its source text.
@@ -367,8 +395,9 @@ If no more macro expansions are visible after this, exit
   (let ((overlay (macrostep-overlay-at-point)))
     (when (not overlay) (error "No macro expansion at point"))
     (let ((buffer-read-only nil))
-      (atomic-change-group
-       (macrostep-collapse-overlay overlay))))
+      (with-silent-modifications
+        (atomic-change-group
+          (macrostep-collapse-overlay overlay)))))
   (if (not macrostep-overlays)
       (macrostep-mode 0)))
 
@@ -376,11 +405,12 @@ If no more macro expansions are visible after this, exit
   "Collapse all visible macro expansions and exit `macrostep-mode'."
   (interactive)
   (let ((buffer-read-only nil))
-    (dolist (overlay macrostep-overlays)
-      (let ((outermost (= (overlay-get overlay 'priority) 1)))
-        ;; We only need restore the original text for the outermost
-        ;; overlays
-        (macrostep-collapse-overlay overlay (not outermost)))))
+    (with-silent-modifications
+      (dolist (overlay macrostep-overlays)
+        (let ((outermost (= (overlay-get overlay 'priority) 1)))
+          ;; We only need restore the original text for the outermost
+          ;; overlays
+          (macrostep-collapse-overlay overlay (not outermost))))))
   (setq macrostep-overlays nil)
   (macrostep-mode 0))
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]