From fcbbdbdbbc3a99101ae3e2a9be33ee0388467008 Mon Sep 17 00:00:00 2001 From: Joao Tavora Date: Fri, 9 Mar 2012 11:05:39 +0000 Subject: [PATCH 1/5] Don\'t abort loading more snippet dirs if one of them failed --- yasnippet.el | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/yasnippet.el b/yasnippet.el index d2ebae7..f237863 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -1654,10 +1654,17 @@ Below TOP-LEVEL-DIR., each directory is a mode name." (defun yas/load-snippet-dirs () "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) + (message "[yas] Loaded %s" directory)) + (error (push oops errors) + (message "[yas] Check your `yas/snippet-dirs': %s" (second oops))))) + (call-interactively 'yas/load-directory)) + errors)) (defun yas/reload-all (&optional interactive) "Reload all snippets and rebuild the YASnippet menu. " @@ -1677,10 +1684,7 @@ Below TOP-LEVEL-DIR., each directory is a mode name." ;; 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)) ;; Reload the direct keybindings ;; (yas/direct-keymaps-reload) From 66e804dad0e2b06dac1c37a7fdf3a774b8b7d2b6 Mon Sep 17 00:00:00 2001 From: Joao Tavora Date: Tue, 13 Mar 2012 11:23:38 +0000 Subject: [PATCH 2/5] Added a few ert unit tests, mostly for very basic snippet mechanics --- yasnippet-tests.el | 123 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100755 yasnippet-tests.el diff --git a/yasnippet-tests.el b/yasnippet-tests.el new file mode 100755 index 0000000..0cbff75 --- /dev/null +++ b/yasnippet-tests.el @@ -0,0 +1,123 @@ +;;; yasnippet-tests.el --- some yasnippet tests + +;; Copyright (C) 2012 João Távora + +;; Author: João Távora +;; 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 . + +;;; Commentary: + +;; Attempt to 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! + ))) + +;;; Helpers +;;; + +(defun yas/mock-insert (string) + (interactive) + (do ((i 0 (1+ i))) + ((= i (length string))) + (insert (aref string i)))) + + +(provide 'yasnippet-tests) +;;; yasnippet-tests.el ends here From 43232a10db98213a14a3254cab1470c5a127812c Mon Sep 17 00:00:00 2001 From: Joao Tavora Date: Tue, 20 Mar 2012 09:14:18 +0000 Subject: [PATCH 3/5] If no 'key' or 'binding' directives fall back to filename as trigger key --- yasnippet.el | 2 ++ 1 file changed, 2 insertions(+) diff --git a/yasnippet.el b/yasnippet.el index f237863..8de4a39 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -1396,6 +1396,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 From 2188a9d1d100d084ba79bf1bf4237bc72088d311 Mon Sep 17 00:00:00 2001 From: Joao Tavora Date: Tue, 20 Mar 2012 09:15:07 +0000 Subject: [PATCH 4/5] Some loading/reloading with useful fixture code --- yasnippet-tests.el | 65 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/yasnippet-tests.el b/yasnippet-tests.el index 0cbff75..f1219fa 100755 --- a/yasnippet-tests.el +++ b/yasnippet-tests.el @@ -109,6 +109,34 @@ TODO: correct this bug!" "brother from another mother") ;; no newline should be here! ))) +;;; Loading +;;; +(ert-deftest basic-loading () + "Test basic loading and expansion of snippets" + (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")))) + (yas/reload-all) + (with-temp-buffer + (lisp-interaction-mode) + (yas/minor-mode 1) + (insert "sc") + (ert-simulate-command '(yas/expand)) + (should (string= (buffer-substring-no-properties (point-min) (point-max)) + "brother from another mother")))))) + + + ;;; Helpers ;;; @@ -118,6 +146,43 @@ TODO: correct this bug!" ((= 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))) + (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))) + (setq yas/snippet-dirs ',(mapcar #'car (cadr dirs))) + (mapc #'yas/make-file-or-dirs ,dirs) + ,@body)) + (provide 'yasnippet-tests) ;;; yasnippet-tests.el ends here From 440b6936a5dd91f7f811317de84586326d289654 Mon Sep 17 00:00:00 2001 From: Joao Tavora Date: Tue, 20 Mar 2012 09:16:00 +0000 Subject: [PATCH 5/5] makes 'yas/template' objects easier to read in the echo area --- yasnippet.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yasnippet.el b/yasnippet.el index 8de4a39..d9c3882 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -889,7 +889,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 @@ -901,6 +900,7 @@ Do this unless `yas/dont-activate' is truish " menu-binding-pair 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)