mirror of
https://github.com/joaotavora/yasnippet.git
synced 2025-10-13 13:13:03 +00:00
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.
This commit is contained in:
parent
1043b6c557
commit
6102ff5049
63
yasnippet.el
63
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. This would mean a lot of overlay modification hooks
|
||||||
;; running, but if managed correctly (including overlay priorities)
|
;; running, but if managed correctly (including overlay priorities)
|
||||||
;; they should account for all situations...
|
;; 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)
|
(defun yas-expand-snippet (content &optional start end expand-env)
|
||||||
"Expand snippet CONTENT at current point.
|
"Expand snippet CONTENT at current point.
|
||||||
|
|
||||||
@ -3742,6 +3749,7 @@ considered when expanding the snippet."
|
|||||||
(to-delete (and start
|
(to-delete (and start
|
||||||
end
|
end
|
||||||
(buffer-substring-no-properties start end)))
|
(buffer-substring-no-properties start end)))
|
||||||
|
(yas--first-indent-undo nil)
|
||||||
snippet)
|
snippet)
|
||||||
(goto-char start)
|
(goto-char start)
|
||||||
(setq yas--indent-original-column (current-column))
|
(setq yas--indent-original-column (current-column))
|
||||||
@ -3765,7 +3773,8 @@ considered when expanding the snippet."
|
|||||||
;; plain text will get recorded at the end.
|
;; plain text will get recorded at the end.
|
||||||
;;
|
;;
|
||||||
;; stacked expansion: also shoosh the overlay modification hooks
|
;; 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
|
;; snippet creation might evaluate users elisp, which
|
||||||
;; might generate errors, so we have to be ready to catch
|
;; might generate errors, so we have to be ready to catch
|
||||||
;; them mostly to make the undo information
|
;; them mostly to make the undo information
|
||||||
@ -3791,23 +3800,20 @@ considered when expanding the snippet."
|
|||||||
(unless (yas--snippet-fields snippet)
|
(unless (yas--snippet-fields snippet)
|
||||||
(yas-exit-snippet snippet))
|
(yas-exit-snippet snippet))
|
||||||
|
|
||||||
;; Push two undo actions: the deletion of the inserted contents of
|
;; Undo actions from indent of snippet's 1st line.
|
||||||
;; the new snippet (without the "key") followed by an apply of
|
(setq buffer-undo-list
|
||||||
;; `yas--take-care-of-redo' on the newly inserted snippet boundaries
|
(nconc yas--first-indent-undo buffer-undo-list))
|
||||||
;;
|
;; Undo action for the expand snippet contents.
|
||||||
;; A small exception, if `yas-also-auto-indent-first-line'
|
(push (cons (overlay-start (yas--snippet-control-overlay snippet))
|
||||||
;; is t and `yas--indent' decides to indent the line to a
|
(overlay-end (yas--snippet-control-overlay snippet)))
|
||||||
;; point before the actual expansion point, undo would be
|
buffer-undo-list)
|
||||||
;; messed up. We call the early point "newstart"". case,
|
;; Follow up with `yas--take-care-of-redo' on the newly
|
||||||
;; and attempt to fix undo.
|
;; inserted snippet boundaries.
|
||||||
;;
|
(push `(apply yas--take-care-of-redo ,start
|
||||||
(let ((newstart (overlay-start (yas--snippet-control-overlay snippet)))
|
,(overlay-end (yas--snippet-control-overlay snippet))
|
||||||
(end (overlay-end (yas--snippet-control-overlay snippet))))
|
,snippet)
|
||||||
(when (< newstart start)
|
buffer-undo-list)
|
||||||
(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))
|
|
||||||
;; Now, schedule a move to the first field
|
;; Now, schedule a move to the first field
|
||||||
;;
|
;;
|
||||||
(let ((first-field (car (yas--snippet-fields snippet))))
|
(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)
|
(defun yas--indent-region (from to snippet)
|
||||||
"Indent the lines between FROM and TO with `indent-according-to-mode'.
|
"Indent the lines between FROM and TO with `indent-according-to-mode'.
|
||||||
The SNIPPET's markers are preserved."
|
The SNIPPET's markers are preserved."
|
||||||
(let* ((snippet-markers (yas--collect-snippet-markers snippet))
|
|
||||||
(to (set-marker (make-marker) to)))
|
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(goto-char from)
|
|
||||||
(save-restriction
|
(save-restriction
|
||||||
(widen)
|
(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)
|
(cl-loop for bol = (line-beginning-position)
|
||||||
for eol = (line-end-position)
|
for eol = (line-end-position)
|
||||||
if (/= bol eol) do
|
if (/= bol eol) do
|
||||||
@ -4206,7 +4217,13 @@ The SNIPPET's markers are preserved."
|
|||||||
remarkers)))
|
remarkers)))
|
||||||
(unwind-protect
|
(unwind-protect
|
||||||
(progn (back-to-indentation)
|
(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
|
(save-restriction
|
||||||
(narrow-to-region bol (line-end-position))
|
(narrow-to-region bol (line-end-position))
|
||||||
(mapc #'yas--restore-marker-location remarkers))))
|
(mapc #'yas--restore-marker-location remarkers))))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user