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

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

[elpa] master 6102ff5 50/63: Handle undo of snippet 1st line indent prop


From: Noam Postavsky
Subject: [elpa] master 6102ff5 50/63: Handle undo of snippet 1st line indent properly
Date: Mon, 17 Jul 2017 22:54:19 -0400 (EDT)

branch: master
commit 6102ff5049c26f1d99370364fe869f2d92ff66d2
Author: Noam Postavsky <address@hidden>
Commit: Noam Postavsky <address@hidden>

    Handle undo of snippet 1st line indent properly
    
    * yasnippet.el (yas--first-indent-undo)
    (yas--return-first-indent-undo): New variables.
    (yas-expand-snippet): Use them to collect the exact undo info from
    indenting the first snippet line, rather than trying to reconstruct
    it.
    (yas--indent-region): Put undo info from indenting snippet's first
    line into `yas--first-indent-undo' if `yas--return-first-indent-undo'
    is non-nil.
---
 yasnippet.el | 69 +++++++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 43 insertions(+), 26 deletions(-)

diff --git a/yasnippet.el b/yasnippet.el
index 34bc5eb..3f8cca9 100644
--- a/yasnippet.el
+++ b/yasnippet.el
@@ -3713,7 +3713,14 @@ Move the overlays, or create them if they do not exit."
 ;; running. This would mean a lot of overlay modification hooks
 ;; running, but if managed correctly (including overlay priorities)
 ;; they should account for all situations...
-;;
+
+(defvar yas--first-indent-undo nil
+  "Internal variable for indent undo entries.
+Used to pass info from `yas--indent-region' to `yas-expand-snippet'.")
+(defvar yas--return-first-indent-undo nil
+  "Whether to record undo info in `yas--indent-region'.
+See also `yas--first-indent-undo'.")
+
 (defun yas-expand-snippet (content &optional start end expand-env)
   "Expand snippet CONTENT at current point.
 
@@ -3742,6 +3749,7 @@ considered when expanding the snippet."
          (to-delete (and start
                          end
                          (buffer-substring-no-properties start end)))
+         (yas--first-indent-undo nil)
          snippet)
     (goto-char start)
     (setq yas--indent-original-column (current-column))
@@ -3765,7 +3773,8 @@ considered when expanding the snippet."
            ;;    plain text will get recorded at the end.
            ;;
            ;;    stacked expansion: also shoosh the overlay modification hooks
-           (let ((buffer-undo-list t))
+           (let ((buffer-undo-list t)
+                 (yas--return-first-indent-undo t))
              ;; snippet creation might evaluate users elisp, which
              ;; might generate errors, so we have to be ready to catch
              ;; them mostly to make the undo information
@@ -3791,23 +3800,20 @@ considered when expanding the snippet."
            (unless (yas--snippet-fields snippet)
              (yas-exit-snippet snippet))
 
-           ;; Push two undo actions: the deletion of the inserted contents of
-           ;; the new snippet (without the "key") followed by an apply of
-           ;; `yas--take-care-of-redo' on the newly inserted snippet boundaries
-           ;;
-           ;; A small exception, if `yas-also-auto-indent-first-line'
-           ;; is t and `yas--indent' decides to indent the line to a
-           ;; point before the actual expansion point, undo would be
-           ;; messed up. We call the early point "newstart"".  case,
-           ;; and attempt to fix undo.
-           ;;
-           (let ((newstart (overlay-start (yas--snippet-control-overlay 
snippet)))
-                 (end (overlay-end (yas--snippet-control-overlay snippet))))
-             (when (< newstart start)
-               (push (cons (make-string (- start newstart) ? ) newstart) 
buffer-undo-list))
-             (push (cons newstart end) buffer-undo-list)
-             (push `(apply yas--take-care-of-redo ,start ,end ,snippet)
-                   buffer-undo-list))
+           ;; Undo actions from indent of snippet's 1st line.
+           (setq buffer-undo-list
+                 (nconc yas--first-indent-undo buffer-undo-list))
+           ;; Undo action for the expand snippet contents.
+           (push (cons (overlay-start (yas--snippet-control-overlay snippet))
+                       (overlay-end (yas--snippet-control-overlay snippet)))
+                 buffer-undo-list)
+           ;; Follow up with `yas--take-care-of-redo' on the newly
+           ;; inserted snippet boundaries.
+           (push `(apply yas--take-care-of-redo ,start
+                         ,(overlay-end (yas--snippet-control-overlay snippet))
+                         ,snippet)
+                 buffer-undo-list)
+
            ;; Now, schedule a move to the first field
            ;;
            (let ((first-field (car (yas--snippet-fields snippet))))
@@ -4189,12 +4195,17 @@ Buffer must be narrowed to BEG..END used to create the 
snapshot info."
 (defun yas--indent-region (from to snippet)
   "Indent the lines between FROM and TO with `indent-according-to-mode'.
 The SNIPPET's markers are preserved."
-  (let* ((snippet-markers (yas--collect-snippet-markers snippet))
-         (to (set-marker (make-marker) to)))
-    (save-excursion
-      (goto-char from)
-      (save-restriction
-        (widen)
+  (save-excursion
+    (save-restriction
+      (widen)
+      (let* ((snippet-markers (yas--collect-snippet-markers snippet))
+             (to (set-marker (make-marker) to))
+             (control-ov (yas--snippet-control-overlay snippet))
+             (1st-bol (progn (goto-char (if control-ov (overlay-start 
control-ov)
+                                          from))
+                             (beginning-of-line)
+                             (point))))
+        (goto-char from)
         (cl-loop for bol = (line-beginning-position)
                  for eol = (line-end-position)
                  if (/= bol eol) do
@@ -4206,7 +4217,13 @@ The SNIPPET's markers are preserved."
                              remarkers)))
                    (unwind-protect
                        (progn (back-to-indentation)
-                              (indent-according-to-mode))
+                              (if (and yas--return-first-indent-undo
+                                       (= 1st-bol bol))
+                                  (let ((buffer-undo-list nil))
+                                    (indent-according-to-mode)
+                                    (setq yas--first-indent-undo
+                                          (delq nil buffer-undo-list)))
+                                (indent-according-to-mode)))
                      (save-restriction
                        (narrow-to-region bol (line-end-position))
                        (mapc #'yas--restore-marker-location remarkers))))



reply via email to

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