mirror of
https://github.com/joaotavora/yasnippet.git
synced 2025-10-14 13:33:04 +00:00
* stacked expansion is tricky, but can be done
* yas/minor-mode should be needed to expand snippets, this means hooks last while snippets last * will probably *not* fix this bug: ${1:nested{2:thing}} when "thing" is changed "nested"'s end marker doens't move
This commit is contained in:
parent
354580b8f7
commit
b56563de60
101
yasnippet.el
101
yasnippet.el
@ -72,10 +72,8 @@ current column if this variable is non-`nil'.")
|
|||||||
(defvar yas/keymap (make-sparse-keymap)
|
(defvar yas/keymap (make-sparse-keymap)
|
||||||
"The keymap of snippet.")
|
"The keymap of snippet.")
|
||||||
(define-key yas/keymap yas/next-field-key 'yas/next-field)
|
(define-key yas/keymap yas/next-field-key 'yas/next-field)
|
||||||
(define-key yas/keymap yas/clear-field-key 'yas/clear-field)
|
(define-key yas/keymap yas/clear-field-key 'yas/clear-field-or-delete-char)
|
||||||
(define-key yas/keymap (kbd "S-TAB") 'yas/prev-field)
|
(define-key yas/keymap (kbd "S-TAB") 'yas/prev-field)
|
||||||
(define-key yas/keymap (kbd "<DEL>") 'yas/prev-field)
|
|
||||||
(define-key yas/keymap (kbd "DEL") 'yas/prev-field)
|
|
||||||
(define-key yas/keymap (kbd "<deletechar>") 'yas/prev-field)
|
(define-key yas/keymap (kbd "<deletechar>") 'yas/prev-field)
|
||||||
(define-key yas/keymap (kbd "<S-iso-lefttab>") 'yas/prev-field)
|
(define-key yas/keymap (kbd "<S-iso-lefttab>") 'yas/prev-field)
|
||||||
(define-key yas/keymap (kbd "<S-tab>") 'yas/prev-field)
|
(define-key yas/keymap (kbd "<S-tab>") 'yas/prev-field)
|
||||||
@ -526,33 +524,47 @@ the template of a snippet in the current snippet-table."
|
|||||||
end
|
end
|
||||||
nil
|
nil
|
||||||
t
|
t
|
||||||
nil)))
|
t)))
|
||||||
(overlay-put overlay 'keymap yas/keymap)
|
(overlay-put overlay 'keymap yas/keymap)
|
||||||
(overlay-put overlay 'yas/snippet snippet)
|
(overlay-put overlay 'yas/snippet snippet)
|
||||||
(overlay-put overlay 'evaporate t)
|
(overlay-put overlay 'evaporate t)
|
||||||
overlay))
|
overlay))
|
||||||
|
|
||||||
(defun yas/clear-field (&optional field)
|
(defun yas/clear-field-or-delete-char (&optional field)
|
||||||
(interactive)
|
(interactive)
|
||||||
(let ((field (or field
|
(let ((field (or field
|
||||||
(and yas/active-field-overlay
|
(and yas/active-field-overlay
|
||||||
(overlay-buffer yas/active-field-overlay)
|
(overlay-buffer yas/active-field-overlay)
|
||||||
(overlay-get yas/active-field-overlay 'yas/field)))))
|
(overlay-get yas/active-field-overlay 'yas/field)))))
|
||||||
(let ((inhibit-modification-hooks t))
|
(cond ((and field
|
||||||
(delete-region (yas/field-start field) (yas/field-end field)))))
|
(not (yas/field-modified-p field)))
|
||||||
|
(yas/clear-field field))
|
||||||
|
(t
|
||||||
|
(call-interactively 'delete-char)))))
|
||||||
|
|
||||||
|
(defun yas/clear-field (field)
|
||||||
|
(setf (yas/field-modified-p field) t)
|
||||||
|
(delete-region (yas/field-start field) (yas/field-end field)))
|
||||||
|
|
||||||
(defun yas/on-field-overlay-modification (overlay after? beg end &optional length)
|
(defun yas/on-field-overlay-modification (overlay after? beg end &optional length)
|
||||||
"To be written"
|
"Clears the field and updates mirrors, conditionally.
|
||||||
(cond ((and after?
|
|
||||||
(not (yas/undo-in-progress)))
|
Only clears the field if it hasn't been modified and it point it
|
||||||
|
at field start. This hook doesn't do anything if an undo is in
|
||||||
|
progress."
|
||||||
|
(unless (yas/undo-in-progress)
|
||||||
|
(cond (after?
|
||||||
(mapcar #'yas/update-mirrors (yas/snippets-at-point)))
|
(mapcar #'yas/update-mirrors (yas/snippets-at-point)))
|
||||||
(t
|
(t
|
||||||
(let ((field (overlay-get yas/active-field-overlay 'yas/field)))
|
(let ((field (overlay-get yas/active-field-overlay 'yas/field)))
|
||||||
(when (and field
|
(when (and field
|
||||||
(not (or after? (yas/undo-in-progress)))
|
(not after?)
|
||||||
(not (yas/field-modified-p field)))
|
(not (yas/field-modified-p field))
|
||||||
(setf (yas/field-modified-p field) t)
|
(eq (point) (if (markerp (yas/field-start field))
|
||||||
(yas/clear-field field))))))
|
(marker-position (yas/field-start field))
|
||||||
|
(yas/field-start field))))
|
||||||
|
(yas/clear-field field))
|
||||||
|
(setf (yas/field-modified-p field) t))))))
|
||||||
|
|
||||||
(defun yas/on-protection-overlay-modification (overlay after? beg end &optional length)
|
(defun yas/on-protection-overlay-modification (overlay after? beg end &optional length)
|
||||||
"To be written"
|
"To be written"
|
||||||
@ -573,6 +585,7 @@ will be deleted before inserting template."
|
|||||||
(let* ((key (buffer-substring-no-properties start end))
|
(let* ((key (buffer-substring-no-properties start end))
|
||||||
(length (- end start))
|
(length (- end start))
|
||||||
(column (current-column))
|
(column (current-column))
|
||||||
|
(inhibit-modification-hooks t)
|
||||||
snippet)
|
snippet)
|
||||||
(delete-char length)
|
(delete-char length)
|
||||||
(save-restriction
|
(save-restriction
|
||||||
@ -583,22 +596,21 @@ will be deleted before inserting template."
|
|||||||
(push (cons (point-min) (point-max)) buffer-undo-list)
|
(push (cons (point-min) (point-max)) buffer-undo-list)
|
||||||
;; Push an undo action
|
;; Push an undo action
|
||||||
(push `(apply yas/take-care-of-redo ,(point-min) ,(point-max) ,snippet)
|
(push `(apply yas/take-care-of-redo ,(point-min) ,(point-max) ,snippet)
|
||||||
buffer-undo-list))))
|
buffer-undo-list))
|
||||||
|
|
||||||
|
|
||||||
|
;; if this is a stacked expansion update the other snippets at point
|
||||||
|
(mapcar #'yas/update-mirrors (rest (yas/snippets-at-point)))))
|
||||||
|
|
||||||
(defun yas/take-care-of-redo (beg end snippet)
|
(defun yas/take-care-of-redo (beg end snippet)
|
||||||
(let ((inhibit-modification-hooks t))
|
(yas/commit-snippet snippet))
|
||||||
(when yas/active-field-overlay
|
|
||||||
(delete-overlay yas/active-field-overlay))
|
|
||||||
(when yas/field-protection-overlays
|
|
||||||
(mapcar #'delete-overlay yas/field-protection-overlays)))
|
|
||||||
(push `(apply yas/snippet-revive ,beg ,end ,snippet)
|
|
||||||
buffer-undo-list))
|
|
||||||
|
|
||||||
(defun yas/snippet-revive (beg end snippet)
|
(defun yas/snippet-revive (beg end snippet)
|
||||||
(setf (yas/snippet-control-overlay snippet) (yas/make-control-overlay beg end))
|
(setf (yas/snippet-control-overlay snippet) (yas/make-control-overlay beg end))
|
||||||
(overlay-put (yas/snippet-control-overlay snippet) 'yas/snippet snippet)
|
(overlay-put (yas/snippet-control-overlay snippet) 'yas/snippet snippet)
|
||||||
(yas/move-to-field snippet (or (yas/snippet-active-field snippet)
|
(yas/move-to-field snippet (or (yas/snippet-active-field snippet)
|
||||||
(car (yas/snippet-fields snippet))))
|
(car (yas/snippet-fields snippet))))
|
||||||
|
(yas/points-to-markers snippet)
|
||||||
(push `(apply yas/take-care-of-redo ,beg ,end ,snippet)
|
(push `(apply yas/take-care-of-redo ,beg ,end ,snippet)
|
||||||
buffer-undo-list))
|
buffer-undo-list))
|
||||||
|
|
||||||
@ -1098,10 +1110,12 @@ when the condition evaluated to non-nil."
|
|||||||
(yas/field-parent-field field)))
|
(yas/field-parent-field field)))
|
||||||
|
|
||||||
(defun yas/snippets-at-point ()
|
(defun yas/snippets-at-point ()
|
||||||
|
(sort
|
||||||
(remove nil (mapcar #'(lambda (ov)
|
(remove nil (mapcar #'(lambda (ov)
|
||||||
(overlay-get ov 'yas/snippet))
|
(overlay-get ov 'yas/snippet))
|
||||||
(overlays-at (point)))))
|
(overlays-at (point))))
|
||||||
|
#'(lambda (s1 s2)
|
||||||
|
(>= (yas/snippet-id s2) (yas/snippet-id s1)))))
|
||||||
|
|
||||||
(defun yas/next-field (&optional arg)
|
(defun yas/next-field (&optional arg)
|
||||||
"Navigate to next field. If there's none, exit the snippet."
|
"Navigate to next field. If there's none, exit the snippet."
|
||||||
@ -1187,7 +1201,39 @@ up the snippet does not delete it!"
|
|||||||
(defun yas/delete-overlay-region (overlay)
|
(defun yas/delete-overlay-region (overlay)
|
||||||
(delete-region (overlay-start overlay) (overlay-end overlay)))
|
(delete-region (overlay-start overlay) (overlay-end overlay)))
|
||||||
|
|
||||||
(defun yas/commit-snippet (snippet)
|
(defun yas/markers-to-points (snippet)
|
||||||
|
"Convert all markers in SNIPPET to simple integer buffer positions."
|
||||||
|
(dolist (field (yas/snippet-fields snippet))
|
||||||
|
(let ((start (marker-position (yas/field-start field)))
|
||||||
|
(end (marker-position (yas/field-end field))))
|
||||||
|
(set-marker (yas/field-start field) nil)
|
||||||
|
(set-marker (yas/field-end field) nil)
|
||||||
|
(setf (yas/field-start field) start)
|
||||||
|
(setf (yas/field-end field) end))
|
||||||
|
(dolist (mirror (yas/field-mirrors field))
|
||||||
|
(let ((start (marker-position (yas/mirror-start mirror)))
|
||||||
|
(end (marker-position (yas/mirror-end mirror))))
|
||||||
|
(set-marker (yas/mirror-start mirror) nil)
|
||||||
|
(set-marker (yas/mirror-end mirror) nil)
|
||||||
|
(setf (yas/mirror-start mirror) start)
|
||||||
|
(setf (yas/mirror-end mirror) end))))
|
||||||
|
(when (yas/snippet-exit snippet)
|
||||||
|
(let ((exit (marker-position (yas/snippet-exit snippet))))
|
||||||
|
(set-marker (yas/snippet-exit snippet) nil)
|
||||||
|
(setf (yas/snippet-exit snippet) exit))))
|
||||||
|
|
||||||
|
(defun yas/points-to-markers (snippet)
|
||||||
|
"Convert all simple integer buffer positions in SNIPPET to markers"
|
||||||
|
(dolist (field (yas/snippet-fields snippet))
|
||||||
|
(setf (yas/field-start field) (set-marker (make-marker) (yas/field-start field)))
|
||||||
|
(setf (yas/field-end field) (set-marker (make-marker) (yas/field-end field)))
|
||||||
|
(dolist (mirror (yas/field-mirrors field))
|
||||||
|
(setf (yas/mirror-start mirror) (set-marker (make-marker) (yas/mirror-start mirror)))
|
||||||
|
(setf (yas/mirror-end mirror) (set-marker (make-marker) (yas/mirror-end mirror)))))
|
||||||
|
(when (yas/snippet-exit snippet)
|
||||||
|
(setf (yas/snippet-exit snippet) (set-marker (make-marker) (yas/snippet-exit snippet)))))
|
||||||
|
|
||||||
|
(defun yas/commit-snippet (snippet &optional no-hooks)
|
||||||
"Commit SNIPPET, but leave point as it is. This renders the
|
"Commit SNIPPET, but leave point as it is. This renders the
|
||||||
snippet as ordinary text.
|
snippet as ordinary text.
|
||||||
|
|
||||||
@ -1212,6 +1258,8 @@ exiting the snippet."
|
|||||||
(when yas/field-protection-overlays
|
(when yas/field-protection-overlays
|
||||||
(mapcar #'delete-overlay yas/field-protection-overlays)))
|
(mapcar #'delete-overlay yas/field-protection-overlays)))
|
||||||
|
|
||||||
|
(yas/markers-to-points snippet)
|
||||||
|
|
||||||
;; Push an action for snippet revival
|
;; Push an action for snippet revival
|
||||||
;;
|
;;
|
||||||
(push `(apply yas/snippet-revive ,yas/snippet-beg ,yas/snippet-end ,snippet)
|
(push `(apply yas/snippet-revive ,yas/snippet-beg ,yas/snippet-end ,snippet)
|
||||||
@ -1223,7 +1271,7 @@ exiting the snippet."
|
|||||||
;; disappeared, which sometimes happens when the snippet's messed
|
;; disappeared, which sometimes happens when the snippet's messed
|
||||||
;; up...
|
;; up...
|
||||||
;;
|
;;
|
||||||
(run-hooks 'yas/after-exit-snippet-hook)))
|
(unless no-hooks (run-hooks 'yas/after-exit-snippet-hook))))
|
||||||
|
|
||||||
(defun yas/check-commit-snippet ()
|
(defun yas/check-commit-snippet ()
|
||||||
"Checks if point exited the currently active field of the
|
"Checks if point exited the currently active field of the
|
||||||
@ -1303,6 +1351,7 @@ snippet, if so cleans up the whole snippet up."
|
|||||||
(erase-buffer)
|
(erase-buffer)
|
||||||
(setq buffer-undo-list nil)
|
(setq buffer-undo-list nil)
|
||||||
(html-mode)
|
(html-mode)
|
||||||
|
(yas/minor-mode)
|
||||||
(let ((abbrev))
|
(let ((abbrev))
|
||||||
;; (if (require 'ido nil t)
|
;; (if (require 'ido nil t)
|
||||||
;; (setq abbrev (ido-completing-read "Snippet abbrev: " '("crazy" "prip" "prop")))
|
;; (setq abbrev (ido-completing-read "Snippet abbrev: " '("crazy" "prip" "prop")))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user