diff --git a/doc/snippet-development.org b/doc/snippet-development.org
index 9112cd0..1a7ad49 100644
--- a/doc/snippet-development.org
+++ b/doc/snippet-development.org
@@ -420,8 +420,19 @@ The [[sym:yas-choose-value][=yas-choose-value=]] does this work for you. For exa
#+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
+
+ $0
+
+#+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.
diff --git a/yasnippet-tests.el b/yasnippet-tests.el
index 6048467..fb4bc0f 100644
--- a/yasnippet-tests.el
+++ b/yasnippet-tests.el
@@ -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)
diff --git a/yasnippet.el b/yasnippet.el
index d478073..eeeb33f 100644
--- a/yasnippet.el
+++ b/yasnippet.el
@@ -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)