mirror of
https://github.com/joaotavora/yasnippet.git
synced 2025-10-13 13:13:03 +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-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 ()
|
||||
"elisp with strings and unbalance parens inside it"
|
||||
(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.
|
||||
(yas-expand-snippet "soon \\\"`(concat (upcase \"(my arms)\")\"\\\" were all around her\")`")
|
||||
(should (string= (yas--buffer-contents) "soon \"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"))))
|
||||
|
||||
(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
|
||||
|
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
|
||||
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)
|
||||
"Parse a recently inserted snippet template, creating all
|
||||
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
|
||||
;;
|
||||
(goto-char parse-start)
|
||||
(yas--replace-backquotes)
|
||||
;; protect escapes again since previous steps might have generated
|
||||
;; more characters needing escaping
|
||||
;;
|
||||
(goto-char parse-start)
|
||||
(yas--protect-escapes)
|
||||
(yas--save-backquotes)
|
||||
;; parse fields with {}
|
||||
;;
|
||||
(goto-char parse-start)
|
||||
@ -3784,6 +3784,9 @@ Meant to be called in a narrowed buffer, does various passes"
|
||||
;; Delete $-constructs
|
||||
;;
|
||||
(yas--delete-regions yas--dollar-regions)
|
||||
;; restore backquoted expression values
|
||||
;;
|
||||
(yas--restore-backquotes)
|
||||
;; restore escapes
|
||||
;;
|
||||
(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))
|
||||
changed-text))
|
||||
|
||||
(defun yas--replace-backquotes ()
|
||||
"Replace all the \"`(lisp-expression)`\"-style expression
|
||||
with their evaluated value"
|
||||
(defun yas--save-backquotes ()
|
||||
"Save all the \"`(lisp-expression)`\"-style expression
|
||||
with their evaluated value into `yas--backquote-markers-and-strings'"
|
||||
(while (re-search-forward yas--backquote-lisp-expression-regexp nil t)
|
||||
(let ((current-string (match-string 1)) transformed)
|
||||
(delete-region (match-beginning 0) (match-end 0))
|
||||
(setq transformed (yas--eval-lisp (yas--read-lisp (yas--restore-escapes current-string))))
|
||||
(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)
|
||||
(condition-case err
|
||||
|
Loading…
x
Reference in New Issue
Block a user