Slightly improve on fix for #515: Refactor code and add tests

While I agree with the solution for #515 in commit 17fe790 for now,
other approaches might be interesting in the future, like clearing on
other types of insertion, not just self-insertion.

So add some tests and refactor a new function that could be used for
that purpose later on. For now, change no behaviour.

* yasnippet-tests.el (dont-clear-on-partial-deletion-issue-515,
  dont-clear-on-yank-issue-515): New tests. (yas-mock-yank): New
  function.

* yasnippet.el (yas--skip-and-clear-field-p): New function.
  (yas--on-field-overlay-modification): Use it.
This commit is contained in:
João Távora 2016-01-04 10:15:31 +00:00
parent a2c5292724
commit 8b8f12fc84
2 changed files with 51 additions and 4 deletions

View File

@ -142,6 +142,39 @@
;; (should (string= (yas--buffer-contents) ;; (should (string= (yas--buffer-contents)
;; "brother from another mother!")))) ;; "brother from another mother!"))))
(ert-deftest dont-clear-on-partial-deletion-issue-515 ()
"Ensure fields are not cleared when user doesn't really mean to."
(with-temp-buffer
(yas-minor-mode 1)
(yas-expand-snippet "my ${1:kid brother} from another ${2:mother}")
(ert-simulate-command '(kill-word 1))
(ert-simulate-command '(delete-char 1))
(should (string= (yas--buffer-contents)
"my brother from another mother"))
(should (looking-at "brother"))
(ert-simulate-command '(yas-next-field))
(should (looking-at "mother"))
(ert-simulate-command '(yas-prev-field))
(should (looking-at "brother"))))
(ert-deftest dont-clear-on-yank-issue-515 ()
"A yank shouldn't clear and unmodified field." ; or should it? -- jt
(with-temp-buffer
(yas-minor-mode 1)
(yas-expand-snippet "my ${1:kid brother} from another ${2:mother}")
(yas-mock-yank "little")
(yas-mock-insert " ")
(should (string= (yas--buffer-contents)
"my little kid brother from another mother"))
(ert-simulate-command '(yas-next-field))
(ert-simulate-command '(yas-prev-field))
(should (looking-at "little kid brother"))))
;;; Snippet expansion and character escaping ;;; Snippet expansion and character escaping
;;; Thanks to @zw963 (Billy) for the testing ;;; Thanks to @zw963 (Billy) for the testing
@ -814,6 +847,10 @@ add the snippets associated with the given mode."
(let ((last-command-event (aref string i))) (let ((last-command-event (aref string i)))
(ert-simulate-command '(self-insert-command 1))))) (ert-simulate-command '(self-insert-command 1)))))
(defun yas-mock-yank (string)
(let ((interprogram-paste-function (lambda () string)))
(ert-simulate-command '(yank nil))))
(defun yas-make-file-or-dirs (ass) (defun yas-make-file-or-dirs (ass)
(let ((file-or-dir-name (car ass)) (let ((file-or-dir-name (car ass))
(content (cdr ass))) (content (cdr ass)))

View File

@ -3383,7 +3383,16 @@ Move the overlay, or create it if it does not exit."
(overlay-put yas--active-field-overlay 'insert-behind-hooks (overlay-put yas--active-field-overlay 'insert-behind-hooks
'(yas--on-field-overlay-modification)))) '(yas--on-field-overlay-modification))))
(defun yas--on-field-overlay-modification (overlay after? _beg _end &optional _length) (defun yas--skip-and-clear-field-p (field _beg _end &optional _length)
"Tell if newly modified FIELD should be cleared and skipped.
BEG, END and LENGTH like overlay modification hooks."
;; for now, ignore `beg', `end' and `length'.
;;
(and (eq this-command 'self-insert-command)
(not (yas--field-modified-p field))
(= (point) (yas--field-start field))))
(defun yas--on-field-overlay-modification (overlay after? beg end &optional length)
"Clears the field and updates mirrors, conditionally. "Clears the field and updates mirrors, conditionally.
Only clears the field if it hasn't been modified and point is at Only clears the field if it hasn't been modified and point is at
@ -3399,9 +3408,10 @@ field start. This hook does nothing if an undo is in progress."
(yas--field-update-display field)) (yas--field-update-display field))
(yas--update-mirrors snippet)) (yas--update-mirrors snippet))
(field (field
(when (and (eq this-command 'self-insert-command) ;; perhaps we should call `yas--skip-and-clear-field-p'
(not (yas--field-modified-p field)) ;; after the modificaiton takes place
(= (point) (yas--field-start field))) ;;
(when (yas--skip-and-clear-field-p field beg end)
(yas--skip-and-clear field)) (yas--skip-and-clear field))
(setf (yas--field-modified-p field) t)))))) (setf (yas--field-modified-p field) t))))))