Close #937: Officially support automatically moving to next field

* yasnippet-tests.el (auto-next-field): New test.
(yas-saving-variables): Move up in the file.

* yasnippet.el (yas--auto-next): New helper.
(yas-auto-next): New user-visible snippet helper.

* doc/snippet-development.org (Choosing fields value from a list
and other tricks): Add mention of yas-auto-next.
This commit is contained in:
João Távora 2018-05-16 13:22:27 +01:00
parent 5a29fe67d7
commit 4f78d03f85
3 changed files with 49 additions and 6 deletions

View File

@ -420,8 +420,19 @@ The [[sym:yas-choose-value][=yas-choose-value=]] does this work for you. For exa
</div>
#+END_SRC
See the definition of [[sym:yas-choose-value][=yas-choose-value=]] to see how it was written using
the two variables.
See the definition of [[sym:yas-choose-value][=yas-choose-value=]] to see how it was written
using the two variables. If you're really lazy :) and can't spare a
tab keypress, you can automatically move to the next field (or exit)
after choosing the value with [[sym:yas-auto-next][=yas-auto-next=]]. The snippet above
becomes:
#+BEGIN_SRC snippet
<div align="${2:$$(yas-auto-next
(yas-choose-value
'("right" "center" "left")))}">
$0
</div>
#+END_SRC
Here's another use, for LaTeX-mode, which calls reftex-label just as you
enter snippet field 2. This one makes use of [[sym:yas-modified-p][=yas-modified-p=]] directly.

View File

@ -603,6 +603,30 @@ mapconcat #'(lambda (arg)
(ert-simulate-command '(yas-next-field))
(should (looking-at (concat "blo" expected))))))
(defmacro yas-saving-variables (&rest body)
(declare (debug t))
`(yas-call-with-saving-variables #'(lambda () ,@body)))
(ert-deftest auto-next-field ()
"Automatically exit a field after evaluating its transform."
(with-temp-buffer
(yas-saving-variables
(yas-with-snippet-dirs
`((".emacs.d/snippets"
("ruby-mode" ("snip" . ,(concat "foo ${1:$$"
(prin1-to-string '(yas-auto-next
(yas-choose-value
"bar" "foo")))
"} baz ${2:quinn} quinn")))))
(yas-reload-all)
(ruby-mode)
(yas-minor-mode 1)
(set (make-local-variable 'yas-prompt-functions) `(yas-no-prompt))
(yas-mock-insert "snip")
(ert-simulate-command '(yas-expand))
(yas-mock-insert "quux")
(should (equal "foo bar baz quux quinn" (buffer-string)))))))
;;; Snippet expansion and character escaping
;;; Thanks to @zw963 (Billy) for the testing
@ -754,10 +778,6 @@ mapconcat #'(lambda (arg)
(and (buffer-name ,temp-buffer)
(kill-buffer ,temp-buffer))))))))
(defmacro yas-saving-variables (&rest body)
(declare (debug t))
`(yas-call-with-saving-variables #'(lambda () ,@body)))
(ert-deftest example-for-issue-474 ()
(yas--with-font-locked-temp-buffer
(c-mode)

View File

@ -2987,6 +2987,18 @@ The last element of POSSIBILITIES may be a list of strings."
(funcall fn "Choose: " possibilities))
yas-prompt-functions)))
(defun yas--auto-next ()
"Helper for `yas-auto-next'."
(remove-hook 'post-command-hook #'yas--auto-next t)
(yas-next-field))
(defmacro yas-auto-next (&rest body)
"Automatically advance to next field after eval'ing BODY."
(declare (indent 0) (debug t))
`(unless yas-moving-away-p
(prog1 ,@body
(add-hook 'post-command-hook #'yas--auto-next nil t))))
(defun yas-key-to-value (alist)
(unless (or yas-moving-away-p
yas-modified-p)