From b4ccb6e9566c17fe38ab30310e2e64749bd2d7ce Mon Sep 17 00:00:00 2001 From: Joao Tavora Date: Mon, 6 Aug 2012 18:39:11 +0100 Subject: [PATCH 1/8] Refactor: `yas-load-snippet-buffer` can be called non-interactively --- yasnippet.el | 114 +++++++++++++++++++++++++++------------------------ 1 file changed, 60 insertions(+), 54 deletions(-) diff --git a/yasnippet.el b/yasnippet.el index 603ac02..4a4b6ed 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -2512,15 +2512,38 @@ neither do the elements of PARENTS." (defvar yas--guessed-modes nil "List of guessed modes supporting `yas-load-snippet-buffer'.") -(defun yas-load-snippet-buffer (&optional kill) - "Parse and load current buffer's snippet definition. +(defun yas--read-table () + "Ask user for a snippet table, help with some guessing." + (let ((prompt (if (and (featurep 'ido) + ido-mode) + 'ido-completing-read 'completing-read))) + (unless yas--guessed-modes + (set (make-local-variable 'yas--guessed-modes) + (or (yas--compute-major-mode-and-parents buffer-file-name)))) + (intern + (funcall prompt (format "Choose or enter a table (yas guesses %s): " + (if yas--guessed-modes + (first yas--guessed-modes) + "nothing")) + (mapcar #'symbol-name yas--guessed-modes) + nil + nil + nil + nil + (if (first yas--guessed-modes) + (symbol-name (first yas--guessed-modes))))))) -With optional prefix argument KILL quit the window and buffer." - (interactive "P") +(defun yas-load-snippet-buffer (table &optional interactive) + "Parse and load current buffer's snippet definition into TABLE. + +TABLE is a symbol naming a passed to `yas--table-get-create'. + +When called interactively, prompt for the table name and +whether (and where) to save the snippet, then quit the window." + (interactive (list (yas--read-table) t)) (cond - ;; We have `yas--editing-template', this buffer's - ;; content comes from a template which is already loaded and - ;; neatly positioned,... + ;; We have `yas--editing-template', this buffer's content comes from a + ;; template which is already loaded and neatly positioned,... ;; (yas--editing-template (yas-define-snippets-1 (yas--parse-template (yas--template-file yas--editing-template)) @@ -2531,57 +2554,40 @@ With optional prefix argument KILL quit the window and buffer." (t (unless yas--guessed-modes (set (make-local-variable 'yas--guessed-modes) (or (yas--compute-major-mode-and-parents buffer-file-name)))) - (let* ((prompt (if (and (featurep 'ido) - ido-mode) - 'ido-completing-read 'completing-read)) - (table (yas--table-get-create - (intern - (funcall prompt (format "Choose or enter a table (yas guesses %s): " - (if yas--guessed-modes - (first yas--guessed-modes) - "nothing")) - (mapcar #'symbol-name yas--guessed-modes) - nil - nil - nil - nil - (if (first yas--guessed-modes) - (symbol-name (first yas--guessed-modes)))))))) + (let* ((table (yas--table-get-create table))) (set (make-local-variable 'yas--editing-template) (yas-define-snippets-1 (yas--parse-template buffer-file-name) table))))) - ;; Now, offer to save this iff: - ;; - ;; 1) `yas-snippet-dirs' is a list and its first element does not - ;; match this template's file (i.e. this is a library snippet, not - ;; a user snippet) OR - ;; - ;; 2) yas--editing-template comes from a file that we cannot write to... - ;; - (when (or (not (yas--template-file yas--editing-template)) - (not (file-writable-p (yas--template-file yas--editing-template))) - (and (listp yas-snippet-dirs) - (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--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)))) - (when chosen - (let ((default-file-name (or (and (yas--template-file yas--editing-template) - (file-name-nondirectory (yas--template-file yas--editing-template))) - (yas--template-name yas--editing-template)))) - (write-file (concat chosen "/" - (read-from-minibuffer (format "File name to create in %s? " chosen) - default-file-name))) - (setf (yas--template-file yas--editing-template) buffer-file-name)))))) - (when kill - (quit-window kill)) - (yas--message 3 "Snippet \"%s\" loaded for %s." - (yas--template-name yas--editing-template) - (yas--table-name (yas--template-table yas--editing-template)))) + (when (and interactive + (or + ;; Only offer to save this if it looks like a library or new + ;; snippet (loaded from elisp, from a dir in `yas-snippet-dirs' + ;; which is not the first, or from an unwritable file) + ;; + (not (yas--template-file yas--editing-template)) + (not (file-writable-p (yas--template-file yas--editing-template))) + (and (listp yas-snippet-dirs) + (second yas-snippet-dirs) + (not (string-match (expand-file-name (first yas-snippet-dirs)) + (yas--template-file yas--editing-template))))) + (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)))) + (when chosen + (let ((default-file-name (or (and (yas--template-file yas--editing-template) + (file-name-nondirectory (yas--template-file yas--editing-template))) + (yas--template-name yas--editing-template)))) + (write-file (concat chosen "/" + (read-from-minibuffer (format "File name to create in %s? " chosen) + default-file-name))) + (setf (yas--template-file yas--editing-template) buffer-file-name))))) + (when interactive + (quit-window interactive) + (yas--message 3 "Snippet \"%s\" loaded for %s." + (yas--template-name yas--editing-template) + (yas--table-name (yas--template-table yas--editing-template))))) (defun yas-tryout-snippet (&optional debug) From 38093c1a9e1f44679f2f41d9df05a8b4fc363c08 Mon Sep 17 00:00:00 2001 From: Joao Tavora Date: Tue, 7 Aug 2012 12:06:53 +0100 Subject: [PATCH 2/8] Fix: default value for `yas-trigger-key` is not "" not "TAB" After some exploration, this seems to be the more correct default. Corrected test that checks for correct binding in org-mode, pass in emacs23 and emacs24 --- yasnippet-tests.el | 6 +++--- yasnippet.el | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/yasnippet-tests.el b/yasnippet-tests.el index eb1a245..6c75b35 100644 --- a/yasnippet-tests.el +++ b/yasnippet-tests.el @@ -422,9 +422,9 @@ TODO: be meaner" (ert-deftest test-yas-tab-binding () (with-temp-buffer (yas-minor-mode -1) - (should (not (eq (key-binding (yas--read-keybinding yas-trigger-key)) 'yas-expand))) + (should (not (eq (key-binding (yas--read-keybinding "")) 'yas-expand))) (yas-minor-mode 1) - (should (eq (key-binding (yas--read-keybinding yas-trigger-key)) 'yas-expand)) + (should (eq (key-binding (yas--read-keybinding "")) 'yas-expand)) (yas-expand-snippet "$1 $2 $3") (dolist (k (if (listp yas-next-field-key) yas-next-field-key @@ -439,7 +439,7 @@ TODO: be meaner" (with-temp-buffer (org-mode) (yas-minor-mode 1) - (should (eq (key-binding (yas--read-keybinding yas-trigger-key)) 'yas-expand)))) + (should (eq (key-binding (yas--read-keybinding "")) 'yas-expand)))) ;;; Helpers ;;; diff --git a/yasnippet.el b/yasnippet.el index 4a4b6ed..ed75cab 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -236,8 +236,8 @@ Naturally this is only valid when `yas-indent-line' is `auto'" :type 'boolean :group 'yasnippet) -(defcustom yas-trigger-key "TAB" - "The key bound to `yas-expand' when function `yas-minor-mode' is active. +(defcustom yas-trigger-key "" + "The key bound to `yas-expand' when `yas-minor-mode' is active. Value is a string that is converted to the internal Emacs key representation using `read-kbd-macro'." From 951fb3cbe779eef8e558f22794244ad58511b828 Mon Sep 17 00:00:00 2001 From: Joao Tavora Date: Tue, 7 Aug 2012 12:07:32 +0100 Subject: [PATCH 3/8] Fix: recursive `delete-directory` does not exist in Emacs 23 --- yasnippet-tests.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yasnippet-tests.el b/yasnippet-tests.el index 6c75b35..ad125da 100644 --- a/yasnippet-tests.el +++ b/yasnippet-tests.el @@ -513,7 +513,7 @@ TODO: be meaner" (progn (mapc #'yas-make-file-or-dirs dirs) (funcall fn)) - (when (>= emacs-major-version 23) + (when (>= emacs-major-version 24) (delete-directory default-directory 'recursive)))))) (defmacro yas-with-snippet-dirs (dirs &rest body) From cdea084f7a5002348ef38a9977e6fc4951289d0c Mon Sep 17 00:00:00 2001 From: Joao Tavora Date: Tue, 7 Aug 2012 12:09:12 +0100 Subject: [PATCH 4/8] Add: .gitignore ignores local ert files (needed for testing in Emacs 23) --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 6c15488..c433a57 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ extras/imported/** !extras/imported/*/.yas-setup.el .yas-compiled-snippets.el *.elc +ert-x.* +ert.* From 5eede17563ab2716735fceb4862cd4f07eeb9a66 Mon Sep 17 00:00:00 2001 From: Joao Tavora Date: Tue, 7 Aug 2012 12:44:14 +0100 Subject: [PATCH 5/8] Fix: new `yas-trigger-key` default messed up the fallbacks. Introduced an ugly `yas--trigger-key-for-fallback` hack, but should be good. --- yasnippet.el | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/yasnippet.el b/yasnippet.el index ed75cab..db004d0 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -2256,6 +2256,18 @@ expand immediately. Common gateway for end (yas--template-expand-env yas--current-template))))) +(defun yas--trigger-key-for-fallback () + ;; When `yas-trigger-key' is it correctly overrides + ;; org-mode's , for example and searching for fallbacks + ;; correctly returns `org-cycle'. However, most other modes bind + ;; "TAB" (which is translated from ), and calling + ;; (key-binding "TAB") does not place return that command into + ;; our command-2 local. So we cheat. + ;; + (if (string= yas-trigger-key "") + "TAB" + yas-trigger-key)) + (defun yas--fallback (&optional from-trigger-key-p) "Fallback after expansion has failed. @@ -2267,6 +2279,7 @@ Common gateway for `yas-expand-from-trigger-key' and ((eq yas-fallback-behavior 'call-other-command) (let* ((yas-minor-mode nil) (yas--direct-keymaps nil) + (yas-trigger-key (yas--trigger-key-for-fallback)) (keys-1 (this-command-keys-vector)) (keys-2 (and yas-trigger-key from-trigger-key-p @@ -4221,7 +4234,7 @@ When multiple expressions are found, only the last one counts." (let ((fallback-description (cond ((eq yas-fallback-behavior 'call-other-command) (let* ((yas-minor-mode nil) - (fallback (key-binding (read-kbd-macro yas-trigger-key)))) + (fallback (key-binding (read-kbd-macro (yas--trigger-key-for-fallback))))) (or (and fallback (format " call command `%s'." (pp-to-string fallback))) " do nothing."))) From 064c068c453894b8443964698be467f35325c811 Mon Sep 17 00:00:00 2001 From: Jim Myhrberg Date: Sat, 11 Aug 2012 14:37:31 +0100 Subject: [PATCH 6/8] Add `mod` snippet to ruby-mode for `module` definitions --- snippets/ruby-mode/definitions/mod | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 snippets/ruby-mode/definitions/mod diff --git a/snippets/ruby-mode/definitions/mod b/snippets/ruby-mode/definitions/mod new file mode 100644 index 0000000..118400c --- /dev/null +++ b/snippets/ruby-mode/definitions/mod @@ -0,0 +1,13 @@ +# name: module ... end +# contributor: hitesh , jimeh +# key: mod +# -- +module ${1:`(let ((fn (capitalize (file-name-nondirectory + (file-name-sans-extension + (or (buffer-file-name) + (buffer-name (current-buffer)))))))) + (cond + ((string-match "_" fn) (replace-match "" nil nil fn)) + (t fn)))`} + $0 +end \ No newline at end of file From 7981f8d63b133d596c0bd83d0e33534bef36a3f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Wed, 15 Aug 2012 15:09:59 +0100 Subject: [PATCH 7/8] Closes #281: jit-load in reverse order to maintain coherence with `yas-snippet-dirs` --- yasnippet-tests.el | 6 ++++-- yasnippet.el | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/yasnippet-tests.el b/yasnippet-tests.el index ad125da..9af244b 100644 --- a/yasnippet-tests.el +++ b/yasnippet-tests.el @@ -247,11 +247,13 @@ TODO: correct this bug!" '((".emacs.d/snippets" ("c-mode" (".yas-parents" . "cc-mode") - ("printf" . "printf($1);")) + ("printf" . "printf($1);")) ;; notice the overriding for issue #281 ("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")) + ("c-mode" + (".yas-parents" . "c++-mode") + ("printf" . "printf")) ("cc-mode" ("def" . "# define")) ("emacs-lisp-mode" ("dolist" . "(dolist)")) ("lisp-interaction-mode" ("sc" . "brother from another mother")))) diff --git a/yasnippet.el b/yasnippet.el index db004d0..ab84696 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -1812,6 +1812,7 @@ loading." (when yas-minor-mode (dolist (mode (yas--modes-to-activate)) (let ((forms (gethash mode yas--scheduled-jit-loads))) + ;; must reverse to maintain coherence with `yas-snippet-dirs' (dolist (form forms) (yas--message 3 "Loading for `%s', just-in-time: %s!" mode form) (eval form)) From 100beaf735a65dc5f965ebbf55c68f2beef422de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Wed, 15 Aug 2012 15:33:57 +0100 Subject: [PATCH 8/8] Fix: Ooops forgot to commit the actual fix for #281. --- yasnippet.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yasnippet.el b/yasnippet.el index ab84696..17e6f91 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -1811,7 +1811,7 @@ loading." (defun yas--load-pending-jits () (when yas-minor-mode (dolist (mode (yas--modes-to-activate)) - (let ((forms (gethash mode yas--scheduled-jit-loads))) + (let ((forms (reverse (gethash mode yas--scheduled-jit-loads)))) ;; must reverse to maintain coherence with `yas-snippet-dirs' (dolist (form forms) (yas--message 3 "Loading for `%s', just-in-time: %s!" mode form)