mirror of
https://github.com/joaotavora/yasnippet.git
synced 2025-10-13 21:13:04 +00:00
Merge branch 'master' into tighter-tab
This commit is contained in:
commit
7f62611921
@ -13,7 +13,7 @@ SQL, LaTeX, HTML, CSS and more. The snippet syntax is inspired from
|
||||
|
||||
[textmate-snippets]: http://manual.macromates.com/en/snippets
|
||||
[import-docs]: http://yasnippet.googlecode.com/svn/trunk/doc/snippet-development.html#importing-textmate-snippets
|
||||
[youtube-demo]: http://www.youtube.com/watch?v=76Ygeg9miao
|
||||
[youtube-demo]: http://www.youtube.com/watch?v=ZCGmZK4V7Sg
|
||||
[high-res-demo]: http://yasnippet.googlecode.com/files/yas_demo.avi
|
||||
|
||||
# Installation
|
||||
|
252
yasnippet-tests.el
Executable file
252
yasnippet-tests.el
Executable file
@ -0,0 +1,252 @@
|
||||
;;; yasnippet-tests.el --- some yasnippet tests
|
||||
|
||||
;; Copyright (C) 2012 João Távora
|
||||
|
||||
;; Author: João Távora <joaot@siscog.pt>
|
||||
;; Keywords: emulations, convenience
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Test basic snippet mechanics and the loading system
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'yasnippet)
|
||||
(require 'ert)
|
||||
(require 'ert-x)
|
||||
|
||||
|
||||
|
||||
;;; Snippet mechanics
|
||||
|
||||
(ert-deftest field-navigation ()
|
||||
(with-temp-buffer
|
||||
(yas/minor-mode 1)
|
||||
(yas/expand-snippet "${1:brother} from another ${2:mother}")
|
||||
(should (string= (buffer-substring-no-properties (point-min) (point-max))
|
||||
"brother from another mother"))
|
||||
|
||||
(should (looking-at "brother"))
|
||||
(ert-simulate-command '(yas/next-field-or-maybe-expand))
|
||||
(should (looking-at "mother"))
|
||||
(ert-simulate-command '(yas/prev-field))
|
||||
(should (looking-at "brother"))))
|
||||
|
||||
(ert-deftest simple-mirror ()
|
||||
(with-temp-buffer
|
||||
(yas/minor-mode 1)
|
||||
(yas/expand-snippet "${1:brother} from another $1")
|
||||
(should (string= (buffer-substring-no-properties (point-min) (point-max))
|
||||
"brother from another brother"))
|
||||
(ert-simulate-command `(yas/mock-insert "bla"))
|
||||
(should (string= (buffer-substring-no-properties (point-min) (point-max))
|
||||
"bla from another bla"))))
|
||||
|
||||
(ert-deftest mirror-with-transformation ()
|
||||
(with-temp-buffer
|
||||
(yas/minor-mode 1)
|
||||
(yas/expand-snippet "${1:brother} from another ${1:$(upcase yas/text)}")
|
||||
(should (string= (buffer-substring-no-properties (point-min) (point-max))
|
||||
"brother from another BROTHER"))
|
||||
(ert-simulate-command `(yas/mock-insert "bla"))
|
||||
(should (string= (buffer-substring-no-properties (point-min) (point-max))
|
||||
"bla from another BLA"))))
|
||||
|
||||
(ert-deftest nested-placeholders-kill-superfield ()
|
||||
(with-temp-buffer
|
||||
(yas/minor-mode 1)
|
||||
(yas/expand-snippet "brother from ${2:another ${3:mother}}!")
|
||||
(should (string= (buffer-substring-no-properties (point-min) (point-max))
|
||||
"brother from another mother!"))
|
||||
(ert-simulate-command `(yas/mock-insert "bla"))
|
||||
(should (string= (buffer-substring-no-properties (point-min) (point-max))
|
||||
"brother from bla!"))))
|
||||
|
||||
(ert-deftest nested-placeholders-use-subfield ()
|
||||
(with-temp-buffer
|
||||
(yas/minor-mode 1)
|
||||
(yas/expand-snippet "brother from ${2:another ${3:mother}}!")
|
||||
(ert-simulate-command '(yas/next-field-or-maybe-expand))
|
||||
(ert-simulate-command `(yas/mock-insert "bla"))
|
||||
(should (string= (buffer-substring-no-properties (point-min) (point-max))
|
||||
"brother from another bla!"))))
|
||||
|
||||
;; (ert-deftest in-snippet-undo ()
|
||||
;; (with-temp-buffer
|
||||
;; (yas/minor-mode 1)
|
||||
;; (yas/expand-snippet "brother from ${2:another ${3:mother}}!")
|
||||
;; (ert-simulate-command '(yas/next-field-or-maybe-expand))
|
||||
;; (ert-simulate-command `(yas/mock-insert "bla"))
|
||||
;; (ert-simulate-command '(undo))
|
||||
;; (should (string= (buffer-substring-no-properties (point-min) (point-max))
|
||||
;; "brother from another mother!"))))
|
||||
|
||||
|
||||
;;; Misc tests
|
||||
;;;
|
||||
|
||||
(ert-deftest protection-overlay-no-cheating ()
|
||||
"Protection overlays at the very end of the buffer, are dealt by cheatingly inserting a newline!
|
||||
|
||||
TODO: correct this bug!"
|
||||
:expected-result :failed
|
||||
(with-temp-buffer
|
||||
(yas/minor-mode 1)
|
||||
(yas/expand-snippet "${2:brother} from another ${1:mother}")
|
||||
(should (string= (buffer-substring-no-properties (point-min) (point-max))
|
||||
"brother from another mother") ;; no newline should be here!
|
||||
)))
|
||||
|
||||
;;; Loading
|
||||
;;;
|
||||
(defmacro with-some-interesting-snippet-dirs (&rest body)
|
||||
`(yas/saving-variables
|
||||
(with-snippet-dirs
|
||||
'((".emacs.d/snippets"
|
||||
("c-mode"
|
||||
(".yas-parents" . "cc-mode")
|
||||
("printf" . "printf($1);"))
|
||||
("emacs-lisp-mode" ("ert-deftest" . "(ert-deftest ${1:name} () $0)"))
|
||||
("lisp-interaction-mode" (".yas-parents" . "emacs-lisp-mode")))
|
||||
("library/snippets"
|
||||
("c-mode" (".yas-parents" . "c++-mode"))
|
||||
("cc-mode" ("def" . "# define"))
|
||||
("emacs-lisp-mode" ("dolist" . "(dolist)"))
|
||||
("lisp-interaction-mode" ("sc" . "brother from another mother"))))
|
||||
,@body)))
|
||||
|
||||
(ert-deftest basic-jit-loading ()
|
||||
"Test basic loading and expansion of snippets"
|
||||
(with-some-interesting-snippet-dirs
|
||||
(yas/reload-all)
|
||||
(yas/basic-jit-loading-1)))
|
||||
|
||||
(ert-deftest basic-jit-loading-with-compiled-snippets ()
|
||||
"Test basic loading and expansion of snippets"
|
||||
(with-some-interesting-snippet-dirs
|
||||
(yas/reload-all)
|
||||
(yas/recompile-all)
|
||||
(flet ((yas/load-directory-2
|
||||
(&rest dummies)
|
||||
(ert-fail "yas/load-directory-2 shouldn't be called when snippets have been compiled")))
|
||||
(yas/reload-all)
|
||||
(yas/basic-jit-loading-1))))
|
||||
|
||||
(defun yas/basic-jit-loading-1 (&optional compile)
|
||||
(with-temp-buffer
|
||||
(should (= 4 (hash-table-count yas/scheduled-jit-loads)))
|
||||
(should (= 0 (hash-table-count yas/tables)))
|
||||
(lisp-interaction-mode)
|
||||
(yas/minor-mode 1)
|
||||
(should (= 2 (hash-table-count yas/scheduled-jit-loads)))
|
||||
(should (= 2 (hash-table-count yas/tables)))
|
||||
(should (= 1 (hash-table-count (yas/table-uuidhash (gethash 'lisp-interaction-mode yas/tables)))))
|
||||
(should (= 2 (hash-table-count (yas/table-uuidhash (gethash 'emacs-lisp-mode yas/tables)))))
|
||||
(yas/should-expand '(("sc" . "brother from another mother")
|
||||
("dolist" . "(dolist)")
|
||||
("ert-deftest" . "(ert-deftest name () )")))
|
||||
(c-mode)
|
||||
(yas/minor-mode 1)
|
||||
(should (= 0 (hash-table-count yas/scheduled-jit-loads)))
|
||||
(should (= 4 (hash-table-count yas/tables)))
|
||||
(should (= 1 (hash-table-count (yas/table-uuidhash (gethash 'c-mode yas/tables)))))
|
||||
(should (= 1 (hash-table-count (yas/table-uuidhash (gethash 'cc-mode yas/tables)))))
|
||||
(yas/should-expand '(("printf" . "printf();")
|
||||
("def" . "# define")))
|
||||
(yas/should-not-expand '("sc" "dolist" "ert-deftest"))))
|
||||
|
||||
;;; Helpers
|
||||
;;;
|
||||
|
||||
(defun yas/should-expand (keys-and-expansions)
|
||||
(dolist (key-and-expansion keys-and-expansions)
|
||||
(yas/exit-all-snippets)
|
||||
(erase-buffer)
|
||||
(insert (car key-and-expansion))
|
||||
(let ((yas/fallback-behavior nil))
|
||||
(ert-simulate-command '(yas/expand)))
|
||||
(should (string= (buffer-substring-no-properties (point-min) (point-max))
|
||||
(cdr key-and-expansion))))
|
||||
(yas/exit-all-snippets))
|
||||
|
||||
(defun yas/should-not-expand (keys)
|
||||
(dolist (key keys)
|
||||
(yas/exit-all-snippets)
|
||||
(erase-buffer)
|
||||
(insert key)
|
||||
(let ((yas/fallback-behavior nil))
|
||||
(ert-simulate-command '(yas/expand)))
|
||||
(should (string= (buffer-substring-no-properties (point-min) (point-max)) key))))
|
||||
|
||||
(defun yas/mock-insert (string)
|
||||
(interactive)
|
||||
(do ((i 0 (1+ i)))
|
||||
((= i (length string)))
|
||||
(insert (aref string i))))
|
||||
|
||||
(defun yas/make-file-or-dirs (ass)
|
||||
(let ((file-or-dir-name (car ass))
|
||||
(content (cdr ass)))
|
||||
(cond ((listp content)
|
||||
(make-directory file-or-dir-name 'parents)
|
||||
(let ((default-directory (concat default-directory "/" file-or-dir-name)))
|
||||
(mapc #'yas/make-file-or-dirs content)))
|
||||
((stringp content)
|
||||
(with-current-buffer (find-file file-or-dir-name)
|
||||
(insert content)
|
||||
(save-buffer)
|
||||
(kill-buffer (current-buffer))))
|
||||
(t
|
||||
(message "[yas] oops don't know this content")))))
|
||||
|
||||
|
||||
(defun yas/variables ()
|
||||
(let ((syms))
|
||||
(mapatoms #'(lambda (sym)
|
||||
(if (and (string-match "^yas/[^/]" (symbol-name sym))
|
||||
(boundp sym))
|
||||
(push sym syms))))
|
||||
syms))
|
||||
|
||||
|
||||
(defmacro yas/saving-variables (&rest body)
|
||||
`(let ,(mapcar #'(lambda (sym)
|
||||
`(,sym ,sym))
|
||||
(yas/variables))
|
||||
,@body))
|
||||
|
||||
(defmacro with-snippet-dirs (dirs &rest body)
|
||||
`(let ((default-directory (make-temp-file "yasnippet-fixture" t)))
|
||||
(unwind-protect
|
||||
(progn
|
||||
(setq yas/snippet-dirs ',(mapcar #'car (cadr dirs)))
|
||||
(mapc #'yas/make-file-or-dirs ,dirs)
|
||||
,@body)
|
||||
(when (>= emacs-major-version 23)
|
||||
(delete-directory default-directory 'recursive)))))
|
||||
|
||||
;;; Older emacsen
|
||||
;;;
|
||||
(unless (fboundp 'special-mode)
|
||||
(define-minor-mode special-mode "Just a placeholder for something isn't in emacs 22"))
|
||||
|
||||
;;; btw to test this in emacs22 mac osx:
|
||||
;;; curl -L -O https://github.com/mirrors/emacs/raw/master/lisp/emacs-lisp/ert.el
|
||||
;;; curl -L -O https://github.com/mirrors/emacs/raw/master/lisp/emacs-lisp/ert-x.el
|
||||
;;; /usr/bin/emacs -nw -Q -L . -l yasnippet-tests.el --batch -e ert
|
||||
|
||||
(provide 'yasnippet-tests)
|
||||
;;; yasnippet-tests.el ends here
|
517
yasnippet.el
517
yasnippet.el
@ -29,7 +29,7 @@
|
||||
;;; Commentary:
|
||||
|
||||
;; Basic steps to setup:
|
||||
;;
|
||||
;;
|
||||
;; (add-to-list 'load-path
|
||||
;; "~/.emacs.d/plugins/yasnippet")
|
||||
;; (require 'yasnippet)
|
||||
@ -181,6 +181,7 @@ as the default for storing the user's new snippets."
|
||||
(equal old new))
|
||||
(yas/reload-all)))))
|
||||
(defun yas/snippet-dirs ()
|
||||
"Returns `yas/snippet-dirs' (which see) as a list."
|
||||
(if (listp yas/snippet-dirs) yas/snippet-dirs (list yas/snippet-dirs)))
|
||||
(defvaralias 'yas/root-directory 'yas/snippet-dirs)
|
||||
|
||||
@ -722,42 +723,55 @@ snippet itself contains a condition that returns the symbol
|
||||
))
|
||||
|
||||
(defvar yas/tables (make-hash-table)
|
||||
"A hash table of MAJOR-MODE symbols to `yas/table' objects.")
|
||||
"A hash table of mode symbols to `yas/table' objects.")
|
||||
|
||||
(defvar yas/parents (make-hash-table)
|
||||
"A hash table of mode symbols do lists of direct parent mode symbols.
|
||||
|
||||
This list is populated when reading the \".yas-parents\" files
|
||||
found when traversing snippet directories with
|
||||
`yas/load-directory'.
|
||||
|
||||
There might be additionalal parenting information stored in the
|
||||
`derived-mode-parent' property of some mode symbols, but that is
|
||||
not recorded here.")
|
||||
|
||||
(defvar yas/direct-keymaps (list)
|
||||
"Keymap alist supporting direct snippet keybindings.
|
||||
|
||||
This variable is is placed `emulation-mode-map-alists'.
|
||||
This variable is is placed in `emulation-mode-map-alists'.
|
||||
|
||||
Its elements looks like (TABLE-NAME . KEYMAP) and are
|
||||
calculated when loading snippets. TABLE-NAME is a variable
|
||||
set buffer-locally when entering `yas/minor-mode'. KEYMAP binds
|
||||
all defined direct keybindings to the command
|
||||
`yas/expand-from-keymap', which acts similarly to `yas/expand'")
|
||||
Its elements looks like (TABLE-NAME . KEYMAP). They're
|
||||
instantiated on `yas/reload-all' but KEYMAP is added to only when
|
||||
loading snippets. `yas//direct-TABLE-NAME' is then a variable set
|
||||
buffer-locally when entering `yas/minor-mode'. KEYMAP binds all
|
||||
defined direct keybindings to the command
|
||||
`yas/expand-from-keymap' which then which snippet to expand.")
|
||||
|
||||
(defun yas/direct-keymaps-reload ()
|
||||
"Force reload the direct keybinding for active snippet tables."
|
||||
(interactive)
|
||||
(setq yas/direct-keymaps nil)
|
||||
(maphash #'(lambda (name table)
|
||||
(mapc #'(lambda (table)
|
||||
(push (cons (intern (format "yas//direct-%s" name))
|
||||
(yas/table-direct-keymap table))
|
||||
yas/direct-keymaps))
|
||||
(cons table (yas/table-get-all-parents table))))
|
||||
(push (cons (intern (format "yas//direct-%s" name))
|
||||
(yas/table-direct-keymap table))
|
||||
yas/direct-keymaps))
|
||||
yas/tables))
|
||||
|
||||
(defun yas/direct-keymaps-set-vars ()
|
||||
(defun yas/modes-to-activate ()
|
||||
"Compute list of mode symbols that are active for `yas/expand'
|
||||
and friends."
|
||||
(let ((modes-to-activate (list major-mode))
|
||||
(mode major-mode))
|
||||
(while (setq mode (get mode 'derived-mode-parent))
|
||||
(push mode modes-to-activate))
|
||||
(dolist (mode (yas/extra-modes))
|
||||
(push mode modes-to-activate))
|
||||
(dolist (mode modes-to-activate)
|
||||
(let ((name (intern (format "yas//direct-%s" mode))))
|
||||
(set-default name nil)
|
||||
(set (make-local-variable name) t)))))
|
||||
(remove-duplicates
|
||||
(append modes-to-activate
|
||||
(mapcan #'(lambda (mode)
|
||||
(yas/all-parents mode))
|
||||
modes-to-activate)))))
|
||||
|
||||
(defvar yas/minor-mode-hook nil
|
||||
"Hook run when yas/minor-mode is turned on")
|
||||
@ -795,7 +809,15 @@ Key bindings:
|
||||
;; `yas/direct-keymaps-set-vars'.
|
||||
;;
|
||||
(add-hook 'post-command-hook 'yas/post-command-handler nil t)
|
||||
(add-hook 'yas/minor-mode-hook 'yas/direct-keymaps-set-vars-runonce 'append))
|
||||
;; Set the `yas//direct-%s' vars for direct keymap expansion
|
||||
;;
|
||||
(dolist (mode (yas/modes-to-activate))
|
||||
(let ((name (intern (format "yas//direct-%s" mode))))
|
||||
(set-default name nil)
|
||||
(set (make-local-variable name) t)))
|
||||
;; Perform JIT loads
|
||||
;;
|
||||
(yas/load-pending-jits))
|
||||
(t
|
||||
;; Uninstall the direct keymaps and the post-command hook
|
||||
;;
|
||||
@ -805,9 +827,6 @@ Key bindings:
|
||||
;;
|
||||
(setq yas/trigger-key-overriding nil))))
|
||||
|
||||
(defun yas/direct-keymaps-set-vars-runonce ()
|
||||
(yas/direct-keymaps-set-vars)
|
||||
(remove-hook 'yas/minor-mode-hook 'yas/direct-keymaps-set-vars-runonce))
|
||||
|
||||
(defvar yas/dont-activate nil
|
||||
"If non-nil don't let `yas/minor-mode-on' active yas for this buffer.
|
||||
@ -836,10 +855,15 @@ Do this unless `yas/dont-activate' is truish "
|
||||
:group 'yasnippet
|
||||
:require 'yasnippet)
|
||||
|
||||
(add-hook 'yas/global-mode-hook 'yas/reload-all-maybe)
|
||||
(defun yas/reload-all-maybe ()
|
||||
(if yas/global-mode
|
||||
(yas/reload-all)))
|
||||
(defadvice yas/global-mode (before yas/reload-with-jit (arg) activate)
|
||||
(cond ((and arg
|
||||
(numberp arg)
|
||||
(> arg 1))
|
||||
;; explicitly enabling
|
||||
(yas/reload-all 'with-jit))
|
||||
((not yas/global-mode)
|
||||
;; toggling
|
||||
(yas/reload-all 'with-jit))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Major mode stuff
|
||||
@ -883,10 +907,10 @@ Do this unless `yas/dont-activate' is truish "
|
||||
|
||||
(define-derived-mode snippet-mode text-mode "Snippet"
|
||||
"A mode for editing yasnippets"
|
||||
(set-syntax-table (standard-syntax-table))
|
||||
(setq font-lock-defaults '(yas/font-lock-keywords))
|
||||
(set (make-local-variable 'require-final-newline) nil)
|
||||
(use-local-map snippet-mode-map))
|
||||
(set (make-local-variable 'comment-start) "#")
|
||||
(set (make-local-variable 'comment-start-skip) "#+[\t ]*"))
|
||||
|
||||
|
||||
|
||||
@ -894,7 +918,6 @@ Do this unless `yas/dont-activate' is truish "
|
||||
|
||||
(defstruct (yas/template (:constructor yas/make-blank-template))
|
||||
"A template for a snippet."
|
||||
table
|
||||
key
|
||||
content
|
||||
name
|
||||
@ -904,8 +927,9 @@ Do this unless `yas/dont-activate' is truish "
|
||||
keybinding
|
||||
uuid
|
||||
menu-binding-pair
|
||||
group ;; as dictated by the #group: directive or .yas-make-groups
|
||||
group ;; as dictated by the #group: directive or .yas-make-groups
|
||||
perm-group ;; as dictated by `yas/define-menu'
|
||||
table
|
||||
)
|
||||
|
||||
(defun yas/populate-template (template &rest args)
|
||||
@ -938,11 +962,6 @@ Has the following fields:
|
||||
another hash of (NAME . TEMPLATE) where NAME is the snippet's
|
||||
name and TEMPLATE is a `yas/template' object.
|
||||
|
||||
`yas/table-parents'
|
||||
|
||||
A list of tables considered parents of this table: i.e. when
|
||||
searching for expansions they are searched as well.
|
||||
|
||||
`yas/table-direct-keymap'
|
||||
|
||||
A keymap for the snippets in this table that have direct
|
||||
@ -1056,7 +1075,7 @@ Also takes care of adding and updaring to the associated menu."
|
||||
(yas/delete-from-keymap keymap (yas/template-uuid template))
|
||||
|
||||
;; Add necessary subgroups as necessary.
|
||||
;;
|
||||
;;
|
||||
(dolist (subgroup group)
|
||||
(let ((subgroup-keymap (lookup-key keymap (vector (make-symbol subgroup)))))
|
||||
(unless (and subgroup-keymap
|
||||
@ -1065,9 +1084,9 @@ Also takes care of adding and updaring to the associated menu."
|
||||
(define-key keymap (vector (make-symbol subgroup))
|
||||
`(menu-item ,subgroup ,subgroup-keymap)))
|
||||
(setq keymap subgroup-keymap)))
|
||||
|
||||
|
||||
;; Add this entry to the keymap
|
||||
;;
|
||||
;;
|
||||
(let ((menu-binding-pair (yas/snippet-menu-binding-pair-get-create template)))
|
||||
(define-key keymap (vector (make-symbol (yas/template-uuid template))) (car menu-binding-pair))))))
|
||||
|
||||
@ -1098,8 +1117,7 @@ string and TEMPLATE is a `yas/template' structure."
|
||||
(save-match-data
|
||||
(eval condition))))
|
||||
(error (progn
|
||||
(message (format "[yas] error in condition evaluation: %s"
|
||||
(error-message-string err)))
|
||||
(yas/message 1 "Error in condition evaluation: %s" (error-message-string err))
|
||||
nil))))
|
||||
|
||||
|
||||
@ -1144,12 +1162,11 @@ conditions to filter out potential expansions."
|
||||
(t
|
||||
(eq requirement result)))))
|
||||
|
||||
(defun yas/table-get-all-parents (table)
|
||||
"Returns a list of all parent tables of TABLE"
|
||||
(let ((parents (yas/table-parents table)))
|
||||
(when parents
|
||||
(append (copy-list parents)
|
||||
(mapcan #'yas/table-get-all-parents parents)))))
|
||||
(defun yas/all-parents (mode)
|
||||
"Returns a list of all parent modes of MODE"
|
||||
(let ((parents (gethash mode yas/parents)))
|
||||
(append parents
|
||||
(mapcan #'yas/all-parents parents))))
|
||||
|
||||
(defun yas/table-templates (table)
|
||||
(when table
|
||||
@ -1221,8 +1238,8 @@ a list of modes like this to help the judgement."
|
||||
(when result
|
||||
(format "%s" result))))))
|
||||
(error (if yas/good-grace
|
||||
(format "[yas] elisp error! %s" (error-message-string err))
|
||||
(error (format "[yas] elisp error: %s"
|
||||
(yas/format "elisp error! %s" (error-message-string err))
|
||||
(error (yas/format "elisp error: %s"
|
||||
(error-message-string err)))))))))
|
||||
(when (and (consp retval)
|
||||
(eq 'yas/exception (car retval)))
|
||||
@ -1233,8 +1250,8 @@ a list of modes like this to help the judgement."
|
||||
(condition-case err
|
||||
(eval form)
|
||||
(error (if yas/good-grace
|
||||
(format "[yas] elisp error! %s" (error-message-string err))
|
||||
(error (format "[yas] elisp error: %s"
|
||||
(yas/format "elisp error! %s" (error-message-string err))
|
||||
(error (yas/format "elisp error: %s"
|
||||
(error-message-string err)))))))
|
||||
|
||||
(defun yas/read-lisp (string &optional nil-on-error)
|
||||
@ -1245,7 +1262,7 @@ return an expression that when evaluated will issue an error."
|
||||
(condition-case err
|
||||
(read string)
|
||||
(error (and (not nil-on-error)
|
||||
`(error (error-message-string err))))))
|
||||
`(error (error-message-string ,err))))))
|
||||
|
||||
(defun yas/read-keybinding (keybinding)
|
||||
"Read KEYBINDING as a snippet keybinding, return a vector."
|
||||
@ -1257,7 +1274,7 @@ return an expression that when evaluated will issue an error."
|
||||
(read-kbd-macro keybinding 'need-vector))))
|
||||
res)
|
||||
(error
|
||||
(message "[yas] warning: keybinding \"%s\" invalid since %s."
|
||||
(yas/message 3 "warning: keybinding \"%s\" invalid since %s."
|
||||
keybinding (error-message-string err))
|
||||
nil))))
|
||||
|
||||
@ -1273,11 +1290,7 @@ ensure your use `make-local-variable' when you set it.")
|
||||
(defvaralias 'yas/mode-symbol 'yas/extra-modes)
|
||||
|
||||
(defun yas/table-get-create (mode)
|
||||
"Get the snippet table corresponding to MODE.
|
||||
|
||||
Optional DIRECTORY gets recorded as the default directory to
|
||||
search for snippet files if the retrieved/created table didn't
|
||||
already have such a property."
|
||||
"Get or create the snippet table corresponding to MODE."
|
||||
(let ((table (gethash mode
|
||||
yas/tables)))
|
||||
(unless table
|
||||
@ -1287,31 +1300,15 @@ already have such a property."
|
||||
(yas/table-direct-keymap table)))
|
||||
table))
|
||||
|
||||
(defun yas/get-snippet-tables (&optional mode-symbol dont-search-parents)
|
||||
(defun yas/get-snippet-tables ()
|
||||
"Get snippet tables for current buffer.
|
||||
|
||||
Return a list of 'yas/table' objects indexed by mode.
|
||||
|
||||
The modes are tried in this order: optional MODE-SYMBOL, then
|
||||
`yas/extra-modes', then `major-mode' then, unless
|
||||
DONT-SEARCH-PARENTS is non-nil, the guessed parent mode of either
|
||||
MODE-SYMBOL or `major-mode'.
|
||||
|
||||
Guessing is done by looking up the MODE-SYMBOL's
|
||||
`derived-mode-parent' property, see also `derived-mode-p'."
|
||||
(let ((mode-tables
|
||||
(remove nil
|
||||
(mapcar #'(lambda (mode)
|
||||
(gethash mode yas/tables))
|
||||
(remove nil (append (list mode-symbol)
|
||||
(yas/extra-modes)
|
||||
(list major-mode
|
||||
(and (not dont-search-parents)
|
||||
(get major-mode
|
||||
'derived-mode-parent)))))))))
|
||||
(remove-duplicates
|
||||
(append mode-tables
|
||||
(mapcan #'yas/table-get-all-parents mode-tables)))))
|
||||
Return a list of `yas/table' objects. The list of modes to
|
||||
consider is returned by `yas/modes-to-activate'"
|
||||
(remove nil
|
||||
(mapcar #'(lambda (mode-name)
|
||||
(gethash mode-name yas/tables))
|
||||
(yas/modes-to-activate))))
|
||||
|
||||
(defun yas/menu-keymap-get-create (table)
|
||||
"Get or create the main menu keymap correspondong to MODE.
|
||||
@ -1401,6 +1398,8 @@ Here's a list of currently recognized directives:
|
||||
(setq binding (match-string-no-properties 2)))))
|
||||
(setq template
|
||||
(buffer-substring-no-properties (point-min) (point-max))))
|
||||
(unless (or key binding)
|
||||
(setq key (and file (file-name-nondirectory file))))
|
||||
(when (eq type 'command)
|
||||
(setq template (yas/read-lisp (concat "(progn" template ")"))))
|
||||
(when group
|
||||
@ -1555,7 +1554,7 @@ TEMPLATES is a list of `yas/template'."
|
||||
(keyboard-quit))))
|
||||
|
||||
(defun yas/ido-prompt (prompt choices &optional display-fn)
|
||||
(when (featurep 'ido)
|
||||
(when (fboundp 'ido-completing-read)
|
||||
(yas/completing-prompt prompt choices display-fn #'ido-completing-read)))
|
||||
|
||||
(eval-when-compile (require 'dropdown-list nil t))
|
||||
@ -1582,7 +1581,7 @@ TEMPLATES is a list of `yas/template'."
|
||||
filtered-choices
|
||||
chosen
|
||||
d
|
||||
(completion-fn (or completion-fn
|
||||
(completion-fn (or completion-fnn
|
||||
#'completing-read)))
|
||||
(dolist (choice choices)
|
||||
(setq d (or (and display-fn (funcall display-fn choice))
|
||||
@ -1606,84 +1605,118 @@ TEMPLATES is a list of `yas/template'."
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Loading snippets from files
|
||||
;;
|
||||
(defun yas/load-directory-1 (directory &optional mode-sym parents no-compiled-snippets)
|
||||
"Recursively load snippet templates from DIRECTORY."
|
||||
(unless (file-exists-p (concat directory "/" ".yas-skip"))
|
||||
;; Load .yas-setup.el files wherever we find them
|
||||
;;
|
||||
(load (expand-file-name ".yas-setup" directory) 'noerror)
|
||||
(if (and (not no-compiled-snippets)
|
||||
(load (expand-file-name ".yas-compiled-snippets" directory) 'noerror))
|
||||
(message "Loading much faster .yas-compiled-snippets from %s" directory)
|
||||
(let* ((major-mode-and-parents (if mode-sym
|
||||
(cons mode-sym parents)
|
||||
(yas/compute-major-mode-and-parents (concat directory
|
||||
"/dummy"))))
|
||||
(default-directory directory)
|
||||
(snippet-defs nil))
|
||||
;; load the snippet files
|
||||
;;
|
||||
(with-temp-buffer
|
||||
(dolist (file (yas/subdirs directory 'no-subdirs-just-files))
|
||||
(when (file-readable-p file)
|
||||
(insert-file-contents file nil nil nil t)
|
||||
(push (yas/parse-template file)
|
||||
snippet-defs))))
|
||||
(when (or snippet-defs
|
||||
(cdr major-mode-and-parents))
|
||||
(yas/define-snippets (car major-mode-and-parents)
|
||||
snippet-defs
|
||||
(cdr major-mode-and-parents)))
|
||||
;; now recurse to a lower level
|
||||
;;
|
||||
(dolist (subdir (yas/subdirs directory))
|
||||
(yas/load-directory-1 subdir
|
||||
(car major-mode-and-parents)
|
||||
(cdr major-mode-and-parents)
|
||||
t))))))
|
||||
(defun yas/load-yas-setup-file (file)
|
||||
(load file 'noerror))
|
||||
|
||||
(defun yas/load-directory (top-level-dir)
|
||||
(defun yas/load-directory (top-level-dir &optional nojit)
|
||||
"Load snippet definition from directory hierarchy under TOP-LEVEL-DIR.
|
||||
|
||||
Below TOP-LEVEL-DIR., each directory is a mode name."
|
||||
Below TOP-LEVEL-DIR each directory is a mode name."
|
||||
(interactive "DSelect the root directory: ")
|
||||
(unless (file-directory-p top-level-dir)
|
||||
(error "%s is not a directory" top-level-dir))
|
||||
(unless yas/snippet-dirs
|
||||
(setq yas/snippet-dirs top-level-dir))
|
||||
(dolist (dir (yas/subdirs top-level-dir))
|
||||
(yas/load-directory-1 dir))
|
||||
(let* ((major-mode-and-parents (yas/compute-major-mode-and-parents
|
||||
(concat dir "/dummy")))
|
||||
(mode-sym (car major-mode-and-parents))
|
||||
(parents (cdr major-mode-and-parents)))
|
||||
(yas/define-parents mode-sym parents)
|
||||
(let ((form `(yas/load-directory-1 ,dir
|
||||
',mode-sym
|
||||
',parents)))
|
||||
(if (or (called-interactively-p)
|
||||
nojit)
|
||||
(eval form)
|
||||
(yas/schedule-jit mode-sym form)))))
|
||||
(when (interactive-p)
|
||||
(message "[yas] Loaded snippets from %s." top-level-dir)))
|
||||
(yas/message 3 "Loaded snippets from %s." top-level-dir)))
|
||||
|
||||
(defun yas/load-snippet-dirs ()
|
||||
(defun yas/load-directory-1 (directory mode-sym parents &optional no-compiled-snippets)
|
||||
"Recursively load snippet templates from DIRECTORY."
|
||||
(unless (file-exists-p (concat directory "/" ".yas-skip"))
|
||||
(if (and (not no-compiled-snippets)
|
||||
(load (expand-file-name ".yas-compiled-snippets" directory) 'noerror (<= yas/verbosity 2)))
|
||||
(yas/message 2 "Loading much faster .yas-compiled-snippets from %s" directory)
|
||||
(yas/load-directory-2 directory mode-sym parents))))
|
||||
|
||||
(defun yas/load-directory-2 (directory mode-sym parents)
|
||||
;; Load .yas-setup.el files wherever we find them
|
||||
;;
|
||||
(yas/load-yas-setup-file (expand-file-name ".yas-setup" directory))
|
||||
(let* ((default-directory directory)
|
||||
(snippet-defs nil))
|
||||
;; load the snippet files
|
||||
;;
|
||||
(with-temp-buffer
|
||||
(dolist (file (yas/subdirs directory 'no-subdirs-just-files))
|
||||
(when (file-readable-p file)
|
||||
(insert-file-contents file nil nil nil t)
|
||||
(push (yas/parse-template file)
|
||||
snippet-defs))))
|
||||
(when snippet-defs
|
||||
(yas/define-snippets mode-sym
|
||||
snippet-defs))
|
||||
;; now recurse to a lower level
|
||||
;;
|
||||
(dolist (subdir (yas/subdirs directory))
|
||||
(yas/load-directory-2 subdir
|
||||
mode-sym
|
||||
nil))))
|
||||
|
||||
(defun yas/load-snippet-dirs (&optional nojit)
|
||||
"Reload the directories listed in `yas/snippet-dirs' or
|
||||
prompt the user to select one."
|
||||
(if yas/snippet-dirs
|
||||
(dolist (directory (reverse (yas/snippet-dirs)))
|
||||
(yas/load-directory directory))
|
||||
(call-interactively 'yas/load-directory)))
|
||||
(let (errors)
|
||||
(if yas/snippet-dirs
|
||||
(dolist (directory (reverse (yas/snippet-dirs)))
|
||||
(condition-case oops
|
||||
(progn
|
||||
(yas/load-directory directory nojit)
|
||||
(yas/message 3 "Loaded %s" directory))
|
||||
(error (push oops errors)
|
||||
(yas/message 3 "Check your `yas/snippet-dirs': %s" (second oops)))))
|
||||
(call-interactively 'yas/load-directory))
|
||||
errors))
|
||||
|
||||
(defun yas/reload-all (&optional interactive)
|
||||
(defun yas/reload-all (&optional nojit)
|
||||
"Reload all snippets and rebuild the YASnippet menu. "
|
||||
(interactive "p")
|
||||
(let ((errors))
|
||||
;; Empty all snippet tables and all menu tables
|
||||
;; Empty all snippet tables, parenting info and all menu tables
|
||||
;;
|
||||
(setq yas/tables (make-hash-table))
|
||||
(setq yas/parents (make-hash-table))
|
||||
(setq yas/menu-table (make-hash-table))
|
||||
|
||||
;; Cancel all pending 'yas/scheduled-jit-loads'
|
||||
;;
|
||||
(setq yas/scheduled-jit-loads (make-hash-table))
|
||||
|
||||
;; Reload the directories listed in `yas/snippet-dirs' or prompt
|
||||
;; the user to select one.
|
||||
;;
|
||||
(condition-case oops
|
||||
(yas/load-snippet-dirs)
|
||||
(error (push oops errors)
|
||||
(message "[yas] Check your `yas/snippet-dirs': %s" (second oops))))
|
||||
(setq errors (yas/load-snippet-dirs nojit))
|
||||
;; Reload the direct keybindings
|
||||
;;
|
||||
(yas/direct-keymaps-reload)
|
||||
(message "[yas] Reloaded everything...%s." (if errors " (some errors, check *Messages*)" ""))))
|
||||
;; Reload the trigger-key (shoudn't be needed, but see issue #237)
|
||||
;;
|
||||
(yas/trigger-key-reload)
|
||||
(yas/message 3 "Reloaded everything...%s." (if errors " (some errors, check *Messages*)" ""))))
|
||||
|
||||
(defun yas/load-pending-jits ()
|
||||
(when yas/minor-mode
|
||||
(dolist (mode (yas/modes-to-activate))
|
||||
(let ((forms (gethash mode yas/scheduled-jit-loads)))
|
||||
(dolist (form forms)
|
||||
(yas/message 3 "Loading snippets for %s, just in time: %s!" mode form)
|
||||
(eval form))
|
||||
(remhash mode yas/scheduled-jit-loads)))))
|
||||
|
||||
;; (when (<= emacs-major-version 22)
|
||||
;; (add-hook 'after-change-major-mode-hook 'yas/load-pending-jits))
|
||||
|
||||
(defun yas/quote-string (string)
|
||||
"Escape and quote STRING.
|
||||
@ -1701,63 +1734,73 @@ foo\"bar\\! -> \"foo\\\"bar\\\\!\""
|
||||
"For backward compatibility, enable `yas/minor-mode' globally"
|
||||
(yas/global-mode 1))
|
||||
|
||||
(defun yas/compile-top-level-dir (top-level-dir)
|
||||
"Create .yas-compiled-snippets.el files under subdirs of TOP-LEVEL-DIR."
|
||||
(defun yas/compile-directory (top-level-dir)
|
||||
"Create .yas-compiled-snippets.el files under subdirs of TOP-LEVEL-DIR.
|
||||
|
||||
This works by stubbing a few functions, then calling
|
||||
`yas/load-directory'."
|
||||
(interactive "DTop level snippet directory?")
|
||||
(dolist (dir (yas/subdirs top-level-dir))
|
||||
(yas/compile-snippets dir)))
|
||||
(flet ((yas/load-yas-setup-file
|
||||
(file)
|
||||
(let ((elfile (concat file ".el")))
|
||||
(when (file-exists-p elfile)
|
||||
(insert ";;; .yas-setup.el support file if any:\n;;;\n")
|
||||
(insert-file-contents elfile)
|
||||
(end-of-buffer)
|
||||
)))
|
||||
(yas/define-snippets
|
||||
(mode snippets)
|
||||
(insert ";;; Snippet definitions:\n;;;\n")
|
||||
(let ((literal-snippets (list))
|
||||
(print-length nil))
|
||||
(dolist (snippet snippets)
|
||||
(let ((key (first snippet))
|
||||
(template-content (second snippet))
|
||||
(name (third snippet))
|
||||
(condition (fourth snippet))
|
||||
(group (fifth snippet))
|
||||
(expand-env (sixth snippet))
|
||||
(file nil) ;; (seventh snippet)) ;; omit on purpose
|
||||
(binding (eighth snippet))
|
||||
(uuid (ninth snippet)))
|
||||
(push `(,key
|
||||
,template-content
|
||||
,name
|
||||
,condition
|
||||
,group
|
||||
,expand-env
|
||||
,file
|
||||
,binding
|
||||
,uuid)
|
||||
literal-snippets)))
|
||||
(insert (pp-to-string `(yas/define-snippets ',mode ',literal-snippets)))
|
||||
(insert "\n\n")))
|
||||
(yas/load-directory-1
|
||||
(dir mode parents &rest ignore)
|
||||
(let ((output-file (concat (file-name-as-directory dir) ".yas-compiled-snippets.el")))
|
||||
(with-temp-file output-file
|
||||
(insert (format ";;; Compiled snippets and support files for `%s'\n" mode))
|
||||
(yas/load-directory-2 dir mode parents)
|
||||
(insert (format ";;; Do not edit! File generated at %s\n" (current-time-string)))))))
|
||||
(yas/load-directory top-level-dir 'im-compiling-so-no-jit-ok?)))
|
||||
|
||||
(defun yas/compile-snippets (input-dir &optional output-file)
|
||||
"Compile snippets files in INPUT-DIR to OUTPUT-FILE file.
|
||||
(defun yas/recompile-all ()
|
||||
"Compile every dir in `yas/snippet-dirs'."
|
||||
(interactive)
|
||||
(mapc #'yas/compile-directory (yas/snippet-dirs)))
|
||||
|
||||
Prompts for INPUT-DIR and OUTPUT-FILE if called-interactively"
|
||||
(interactive (let* ((input-dir (read-directory-name "Snippet dir "))
|
||||
(output-file (let ((ido-everywhere nil))
|
||||
(read-file-name "Output file "
|
||||
input-dir nil nil
|
||||
".yas-compiled-snippets.el"
|
||||
nil))))
|
||||
(list input-dir output-file)))
|
||||
(let ((default-directory input-dir))
|
||||
(with-temp-file (setq output-file (or output-file ".yas-compiled-snippets.el"))
|
||||
(flet ((yas/define-snippets
|
||||
(mode snippets &optional parent-or-parents)
|
||||
(insert (format ";;; %s - automatically compiled snippets for `%s' , do not edit!\n"
|
||||
(file-name-nondirectory output-file) mode))
|
||||
(insert ";;;\n")
|
||||
(let ((literal-snippets (list)))
|
||||
(dolist (snippet snippets)
|
||||
(let ((key (first snippet))
|
||||
(template-content (second snippet))
|
||||
(name (third snippet))
|
||||
(condition (fourth snippet))
|
||||
(group (fifth snippet))
|
||||
(expand-env (sixth snippet))
|
||||
(file nil) ;; (seventh snippet)) ;; omit on purpose
|
||||
(binding (eighth snippet))
|
||||
(uuid (ninth snippet)))
|
||||
(push `(,key
|
||||
,template-content
|
||||
,name
|
||||
,condition
|
||||
,group
|
||||
,expand-env
|
||||
,file
|
||||
,binding
|
||||
,uuid)
|
||||
literal-snippets)))
|
||||
(insert (pp-to-string `(yas/define-snippets ',mode ',literal-snippets ',parent-or-parents)))
|
||||
(insert "\n\n")
|
||||
(insert (format ";;; %s - automatically compiled snippets for `%s' end here\n"
|
||||
(file-name-nondirectory output-file) mode))
|
||||
(insert ";;;"))))
|
||||
(yas/load-directory-1 input-dir nil nil 'no-compiled-snippets))))
|
||||
|
||||
(if (and (called-interactively-p)
|
||||
(yes-or-no-p (format "Open the resulting file (%s)? "
|
||||
(expand-file-name output-file))))
|
||||
(find-file-other-window output-file)))
|
||||
|
||||
;;; JIT loading
|
||||
;;;
|
||||
|
||||
(defvar yas/scheduled-jit-loads (make-hash-table)
|
||||
"Alist of mode-symbols to forms to be evaled when `yas/minor-mode' kicks in.")
|
||||
|
||||
(defun yas/schedule-jit (mode form)
|
||||
(puthash mode
|
||||
(cons form
|
||||
(gethash mode yas/scheduled-jit-loads))
|
||||
yas/scheduled-jit-loads))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@ -1770,7 +1813,14 @@ Prompts for INPUT-DIR and OUTPUT-FILE if called-interactively"
|
||||
yas/version
|
||||
") -- pluskid <pluskid@gmail.com>/joaotavora <joaotavora@gmail.com>")))
|
||||
|
||||
(defun yas/define-snippets (mode snippets &optional parent-mode)
|
||||
(defun yas/define-parents (mode parents)
|
||||
"Add PARENTS to the list of MODE's parents"
|
||||
(puthash mode-sym (remove-duplicates
|
||||
(append parents
|
||||
(gethash mode-sym yas/parents)))
|
||||
yas/parents))
|
||||
|
||||
(defun yas/define-snippets (mode snippets)
|
||||
"Define SNIPPETS for MODE.
|
||||
|
||||
SNIPPETS is a list of snippet definitions, each taking the
|
||||
@ -1796,32 +1846,9 @@ UUID is the snippets \"unique-id\". Loading a second snippet file
|
||||
with the same uuid replaced the previous snippet.
|
||||
|
||||
You can use `yas/parse-template' to return such lists based on
|
||||
the current buffers contents.
|
||||
|
||||
Optional PARENT-MODE can be used to specify the parent tables of
|
||||
MODE. It can be a mode symbol of a list of mode symbols. It does
|
||||
not need to be a real mode."
|
||||
;; X) `snippet-table' is created or retrieved for MODE, same goes
|
||||
;; for the list of snippet tables `parent-tables'.
|
||||
;;
|
||||
the current buffers contents."
|
||||
(let ((snippet-table (yas/table-get-create mode))
|
||||
(parent-tables (mapcar #'yas/table-get-create
|
||||
(if (listp parent-mode)
|
||||
parent-mode
|
||||
(list parent-mode))))
|
||||
(template nil))
|
||||
;; X) Connect `snippet-table' with `parent-tables'.
|
||||
;;
|
||||
;; TODO: this should be a remove-duplicates of the concatenation
|
||||
;; of `snippet-table's existings parents with the new parents...
|
||||
;;
|
||||
(dolist (parent parent-tables)
|
||||
(unless (find parent (yas/table-parents snippet-table))
|
||||
(push parent
|
||||
(yas/table-parents snippet-table))))
|
||||
|
||||
;; X) Now, iterate for evey snippet def list
|
||||
;;
|
||||
(dolist (snippet snippets)
|
||||
(setq template (yas/define-snippets-1 snippet
|
||||
snippet-table)))
|
||||
@ -1894,7 +1921,7 @@ not need to be a real mode."
|
||||
"Recursively delete items with UUID from KEYMAP and its submenus."
|
||||
|
||||
;; XXX: This used to skip any submenus named \"parent mode\"
|
||||
;;
|
||||
;;
|
||||
;; First of all, recursively enter submenus, i.e. the tree is
|
||||
;; searched depth first so that stale submenus can be found in the
|
||||
;; higher passes.
|
||||
@ -1905,10 +1932,10 @@ not need to be a real mode."
|
||||
(yas/delete-from-keymap (third (cdr item)) uuid)))
|
||||
(rest keymap))
|
||||
;; Set the uuid entry to nil
|
||||
;;
|
||||
;;
|
||||
(define-key keymap (vector (make-symbol uuid)) nil)
|
||||
;; Destructively modify keymap
|
||||
;;
|
||||
;;
|
||||
(setcdr keymap (delete-if #'(lambda (item)
|
||||
(or (null (cdr item))
|
||||
(and (keymapp (third (cdr item)))
|
||||
@ -1973,7 +2000,7 @@ ommited from MODE's menu, even if they're manually loaded.
|
||||
(define-key keymap (vector (gensym))
|
||||
'(menu-item "----")))
|
||||
(t
|
||||
(message "[yas] don't know anything about menu entry %s" (first e))))))
|
||||
(yas/message 3 "Don't know anything about menu entry %s" (first e))))))
|
||||
|
||||
(defun yas/define (mode key template &optional name condition group)
|
||||
"Define a snippet. Expanding KEY into TEMPLATE.
|
||||
@ -2172,7 +2199,7 @@ by condition."
|
||||
(car where)
|
||||
(cdr where)
|
||||
(yas/template-expand-env yas/current-template))
|
||||
(message "[yas] No snippets can be inserted here!"))))
|
||||
(yas/message 3 "No snippets can be inserted here!"))))
|
||||
|
||||
(defun yas/visit-snippet-file ()
|
||||
"Choose a snippet to edit, selection like `yas/insert-snippet'.
|
||||
@ -2261,7 +2288,7 @@ where snippets of table might exist."
|
||||
(or (some #'(lambda (dir) (when (file-directory-p dir) dir)) (cdr table-and-dirs))
|
||||
(let ((candidate (first (cdr table-and-dirs))))
|
||||
(unless (file-writable-p (file-name-directory candidate))
|
||||
(error "[yas] %s is not writable." candidate))
|
||||
(error (yas/format "%s is not writable." candidate)))
|
||||
(if (y-or-n-p (format "Guessed directory (%s) for%s%s table \"%s\" does not exist! Create? "
|
||||
candidate
|
||||
(if (gethash (intern (yas/table-name (car table-and-dirs)))
|
||||
@ -2393,7 +2420,7 @@ With optional prefix argument KILL quit the window and buffer."
|
||||
;; neatly positioned,...
|
||||
;;
|
||||
(yas/editing-template
|
||||
(yas/define-snippets-1 (yas/parse-template (yas/template-file yas/editing-template))
|
||||
(yas/define-snippets-1 (yas/parse-template (yas/template-file yas/editing-template))
|
||||
(yas/template-table yas/editing-template)))
|
||||
;; Try to use `yas/guessed-modes'. If we don't have that use the
|
||||
;; value from `yas/compute-major-mode-and-parents'
|
||||
@ -2417,7 +2444,7 @@ With optional prefix argument KILL quit the window and buffer."
|
||||
nil
|
||||
(if (first yas/guessed-modes)
|
||||
(symbol-name (first yas/guessed-modes))))))))
|
||||
(set (make-local-variable 'yas/editing-template)
|
||||
(set (make-local-variable 'yas/editing-template)
|
||||
(yas/define-snippets-1 (yas/parse-template buffer-file-name)
|
||||
table)))))
|
||||
;; Now, offer to save this shit iff:
|
||||
@ -2434,8 +2461,8 @@ With optional prefix argument KILL quit the window and buffer."
|
||||
(second yas/snippet-dirs)
|
||||
(not (string-match (expand-file-name (first yas/snippet-dirs))
|
||||
(yas/template-file yas/editing-template)))))
|
||||
|
||||
(when (y-or-n-p "[yas] Looks like a library or new snippet. Save to new file? ")
|
||||
|
||||
(when (y-or-n-p (yas/format "Looks like a library or new snippet. Save to new file? "))
|
||||
(let* ((option (first (yas/guess-snippet-directories (yas/template-table yas/editing-template))))
|
||||
(chosen (and option
|
||||
(yas/make-directory-maybe option))))
|
||||
@ -2449,7 +2476,7 @@ With optional prefix argument KILL quit the window and buffer."
|
||||
(setf (yas/template-file yas/editing-template) buffer-file-name))))))
|
||||
(when kill
|
||||
(quit-window kill))
|
||||
(message "[yas] Snippet \"%s\" loaded for %s."
|
||||
(yas/message 3 "Snippet \"%s\" loaded for %s."
|
||||
(yas/template-name yas/editing-template)
|
||||
(yas/table-name (yas/template-table yas/editing-template))))
|
||||
|
||||
@ -2463,7 +2490,7 @@ With optional prefix argument KILL quit the window and buffer."
|
||||
(fboundp (car major-mode-and-parent))
|
||||
(car major-mode-and-parent))
|
||||
(first yas/guessed-modes)
|
||||
(intern (read-from-minibuffer "[yas] please input a mode: "))))
|
||||
(intern (read-from-minibuffer (yas/format "Please input a mode: ")))))
|
||||
(yas/current-template
|
||||
(and parsed
|
||||
(fboundp test-mode)
|
||||
@ -2488,7 +2515,7 @@ With optional prefix argument KILL quit the window and buffer."
|
||||
(require 'yasnippet-debug nil t))
|
||||
(add-hook 'post-command-hook 'yas/debug-snippet-vars nil t))))
|
||||
(t
|
||||
(message "[yas] Cannot test snippet for unknown major mode")))))
|
||||
(yas/message 3 "Cannot test snippet for unknown major mode")))))
|
||||
|
||||
(defun yas/template-fine-group (template)
|
||||
(car (last (or (yas/template-group template)
|
||||
@ -2563,7 +2590,7 @@ With optional prefix argument KILL quit the window and buffer."
|
||||
(setq group (or (yas/template-fine-group v)
|
||||
"(top level)"))
|
||||
(when (yas/template-name v)
|
||||
|
||||
|
||||
(aput 'groups-alist group (cons v (aget groups-alist group)))))
|
||||
(yas/table-uuidhash table))
|
||||
(dolist (group-and-templates groups-alist)
|
||||
@ -2574,7 +2601,7 @@ With optional prefix argument KILL quit the window and buffer."
|
||||
(let ((name (truncate-string-to-width (propertize (format "\\\\snippet `%s'" (yas/template-name p))
|
||||
'yasnippet p)
|
||||
50 0 ? "..."))
|
||||
(group (prog1 group
|
||||
(group (prog1 group
|
||||
(setq group (make-string (length group) ? ))))
|
||||
(condition-string (let ((condition (yas/template-condition p)))
|
||||
(if (and condition
|
||||
@ -2586,7 +2613,7 @@ With optional prefix argument KILL quit the window and buffer."
|
||||
"(a)"))))
|
||||
(insert group " ")
|
||||
(insert condition-string " ")
|
||||
(insert name
|
||||
(insert name
|
||||
(if (string-match "\\.\\.\\.$" name)
|
||||
"'"
|
||||
" ")
|
||||
@ -2649,7 +2676,7 @@ If found, the content of subexp group SUBEXP (default 0) is
|
||||
|
||||
Otherwise throw exception."
|
||||
(when (and yas/moving-away-p (notany #'(lambda (pos) (string= pos yas/text)) possibilities))
|
||||
(yas/throw (format "[yas] field only allows %s" possibilities))))
|
||||
(yas/throw (yas/format "Field only allows %s" possibilities))))
|
||||
|
||||
(defun yas/field-value (number)
|
||||
"Get the string for field with NUMBER.
|
||||
@ -2892,7 +2919,7 @@ Also create some protection overlays"
|
||||
(yas/place-overlays snippet field)
|
||||
(overlay-put yas/active-field-overlay 'yas/field field)
|
||||
(let ((number (yas/field-number field)))
|
||||
;; check for the special ${0: ...} field
|
||||
;; check for the special ${0: ...} field
|
||||
(if (and number (zerop number))
|
||||
(progn
|
||||
(set-mark (yas/field-end field))
|
||||
@ -2934,7 +2961,7 @@ Also create some protection overlays"
|
||||
(mapc #'(lambda (snippet)
|
||||
(yas/exit-snippet snippet)
|
||||
(yas/check-commit-snippet))
|
||||
(yas/snippets-at-point)))
|
||||
(yas/snippets-at-point 'all-snippets)))
|
||||
|
||||
|
||||
;;; Some low level snippet-routines
|
||||
@ -2990,13 +3017,13 @@ snippet as ordinary text."
|
||||
;; again from `yas/take-care-of-redo'....
|
||||
(setf (yas/snippet-fields snippet) nil)))
|
||||
|
||||
(message "[yas] snippet %s exited." (yas/snippet-id snippet)))
|
||||
(yas/message 3 "Snippet %s exited." (yas/snippet-id snippet)))
|
||||
|
||||
(defun yas/safely-run-hooks (hook-var)
|
||||
(condition-case error
|
||||
(run-hooks hook-var)
|
||||
(error
|
||||
(message "[yas] %s error: %s" hook-var (error-message-string error)))))
|
||||
(yas/message 3 "%s error: %s" hook-var (error-message-string error)))))
|
||||
|
||||
|
||||
(defun yas/check-commit-snippet ()
|
||||
@ -3007,7 +3034,7 @@ snippet, if so cleans up the whole snippet up."
|
||||
(snippet-exit-transform))
|
||||
(dolist (snippet snippets)
|
||||
(let ((active-field (yas/snippet-active-field snippet)))
|
||||
(setq snippet-exit-transform (yas/snippet-force-exit snippet))
|
||||
(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))
|
||||
@ -3395,7 +3422,7 @@ considered when expanding the snippet."
|
||||
(when first-field
|
||||
(sit-for 0) ;; fix issue 125
|
||||
(yas/move-to-field snippet first-field)))
|
||||
(message "[yas] snippet expanded.")
|
||||
(yas/message 3 "snippet expanded.")
|
||||
t))))
|
||||
|
||||
(defun yas/take-care-of-redo (beg end snippet)
|
||||
@ -3679,7 +3706,7 @@ SNIPPET-MARKERS."
|
||||
(widen)
|
||||
(condition-case err
|
||||
(indent-according-to-mode)
|
||||
(error (message "[yas] warning: yas/indent-according-to-mode habing problems running %s" indent-line-function)
|
||||
(error (yas/message 3 "Warning: `yas/indent-according-to-mode' having problems running %s" indent-line-function)
|
||||
nil)))
|
||||
(mapc #'(lambda (marker)
|
||||
(set-marker marker (point)))
|
||||
@ -4022,7 +4049,7 @@ that the rest of `yas/post-command-handler' runs.")
|
||||
(apply (car fn-and-args)
|
||||
(cdr fn-and-args)))
|
||||
yas/post-command-runonce-actions)
|
||||
(error (message "[yas] problem running `yas/post-command-runonce-actions'!")))
|
||||
(error (yas/message 3 "Problem running `yas/post-command-runonce-actions'!")))
|
||||
(setq yas/post-command-runonce-actions nil))
|
||||
(cond (yas/protection-violation
|
||||
(goto-char yas/protection-violation)
|
||||
@ -4129,13 +4156,25 @@ Remaining args as in `yas/expand-snippet'."
|
||||
(gethash uuid (yas/table-uuidhash table)))))
|
||||
(when yas/current-template
|
||||
(yas/expand-snippet (yas/template-content yas/current-template)))))
|
||||
|
||||
;;; Utils
|
||||
;;;
|
||||
|
||||
(defvar yas/verbosity 4
|
||||
"Log level for `yas/message' 4 means trace most anything, 0 means nothing.")
|
||||
(defun yas/message (level message &rest args)
|
||||
(when (> yas/verbosity level)
|
||||
(message (apply #'yas/format message args))))
|
||||
|
||||
(defun yas/format (format-control &rest format-args)
|
||||
(apply #'format (concat "[yas] " format-control) format-args))
|
||||
|
||||
|
||||
;;; Some hacks:
|
||||
;;;
|
||||
;; `locate-dominating-file'
|
||||
;;;
|
||||
;; `locate-dominating-file'
|
||||
;; `region-active-p'
|
||||
;;
|
||||
;;
|
||||
;; added for compatibility in emacs < 23
|
||||
(unless (>= emacs-major-version 23)
|
||||
(unless (fboundp 'region-active-p)
|
||||
|
Loading…
x
Reference in New Issue
Block a user