mirror of
https://github.com/joaotavora/yasnippet.git
synced 2025-10-13 13:13:03 +00:00
support tabstops
This commit is contained in:
parent
fb5bc52bb6
commit
4570f1bac2
96
yasnippet.el
96
yasnippet.el
@ -84,15 +84,16 @@ current column if this variable is non-`nil'.")
|
|||||||
(defstruct (yas/snippet (:constructor yas/make-snippet ()))
|
(defstruct (yas/snippet (:constructor yas/make-snippet ()))
|
||||||
"A snippet."
|
"A snippet."
|
||||||
(groups nil)
|
(groups nil)
|
||||||
|
(tabstops nil) ; tabstops are those groups whose init value is empty
|
||||||
(exit-marker nil)
|
(exit-marker nil)
|
||||||
(id (yas/snippet-next-id) :read-only t))
|
(id (yas/snippet-next-id) :read-only t)
|
||||||
|
(overlay nil))
|
||||||
(defstruct (yas/group (:constructor yas/make-group (primary-field snippet)))
|
(defstruct (yas/group (:constructor yas/make-group (primary-field snippet)))
|
||||||
"A group contains a list of field with the same number."
|
"A group contains a list of field with the same number."
|
||||||
primary-field
|
primary-field
|
||||||
(fields (list primary-field))
|
(fields (list primary-field))
|
||||||
(next nil)
|
(next nil)
|
||||||
(prev nil)
|
(prev nil)
|
||||||
(keymap-overlay nil)
|
|
||||||
snippet)
|
snippet)
|
||||||
(defstruct (yas/field (:constructor yas/make-field (overlay number value)))
|
(defstruct (yas/field (:constructor yas/make-field (overlay number value)))
|
||||||
"A field in a snippet."
|
"A field in a snippet."
|
||||||
@ -117,7 +118,7 @@ current column if this variable is non-`nil'.")
|
|||||||
"Get the default value of the field group."
|
"Get the default value of the field group."
|
||||||
(or (yas/field-value
|
(or (yas/field-value
|
||||||
(yas/group-primary-field group))
|
(yas/group-primary-field group))
|
||||||
"(no default value)"))
|
""))
|
||||||
(defun yas/group-number (group)
|
(defun yas/group-number (group)
|
||||||
"Get the number of the field group."
|
"Get the number of the field group."
|
||||||
(yas/field-number
|
(yas/field-number
|
||||||
@ -202,7 +203,12 @@ the template of a snippet in the current snippet-table."
|
|||||||
(unless (eq field-overlay primary-overlay)
|
(unless (eq field-overlay primary-overlay)
|
||||||
(goto-char (overlay-start field-overlay))
|
(goto-char (overlay-start field-overlay))
|
||||||
(insert text)
|
(insert text)
|
||||||
(delete-char original-length)))))))
|
(if (= (overlay-start field-overlay)
|
||||||
|
(overlay-end field-overlay))
|
||||||
|
(move-overlay field-overlay
|
||||||
|
(overlay-start field-overlay)
|
||||||
|
(point))
|
||||||
|
(delete-char original-length))))))))
|
||||||
|
|
||||||
(defun yas/overlay-modification-hook (overlay after? beg end &optional length)
|
(defun yas/overlay-modification-hook (overlay after? beg end &optional length)
|
||||||
"Modification hook for snippet field overlay."
|
"Modification hook for snippet field overlay."
|
||||||
@ -215,9 +221,10 @@ the template of a snippet in the current snippet-table."
|
|||||||
(inhibit-modification-hooks t))
|
(inhibit-modification-hooks t))
|
||||||
(when (not (overlay-get overlay 'yas/modified?))
|
(when (not (overlay-get overlay 'yas/modified?))
|
||||||
(overlay-put overlay 'yas/modified? t)
|
(overlay-put overlay 'yas/modified? t)
|
||||||
(save-excursion
|
(when (> (overlay-end overlay) end)
|
||||||
(goto-char end)
|
(save-excursion
|
||||||
(delete-char (- (overlay-end overlay) end))))
|
(goto-char end)
|
||||||
|
(delete-char (- (overlay-end overlay) end)))))
|
||||||
(yas/synchronize-fields field-group))))
|
(yas/synchronize-fields field-group))))
|
||||||
(defun yas/overlay-insert-behind-hook (overlay after? beg end &optional length)
|
(defun yas/overlay-insert-behind-hook (overlay after? beg end &optional length)
|
||||||
"Hook for snippet overlay when text is inserted just behind a snippet field."
|
"Hook for snippet overlay when text is inserted just behind a snippet field."
|
||||||
@ -319,20 +326,21 @@ will be deleted before inserting template."
|
|||||||
(setf (yas/group-next prev) group))
|
(setf (yas/group-next prev) group))
|
||||||
(setq prev group)))
|
(setq prev group)))
|
||||||
|
|
||||||
;; Step 7: Create keymap overlay for each group
|
;; Step 7: Create keymap overlay for snippet
|
||||||
(dolist (group (yas/snippet-groups snippet))
|
(let ((overlay (make-overlay (point-min)
|
||||||
(let* ((overlay (yas/field-overlay (yas/group-primary-field group)))
|
(point-max)
|
||||||
(keymap-overlay (make-overlay (overlay-start overlay)
|
nil
|
||||||
(overlay-end overlay)
|
nil
|
||||||
nil
|
t)))
|
||||||
nil
|
(overlay-put overlay 'keymap yas/keymap)
|
||||||
t)))
|
(overlay-put overlay 'yas/snippet-reference snippet)
|
||||||
(overlay-put keymap-overlay 'keymap yas/keymap)
|
(setf (yas/snippet-overlay snippet) overlay))
|
||||||
(setf (yas/group-keymap-overlay group) keymap-overlay)))
|
|
||||||
|
|
||||||
;; Step 8: Replace fields with default values
|
;; Step 8: Replace fields with default values
|
||||||
(dolist (group (yas/snippet-groups snippet))
|
(dolist (group (yas/snippet-groups snippet))
|
||||||
(let ((value (yas/group-value group)))
|
(let ((value (yas/group-value group)))
|
||||||
|
(when (string= "" value)
|
||||||
|
(push group (yas/snippet-tabstops snippet)))
|
||||||
(dolist (field (yas/group-fields group))
|
(dolist (field (yas/group-fields group))
|
||||||
(let* ((overlay (yas/field-overlay field))
|
(let* ((overlay (yas/field-overlay field))
|
||||||
(start (overlay-start overlay))
|
(start (overlay-start overlay))
|
||||||
@ -398,7 +406,7 @@ will be deleted before inserting template."
|
|||||||
(let ((point (or point (point)))
|
(let ((point (or point (point)))
|
||||||
(snippet-overlay nil))
|
(snippet-overlay nil))
|
||||||
(dolist (overlay (overlays-at point))
|
(dolist (overlay (overlays-at point))
|
||||||
(when(overlay-get overlay 'yas/snippet)
|
(when (overlay-get overlay 'yas/snippet)
|
||||||
(if (null snippet-overlay)
|
(if (null snippet-overlay)
|
||||||
(setq snippet-overlay overlay)
|
(setq snippet-overlay overlay)
|
||||||
(when (> (yas/snippet-id (overlay-get overlay 'yas/snippet))
|
(when (> (yas/snippet-id (overlay-get overlay 'yas/snippet))
|
||||||
@ -406,6 +414,21 @@ will be deleted before inserting template."
|
|||||||
(setq snippet-overlay overlay)))))
|
(setq snippet-overlay overlay)))))
|
||||||
snippet-overlay))
|
snippet-overlay))
|
||||||
|
|
||||||
|
(defun yas/snippet-of-current-keymap (&optional point)
|
||||||
|
"Get the snippet holding the snippet keymap under POINT."
|
||||||
|
(let ((point (or point (point)))
|
||||||
|
(keymap-snippet nil)
|
||||||
|
(snippet nil))
|
||||||
|
(dolist (overlay (overlays-at point))
|
||||||
|
(setq snippet (overlay-get overlay 'yas/snippet-reference))
|
||||||
|
(when snippet
|
||||||
|
(if (null keymap-snippet)
|
||||||
|
(setq keymap-snippet snippet)
|
||||||
|
(when (> (yas/snippet-id snippet)
|
||||||
|
(yas/snippet-id keymap-snippet))
|
||||||
|
(setq keymap-snippet snippet)))))
|
||||||
|
keymap-snippet))
|
||||||
|
|
||||||
(defun yas/current-overlay-for-navigation ()
|
(defun yas/current-overlay-for-navigation ()
|
||||||
"Get current overlay for navigation. Might be overlay at current or previous point."
|
"Get current overlay for navigation. Might be overlay at current or previous point."
|
||||||
(let ((overlay1 (yas/current-snippet-overlay))
|
(let ((overlay1 (yas/current-snippet-overlay))
|
||||||
@ -423,6 +446,17 @@ will be deleted before inserting template."
|
|||||||
overlay2
|
overlay2
|
||||||
overlay1)))))
|
overlay1)))))
|
||||||
|
|
||||||
|
(defun yas/navigate-group (group next?)
|
||||||
|
"Go to next of previous field group. Exit snippet if none."
|
||||||
|
(let ((target (if next?
|
||||||
|
(yas/group-next group)
|
||||||
|
(yas/group-prev group))))
|
||||||
|
(if target
|
||||||
|
(goto-char (overlay-start
|
||||||
|
(yas/field-overlay
|
||||||
|
(yas/group-primary-field target))))
|
||||||
|
(yas/exit-snippet (yas/group-snippet group)))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; User level functions
|
;; User level functions
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
@ -447,14 +481,22 @@ otherwise, nil returned."
|
|||||||
(interactive)
|
(interactive)
|
||||||
(let ((overlay (yas/current-overlay-for-navigation)))
|
(let ((overlay (yas/current-overlay-for-navigation)))
|
||||||
(if overlay
|
(if overlay
|
||||||
(let ((next (yas/group-next
|
(yas/navigate-group (overlay-get overlay 'yas/group) t)
|
||||||
(overlay-get overlay 'yas/group))))
|
(let ((snippet (yas/snippet-of-current-keymap))
|
||||||
(if next
|
(done nil))
|
||||||
(goto-char (overlay-start
|
(if snippet
|
||||||
(yas/field-overlay
|
(do* ((tabstops (yas/snippet-tabstops snippet) (cdr tabstops))
|
||||||
(yas/group-primary-field next))))
|
(tabstop (car tabstops) (car tabstops)))
|
||||||
(yas/exit-snippet (overlay-get overlay 'yas/snippet))))
|
((or (null tabstops)
|
||||||
(message "Not in a snippet field."))))
|
done)
|
||||||
|
(unless done (message "Not in a snippet field.")))
|
||||||
|
(when (= (point)
|
||||||
|
(overlay-start
|
||||||
|
(yas/field-overlay
|
||||||
|
(yas/group-primary-field tabstop))))
|
||||||
|
(setq done t)
|
||||||
|
(yas/navigate-group tabstop t)))
|
||||||
|
(message "Not in a snippet field."))))))
|
||||||
|
|
||||||
(defun yas/prev-field-group ()
|
(defun yas/prev-field-group ()
|
||||||
"Navigate to prev field group. If there's none, exit the snippet."
|
"Navigate to prev field group. If there's none, exit the snippet."
|
||||||
@ -474,8 +516,8 @@ otherwise, nil returned."
|
|||||||
"Goto exit-marker of SNIPPET and delete the snippet."
|
"Goto exit-marker of SNIPPET and delete the snippet."
|
||||||
(interactive)
|
(interactive)
|
||||||
(goto-char (yas/snippet-exit-marker snippet))
|
(goto-char (yas/snippet-exit-marker snippet))
|
||||||
|
(delete-overlay (yas/snippet-overlay snippet))
|
||||||
(dolist (group (yas/snippet-groups snippet))
|
(dolist (group (yas/snippet-groups snippet))
|
||||||
(delete-overlay (yas/group-keymap-overlay group))
|
|
||||||
(dolist (field (yas/group-fields group))
|
(dolist (field (yas/group-fields group))
|
||||||
(delete-overlay (yas/field-overlay field)))))
|
(delete-overlay (yas/field-overlay field)))))
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user