[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] master 7ea1305 09/51: Fix undo when first line indentation moves
From: |
Noam Postavsky |
Subject: |
[elpa] master 7ea1305 09/51: Fix undo when first line indentation moves snippet forward |
Date: |
Sun, 13 May 2018 13:11:40 -0400 (EDT) |
branch: master
commit 7ea1305e6715e7324e5e5713ee9d37dd1a89d211
Author: Noam Postavsky <address@hidden>
Commit: Noam Postavsky <address@hidden>
Fix undo when first line indentation moves snippet forward
* yasnippet.el (yas--first-indent-undo, yas--get-indent-undo-pos):
Remove.
(yas-expand-snippet): Move undo-related code from here...
(yas--snippet-create): ... to here. Collect undo information from
yas--indent in the normal, unsuppressed way.
(yas--indent-region): Don't collect undo information specially.
(yas--take-care-of-redo): Remove unused parameters.
* yasnippet-tests.el (undo-indentation-1): Rename from
undo-indentation.
(undo-indentation-2): New test.
(undo-indentation-multiline-1): Rename from
undo-indentation-multiline.
(undo-indentation-multiline-2): New test.
---
yasnippet-tests.el | 43 +++++++++++++++++++++++++--
yasnippet.el | 85 +++++++++++++++++++-----------------------------------
2 files changed, 70 insertions(+), 58 deletions(-)
diff --git a/yasnippet-tests.el b/yasnippet-tests.el
index d067dc1..13fff53 100644
--- a/yasnippet-tests.el
+++ b/yasnippet-tests.el
@@ -297,7 +297,7 @@ attention to case differences."
;; (should (string= (yas--buffer-contents)
;; "brother from another mother!"))))
-(ert-deftest undo-indentation ()
+(ert-deftest undo-indentation-1 ()
"Check undoing works when only line of snippet is indented."
(let ((yas-also-auto-indent-first-line t))
(yas-with-snippet-dirs
@@ -315,8 +315,27 @@ attention to case differences."
(ert-simulate-command '(undo))
(should (string= (buffer-string) "(let\n(while s"))))))
-(ert-deftest undo-indentation-multiline ()
- "Check undoing works when first line of multi-line snippet is indented."
+(ert-deftest undo-indentation-2 ()
+ "Check undoing works when only line of snippet is indented."
+ (let ((yas-also-auto-indent-first-line t)
+ (indent-tabs-mode nil))
+ (yas-with-snippet-dirs
+ '((".emacs.d/snippets" ("emacs-lisp-mode" ("t" . "; TODO"))))
+ (with-temp-buffer
+ (emacs-lisp-mode)
+ (yas-reload-all)
+ (yas-minor-mode 1)
+ (insert "t")
+ (setq buffer-undo-list ())
+ (ert-simulate-command '(yas-expand))
+ ;; Need undo barrier, I think command loop puts it normally.
+ (push nil buffer-undo-list)
+ (should (string= (buffer-string) (concat (make-string comment-column
?\s) "; TODO")))
+ (ert-simulate-command '(undo))
+ (should (string= (buffer-string) "t"))))))
+
+(ert-deftest undo-indentation-multiline-1 ()
+ "Check undoing works when 1st line of multi-line snippet is indented."
(yas-with-snippet-dirs
'((".emacs.d/snippets" ("js-mode" ("if" . "if ($1) {\n\n}\n"))))
(with-temp-buffer
@@ -332,6 +351,24 @@ attention to case differences."
(ert-simulate-command '(undo))
(should (string= (buffer-string) "if\nabc = 123456789 + abcdef;")))))
+
+(ert-deftest undo-indentation-multiline-2 ()
+ "Check undoing works when 2nd line of multi-line snippet is indented."
+ (yas-with-snippet-dirs
+ '((".emacs.d/snippets" ("js-mode" ("if" . "if (true) {\n${1:foo};\n}\n"))))
+ (with-temp-buffer
+ (js-mode)
+ (yas-reload-all)
+ (yas-minor-mode 1)
+ (insert "if\nabc = 123456789 + abcdef;")
+ (setq buffer-undo-list ())
+ (goto-char (point-min))
+ (search-forward "if")
+ (ert-simulate-command '(yas-expand))
+ (push nil buffer-undo-list) ; See test above.
+ (ert-simulate-command '(undo))
+ (should (string= (buffer-string) "if\nabc = 123456789 + abcdef;")))))
+
(ert-deftest dont-clear-on-partial-deletion-issue-515 ()
"Ensure fields are not cleared when user doesn't really mean to."
(with-temp-buffer
diff --git a/yasnippet.el b/yasnippet.el
index f351de2..a8a3bbb 100644
--- a/yasnippet.el
+++ b/yasnippet.el
@@ -3740,14 +3740,6 @@ Move the overlays, or create them if they do not exit."
;; 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--get-indent-undo-pos nil
- "Record undo info for line beginning at given position.
-We bind this when first creating a snippet. See also
-`yas--first-indent-undo'.")
-
(defun yas-expand-snippet (content &optional start end expand-env)
"Expand snippet CONTENT at current point.
@@ -3784,7 +3776,6 @@ considered when expanding the snippet."
(yas-selected-text
(or yas-selected-text
(if (not clear-field) to-delete)))
- (yas--first-indent-undo nil)
snippet)
(goto-char start)
(setq yas--indent-original-column (current-column))
@@ -3798,25 +3789,11 @@ considered when expanding the snippet."
(yas--eval-for-effect content))
(t
;; x) This is a snippet-snippet :-)
- ;;
- ;; Narrow the region down to the content, shoosh the
- ;; `buffer-undo-list', and create the snippet, the new
- ;; snippet updates its mirrors once, so we are left with
- ;; some plain text. The undo action for deleting this
- ;; plain text will get recorded at the end.
- ;;
- ;; stacked expansion: also shoosh the overlay modification hooks
- (let ((buffer-undo-list t)
- (yas--get-indent-undo-pos (line-beginning-position)))
- ;; 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
- ;;
- (setq yas--start-column (current-column))
- (let ((yas--inhibit-overlay-hooks t))
- (insert content)
- (setq snippet
- (yas--snippet-create expand-env start (point)))))
+ (setq yas--start-column (current-column))
+ ;; Stacked expansion: also shoosh the overlay modification hooks.
+ (let ((yas--inhibit-overlay-hooks t))
+ (setq snippet
+ (yas--snippet-create content expand-env start (point))))
;; stacked-expansion: This checks for stacked expansion, save the
;; `yas--previous-active-field' and advance its boundary.
@@ -3833,20 +3810,6 @@ considered when expanding the snippet."
(unless (yas--snippet-fields snippet)
(yas-exit-snippet snippet))
- ;; 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))))
@@ -3863,7 +3826,7 @@ considered when expanding the snippet."
(yas--message 4 "snippet %d expanded." (yas--snippet-id snippet))
t))))
-(defun yas--take-care-of-redo (_beg _end snippet)
+(defun yas--take-care-of-redo (snippet)
"Commits SNIPPET, which in turn pushes an undo action for reviving it.
Meant to exit in the `buffer-undo-list'."
@@ -3891,16 +3854,34 @@ After revival, push the `yas--take-care-of-redo' in the
(push `(apply yas--take-care-of-redo ,beg ,end ,snippet)
buffer-undo-list)))
-(defun yas--snippet-create (expand-env begin end)
+(defun yas--snippet-create (content expand-env begin end)
"Create a snippet from a template inserted at BEGIN to END.
Returns the newly created snippet."
(save-restriction
- (narrow-to-region begin end)
(let ((snippet (yas--make-snippet expand-env)))
(yas--letenv expand-env
- (goto-char begin)
- (yas--snippet-parse-create snippet)
+ ;; Put a single undo action for the expanded snippet's
+ ;; content.
+ (let ((buffer-undo-list t))
+ ;; Some versions of cc-mode fail when inserting snippet
+ ;; content in a narrowed buffer.
+ (goto-char begin)
+ (insert content)
+ (setq end (+ end (length content)))
+ (narrow-to-region begin end)
+ (goto-char (point-min))
+ (yas--snippet-parse-create snippet))
+ (push (cons (point-min) (point-max))
+ buffer-undo-list)
+
+ ;; Indent, collecting undo information normally.
+ (yas--indent snippet)
+
+ ;; Follow up with `yas--take-care-of-redo' on the newly
+ ;; inserted snippet boundaries.
+ (push `(apply yas--take-care-of-redo ,snippet)
+ buffer-undo-list)
;; Sort and link each field
(yas--snippet-sort-fields snippet)
@@ -4111,8 +4092,7 @@ Meant to be called in a narrowed buffer, does various
passes"
(goto-char parse-start)
(yas--restore-escapes) ; Restore escapes.
(yas--update-mirrors snippet) ; Update mirrors for the first time.
- (goto-char parse-start))
- (yas--indent snippet)) ; Indent the best we can.
+ (goto-char parse-start)))
;; HACK: Some implementations of `indent-line-function' (called via
;; `indent-according-to-mode') delete text before they insert (like
@@ -4252,12 +4232,7 @@ The SNIPPET's markers are preserved."
remarkers)))
(unwind-protect
(progn (back-to-indentation)
- (if (eq yas--get-indent-undo-pos bol)
- (let ((buffer-undo-list nil))
- (indent-according-to-mode)
- (setq yas--first-indent-undo
- (delq nil buffer-undo-list)))
- (indent-according-to-mode)))
+ (indent-according-to-mode))
(save-restriction
(narrow-to-region bol (line-end-position))
(mapc #'yas--restore-marker-location remarkers))))
- [elpa] master ece7935 07/51: * yasnippet.el (yas--message): Fix invalid docstring reference., (continued)
- [elpa] master ece7935 07/51: * yasnippet.el (yas--message): Fix invalid docstring reference., Noam Postavsky, 2018/05/13
- [elpa] master 4ab9cb5 04/51: Set test to fail with newer org version, Noam Postavsky, 2018/05/13
- [elpa] master 0b8d434 05/51: Unset autoload-compute-prefixes for utility files, Noam Postavsky, 2018/05/13
- [elpa] master acec3ba 06/51: * doc/faq.org: Fix typo., Noam Postavsky, 2018/05/13
- [elpa] master ee81da9 11/51: Allow "# --" end-of-header marker to have trailing space, Noam Postavsky, 2018/05/13
- [elpa] master b1ca219 12/51: Remove submodules (snippet and yasmate), Noam Postavsky, 2018/05/13
- [elpa] master 35a4df7 03/51: Let whitespace-global-mode work in new snippet buffers, Noam Postavsky, 2018/05/13
- [elpa] master d806b04 15/51: * yasnippet.el (snippet-mode): Derive from prog-mode., Noam Postavsky, 2018/05/13
- [elpa] master 1292cd2 10/51: Refactor undo tests, Noam Postavsky, 2018/05/13
- [elpa] master 203059a 17/51: * yasnippet.el (yas-key-syntaxes): Prefer the longest key., Noam Postavsky, 2018/05/13
- [elpa] master 7ea1305 09/51: Fix undo when first line indentation moves snippet forward,
Noam Postavsky <=
- [elpa] master 6ffd1c7 22/51: ; .travis.yml: Test with 25.3 and 26 prelease., Noam Postavsky, 2018/05/13
- [elpa] master 2e69471 24/51: ; yasnippet-debug.el: macroexp-progn is not avaiable in Emacs 23., Noam Postavsky, 2018/05/13
- [elpa] master 3d7cafc 34/51: Make yas-snippet-mode-buffer-p robust against symlinks, Noam Postavsky, 2018/05/13
- [elpa] master ba73f20 27/51: Bind field skip and clear command conditionally, Noam Postavsky, 2018/05/13
- [elpa] master ce11fd6 13/51: * yasnippet.el (yas-reload-all): Mention if no snippets were found., Noam Postavsky, 2018/05/13
- [elpa] master e200a3b 08/51: Let snippet insertion trigger active field clearing., Noam Postavsky, 2018/05/13
- [elpa] master 04062d8 14/51: Don't set yas-selected-text to non-selected text, Noam Postavsky, 2018/05/13
- [elpa] master ad3a4d1 16/51: Don't use prog-mode in older Emacs, Noam Postavsky, 2018/05/13
- [elpa] master 16c2b38 18/51: Update `yas--take-care-of-redo' call in buffer undo list, Noam Postavsky, 2018/05/13
- [elpa] master e35c031 25/51: * yasnippet.el (yas--guess-snippet-directories): Guess major mode first., Noam Postavsky, 2018/05/13