mirror of
https://github.com/joaotavora/yasnippet.git
synced 2025-10-13 13:13:03 +00:00
* Much closer to getting this all working, undo, redo and nested
stuff. Works most of the time but: 1. Consider getting rid of the `deleted' state of a group and using some other criteria to discover if user can move to a group. `deleted' is only for subgroups anyway, i think. 2. Consider adding information about restoring boundaries in the yas/group itself. This way, a) upon `yas/snippet-cleanup', start and end marker could simply be set to nil and deleted. b) `yas/undo-restore-active-group' could recurse down subgroups restoring them as well. (maybe without specifically moving to them, but OK. 3. Don't forget to correct `yas/update-mirrors' to correctly use the transformations in the mirror fields.
This commit is contained in:
parent
d9cb83dc93
commit
5a3b161219
124
yasnippet.el
124
yasnippet.el
@ -298,7 +298,7 @@ set to t."
|
||||
(id (yas/snippet-next-id) :read-only t)
|
||||
(control-overlay nil)
|
||||
(active-field-overlay nil)
|
||||
undo-saved-boundaries
|
||||
undo-saved-info
|
||||
(active-group nil)
|
||||
(end-marker nil))
|
||||
|
||||
@ -529,7 +529,7 @@ the template of a snippet in the current snippet-table."
|
||||
start
|
||||
end)))
|
||||
|
||||
(defun yas/synchronize-fields (field-group &optional dont-recurse-down)
|
||||
(defun yas/update-mirrors (field-group &optional dont-recurse-down)
|
||||
"Update all mirror fields' text according to the primary field."
|
||||
(when (yas/snippet-valid? (yas/group-snippet field-group))
|
||||
(save-excursion
|
||||
@ -544,37 +544,36 @@ the template of a snippet in the current snippet-table."
|
||||
;; Call recursively for subfields
|
||||
(unless dont-recurse-down
|
||||
(dolist (subfield (yas/field-subfields primary))
|
||||
(yas/synchronize-fields (yas/field-group subfield))))
|
||||
(yas/update-mirrors (yas/field-group subfield))))
|
||||
;; Call recursively for parent field
|
||||
(when (yas/field-parent-field primary)
|
||||
(yas/synchronize-fields (yas/field-group (yas/field-parent-field primary))
|
||||
(yas/update-mirrors (yas/field-group (yas/field-parent-field primary))
|
||||
'dont-recurse))))))
|
||||
|
||||
(defun yas/current-field-text (field)
|
||||
(buffer-substring-no-properties (yas/field-start field)
|
||||
(yas/field-end field)))
|
||||
|
||||
(defun yas/current-active-group (&optional snippet point)
|
||||
"..."
|
||||
(let ((snippet (or snippet
|
||||
(yas/snippet-of-current-keymap (or point
|
||||
(point))))))
|
||||
(and snippet
|
||||
(yas/snippet-active-group snippet))))
|
||||
|
||||
(defun yas/overlay-modification-hook (overlay after? beg end &optional length)
|
||||
"Synchronizes all fields for the group of the current field overlay
|
||||
|
||||
Used to ensure mirror fields in the same group contain the same value
|
||||
of the primary field."
|
||||
(message (format "Running mod hook for %s of %s."
|
||||
(cond ((overlay-get overlay 'yas/snippet-reference)
|
||||
(format "big overlay of snippet %s," (yas/snippet-id (overlay-get overlay 'yas/snippet-reference))))
|
||||
((overlay-get overlay 'yas/group)
|
||||
(format "field overlay of group $%s," (yas/group-number (overlay-get overlay 'yas/group))))
|
||||
(t
|
||||
"STH UNKNOWN"))
|
||||
overlay))
|
||||
(when after?
|
||||
;; (and after? (not undo-in-progress))
|
||||
(yas/synchronize-fields (overlay-get overlay 'yas/group))))
|
||||
(yas/update-mirrors (yas/current-active-group))))
|
||||
|
||||
(defun yas/overlay-insert-in-front-hook (overlay after? beg end &optional length)
|
||||
"Hook for snippet overlay when text is inserted in front of a snippet field."
|
||||
(let ((group (overlay-get overlay 'yas/group)))
|
||||
(let ((group (yas/current-active-group)))
|
||||
(when (and after?
|
||||
group)
|
||||
(let ((inhibit-modification-hooks t))
|
||||
@ -590,13 +589,15 @@ of the primary field."
|
||||
(delete-char (- (overlay-end overlay) end))))
|
||||
;;
|
||||
;; Mark subgroups as `yas/group-deleted', so we're no longer
|
||||
;; able to move them. XXX:UNDO:TODO: This action has to be undoable!
|
||||
;; able to move them. This action is undoable as long as
|
||||
;; `yas/undo-before-hook' exists in the `pre-command-hook'
|
||||
;; in the proper place.
|
||||
;;
|
||||
(mapcar #'(lambda (group)
|
||||
(setf (yas/group-deleted group) t))
|
||||
(mapcar #'yas/field-group (yas/field-subfields (yas/group-primary-field group)))))
|
||||
;; in any case, synchronize mirror fields
|
||||
(yas/synchronize-fields group)))))
|
||||
(yas/update-mirrors group)))))
|
||||
|
||||
(defun yas/move-overlay-and-field (overlay field start end)
|
||||
(move-overlay overlay
|
||||
@ -607,13 +608,13 @@ of the primary field."
|
||||
|
||||
(defun yas/overlay-insert-behind-hook (overlay after? beg end &optional length)
|
||||
"Hook for snippet overlay when text is inserted just behind the currently active field overlay."
|
||||
(let* ((group (overlay-get overlay 'yas/group))
|
||||
(let* ((group (yas/current-active-group))
|
||||
(field (and group
|
||||
(yas/group-primary-field group))))
|
||||
(when (and after?
|
||||
field)
|
||||
(yas/move-overlay-and-field overlay field (overlay-start overlay) end)
|
||||
(yas/synchronize-fields group))))
|
||||
(yas/update-mirrors group))))
|
||||
|
||||
(defun yas/remove-recent-undo-from-history ()
|
||||
(let ((undo (car buffer-undo-list)))
|
||||
@ -1320,6 +1321,7 @@ when the condition evaluated to non-nil."
|
||||
(overlay (yas/snippet-active-field-overlay snippet)))
|
||||
(goto-char (yas/field-start field))
|
||||
(setf (yas/snippet-active-group snippet) group)
|
||||
(setf (yas/group-deleted group) nil)
|
||||
(cond ((and overlay
|
||||
(overlay-buffer overlay))
|
||||
(move-overlay overlay (yas/field-start field)
|
||||
@ -1330,9 +1332,7 @@ when the condition evaluated to non-nil."
|
||||
(overlay-put overlay 'insert-in-front-hooks yas/overlay-insert-in-front-hooks)
|
||||
(overlay-put overlay 'insert-behind-hooks yas/overlay-insert-behind-hooks)
|
||||
(overlay-put overlay 'face 'yas/field-highlight-face)
|
||||
(setf (yas/snippet-active-field-overlay snippet) overlay)))
|
||||
(overlay-put overlay 'yas/group group)
|
||||
(overlay-put overlay 'yas/field field)))
|
||||
(setf (yas/snippet-active-field-overlay snippet) overlay)))))
|
||||
|
||||
|
||||
(defun yas/prev-field-group ()
|
||||
@ -1383,8 +1383,8 @@ up the snippet does not delete it!"
|
||||
registered snippet exists in the current buffer. Return snippet"
|
||||
(puthash (yas/snippet-id snippet) snippet yas/registered-snippets)
|
||||
(add-hook 'pre-command-hook 'yas/undo-before-hook 'append 'local)
|
||||
(add-hook 'post-command-hook 'yas/check-cleanup-snippet 'append 'local)
|
||||
(add-hook 'post-command-hook 'yas/undo-after-hook 'append 'local)
|
||||
(add-hook 'post-command-hook 'yas/check-cleanup-snippet 'append 'local)
|
||||
;; DEBUG
|
||||
(add-hook 'post-command-hook 'yas/debug-some-vars 'append 'local)
|
||||
snippet)
|
||||
@ -1401,9 +1401,7 @@ current buffer."
|
||||
(remove-hook 'post-command-hook 'yas/undo-after-hook 'local)
|
||||
(remove-hook 'post-command-hook 'yas/check-cleanup-snippet 'local)
|
||||
;; DEBUG
|
||||
(remove-hook 'post-command-hook 'yas/debug-some-vars ' 'local)
|
||||
|
||||
))
|
||||
(remove-hook 'post-command-hook 'yas/debug-some-vars 'local)))
|
||||
|
||||
(defun yas/exterminate-snippets ()
|
||||
"Remove all locally registered snippets and remove
|
||||
@ -1471,18 +1469,18 @@ snippet, if so cleans up the whole snippet up.
|
||||
This function is part of `post-command-hook' while
|
||||
registered snippets last."
|
||||
(let* ((snippet (yas/snippet-of-current-keymap))
|
||||
(field-overlay (and snippet
|
||||
(yas/snippet-active-field-overlay snippet))))
|
||||
(cond ( ;;
|
||||
(group (and snippet
|
||||
(yas/snippet-active-group snippet))))
|
||||
(cond (;;
|
||||
;; No snippet at point, cleanup *all* snippets
|
||||
;;
|
||||
(null snippet)
|
||||
(yas/exterminate-snippets))
|
||||
( ;; A snippet exits at point, but point left the currently
|
||||
(;; A snippet exits at point, but point left the currently
|
||||
;; active field overlay
|
||||
(and field-overlay
|
||||
(or (> (point) (overlay-end field-overlay))
|
||||
(< (point) (overlay-start field-overlay))))
|
||||
(or (not group)
|
||||
(and group
|
||||
(not (yas/point-in-field-p (yas/group-primary-field group)))))
|
||||
(yas/cleanup-snippet snippet))
|
||||
(;;
|
||||
;; Snippet at point, and point inside a snippet field,
|
||||
@ -1504,35 +1502,44 @@ registered snippets last."
|
||||
(yas/snippet-active-field-overlay snippet))))
|
||||
(when (and field-overlay
|
||||
(overlay-buffer field-overlay))
|
||||
(setf (yas/snippet-undo-saved-boundaries snippet)
|
||||
(setf (yas/snippet-undo-saved-info snippet)
|
||||
(list
|
||||
;;
|
||||
;; Save boundaries of current field
|
||||
;;
|
||||
(cons (overlay-start field-overlay)
|
||||
(overlay-end field-overlay))))))
|
||||
(overlay-end field-overlay))
|
||||
;;
|
||||
;; Save a reference to current group
|
||||
;;
|
||||
(yas/snippet-active-group snippet))))))
|
||||
|
||||
(defun yas/undo-after-hook ()
|
||||
"..."
|
||||
(let* ((snippet (yas/snippet-of-current-keymap))
|
||||
(saved-boundaries (and snippet
|
||||
(yas/snippet-undo-saved-boundaries snippet))))
|
||||
(unless (null snippet)
|
||||
(yas/push-undo-action-maybe (list 'yas/undo-restore-active-group nil)))
|
||||
(unless (null saved-boundaries)
|
||||
(yas/push-undo-action-maybe (list 'yas/undo-restore-boundaries
|
||||
(car saved-boundaries)
|
||||
(cdr saved-boundaries))))))
|
||||
(saved-info (and snippet
|
||||
(yas/snippet-undo-saved-info snippet))))
|
||||
(unless (null saved-info)
|
||||
(yas/push-undo-action-maybe (list 'yas/undo-restore-active-group
|
||||
(second saved-info)
|
||||
(car (first saved-info))
|
||||
(cdr (first saved-info)))))))
|
||||
|
||||
|
||||
|
||||
(defun yas/undo-restore-active-group (&optional point)
|
||||
(defun yas/undo-restore-active-group (group start end)
|
||||
"..."
|
||||
(let* ((point (or point
|
||||
(point)))
|
||||
(snippet (yas/snippet-of-current-keymap point)))
|
||||
(message "Would restoring group point %s and %s"
|
||||
point
|
||||
(if snippet
|
||||
(format "snippet id %d" (yas/snippet-id snippet))
|
||||
"NO SNIPPET!!!"))))
|
||||
(let* ((snippet (yas/snippet-of-current-keymap))
|
||||
(field-overlay (yas/snippet-active-field-overlay snippet))
|
||||
(field (yas/group-primary-field group)))
|
||||
(yas/move-to-group snippet group)
|
||||
(yas/move-overlay-and-field field-overlay field start end)
|
||||
(yas/update-mirrors group)))
|
||||
|
||||
(defun yas/point-in-field-p (field &optional point)
|
||||
"..."
|
||||
(let ((point (or point
|
||||
(point))))
|
||||
(and (>= point (yas/field-start field))
|
||||
(<= point (yas/field-end field)))))
|
||||
|
||||
(defun yas/push-undo-action-maybe (apply-args)
|
||||
"..."
|
||||
@ -1570,17 +1577,6 @@ registered snippets last."
|
||||
target-separator))))))
|
||||
|
||||
|
||||
(defun yas/undo-restore-boundaries (start end)
|
||||
"..."
|
||||
(let* ((snippet (yas/snippet-of-current-keymap))
|
||||
(field-overlay (and snippet
|
||||
(yas/snippet-active-field-overlay snippet)))
|
||||
(group (and snippet
|
||||
(yas/snippet-active-group snippet)))
|
||||
(field (and group
|
||||
(yas/group-primary-field group))))
|
||||
(yas/move-overlay-and-field field-overlay field start end)))
|
||||
|
||||
;; Debug functions. Use (or change) at will whenever needed.
|
||||
|
||||
(defun yas/debug-some-vars ()
|
||||
|
Loading…
x
Reference in New Issue
Block a user