Closes #296: No longer use customizable yas-trigger-key and friends.

Use keymaps that the user can customise with `define-key` like all the
other modes
This commit is contained in:
João Távora 2012-11-06 14:12:18 +00:00
parent f836621480
commit cd70010b83
2 changed files with 49 additions and 146 deletions

View File

@ -444,21 +444,19 @@ TODO: be meaner"
(yas-minor-mode 1)
(should (eq (key-binding (yas--read-keybinding "<tab>")) 'yas-expand))
(yas-expand-snippet "$1 $2 $3")
(dolist (k (if (listp yas-next-field-key)
yas-next-field-key
(list yas-next-field-key)))
(should (eq (key-binding (yas--read-keybinding k)) 'yas-next-field-or-maybe-expand)))
(dolist (k (if (listp yas-prev-field-key)
yas-prev-field-key
(list yas-prev-field-key)))
(should (eq (key-binding (yas--read-keybinding k)) 'yas-prev-field)))))
(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-yas-in-org ()
(with-temp-buffer
(org-mode)
(yas-minor-mode 1)
(should (eq (key-binding (yas--read-keybinding "<tab>")) 'yas-expand))))
(should (eq (key-binding [(tab)]) 'yas-expand))
(should (eq (key-binding (kbd "TAB")) 'yas-expand))))
;;; Helpers
;;;
(defun yas/ert ()

View File

@ -63,7 +63,8 @@
;; M-x yas-expand
;;
;; Try to expand snippets before point. In `yas-minor-mode',
;; this is bound to `yas-trigger-key' which you can customize.
;; this is normally bound to TAB, but you can customize it in
;; `yas-minor-mode-map'.
;;
;; M-x yas-load-directory
;;
@ -236,81 +237,20 @@ 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 `yas-minor-mode' is active.
Value is a string that is converted to the internal Emacs key
representation using `read-kbd-macro'."
:type 'string
:group 'yasnippet
:set #'(lambda (symbol key)
(let ((old (and (boundp symbol)
(symbol-value symbol))))
(set-default symbol key)
;; On very first loading of this defcustom,
;; `yas-trigger-key' is *not* loaded.
(if (fboundp 'yas--trigger-key-reload)
(yas--trigger-key-reload old)))))
(defcustom yas-next-field-key '("TAB" "<tab>")
"The key to navigate to next field when a snippet is active.
Value is a string that is converted to the internal Emacs key
representation using `read-kbd-macro'.
Can also be a list of strings."
:type '(choice (string :tag "String")
(repeat :args (string) :tag "List of strings"))
:group 'yasnippet
:set #'(lambda (symbol val)
(set-default symbol val)
(if (fboundp 'yas--init-yas-in-snippet-keymap)
(yas--init-yas-in-snippet-keymap))))
(defcustom yas-prev-field-key '("<backtab>" "<S-tab>")
"The key to navigate to previous field when a snippet is active.
Value is a string that is converted to the internal Emacs key
representation using `read-kbd-macro'.
Can also be a list of strings."
:type '(choice (string :tag "String")
(repeat :args (string) :tag "List of strings"))
:group 'yasnippet
:set #'(lambda (symbol val)
(set-default symbol val)
(if (fboundp 'yas--init-yas-in-snippet-keymap)
(yas--init-yas-in-snippet-keymap))))
(defcustom yas-skip-and-clear-key '("C-d" "<delete>" "<deletechar>")
"The key to clear the currently active field.
Value is a string that is converted to the internal Emacs key
representation using `read-kbd-macro'.
Can also be a list of strings."
:type '(choice (string :tag "String")
(repeat :args (string) :tag "List of strings"))
:group 'yasnippet
:set #'(lambda (symbol val)
(set-default symbol val)
(if (fboundp 'yas--init-yas-in-snippet-keymap)
(yas--init-yas-in-snippet-keymap))))
(defcustom yas-triggers-in-field nil
"If non-nil, `yas-next-field-key' can trigger stacked expansions.
"If non-nil, allow stacked expansions (snippets inside snippets).
Otherwise, `yas-next-field-key' just tries to move on to the next
field"
Otherwise `yas-next-field-or-maybe-expand' just moves on to the
next field"
:type 'boolean
:group 'yasnippet)
(defcustom yas-fallback-behavior 'call-other-command
"How to act when `yas-trigger-key' does *not* expand a snippet.
"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 `yas-trigger-key'.
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)
@ -417,28 +357,15 @@ the trigger key itself."
:group 'yasnippet)
;;; User can also customize the next defvars
(defun yas--define-some-keys (keys keymap definition)
"Bind KEYS to DEFINITION in KEYMAP, read with `read-kbd-macro'."
(let ((keys (or (and (listp keys) keys)
(list keys))))
(dolist (key keys)
(define-key keymap (read-kbd-macro key) definition))))
(defun yas--init-yas-in-snippet-keymap ()
(setq yas-keymap
(let ((map (make-sparse-keymap)))
(mapc #'(lambda (binding)
(yas--define-some-keys (car binding) map (cdr binding)))
`((,yas-next-field-key . yas-next-field-or-maybe-expand)
(,yas-prev-field-key . yas-prev-field)
("C-g" . yas-abort-snippet)
(,yas-skip-and-clear-key . yas-skip-and-clear-or-delete-char)))
map)))
(defvar yas-keymap (yas--init-yas-in-snippet-keymap)
"The keymap active while a snippet expansion is in progress.")
(defvar yas-keymap (let ((map (make-sparse-keymap)))
(define-key map [(tab)] 'yas-next-field-or-maybe-expand)
(define-key map (kbd "TAB") 'yas-next-field-or-maybe-expand)
(define-key map [(shift tab)] 'yas-prev-field)
(define-key map [backtab] 'yas-prev-field)
(define-key map (kbd "C-g") 'yas-abort-snippet)
(define-key map (kbd "C-d") 'yas-skip-and-clear-or-delete-char)
map)
"The active keymap while a snippet expansion is in progress.")
(defvar yas-key-syntaxes (list "w" "w_" "w_." "w_.()" "^ ")
"List of character syntaxes used to find a trigger key before point.
@ -694,6 +621,8 @@ snippet itself contains a condition that returns the symbol
;; Now for the stuff that has direct keybindings
;;
(define-key map [(tab)] 'yas-expand)
(define-key map (kbd "TAB") 'yas-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)
@ -702,20 +631,6 @@ snippet itself contains a condition that returns the symbol
(defvar yas-minor-mode-map (yas--init-minor-keymap)
"The keymap used when `yas-minor-mode' is active.")
(defun yas--trigger-key-reload (&optional unbind-key)
"Rebind `yas-expand' to the new value of `yas-trigger-key'.
With optional UNBIND-KEY, try to unbind that key from
`yas-minor-mode-map'."
(when (and unbind-key
(stringp unbind-key)
(not (string= unbind-key "")))
(define-key yas-minor-mode-map (read-kbd-macro unbind-key) nil))
(when (and yas-trigger-key
(stringp yas-trigger-key)
(not (string= yas-trigger-key "")))
(define-key yas-minor-mode-map (read-kbd-macro yas-trigger-key) 'yas-expand)))
(defvar yas--tables (make-hash-table)
"A hash table of mode symbols to `yas--table' objects.")
@ -774,15 +689,14 @@ and friends."
(define-minor-mode yas-minor-mode
"Toggle YASnippet mode.
When YASnippet mode is enabled, the `yas-trigger-key' key expands
snippets of code depending on the major mode.
When YASnippet mode is enabled, `yas-expand', normally bound to
the TAB key, expands snippets of code depending on the major
mode.
With no argument, this command toggles the mode.
positive prefix argument turns on the mode.
Negative prefix argument turns off the mode.
You can customize the key through `yas-trigger-key'.
Key bindings:
\\{yas-minor-mode-map}"
nil
@ -790,9 +704,6 @@ Key bindings:
" yas"
:group 'yasnippet
(cond (yas-minor-mode
;; Reload the trigger key
;;
(yas--trigger-key-reload)
;; Install the direct keymaps in `emulation-mode-map-alists'
;; (we use `add-hook' even though it's not technically a hook,
;; but it works). Then define variables named after modes to
@ -1800,9 +1711,6 @@ loading."
;; Reload the direct keybindings
;;
(yas-direct-keymaps-reload)
;; Reload the trigger-key (shoudn't be needed, but see issue #237)
;;
(yas--trigger-key-reload)
(yas--message 3 "Reloaded everything%s...%s."
(if interactive "" " (snippets will load just-in-time)")
@ -2259,12 +2167,10 @@ expand immediately. Common gateway for
;; Apropos the trigger key and the fallback binding:
;;
;; When `yas-trigger-key' is <tab> it correctly overrides
;; org-mode's <tab>, for example and searching for fallbacks
;; correctly returns `org-cycle'. However, most other modes bind
;; "TAB" (which is translated from <tab>), and calling
;; (key-binding "TAB") does not place return that command into
;; our command-2 local. So we cheat.
;; When `yas-minor-mode-map' binds <tab>, that correctly overrides
;; org-mode's <tab>, for example and searching for fallbacks correctly
;; returns `org-cycle'. However, most other modes bind "TAB". TODO,
;; improve this explanation.
;;
(defun yas--fallback (&optional from-trigger-key-p)
"Fallback after expansion has failed.
@ -2275,15 +2181,11 @@ Common gateway for `yas-expand-from-trigger-key' and
;; return nil
nil)
((eq yas-fallback-behavior 'call-other-command)
(let* ((yas-minor-mode nil)
(yas--direct-keymaps nil)
(keys (this-single-command-keys))
(beyond-yasnippet (or (key-binding keys t)
(key-binding (yas--fallback-translate-input keys) t))))
(let* ((beyond-yasnippet (yas--keybinding-beyond-yasnippet)))
(yas--message 4 "Falling back to %s" beyond-yasnippet)
(when (commandp beyond-yasnippet)
(setq this-original-command beyond-yasnippet)
(call-interactively beyond-yasnippet))))
(assert (or (null beyond-yasnippet) (commandp beyond-yasnippet)))
(setq this-original-command beyond-yasnippet)
(call-interactively beyond-yasnippet)))
((and (listp yas-fallback-behavior)
(cdr yas-fallback-behavior)
(eq 'apply (car yas-fallback-behavior)))
@ -2297,11 +2199,19 @@ Common gateway for `yas-expand-from-trigger-key' and
;; also return nil if all the other fallbacks have failed
nil)))
(defun yas--keybinding-beyond-yasnippet ()
"Returns the "
(let* ((yas-minor-mode nil)
(yas--direct-keymaps nil)
(keys (this-single-command-keys)))
(or (key-binding keys t)
(key-binding (yas--fallback-translate-input keys) t))))
(defun yas--fallback-translate-input (keys)
"Emulate `read-key-sequence', at least what I think it does.
Keys should be an untranslated key vector. Returns a translated
vector of keys. XXX not working yet"
vector of keys. FIXME not thoroughly tested"
(let ((retval [])
(i 0))
(while (< i (length keys))
@ -4259,15 +4169,14 @@ When multiple expressions are found, only the last one counts."
"A doc synthethizer for `yas--expand-from-trigger-key-doc'."
(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-for-fallback)))))
(let* ((fallback (yas--keybinding-beyond-yasnippet)))
(or (and fallback
(format " call command `%s'." (pp-to-string fallback)))
" do nothing.")))
" do nothing (`yas-expand' doesn't shadow\nanything)")))
((eq yas-fallback-behavior 'return-nil)
", do nothing.")
(t
", defer to `yas--fallback-behaviour' :-)"))))
", defer to `yas-fallback-behaviour' (which see)"))))
(concat "Expand a snippet before point. If no snippet
expansion is possible,"
fallback-description
@ -4446,10 +4355,6 @@ handle the end-of-buffer error fired in it by calling
yas-indent-line
yas-also-auto-indent-first-line
yas-snippet-revival
yas-trigger-key
yas-next-field-key
yas-prev-field-key
yas-skip-and-clear-key
yas-triggers-in-field
yas-fallback-behavior
yas-choose-keys-first