mirror of
https://github.com/joaotavora/yasnippet.git
synced 2025-10-13 13:13:03 +00:00
* Fix more bugs, still some more to go
* For example the inexisting parent-mode when a mode has groups * Display triggerkey in menu entries if the snippet has a trigger key
This commit is contained in:
parent
0732b08600
commit
8420238a19
180
yasnippet.el
180
yasnippet.el
@ -467,7 +467,7 @@ Here's an example:
|
|||||||
"A regexp to recognize a \"`lisp-expression`\" expression." )
|
"A regexp to recognize a \"`lisp-expression`\" expression." )
|
||||||
|
|
||||||
(defconst yas/transform-mirror-regexp
|
(defconst yas/transform-mirror-regexp
|
||||||
"${\\(?:\\([0-9]+\\):\\)?$\\([^}]*\\)"
|
"${\\(?:\\([0-9]+\\):\\)?$\\(([^}]*\\)"
|
||||||
"A regexp to *almost* recognize a mirror with a transform.")
|
"A regexp to *almost* recognize a mirror with a transform.")
|
||||||
|
|
||||||
(defconst yas/simple-mirror-regexp
|
(defconst yas/simple-mirror-regexp
|
||||||
@ -1833,7 +1833,8 @@ otherwise, proposes to create the first option returned by
|
|||||||
|
|
||||||
(defun yas/compute-major-mode-and-parents (file &optional prompt-if-failed no-hierarchy-parents)
|
(defun yas/compute-major-mode-and-parents (file &optional prompt-if-failed no-hierarchy-parents)
|
||||||
(let* ((file-dir (and file
|
(let* ((file-dir (and file
|
||||||
(directory-file-name (file-name-directory file))))
|
(directory-file-name (or (locate-dominating-file file ".yas-make-groups")
|
||||||
|
(directory-file-name (file-name-directory file))))))
|
||||||
(major-mode-name (and file-dir
|
(major-mode-name (and file-dir
|
||||||
(file-name-nondirectory file-dir)))
|
(file-name-nondirectory file-dir)))
|
||||||
(parent-file-dir (and file-dir
|
(parent-file-dir (and file-dir
|
||||||
@ -1977,15 +1978,6 @@ Otherwise throw exception."
|
|||||||
(when field
|
(when field
|
||||||
(yas/field-text-for-display field))))
|
(yas/field-text-for-display field))))
|
||||||
|
|
||||||
;; (defun yas/oni (text regexp format &optional options)
|
|
||||||
;; "Pipes TEXT thru ruby Oniguruma regexp"
|
|
||||||
;; (replace-regexp-in-string
|
|
||||||
;; "\n$"
|
|
||||||
;; ""
|
|
||||||
;; (shell-command-to-string (format "ruby -e 'puts \"%s\".gsub(\"a\",\"b\")'" text))))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;; Snippet expansion and field management
|
;;; Snippet expansion and field management
|
||||||
|
|
||||||
@ -2785,13 +2777,19 @@ If it does, also call `yas/advance-end-maybe' on FOM."
|
|||||||
(set-marker (yas/fom-start fom) newstart)
|
(set-marker (yas/fom-start fom) newstart)
|
||||||
(yas/advance-end-maybe fom newstart)))
|
(yas/advance-end-maybe fom newstart)))
|
||||||
|
|
||||||
|
|
||||||
|
(defvar yas/dollar-regions nil
|
||||||
|
"When expanding the snippet the \"parse-create\" functions add
|
||||||
|
cons cells to this var")
|
||||||
(defun yas/snippet-parse-create (snippet)
|
(defun yas/snippet-parse-create (snippet)
|
||||||
"Parse a recently inserted snippet template, creating all
|
"Parse a recently inserted snippet template, creating all
|
||||||
necessary fields, mirrors and exit points.
|
necessary fields, mirrors and exit points.
|
||||||
|
|
||||||
Meant to be called in a narrowed buffer, does various passes"
|
Meant to be called in a narrowed buffer, does various passes"
|
||||||
(let ((parse-start (point))
|
(let ((parse-start (point)))
|
||||||
(dollar-regions (list 'reg)))
|
;; Reset the yas/dollar-regions
|
||||||
|
;;
|
||||||
|
(setq yas/dollar-regions nil)
|
||||||
;; protect quote and backquote escapes
|
;; protect quote and backquote escapes
|
||||||
;;
|
;;
|
||||||
(yas/protect-escapes nil '(?` ?'))
|
(yas/protect-escapes nil '(?` ?'))
|
||||||
@ -2807,21 +2805,21 @@ Meant to be called in a narrowed buffer, does various passes"
|
|||||||
;; parse fields with {}
|
;; parse fields with {}
|
||||||
;;
|
;;
|
||||||
(goto-char parse-start)
|
(goto-char parse-start)
|
||||||
(yas/field-parse-create snippet dollar-regions)
|
(yas/field-parse-create snippet)
|
||||||
;; parse simple mirrors and fields
|
;; parse simple mirrors and fields
|
||||||
;;
|
;;
|
||||||
(goto-char parse-start)
|
(goto-char parse-start)
|
||||||
(yas/simple-mirror-parse-create snippet dollar-regions)
|
(yas/simple-mirror-parse-create snippet)
|
||||||
;; parse mirror transforms
|
;; parse mirror transforms
|
||||||
;;
|
;;
|
||||||
(goto-char parse-start)
|
(goto-char parse-start)
|
||||||
(yas/transform-mirror-parse-create snippet dollar-regions)
|
(yas/transform-mirror-parse-create snippet)
|
||||||
;; calculate adjacencies of fields and mirrors
|
;; calculate adjacencies of fields and mirrors
|
||||||
;;
|
;;
|
||||||
(yas/calculate-adjacencies snippet)
|
(yas/calculate-adjacencies snippet)
|
||||||
;; Delete $-constructs
|
;; Delete $-constructs
|
||||||
;;
|
;;
|
||||||
(yas/delete-regions (copy-list (rest dollar-regions)))
|
(yas/delete-regions yas/dollar-regions)
|
||||||
;; restore escapes
|
;; restore escapes
|
||||||
;;
|
;;
|
||||||
(goto-char parse-start)
|
(goto-char parse-start)
|
||||||
@ -2965,57 +2963,72 @@ With optional string TEXT do it in string instead of the buffer."
|
|||||||
(set-marker-insertion-type marker nil)
|
(set-marker-insertion-type marker nil)
|
||||||
marker))
|
marker))
|
||||||
|
|
||||||
(defun yas/add-to-list (l e)
|
(defun yas/field-parse-create (snippet &optional parent-field)
|
||||||
(setf (cdr l)
|
"Parse most field expressions, except for the simple one \"$n\".
|
||||||
(cons e (cdr l))))
|
|
||||||
|
|
||||||
(defun yas/field-parse-create (snippet dollar-regions &optional parent-field)
|
|
||||||
"Parse most field expression, except for the simple one \"$n\".
|
|
||||||
|
|
||||||
The following count as a field:
|
The following count as a field:
|
||||||
|
|
||||||
* \"${n: text}\", for a numbered field with default text, as long as N is not 0;
|
* \"${n: text}\", for a numbered field with default text, as long as N is not 0;
|
||||||
|
|
||||||
* \"${n: text$(expression)}, the same with a lisp expression;
|
* \"${n: text$(expression)}, the same with a lisp expression;
|
||||||
|
this is caught with the curiously named `yas/multi-dollar-lisp-expression-regexp'
|
||||||
|
|
||||||
* the same as above but unnumbered, (no N:) and number is calculated automatically.
|
* the same as above but unnumbered, (no N:) and number is calculated automatically.
|
||||||
|
|
||||||
When multiple expressions are found, only the last one counts."
|
When multiple expressions are found, only the last one counts."
|
||||||
|
;;
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(while (re-search-forward yas/field-regexp nil t)
|
(while (re-search-forward yas/field-regexp nil t)
|
||||||
(let* ((real-match-end-0 (yas/scan-sexps (1+ (match-beginning 0)) 1))
|
(let* ((real-match-end-0 (yas/scan-sexps (1+ (match-beginning 0)) 1))
|
||||||
(number (and (match-string-no-properties 1)
|
(number (and (match-string-no-properties 1)
|
||||||
(string-to-number (match-string-no-properties 1))))
|
(string-to-number (match-string-no-properties 1))))
|
||||||
(brand-new-field (and real-match-end-0
|
(brand-new-field (and real-match-end-0
|
||||||
(not (save-match-data
|
;; break if on "$(" immediately
|
||||||
(eq (string-match "$[ \t\n]*("
|
;; after the ":", this will be
|
||||||
(match-string-no-properties 2)) 0)))
|
;; caught as a mirror with
|
||||||
(not (and number (zerop number)))
|
;; transform later.
|
||||||
(yas/make-field number
|
(not (save-match-data
|
||||||
(yas/make-marker (match-beginning 2))
|
(eq (string-match "$[ \t\n]*("
|
||||||
(yas/make-marker (1- real-match-end-0))
|
(match-string-no-properties 2)) 0)))
|
||||||
parent-field))))
|
(not (and number (zerop number)))
|
||||||
(when brand-new-field
|
(yas/make-field number
|
||||||
(yas/add-to-list dollar-regions
|
(yas/make-marker (match-beginning 2))
|
||||||
(cons (1- real-match-end-0) real-match-end-0))
|
(yas/make-marker (1- real-match-end-0))
|
||||||
(yas/add-to-list dollar-regions
|
parent-field))))
|
||||||
(cons (match-beginning 0) (match-beginning 2)))
|
(when brand-new-field
|
||||||
(push brand-new-field (yas/snippet-fields snippet))
|
(goto-char real-match-end-0)
|
||||||
(save-excursion
|
(push (cons (1- real-match-end-0) real-match-end-0)
|
||||||
(save-restriction
|
yas/dollar-regions)
|
||||||
(narrow-to-region (yas/field-start brand-new-field) (yas/field-end brand-new-field))
|
(push (cons (match-beginning 0) (match-beginning 2))
|
||||||
(goto-char (point-min))
|
yas/dollar-regions)
|
||||||
(yas/field-parse-create snippet dollar-regions brand-new-field)))))))
|
(push brand-new-field (yas/snippet-fields snippet))
|
||||||
|
(save-excursion
|
||||||
|
(save-restriction
|
||||||
|
(narrow-to-region (yas/field-start brand-new-field) (yas/field-end brand-new-field))
|
||||||
|
(goto-char (point-min))
|
||||||
|
(yas/field-parse-create snippet brand-new-field)))))))
|
||||||
|
;; if we entered from a parent field, now search for the
|
||||||
|
;; `yas/multi-dollar-lisp-expression-regexp'. THis is used for
|
||||||
|
;; primary field transformations
|
||||||
|
;;
|
||||||
(when parent-field
|
(when parent-field
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(while (re-search-forward yas/multi-dollar-lisp-expression-regexp nil t)
|
(while (re-search-forward yas/multi-dollar-lisp-expression-regexp nil t)
|
||||||
(let* ((real-match-end-1 (yas/scan-sexps (match-beginning 1) 1)))
|
(let* ((real-match-end-1 (yas/scan-sexps (match-beginning 1) 1)))
|
||||||
(when real-match-end-1
|
;; commit the primary field transformation if we don't find
|
||||||
(let ((lisp-expression-string (buffer-substring-no-properties (match-beginning 1)
|
;; it in yas/dollar-regions (a subnested field) might have
|
||||||
real-match-end-1)))
|
;; already caught it.
|
||||||
(setf (yas/field-transform parent-field) (yas/restore-escapes lisp-expression-string)))
|
(when (and real-match-end-1
|
||||||
(yas/add-to-list dollar-regions
|
(not (member (cons (match-beginning 0)
|
||||||
(cons (match-beginning 0) real-match-end-1))))))))
|
real-match-end-1)
|
||||||
|
yas/dollar-regions)))
|
||||||
|
(let ((lisp-expression-string (buffer-substring-no-properties (match-beginning 1)
|
||||||
|
real-match-end-1)))
|
||||||
|
(setf (yas/field-transform parent-field) (yas/restore-escapes lisp-expression-string)))
|
||||||
|
(push (cons (match-beginning 0) real-match-end-1)
|
||||||
|
yas/dollar-regions)))))))
|
||||||
|
|
||||||
(defun yas/transform-mirror-parse-create (snippet dollar-regions)
|
(defun yas/transform-mirror-parse-create (snippet)
|
||||||
"Parse the \"${n:$(lisp-expression)}\" mirror transformations."
|
"Parse the \"${n:$(lisp-expression)}\" mirror transformations."
|
||||||
(while (re-search-forward yas/transform-mirror-regexp nil t)
|
(while (re-search-forward yas/transform-mirror-regexp nil t)
|
||||||
(let* ((real-match-end-0 (yas/scan-sexps (1+ (match-beginning 0)) 1))
|
(let* ((real-match-end-0 (yas/scan-sexps (1+ (match-beginning 0)) 1))
|
||||||
@ -3031,37 +3044,36 @@ When multiple expressions are found, only the last one counts."
|
|||||||
(buffer-substring-no-properties (match-beginning 2)
|
(buffer-substring-no-properties (match-beginning 2)
|
||||||
(1- real-match-end-0))))
|
(1- real-match-end-0))))
|
||||||
(yas/field-mirrors field))
|
(yas/field-mirrors field))
|
||||||
(yas/add-to-list dollar-regions
|
(push (cons (match-beginning 0) real-match-end-0) yas/dollar-regions)))))
|
||||||
(cons (match-beginning 0) real-match-end-0))))))
|
|
||||||
|
|
||||||
(defun yas/simple-mirror-parse-create (snippet dollar-regions)
|
(defun yas/simple-mirror-parse-create (snippet)
|
||||||
"Parse the simple \"$n\" mirrors and the exit-marker."
|
"Parse the simple \"$n\" mirrors and the exit-marker."
|
||||||
(while (re-search-forward yas/simple-mirror-regexp nil t)
|
(while (re-search-forward yas/simple-mirror-regexp nil t)
|
||||||
(let ((number (string-to-number (match-string-no-properties 1))))
|
(let ((number (string-to-number (match-string-no-properties 1))))
|
||||||
(cond ((zerop number)
|
(cond ((zerop number)
|
||||||
|
|
||||||
(setf (yas/snippet-exit snippet)
|
(setf (yas/snippet-exit snippet)
|
||||||
(yas/make-exit (yas/make-marker (match-end 0))))
|
(yas/make-exit (yas/make-marker (match-end 0))))
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(goto-char (match-beginning 0))
|
(goto-char (match-beginning 0))
|
||||||
(when (and yas/wrap-around-region yas/selected-text)
|
(when (and yas/wrap-around-region yas/selected-text)
|
||||||
(insert yas/selected-text))
|
(insert yas/selected-text))
|
||||||
(yas/add-to-list dollar-regions
|
(push (cons (point) (yas/exit-marker (yas/snippet-exit snippet)))
|
||||||
(cons (point) (yas/exit-marker (yas/snippet-exit snippet))))))
|
yas/dollar-regions)))
|
||||||
(t
|
(t
|
||||||
(let ((field (yas/snippet-find-field snippet number)))
|
(let ((field (yas/snippet-find-field snippet number)))
|
||||||
(if field
|
(if field
|
||||||
(push (yas/make-mirror (yas/make-marker (match-beginning 0))
|
(push (yas/make-mirror (yas/make-marker (match-beginning 0))
|
||||||
(yas/make-marker (match-beginning 0))
|
(yas/make-marker (match-beginning 0))
|
||||||
nil)
|
nil)
|
||||||
(yas/field-mirrors field))
|
(yas/field-mirrors field))
|
||||||
(push (yas/make-field number
|
(push (yas/make-field number
|
||||||
(yas/make-marker (match-beginning 0))
|
(yas/make-marker (match-beginning 0))
|
||||||
(yas/make-marker (match-beginning 0))
|
(yas/make-marker (match-beginning 0))
|
||||||
nil)
|
nil)
|
||||||
(yas/snippet-fields snippet))))
|
(yas/snippet-fields snippet))))
|
||||||
(yas/add-to-list dollar-regions
|
(push (cons (match-beginning 0) (match-end 0))
|
||||||
(cons (match-beginning 0) (match-end 0))))))))
|
yas/dollar-regions))))))
|
||||||
|
|
||||||
(defun yas/delete-regions (regions)
|
(defun yas/delete-regions (regions)
|
||||||
"Sort disjuct REGIONS by start point, then delete from the back."
|
"Sort disjuct REGIONS by start point, then delete from the back."
|
||||||
|
Loading…
x
Reference in New Issue
Block a user