mirror of
https://github.com/joaotavora/yasnippet.git
synced 2025-10-13 21:13:04 +00:00
Closes #271: save backquoted elisp and re-insert at end of expansion
This commit is contained in:
parent
6be1de4a09
commit
f35d2dba11
@ -112,17 +112,78 @@
|
|||||||
(should (string= (yas--buffer-contents) "blabla}ble"))
|
(should (string= (yas--buffer-contents) "blabla}ble"))
|
||||||
(should (string= (yas-field-value 1) "bla}"))))
|
(should (string= (yas-field-value 1) "bla}"))))
|
||||||
|
|
||||||
|
(ert-deftest escape-backslashes ()
|
||||||
|
(with-temp-buffer
|
||||||
|
(yas-minor-mode 1)
|
||||||
|
(yas-expand-snippet "bla\\ble")
|
||||||
|
(should (string= (yas--buffer-contents) "bla\\ble"))))
|
||||||
|
|
||||||
(ert-deftest escape-some-elisp-with-strings ()
|
(ert-deftest escape-some-elisp-with-strings ()
|
||||||
|
"elisp with strings and unbalance parens inside it"
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
(yas-minor-mode 1)
|
(yas-minor-mode 1)
|
||||||
;; The rules here is: to output a literal `"' you need to escape
|
;; The rules here is: to output a literal `"' you need to escape
|
||||||
;; it with one backslash. You don't need to escape them in
|
;; it with one backslash. You don't need to escape them in
|
||||||
;; embedded elisp.
|
;; embedded elisp.
|
||||||
(yas-expand-snippet "soon \\\"`(concat (upcase \"(my arms)\")\"\\\" were all around her\")`")
|
(yas-expand-snippet "soon \\\"`(concat (upcase \"(my arms\")\"\\\" were all around her\")`")
|
||||||
(should (string= (yas--buffer-contents) "soon \"MY ARMS\" were all around her"))))
|
(should (string= (yas--buffer-contents) "soon \"(MY ARMS\" were all around her"))))
|
||||||
|
|
||||||
|
(ert-deftest escape-some-elisp-with-backslashes ()
|
||||||
|
(with-temp-buffer
|
||||||
|
(yas-minor-mode 1)
|
||||||
|
;; And the rule here is: to output a literal `\' inside a string
|
||||||
|
;; inside embedded elisp you need a total of six `\'
|
||||||
|
(yas-expand-snippet "bla`(upcase \"hey\\\\\\yo\")`ble")
|
||||||
|
(should (string= (yas--buffer-contents) "blaHEY\\YOble"))))
|
||||||
|
|
||||||
|
(ert-deftest be-careful-when-escaping-in-yas-selected-text ()
|
||||||
|
(with-temp-buffer
|
||||||
|
(yas-minor-mode 1)
|
||||||
|
(let ((yas/selected-text "He\\\\o world!"))
|
||||||
|
(yas-expand-snippet "Look ma! `(yas/selected-text)`")
|
||||||
|
(should (string= (yas--buffer-contents) "Look ma! He\\\\o world!")))
|
||||||
|
(yas-exit-all-snippets)
|
||||||
|
(erase-buffer)
|
||||||
|
(let ((yas/selected-text "He\"o world!"))
|
||||||
|
(yas-expand-snippet "Look ma! `(yas/selected-text)`")
|
||||||
|
(should (string= (yas--buffer-contents) "Look ma! He\"o world!")))
|
||||||
|
(yas-exit-all-snippets)
|
||||||
|
(erase-buffer)
|
||||||
|
(let ((yas/selected-text "He\"\)\\o world!"))
|
||||||
|
(yas-expand-snippet "Look ma! `(yas/selected-text)`")
|
||||||
|
(should (string= (yas--buffer-contents) "Look ma! He\"\)\\o world!")))
|
||||||
|
(yas-exit-all-snippets)
|
||||||
|
(erase-buffer))))
|
||||||
|
|
||||||
|
(ert-deftest be-careful-when-escaping-in-yas-selected-text-2 ()
|
||||||
|
(with-temp-buffer
|
||||||
|
(let ((yas/selected-text "He)}o world!"))
|
||||||
|
(yas-expand-snippet "Look ma! ${1:`(yas/selected-text)`} OK?")
|
||||||
|
(should (string= (yas--buffer-contents) "Look ma! He)}o world! OK?")))))
|
||||||
|
|
||||||
|
(ert-deftest mirror-transformation ()
|
||||||
|
(with-temp-buffer
|
||||||
|
(yas-minor-mode 1)
|
||||||
|
(let ((snippet "${1:`(concat \"foo\" \"bar\")`} ${1:$(concat (upcase yas/text) \"baz\")}"))
|
||||||
|
(yas-expand-snippet snippet)
|
||||||
|
(should (string= (yas--buffer-contents) "foobar FOOBARbaz"))
|
||||||
|
(yas-exit-all-snippets)
|
||||||
|
(erase-buffer)
|
||||||
|
(yas-expand-snippet snippet)
|
||||||
|
(ert-simulate-command `(yas-mock-insert "bla"))
|
||||||
|
(should (string= (yas--buffer-contents) "bla BLAbaz")))))
|
||||||
|
|
||||||
|
(ert-deftest primary-field-transformation ()
|
||||||
|
(with-temp-buffer
|
||||||
|
(yas-minor-mode 1)
|
||||||
|
;; The rules here is: to output a literal `"' you need to escape
|
||||||
|
;; it with one backslash. You don't need to escape them in
|
||||||
|
;; embedded elisp.
|
||||||
|
(let ((snippet "${1:$$(upcase yas/text)}${1:$(concat \"bar\" yas/text)}"))
|
||||||
|
(yas-expand-snippet snippet)
|
||||||
|
(should (string= (yas--buffer-contents) "bar"))
|
||||||
|
(ert-simulate-command `(yas-mock-insert "foo"))
|
||||||
|
(should (string= (yas--buffer-contents) "FOObarFOO")))))
|
||||||
|
|
||||||
|
|
||||||
;;; Misc tests
|
;;; Misc tests
|
||||||
|
42
yasnippet.el
42
yasnippet.el
@ -3745,6 +3745,11 @@ next FOM. Works its way up recursively for parents of parents."
|
|||||||
"When expanding the snippet the \"parse-create\" functions add
|
"When expanding the snippet the \"parse-create\" functions add
|
||||||
cons cells to this var")
|
cons cells to this var")
|
||||||
|
|
||||||
|
(defvar yas--backquote-markers-and-strings nil
|
||||||
|
"List of (MARKER . STRING) marking where the the values
|
||||||
|
from backquoted lisp expressions should be inserted at the end of
|
||||||
|
expansion" )
|
||||||
|
|
||||||
(defun yas--snippet-parse-create (snippet)
|
(defun yas--snippet-parse-create (snippet)
|
||||||
"Parse a recently inserted snippet template, creating all
|
"Parse a recently inserted snippet template, creating all
|
||||||
necessary fields, mirrors and exit points.
|
necessary fields, mirrors and exit points.
|
||||||
@ -3760,12 +3765,7 @@ Meant to be called in a narrowed buffer, does various passes"
|
|||||||
;; replace all backquoted expressions
|
;; replace all backquoted expressions
|
||||||
;;
|
;;
|
||||||
(goto-char parse-start)
|
(goto-char parse-start)
|
||||||
(yas--replace-backquotes)
|
(yas--save-backquotes)
|
||||||
;; protect escapes again since previous steps might have generated
|
|
||||||
;; more characters needing escaping
|
|
||||||
;;
|
|
||||||
(goto-char parse-start)
|
|
||||||
(yas--protect-escapes)
|
|
||||||
;; parse fields with {}
|
;; parse fields with {}
|
||||||
;;
|
;;
|
||||||
(goto-char parse-start)
|
(goto-char parse-start)
|
||||||
@ -3784,6 +3784,9 @@ Meant to be called in a narrowed buffer, does various passes"
|
|||||||
;; Delete $-constructs
|
;; Delete $-constructs
|
||||||
;;
|
;;
|
||||||
(yas--delete-regions yas--dollar-regions)
|
(yas--delete-regions yas--dollar-regions)
|
||||||
|
;; restore backquoted expression values
|
||||||
|
;;
|
||||||
|
(yas--restore-backquotes)
|
||||||
;; restore escapes
|
;; restore escapes
|
||||||
;;
|
;;
|
||||||
(goto-char parse-start)
|
(goto-char parse-start)
|
||||||
@ -3915,15 +3918,34 @@ With optional string TEXT do it in string instead of the buffer."
|
|||||||
(or escaped yas--escaped-characters))
|
(or escaped yas--escaped-characters))
|
||||||
changed-text))
|
changed-text))
|
||||||
|
|
||||||
(defun yas--replace-backquotes ()
|
(defun yas--save-backquotes ()
|
||||||
"Replace all the \"`(lisp-expression)`\"-style expression
|
"Save all the \"`(lisp-expression)`\"-style expression
|
||||||
with their evaluated value"
|
with their evaluated value into `yas--backquote-markers-and-strings'"
|
||||||
(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 1)) transformed)
|
(let ((current-string (match-string 1)) transformed)
|
||||||
(delete-region (match-beginning 0) (match-end 0))
|
(delete-region (match-beginning 0) (match-end 0))
|
||||||
(setq transformed (yas--eval-lisp (yas--read-lisp (yas--restore-escapes current-string))))
|
(setq transformed (yas--eval-lisp (yas--read-lisp (yas--restore-escapes current-string))))
|
||||||
(goto-char (match-beginning 0))
|
(goto-char (match-beginning 0))
|
||||||
(when transformed (insert transformed)))))
|
(when transformed
|
||||||
|
(let ((marker (make-marker)))
|
||||||
|
(insert "Y") ;; quite horrendous, I love it :)
|
||||||
|
(set-marker marker (point))
|
||||||
|
(insert "Y")
|
||||||
|
(push (cons marker transformed) yas--backquote-markers-and-strings))))))
|
||||||
|
|
||||||
|
(defun yas--restore-backquotes ()
|
||||||
|
"Replace all the markers in
|
||||||
|
`yas--backquote-markers-and-strings' with their values"
|
||||||
|
(while yas--backquote-markers-and-strings
|
||||||
|
(let* ((marker-and-string (pop yas--backquote-markers-and-strings))
|
||||||
|
(marker (car marker-and-string))
|
||||||
|
(string (cdr marker-and-string)))
|
||||||
|
(save-excursion
|
||||||
|
(goto-char marker)
|
||||||
|
(delete-char -1)
|
||||||
|
(insert string)
|
||||||
|
(delete-char 1)
|
||||||
|
(set-marker marker nil)))))
|
||||||
|
|
||||||
(defun yas--scan-sexps (from count)
|
(defun yas--scan-sexps (from count)
|
||||||
(condition-case err
|
(condition-case err
|
||||||
|
Loading…
x
Reference in New Issue
Block a user