From de34d91a3c149993526370f98cf36eb6da565976 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sun, 10 Aug 2014 12:21:47 -0400 Subject: [PATCH 1/6] Closes #470, handle non-whitespace newlines Many modes put newlines in comment ender class because they have line comments. * yasnippet.el (yas-try-key-from-whitespace): new function. (yas-key-syntaxes): use it in place of "^ ". * yasnippet-tests.el (complicated-yas-key-syntaxes): test it. --- yasnippet-tests.el | 12 ++++++++---- yasnippet.el | 14 +++++++++++++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/yasnippet-tests.el b/yasnippet-tests.el index f40ed25..ae7a8d1 100644 --- a/yasnippet-tests.el +++ b/yasnippet-tests.el @@ -322,12 +322,13 @@ TODO: correct this bug!" (yas-saving-variables (yas-with-snippet-dirs '((".emacs.d/snippets" - ("text-mode" + ("emacs-lisp-mode" ("foo-barbaz" . "# condition: yas--foobarbaz\n# --\nOKfoo-barbazOK") ("barbaz" . "# condition: yas--barbaz\n# --\nOKbarbazOK") - ("baz" . "OKbazOK")))) + ("baz" . "OKbazOK") + ("'quote" . "OKquoteOK")))) (yas-reload-all) - (text-mode) + (emacs-lisp-mode) (yas-minor-mode-on) (let ((yas-key-syntaxes '("w" "w_"))) (let ((yas--barbaz t)) @@ -342,7 +343,10 @@ TODO: correct this bug!" 'again)) yas-key-syntaxes)) (yas--foobarbaz t)) - (yas-should-expand '(("foo-barbaz" . "foo-barOKbazOK"))))))))) + (yas-should-expand '(("foo-barbaz" . "foo-barOKbazOK"))))) + (let ((yas-key-syntaxes '(yas-try-key-from-whitespace))) + (yas-should-expand '(("xxx\n'quote" . "xxx\nOKquoteOK") + ("xxx 'quote" . "xxx OKquoteOK")))))))) ;;; Loading diff --git a/yasnippet.el b/yasnippet.el index fc5d36b..741ab61 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -388,7 +388,8 @@ the trigger key itself." map) "The active keymap while a snippet expansion is in progress.") -(defvar yas-key-syntaxes (list "w" "w_" "w_." "w_.()" "^ ") +(defvar yas-key-syntaxes (list "w" "w_" "w_." "w_.()" + #'yas-try-key-from-whitespace) "Syntaxes and functions to help look for trigger keys before point. Each element in this list specifies how to skip buffer positions @@ -2725,6 +2726,17 @@ and `kill-buffer' instead." groups-hash))) + +;;; User convenience functions, for using in `yas-key-syntaxes' + +(defun yas-try-key-from-whitespace () + "Go back to nearest whitespace. + +A newline will be considered whitespace even if the mode syntax +marks it as something else (typically comment ender). Use as +element of `yas-key-syntaxes'." + (skip-chars-backward "^[:space:]\n")) + ;;; User convenience functions, for using in snippet definitions From 280ece2af4be2b51629557944feb4f6e36b751f3 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sun, 10 Aug 2014 12:47:22 -0400 Subject: [PATCH 2/6] Add yas-shortest-key-until-whitespace Example yas-key-syntaxes function. * yasnippet.el (yas-shortest-key-until-whitespace): new function. * yasnippet-tests.el (complicated-yas-key-syntaxes): test it. --- yasnippet-tests.el | 5 ++++- yasnippet.el | 9 +++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/yasnippet-tests.el b/yasnippet-tests.el index ae7a8d1..8a845dc 100644 --- a/yasnippet-tests.el +++ b/yasnippet-tests.el @@ -346,7 +346,10 @@ TODO: correct this bug!" (yas-should-expand '(("foo-barbaz" . "foo-barOKbazOK"))))) (let ((yas-key-syntaxes '(yas-try-key-from-whitespace))) (yas-should-expand '(("xxx\n'quote" . "xxx\nOKquoteOK") - ("xxx 'quote" . "xxx OKquoteOK")))))))) + ("xxx 'quote" . "xxx OKquoteOK")))) + (let ((yas-key-syntaxes '(yas-shortest-key-until-whitespace)) + (yas--foobarbaz t) (yas--barbaz t)) + (yas-should-expand '(("foo-barbaz" . "foo-barOKbazOK")))))))) ;;; Loading diff --git a/yasnippet.el b/yasnippet.el index 741ab61..e006d52 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -2737,6 +2737,15 @@ marks it as something else (typically comment ender). Use as element of `yas-key-syntaxes'." (skip-chars-backward "^[:space:]\n")) +(defun yas-shortest-key-until-whitespace () + "Return `again' until at whitespace. + +A newline will be considered whitespace even if the mode syntax +marks it as something else (typically comment ender). Use as +element of `yas-key-syntaxes'." + (when (/= (skip-chars-backward "^[:space:]\n" (1- (point))) 0) + 'again)) + ;;; User convenience functions, for using in snippet definitions From 10ecde158e5efae11186aa4c261aaec6261e8e51 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sun, 10 Aug 2014 12:52:52 -0400 Subject: [PATCH 3/6] Pass start point to yas-key-syntaxes functions * yasnippet-tests.el (complicated-yas-key-syntaxes): accept argument. * yasnippet.el (yas-try-key-from-whitespace): accept argument. (yas-shortest-key-until-whitespace): accept argument. (yas--templates-for-key-at-point): pass start point the methods. (yas-key-syntaxes): update docstring. --- yasnippet-tests.el | 2 +- yasnippet.el | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/yasnippet-tests.el b/yasnippet-tests.el index 8a845dc..12ca615 100644 --- a/yasnippet-tests.el +++ b/yasnippet-tests.el @@ -337,7 +337,7 @@ TODO: correct this bug!" (let ((yas--foobarbaz t)) (yas-should-expand '(("foo-barbaz" . "OKfoo-barbazOK")))) (let ((yas-key-syntaxes - (cons #'(lambda () + (cons #'(lambda (_start-point) (unless (looking-back "-") (backward-char) 'again)) diff --git a/yasnippet.el b/yasnippet.el index e006d52..93eceb2 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -395,15 +395,15 @@ the trigger key itself." Each element in this list specifies how to skip buffer positions backwards and look for the start of a trigger key. -Each element can be either a string or a functino of no -arguments. A string element is simply passed to -`skip-syntax-backward' whereas a function element is called with -no arguments and should also place point before the original +Each element can be either a string or a function receiving the +original point as an argument. A string element is simply passed +to `skip-syntax-backward' whereas a function element is called +with no arguments and should also place point before the original position. The string between the resulting buffer position and the original -point.in the is matched against the trigger keys in the active -snippet tables. +point is matched against the trigger keys in the active snippet +tables. If no expandable snippets are found, the next element is the list is tried, unless a function element returned the symbol `again', @@ -1239,7 +1239,7 @@ Returns (TEMPLATES START END). This function respects (skip-syntax-backward method) (setq methods (cdr methods))) ((functionp method) - (unless (eq (funcall method) + (unless (eq (funcall method original) 'again) (setq methods (cdr methods)))) (t @@ -2729,7 +2729,7 @@ and `kill-buffer' instead." ;;; User convenience functions, for using in `yas-key-syntaxes' -(defun yas-try-key-from-whitespace () +(defun yas-try-key-from-whitespace (_start-point) "Go back to nearest whitespace. A newline will be considered whitespace even if the mode syntax @@ -2737,7 +2737,7 @@ marks it as something else (typically comment ender). Use as element of `yas-key-syntaxes'." (skip-chars-backward "^[:space:]\n")) -(defun yas-shortest-key-until-whitespace () +(defun yas-shortest-key-until-whitespace (_start-point) "Return `again' until at whitespace. A newline will be considered whitespace even if the mode syntax From 5d10b5dfee3ee3d1c5c199e8c9acfb9c9b26172c Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sun, 10 Aug 2014 13:07:43 -0400 Subject: [PATCH 4/6] Add yas-longest-key-from-whitespace Example yas-key-syntaxes function. * yasnippet.el (yas-longest-key-from-whitespace): new function. * yasnippet-tests.el (complicated-yas-key-syntaxes): test it. --- yasnippet-tests.el | 4 +++- yasnippet.el | 13 +++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/yasnippet-tests.el b/yasnippet-tests.el index 12ca615..d090c51 100644 --- a/yasnippet-tests.el +++ b/yasnippet-tests.el @@ -349,7 +349,9 @@ TODO: correct this bug!" ("xxx 'quote" . "xxx OKquoteOK")))) (let ((yas-key-syntaxes '(yas-shortest-key-until-whitespace)) (yas--foobarbaz t) (yas--barbaz t)) - (yas-should-expand '(("foo-barbaz" . "foo-barOKbazOK")))))))) + (yas-should-expand '(("foo-barbaz" . "foo-barOKbazOK"))) + (setq yas-key-syntaxes '(yas-longest-key-from-whitespace)) + (yas-should-expand '(("foo-barbaz" . "OKfoo-barbazOK")))))))) ;;; Loading diff --git a/yasnippet.el b/yasnippet.el index 93eceb2..dcf6bf0 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -2746,6 +2746,19 @@ element of `yas-key-syntaxes'." (when (/= (skip-chars-backward "^[:space:]\n" (1- (point))) 0) 'again)) +(defun yas-longest-key-from-whitespace (start-point) + "Go back to nearest whitespace, then go forward and return `again' until at START-POINT. + +A newline will be considered whitespace even if the mode syntax +marks it as something else (typically comment ender). Use as +element of `yas-key-syntaxes'." + (if (= (point) start-point) + (yas-try-key-from-whitespace start-point) + (forward-char)) + (unless (= original (1+ (point))) + 'again)) + + ;;; User convenience functions, for using in snippet definitions From 47a3d5f1cb13713062592a9fa27dbe2c444f3da2 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sun, 10 Aug 2014 13:13:45 -0400 Subject: [PATCH 5/6] Fix yas-key-syntaxes example functions docstrings. * yasnippet.el (yas-try-key-from-whitespace), (yas-shortest-key-until-whitespace), (yas-longest-key-from-whitespace): docstring describes the effect, not implementation. --- yasnippet.el | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/yasnippet.el b/yasnippet.el index dcf6bf0..900d326 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -2730,28 +2730,22 @@ and `kill-buffer' instead." ;;; User convenience functions, for using in `yas-key-syntaxes' (defun yas-try-key-from-whitespace (_start-point) - "Go back to nearest whitespace. + "As `yas-key-syntaxes' element, look for whitespace delimited key. A newline will be considered whitespace even if the mode syntax -marks it as something else (typically comment ender). Use as -element of `yas-key-syntaxes'." +marks it as something else (typically comment ender)." (skip-chars-backward "^[:space:]\n")) (defun yas-shortest-key-until-whitespace (_start-point) - "Return `again' until at whitespace. - -A newline will be considered whitespace even if the mode syntax -marks it as something else (typically comment ender). Use as -element of `yas-key-syntaxes'." + "Like `yas-longest-key-from-whitespace' but take the shortest key." (when (/= (skip-chars-backward "^[:space:]\n" (1- (point))) 0) 'again)) (defun yas-longest-key-from-whitespace (start-point) - "Go back to nearest whitespace, then go forward and return `again' until at START-POINT. + "As `yas-key-syntaxes' element, look for longest key between point and whitespace. A newline will be considered whitespace even if the mode syntax -marks it as something else (typically comment ender). Use as -element of `yas-key-syntaxes'." +marks it as something else (typically comment ender)." (if (= (point) start-point) (yas-try-key-from-whitespace start-point) (forward-char)) From d982b701fc4dc2e37e1a02b0aed2f0f713d9bf68 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sun, 10 Aug 2014 13:29:25 -0400 Subject: [PATCH 6/6] Fix edge case in yas-longest-key-from-whitespace * yasnippet.el (yas-longest-key-from-whitespace): don't try again if start-point is on whitespace. * yasnippet-tests.el (complicated-yas-key-syntaxes): check edge case. --- yasnippet-tests.el | 3 ++- yasnippet.el | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/yasnippet-tests.el b/yasnippet-tests.el index d090c51..4b3a440 100644 --- a/yasnippet-tests.el +++ b/yasnippet-tests.el @@ -351,7 +351,8 @@ TODO: correct this bug!" (yas--foobarbaz t) (yas--barbaz t)) (yas-should-expand '(("foo-barbaz" . "foo-barOKbazOK"))) (setq yas-key-syntaxes '(yas-longest-key-from-whitespace)) - (yas-should-expand '(("foo-barbaz" . "OKfoo-barbazOK")))))))) + (yas-should-expand '(("foo-barbaz" . "OKfoo-barbazOK") + ("foo " . "foo ")))))))) ;;; Loading diff --git a/yasnippet.el b/yasnippet.el index 900d326..ea5fe33 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -2749,7 +2749,7 @@ marks it as something else (typically comment ender)." (if (= (point) start-point) (yas-try-key-from-whitespace start-point) (forward-char)) - (unless (= original (1+ (point))) + (unless (<= start-point (1+ (point))) 'again))