emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] master 5729354 2/2: Merge commit '8dbcc8e07c462777378cc859eced622


From: Stephen Leake
Subject: [elpa] master 5729354 2/2: Merge commit '8dbcc8e07c462777378cc859eced622ec9b0fc4d'
Date: Sun, 29 Dec 2019 15:28:45 -0500 (EST)

branch: master
commit 5729354dfb90c8ed3ea487cc42e0887f8d45dc53
Merge: fbc8665 8dbcc8e
Author: Stephen Leake <address@hidden>
Commit: Stephen Leake <address@hidden>

    Merge commit '8dbcc8e07c462777378cc859eced622ec9b0fc4d'
---
 packages/debbugs/debbugs-gnu.el                 |   4 +-
 packages/rainbow-mode/rainbow-mode.el           |  32 +-
 packages/yasnippet/NEWS                         |  76 ++-
 packages/yasnippet/README.mdown                 |   2 +-
 packages/yasnippet/doc/faq.org                  |  69 +--
 packages/yasnippet/doc/snippet-development.org  |  71 ++-
 packages/yasnippet/doc/snippet-expansion.org    |  10 +-
 packages/yasnippet/doc/snippet-organization.org |   2 +-
 packages/yasnippet/yasnippet-debug.el           |   8 +-
 packages/yasnippet/yasnippet-tests.el           | 212 ++++++-
 packages/yasnippet/yasnippet.el                 | 737 ++++++++++++++----------
 11 files changed, 820 insertions(+), 403 deletions(-)

diff --git a/packages/debbugs/debbugs-gnu.el b/packages/debbugs/debbugs-gnu.el
index 13a3274..be564ca 100644
--- a/packages/debbugs/debbugs-gnu.el
+++ b/packages/debbugs/debbugs-gnu.el
@@ -2280,10 +2280,10 @@ or bug ranges, with default to 
`debbugs-gnu-default-bug-number-list'."
   :type 'directory
   :version "25.2")
 
-(defcustom debbugs-gnu-branch-directory "~/src/emacs/emacs-25/"
+(defcustom debbugs-gnu-branch-directory "~/src/emacs/emacs-27/"
   "The directory where the previous source tree lives."
   :type 'directory
-  :version "25.2")
+  :version "28.1")
 
 (defvar debbugs-gnu-current-directory nil
   "The current source tree directory.")
diff --git a/packages/rainbow-mode/rainbow-mode.el 
b/packages/rainbow-mode/rainbow-mode.el
index 653e166..f49de88 100644
--- a/packages/rainbow-mode/rainbow-mode.el
+++ b/packages/rainbow-mode/rainbow-mode.el
@@ -1,10 +1,10 @@
 ;;; rainbow-mode.el --- Colorize color names in buffers
 
-;; Copyright (C) 2010-2018 Free Software Foundation, Inc
+;; Copyright (C) 2010-2019 Free Software Foundation, Inc
 
 ;; Author: Julien Danjou <address@hidden>
 ;; Keywords: faces
-;; Version: 1.0.2
+;; Version: 1.0.3
 
 ;; This file is part of GNU Emacs.
 
@@ -29,9 +29,7 @@
 
 ;;; Code:
 
-(eval-when-compile
-  (require 'cl))
-
+(require 'cl-lib)
 (require 'regexp-opt)
 (require 'faces)
 (require 'color)
@@ -1060,7 +1058,7 @@ If the percentage value is above 100, it's converted to 
100."
         (s (/ (string-to-number (match-string-no-properties 2)) 100.0))
         (l (/ (string-to-number (match-string-no-properties 3)) 100.0)))
     (rainbow-colorize-match
-     (multiple-value-bind (r g b)
+     (cl-destructuring-bind (r g b)
          (color-hsl-to-rgb h s l)
        (format "#%02X%02X%02X" (* r 255) (* g 255) (* b 255))))))
 
@@ -1190,17 +1188,27 @@ Return a value between 0 and 1."
      ,@rainbow-html-colors-font-lock-keywords
      ,@rainbow-html-rgb-colors-font-lock-keywords)))
 
+(defvar rainbow-keywords-hook nil
+  "Hook used to add additional font-lock keywords.
+This hook is called by `rainbow-mode' before it re-enables
+`font-lock-mode'.  Hook functions must only add additional
+keywords when `rainbow-mode' is non-nil.  When that is nil,
+then they must remove those additional keywords again.")
+
 ;;;###autoload
 (define-minor-mode rainbow-mode
   "Colorize strings that represent colors.
 This will fontify with colors the string like \"#aabbcc\" or \"blue\"."
   :lighter " Rbow"
-  (progn
-    (if rainbow-mode
-        (rainbow-turn-on)
-      (rainbow-turn-off))
-    ;; Call font-lock-mode to refresh the buffer when used e.g. interactively
-    (font-lock-mode 1)))
+  (if rainbow-mode
+      (rainbow-turn-on)
+    (rainbow-turn-off))
+  ;; We cannot use `rainbow-mode-hook' because this has
+  ;; to be done before `font-lock-mode' is re-enabled.
+  (run-hooks 'rainbow-keywords-hook)
+  ;; Call `font-lock-mode' to refresh the buffer when used
+  ;; e.g. interactively.
+  (font-lock-mode 1))
 
 (provide 'rainbow-mode)
 
diff --git a/packages/yasnippet/NEWS b/packages/yasnippet/NEWS
index 6bea12f..35d514f 100644
--- a/packages/yasnippet/NEWS
+++ b/packages/yasnippet/NEWS
@@ -1,8 +1,82 @@
 Yasnippet NEWS -- history of user-visible changes.
 
-Copyright (C) 2017-2018 Free Software Foundation, Inc.
+Copyright (C) 2017-2019 Free Software Foundation, Inc.
 See the end of the file for license conditions.
 
+* 0.14.0 (Dec 22, 2019)
+
+** Changes
+
+*** New 'yas-auto-next' macro, automatically moves to next field.
+See Github #937.
+
+*** Yasnippet now officially requires Emacs 23 or greater.
+See Github #940.
+
+*** Snippets for 'fundamental-mode' are available in all modes.
+See Github #949, and #936.
+
+*** New function for snippets, 'yas-completing-read'.
+See Github #934.
+
+*** New function 'yas-maybe-expand-abbrev-key-filter'.
+This can be used for making conditional keybindings for snippets.
+Promoted from 'yas--maybe-expand-key-filter'.  See Github #943.
+
+*** DEL can now be used to clear fields, similar <delete>.
+It is bound to the new conditional command 'yas-maybe-clear-field', which may
+be bound to other keys as well.  See Github #960 and #957.
+
+*** Snippet field movement commands may now trigger eldoc.
+See Github #952.
+
+*** New variable 'yas-keymap-disable-hook'.
+Can be used (e.g., for company-mode) to temporarily disable
+'yas-keymap' bindings, or any binding made by the new function
+'yas-filtered-definition'.  See Github #987.
+
+*** New variable 'yas-inhibit-overlay-modification-protection'.
+This allows a snippet to remain active, even if some commands make
+modifications outside the expected area (i.e., the active snippet
+field).
+
+*** 'yas-minor-mode' is no longer enabled in temp buffers.
+That is, buffers whose name starts with a space.  This setting may be
+undone by removing 'yas-temp-buffer-p' from
+'yas-dont-activate-functions'.  See Github #985.
+
+*** Accept unescaped '{', for LSP compatibility.
+See Github #979.
+
+** Fixed bugs
+
+*** 'yas-not-string-or-comment-condition' no longer relies on 'this-command'.
+This lets it work correctly with conditional key-bindings.  See Github
+#973, #991.
+
+*** Fix snippet expansion in org src buffers.
+Note that this still doesn't work in text-mode blocks.
+See Github #976, #989.
+
+*** Fix snippet insertion for keyless snippets.
+See Github #1014.
+
+*** Fix errors with company-mode completion within snippet fields.
+See Github #995.
+
+*** Fix errors with cc-mode.
+See Github #962.
+
+*** Fix problems with lsp-mode.
+**** Improve performance in overlay heavy buffers (Github #926).
+**** Fix double call of 'before/after-change-functions' (Github #966).
+
+*** Fix errors with nested snippet expansion.
+See Github #961, #1002.
+
+*** Stop yas-field-highlight-face inheriting from bogus 'quote' face.
+
+
 * 0.13.0 (May 13, 2018)
 
 ** Changes
diff --git a/packages/yasnippet/README.mdown b/packages/yasnippet/README.mdown
index 76772c8..b30d520 100644
--- a/packages/yasnippet/README.mdown
+++ b/packages/yasnippet/README.mdown
@@ -61,7 +61,7 @@ get some!
 1. [yasnippet-snippets] - a snippet collection package maintained by
     [AndreaCrotti](https://github.com/AndreaCrotti).
 
-    It can be installed with `M-x install-package RET
+    It can be installed with `M-x package-install RET
     yasnippet-snippets` if you have added MELPA to your package
     sources.
 
diff --git a/packages/yasnippet/doc/faq.org b/packages/yasnippet/doc/faq.org
index 9994e7b..6cff4d8 100644
--- a/packages/yasnippet/doc/faq.org
+++ b/packages/yasnippet/doc/faq.org
@@ -7,6 +7,16 @@
   the Github issue tracker.  It might be more up-to-date than this
   list.
 
+* Why are my snippet abbrev keys triggering when I don't want them too?
+Expansion of abbrev keys is controlled by 
[[sym:yas-key-syntaxes][=yas-key-syntaxes=]].  Try
+removing entries which correspond to the abbrev key character syntax.
+For example, if you have a snippet with abbrev key "bar", that you
+don't want to trigger when point follows the text =foo_bar=, remove
+the ="w"= entry (since "bar" has only word syntax characters).
+
+* Why aren't my snippet abbrev keys triggering when I want them too?
+See previous question, but in reverse.
+
 * Why is there an extra newline?
 
 If there is a newline at the end of a snippet definition file,
@@ -20,58 +30,39 @@ final newline automatically.
 
 * Why doesn't TAB navigation work with flyspell
 
-A workaround is to inhibit flyspell overlays while the snippet is
-active:
+This is [[https://debbugs.gnu.org/26672][Emacs Bug#26672]], so you should 
upgrade to version 25.3 or
+better.  Otherwise, a workaround is to inhibit flyspell overlays while
+the snippet is active:
 
 #+BEGIN_SRC emacs-lisp
   (add-hook 'flyspell-incorrect-hook
-            #'(lambda (dummy1 dummy2 dymmy3)
+            #'(lambda (&rest _)
                 (and yas-active-field-overlay
                      (overlay-buffer yas-active-field-overlay))))
 #+END_SRC
 
-This is apparently related to overlay priorities. For some reason, the
-=keymap= property of flyspell's overlays always takes priority over the
-same property in YASnippet's overlays, even if one sets the latter's
-=priority= property to something big. If you know emacs-lisp and can
-solve this problem, drop a line in the
-[[http://groups.google.com/group/smart-snippet][discussion group]].
-
 * How do I use alternative keys, i.e. not TAB?
 
-Edit the keymaps [[sym:yas-minor-mode-map][=yas-minor-mode-map=]] and
-[[sym:yas-keymap][=yas-keymap=]] as you would any other keymap:
+Edit the keymaps [[sym:yas-minor-mode-map][=yas-minor-mode-map=]] and 
[[sym:yas-keymap][=yas-keymap=]] as you would
+any other keymap, but use 
[[sym:yas-filtered-definition][=yas-filtered-definition=]] on the definition
+if you want to respect 
[[sym:yas-keymap-disable-hook][=yas-keymap-disable-hook=]]:
 
 #+begin_src emacs-lisp :exports code
-   (define-key yas-minor-mode-map (kbd "<tab>") nil)
-   (define-key yas-minor-mode-map (kbd "TAB") nil)
-   (define-key yas-minor-mode-map (kbd "<the new key>") yas-maybe-expand)
-
-   ;;keys for navigation
-   (define-key yas-keymap [(tab)]       nil)
-   (define-key yas-keymap (kbd "TAB")   nil)
-   (define-key yas-keymap [(shift tab)] nil)
-   (define-key yas-keymap [backtab]     nil)
-   (define-key yas-keymap (kbd "<new-next-field-key>") 
'yas-next-field-or-maybe-expand)
-   (define-key yas-keymap (kbd "<new-prev-field-key>") 'yas-prev)
+  (define-key yas-minor-mode-map (kbd "<tab>") nil)
+  (define-key yas-minor-mode-map (kbd "TAB") nil)
+  (define-key yas-minor-mode-map (kbd "<the new key>") yas-maybe-expand)
+
+  ;;keys for navigation
+  (define-key yas-keymap [(tab)]       nil)
+  (define-key yas-keymap (kbd "TAB")   nil)
+  (define-key yas-keymap [(shift tab)] nil)
+  (define-key yas-keymap [backtab]     nil)
+  (define-key yas-keymap (kbd "<new-next-field-key>")
+    (yas-filtered-definition 'yas-next-field-or-maybe-expand))
+  (define-key yas-keymap (kbd "<new-prev-field-key>")
+    (yas-filtered-definition 'yas-prev-field))
 #+end_src
 
-* How do I turn off the minor mode where in some buffers?
-
-The best way, since version 0.6.1c, is to set the default value of the
-variable [[sym:yas-dont-activate][=yas-dont-activate=]] to a lambda function 
like so:
-
-#+BEGIN_SRC emacs-lisp
-  (set-default 'yas-dont-activate
-               #'(lambda ()
-                   (and yas-root-directory
-                        (null (yas-get-snippet-tables)))))
-#+END_SRC
-
-This is also the default value starting for that version. It skips the
-minor mode in buffers where it is not applicable (no snippet tables),
-but only once you have setup your yas-root-directory.
-
 * How do I define an abbrev key containing characters not supported by the 
filesystem?
 
 -  *Note*: This question applies if you're still defining snippets
diff --git a/packages/yasnippet/doc/snippet-development.org 
b/packages/yasnippet/doc/snippet-development.org
index 9112cd0..806f82e 100644
--- a/packages/yasnippet/doc/snippet-development.org
+++ b/packages/yasnippet/doc/snippet-development.org
@@ -8,7 +8,7 @@
 
 There are some ways you can quickly find a snippet file or create a new one:
 
--  =M-x yas-new-snippet=, key bindind: =C-c & C-n=
+-  =M-x yas-new-snippet=, key binding: =C-c & C-n=
 
    Creates a new buffer with a template for making a new snippet.  The
    buffer is in =snippet-mode= (see [[snippet-mode][below]]).  When you are 
done editing
@@ -62,7 +62,7 @@ expanded.
 Optionally, if the file contains a line of =# --=, the lines above it
 count as comments, some of which can be /directives/ (or meta data).
 Snippet directives look like =# property: value= and tweak certain
-snippets properties described below. If no =# --= is found, the whole
+snippet properties described below. If no =# --= is found, the whole
 file is considered the snippet template.
 
 Here's a typical example:
@@ -94,7 +94,7 @@ was loaded from.
 
 ** =# condition:= snippet condition
 
-This is a piece of Emacs-lisp code. If a snippet has a condition, then
+This is a piece of Emacs Lisp code. If a snippet has a condition, then
 it will only be expanded when the condition code evaluate to some
 non-nil value.
 
@@ -104,7 +104,7 @@ See also 
[[sym:yas-buffer-local-condition][=yas-buffer-local-condition=]] in
 ** =# group:= snippet menu grouping
 
 When expanding/visiting snippets from the menu-bar menu, snippets for a
-given mode can be grouped into sub-menus . This is useful if one has too
+given mode can be grouped into sub-menus. This is useful if one has too
 many snippets for a mode which will make the menu too long.
 
 The =# group:= property only affect menu construction (See
@@ -113,14 +113,14 @@ achieved by grouping snippets into sub-directories and 
using the
 =.yas-make-groups= special file (for this see
 [[./snippet-organization.org][Organizing Snippets]]
 
-Refer to the bundled snippets for =ruby-mode= for examples on the
+Refer to the bundled snippets for =ruby-mode= for examples of the
 =# group:= directive. Group can also be nested, e.g.
-=control structure.loops= tells that the snippet is under the =loops=
+=control structure.loops= indicates that the snippet is under the =loops=
 group which is under the =control structure= group.
 
 ** =# expand-env:= expand environment
 
-This is another piece of Emacs-lisp code in the form of a =let= /varlist
+This is another piece of Emacs Lisp code in the form of a =let= /varlist
 form/, i.e. a list of lists assigning values to variables. It can be
 used to override variable values while the snippet is being expanded.
 
@@ -154,9 +154,9 @@ You can use this directive to expand a snippet directly 
from a normal
 Emacs keybinding. The keybinding will be registered in the Emacs keymap
 named after the major mode the snippet is active for.
 
-Additionally a variable [[sym:yas-prefix][=yas-prefix=]] is set to to the 
prefix argument
+Additionally a variable [[sym:yas-prefix][=yas-prefix=]] is set to the prefix 
argument
 you normally use for a command. This allows for small variations on the
-same snippet, for example in this "html-mode" snippet.
+same snippet, for example in this =html-mode= snippet.
 
 #+BEGIN_SRC snippet
   # name: <p>...</p>
@@ -172,7 +172,7 @@ will expand the paragraph tag without newlines.
 ** =# type:= =snippet= or =command=
 
 If the =type= directive is set to =command=, the body of the snippet
-is interpreted as lisp code to be evaluated when the snippet is
+is interpreted as Lisp code to be evaluated when the snippet is
 triggered.
 
 If it's =snippet= (the default when there is no =type= directive), the
@@ -202,14 +202,14 @@ usually interpreted as plain text, except =$= and =`=. 
You need to
 use =\= to escape them: =\$= and =\`=. The =\= itself may also needed to be
 escaped as =\\= sometimes.
 
-** Embedded Emacs-lisp code
+** Embedded Emacs Lisp code
 
-Emacs-Lisp code can be embedded inside the template, written inside
-back-quotes (=`=). The lisp forms are evaluated when the snippet is
+Emacs Lisp code can be embedded inside the template, written inside
+back-quotes (=`=). The Lisp forms are evaluated when the snippet is
 being expanded. The evaluation is done in the same buffer as the
 snippet being expanded.
 
-Here's an example for c-mode to calculate the header file guard
+Here's an example for =c-mode= to calculate the header file guard
 dynamically:
 
 #+BEGIN_SRC snippet
@@ -221,8 +221,8 @@ dynamically:
   #endif /* $1 */
 #+END_SRC
 
-From version 0.6, snippets expansions are run with some special
-Emacs-lisp variables bound. One of this is 
[[sym:yas-selected-text][=yas-selected-text=]]. You can
+From version 0.6, snippet expansions are run with some special
+Emacs Lisp variables bound. One of these is 
[[sym:yas-selected-text][=yas-selected-text=]]. You can
 therefore define a snippet like:
 
 #+BEGIN_SRC snippet
@@ -237,7 +237,7 @@ Alternatively, you can also customize the variable
 
 *** Note: backquote expressions should not modify the buffer
 
-Please note that the lisp forms in backquotes should *not* modify the
+Please note that the Lisp forms in backquotes should *not* modify the
 buffer, doing so will trigger a warning.  For example, instead of
 doing
 
@@ -284,7 +284,7 @@ The number can be omitted if you don't want to create 
[[mirrors-fields][mirrors]
 
 ** Mirrors <<mirrors-fields>>
 
-We refer the tab stops with placeholders as a /field/.  A field can
+We refer to tab stops with placeholders as a /field/.  A field can
 have mirrors.  *All* mirrors get updated whenever you update any field
 text.  Here's an example:
 
@@ -299,15 +299,15 @@ also be inserted at =\end{$1}=. The best explanation is 
to see the
 screencast([[http://www.youtube.com/watch?v=vOj7btx3ATg][YouTube]] or 
[[http://yasnippet.googlecode.com/files/yasnippet.avi][avi video]]).
 
 The tab stops with the same number to the field act as its mirrors. If
-none of the tab stops has an initial value, the first one is selected as
-the field and others mirrors.
+none of the tab stops have an initial value, the first one is selected as
+the field and the others are its mirrors.
 
 ** Mirrors with transformations <<mirror-transformations>>
 
 If the value of an =${n:=-construct starts with and contains =$(=,
 then it is interpreted as a mirror for field =n= with a
 transformation. The mirror's text content is calculated according to
-this transformation, which is Emacs-lisp code that gets evaluated in
+this transformation, which is Emacs Lisp code that gets evaluated in
 an environment where the variable [[sym:yas-text][=yas-text=]] is bound to the 
text
 content (string) contained in the field =n=. Here's an example for
 Objective-C:
@@ -378,7 +378,7 @@ due to incomplete format codes.
 
 ** Fields with transformations
 
-From version 0.6 on, you can also have lisp transformation inside
+From version 0.6 on, you can also have Lisp transformation inside
 fields. These work mostly like mirror transformations. However, they
 are evaluated when you first enter the field, after each change you
 make to the field and also just before you exit the field.
@@ -412,25 +412,38 @@ the field, and with some useful variables bound, notably
 can place a transformation in the primary field that lets you select
 default values for it.
 
-The [[sym:yas-choose-value][=yas-choose-value=]] does this work for you. For 
example:
+For example, the [[sym:yas-choose-value][=yas-completing-read=]] function is 
version of
+=completing-read= which checks these variables.  For example, asking
+the user for the initial value of a field:
 
 #+BEGIN_SRC snippet
-  <div align="${2:$$(yas-choose-value '("right" "center" "left"))}">
+  <div align="${2:$$(yas-completing-read "Alignment? " '("right" "center" 
"left"))}">
     $0
   </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-completing-read=]] 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:
 
-Here's another use, for LaTeX-mode, which calls reftex-label just as you
+#+BEGIN_SRC snippet
+  <div align="${2:$$(yas-auto-next
+                      (yas-completing-read
+                        "Alignment? "
+                        '("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.
 
 #+BEGIN_SRC snippet
   \section{${1:"Titel der Tour"}}%
   \index{$1}%
-  \label{{2:"waiting for reftex-label call..."$(unless yas-modified-p 
(reftex-label nil 'dont-
-  insert))}}%
+  \label{{2:"waiting for reftex-label call..."$(unless yas-modified-p 
(reftex-label nil 'dont-insert))}}%
 #+END_SRC
 
 The function [[sym:yas-verify-value][=yas-verify-value=]] has another neat 
trick, and makes use
diff --git a/packages/yasnippet/doc/snippet-expansion.org 
b/packages/yasnippet/doc/snippet-expansion.org
index a699d57..0a00981 100644
--- a/packages/yasnippet/doc/snippet-expansion.org
+++ b/packages/yasnippet/doc/snippet-expansion.org
@@ -161,11 +161,13 @@ In particular, the following things matter:
    =M-x describe-variable RET major-mode RET= to find out which major
    mode you are in currently.
 
--  Parent tables
+- Parent tables
 
-   Snippet tables defined as the parent of some other eligible table are
-   also considered. This works recursively, i.e. parents of parents of
-   eligible tables are also considered.
+  Snippet tables defined as the parent of some other eligible table
+  are also considered.  This works recursively, i.e., parents of
+  parents of eligible tables are also considered.  As a special case,
+  if a mode doesn't have a parent, then =fundamental-mode= is
+  considered to be its parent.
 
 -  Buffer-local list of extra modes
 
diff --git a/packages/yasnippet/doc/snippet-organization.org 
b/packages/yasnippet/doc/snippet-organization.org
index 22d3e46..6b8feef 100644
--- a/packages/yasnippet/doc/snippet-organization.org
+++ b/packages/yasnippet/doc/snippet-organization.org
@@ -33,7 +33,7 @@
    The default considers:
 
     - a personal collection that lives in =~/.emacs.d/snippets=
-    - the bundled collection, taken as a relative path to =yasnippet.el= 
localtion
+    - the bundled collection, taken as a relative path to =yasnippet.el= 
location
 
    When you come across other snippet collections, do the following to try them
    out:
diff --git a/packages/yasnippet/yasnippet-debug.el 
b/packages/yasnippet/yasnippet-debug.el
index abce89c..d33e8a5 100644
--- a/packages/yasnippet/yasnippet-debug.el
+++ b/packages/yasnippet/yasnippet-debug.el
@@ -141,7 +141,9 @@
          (decorator-end (overlay-get ov 'after-string))
          (beg (yas-debug-ov-fom-start range))
          (end (yas-debug-ov-fom-end range)))
-    (if (and beg end (not (integerp beg)) (not (integerp end)))
+    (if (and beg end (or (overlayp range)
+                         (and (not (integerp beg))
+                              (not (integerp end)))))
         (propertize (format "from %d to %d" (+ beg) (+ end))
                     'cursor-sensor-functions
                     `(,(lambda (_window _oldpos dir)
@@ -155,7 +157,7 @@
       "<dead>")))
 
 (defmacro yas-debug-with-tracebuf (outbuf &rest body)
-  (declare (indent 1))
+  (declare (indent 1) (debug (sexp body)))
   (let ((tracebuf-var (make-symbol "tracebuf")))
     `(let ((,tracebuf-var (or ,outbuf (get-buffer-create "*YASnippet 
trace*"))))
        (unless (eq ,tracebuf-var (current-buffer))
@@ -252,6 +254,8 @@ buffer-locally, otherwise install it globally.  If HOOK is
             (setq yas-debug-target-snippets
                   (cl-delete-if-not #'yas--snippet-p 
yas-debug-target-snippets)))
           (let ((yas-debug-recently-live-indicators nil))
+            (printf "(length yas--snippets-snippets) => %d\n"
+                    (length yas--active-snippets))
             (dolist (snippet (or yas-debug-target-snippets
                                  (yas-active-snippets)))
               (printf "snippet %d\n" (yas--snippet-id snippet))
diff --git a/packages/yasnippet/yasnippet-tests.el 
b/packages/yasnippet/yasnippet-tests.el
index 6048467..f7ca2bb 100644
--- a/packages/yasnippet/yasnippet-tests.el
+++ b/packages/yasnippet/yasnippet-tests.el
@@ -193,6 +193,20 @@ attention to case differences."
     (should (string= (yas--buffer-contents)
                      "bla from another BLA"))))
 
+(ert-deftest yas-mirror-many-fields ()
+  (with-temp-buffer
+    (yas-minor-mode 1)
+    (yas-expand-snippet "${1:brother} and ${2:brother} are${1:$(if (string= 
(yas-field-value 1) (yas-field-value 2)) \" \" \" not \")}the same word")
+    (should (string= (yas--buffer-contents)
+                     "brother and brother are the same word"))
+    (yas-mock-insert "bla")
+    (should (string= (yas--buffer-contents)
+                     "bla and brother are not the same word"))
+    (ert-simulate-command '(yas-next-field-or-maybe-expand))
+    (yas-mock-insert "bla")
+    (should (string= (yas--buffer-contents)
+                     "bla and bla are the same word"))))
+
 (ert-deftest mirror-with-transformation-and-autofill ()
   "Test interaction of autofill with mirror transforms"
   (let ((words "one two three four five")
@@ -332,6 +346,31 @@ attention to case differences."
         (ert-simulate-command '(undo))  ; Redo (re-expand snippet).
         (should (string-match-p "\\`one,and done" (buffer-string)))))))
 
+(ert-deftest undo-revive-and-do-again ()
+  "Check undo-revived snippet is properly ended."
+  ;; See https://github.com/joaotavora/yasnippet/issues/1006.
+  (yas-with-snippet-dirs '((".emacs.d/snippets"
+                            ("emacs-lisp-mode" ("x" . "${1:one},and done"))))
+    (with-temp-buffer
+      (emacs-lisp-mode)
+      (yas-reload-all)
+      (yas-minor-mode 1)
+      (yas-expand-snippet "x$0")
+      (setq buffer-undo-list nil)
+      (ert-simulate-command '(yas-expand))
+      (push nil buffer-undo-list)
+      (ert-simulate-command '(yas-next-field)) ; $1 -> exit snippet.
+      (should (string-match-p "\\`one,and done" (buffer-string)))
+      (push nil buffer-undo-list)
+      (ert-simulate-command '(undo))    ; Revive snippet.
+      (yas-mock-insert "abc")
+      (ert-simulate-command '(yas-next-field)) ; $1 -> exit snippet again.
+      (should (string-match-p "\\`abc,and done" (buffer-string)))
+      ;; We should have exited snippet and cleaned up any overlays.
+      (should-not (cl-some (lambda (o) (overlay-get o 'yas--snippet))
+                           (overlays-in (point-min) (point-max)))))))
+
+
 (defun yas-test-expand-and-undo (mode snippet-entry initial-contents)
   (yas-with-snippet-dirs
    `((".emacs.d/snippets" (,(symbol-name mode) ,snippet-entry)))
@@ -556,6 +595,22 @@ int foo()
   }
 }" (buffer-string)))))
 
+(ert-deftest indent-cc-mode-2 ()
+  "Handling of cc-mode's preprocessor indentation."
+  (with-temp-buffer
+    (c-mode)
+    (yas-minor-mode +1)
+    (yas-expand-snippet "\
+#ifndef `\"FOO\"`
+#define FOO
+#endif
+")
+    (should (string= "\
+#ifndef FOO
+#define FOO
+#endif
+" (buffer-substring-no-properties (point-min) (point-max))))))
+
 (ert-deftest indent-snippet-mode ()
   "Handling of snippet-mode indentation."
   ;; This is an interesting case because newlines match [[:space:]] in
@@ -578,6 +633,28 @@ int foo()
     ;; Assuming 2 space indent.
     (should (string= "def xxx\n  xxx\nend" (buffer-string)))))
 
+(defun yas-test-delete-and-insert-command (beg end new)
+  "Simulate a completion command (similar to company-mode)."
+  (interactive "r\ns")
+  ;; Simulate a completion command (like what company-mode does)
+  ;; which deletes the "xxx" and then replaces it with something
+  ;; else.
+  (delete-region beg end)
+  (insert new))
+
+(ert-deftest indent-mirrors-on-complex-update ()
+  "Don't get messed up by command that deletes and then inserts."
+  (with-temp-buffer
+    (ruby-mode)
+    (yas-minor-mode 1)
+    (yas-expand-snippet "def foo\n  ${1:slice} = append($1)\nend")
+    (yas-mock-insert "xxx")
+    (ert-simulate-command `(yas-test-delete-and-insert-command
+                            ,(- (point) 3) ,(point) ,"yyy"))
+    ;; Assuming 2 space indent.
+    (should (string= "def foo\n  yyy = append(yyy)\nend" (buffer-string)))))
+
+
 
 (ert-deftest snippet-with-multiline-mirrors-issue-665 ()
   "In issue 665, a multi-line mirror is attempted."
@@ -603,6 +680,34 @@ 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")))
+                                         "} ${2:$$"
+                                         (prin1-to-string '(yas-auto-next
+                                                            (yas-choose-value
+                                                             "too" "foo")))
+                                         "} baz ${3: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 too baz quux quinn" (buffer-string)))))))
+
 
 ;;; Snippet expansion and character escaping
 ;;; Thanks to @zw963 (Billy) for the testing
@@ -676,6 +781,20 @@ mapconcat #'(lambda (arg)
       (yas-expand-snippet "Look ma! ${1:`(yas-selected-text)`} OK?")
       (should (string= (yas--buffer-contents) "Look ma! He)}o world! OK?")))))
 
+(ert-deftest escaping-for-lsp-style-snippet-syntax ()
+  "See Github #979."
+  (should
+   (string= (with-temp-buffer
+              (yas-minor-mode 1)
+              (yas-expand-snippet
+               "Printf(${1:format string}, ${2:args ...interface{\\}})${0}")
+              (yas--buffer-contents))
+            (with-temp-buffer
+              (yas-minor-mode 1)
+              (yas-expand-snippet
+               "Printf(${1:format string}, ${2:args ...interface\\{\\}})${0}")
+              (yas--buffer-contents)))))
+
 (ert-deftest insert-snippet-with-backslashes-in-active-field ()
   ;; This test case fails if `yas--inhibit-overlay-hooks' is not bound
   ;; in `yas-expand-snippet' (see Github #844).
@@ -754,10 +873,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)
@@ -948,7 +1063,7 @@ hello ${1:$(when (stringp yas-text) (funcall func 
yas-text))} foo${1:$$(concat \
            ("'quote" . "OKquoteOK"))))
        (yas-reload-all)
        (emacs-lisp-mode)
-       (yas-minor-mode-on)
+       (yas-minor-mode +1)
        (let ((yas-key-syntaxes '("w" "w_")))
          (let ((yas--barbaz t))
            (yas-should-expand '(("foo-barbaz" . "foo-OKbarbazOK")
@@ -1030,6 +1145,47 @@ hello ${1:$(when (stringp yas-text) (funcall func 
yas-text))} foo${1:$$(concat \
       (ert-simulate-command '(yas-next-field-or-maybe-expand))
       (should (string= (buffer-string) "\\sqrt[3]{\\sqrt[5]{2}}")))))
 
+(ert-deftest nested-snippet-expansion-4 ()
+  "See Github #959."
+  (let ((yas-triggers-in-field t))
+    (yas-with-snippet-dirs
+     '((".emacs.d/snippets"
+        ("text-mode"
+         ("ch" . "<-${1:ch}"))))
+     (yas-reload-all)
+     (text-mode)
+     (yas-minor-mode +1)
+     (yas-expand-snippet "ch$0\n")
+     (ert-simulate-command '(yas-expand))
+     (ert-simulate-command '(forward-char 2))
+     (ert-simulate-command '(yas-expand))
+     (yas-mock-insert "abc")
+     (ert-simulate-command '(yas-next-field-or-maybe-expand))
+     (yas-mock-insert "def")
+     (ert-simulate-command '(yas-next-field-or-maybe-expand))
+     (should (string= (buffer-string) "<-<-abcdef\n")))))
+
+(ert-deftest nested-snippet-expansion-5-nested-delete ()
+  "See Github #996."
+  (let ((yas-triggers-in-field t))
+    (yas-with-snippet-dirs
+     '((".emacs.d/snippets"
+        ("text-mode"
+         ("sel" . "${1:ch}")
+         ("ch" . "<-${1:ch}"))))
+     (yas-reload-all)
+     (text-mode)
+     (yas-minor-mode +1)
+     (insert "sel")
+     (ert-simulate-command '(yas-expand))
+     (ert-simulate-command '(forward-word 1))
+     (ert-simulate-command '(yas-expand))
+     (ert-simulate-command '(forward-word 1))
+     ;; The (cl-assert (memq pfield (yas--snippet-fields psnippet)))
+     ;; in `yas--on-field-overlay-modification' failed here.
+     (ert-simulate-command '(delete-backward-char 1))
+     (should (string= (buffer-string) "<-c\n")))))
+
 
 ;;; Loading
 ;;;
@@ -1190,7 +1346,8 @@ hello ${1:$(when (stringp yas-text) (funcall func 
yas-text))} foo${1:$$(concat \
      (yas-reload-all)
      (with-temp-buffer
        (let* ((major-mode 'c-mode)
-              (expected `(c-mode
+              (expected `(fundamental-mode
+                          c-mode
                           cc-mode
                           yet-another-c-mode
                           and-also-this-one
@@ -1243,7 +1400,8 @@ hello ${1:$(when (stringp yas-text) (funcall func 
yas-text))} foo${1:$$(concat \
                          (yas-reload-all)
                          (with-temp-buffer
                            (let* ((major-mode 'yas--test-mode)
-                                  (expected `(c-mode
+                                  (expected `(fundamental-mode
+                                              c-mode
                                               ,@(if (fboundp 'prog-mode)
                                                     '(prog-mode))
                                               yas--phony-c-mode
@@ -1495,17 +1653,35 @@ TODO: be meaner"
       (should (eq (key-binding [(tab)]) 'yas-expand))
       (should (eq (key-binding (kbd "TAB")) 'yas-expand))))))
 
-(ert-deftest yas-org-native-tab-in-source-block ()
+(ert-deftest yas-org-native-tab-in-source-block-text ()
+  "Test expansion of snippets in org source blocks."
+  ;; org 9+ no longer runs fontification for text-mode, so our hacks
+  ;; don't work.  Note that old ert doesn't have skipping, so we have
+  ;; to expect failure instead.
+  :expected-result (if (and (fboundp 'org-in-src-block-p)
+                            (version< (org-version) "9"))
+                       :passed :failed)
+  (let ((text-mode-hook #'yas-minor-mode))
+    (do-yas-org-native-tab-in-source-block "text")))
+
+(ert-deftest yas-org-native-tab-in-source-block-emacs-lisp ()
   "Test expansion of snippets in org source blocks."
-  :expected-result (if (and (fboundp 'org-in-src-block-p) (version< 
(org-version) "9"))
+  :expected-result (if (fboundp 'org-in-src-block-p)
                        :passed :failed)
+  (let ((emacs-lisp-mode-hook #'yas-minor-mode)
+        ;; This makes the test a bit less comprehensive, but it's
+        ;; needed to avoid bumping into Emacs Bug#35264.
+        (org-src-preserve-indentation t))
+    (do-yas-org-native-tab-in-source-block "emacs-lisp")))
+
+(defun do-yas-org-native-tab-in-source-block (mode)
   (yas-saving-variables
    (yas-with-snippet-dirs
-    '((".emacs.d/snippets"
-       ("text-mode"
+    `((".emacs.d/snippets"
+       (,(concat mode "-mode")
         ("T" . "${1:one} $1\n${2:two} $2\n<<$0>> done!"))))
-    (let ((text-mode-hook '(yas-minor-mode))
-          (org-src-tab-acts-natively t)
+    ;; Binding both text and prog mode hook should cover everything.
+    (let ((org-src-tab-acts-natively t)
           ;; Org 8.x requires this in order for
           ;; `org-src-tab-acts-natively' to have effect.
           (org-src-fontify-natively t))
@@ -1514,7 +1690,7 @@ TODO: be meaner"
       (yas--with-font-locked-temp-buffer
        (org-mode)
        (yas-minor-mode 1)
-       (insert "#+BEGIN_SRC text\nT\n#+END_SRC")
+       (insert "#+BEGIN_SRC " mode "\nT\n#+END_SRC")
        (if (fboundp 'font-lock-ensure)
            (font-lock-ensure)
          (jit-lock-fontify-now))
@@ -1530,9 +1706,9 @@ TODO: be meaner"
        ;; Check snippet expansion, ignore leading whitespace due to
        ;; `org-edit-src-content-indentation'.
        (should (looking-at "\
-[[:space:]]*one one
-[[:space:]]*two two
-[[:space:]]*<<>> done!")))))))
+\[[:space:]]*one one
+\[[:space:]]*two two
+\[[:space:]]*<<>> done!")))))))
 
 
 (ert-deftest test-yas-activate-extra-modes ()
@@ -1548,7 +1724,7 @@ add the snippets associated with the given mode."
            ("car" . "(car )"))))
        (yas-reload-all)
        (emacs-lisp-mode)
-       (yas-minor-mode-on)
+       (yas-minor-mode +1)
        (yas-activate-extra-mode 'markdown-mode)
        (should (eq 'markdown-mode (car yas--extra-modes)))
        (yas-should-expand '(("_" . "_Text_ ")))
diff --git a/packages/yasnippet/yasnippet.el b/packages/yasnippet/yasnippet.el
index c3020bf..e0b5537 100644
--- a/packages/yasnippet/yasnippet.el
+++ b/packages/yasnippet/yasnippet.el
@@ -5,7 +5,7 @@
 ;;          João Távora <address@hidden>,
 ;;          Noam Postavsky <address@hidden>
 ;; Maintainer: Noam Postavsky <address@hidden>
-;; Version: 0.13.0
+;; Version: 0.14.0
 ;; X-URL: http://github.com/joaotavora/yasnippet
 ;; Keywords: convenience, emulation
 ;; URL: http://github.com/joaotavora/yasnippet
@@ -132,6 +132,7 @@
 ;;; Code:
 
 (require 'cl-lib)
+(require 'eldoc) ; Needed for 24.
 (declare-function cl-progv-after "cl-extra") ; Needed for 23.4.
 (require 'easymenu)
 (require 'help-mode)
@@ -159,7 +160,7 @@
 
 (defconst yas-installed-snippets-dir (expand-file-name "snippets" 
yas--loaddir))
 (make-obsolete-variable 'yas-installed-snippets-dir "\
-Yasnippet no longer comes with installed snippets" "0.13")
+Yasnippet no longer comes with installed snippets" "0.14")
 
 (defconst yas--default-user-snippets-dir
   (expand-file-name "snippets" user-emacs-directory))
@@ -385,7 +386,7 @@ It must be set to nil before loading yasnippet to take 
effect."
 ;; Only two faces, and one of them shouldn't even be used...
 ;;
 (defface yas-field-highlight-face
-  '((t (:inherit 'region)))
+  '((t (:inherit region)))
   "The face used to highlight the currently active field of a snippet")
 
 (defface yas--field-debug-face
@@ -401,16 +402,35 @@ It must be set to nil before loading yasnippet to take 
effect."
   "A conditional key definition.
 This can be used as a key definition in keymaps to bind a key to
 `yas-skip-and-clear-field' only when at the beginning of an
-unmodified snippey field.")
-
-(defvar yas-keymap  (let ((map (make-sparse-keymap)))
-                      (define-key map [(tab)]       
'yas-next-field-or-maybe-expand)
-                      (define-key map (kbd "TAB")   
'yas-next-field-or-maybe-expand)
-                      (define-key map [(shift tab)] 'yas-prev-field)
-                      (define-key map [backtab]     'yas-prev-field)
-                      (define-key map (kbd "C-g")   'yas-abort-snippet)
-                      (define-key map (kbd "C-d")   
yas-maybe-skip-and-clear-field)
-                      map)
+unmodified snippet field.")
+
+(defconst yas-maybe-clear-field
+    '(menu-item "" yas-clear-field
+                :filter yas--maybe-clear-field-filter)
+    "A conditional key definition.
+This can be used as a key definition in keymaps to bind a key to
+`yas-clear-field' only when at the beginning of an
+unmodified snippet field.")
+
+(defun yas-filtered-definition (def)
+  "Return a condition key definition.
+The condition will respect the value of `yas-keymap-disable-hook'."
+  `(menu-item "" ,def
+              :filter ,(lambda (cmd) (unless (run-hook-with-args-until-success
+                                         'yas-keymap-disable-hook)
+                                  cmd))))
+
+(defvar yas-keymap
+  (let ((map (make-sparse-keymap)))
+    (define-key map [(tab)]       (yas-filtered-definition 
'yas-next-field-or-maybe-expand))
+    (define-key map (kbd "TAB")   (yas-filtered-definition 
'yas-next-field-or-maybe-expand))
+    (define-key map [(shift tab)] (yas-filtered-definition 'yas-prev-field))
+    (define-key map [backtab]     (yas-filtered-definition 'yas-prev-field))
+    (define-key map (kbd "C-g")   (yas-filtered-definition 'yas-abort-snippet))
+    ;; Yes, filters can be chained!
+    (define-key map (kbd "C-d")   (yas-filtered-definition 
yas-maybe-skip-and-clear-field))
+    (define-key map (kbd "DEL")   (yas-filtered-definition 
yas-maybe-clear-field))
+    map)
   "The active keymap while a snippet expansion is in progress.")
 
 (defvar yas-key-syntaxes (list #'yas-try-key-from-whitespace
@@ -441,7 +461,7 @@ are looked for first. Failing that, longer keys composed of
 \"word\" or \"symbol\" syntax are looked for. Therefore,
 triggering after
 
-foo-bar
+foo-barbaz
 
 will, according to the \"w\" element first try \"barbaz\". If
 that isn't a trigger key, \"foo-barbaz\" is tried, respecting the
@@ -470,10 +490,8 @@ Attention: These hooks are not run when exiting 
nested/stacked snippet expansion
   "Hooks to run just before expanding a snippet.")
 
 (defconst yas-not-string-or-comment-condition
-  '(if (and (let ((ppss (syntax-ppss)))
-              (or (nth 3 ppss) (nth 4 ppss)))
-            (memq this-command '(yas-expand yas-expand-from-trigger-key
-                                            yas-expand-from-keymap)))
+  '(if (let ((ppss (syntax-ppss)))
+         (or (nth 3 ppss) (nth 4 ppss)))
        '(require-snippet-condition . force-in-comment)
      t)
   "Disables snippet expansion in strings and comments.
@@ -536,16 +554,32 @@ conditions.
     (const :tag "Disable all snippet expansion" nil)
     sexp))
 
+(defcustom yas-keymap-disable-hook nil
+  "The `yas-keymap' bindings are disabled if any function in this list returns 
non-nil.
+This is useful to control whether snippet navigation bindings
+override bindings from other packages (e.g., `company-mode')."
+  :type 'hook)
+
 (defcustom yas-overlay-priority 100
   "Priority to use for yasnippets overlays.
 This is useful to control whether snippet navigation bindings
-override bindings from other packages (e.g., `company-mode')."
+override `keymap' overlay property bindings from other packages."
   :type 'integer)
 
+(defcustom yas-inhibit-overlay-modification-protection nil
+  "If nil, changing text outside the active field aborts the snippet.
+This protection is intended to prevent yasnippet from ending up
+in an inconsistent state.  However, some packages (e.g., the
+company completion package) may trigger this protection when it
+is not needed.  In that case, setting this variable to non-nil
+can be useful."
+  ;; See also `yas--on-protection-overlay-modification'.
+  :type 'boolean)
+
 
 ;;; Internal variables
 
-(defconst yas--version "0.13.0")
+(defconst yas--version "0.14.0")
 
 (defvar yas--menu-table (make-hash-table)
   "A hash table of MAJOR-MODE symbols to menu keymaps.")
@@ -617,21 +651,24 @@ override bindings from other packages (e.g., 
`company-mode')."
 
 ;;; Minor mode stuff
 
-;; XXX: `last-buffer-undo-list' is somehow needed in Carbon Emacs for MacOSX
-(defvar last-buffer-undo-list nil)
-
 (defvar yas--minor-mode-menu nil
   "Holds the YASnippet menu.")
 
 (defvar yas--condition-cache-timestamp nil)
 
-(defun yas--maybe-expand-key-filter (cmd)
+(defun yas-maybe-expand-abbrev-key-filter (cmd)
+  "Return CMD if there is an expandable snippet at point.
+This function is useful as a `:filter' to a conditional key
+definition."
   (when (let ((yas--condition-cache-timestamp (current-time)))
           (yas--templates-for-key-at-point))
     cmd))
 
+(define-obsolete-function-alias 'yas--maybe-expand-key-filter
+  #'yas-maybe-expand-abbrev-key-filter "0.14")
+
 (defconst yas-maybe-expand
-  '(menu-item "" yas-expand :filter yas--maybe-expand-key-filter)
+  '(menu-item "" yas-expand :filter yas-maybe-expand-abbrev-key-filter)
   "A conditional key definition.
 This can be used as a key definition in keymaps to bind a key to
 `yas-expand' only when there is a snippet available to be
@@ -803,7 +840,10 @@ which decides on the snippet to expand.")
          (yas--dfs
           (lambda (mode)
             (cl-loop for neighbour
-                     in (cl-list* (get mode 'derived-mode-parent)
+                     in (cl-list* (or (get mode 'derived-mode-parent)
+                                      ;; Consider `fundamental-mode'
+                                      ;; as ultimate ancestor.
+                                      'fundamental-mode)
                                   ;; NOTE: `fboundp' check is redundant
                                   ;; since Emacs 24.4.
                                   (and (fboundp mode) (symbol-function mode))
@@ -901,9 +941,12 @@ activate snippets associated with that mode."
        (remove mode
                yas--extra-modes)))
 
+(defun yas-temp-buffer-p (&optional buffer)
+  (eq (aref (buffer-name buffer) 0) ?\s))
+
 (define-obsolete-variable-alias 'yas-dont-activate
   'yas-dont-activate-functions "0.9.2")
-(defvar yas-dont-activate-functions (list #'minibufferp)
+(defvar yas-dont-activate-functions (list #'minibufferp #'yas-temp-buffer-p)
   "Special hook to control which buffers `yas-global-mode' affects.
 Functions are called with no argument, and should return non-nil to prevent
 `yas-global-mode' from enabling yasnippet in this buffer.
@@ -1356,6 +1399,9 @@ conditions to filter out potential expansions."
                                 (push (cons name template) acc))
                             namehash))
                (yas--table-hash table))
+      (maphash #'(lambda (uuid template)
+                   (push (cons uuid template) acc))
+               (yas--table-uuidhash table))
       (yas--filter-templates-by-condition acc))))
 
 (defun yas--templates-for-key-at-point ()
@@ -1648,10 +1694,8 @@ Here's a list of currently recognized directives:
         (let ((where (if (region-active-p)
                          (cons (region-beginning) (region-end))
                        (cons (point) (point)))))
-          (yas-expand-snippet (yas--template-content yas--current-template)
-                              (car where)
-                              (cdr where)
-                              (yas--template-expand-env 
yas--current-template)))))))
+          (yas-expand-snippet yas--current-template
+                              (car where) (cdr where)))))))
 
 (defun yas--key-from-desc (text)
   "Return a yasnippet key from a description string TEXT."
@@ -2328,6 +2372,10 @@ object satisfying `yas--field-p' to restrict the 
expansion to."
       (yas--fallback))))
 
 (defun yas--maybe-expand-from-keymap-filter (cmd)
+  "Check whether a snippet may be expanded.
+If there are expandable snippets, return CMD (this is useful for
+conditional keybindings) or the list of expandable snippet
+template objects if CMD is nil (this is useful as a more general predicate)."
   (let* ((yas--condition-cache-timestamp (current-time))
          (vec (cl-subseq (this-command-keys-vector)
                          (if current-prefix-arg
@@ -2352,14 +2400,12 @@ object satisfying `yas--field-p' to restrict the 
expansion to."
 Prompt the user if TEMPLATES has more than one element, else
 expand immediately.  Common gateway for
 `yas-expand-from-trigger-key' and `yas-expand-from-keymap'."
-  (let ((yas--current-template (or (and (cl-rest templates) ;; more than one
-                                        (yas--prompt-for-template (mapcar 
#'cdr templates)))
-                                   (cdar templates))))
+  (let ((yas--current-template
+         (or (and (cl-rest templates) ;; more than one
+                  (yas--prompt-for-template (mapcar #'cdr templates)))
+             (cdar templates))))
     (when yas--current-template
-      (yas-expand-snippet (yas--template-content yas--current-template)
-                          start
-                          end
-                          (yas--template-expand-env yas--current-template)))))
+      (yas-expand-snippet yas--current-template start end))))
 
 ;; Apropos the trigger key and the fallback binding:
 ;;
@@ -2504,10 +2550,7 @@ by condition."
                     (cons (region-beginning) (region-end))
                   (cons (point) (point)))))
     (if yas--current-template
-        (yas-expand-snippet (yas--template-content yas--current-template)
-                            (car where)
-                            (cdr where)
-                            (yas--template-expand-env yas--current-template))
+        (yas-expand-snippet yas--current-template (car where) (cdr where))
       (yas--message 1 "No snippets can be inserted here!"))))
 
 (defun yas-visit-snippet-file ()
@@ -2795,17 +2838,17 @@ DEBUG is for debugging the YASnippet engine itself."
                                    :name        (nth 2 parsed)
                                    :expand-env  (nth 5 parsed)))))
     (cond (yas--current-template
-           (let ((buffer-name (format "*testing snippet: %s*" 
(yas--template-name yas--current-template))))
+           (let ((buffer-name
+                  (format "*testing snippet: %s*"
+                          (yas--template-name yas--current-template))))
              (kill-buffer (get-buffer-create buffer-name))
              (switch-to-buffer (get-buffer-create buffer-name))
              (setq buffer-undo-list nil)
              (condition-case nil (funcall test-mode) (error nil))
             (yas-minor-mode 1)
              (setq buffer-read-only nil)
-             (yas-expand-snippet (yas--template-content yas--current-template)
-                                 (point-min)
-                                 (point-max)
-                                 (yas--template-expand-env 
yas--current-template))
+             (yas-expand-snippet yas--current-template
+                                 (point-min) (point-max))
              (when (and debug
                         (require 'yasnippet-debug nil t))
                (yas-debug-snippets "*YASnippet trace*" 'snippet-navigation)
@@ -2986,6 +3029,33 @@ The last element of POSSIBILITIES may be a list of 
strings."
                (funcall fn "Choose: " possibilities))
              yas-prompt-functions)))
 
+(defun yas-completing-read (&rest args)
+  "A snippet-aware version of `completing-read'.
+This can be used to query the user for the initial value of a
+snippet field.  The arguments are the same as `completing-read'.
+
+\(fn PROMPT COLLECTION &optional PREDICATE REQUIRE-MATCH INITIAL-INPUT HIST 
DEF INHERIT-INPUT-METHOD)"
+  (unless (or yas-moving-away-p
+              yas-modified-p)
+    (apply #'completing-read args)))
+
+(defun yas--auto-next ()
+  "Helper for `yas-auto-next'."
+  (cl-loop
+   do (progn (remove-hook 'post-command-hook #'yas--auto-next t)
+             (yas-next-field))
+   ;; The transform in the next field may have requested auto-next as
+   ;; well.  Call it ourselves, since the command loop itself won't
+   ;; recheck the value of post-command-hook while running it.
+   while (memq #'yas--auto-next post-command-hook)))
+
+(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)
@@ -3003,7 +3073,7 @@ The last element of POSSIBILITIES may be a list of 
strings."
 (defun yas-verify-value (possibilities)
   "Verify that the current field value is in POSSIBILITIES.
 Otherwise signal `yas-exception'."
-  (when (and yas-moving-away-p (cl-notany (lambda (pos) (string= pos 
yas-text)) possibilities))
+  (when (and yas-moving-away-p (not (member yas-text possibilities)))
     (yas-throw (format "Field only allows %s" possibilities))))
 
 (defun yas-field-value (number)
@@ -3057,6 +3127,10 @@ other fields."
 (defvar yas--active-field-overlay nil
   "Overlays the currently active field.")
 
+(defvar yas--active-snippets nil
+  "List of currently active snippets")
+(make-variable-buffer-local 'yas--active-snippets)
+
 (defvar yas--field-protection-overlays nil
   "Two overlays protect the current active field.")
 
@@ -3260,12 +3334,19 @@ equivalent to a range covering the whole buffer."
          (setq beg (point-min) end (point-max)))
         ((not end)
          (setq end (1+ beg))))
-  (cl-sort
-   (delete-dups ;; Snippets have multiple overlays.
-    (delq nil
-          (mapcar (lambda (ov) (overlay-get ov 'yas--snippet))
-                  (overlays-in beg end))))
-   #'>= :key #'yas--snippet-id))
+  (if (and (eq beg (point-min))
+           (eq end (point-max)))
+      yas--active-snippets
+    ;; Note: don't use `mapcar' here, since it would allocate in
+    ;; proportion to the amount of overlays, even though the list of
+    ;; active snippets should be very small.
+    (let ((snippets nil))
+      (dolist (ov (overlays-in beg end))
+        (let ((snippet (overlay-get ov 'yas--snippet)))
+          ;; Snippets have multiple overlays, so check for dups.
+          (when (and snippet (not (memq snippet snippets)))
+            (push snippet snippets))))
+      (cl-sort snippets #'>= :key #'yas--snippet-id))))
 
 (define-obsolete-function-alias 'yas--snippets-at-point
   'yas-active-snippets "0.12")
@@ -3305,8 +3386,9 @@ Otherwise delegate to `yas-next-field'."
 If there's none, exit the snippet."
   (interactive)
   (unless arg (setq arg 1))
-  (let* ((snippet (car (yas-active-snippets)))
-         (active-field (overlay-get yas--active-field-overlay 'yas--field))
+  (let* ((active-field (overlay-get yas--active-field-overlay 'yas--field))
+         (snippet (car (yas-active-snippets (yas--field-start active-field)
+                                            (yas--field-end active-field))))
          (target-field (yas--find-next-field arg snippet active-field)))
     (yas--letenv (yas--snippet-expand-env snippet)
       ;; Apply transform to active field.
@@ -3425,6 +3507,9 @@ This renders the snippet as ordinary text."
     ;;
     (yas--markers-to-points snippet)
 
+    ;; It's no longer an active snippet.
+    (cl-callf2 delq snippet yas--active-snippets)
+
     ;; Take care of snippet revival on undo.
     (if (and yas-snippet-revival (listp buffer-undo-list))
         (push `(apply yas--snippet-revive ,yas-snippet-beg ,yas-snippet-end 
,snippet)
@@ -3448,10 +3533,7 @@ This renders the snippet as ordinary text."
       (dolist (snippet snippets)
         (yas--snippet-map-markers
          (lambda (m)
-           (goto-char m)
-           (beginning-of-line)
-           (prog1 (cons (count-lines (point-min) (point))
-                        (yas--snapshot-marker-location m))
+           (prog1 (cons m (yas--snapshot-line-location m))
              (set-marker m nil)))
          snippet)
         (let ((ctrl-ov (yas--snapshot-overlay-line-location
@@ -3459,23 +3541,27 @@ This renders the snippet as ordinary text."
           (push (list ctrl-ov dst-base-line snippet) to-move)
           (delete-overlay (car ctrl-ov))))
       (with-current-buffer buf
-        (setq yas--snippets-to-move (nconc to-move yas--snippets-to-move))))))
+        (cl-callf2 nconc to-move yas--snippets-to-move)))))
 
 (defun yas--on-buffer-kill ()
   ;; Org mode uses temp buffers for fontification and "native tab",
   ;; move all the snippets to the original org-mode buffer when it's
   ;; killed.
-  (let ((org-marker nil))
+  (let ((org-marker nil)
+        (org-buffer nil))
     (when (and yas-minor-mode
                (or (bound-and-true-p org-edit-src-from-org-mode)
                    (bound-and-true-p org-src--from-org-mode))
                (markerp
                 (setq org-marker
                       (or (bound-and-true-p org-edit-src-beg-marker)
-                          (bound-and-true-p org-src--beg-marker)))))
+                          (bound-and-true-p org-src--beg-marker))))
+               ;; If the org source buffer is killed before the temp
+               ;; fontification one, org-marker might point nowhere.
+               (setq org-buffer (marker-buffer org-marker)))
       (yas--prepare-snippets-for-move
        (point-min) (point-max)
-       (marker-buffer org-marker) org-marker))))
+       org-buffer org-marker))))
 
 (add-hook 'kill-buffer-hook #'yas--on-buffer-kill)
 
@@ -3485,18 +3571,16 @@ This renders the snippet as ordinary text."
            for base-pos = (progn (goto-char (point-min))
                                  (forward-line base-line) (point))
            do (yas--snippet-map-markers
-               (lambda (l-m-r-w)
-                 (goto-char base-pos)
-                 (forward-line (nth 0 l-m-r-w))
-                 (save-restriction
-                   (narrow-to-region (line-beginning-position)
-                                     (line-end-position))
-                   (yas--restore-marker-location (cdr l-m-r-w)))
-                 (nth 1 l-m-r-w))
+               (lambda (saved-location)
+                 (let ((m (pop saved-location)))
+                   (set-marker m (yas--goto-saved-line-location
+                                  base-pos saved-location))
+                   m))
                snippet)
            (goto-char base-pos)
-           (yas--restore-overlay-location ctrl-ov)
-           (yas--maybe-move-to-active-field snippet))
+           (yas--restore-overlay-line-location base-pos ctrl-ov)
+           (yas--maybe-move-to-active-field snippet)
+           (push snippet yas--active-snippets))
   (setq yas--snippets-to-move nil))
 
 (defun yas--safely-call-fun (fun)
@@ -3518,13 +3602,12 @@ HOOK should be a symbol, a hook variable, as in 
`run-hooks'."
   "Check if point exited the currently active field of the snippet.
 
 If so cleans up the whole snippet up."
-  (let* ((snippets (yas-active-snippets 'all))
-         (snippets-left snippets)
-         (snippet-exit-transform)
+  (let* ((snippet-exit-transform nil)
+         (exited-snippets-p nil)
          ;; Record the custom snippet `yas-after-exit-snippet-hook'
          ;; set in the expand-env field.
          (snippet-exit-hook yas-after-exit-snippet-hook))
-    (dolist (snippet snippets)
+    (dolist (snippet yas--active-snippets)
       (let ((active-field (yas--snippet-active-field snippet)))
         (yas--letenv (yas--snippet-expand-env snippet)
           ;; Note: the `force-exit' field could be a transform in case of
@@ -3532,10 +3615,10 @@ If so cleans up the whole snippet up."
           (setq snippet-exit-transform (yas--snippet-force-exit snippet))
           (cond ((or snippet-exit-transform
                      (not (and active-field (yas--field-contains-point-p 
active-field))))
-                 (setq snippets-left (delete snippet snippets-left))
                  (setf (yas--snippet-force-exit snippet) nil)
                  (setq snippet-exit-hook yas-after-exit-snippet-hook)
-                 (yas--commit-snippet snippet))
+                 (yas--commit-snippet snippet)
+                 (setq exited-snippets-p t))
                 ((and active-field
                       (or (not yas--active-field-overlay)
                           (not (overlay-buffer yas--active-field-overlay))))
@@ -3549,7 +3632,7 @@ If so cleans up the whole snippet up."
                    (yas--update-mirrors snippet)))
                 (t
                  nil)))))
-    (unless (or (null snippets) snippets-left)
+    (unless (or yas--active-snippets (not exited-snippets-p))
       (when snippet-exit-transform
         (yas--eval-for-effect snippet-exit-transform))
       (let ((yas-after-exit-snippet-hook snippet-exit-hook))
@@ -3635,6 +3718,11 @@ Use as a `:filter' argument for a conditional 
keybinding."
   (yas--skip-and-clear (or field (yas-current-field)))
   (yas-next-field 1))
 
+(defun yas-clear-field (&optional field)
+  "Clears unmodified FIELD if at field start."
+  (interactive)
+  (yas--skip-and-clear (or field (yas-current-field))))
+
 (defun yas-skip-and-clear-or-delete-char (&optional field)
   "Clears unmodified field if at field start, skips to next tab.
 
@@ -3697,13 +3785,49 @@ BEG, END and LENGTH like overlay modification hooks."
        (= beg (yas--field-start field)) ; Insertion at field start?
        (not (yas--field-modified-p field))))
 
+
+(defun yas--merge-and-drop-dups (list1 list2 cmp key)
+  ;; `delete-consecutive-dups' + `cl-merge'.
+  (funcall (if (fboundp 'delete-consecutive-dups)
+               #'delete-consecutive-dups ; 24.4
+             #'delete-dups)
+           (cl-merge 'list list1 list2 cmp :key key)))
+
+(defvar yas--before-change-modified-snippets nil)
+(make-variable-buffer-local 'yas--before-change-modified-snippets)
+
+(defun yas--gather-active-snippets (overlay beg end then-delete)
+  ;; Add active snippets in BEG..END into an OVERLAY keyed entry of
+  ;; `yas--before-change-modified-snippets'.  Return accumulated list.
+  ;; If THEN-DELETE is non-nil, delete the entry.
+  (let ((new (yas-active-snippets beg end))
+        (old (assq overlay yas--before-change-modified-snippets)))
+    (prog1 (cond ((and new old)
+                  (setf (cdr old)
+                        (yas--merge-and-drop-dups
+                         (cdr old) new
+                         ;; Sort like `yas-active-snippets'.
+                         #'>= #'yas--snippet-id)))
+                 (new (unless then-delete
+                        ;; Don't add new entry if we're about to
+                        ;; remove it anyway.
+                        (push (cons overlay new)
+                              yas--before-change-modified-snippets))
+                      new)
+                 (old (cdr old))
+                 (t nil))
+      (when then-delete
+        (cl-callf2 delq old yas--before-change-modified-snippets)))))
+
+(defvar yas--todo-snippet-indent nil nil)
+(make-variable-buffer-local 'yas--todo-snippet-indent)
+
 (defun yas--on-field-overlay-modification (overlay after? beg end &optional 
length)
   "Clears the field and updates mirrors, conditionally.
 
 Only clears the field if it hasn't been modified and point is at
 field start.  This hook does nothing if an undo is in progress."
-  (unless (or (not after?)
-              yas--inhibit-overlay-hooks
+  (unless (or yas--inhibit-overlay-hooks
               (not (overlayp yas--active-field-overlay)) ; Avoid Emacs bug 
#21824.
               ;; If a single change hits multiple overlays of the same
               ;; snippet, then we delete the snippet the first time,
@@ -3716,20 +3840,52 @@ field start.  This hook does nothing if an undo is in 
progress."
            (field (overlay-get overlay 'yas--field))
            (snippet (overlay-get yas--active-field-overlay 'yas--snippet)))
       (if (yas--snippet-live-p snippet)
-          (save-match-data
-            (yas--letenv (yas--snippet-expand-env snippet)
-              (when (yas--skip-and-clear-field-p field beg end length)
-                ;; We delete text starting from the END of insertion.
-                (yas--skip-and-clear field end))
-              (setf (yas--field-modified-p field) t)
-              (yas--advance-end-maybe field (overlay-end overlay))
-              (save-excursion
-                (yas--field-update-display field))
-              (yas--update-mirrors snippet)))
+          (if after?
+              (save-match-data
+                (yas--letenv (yas--snippet-expand-env snippet)
+                  (when (yas--skip-and-clear-field-p field beg end length)
+                    ;; We delete text starting from the END of insertion.
+                    (yas--skip-and-clear field end))
+                  (setf (yas--field-modified-p field) t)
+                  ;; Adjust any pending active fields in case of stacked
+                  ;; expansion.
+                  (let ((pfield field)
+                        (psnippets (yas--gather-active-snippets
+                                    overlay beg end t)))
+                    (while (and pfield psnippets)
+                      (let ((psnippet (pop psnippets)))
+                        (cl-assert (memq pfield (yas--snippet-fields 
psnippet)))
+                        (yas--advance-end-maybe pfield (overlay-end overlay))
+                        (setq pfield (yas--snippet-previous-active-field 
psnippet)))))
+                  ;; Update fields now, but delay auto indentation until
+                  ;; post-command.  We don't want to run indentation on
+                  ;; the intermediate state where field text might be
+                  ;; removed (and hence the field could be deleted along
+                  ;; with leading indentation).
+                  (let ((yas-indent-line nil))
+                    (save-excursion
+                      (yas--field-update-display field))
+                    (yas--update-mirrors snippet))
+                  (unless (or (not (eq yas-indent-line 'auto))
+                              (memq snippet yas--todo-snippet-indent))
+                    (push snippet yas--todo-snippet-indent))))
+            ;; Remember active snippets to use for after the change.
+            (yas--gather-active-snippets overlay beg end nil))
         (lwarn '(yasnippet zombie) :warning "Killing zombie snippet!")
         (delete-overlay overlay)))))
 
+(defun yas--do-todo-snippet-indent ()
+  ;; Do pending indentation of snippet fields, called from
+  ;; `yas--post-command-handler'.
+  (when yas--todo-snippet-indent
+    (save-excursion
+      (cl-loop for snippet in yas--todo-snippet-indent
+               do (yas--indent-mirrors-of-snippet
+                   snippet (yas--snippet-field-mirrors snippet)))
+      (setq yas--todo-snippet-indent nil))))
+
 (defun yas--auto-fill ()
+  ;; Preserve snippet markers during auto-fill.
   (let* ((orig-point (point))
          (end (progn (forward-paragraph) (point)))
          (beg (progn (backward-paragraph) (point)))
@@ -3739,57 +3895,59 @@ field start.  This hook does nothing if an undo is in 
progress."
     (dolist (snippet snippets)
       (dolist (m (yas--collect-snippet-markers snippet))
         (when (and (<= beg m) (<= m end))
-          (push (yas--snapshot-marker-location m beg end) remarkers)))
+          (push (cons m (yas--snapshot-location m beg end)) remarkers)))
       (push (yas--snapshot-overlay-location
              (yas--snippet-control-overlay snippet) beg end)
             reoverlays))
     (goto-char orig-point)
     (let ((yas--inhibit-overlay-hooks t))
-      (if (null yas--original-auto-fill-function)
-          ;; Try to get more info on #873/919.
-          (let ((yas--fill-fun-values `((t ,(default-value 
'yas--original-auto-fill-function))))
-                (fill-fun-values `((t ,(default-value 'auto-fill-function))))
-                ;; Listing 2 buffers with the same value is enough
-                (print-length 3))
-            (save-current-buffer
-              (dolist (buf (let ((bufs (buffer-list)))
-                             ;; List the current buffer first.
-                             (setq bufs (cons (current-buffer)
-                                              (remq (current-buffer) bufs)))))
-                (set-buffer buf)
-                (let* ((yf-cell (assq yas--original-auto-fill-function
-                                      yas--fill-fun-values))
-                       (af-cell (assq auto-fill-function fill-fun-values)))
-                  (when (local-variable-p 'yas--original-auto-fill-function)
-                    (if yf-cell (setcdr yf-cell (cons buf (cdr yf-cell)))
-                      (push (list yas--original-auto-fill-function buf) 
yas--fill-fun-values)))
-                  (when (local-variable-p 'auto-fill-function)
-                    (if af-cell (setcdr af-cell (cons buf (cdr af-cell)))
-                      (push (list auto-fill-function buf) fill-fun-values))))))
-                 (lwarn '(yasnippet auto-fill bug) :error
-                        "`yas--original-auto-fill-function' unexpectedly nil 
in %S!  Disabling auto-fill.
+      (if yas--original-auto-fill-function
+          (funcall yas--original-auto-fill-function)
+        ;; Shouldn't happen, gather more info about it (see #873/919).
+        (let ((yas--fill-fun-values `((t ,(default-value 
'yas--original-auto-fill-function))))
+              (fill-fun-values `((t ,(default-value 'auto-fill-function))))
+              ;; Listing 2 buffers with the same value is enough
+              (print-length 3))
+          (save-current-buffer
+            (dolist (buf (let ((bufs (buffer-list)))
+                           ;; List the current buffer first.
+                           (setq bufs (cons (current-buffer)
+                                            (remq (current-buffer) bufs)))))
+              (set-buffer buf)
+              (let* ((yf-cell (assq yas--original-auto-fill-function
+                                    yas--fill-fun-values))
+                     (af-cell (assq auto-fill-function fill-fun-values)))
+                (when (local-variable-p 'yas--original-auto-fill-function)
+                  (if yf-cell (setcdr yf-cell (cons buf (cdr yf-cell)))
+                    (push (list yas--original-auto-fill-function buf) 
yas--fill-fun-values)))
+                (when (local-variable-p 'auto-fill-function)
+                  (if af-cell (setcdr af-cell (cons buf (cdr af-cell)))
+                    (push (list auto-fill-function buf) fill-fun-values))))))
+          (lwarn '(yasnippet auto-fill bug) :error
+                 "`yas--original-auto-fill-function' unexpectedly nil in %S!  
Disabling auto-fill.
   %S
   `auto-fill-function': %S\n%s"
-                        (current-buffer) yas--fill-fun-values fill-fun-values
-                        (if (fboundp 'backtrace--print-frame)
-                            (with-output-to-string
-                              (mapc (lambda (frame)
-                                      (apply #'backtrace--print-frame frame))
-                                    yas--watch-auto-fill-backtrace))
-                          ""))
-                 ;; Try to avoid repeated triggering of this bug.
-                 (auto-fill-mode -1)
-                 ;; Don't pop up more than once in a session (still log 
though).
-                 (defvar warning-suppress-types) ; `warnings' is autoloaded by 
`lwarn'.
-                 (add-to-list 'warning-suppress-types '(yasnippet auto-fill 
bug)))
-        (funcall yas--original-auto-fill-function)))
+                 (current-buffer) yas--fill-fun-values fill-fun-values
+                 (if (fboundp 'backtrace--print-frame)
+                     (with-output-to-string
+                       (mapc (lambda (frame)
+                               (apply #'backtrace--print-frame frame))
+                             yas--watch-auto-fill-backtrace))
+                   ""))
+          ;; Try to avoid repeated triggering of this bug.
+          (auto-fill-mode -1)
+          ;; Don't pop up more than once in a session (still log though).
+          (defvar warning-suppress-types) ; `warnings' is autoloaded by 
`lwarn'.
+          (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug)))))
     (save-excursion
       (setq end (progn (forward-paragraph) (point)))
       (setq beg (progn (backward-paragraph) (point))))
     (save-excursion
       (save-restriction
         (narrow-to-region beg end)
-        (mapc #'yas--restore-marker-location remarkers)
+        (dolist (remarker remarkers)
+          (set-marker (car remarker)
+                      (yas--goto-saved-location (cdr remarker))))
         (mapc #'yas--restore-overlay-location reoverlays))
       (mapc (lambda (snippet)
               (yas--letenv (yas--snippet-expand-env snippet)
@@ -3843,6 +4001,7 @@ Move the overlays, or create them if they do not exit."
 (defun yas--on-protection-overlay-modification (_overlay after? beg end 
&optional length)
   "Commit the snippet if the protection overlay is being killed."
   (unless (or yas--inhibit-overlay-hooks
+              yas-inhibit-overlay-modification-protection
               (not after?)
               (= length (- end beg)) ; deletion or insertion
               (yas--undo-in-progress))
@@ -3997,6 +4156,7 @@ After revival, push the `yas--take-care-of-redo' in the
   (when (yas--maybe-move-to-active-field snippet)
     (setf (yas--snippet-control-overlay snippet) (yas--make-control-overlay 
snippet beg end))
     (overlay-put (yas--snippet-control-overlay snippet) 'yas--snippet snippet)
+    (push snippet yas--active-snippets)
     (when (listp buffer-undo-list)
       (push `(apply yas--take-care-of-redo ,snippet)
             buffer-undo-list))))
@@ -4010,15 +4170,21 @@ Returns the newly created snippet."
       (yas--letenv expand-env
         ;; Put a single undo action for the expanded snippet's
         ;; content.
-        (let ((buffer-undo-list t))
+        (let ((buffer-undo-list t)
+              (inhibit-modification-hooks t))
           ;; Some versions of cc-mode fail when inserting snippet
-          ;; content in a narrowed buffer.
+          ;; content in a narrowed buffer, so make sure to insert
+          ;; before narrowing.  Furthermore, call before and after
+          ;; change functions manually, otherwise cc-mode's cache can
+          ;; get messed up.
           (goto-char begin)
+          (run-hook-with-args 'before-change-functions begin begin)
           (insert content)
           (setq end (+ end (length content)))
           (narrow-to-region begin end)
           (goto-char (point-min))
-          (yas--snippet-parse-create snippet))
+          (yas--snippet-parse-create snippet)
+          (run-hook-with-args 'after-change-functions (point-min) (point-max) 
0))
         (when (listp buffer-undo-list)
           (push (cons (point-min) (point-max))
                 buffer-undo-list))
@@ -4042,6 +4208,7 @@ Returns the newly created snippet."
         ;; Move to end
         (goto-char (point-max))
 
+        (push snippet yas--active-snippets)
         snippet))))
 
 
@@ -4261,35 +4428,54 @@ Meant to be called in a narrowed buffer, does various 
passes"
 ;; current paragraph instead of line.
 ;;
 ;; 2. Moving snippets from an `org-src' temp buffer into the main org
-;; buffer, in this case we need to count the line offsets (because org
-;; may add indentation on each line making character positions
-;; unreliable).
+;; buffer, in this case we need to count the relative line number
+;; (because org may add indentation on each line making character
+;; positions unreliable).
+;;
+;; Data formats:
+;; (LOCATION) = (REGEXP WS-COUNT)
+;; MARKER -> (MARKER . (LOCATION))
+;; OVERLAY -> (OVERLAY LOCATION-BEG LOCATION-END)
+;;
+;; For `org-src' temp buffer, add a line number to format:
+;; (LINE-LOCATION) = (LINE . (LOCATION))
+;; MARKER@LINE -> (MARKER . (LINE-LOCATION))
+;; OVERLAY@LINE -> (OVERLAY LINE-LOCATION-BEG LINE-LOCATION-END)
 ;;
 ;; This is all best-effort heuristic stuff, but it should cover 99% of
 ;; use-cases.
 
-(defun yas--snapshot-marker-location (marker &optional beg end)
-  "Returns info for restoring MARKER's location after indent.
-The returned value is a list of the form (MARKER REGEXP WS-COUNT)."
+(defun yas--snapshot-location (position &optional beg end)
+  "Returns info for restoring POSITIONS's location after indent.
+The returned value is a list of the form (REGEXP WS-COUNT).
+POSITION may be either a marker or just a buffer position.  The
+REGEXP matches text between BEG..END which default to the current
+line if omitted."
+  (goto-char position)
   (unless beg (setq beg (line-beginning-position)))
   (unless end (setq end (line-end-position)))
-  (let ((before (split-string (buffer-substring-no-properties beg marker)
+  (let ((before (split-string (buffer-substring-no-properties beg position)
                               "[[:space:]\n]+" t))
-        (after (split-string (buffer-substring-no-properties marker end)
+        (after (split-string (buffer-substring-no-properties position end)
                              "[[:space:]\n]+" t)))
-    (list marker
-          (concat "[[:space:]\n]*"
+    (list (concat "[[:space:]\n]*"
                   (mapconcat (lambda (s)
-                               (if (eq s marker) "\\(\\)"
+                               (if (eq s position) "\\(\\)"
                                  (regexp-quote s)))
-                             (nconc before (list marker) after)
+                             (nconc before (list position) after)
                              "[[:space:]\n]*"))
-          (progn (goto-char marker)
-                 (skip-chars-forward "[:space:]\n" end)
-                 (- (point) marker)))))
+          (progn (skip-chars-forward "[:space:]\n" end)
+                 (- (point) position)))))
+
+(defun yas--snapshot-line-location (position &optional beg end)
+  "Like `yas--snapshot-location', but return also line number.
+Returned format is (LINE REGEXP WS-COUNT)."
+  (goto-char position)
+  (cons (count-lines (point-min) (line-beginning-position))
+        (yas--snapshot-location position beg end)))
 
 (defun yas--snapshot-overlay-location (overlay beg end)
-  "Like `yas--snapshot-marker-location' for overlays.
+  "Like `yas--snapshot-location' for overlays.
 The returned format is (OVERLAY (RE WS) (RE WS)).  Either of
 the (RE WS) lists may be nil if the start or end, respectively,
 of the overlay is outside the range BEG .. END."
@@ -4297,67 +4483,59 @@ of the overlay is outside the range BEG .. END."
         (oend (overlay-end overlay)))
     (list overlay
           (when (and (<= beg obeg) (< obeg end))
-            (cdr (yas--snapshot-marker-location obeg beg end)))
+            (yas--snapshot-location obeg beg end))
           (when (and (<= beg oend) (< oend end))
-            (cdr (yas--snapshot-marker-location oend beg end))))))
+            (yas--snapshot-location oend beg end)))))
 
 (defun yas--snapshot-overlay-line-location (overlay)
   "Return info for restoring OVERLAY's line based location.
 The returned format is (OVERLAY (LINE RE WS) (LINE RE WS))."
-  (let ((loc-beg (progn (goto-char (overlay-start overlay))
-                        (yas--snapshot-marker-location (point))))
-        (loc-end (progn (goto-char (overlay-end overlay))
-                        (yas--snapshot-marker-location (point)))))
-    (setcar loc-beg (count-lines (point-min) (progn (goto-char (car loc-beg))
-                                                    
(line-beginning-position))))
-    (setcar loc-end (count-lines (point-min) (progn (goto-char (car loc-end))
-                                                    
(line-beginning-position))))
-    (list overlay loc-beg loc-end)))
-
-(defun yas--goto-saved-location (regexp ws-count)
-  "Move point to location saved by `yas--snapshot-marker-location'.
-Buffer must be narrowed to BEG..END used to create the snapshot info."
-  (goto-char (point-min))
-  (if (not (looking-at regexp))
-      (lwarn '(yasnippet re-marker) :warning
-             "Couldn't find: %S" regexp)
-    (goto-char (match-beginning 1))
-    (skip-chars-forward "[:space:]\n")
-    (skip-chars-backward "[:space:]\n" (- (point) ws-count))))
-
-(defun yas--restore-marker-location (re-marker)
-  "Restores marker based on info from `yas--snapshot-marker-location'.
+  (list overlay
+        (yas--snapshot-line-location (overlay-start overlay))
+        (yas--snapshot-line-location (overlay-end overlay))))
+
+(defun yas--goto-saved-location (re-count)
+  "Move to and return point saved by `yas--snapshot-location'.
 Buffer must be narrowed to BEG..END used to create the snapshot info."
-  (apply #'yas--goto-saved-location (cdr re-marker))
-  (set-marker (car re-marker) (point)))
+  (let ((regexp (pop re-count))
+        (ws-count (pop re-count)))
+    (goto-char (point-min))
+    (if (not (looking-at regexp))
+        (lwarn '(yasnippet re-marker) :warning
+               "Couldn't find: %S" regexp)
+      (goto-char (match-beginning 1))
+      (skip-chars-forward "[:space:]\n")
+      (skip-chars-backward "[:space:]\n" (- (point) ws-count)))
+    (point)))
 
 (defun yas--restore-overlay-location (ov-locations)
-  "Restores marker based on info from `yas--snapshot-marker-location'.
+  "Restores marker based on info from `yas--snapshot-overlay-location'.
 Buffer must be narrowed to BEG..END used to create the snapshot info."
   (cl-destructuring-bind (overlay loc-beg loc-end) ov-locations
     (move-overlay overlay
                   (if (not loc-beg) (overlay-start overlay)
-                    (apply #'yas--goto-saved-location loc-beg)
-                    (point))
+                    (yas--goto-saved-location loc-beg))
                   (if (not loc-end) (overlay-end overlay)
-                    (apply #'yas--goto-saved-location loc-end)
-                    (point)))))
-
-
-(defun yas--restore-overlay-line-location (ov-locations)
-  "Restores overlay based on info from `yas--snapshot-overlay-line-location'."
+                    (yas--goto-saved-location loc-end)))))
+
+(defun yas--goto-saved-line-location (base-pos l-re-count)
+  "Move to and return point saved by `yas--snapshot-line-location'.
+Additionally requires BASE-POS to tell where the line numbers are
+relative to."
+  (goto-char base-pos)
+  (forward-line (pop l-re-count))
   (save-restriction
-    (move-overlay (car ov-locations)
-                  (save-excursion
-                    (forward-line (car (nth 1 ov-locations)))
-                    (narrow-to-region (line-beginning-position) 
(line-end-position))
-                    (apply #'yas--goto-saved-location (cdr (nth 1 
ov-locations)))
-                    (point))
-                  (save-excursion
-                    (forward-line (car (nth 2 ov-locations)))
-                    (narrow-to-region (line-beginning-position) 
(line-end-position))
-                    (apply #'yas--goto-saved-location (cdr (nth 2 
ov-locations)))
-                    (point)))))
+    (narrow-to-region (line-beginning-position)
+                      (line-end-position))
+    (yas--goto-saved-location l-re-count)))
+
+(defun yas--restore-overlay-line-location (base-pos ov-locations)
+  "Restores marker based on info from `yas--snapshot-overlay-line-location'."
+  (cl-destructuring-bind (overlay beg-l-r-w end-l-r-w)
+      ov-locations
+    (move-overlay overlay
+                  (yas--goto-saved-line-location base-pos beg-l-r-w)
+                  (yas--goto-saved-line-location base-pos end-l-r-w))))
 
 (defun yas--indent-region (from to snippet)
   "Indent the lines between FROM and TO with `indent-according-to-mode'.
@@ -4376,14 +4554,16 @@ The SNIPPET's markers are preserved."
                  (let ((remarkers nil))
                    (dolist (m snippet-markers)
                      (when (and (<= bol m) (<= m eol))
-                       (push (yas--snapshot-marker-location m bol eol)
+                       (push (cons m (yas--snapshot-location m bol eol))
                              remarkers)))
                    (unwind-protect
                        (progn (back-to-indentation)
                               (indent-according-to-mode))
                      (save-restriction
                        (narrow-to-region bol (line-end-position))
-                       (mapc #'yas--restore-marker-location remarkers))))
+                       (dolist (remarker remarkers)
+                         (set-marker (car remarker)
+                                     (yas--goto-saved-location (cdr 
remarker)))))))
                  while (and (zerop (forward-line 1))
                             (< (point) to)))))))
 
@@ -4481,8 +4661,7 @@ Lisp expression."
                                                     current-string '(?`))))))
         (goto-char (match-beginning 0))
         (when transformed
-          (let ((marker (make-marker))
-                (before-change-functions (cdr before-change-functions)))
+          (let ((marker (make-marker)))
             (yas--save-restriction-and-widen
               (insert "Y") ;; quite horrendous, I love it :)
               (set-marker marker (point))
@@ -4551,7 +4730,14 @@ When multiple expressions are found, only the last one 
counts."
   ;;
   (save-excursion
     (while (re-search-forward yas--field-regexp nil t)
-      (let* ((real-match-end-0 (yas--scan-sexps (1+ (match-beginning 0)) 1))
+      (let* ((brace-scan (yas--scan-sexps (1+ (match-beginning 0)) 1))
+             ;; 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
+             ;; be lenient, because we can.
+             (real-match-end-0 (if (eq ?} (char-before brace-scan))
+                                   brace-scan
+                                 (point)))
              (number (and (match-string-no-properties 1)
                           (string-to-number (match-string-no-properties 1))))
              (brand-new-field (and real-match-end-0
@@ -4685,46 +4871,58 @@ When multiple expressions are found, only the last one 
counts."
                     (parent 1)
                     (t 0))))))
 
+(defun yas--snippet-field-mirrors (snippet)
+  ;; Make a list of (FIELD . MIRROR).
+  (cl-sort
+   (cl-mapcan (lambda (field)
+                (mapcar (lambda (mirror)
+                          (cons field mirror))
+                        (yas--field-mirrors field)))
+              (yas--snippet-fields snippet))
+   ;; Then sort this list so that entries with mirrors with
+   ;; parent fields appear before.  This was important for
+   ;; fixing #290, and also handles the case where a mirror in
+   ;; a field causes another mirror to need reupdating.
+   #'> :key (lambda (fm) (yas--calculate-mirror-depth (cdr fm)))))
+
+(defun yas--indent-mirrors-of-snippet (snippet &optional f-ms)
+  ;; Indent mirrors of SNIPPET.  F-MS is the return value of
+  ;; (yas--snippet-field-mirrors SNIPPET).
+  (when (eq yas-indent-line 'auto)
+    (let ((yas--inhibit-overlay-hooks t))
+      (cl-loop for (beg . end) in
+               (cl-sort (mapcar (lambda (f-m)
+                                  (let ((mirror (cdr f-m)))
+                                    (cons (yas--mirror-start mirror)
+                                          (yas--mirror-end mirror))))
+                                (or f-ms
+                                    (yas--snippet-field-mirrors snippet)))
+                        #'< :key #'car)
+               do (yas--indent-region beg end snippet)))))
+
 (defun yas--update-mirrors (snippet)
   "Update all the mirrors of SNIPPET."
   (yas--save-restriction-and-widen
     (save-excursion
-      (cl-loop
-       for (field . mirror)
-       in (cl-sort
-           ;; Make a list of (FIELD . MIRROR).
-           (cl-mapcan (lambda (field)
-                        (mapcar (lambda (mirror)
-                                  (cons field mirror))
-                                (yas--field-mirrors field)))
-                      (yas--snippet-fields snippet))
-           ;; Then sort this list so that entries with mirrors with
-           ;; parent fields appear before.  This was important for
-           ;; fixing #290, and also handles the case where a mirror in
-           ;; a field causes another mirror to need reupdating.
-           #'> :key (lambda (fm) (yas--calculate-mirror-depth (cdr fm))))
-       ;; Before updating a mirror with a parent-field, maybe advance
-       ;; its start (#290).
-       do (let ((parent-field (yas--mirror-parent-field mirror)))
-            (when parent-field
-              (yas--advance-start-maybe mirror (yas--fom-start parent-field))))
-       ;; Update this mirror.
-       do (yas--mirror-update-display mirror field)
-       ;; Delay indenting until we're done all mirrors.  We must do
-       ;; this to avoid losing whitespace between fields that are
-       ;; still empty (i.e., they will be non-empty after updating).
-       when (eq yas-indent-line 'auto)
-       collect (cons (yas--mirror-start mirror) (yas--mirror-end mirror))
-       into indent-regions
-       ;; `yas--place-overlays' is needed since the active field and
-       ;; protected overlays might have been changed because of insertions
-       ;; in `yas--mirror-update-display'.
-       do (let ((active-field (yas--snippet-active-field snippet)))
-            (when active-field (yas--place-overlays snippet active-field)))
-       finally do
-       (let ((yas--inhibit-overlay-hooks t))
-         (cl-loop for (beg . end) in (cl-sort indent-regions #'< :key #'car)
-                  do (yas--indent-region beg end snippet)))))))
+      (let ((f-ms (yas--snippet-field-mirrors snippet)))
+        (cl-loop
+         for (field . mirror) in f-ms
+         ;; Before updating a mirror with a parent-field, maybe advance
+         ;; its start (#290).
+         do (let ((parent-field (yas--mirror-parent-field mirror)))
+              (when parent-field
+                (yas--advance-start-maybe mirror (yas--fom-start 
parent-field))))
+         ;; Update this mirror.
+         do (yas--mirror-update-display mirror field)
+         ;; `yas--place-overlays' is needed since the active field and
+         ;; protected overlays might have been changed because of insertions
+         ;; in `yas--mirror-update-display'.
+         do (let ((active-field (yas--snippet-active-field snippet)))
+              (when active-field (yas--place-overlays snippet active-field))))
+        ;; Delay indenting until we're done all mirrors.  We must do
+        ;; this to avoid losing whitespace between fields that are
+        ;; still empty (i.e., they will be non-empty after updating).
+        (yas--indent-mirrors-of-snippet snippet f-ms)))))
 
 (defun yas--mirror-update-display (mirror field)
   "Update MIRROR according to FIELD (and mirror transform)."
@@ -4782,6 +4980,7 @@ When multiple expressions are found, only the last one 
counts."
     ;; Don't pop up more than once in a session (still log though).
     (defvar warning-suppress-types) ; `warnings' is autoloaded by `lwarn'.
     (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug)))
+  (yas--do-todo-snippet-indent)
   (condition-case err
       (progn (yas--finish-moving-snippets)
              (cond ((eq 'undo this-command)
@@ -4884,6 +5083,12 @@ object satisfying `yas--field-p' to restrict the 
expansion to.")))
           (help-xref-button 1 'help-snippet-def template)
           (delete-region (match-end 1) (match-end 0))
           (delete-region (match-beginning 0) (match-beginning 1)))))))
+
+;;; Eldoc configuration.
+(eldoc-add-command 'yas-next-field-or-maybe-expand
+                   'yas-next-field 'yas-prev-field
+                   'yas-expand 'yas-expand-from-keymap
+                   'yas-expand-from-trigger-key)
 
 ;;; Utils
 
@@ -4904,62 +5109,6 @@ object satisfying `yas--field-p' to restrict the 
expansion to.")))
   (apply #'format (concat "[yas] " format-control) format-args))
 
 
-;;; Some hacks:
-;;
-;; The functions
-;;
-;; `locate-dominating-file'
-;; `region-active-p'
-;;
-;; added for compatibility in emacsen < 23
-(unless (>= emacs-major-version 23)
-  (unless (fboundp 'region-active-p)
-    (defun region-active-p ()  (and transient-mark-mode mark-active)))
-
-  (unless (fboundp 'locate-dominating-file)
-    (defvar locate-dominating-stop-dir-regexp
-      "\\`\\(?:[\\/][\\/][^\\/]+[\\/]\\|/\\(?:net\\|afs\\|\\.\\.\\.\\)/\\)\\'"
-      "Regexp of directory names which stop the search in 
`locate-dominating-file'.
-Any directory whose name matches this regexp will be treated like
-a kind of root directory by `locate-dominating-file' which will stop its search
-when it bumps into it.
-The default regexp prevents fruitless and time-consuming attempts to find
-special files in directories in which filenames are interpreted as hostnames,
-or mount points potentially requiring authentication as a different user.")
-
-    (defun locate-dominating-file (file name)
-      "Look up the directory hierarchy from FILE for a file named NAME.
-Stop at the first parent directory containing a file NAME,
-and return the directory.  Return nil if not found."
-      ;; We used to use the above locate-dominating-files code, but the
-      ;; directory-files call is very costly, so we're much better off doing
-      ;; multiple calls using the code in here.
-      ;;
-      ;; Represent /home/luser/foo as ~/foo so that we don't try to look for
-      ;; `name' in /home or in /.
-      (setq file (abbreviate-file-name file))
-      (let ((root nil)
-            try)
-        (while (not (or root
-                        (null file)
-                        ;; FIXME: Disabled this heuristic because it is 
sometimes
-                        ;; inappropriate.
-                        ;; As a heuristic, we stop looking up the hierarchy of
-                        ;; directories as soon as we find a directory belonging
-                        ;; to another user.  This should save us from looking 
in
-                        ;; things like /net and /afs.  This assumes that all 
the
-                        ;; files inside a project belong to the same user.
-                        ;; (let ((prev-user user))
-                        ;;   (setq user (nth 2 (file-attributes file)))
-                        ;;   (and prev-user (not (equal user prev-user))))
-                        (string-match locate-dominating-stop-dir-regexp file)))
-          (setq try (file-exists-p (expand-file-name name file)))
-          (cond (try (setq root file))
-                ((equal file (setq file (file-name-directory
-                                         (directory-file-name file))))
-                 (setq file nil))))
-        root))))
-
 ;;; Unloading
 
 (defvar unload-function-defs-list) ; loadhist.el



reply via email to

[Prev in Thread] Current Thread [Next in Thread]