Scan nested fields properly

* yasnippet.el (yas--scan-for-field-end): New function.
(yas--field-parse-create): Use it instead of yas--scan-sexps, which
isn't able to distinguish between ${...} (a nested field) and
{...} (plain old braces in the snippet text).
* yasnippet-tests.el (yas-escaping-close-brace): New test.
This commit is contained in:
Noam Postavsky 2020-03-25 22:21:37 -04:00
parent 7c02bc142c
commit 170d13d069
2 changed files with 22 additions and 1 deletions

View File

@ -947,6 +947,18 @@ mapconcat #'(lambda (arg)
(yas-mock-insert "baz")
(should (string= (yas--buffer-contents) "foobaaarbazok")))))
(ert-deftest yas-escaping-close-brace ()
"Close braces may be escaped with braces, reduction from eglot issue.
See https://github.com/joaotavora/eglot/issues/336."
(with-temp-buffer
(yas-minor-mode +1)
;; NOTE: put a period at the end to avoid the bug tested by
;; `protection-overlay-no-cheating'.
(yas-expand-snippet "${1:one{\\}}, ${2:two{\\}}.")
(yas-next-field)
(yas-next-field)
(should (string= (buffer-string) "one{}, two{}."))))
;;; Misc tests
;;;

View File

@ -4719,6 +4719,13 @@ SAVED-QUOTES is the in format returned by `yas--save-backquotes'."
yas--indent-markers))
(setq yas--indent-markers (nreverse yas--indent-markers)))
(defun yas--scan-for-field-end ()
(while (progn (re-search-forward "\\${\\|}")
(when (eq (char-before) ?\{)
;; Nested field.
(yas--scan-for-field-end))))
(point))
(defun yas--field-parse-create (snippet &optional parent-field)
"Parse most field expressions in SNIPPET, except for the simple one \"$n\".
@ -4735,7 +4742,9 @@ When multiple expressions are found, only the last one counts."
;;
(save-excursion
(while (re-search-forward yas--field-regexp nil t)
(let* ((brace-scan (yas--scan-sexps (1+ (match-beginning 0)) 1))
(let* ((brace-scan (save-match-data
(goto-char (match-beginning 2))
(yas--scan-for-field-end)))
;; if the `brace-scan' didn't reach a brace, we have a
;; snippet with invalid escaping, probably a closing
;; brace escaped with two backslashes (github#979). But