mirror of
https://github.com/joaotavora/yasnippet.git
synced 2025-10-14 05:23:04 +00:00
Work around Emacs Bug#30931 (Misc_Free in undo list)
* yasnippet.el (yas--remove-misc-free-from-undo): New function. (yas--save-restriction-and-widen): New macro. (yas--eval-for-string, yas--snippet-parse-create) (yas--indent-region, yas--save-backquotes) (yas--restore-backquotes, yas--update-mirrors): Use it.
This commit is contained in:
parent
16686075bb
commit
f9231b0e3d
57
yasnippet.el
57
yasnippet.el
@ -1412,15 +1412,51 @@ Returns (TEMPLATES START END). This function respects
|
|||||||
|
|
||||||
;;; Internal functions and macros:
|
;;; Internal functions and macros:
|
||||||
|
|
||||||
|
(defun yas--remove-misc-free-from-undo (old-undo-list)
|
||||||
|
"Tries to work around Emacs Bug#30931.
|
||||||
|
Helper function for `yas--save-restriction-and-widen'."
|
||||||
|
;; If Bug#30931 is unfixed, we get (#<Lisp_Misc_Free> . INTEGER)
|
||||||
|
;; entries in the undo list. If we call `type-of' on the
|
||||||
|
;; Lisp_Misc_Free object then Emacs aborts, so try to find it by
|
||||||
|
;; checking that its type is none of the expected ones.
|
||||||
|
(when (consp buffer-undo-list)
|
||||||
|
(let* ((prev buffer-undo-list)
|
||||||
|
(undo-list prev))
|
||||||
|
(while (and (consp undo-list)
|
||||||
|
;; Only check new entries.
|
||||||
|
(not (eq undo-list old-undo-list)))
|
||||||
|
(let ((entry (pop undo-list)))
|
||||||
|
(when (consp entry)
|
||||||
|
(let ((head (car entry)))
|
||||||
|
(unless (or (stringp head)
|
||||||
|
(markerp head)
|
||||||
|
(integerp head)
|
||||||
|
(symbolp head)
|
||||||
|
(not (integerp (cdr entry))))
|
||||||
|
;; (message "removing misc free %S" entry)
|
||||||
|
(setcdr prev undo-list)))))
|
||||||
|
(setq prev undo-list)))))
|
||||||
|
|
||||||
|
(defmacro yas--save-restriction-and-widen (&rest body)
|
||||||
|
"Equivalent to (save-restriction (widen) BODY).
|
||||||
|
Also tries to work around Emacs Bug#30931."
|
||||||
|
(declare (debug (body)) (indent 0))
|
||||||
|
;; Disable garbage collection, since it could cause an abort.
|
||||||
|
`(let ((gc-cons-threshold most-positive-fixnum)
|
||||||
|
(old-undo-list buffer-undo-list))
|
||||||
|
(prog1 (save-restriction
|
||||||
|
(widen)
|
||||||
|
,@body)
|
||||||
|
(yas--remove-misc-free-from-undo old-undo-list))))
|
||||||
|
|
||||||
(defun yas--eval-for-string (form)
|
(defun yas--eval-for-string (form)
|
||||||
"Evaluate FORM and convert the result to string."
|
"Evaluate FORM and convert the result to string."
|
||||||
(let ((debug-on-error (and (not (memq yas-good-grace '(t inline)))
|
(let ((debug-on-error (and (not (memq yas-good-grace '(t inline)))
|
||||||
debug-on-error)))
|
debug-on-error)))
|
||||||
(condition-case oops
|
(condition-case oops
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(save-restriction
|
(yas--save-restriction-and-widen
|
||||||
(save-match-data
|
(save-match-data
|
||||||
(widen)
|
|
||||||
(let ((result (eval form)))
|
(let ((result (eval form)))
|
||||||
(when result
|
(when result
|
||||||
(format "%s" result))))))
|
(format "%s" result))))))
|
||||||
@ -4187,8 +4223,7 @@ Meant to be called in a narrowed buffer, does various passes"
|
|||||||
(syntax-ppss-flush-cache parse-start))
|
(syntax-ppss-flush-cache parse-start))
|
||||||
;; Set "next" links of fields & mirrors.
|
;; Set "next" links of fields & mirrors.
|
||||||
(yas--calculate-adjacencies snippet)
|
(yas--calculate-adjacencies snippet)
|
||||||
(save-restriction
|
(yas--save-restriction-and-widen ; Delete $-constructs.
|
||||||
(widen) ; Delete $-constructs.
|
|
||||||
(yas--delete-regions yas--dollar-regions))
|
(yas--delete-regions yas--dollar-regions))
|
||||||
;; Make sure to do this insertion *after* deleting the dollar
|
;; Make sure to do this insertion *after* deleting the dollar
|
||||||
;; regions, otherwise we invalidate the calculated positions of
|
;; regions, otherwise we invalidate the calculated positions of
|
||||||
@ -4329,8 +4364,7 @@ Buffer must be narrowed to BEG..END used to create the snapshot info."
|
|||||||
"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."
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(save-restriction
|
(yas--save-restriction-and-widen
|
||||||
(widen)
|
|
||||||
(let* ((snippet-markers (yas--collect-snippet-markers snippet))
|
(let* ((snippet-markers (yas--collect-snippet-markers snippet))
|
||||||
(to (set-marker (make-marker) to)))
|
(to (set-marker (make-marker) to)))
|
||||||
(goto-char from)
|
(goto-char from)
|
||||||
@ -4439,7 +4473,7 @@ Lisp expression."
|
|||||||
(setq yas--change-detected t)))))
|
(setq yas--change-detected t)))))
|
||||||
(while (re-search-forward yas--backquote-lisp-expression-regexp nil t)
|
(while (re-search-forward yas--backquote-lisp-expression-regexp nil t)
|
||||||
(let ((current-string (match-string-no-properties 1)) transformed)
|
(let ((current-string (match-string-no-properties 1)) transformed)
|
||||||
(save-restriction (widen)
|
(yas--save-restriction-and-widen
|
||||||
(delete-region (match-beginning 0) (match-end 0)))
|
(delete-region (match-beginning 0) (match-end 0)))
|
||||||
(let ((before-change-functions
|
(let ((before-change-functions
|
||||||
(cons detect-change before-change-functions)))
|
(cons detect-change before-change-functions)))
|
||||||
@ -4450,8 +4484,7 @@ Lisp expression."
|
|||||||
(when transformed
|
(when transformed
|
||||||
(let ((marker (make-marker))
|
(let ((marker (make-marker))
|
||||||
(before-change-functions (cdr before-change-functions)))
|
(before-change-functions (cdr before-change-functions)))
|
||||||
(save-restriction
|
(yas--save-restriction-and-widen
|
||||||
(widen)
|
|
||||||
(insert "Y") ;; quite horrendous, I love it :)
|
(insert "Y") ;; quite horrendous, I love it :)
|
||||||
(set-marker marker (point))
|
(set-marker marker (point))
|
||||||
(insert "Y"))
|
(insert "Y"))
|
||||||
@ -4471,8 +4504,7 @@ SAVED-QUOTES is the in format returned by `yas--save-backquotes'."
|
|||||||
(cl-loop for (marker . string) in saved-quotes do
|
(cl-loop for (marker . string) in saved-quotes do
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(goto-char marker)
|
(goto-char marker)
|
||||||
(save-restriction
|
(yas--save-restriction-and-widen
|
||||||
(widen)
|
|
||||||
(delete-char -1)
|
(delete-char -1)
|
||||||
(insert string)
|
(insert string)
|
||||||
(delete-char 1))
|
(delete-char 1))
|
||||||
@ -4653,8 +4685,7 @@ When multiple expressions are found, only the last one counts."
|
|||||||
|
|
||||||
(defun yas--update-mirrors (snippet)
|
(defun yas--update-mirrors (snippet)
|
||||||
"Update all the mirrors of SNIPPET."
|
"Update all the mirrors of SNIPPET."
|
||||||
(save-restriction
|
(yas--save-restriction-and-widen
|
||||||
(widen)
|
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(cl-loop
|
(cl-loop
|
||||||
for (field . mirror)
|
for (field . mirror)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user