* a little cheating sometimes inserts a newline at end of the buffer...

This commit is contained in:
capitaomorte 2009-07-10 15:37:21 +00:00
parent 460bf76bae
commit daf3c788a5

View File

@ -95,6 +95,10 @@ mode will be listed under the menu \"yasnippet\".")
(defvar yas/trigger-symbol " =>" (defvar yas/trigger-symbol " =>"
"The text that will be used in menu to represent the trigger.") "The text that will be used in menu to represent the trigger.")
(defvar yas/good-grace nil
"If non-nil, don't raise errors in inline elisp evaluation,
return the error string instead.")
(defface yas/field-highlight-face (defface yas/field-highlight-face
'((((class color) (background light)) (:background "DarkSeaGreen1")) '((((class color) (background light)) (:background "DarkSeaGreen1"))
(t (:background "DimGrey"))) (t (:background "DimGrey")))
@ -272,13 +276,7 @@ You can customize the key through `yas/trigger-key'."
;; The indicator for the mode line. ;; The indicator for the mode line.
" yas" " yas"
:group 'editing :group 'editing
(define-key yas/minor-mode-map yas/trigger-key 'yas/expand) (define-key yas/minor-mode-map yas/trigger-key 'yas/expand))
(if yas/minor-mode
(progn
(add-hook 'post-command-hook 'yas/post-command-handler nil t)
(add-hook 'pre-command-hook 'yas/pre-command-handler t t))
(remove-hook 'post-command-hook 'yas/post-command-handler)
(remove-hook 'pre-command-hook 'yas/pre-command-handler)))
(defun yas/minor-mode-auto-on () (defun yas/minor-mode-auto-on ()
"Turn on YASnippet minor mode unless `yas/dont-activate' is "Turn on YASnippet minor mode unless `yas/dont-activate' is
@ -383,6 +381,8 @@ a list of modes like this to help the judgement."
(or (fboundp mode) (or (fboundp mode)
(find mode yas/known-modes))) (find mode yas/known-modes)))
;; TODO: This is a possible optimization point, the expression could ;; TODO: This is a possible optimization point, the expression could
;; be stored in cons format instead of string, ;; be stored in cons format instead of string,
(defun yas/eval-string (string) (defun yas/eval-string (string)
@ -395,8 +395,11 @@ a list of modes like this to help the judgement."
(let ((result (eval (read string)))) (let ((result (eval (read string))))
(when result (when result
(format "%s" result)))))) (format "%s" result))))))
(error (format "(error in elisp evaluation: %s)" (error (if yas/good-grace
(error-message-string err))))) (format "(yasnippet: error in elisp evaluation: %s)"
(error-message-string err))
(error (format "(yassnippet: error in elisp evaluation: %s)"
(error-message-string err)))))))
(defun yas/snippet-table (mode) (defun yas/snippet-table (mode)
"Get the snippet table corresponding to MODE." "Get the snippet table corresponding to MODE."
@ -862,8 +865,10 @@ when the condition evaluated to non-nil."
"Calculate the value of the field/mirror. If there's a transform "Calculate the value of the field/mirror. If there's a transform
for this field, apply it. Otherwise, the value is returned for this field, apply it. Otherwise, the value is returned
unmodified." unmodified."
(let* ((text (yas/field-text-for-display field)) (let* ((yas/text (yas/field-text-for-display field))
(modified-p (yas/field-modified-p field)) (text yas/text)
(yas/modified-p (yas/field-modified-p field))
(yas/moving-away nil)
(transform (if (yas/mirror-p field-or-mirror) (transform (if (yas/mirror-p field-or-mirror)
(yas/mirror-transform field-or-mirror) (yas/mirror-transform field-or-mirror)
(yas/field-transform field-or-mirror))) (yas/field-transform field-or-mirror)))
@ -908,11 +913,11 @@ have, compare through the field's start point"
"Return a sorted list of snippets at point, most recently "Return a sorted list of snippets at point, most recently
inserted first." inserted first."
(sort (sort
(remove nil (mapcar #'(lambda (ov) (remove nil (remove-duplicates (mapcar #'(lambda (ov)
(overlay-get ov 'yas/snippet)) (overlay-get ov 'yas/snippet))
(if all-snippets (if all-snippets
(overlays-in (point-min) (point-max)) (overlays-in (point-min) (point-max))
(overlays-at (point))))) (overlays-at (point))))))
#'(lambda (s1 s2) #'(lambda (s1 s2)
(<= (yas/snippet-id s2) (yas/snippet-id s1))))) (<= (yas/snippet-id s2) (yas/snippet-id s1)))))
@ -928,6 +933,16 @@ inserted first."
(yas/field-number active-field)))) (yas/field-number active-field))))
(live-fields (remove-if #'yas/field-probably-deleted-p (yas/snippet-fields snippet))) (live-fields (remove-if #'yas/field-probably-deleted-p (yas/snippet-fields snippet)))
(target-field (yas/snippet-find-field snippet number))) (target-field (yas/snippet-find-field snippet number)))
;; First check if we're moving out of a field
;;
(when (and active-field
(yas/field-transform active-field))
(let* ((yas/moving-away t)
(yas/text (yas/field-text-for-display active-field))
(text yas/text)
(yas/modified-p (yas/field-modified-p active-field)))
(yas/eval-string (yas/field-transform active-field))))
;; Now actually move...
(cond ((and number (cond ((and number
(> number (length live-fields))) (> number (length live-fields)))
(yas/exit-snippet snippet)) (yas/exit-snippet snippet))
@ -964,9 +979,6 @@ up the snippet does not delete it!"
(yas/snippet-exit snippet) (yas/snippet-exit snippet)
(overlay-end (yas/snippet-control-overlay snippet))))) (overlay-end (yas/snippet-control-overlay snippet)))))
(defun yas/delete-overlay-region (overlay)
(delete-region (overlay-start overlay) (overlay-end overlay)))
;;; Apropos markers-to-points: This can be useful for performance reasons, so ;;; Apropos markers-to-points: This can be useful for performance reasons, so
;;; that an excessive number of live markers arent kept aroung in the ;;; that an excessive number of live markers arent kept aroung in the
;;; `buffer-undo-list'. In `markers-to-points', the set-to-nil ;;; `buffer-undo-list'. In `markers-to-points', the set-to-nil
@ -1065,11 +1077,13 @@ exiting the snippet."
(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
snippet, if so cleans up the whole snippet up." snippet, if so cleans up the whole snippet up."
(let* ((snippets (yas/snippets-at-point 'all-snippets))) (let* ((snippets (yas/snippets-at-point 'all-snippets))
(snippets-left snippets))
(dolist (snippet snippets) (dolist (snippet snippets)
(let ((active-field (yas/snippet-active-field snippet))) (let ((active-field (yas/snippet-active-field snippet)))
(cond ((not (and active-field (yas/field-contains-point-p active-field))) (cond ((not (and active-field (yas/field-contains-point-p active-field)))
(yas/commit-snippet snippet)) (yas/commit-snippet snippet)
(setq snippets-left (delete snippet snippets-left)))
((and active-field ((and active-field
(or (not yas/active-field-overlay) (or (not yas/active-field-overlay)
(not (overlay-buffer yas/active-field-overlay)))) (not (overlay-buffer yas/active-field-overlay))))
@ -1082,7 +1096,10 @@ snippet, if so cleans up the whole snippet up."
(yas/move-to-field snippet active-field) (yas/move-to-field snippet active-field)
(yas/update-mirrors snippet))) (yas/update-mirrors snippet)))
(t (t
nil)))))) nil))))
(unless snippets-left
(remove-hook 'post-command-hook 'yas/post-command-handler 'local)
(remove-hook 'pre-command-hook 'yas/pre-command-handler 'local))))
(defun yas/field-contains-point-p (field &optional point) (defun yas/field-contains-point-p (field &optional point)
(let ((point (or point (let ((point (or point
@ -1204,21 +1221,6 @@ progress."
(yas/clear-field field)) (yas/clear-field field))
(setf (yas/field-modified-p field) t)))))) (setf (yas/field-modified-p field) t))))))
(defun yas/field-update-display (field snippet)
"Much like `yas/mirror-update-display', but for fields"
(when (yas/field-transform field)
(let ((inhibit-modification-hooks t)
(transformed (yas/apply-transform field field 'nil-on-empty))
(point (point)))
(when (and transformed
(not (string= transformed (buffer-substring-no-properties (yas/field-start field) (yas/field-end field)))))
(goto-char (yas/field-start field))
(insert transformed)
(if (> (yas/field-end field) (point))
(delete-region (point) (yas/field-end field))
(set-marker (yas/field-end field) (point)))
t))))
;;; ;;;
;;; Apropos protection overlays:... ;;; Apropos protection overlays:...
;;; ;;;
@ -1241,18 +1243,30 @@ progress."
"Place protection overlays surrounding SNIPPET's FIELD. "Place protection overlays surrounding SNIPPET's FIELD.
Move the overlays, or create them if they do not exit." Move the overlays, or create them if they do not exit."
(let ((start (yas/field-start field))
(end (yas/field-end field)))
;; First check if the (1+ end) is contained in the buffer,
;; otherwise we'll have to do a bit of cheating and silently
;; insert a newline.
(when (< (point-max) (1+ end))
(save-excursion
(let ((inhibit-modification-hooks t))
(goto-char (point-max))
(newline))))
;; go on to normal overlay creation/moving
(cond ((and yas/field-protection-overlays (cond ((and yas/field-protection-overlays
(every #'overlay-buffer yas/field-protection-overlays)) (every #'overlay-buffer yas/field-protection-overlays))
(move-overlay (first yas/field-protection-overlays) (1- (yas/field-start field)) (yas/field-start field)) (move-overlay (first yas/field-protection-overlays) (1- start) start)
(move-overlay (second yas/field-protection-overlays) (yas/field-end field) (1+ (yas/field-end field)))) (move-overlay (second yas/field-protection-overlays) end (1+ end)))
(t (t
(setq yas/field-protection-overlays (setq yas/field-protection-overlays
(list (make-overlay (1- (yas/field-start field)) (yas/field-start field) nil t nil) (list (make-overlay (1- start) start nil t nil)
(make-overlay (yas/field-end field) (1+ (yas/field-end field)) nil t nil))) (make-overlay end (1+ end) nil t nil)))
(dolist (ov yas/field-protection-overlays) (dolist (ov yas/field-protection-overlays)
(overlay-put ov 'face 'yas/field-debug-face) (overlay-put ov 'face 'yas/field-debug-face)
(overlay-put ov 'yas/snippet snippet)
;; (overlay-put ov 'evaporate t) ;; (overlay-put ov 'evaporate t)
(overlay-put ov 'modification-hooks '(yas/on-protection-overlay-modification)))))) (overlay-put ov 'modification-hooks '(yas/on-protection-overlay-modification)))))))
(defvar yas/protection-violation nil (defvar yas/protection-violation nil
"When non-nil, signals attempts to erronesly exit or modify the snippet. "When non-nil, signals attempts to erronesly exit or modify the snippet.
@ -1374,6 +1388,9 @@ After revival, push the `yas/take-care-of-redo' in the
(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))))
(add-hook 'post-command-hook 'yas/post-command-handler nil t)
(add-hook 'pre-command-hook 'yas/pre-command-handler t t)
(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))
@ -1397,6 +1414,10 @@ Returns the newly created snippet."
;; Move to end ;; Move to end
(goto-char (point-max)) (goto-char (point-max))
;; Setup hooks
(add-hook 'post-command-hook 'yas/post-command-handler nil t)
(add-hook 'pre-command-hook 'yas/pre-command-handler t t)
snippet)) snippet))
(defun yas/snippet-sort-link-fields (snippet) (defun yas/snippet-sort-link-fields (snippet)
@ -1438,7 +1459,14 @@ Meant to be called in a narrowed buffer, does various passes"
(yas/simple-mirror-parse-create snippet) (yas/simple-mirror-parse-create snippet)
;; restore escapes ;; restore escapes
;; ;;
(yas/restore-escapes))) (goto-char parse-start)
(yas/restore-escapes)
;; indent the best we can
;;
))
(defun yas/escape-string (escaped) (defun yas/escape-string (escaped)
(concat "YASESCAPE" (format "%d" escaped) "PROTECTGUARD")) (concat "YASESCAPE" (format "%d" escaped) "PROTECTGUARD"))
@ -1556,14 +1584,41 @@ When multiple such expressions are found, only the last one counts."
(defun yas/mirror-update-display (mirror field) (defun yas/mirror-update-display (mirror field)
"Update MIRROR according to FIELD (and mirror transform)." "Update MIRROR according to FIELD (and mirror transform)."
(let ((transformed (yas/apply-transform mirror field))) (let ((transformed (yas/apply-transform mirror field 'nil-on-empty)))
(when (not (string= transformed (buffer-substring-no-properties (yas/mirror-start mirror) (yas/mirror-end mirror)))) (when (and transformed
(not (string= transformed (buffer-substring-no-properties (yas/mirror-start mirror) (yas/mirror-end mirror)))))
(goto-char (yas/mirror-start mirror)) (goto-char (yas/mirror-start mirror))
(insert transformed) (insert transformed)
(if (> (yas/mirror-end mirror) (point)) (if (> (yas/mirror-end mirror) (point))
(delete-region (point) (yas/mirror-end mirror)) (delete-region (point) (yas/mirror-end mirror))
(set-marker (yas/mirror-end mirror) (point)))))) (set-marker (yas/mirror-end mirror) (point))))))
(defun yas/field-update-display (field snippet)
"Much like `yas/mirror-update-display', but for fields"
(when (yas/field-transform field)
(let ((inhibit-modification-hooks t)
(transformed (yas/apply-transform field field 'nil-on-empty))
(point (point)))
(when (and transformed
(not (string= transformed (buffer-substring-no-properties (yas/field-start field) (yas/field-end field)))))
(setf (yas/field-modified-p field) t)
(goto-char (yas/field-start field))
(insert transformed)
(if (> (yas/field-end field) (point))
(delete-region (point) (yas/field-end field))
(set-marker (yas/field-end field) (point)))
t))))
;; User convenience functions
(defun yas/choose (&rest possibilities)
(ido-completing-read "Choose: " possibilities nil nil nil nil (car possibilities)))
(defun yas/restrict (&rest possibilities)
(when (notany #'(lambda (pos) (string= pos yas/text)) possibilities)
(error "hey don't move away just now")))
;; Debug functions. Use (or change) at will whenever needed. ;; Debug functions. Use (or change) at will whenever needed.
;; ;;