* Support exits in the form of ${0:ephemeral text}

* Clean up whitespace
* Minor bug fixes
This commit is contained in:
capitaomorte 2010-03-31 22:54:11 +00:00
parent 83a81b2a9c
commit 4a8651f34f

View File

@ -44,7 +44,7 @@
;; ;;
;; Steps 4. and 5. are optional, you don't have to use the minor ;; Steps 4. and 5. are optional, you don't have to use the minor
;; mode to use YASnippet. ;; mode to use YASnippet.
;; ;;
;; Interesting variables are: ;; Interesting variables are:
;; ;;
;; `yas/snippet-dirs' ;; `yas/snippet-dirs'
@ -114,7 +114,7 @@
;; sets it to the appropriate major mode and inserts the ;; sets it to the appropriate major mode and inserts the
;; snippet there, so you can see what it looks like. This is ;; snippet there, so you can see what it looks like. This is
;; bound to "C-c C-t" while in `snippet-mode'. ;; bound to "C-c C-t" while in `snippet-mode'.
;; ;;
;; M-x yas/describe-tables ;; M-x yas/describe-tables
;; ;;
;; Lists known snippets in a separate buffer. User is ;; Lists known snippets in a separate buffer. User is
@ -255,7 +255,7 @@ representation using `read-kbd-macro'."
;; `yas/trigger-key' is *not* loaded. ;; `yas/trigger-key' is *not* loaded.
(if (fboundp 'yas/trigger-key-reload) (if (fboundp 'yas/trigger-key-reload)
(yas/trigger-key-reload old))))) (yas/trigger-key-reload old)))))
(defcustom yas/next-field-key '("TAB" "<tab>") (defcustom yas/next-field-key '("TAB" "<tab>")
"The key to navigate to next field when a snippet is active. "The key to navigate to next field when a snippet is active.
@ -270,7 +270,7 @@ Can also be a list of strings."
(set-default symbol val) (set-default symbol val)
(if (fboundp 'yas/init-yas-in-snippet-keymap) (if (fboundp 'yas/init-yas-in-snippet-keymap)
(yas/init-yas-in-snippet-keymap)))) (yas/init-yas-in-snippet-keymap))))
(defcustom yas/prev-field-key '("<backtab>" "<S-tab>") (defcustom yas/prev-field-key '("<backtab>" "<S-tab>")
"The key to navigate to previous field when a snippet is active. "The key to navigate to previous field when a snippet is active.
@ -492,7 +492,7 @@ This variable is a lisp form:
* If it evaluates to t or some other non-nil value * If it evaluates to t or some other non-nil value
* Snippet bearing no conditions, or conditions that * Snippet bearing no conditions, or conditions that
evaluate to non-nil, are considered for expansion. evaluate to non-nil, are considered for expansion.
* Otherwise, the snippet is not considered. * Otherwise, the snippet is not considered.
@ -587,7 +587,7 @@ snippet itself contains a condition that returns the symbol
["Visit snippet file..." yas/visit-snippet-file ["Visit snippet file..." yas/visit-snippet-file
:help "Prompt for an expandable snippet and find its file"] :help "Prompt for an expandable snippet and find its file"]
["Find snippets..." yas/find-snippets ["Find snippets..." yas/find-snippets
:help "Invoke `find-file' in the appropriate snippet directory"] :help "Invoke `find-file' in the appropriate snippet directory"]
"----" "----"
("Snippet menu behaviour" ("Snippet menu behaviour"
["Visit snippets" (setq yas/visit-from-menu t) ["Visit snippets" (setq yas/visit-from-menu t)
@ -654,27 +654,27 @@ snippet itself contains a condition that returns the symbol
'yas/completing-prompt-prompt)] 'yas/completing-prompt-prompt)]
) )
("Misc" ("Misc"
["Wrap region in exit marker" ["Wrap region in exit marker"
(setq yas/wrap-around-region (setq yas/wrap-around-region
(not yas/wrap-around-region)) (not yas/wrap-around-region))
:help "If non-nil automatically wrap the selected text in the $0 snippet exit" :help "If non-nil automatically wrap the selected text in the $0 snippet exit"
:style toggle :selected yas/wrap-around-region] :style toggle :selected yas/wrap-around-region]
["Allow stacked expansions " ["Allow stacked expansions "
(setq yas/triggers-in-field (setq yas/triggers-in-field
(not yas/triggers-in-field)) (not yas/triggers-in-field))
:help "If non-nil allow snippets to be triggered inside other snippet fields" :help "If non-nil allow snippets to be triggered inside other snippet fields"
:style toggle :selected yas/triggers-in-field] :style toggle :selected yas/triggers-in-field]
["Revive snippets on undo " ["Revive snippets on undo "
(setq yas/snippet-revival (setq yas/snippet-revival
(not yas/snippet-revival)) (not yas/snippet-revival))
:help "If non-nil allow snippets to become active again after undo" :help "If non-nil allow snippets to become active again after undo"
:style toggle :selected yas/snippet-revival] :style toggle :selected yas/snippet-revival]
["Good grace " ["Good grace "
(setq yas/good-grace (setq yas/good-grace
(not yas/good-grace)) (not yas/good-grace))
:help "If non-nil don't raise errors in bad embedded eslip in snippets" :help "If non-nil don't raise errors in bad embedded eslip in snippets"
:style toggle :selected yas/good-grace] :style toggle :selected yas/good-grace]
["Ignore filenames as triggers" ["Ignore filenames as triggers"
(setq yas/ignore-filenames-as-triggers (setq yas/ignore-filenames-as-triggers
(not yas/ignore-filenames-as-triggers)) (not yas/ignore-filenames-as-triggers))
:help "If non-nil don't derive tab triggers from filenames" :help "If non-nil don't derive tab triggers from filenames"
@ -706,7 +706,7 @@ With optional UNBIND-KEY, try to unbind that key from
(when (and unbind-key (when (and unbind-key
(stringp unbind-key) (stringp unbind-key)
(not (string= unbind-key ""))) (not (string= unbind-key "")))
(define-key yas/minor-mode-map (read-kbd-macro unbind-key) nil)) (define-key yas/minor-mode-map (read-kbd-macro unbind-key) nil))
(when (and yas/trigger-key (when (and yas/trigger-key
(stringp yas/trigger-key) (stringp yas/trigger-key)
(not (string= yas/trigger-key ""))) (not (string= yas/trigger-key "")))
@ -729,7 +729,7 @@ all defined direct keybindings to the command
(defun yas/direct-keymaps-reload () (defun yas/direct-keymaps-reload ()
"Force reload the direct keybinding for active snippet tables." "Force reload the direct keybinding for active snippet tables."
(interactive) (interactive)
(setq yas/direct-keymaps nil) (setq yas/direct-keymaps nil)
(maphash #'(lambda (name table) (maphash #'(lambda (name table)
(mapc #'(lambda (table) (mapc #'(lambda (table)
(push (cons (intern (format "yas//direct-%s" name)) (push (cons (intern (format "yas//direct-%s" name))
@ -778,7 +778,7 @@ Key bindings:
(yas/trigger-key-reload) (yas/trigger-key-reload)
;; Load all snippets definitions unless we still don't have a ;; Load all snippets definitions unless we still don't have a
;; root-directory or some snippets have already been loaded. ;; root-directory or some snippets have already been loaded.
;; ;;
(unless (or (null yas/snippet-dirs) (unless (or (null yas/snippet-dirs)
(> (hash-table-count yas/tables) 0)) (> (hash-table-count yas/tables) 0))
(yas/reload-all)) (yas/reload-all))
@ -791,7 +791,7 @@ Key bindings:
(add-hook 'yas/minor-mode-hook 'yas/direct-keymaps-set-vars-runonce 'append)) (add-hook 'yas/minor-mode-hook 'yas/direct-keymaps-set-vars-runonce 'append))
(t (t
;; Uninstall the direct keymaps. ;; Uninstall the direct keymaps.
;; ;;
(remove-hook 'emulation-mode-map-alists 'yas/direct-keymaps)))) (remove-hook 'emulation-mode-map-alists 'yas/direct-keymaps))))
(defun yas/direct-keymaps-set-vars-runonce () (defun yas/direct-keymaps-set-vars-runonce ()
@ -1018,7 +1018,7 @@ keybinding)."
(and key (concat key yas/trigger-symbol)))) (and key (concat key yas/trigger-symbol))))
(setcar (cdr menu-binding) (setcar (cdr menu-binding)
name)) name))
(puthash (yas/template-uid template) template (yas/table-uidhash table)))) (puthash (yas/template-uid template) template (yas/table-uidhash table))))
(defun yas/update-template (snippet-table template) (defun yas/update-template (snippet-table template)
@ -1066,7 +1066,8 @@ This function implements the rules described in
(if (eq requirement 'always) (if (eq requirement 'always)
templates templates
(remove-if-not #'(lambda (pair) (remove-if-not #'(lambda (pair)
(yas/template-can-expand-p (yas/template-condition (cdr pair)) requirement)) (yas/template-can-expand-p
(yas/template-condition (cdr pair)) requirement))
templates)))) templates))))
(defun yas/require-template-specific-condition-p () (defun yas/require-template-specific-condition-p ()
@ -1095,7 +1096,7 @@ conditions to filter out potential expansions."
(eq requirement result))))) (eq requirement result)))))
(defun yas/table-get-all-parents (table) (defun yas/table-get-all-parents (table)
"Returns a list of all parent tables of TABLE" "Returns a list of all parent tables of TABLE"
(let ((parents (yas/table-parents table))) (let ((parents (yas/table-parents table)))
(when parents (when parents
(append (copy-list parents) (append (copy-list parents)
@ -1200,7 +1201,7 @@ return an expression that when evaluated will issue an error."
(defun yas/read-keybinding (keybinding) (defun yas/read-keybinding (keybinding)
"Read KEYBINDING as a snippet keybinding, return a vector." "Read KEYBINDING as a snippet keybinding, return a vector."
(when (and keybinding (when (and keybinding
(not (string-match "keybinding" keybinding))) (not (string-match "keybinding" keybinding)))
(condition-case err (condition-case err
(let ((keybinding-string (or (and (string-match "\".*\"" keybinding) (let ((keybinding-string (or (and (string-match "\".*\"" keybinding)
(read keybinding)) (read keybinding))
@ -1397,7 +1398,7 @@ Here's a list of currently recognized variables:
(directory-files directory t))) (directory-files directory t)))
(defun yas/make-menu-binding (template) (defun yas/make-menu-binding (template)
(let ((mode (intern (yas/table-name (yas/template-table template))))) (let ((mode (intern (yas/table-name (yas/template-table template)))))
`(lambda () (interactive) (yas/expand-or-visit-from-menu ',mode ,(yas/template-uid template))))) `(lambda () (interactive) (yas/expand-or-visit-from-menu ',mode ,(yas/template-uid template)))))
(defun yas/expand-or-visit-from-menu (mode uid) (defun yas/expand-or-visit-from-menu (mode uid)
@ -1527,12 +1528,15 @@ TEMPLATES is a list of `yas/template'."
(unless (file-exists-p (concat directory "/" ".yas-skip")) (unless (file-exists-p (concat directory "/" ".yas-skip"))
(let* ((major-mode-and-parents (if mode-sym (let* ((major-mode-and-parents (if mode-sym
(cons mode-sym parents) (cons mode-sym parents)
(yas/compute-major-mode-and-parents (concat directory "/dummy")))) (yas/compute-major-mode-and-parents (concat directory
(yas/ignore-filenames-as-triggers (or yas/ignore-filenames-as-triggers "/dummy"))))
(file-exists-p (concat directory "/" ".yas-ignore-filenames-as-triggers")))) (yas/ignore-filenames-as-triggers
(or yas/ignore-filenames-as-triggers
(file-exists-p (concat directory "/"
".yas-ignore-filenames-as-triggers"))))
(snippet-defs nil)) (snippet-defs nil))
;; load the snippet files ;; load the snippet files
;; ;;
(with-temp-buffer (with-temp-buffer
(dolist (file (yas/subdirs directory 'no-subdirs-just-files)) (dolist (file (yas/subdirs directory 'no-subdirs-just-files))
(when (file-readable-p file) (when (file-readable-p file)
@ -1544,7 +1548,7 @@ TEMPLATES is a list of `yas/template'."
snippet-defs snippet-defs
(cdr major-mode-and-parents))) (cdr major-mode-and-parents)))
;; now recurse to a lower level ;; now recurse to a lower level
;; ;;
(dolist (subdir (yas/subdirs directory)) (dolist (subdir (yas/subdirs directory))
(yas/load-directory-1 subdir (yas/load-directory-1 subdir
(car major-mode-and-parents) (car major-mode-and-parents)
@ -1567,16 +1571,16 @@ content of the file is the template."
(when (interactive-p) (when (interactive-p)
(message "[yas] Loaded snippets from %s." directory))) (message "[yas] Loaded snippets from %s." directory)))
(defun yas/load-snippet-dirs () (defun yas/load-snippet-dirs ()
"Reload the directories listed in `yas/snippet-dirs' or "Reload the directories listed in `yas/snippet-dirs' or
prompt the user to select one." prompt the user to select one."
(if yas/snippet-dirs (if yas/snippet-dirs
(if (listp yas/snippet-dirs) (if (listp yas/snippet-dirs)
(dolist (directory (reverse yas/snippet-dirs)) (dolist (directory (reverse yas/snippet-dirs))
(yas/load-directory directory)) (yas/load-directory directory))
(yas/load-directory yas/snippet-dirs)) (yas/load-directory yas/snippet-dirs))
(call-interactively 'yas/load-directory))) (call-interactively 'yas/load-directory)))
(defun yas/reload-all (&optional reset-root-directory) (defun yas/reload-all (&optional reset-root-directory)
"Reload all snippets and rebuild the YASnippet menu. " "Reload all snippets and rebuild the YASnippet menu. "
(interactive "P") (interactive "P")
@ -1664,8 +1668,9 @@ Here's the default value for all the parameters:
(require 'yasnippet-bundle)`\" (require 'yasnippet-bundle)`\"
\"dropdown-list.el\") \"dropdown-list.el\")
" "
(interactive "ffind the yasnippet.el file: \nFTarget bundle file: \nDSnippet directory to bundle: \nMExtra code? \nfdropdown-library: ") (interactive (concat "ffind the yasnippet.el file: \nFTarget bundle file: "
"\nDSnippet directory to bundle: \nMExtra code? \nfdropdown-library: "))
(let* ((yasnippet (or yasnippet (let* ((yasnippet (or yasnippet
"yasnippet.el")) "yasnippet.el"))
(yasnippet-bundle (or yasnippet-bundle (yasnippet-bundle (or yasnippet-bundle
@ -1708,7 +1713,7 @@ Here's the default value for all the parameters:
(condition (fourth snippet)) (condition (fourth snippet))
(group (fifth snippet)) (group (fifth snippet))
(expand-env (sixth snippet)) (expand-env (sixth snippet))
(file nil) ;; (seventh snippet)) ;; omit on purpose (file nil) ;; (seventh snippet)) ;; omit on purpose
(binding (eighth snippet)) (binding (eighth snippet))
(uid (ninth snippet))) (uid (ninth snippet)))
(push `(,key (push `(,key
@ -1738,14 +1743,14 @@ Here's the default value for all the parameters:
;; bundle-specific provide and value for yas/dont-activate ;; bundle-specific provide and value for yas/dont-activate
(let ((bundle-feature-name (file-name-nondirectory (let ((bundle-feature-name (file-name-nondirectory
(file-name-sans-extension (file-name-sans-extension
yasnippet-bundle)))) yasnippet-bundle))))
(insert (pp-to-string `(set-default 'yas/dont-activate (insert (pp-to-string `(set-default 'yas/dont-activate
#'(lambda () #'(lambda ()
(and (or yas/snippet-dirs (and (or yas/snippet-dirs
(featurep ',(make-symbol bundle-feature-name))) (featurep ',(make-symbol bundle-feature-name)))
(null (yas/get-snippet-tables))))))) (null (yas/get-snippet-tables)))))))
(insert (pp-to-string `(provide ',(make-symbol bundle-feature-name))))) (insert (pp-to-string `(provide ',(make-symbol bundle-feature-name)))))
(insert ";;; " (insert ";;; "
(file-name-nondirectory yasnippet-bundle) (file-name-nondirectory yasnippet-bundle)
" ends here\n")))) " ends here\n"))))
@ -1819,11 +1824,11 @@ not need to be a real mode."
(unless (find parent (yas/table-parents snippet-table)) (unless (find parent (yas/table-parents snippet-table))
(push (yas/table-parents snippet-table) (push (yas/table-parents snippet-table)
parent))) parent)))
;; X) The keymap created here here is the menu keymap, it is also ;; X) The keymap created here here is the menu keymap, it is also
;; gotten/created according to MODE. Make a menu entry for ;; gotten/created according to MODE. Make a menu entry for
;; mode ;; mode
;; ;;
(when yas/use-menu (when yas/use-menu
(setq menu-keymap (yas/menu-keymap-get-create snippet-table)) (setq menu-keymap (yas/menu-keymap-get-create snippet-table))
(define-key yas/minor-mode-menu (vector mode) (define-key yas/minor-mode-menu (vector mode)
@ -1842,7 +1847,7 @@ not need to be a real mode."
(let* ((file (seventh snippet)) (let* ((file (seventh snippet))
(key (or (car snippet) (key (or (car snippet)
(unless yas/ignore-filenames-as-triggers (unless yas/ignore-filenames-as-triggers
(and file (and file
(file-name-sans-extension (file-name-nondirectory file)))))) (file-name-sans-extension (file-name-nondirectory file))))))
(name (or (third snippet) (name (or (third snippet)
(and file (and file
@ -1911,7 +1916,7 @@ not need to be a real mode."
,(yas/make-menu-binding template) ,(yas/make-menu-binding template)
:keys ,nil) :keys ,nil)
type))))) type)))))
(defun yas/show-menu-p (mode) (defun yas/show-menu-p (mode)
(cond ((eq yas/use-menu 'abbreviate) (cond ((eq yas/use-menu 'abbreviate)
(find mode (find mode
@ -1921,7 +1926,7 @@ not need to be a real mode."
((eq yas/use-menu 'real-modes) ((eq yas/use-menu 'real-modes)
(yas/real-mode? mode)) (yas/real-mode? mode))
(t (t
t))) t)))
(defun yas/delete-from-keymap (keymap name) (defun yas/delete-from-keymap (keymap name)
"Recursively delete items named NAME from KEYMAP and its submenus. "Recursively delete items named NAME from KEYMAP and its submenus.
@ -2059,7 +2064,8 @@ object satisfying `yas/field-p' to restrict the expansion to."
(setq yas/condition-cache-timestamp (current-time)) (setq yas/condition-cache-timestamp (current-time))
(multiple-value-bind (templates start end) (if field (multiple-value-bind (templates start end) (if field
(save-restriction (save-restriction
(narrow-to-region (yas/field-start field) (yas/field-end field)) (narrow-to-region (yas/field-start field)
(yas/field-end field))
(yas/current-key)) (yas/current-key))
(yas/current-key)) (yas/current-key))
(if templates (if templates
@ -2080,7 +2086,7 @@ If expansion fails, execute the previous binding for this key"
(yas/expand-or-prompt-for-template templates) (yas/expand-or-prompt-for-template templates)
(let ((yas/fallback-behavior 'call-other-command)) (let ((yas/fallback-behavior 'call-other-command))
(yas/fallback))))) (yas/fallback)))))
(defun yas/expand-or-prompt-for-template (templates &optional start end) (defun yas/expand-or-prompt-for-template (templates &optional start end)
"Expand one of TEMPLATES from START to END. "Expand one of TEMPLATES from START to END.
@ -2111,7 +2117,7 @@ Common gateway for `yas/expand-from-trigger-key' and
(keys-2 (and yas/trigger-key (keys-2 (and yas/trigger-key
from-trigger-key-p from-trigger-key-p
(stringp yas/trigger-key) (stringp yas/trigger-key)
(read-kbd-macro yas/trigger-key))) (read-kbd-macro yas/trigger-key)))
(command-1 (and keys-1 (key-binding keys-1))) (command-1 (and keys-1 (key-binding keys-1)))
(command-2 (and keys-2 (key-binding keys-2))) (command-2 (and keys-2 (key-binding keys-2)))
;; An (ugly) safety: prevents infinite recursion of ;; An (ugly) safety: prevents infinite recursion of
@ -2135,7 +2141,7 @@ Common gateway for `yas/expand-from-trigger-key' and
(t (t
;; also return nil if all the other fallbacks have failed ;; also return nil if all the other fallbacks have failed
nil))) nil)))
;;; Snippet development ;;; Snippet development
@ -2259,11 +2265,11 @@ lurking."
;; work. The real table, if it does not exist in ;; work. The real table, if it does not exist in
;; yas/tables will be created when the first snippet for ;; yas/tables will be created when the first snippet for
;; that mode is loaded. ;; that mode is loaded.
;; ;;
(unless (or table (gethash major-mode yas/tables)) (unless (or table (gethash major-mode yas/tables))
(setq tables (cons (yas/make-snippet-table (symbol-name major-mode)) (setq tables (cons (yas/make-snippet-table (symbol-name major-mode))
tables))) tables)))
(mapcar #'(lambda (table) (mapcar #'(lambda (table)
(cons table (cons table
(mapcar #'(lambda (subdir) (mapcar #'(lambda (subdir)
@ -2295,11 +2301,12 @@ lurking."
"" ""
(interactive "P") (interactive "P")
(let ((guessed-directories (yas/guess-snippet-directories))) (let ((guessed-directories (yas/guess-snippet-directories)))
(switch-to-buffer (format "*new snippet for %s*" (switch-to-buffer (format "*new snippet for %s*"
(if guessed-directories (if guessed-directories
(yas/table-name (car (first guessed-directories))) (yas/table-name (car (first guessed-directories)))
"unknown mode"))) "unknown mode")))
(erase-buffer)
(snippet-mode) (snippet-mode)
(setq yas/guessed-directories guessed-directories) (setq yas/guessed-directories guessed-directories)
(unless (and choose-instead-of-guess (unless (and choose-instead-of-guess
@ -2324,7 +2331,7 @@ With prefix arg SAME-WINDOW opens the buffer in the same window.
Because snippets can be loaded from many different locations, Because snippets can be loaded from many different locations,
this has to guess the correct directory using this has to guess the correct directory using
`yas/guess-snippet-directories', which returns a list of `yas/guess-snippet-directories', which returns a list of
options. options.
If any one of these exists, it is taken and `find-file' is called If any one of these exists, it is taken and `find-file' is called
there, otherwise, proposes to create the first option returned by there, otherwise, proposes to create the first option returned by
@ -2401,7 +2408,7 @@ With optional prefix argument KILL quit the window and buffer."
((and (boundp 'yas/current-template) ((and (boundp 'yas/current-template)
yas/current-template yas/current-template
(yas/template-p yas/current-template)) (yas/template-p yas/current-template))
(let ((parsed (yas/parse-template (yas/template-file yas/current-template)))) (let ((parsed (yas/parse-template (yas/template-file yas/current-template))))
;; ... just change its template, expand-env, condition, key, ;; ... just change its template, expand-env, condition, key,
;; keybinding and name. The group cannot be changed. ;; keybinding and name. The group cannot be changed.
@ -2485,7 +2492,7 @@ With optional prefix argument KILL quit the window and buffer."
(guessed-directories yas/guessed-directories) (guessed-directories yas/guessed-directories)
(option (or (and (not (y-or-n-p "Let yasnippet guess tables? ")) (option (or (and (not (y-or-n-p "Let yasnippet guess tables? "))
(first (first
(yas/guess-snippet-directories (yas/guess-snippet-directories
(some #'(lambda (fn) (some #'(lambda (fn)
(funcall fn "Choose any snippet table: " (funcall fn "Choose any snippet table: "
(let (res) (let (res)
@ -2527,11 +2534,13 @@ With optional prefix argument KILL quit the window and buffer."
(test-mode (or (and (car major-mode-and-parent) (test-mode (or (and (car major-mode-and-parent)
(fboundp (car major-mode-and-parent)) (fboundp (car major-mode-and-parent))
(car major-mode-and-parent)) (car major-mode-and-parent))
(and yas/guessed-directories
(intern (yas/table-name (car (first yas/guessed-directories)))))
(intern (read-from-minibuffer "[yas] please input a mode: ")))) (intern (read-from-minibuffer "[yas] please input a mode: "))))
(template (and parsed (template (and parsed
(fboundp test-mode) (fboundp test-mode)
(yas/populate-template (yas/make-blank-template) (yas/populate-template (yas/make-blank-template)
:table nil ;; an ephemeral snippet has no table... :table nil ;; no tables for ephemeral snippets
:key (first parsed) :key (first parsed)
:content (second parsed) :content (second parsed)
:name (third parsed) :name (third parsed)
@ -2541,7 +2550,7 @@ With optional prefix argument KILL quit the window and buffer."
(set-buffer (switch-to-buffer buffer-name)) (set-buffer (switch-to-buffer buffer-name))
(erase-buffer) (erase-buffer)
(setq buffer-undo-list nil) (setq buffer-undo-list nil)
(funcall test-mode) (condition-case nil (funcall test-mode) (error nil))
(yas/expand-snippet (yas/template-content template) (yas/expand-snippet (yas/template-content template)
(point-min) (point-min)
(point-max) (point-max)
@ -2569,7 +2578,7 @@ With optional prefix argument KILL quit the window and buffer."
(original-buffer (current-buffer)) (original-buffer (current-buffer))
(continue t) (continue t)
(yas/condition-cache-timestamp (current-time))) (yas/condition-cache-timestamp (current-time)))
(with-current-buffer buffer (with-current-buffer buffer
(let ((buffer-read-only nil)) (let ((buffer-read-only nil))
(erase-buffer) (erase-buffer)
(cond ((not by-name-hash) (cond ((not by-name-hash)
@ -2684,7 +2693,7 @@ Otherwise throw exception."
(yas/throw (format "[yas] field only allows %s" possibilities)))) (yas/throw (format "[yas] field only allows %s" possibilities))))
(defun yas/ephemeral-field (number) (defun yas/ephemeral-field (number)
"Automatically exit snippet when something is type in field NUMBER. "Automatically exit snippet when something is typed in field NUMBER.
To be used as a primary field transformation." To be used as a primary field transformation."
(when yas/modified-p (yas/exit-snippet (first (yas/snippets-at-point))) (yas/field-value number))) (when yas/modified-p (yas/exit-snippet (first (yas/snippets-at-point))) (yas/field-value number)))
@ -2808,8 +2817,7 @@ With optional string TEXT do it in that string."
"Sort the fields of SNIPPET in navigation order." "Sort the fields of SNIPPET in navigation order."
(setf (yas/snippet-fields snippet) (setf (yas/snippet-fields snippet)
(sort (yas/snippet-fields snippet) (sort (yas/snippet-fields snippet)
'(lambda (field1 field2) #'yas/snippet-field-compare)))
(yas/snippet-field-compare field1 field2)))))
(defun yas/snippet-field-compare (field1 field2) (defun yas/snippet-field-compare (field1 field2)
"Compare two fields. The field with a number is sorted first. "Compare two fields. The field with a number is sorted first.
@ -2819,10 +2827,11 @@ have, compare through the field's start point"
(n2 (yas/field-number field2))) (n2 (yas/field-number field2)))
(if n1 (if n1
(if n2 (if n2
(< n1 n2) (or (zerop n2) (and (not (zerop n1))
t) (< n1 n2)))
(not (zerop n1)))
(if n2 (if n2
nil (zerop n2)
(< (yas/field-start field1) (< (yas/field-start field1)
(yas/field-start field2)))))) (yas/field-start field2))))))
@ -3133,7 +3142,7 @@ Otherwise deletes a character normally by calling `delete-char'."
;; fields as modified, too. If the childen have mirrors-in-fields ;; fields as modified, too. If the childen have mirrors-in-fields
;; this prevents them from updating erroneously (we're skipping and ;; this prevents them from updating erroneously (we're skipping and
;; deleting!). ;; deleting!).
;; ;;
(yas/mark-this-and-children-modified field) (yas/mark-this-and-children-modified field)
(delete-region (yas/field-start field) (yas/field-end field))) (delete-region (yas/field-start field) (yas/field-end field)))
@ -3176,13 +3185,19 @@ Only clears the field if it hasn't been modified and it point it
at field start. This hook doesn't do anything if an undo is in at field start. This hook doesn't do anything if an undo is in
progress." progress."
(unless (yas/undo-in-progress) (unless (yas/undo-in-progress)
(let ((field (overlay-get yas/active-field-overlay 'yas/field))) (let* ((field (overlay-get yas/active-field-overlay 'yas/field))
(number (and field (yas/field-number field)))
(snippet (overlay-get yas/active-field-overlay 'yas/snippet)))
(cond (after? (cond (after?
(yas/advance-end-maybe field (overlay-end overlay)) (yas/advance-end-maybe field (overlay-end overlay))
;;; primary field transform: normal calls to expression ;; primary field transform: normal calls to expression or
(let ((saved-point (point))) ;; force an exit on next `post-command-hook' if the
(yas/field-update-display field (car (yas/snippets-at-point))) ;; number is 0
(goto-char saved-point)) (if (and number (zerop number))
(setf (yas/snippet-force-exit snippet) t)
(let ((saved-point (point)))
(yas/field-update-display field (car (yas/snippets-at-point)))
(goto-char saved-point)))
(yas/update-mirrors (car (yas/snippets-at-point)))) (yas/update-mirrors (car (yas/snippets-at-point))))
(field (field
(when (and (not after?) (when (and (not after?)
@ -3320,7 +3335,7 @@ considered when expanding the snippet."
(cond ((listp content) (cond ((listp content)
;; x) This is a snippet-command ;; x) This is a snippet-command
;; ;;
(yas/eval-lisp-no-saves content)) (yas/eval-lisp-no-saves content))
(t (t
;; x) This is a snippet-snippet :-) ;; x) This is a snippet-snippet :-)
@ -3651,18 +3666,16 @@ Meant to be called in a narrowed buffer, does various passes"
(defun yas/indent-according-to-mode (snippet-markers) (defun yas/indent-according-to-mode (snippet-markers)
"Indent current line according to mode, preserving "Indent current line according to mode, preserving
SNIPPET-MARKERS." SNIPPET-MARKERS."
;; XXX: Here seems to be the indent problem: ;;; Apropos indenting problems....
;; ;;
;; `indent-according-to-mode' uses whatever ;; `indent-according-to-mode' uses whatever `indent-line-function'
;; `indent-line-function' is available. Some ;; is available. Some implementations of these functions delete text
;; implementations of these functions delete text ;; before they insert. If there happens to be a marker just after
;; before they insert. If there happens to be a marker ;; the text being deleted, the insertion actually happens after the
;; just after the text being deleted, the insertion ;; marker, which misplaces it.
;; actually happens after the marker, which misplaces
;; it.
;; ;;
;; This would also happen if we had used overlays with ;; This would also happen if we had used overlays with the
;; the `front-advance' property set to nil. ;; `front-advance' property set to nil.
;; ;;
;; This is why I have these `trouble-markers', they are the ones at ;; This is why I have these `trouble-markers', they are the ones at
;; they are the ones at the first non-whitespace char at the line ;; they are the ones at the first non-whitespace char at the line
@ -3817,7 +3830,8 @@ When multiple expressions are found, only the last one counts."
(not (save-match-data (not (save-match-data
(eq (string-match "$[ \t\n]*(" (eq (string-match "$[ \t\n]*("
(match-string-no-properties 2)) 0))) (match-string-no-properties 2)) 0)))
(not (and number (zerop number))) ;; allow ${0: some exit text}
;; (not (and number (zerop number)))
(yas/make-field number (yas/make-field number
(yas/make-marker (match-beginning 2)) (yas/make-marker (match-beginning 2))
(yas/make-marker (1- real-match-end-0)) (yas/make-marker (1- real-match-end-0))
@ -3837,7 +3851,7 @@ When multiple expressions are found, only the last one counts."
;; if we entered from a parent field, now search for the ;; if we entered from a parent field, now search for the
;; `yas/multi-dollar-lisp-expression-regexp'. THis is used for ;; `yas/multi-dollar-lisp-expression-regexp'. THis is used for
;; primary field transformations ;; primary field transformations
;; ;;
(when parent-field (when parent-field
(save-excursion (save-excursion
(while (re-search-forward yas/multi-dollar-lisp-expression-regexp nil t) (while (re-search-forward yas/multi-dollar-lisp-expression-regexp nil t)
@ -3850,7 +3864,7 @@ When multiple expressions are found, only the last one counts."
;; 2. we really make sure we have either two '$' or some ;; 2. we really make sure we have either two '$' or some
;; text and a '$' after the colon ':'. This is a FIXME: work ;; text and a '$' after the colon ':'. This is a FIXME: work
;; my regular expressions and end these ugly hacks. ;; my regular expressions and end these ugly hacks.
;; ;;
(when (and real-match-end-1 (when (and real-match-end-1
(not (member (cons (match-beginning 0) (not (member (cons (match-beginning 0)
real-match-end-1) real-match-end-1)
@ -3882,13 +3896,13 @@ When multiple expressions are found, only the last one counts."
(buffer-substring-no-properties (match-beginning 2) (buffer-substring-no-properties (match-beginning 2)
(1- real-match-end-0)))))))) (1- real-match-end-0))))))))
(when brand-new-mirror (when brand-new-mirror
(push brand-new-mirror (push brand-new-mirror
(yas/field-mirrors field)) (yas/field-mirrors field))
(yas/calculate-mirrors-in-fields snippet brand-new-mirror) (yas/calculate-mirrors-in-fields snippet brand-new-mirror)
(push (cons (match-beginning 0) real-match-end-0) yas/dollar-regions))))) (push (cons (match-beginning 0) real-match-end-0) yas/dollar-regions)))))
(defun yas/simple-mirror-parse-create (snippet) (defun yas/simple-mirror-parse-create (snippet)
"Parse the simple \"$n\" mirrors and the exit-marker." "Parse the simple \"$n\" fields/mirrors/exitmarkers."
(while (re-search-forward yas/simple-mirror-regexp nil t) (while (re-search-forward yas/simple-mirror-regexp nil t)
(let ((number (string-to-number (match-string-no-properties 1)))) (let ((number (string-to-number (match-string-no-properties 1))))
(cond ((zerop number) (cond ((zerop number)
@ -3914,7 +3928,7 @@ When multiple expressions are found, only the last one counts."
(yas/make-marker (match-beginning 0)) (yas/make-marker (match-beginning 0))
(yas/make-marker (match-beginning 0)) (yas/make-marker (match-beginning 0))
nil))) nil)))
(push brand-new-mirror (push brand-new-mirror
(yas/field-mirrors field)) (yas/field-mirrors field))
(yas/calculate-mirrors-in-fields snippet brand-new-mirror)) (yas/calculate-mirrors-in-fields snippet brand-new-mirror))
(push (yas/make-field number (push (yas/make-field number
@ -3947,11 +3961,11 @@ When multiple expressions are found, only the last one counts."
(let ((inhibit-modification-hooks t) (let ((inhibit-modification-hooks t)
(mirror-parent-field (yas/mirror-parent-field mirror))) (mirror-parent-field (yas/mirror-parent-field mirror)))
;; updatte this mirror ;; updatte this mirror
;; ;;
(yas/mirror-update-display mirror field) (yas/mirror-update-display mirror field)
;; for mirrors-in-fields: schedule a possible ;; for mirrors-in-fields: schedule a possible
;; parent field for reupdting later on ;; parent field for reupdting later on
;; ;;
(when mirror-parent-field (when mirror-parent-field
(add-to-list 'fields mirror-parent-field 'append #'eq)) (add-to-list 'fields mirror-parent-field 'append #'eq))
;; `yas/place-overlays' is needed if the active field and ;; `yas/place-overlays' is needed if the active field and
@ -4053,16 +4067,17 @@ that the rest of `yas/post-command-handler' runs.")
(put 'yas/expand 'function-documentation '(yas/expand-from-trigger-key-doc)) (put 'yas/expand 'function-documentation '(yas/expand-from-trigger-key-doc))
(defun yas/expand-from-trigger-key-doc () (defun yas/expand-from-trigger-key-doc ()
"A doc synthethizer for `yas/expand-from-trigger-key-doc'." "A doc synthethizer for `yas/expand-from-trigger-key-doc'."
(let ((fallback-description (cond ((eq yas/fallback-behavior 'call-other-command) (let ((fallback-description
(let* ((yas/minor-mode nil) (cond ((eq yas/fallback-behavior 'call-other-command)
(fallback (key-binding (read-kbd-macro yas/trigger-key)))) (let* ((yas/minor-mode nil)
(or (and fallback (fallback (key-binding (read-kbd-macro yas/trigger-key))))
(format " call command `%s'." (pp-to-string fallback))) (or (and fallback
" do nothing."))) (format " call command `%s'." (pp-to-string fallback)))
((eq yas/fallback-behavior 'return-nil) " do nothing.")))
", do nothing.") ((eq yas/fallback-behavior 'return-nil)
(t ", do nothing.")
", defer to `yas/fallback-behaviour' :-)")))) (t
", defer to `yas/fallback-behaviour' :-)"))))
(concat "Expand a snippet before point. If no snippet (concat "Expand a snippet before point. If no snippet
expansion is possible," expansion is possible,"
fallback-description fallback-description