branch: master commit 1a860bd50b64944ff5d7fca079dc08753d0111c2 Author: Noam Postavsky <npost...@users.sourceforge.net> Commit: Noam Postavsky <npost...@users.sourceforge.net>
Fix undo information recording for multiline snippets * yasnippet.el (yas--get-indent-undo-pos): Renamed from yas--return-first-indent-undo. (yas-expand-snippet): Bind it to line beginning of snippet expansion position. * yasnippet-tests.el (undo-indentation, undo-indentation-multiline): New tests for this and previous fix. --- yasnippet-tests.el | 33 +++++++++++++++++++++++++++++++++ yasnippet.el | 19 +++++++------------ 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/yasnippet-tests.el b/yasnippet-tests.el index 7ab956c..dbe984e 100644 --- a/yasnippet-tests.el +++ b/yasnippet-tests.el @@ -176,6 +176,39 @@ ;; (should (string= (yas--buffer-contents) ;; "brother from another mother!")))) +(ert-deftest undo-indentation () + "Check undoing works when only line of snippet is indented." + (let ((yas-also-auto-indent-first-line t)) + (yas-with-snippet-dirs + '((".emacs.d/snippets" ("emacs-lisp-mode" ("s" . "(setq $0)")))) + (with-temp-buffer + (emacs-lisp-mode) + (yas-minor-mode 1) + (insert "(let\n(while s") + (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) "(let\n (while (setq )")) + (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." + (yas-with-snippet-dirs + '((".emacs.d/snippets" ("js-mode" ("if" . "if ($1) {\n\n}\n")))) + (with-temp-buffer + (js-mode) + (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 3f8cca9..798e49e 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -3717,9 +3717,10 @@ Move the overlays, or create them if they do not exit." (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'.") +(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. @@ -3774,7 +3775,7 @@ considered when expanding the snippet." ;; ;; stacked expansion: also shoosh the overlay modification hooks (let ((buffer-undo-list t) - (yas--return-first-indent-undo 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 @@ -4199,12 +4200,7 @@ The SNIPPET's markers are preserved." (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)))) + (to (set-marker (make-marker) to))) (goto-char from) (cl-loop for bol = (line-beginning-position) for eol = (line-end-position) @@ -4217,8 +4213,7 @@ The SNIPPET's markers are preserved." remarkers))) (unwind-protect (progn (back-to-indentation) - (if (and yas--return-first-indent-undo - (= 1st-bol bol)) + (if (eq yas--get-indent-undo-pos bol) (let ((buffer-undo-list nil)) (indent-according-to-mode) (setq yas--first-indent-undo