From 32ee5cbde5313985c889d1e4bfd6d7d836f4ca3d Mon Sep 17 00:00:00 2001 From: Joao Tavora Date: Mon, 21 Oct 2013 09:28:44 +0100 Subject: [PATCH 1/5] Closes #415: remove c-specific hacks, harmful on emacs 24.3 --- yasnippet.el | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/yasnippet.el b/yasnippet.el index 91aabd9..64b0434 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -4394,33 +4394,6 @@ and return the directory. Return nil if not found." (setq file nil)))) root)))) -;; `c-neutralize-syntax-in-CPP` sometimes fires "End of Buffer" error -;; (when it execute forward-char) and interrupt the after change -;; hook. Thus prevent the insert-behind hook of yasnippet to be -;; invoked. Here's a way to reproduce it: - -;; # open a *new* Emacs. -;; # load yasnippet. -;; # open a *new* .cpp file. -;; # input "inc" and press TAB to expand the snippet. -;; # select the `#include <...>` snippet. -;; # type inside `<>` - -(defadvice c-neutralize-syntax-in-CPP - (around yas--mp/c-neutralize-syntax-in-CPP activate) - "Adviced `c-neutralize-syntax-in-CPP' to properly -handle the `end-of-buffer' error fired in it by calling -`forward-char' at the end of buffer." - (condition-case err - ad-do-it - (error (message (error-message-string err))))) - -;; disable c-electric-* serial command in YAS fields -(add-hook 'c-mode-common-hook - '(lambda () - (dolist (k '(":" ">" ";" "<" "{" "}")) - (define-key (symbol-value (make-local-variable 'yas-keymap)) - k 'self-insert-command)))) ;;; Backward compatibility to yasnippet <= 0.7 From ffd497d541c53f466df132b97d2e1de6320a9551 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sat, 26 Oct 2013 12:11:04 -0400 Subject: [PATCH 2/5] don't kill snippet buffer unless saved Split the quit-window part of yas-load-snippet-buffer into yas-load-snippet-buffer-and-close, and only quit if the snippet was saved. This resolves #417, where you could lose a snippet by giving the wrong answer in a prompt. --- yasnippet.el | 72 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/yasnippet.el b/yasnippet.el index 64b0434..5d0d90a 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -837,7 +837,8 @@ Honour `yas-dont-activate', which see." (when (third ent) (define-key map (third ent) (second ent))) (vector (first ent) (second ent) t)) - '(("Load this snippet" yas-load-snippet-buffer "\C-c\C-c") + '(("Load this snippet" yas-load-snippet-buffer "\C-c\C-l") + ("Load and quit window" yas-load-snippet-buffer-and-close "\C-c\C-c") ("Try out this snippet" yas-tryout-snippet "\C-c\C-t"))))) map) "The keymap used when `snippet-mode' is active.") @@ -2527,7 +2528,9 @@ neither do the elements of PARENTS." 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." +whether (and where) to save the snippet. + +Returns the name of the file saved (if any)." (interactive (list (yas--read-table) t)) (cond ;; We have `yas--editing-template', this buffer's content comes from a @@ -2547,35 +2550,42 @@ whether (and where) to save the snippet, then quit the window." (yas--define-snippets-1 (yas--parse-template buffer-file-name) table))))) - (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 - (yas--message 3 "Snippet \"%s\" loaded for %s." - (yas--template-name yas--editing-template) - (yas--table-name (yas--template-table yas--editing-template))) - (quit-window interactive))) + (prog1 + (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 + (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-load-snippet-buffer-and-close (table &optional kill interactive) + "Call `yas-load-snippet-buffer' and then `quit-window', prefix + argument KILL passed to `quit-window'." + (interactive (list (yas--read-table) current-prefix-arg t)) + (and (yas-load-snippet-buffer table interactive) + (quit-window kill))) (defun yas-tryout-snippet (&optional debug) "Test current buffer's snippet template in other buffer." From 205b0e697055d8dd92366da8ba0963e350ad7817 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sat, 26 Oct 2013 13:42:32 -0400 Subject: [PATCH 3/5] move snippet saving from loading to closing yas-load-snippet-buffer now just loads the snippet, yas-load-snippet-buffer-and-close also saves it. --- yasnippet.el | 77 ++++++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/yasnippet.el b/yasnippet.el index 5d0d90a..19c6a5a 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -2527,10 +2527,7 @@ neither do the elements of PARENTS." 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. - -Returns the name of the file saved (if any)." +When called interactively, prompt for the table name." (interactive (list (yas--read-table) t)) (cond ;; We have `yas--editing-template', this buffer's content comes from a @@ -2549,43 +2546,45 @@ Returns the name of the file saved (if any)." (set (make-local-variable 'yas--editing-template) (yas--define-snippets-1 (yas--parse-template buffer-file-name) table))))) + (when interactive + (yas--message 3 "Snippet \"%s\" loaded for %s." + (yas--template-name yas--editing-template) + (yas--table-name (yas--template-table yas--editing-template))))) - (prog1 - (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 - (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-load-snippet-buffer-and-close (table &optional kill) + "Load the snippet with `yas-load-snippet-buffer', offer to + save, then `quit-window' if saved. -(defun yas-load-snippet-buffer-and-close (table &optional kill interactive) - "Call `yas-load-snippet-buffer' and then `quit-window', prefix - argument KILL passed to `quit-window'." - (interactive (list (yas--read-table) current-prefix-arg t)) - (and (yas-load-snippet-buffer table interactive) - (quit-window kill))) +The prefix argument KILL is passed to `quit-window'. + +Don't use this from a Lisp program, call `yas-load-snippet-buffer' +and `kill-buffer' instead." + (interactive (list (yas--read-table) current-prefix-arg)) + (yas-load-snippet-buffer table t) + (when (and (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) + (quit-window kill)))))) (defun yas-tryout-snippet (&optional debug) "Test current buffer's snippet template in other buffer." From 33dff9ad12ae166a49377a093bf080dc247e1578 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sat, 26 Oct 2013 14:40:50 -0400 Subject: [PATCH 4/5] let C-c C-c save existing snippets too --- yasnippet.el | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/yasnippet.el b/yasnippet.el index 19c6a5a..255b5e4 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -2552,9 +2552,12 @@ When called interactively, prompt for the table name." (yas--table-name (yas--template-table yas--editing-template))))) (defun yas-load-snippet-buffer-and-close (table &optional kill) - "Load the snippet with `yas-load-snippet-buffer', offer to + "Load the snippet with `yas-load-snippet-buffer', possibly save, then `quit-window' if saved. +If the snippet is new, ask the user whether (and where) to save +it. If the snippet already has a file, just save it. + The prefix argument KILL is passed to `quit-window'. Don't use this from a Lisp program, call `yas-load-snippet-buffer' @@ -2583,8 +2586,10 @@ and `kill-buffer' instead." (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) - (quit-window kill)))))) + (setf (yas--template-file yas--editing-template) buffer-file-name))))) + (when buffer-file-name + (save-buffer) + (quit-window kill))) (defun yas-tryout-snippet (&optional debug) "Test current buffer's snippet template in other buffer." From d7b2b89eaaaa1c193a6360e990ff1b2a1e4cf389 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Wed, 30 Oct 2013 18:25:51 -0400 Subject: [PATCH 5/5] widen before deleting regions This avoid problems with c-mode's after change hooks. --- yasnippet.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yasnippet.el b/yasnippet.el index 255b5e4..c7aecfa 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -3819,7 +3819,7 @@ Meant to be called in a narrowed buffer, does various passes" (yas--calculate-adjacencies snippet) ;; Delete $-constructs ;; - (yas--delete-regions yas--dollar-regions) + (save-restriction (widen) (yas--delete-regions yas--dollar-regions)) ;; restore backquoted expression values ;; (yas--restore-backquotes)