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.
This commit is contained in:
Noam Postavsky 2017-06-05 20:50:49 -04:00
parent 6102ff5049
commit 1a860bd50b
2 changed files with 40 additions and 12 deletions

View File

@ -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

View File

@ -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