branch: master commit ba73f20bc305570391a151fa353188803b01f855 Author: Noam Postavsky <npost...@users.sourceforge.net> Commit: Noam Postavsky <npost...@users.sourceforge.net>
Bind field skip and clear command conditionally Rather than embedding the conditionality inside the function body, and hardcoding fallback to `delete-char'. This allows users who want, for example, to use backspace for field skipping to simply do (define-key yas-minor-mode-map (kbd "DEL") yas-maybe-skip-and-clear-field) * yasnippet.el (yas-skip-and-clear-field, yas-current-field) (yas--maybe-clear-field-filter): New command and function, extracted from yas-skip-and-clear-or-delete-char. (yas-skip-and-clear-or-delete-char): Mark obsolete. (yas-maybe-skip-and-clear-field): New constant, for conditional binding. (yas-keymap): Bind it to `C-d' instead of `yas-skip-and-clear-or-delete-char'. * yasnippet-tests.el (delete-numberless-inner-snippet-issue-562): Use `yas-skip-and-clear-field' instead of `yas-skip-and-clear-or-delete-char'. --- yasnippet-tests.el | 2 +- yasnippet.el | 47 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/yasnippet-tests.el b/yasnippet-tests.el index 5751a06..c82d1b0 100644 --- a/yasnippet-tests.el +++ b/yasnippet-tests.el @@ -274,7 +274,7 @@ attention to case differences." (ert-simulate-command '(yas-next-field-or-maybe-expand)) (should (looking-at "testblable")) (ert-simulate-command '(yas-next-field-or-maybe-expand)) - (ert-simulate-command '(yas-skip-and-clear-or-delete-char)) + (ert-simulate-command '(yas-skip-and-clear-field)) (should (looking-at "ble")) (should (null (yas-active-snippets))))) diff --git a/yasnippet.el b/yasnippet.el index 7c8905a..94d8632 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -396,13 +396,21 @@ It must be set to nil before loading yasnippet to take effect." ;;; User-visible variables +(defconst yas-maybe-skip-and-clear-field + '(menu-item "" yas-skip-and-clear-field + :filter yas--maybe-clear-field-filter) + "A conditional key definition. +This can be used as a key definition in keymaps to bind a key to +`yas-skip-and-clear-field' only when at the beginning of an +unmodified snippey field.") + (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) + (define-key map (kbd "C-d") yas-maybe-skip-and-clear-field) map) "The active keymap while a snippet expansion is in progress.") @@ -3547,22 +3555,37 @@ holds the keymap." (overlay-put overlay 'yas--snippet snippet) overlay)) +(defun yas-current-field () + "Return the currently active field." + (and yas--active-field-overlay + (overlay-buffer yas--active-field-overlay) + (overlay-get yas--active-field-overlay 'yas--field))) + +(defun yas--maybe-clear-field-filter (cmd) + "Return CMD if at start of unmodified snippet field. +Use as a `:filter' argument for a conditional keybinding." + (let ((field (yas-current-field))) + (when (and field + (not (yas--field-modified-p field)) + (eq (point) (marker-position (yas--field-start field)))) + cmd))) + +(defun yas-skip-and-clear-field (&optional field) + "Clears unmodified FIELD if at field start, skips to next tab." + (interactive) + (yas--skip-and-clear (or field (yas-current-field))) + (yas-next-field 1)) + (defun yas-skip-and-clear-or-delete-char (&optional field) "Clears unmodified field if at field start, skips to next tab. Otherwise deletes a character normally by calling `delete-char'." (interactive) - (let ((field (or field - (and yas--active-field-overlay - (overlay-buffer yas--active-field-overlay) - (overlay-get yas--active-field-overlay 'yas--field))))) - (cond ((and field - (not (yas--field-modified-p field)) - (eq (point) (marker-position (yas--field-start field)))) - (yas--skip-and-clear field) - (yas-next-field 1)) - (t - (call-interactively 'delete-char))))) + (declare (obsolete "Bind to `yas-maybe-skip-and-clear-field' instead." "0.13")) + (cond ((yas--maybe-clear-field-filter t) + (yas--skip-and-clear (or field (yas-current-field))) + (yas-next-field 1)) + (t (call-interactively 'delete-char)))) (defun yas--skip-and-clear (field &optional from) "Deletes the region of FIELD and sets it's modified state to t.