emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] master 0311fe2 15/63: Use :filter instead of yas--fallback


From: Noam Postavsky
Subject: [elpa] master 0311fe2 15/63: Use :filter instead of yas--fallback
Date: Mon, 17 Jul 2017 22:54:12 -0400 (EDT)

branch: master
commit 0311fe26191a713d4c2b8b0b5fe236eb2372c128
Author: Noam Postavsky <address@hidden>
Commit: Noam Postavsky <address@hidden>

    Use :filter instead of yas--fallback
    
    Instead of making yas-expand and yas-expand-from-keymap search for the
    command that would have been called, use a conditional keybinding so the
    Emacs' builtin keybinding lookup code will do the searching instead.
    
    * doc/faq.org: Remove section about old method binding method.  Update
    example to use new method.
    * doc/snippet-expansion.org (Trigger key): Update explanation for new
    method.
    * yasnippet.el (yas-fallback-behavior): Mark obsolete.
    (yas--maybe-expand-key-filter): New function.
    (yas-maybe-expand): New conditional binding.
    (yas-minor-mode-map): Bind it to TAB and <tab>.
    (yas--maybe-expand-from-keymap-filter): New function, extracted from
    `yas-expand-from-keymap'.
    (yas-maybe-expand-from-keymap): New conditional binding.
    * yasnippet-tests.el (yas--key-binding): New function, like
    `key-binding' but overrides `this-command-keys-vector'.
    (snippet-load-uuid): Use it.
    (test-yas-tab-binding, test-yas-in-org): Insert snippet key before
    testing binding.
---
 doc/faq.org               | 69 +------------------------------------------
 doc/snippet-expansion.org | 41 ++++++++++++++------------
 yasnippet-tests.el        | 55 ++++++++++++++++++++++++-----------
 yasnippet.el              | 74 +++++++++++++++++++++++++++--------------------
 4 files changed, 104 insertions(+), 135 deletions(-)

diff --git a/doc/faq.org b/doc/faq.org
index f40cae8..d80bb3b 100644
--- a/doc/faq.org
+++ b/doc/faq.org
@@ -13,73 +13,6 @@ Note that some editors will automatically add a newline for 
you. In
 Emacs, if you set =require-final-newline= to =t=, it will add the
 final newline automatically.
 
-* Why doesn't TAB expand a snippet?
-
-First check the mode line to see if there's =yas=. If not, then try
-=M-x yas-minor-mode= to manually turn on the minor mode and try to
-expand the snippet again. If it works, then, you can add the following
-code to your =.emacs= /before/ loading YASnippet:
-
-#+BEGIN_SRC emacs-lisp
-  (add-hook 'the-major-mode-hook 'yas-minor-mode-on)
-#+END_SRC
-
-where =the-major-mode= is the major mode in which 
[[sym:yas-minor-mode][=yas-minor-mode=]] isn't
-enabled by default.
-
-The command =M-x yas-global-mode= turns YASnippet on automatically for
-/all/ major modes.
-
-If [[sym:yas-minor-mode][=yas-minor-mode=]] is on but the snippet still not 
expanded. Then try
-to see what command is bound to the =TAB= key: press =C-h k= and then
-press =TAB=. Emacs will show you the result.
-
-You'll see a buffer prompted by Emacs saying that
-=TAB runs the command ...=. Alternatively, you might see
-=<tab> runs the command ...=, note the difference between =TAB= and
-=<tab>= where the latter has priority. If you see =<tab>= bound to a
-command other than [[sym:yas-expand][=yas-expand=]], (e.g. in =org-mode=) you 
can try the
-following code to work around:
-
-#+BEGIN_SRC emacs-lisp
-  (add-hook 'org-mode-hook
-            (let ((original-command (lookup-key org-mode-map [tab])))
-              `(lambda ()
-                 (setq yas-fallback-behavior
-                       '(apply ,original-command))
-                 (local-set-key [tab] 'yas-expand))))
-#+END_SRC
-
-replace =org-mode-hook= and =org-mode-map= with the major mode hook you
-are dealing with (Use =C-h m= to see what major mode you are in).
-
-As an alternative, you can also try
-
-#+BEGIN_SRC emacs-lisp
-  (defun yas-advise-indent-function (function-symbol)
-    (eval `(defadvice ,function-symbol (around yas-try-expand-first activate)
-             ,(format
-               "Try to expand a snippet before point, then call `%s' as usual"
-               function-symbol)
-             (let ((yas-fallback-behavior nil))
-               (unless (and (interactive-p)
-                            (yas-expand))
-                 ad-do-it)))))
-
-  (yas-advise-indent-function 'ruby-indent-line)
-#+END_SRC
-
-To /advise/ the modes indentation function bound to TAB, (in this case
-=ruby-indent-line=) to first try to run [[sym:yas-expand][=yas-expand=]].
-
-If the output of =C-h k RET <tab>= tells you that =<tab>= is indeed
-bound to [[sym:yas-expand][=yas-expand=]] but YASnippet still doesn't work, 
check your
-configuration and you may also ask for help on the 
[[http://groups.google.com/group/smart-snippet][discussion group]].
-See this particular 
[[http://code.google.com/p/yasnippet/issues/detail?id=93&can=1][thread]] for 
quite some solutions and alternatives.
-
-Don't forget to attach the information on what command is bound to TAB
-as well as the mode information (Can be obtained by =C-h m=).
-
 * Why doesn't TAB navigation work with flyspell
 
 A workaround is to inhibit flyspell overlays while the snippet is
@@ -107,7 +40,7 @@ Edit the keymaps 
[[sym:yas-minor-mode-map][=yas-minor-mode-map=]] and
 #+begin_src emacs-lisp :exports code
    (define-key yas-minor-mode-map (kbd "<tab>") nil)
    (define-key yas-minor-mode-map (kbd "TAB") nil)
-   (define-key yas-minor-mode-map (kbd "<the new key>") 'yas-expand)
+   (define-key yas-minor-mode-map (kbd "<the new key>") yas-maybe-expand)
 
    ;;keys for navigation
    (define-key yas-keymap [(tab)]       nil)
diff --git a/doc/snippet-expansion.org b/doc/snippet-expansion.org
index 4bd133b..808a888 100644
--- a/doc/snippet-expansion.org
+++ b/doc/snippet-expansion.org
@@ -32,17 +32,30 @@
 ** Trigger key
 
 [[sym:yas-expand][=yas-expand=]] tries to expand a /snippet abbrev/ (also 
known as
-/snippet key/) before point.
+/snippet key/) before point.  YASnippet also provides a /conditional
+binding/ for this command: the variable [[sym:yas-expand][=yas-maybe-expand=]] 
contains a
+special value which, when bound in a keymap, tells Emacs to call
+[[sym:yas-expand][=yas-expand=]] if and only if there is a snippet abbrev 
before point.  If there is not 
 
-When [[sym:yas-minor-mode][=yas-minor-mode=]] is enabled, it binds 
[[sym:yas-expand][=yas-expand=]] to =TAB= and
-=<tab>= by default, however, you can freely set it to some other key:
+When [[sym:yas-minor-mode][=yas-minor-mode=]] is enabled, it binds 
[[sym:yas-maybe-expand][=yas-maybe-expand=]] to =TAB=
+and =<tab>= by default, however, you can freely remove those bindings:
 
 #+begin_src emacs-lisp :exports code
    (define-key yas-minor-mode-map (kbd "<tab>") nil)
    (define-key yas-minor-mode-map (kbd "TAB") nil)
-   (define-key yas-minor-mode-map (kbd "<the new key>") 'yas-expand)
 #+end_src
 
+And set your own:
+
+#+begin_src emacs-lisp :exports code
+  ;; Bind `SPC' to `yas-expand' when snippet expansion available (it
+  ;; will still call `self-insert-command' otherwise).
+  (define-key yas-minor-mode-map (kbd "SPC") yas-maybe-expand)
+  ;; Bind `C-c y' to `yas-expand' ONLY.
+  (define-key yas-minor-mode-map (kbd "C-c y") #'yas-expand)
+#+end_src
+
+
 To enable the YASnippet minor mode in all buffers globally use the
 command [[sym:yas-global-mode][=yas-global-mode=]]. This will enable a 
modeline indicator,
 =yas=:
@@ -50,24 +63,14 @@ command [[sym:yas-global-mode][=yas-global-mode=]]. This 
will enable a modeline
 [[./images/minor-mode-indicator.png]]
 
 When you use [[sym:yas-global-mode][=yas-global-mode=]] you can also 
selectively disable
-YASnippet in some buffers by setting the buffer-local variable
-[[sym:yas-dont-active][=yas-dont-active=]] in the buffer's mode hook.
+YASnippet in some buffers by calling [[sym:yas-minor-mode][=yas-minor-mode=]] 
with a negative
+argument in the buffer's mode hook.
 
 *** Fallback behaviour
 
-[[sym:yas-fallback-behaviour][=yas-fallback-behaviour=]] is a customization 
variable bound to
-'=call-other-command= by default. If [[sym:yas-expand][=yas-expand=]] failed 
to find any
-suitable snippet to expand, it will disable the minor mode temporarily
-and find if there's any other command bound to the same key.
-
-If found, the command will be called. Usually this works very well
---when there's a snippet, expand it, otherwise, call whatever command
-originally bind to the trigger key.
-
-However, you can change this behavior by customizing the
-[[sym:yas-fallback-behavior][=yas-fallback-behavior=]] variable. If you set 
this variable to
-'=return-nil=, it will return =nil= instead of trying to call the
-/original/ command when no snippet is found.
+YASnippet used to support a more complicated way of sharing
+keybindings before [[sym:yas-expand][=yas-maybe-expand=]] was added.  This is 
now
+obsolete.
 
 ** Insert at point
 
diff --git a/yasnippet-tests.el b/yasnippet-tests.el
index 50fce61..02b4a45 100644
--- a/yasnippet-tests.el
+++ b/yasnippet-tests.el
@@ -668,11 +668,11 @@ TODO: correct this bug!"
      (text-mode)
      (yas-minor-mode +1)
      (should (equal (yas-lookup-snippet "one") "one"))
-     (should (eq (key-binding "\C-c1") 'yas-expand-from-keymap))
+     (should (eq (yas--key-binding "\C-c1") 'yas-expand-from-keymap))
      (yas-define-snippets
       'text-mode '(("_1" "one!" "won" nil nil nil nil nil "uuid-1")))
      (should (null (yas-lookup-snippet "one" nil 'noerror)))
-     (should (null (key-binding "\C-c1")))
+     (should (null (yas--key-binding "\C-c1")))
      (should (equal (yas-lookup-snippet "won") "one!")))))
 
 (ert-deftest snippet-save ()
@@ -963,16 +963,23 @@ TODO: be meaner"
 ;;; The infamous and problematic tab keybinding
 ;;;
 (ert-deftest test-yas-tab-binding ()
-  (with-temp-buffer
-    (yas-minor-mode -1)
-    (should (not (eq (key-binding (yas--read-keybinding "<tab>")) 
'yas-expand)))
-    (yas-minor-mode 1)
-    (should (eq (key-binding (yas--read-keybinding "<tab>")) 'yas-expand))
-    (yas-expand-snippet "$1 $2 $3")
-    (should (eq (key-binding [(tab)]) 'yas-next-field-or-maybe-expand))
-    (should (eq (key-binding (kbd "TAB")) 'yas-next-field-or-maybe-expand))
-    (should (eq (key-binding [(shift tab)]) 'yas-prev-field))
-    (should (eq (key-binding [backtab]) 'yas-prev-field))))
+  (yas-saving-variables
+   (yas-with-snippet-dirs
+    '((".emacs.d/snippets"
+       ("fundamental-mode"
+        ("foo" . "foobar"))))
+    (yas-reload-all)
+    (with-temp-buffer
+      (yas-minor-mode -1)
+      (insert "foo")
+      (should (not (eq (key-binding (yas--read-keybinding "<tab>")) 
'yas-expand)))
+      (yas-minor-mode 1)
+      (should (eq (key-binding (yas--read-keybinding "<tab>")) 'yas-expand))
+      (yas-expand-snippet "$1 $2 $3")
+      (should (eq (key-binding [(tab)]) 'yas-next-field-or-maybe-expand))
+      (should (eq (key-binding (kbd "TAB")) 'yas-next-field-or-maybe-expand))
+      (should (eq (key-binding [(shift tab)]) 'yas-prev-field))
+      (should (eq (key-binding [backtab]) 'yas-prev-field))))))
 
 (ert-deftest test-rebindings ()
   (let* ((yas-minor-mode-map (copy-keymap yas-minor-mode-map))
@@ -992,11 +999,18 @@ TODO: be meaner"
       (should (eq (key-binding (kbd "SPC")) 'yas-expand)))))
 
 (ert-deftest test-yas-in-org ()
-  (with-temp-buffer
-    (org-mode)
-    (yas-minor-mode 1)
-    (should (eq (key-binding [(tab)]) 'yas-expand))
-    (should (eq (key-binding (kbd "TAB")) 'yas-expand))))
+  (yas-saving-variables
+   (yas-with-snippet-dirs
+    '((".emacs.d/snippets"
+       ("org-mode"
+        ("foo" . "foobar"))))
+    (yas-reload-all)
+    (with-temp-buffer
+      (org-mode)
+      (yas-minor-mode 1)
+      (insert "foo")
+      (should (eq (key-binding [(tab)]) 'yas-expand))
+      (should (eq (key-binding (kbd "TAB")) 'yas-expand))))))
 
 (ert-deftest test-yas-activate-extra-modes ()
   "Given a symbol, `yas-activate-extra-mode' should be able to
@@ -1067,6 +1081,13 @@ add the snippets associated with the given mode."
   (let ((interprogram-paste-function (lambda () string)))
     (ert-simulate-command '(yank nil))))
 
+(defun yas--key-binding (key)
+  "Like `key-binding', but override `this-command-keys-vector'.
+This lets `yas--maybe-expand-from-keymap-filter' work as expected."
+  (cl-letf (((symbol-function 'this-command-keys-vector)
+             (lambda () (cl-coerce key 'vector))))
+    (key-binding key)))
+
 (defun yas-make-file-or-dirs (ass)
   (let ((file-or-dir-name (car ass))
         (content (cdr ass)))
diff --git a/yasnippet.el b/yasnippet.el
index 7b01599..1a95005 100644
--- a/yasnippet.el
+++ b/yasnippet.el
@@ -271,22 +271,20 @@ Otherwise `yas-next-field-or-maybe-expand' just moves on 
to the
 next field"
   :type 'boolean)
 
-(defcustom yas-fallback-behavior 'call-other-command
-  "How to act when `yas-expand' does *not* expand a snippet.
-
-- `call-other-command' means try to temporarily disable YASnippet
-    and call the next command bound to whatever key was used to
-    invoke `yas-expand'.
-
-- nil or the symbol `return-nil' mean do nothing. (and
-  `yas-expand' returns nil)
-
-- A Lisp form (apply COMMAND . ARGS) means interactively call
-  COMMAND. If ARGS is non-nil, call COMMAND non-interactively
-  with ARGS as arguments."
+(defcustom yas-fallback-behavior 'return-nil
+  "This option is obsolete.
+Now that the conditional keybinding `yas-maybe-expand' is
+available, there's no more need for it."
   :type '(choice (const :tag "Call previous command"  call-other-command)
                  (const :tag "Do nothing"             return-nil)))
 
+(make-obsolete-variable
+ 'yas-fallback-behavior
+ "For `call-other-command' behavior bind to the conditional
+command value `yas-maybe-expand', for `return-nil' behavior bind
+directly to `yas-expand'."
+ "0.12")
+
 (defcustom yas-choose-keys-first nil
   "If non-nil, prompt for snippet key first, then for template.
 
@@ -560,10 +558,20 @@ snippet itself contains a condition that returns the 
symbol
 (defvar yas--minor-mode-menu nil
   "Holds the YASnippet menu.")
 
+(defun yas--maybe-expand-key-filter (cmd)
+  (if (yas--templates-for-key-at-point) cmd))
+
+(defconst yas-maybe-expand
+  '(menu-item "" yas-expand :filter yas--maybe-expand-key-filter)
+  "A conditional key definition.
+This can be used as a key definition in keymaps to bind a key to
+`yas-expand' only when there is a snippet available to be
+expanded.")
+
 (defvar yas-minor-mode-map
   (let ((map (make-sparse-keymap)))
-    (define-key map [(tab)]     'yas-expand)
-    (define-key map (kbd "TAB") 'yas-expand)
+    (define-key map [(tab)]     yas-maybe-expand)
+    (define-key map (kbd "TAB") yas-maybe-expand)
     (define-key map "\C-c&\C-s" 'yas-insert-snippet)
     (define-key map "\C-c&\C-n" 'yas-new-snippet)
     (define-key map "\C-c&\C-v" 'yas-visit-snippet-file)
@@ -703,10 +711,10 @@ This variable is placed in `emulation-mode-map-alists'.
 
 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.")
+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 `yas-maybe-expand-from-keymap'
+which decides on the snippet to expand.")
 
 (defun yas-direct-keymaps-reload ()
   "Force reload the direct keybinding for active snippet tables."
@@ -976,7 +984,7 @@ Has the following fields:
   A keymap for the snippets in this table that have direct
   keybindings. This is kept in sync with the keyhash, i.e., all
   the elements of the keyhash that are vectors appear here as
-  bindings to `yas-expand-from-keymap'.
+  bindings to `yas-maybe-expand-from-keymap'.
 
 `yas--table-uuidhash'
 
@@ -1075,6 +1083,10 @@ Has the following fields:
         ;;
         (remhash uuid (yas--table-uuidhash table))))))
 
+(defconst yas-maybe-expand-from-keymap
+  '(menu-item "" yas-expand-from-keymap
+              :filter yas--maybe-expand-from-keymap-filter))
+
 (defun yas--add-template (table template)
   "Store in TABLE the snippet template TEMPLATE.
 
@@ -1093,7 +1105,7 @@ keybinding)."
                             (make-hash-table :test 'equal)
                             (yas--table-hash table))))
       (when (vectorp k)
-        (define-key (yas--table-direct-keymap table) k 
'yas-expand-from-keymap)))
+        (define-key (yas--table-direct-keymap table) k 
yas-maybe-expand-from-keymap)))
 
     ;; Update TABLE's `yas--table-uuidhash'
     (puthash (yas--template-uuid template)
@@ -2167,12 +2179,7 @@ object satisfying `yas--field-p' to restrict the 
expansion to."
               (nth 2 templates-and-pos)))
       (yas--fallback))))
 
-(defun yas-expand-from-keymap ()
-  "Directly expand some snippets, searching `yas--direct-keymaps'.
-
-If expansion fails, execute the previous binding for this key"
-  (interactive)
-  (setq yas--condition-cache-timestamp (current-time))
+(defun yas--maybe-expand-from-keymap-filter (cmd)
   (let* ((vec (cl-subseq (this-command-keys-vector)
                          (if current-prefix-arg
                              (length (this-command-keys))
@@ -2180,10 +2187,15 @@ If expansion fails, execute the previous binding for 
this key"
          (templates (cl-mapcan (lambda (table)
                                  (yas--fetch table vec))
                                (yas--get-snippet-tables))))
-    (if templates
-        (yas--expand-or-prompt-for-template templates)
-      (let ((yas-fallback-behavior 'call-other-command))
-        (yas--fallback)))))
+    (if templates (or cmd templates))))
+
+(defun yas-expand-from-keymap ()
+  "Directly expand some snippets, searching `yas--direct-keymaps'."
+  (interactive)
+  (setq yas--condition-cache-timestamp (current-time))
+  (let* ((templates (yas--maybe-expand-from-keymap-filter nil)))
+    (when templates
+      (yas--expand-or-prompt-for-template templates))))
 
 (defun yas--expand-or-prompt-for-template (templates &optional start end)
   "Expand one of TEMPLATES from START to END.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]