summaryrefslogtreecommitdiff
path: root/.emacs.d/lisp/yasnippet.el
diff options
context:
space:
mode:
Diffstat (limited to '.emacs.d/lisp/yasnippet.el')
-rw-r--r--.emacs.d/lisp/yasnippet.el210
1 files changed, 111 insertions, 99 deletions
diff --git a/.emacs.d/lisp/yasnippet.el b/.emacs.d/lisp/yasnippet.el
index 1f6c7de..f13dc4f 100644
--- a/.emacs.d/lisp/yasnippet.el
+++ b/.emacs.d/lisp/yasnippet.el
@@ -728,22 +728,22 @@ defined direct keybindings to the command
728(defun yas--modes-to-activate (&optional mode) 728(defun yas--modes-to-activate (&optional mode)
729 "Compute list of mode symbols that are active for `yas-expand' 729 "Compute list of mode symbols that are active for `yas-expand'
730and friends." 730and friends."
731 (let (dfs) 731 (let (dfs explored)
732 (setq dfs (lambda (mode &optional explored) 732 (setq dfs (lambda (mode)
733 (push mode explored) 733 (unless (memq mode explored)
734 (cons mode 734 (push mode explored)
735 (loop for neighbour 735 (loop for neighbour
736 in (cl-list* (get mode 'derived-mode-parent) 736 in (cl-list* (get mode 'derived-mode-parent)
737 (ignore-errors (symbol-function mode)) 737 (ignore-errors (symbol-function mode))
738 (gethash mode yas--parents)) 738 (gethash mode yas--parents))
739 when (and neighbour 739 when (and neighbour
740 (not (memq neighbour explored)) 740 (not (memq neighbour explored))
741 (symbolp neighbour)) 741 (symbolp neighbour))
742 append (funcall dfs neighbour explored))))) 742 do (funcall dfs neighbour)))))
743 (remove-duplicates (if mode 743 (if mode
744 (funcall dfs mode) 744 (funcall dfs mode)
745 (append yas--extra-modes 745 (mapcar dfs (cons major-mode yas--extra-modes)))
746 (funcall dfs major-mode)))))) 746 explored))
747 747
748(defvar yas-minor-mode-hook nil 748(defvar yas-minor-mode-hook nil
749 "Hook run when `yas-minor-mode' is turned on.") 749 "Hook run when `yas-minor-mode' is turned on.")
@@ -914,14 +914,39 @@ Honour `yas-dont-activate', which see."
914 914
915;;; Internal structs for template management 915;;; Internal structs for template management
916 916
917(defstruct (yas--template (:constructor yas--make-template)) 917(cl-defstruct (yas--template
918 (:constructor yas--make-template)
919 ;; Handles `yas-define-snippets' format, plus the
920 ;; initial TABLE argument.
921 (:constructor
922 yas--define-snippets-2
923 (table
924 key content
925 &optional xname condition group
926 expand-env load-file xkeybinding xuuid save-file
927 &aux
928 (name (or xname
929 ;; A little redundant: we always get a name
930 ;; from `yas--parse-template' except when
931 ;; there isn't a file.
932 (and load-file (file-name-nondirectory load-file))
933 (and save-file (file-name-nondirectory save-file))
934 key))
935 (keybinding (yas--read-keybinding xkeybinding))
936 (uuid (or xuuid name))
937 (old (gethash uuid (yas--table-uuidhash table)))
938 (menu-binding-pair
939 (and old (yas--template-menu-binding-pair old)))
940 (perm-group
941 (and old (yas--template-perm-group old))))))
918 "A template for a snippet." 942 "A template for a snippet."
919 key 943 key
920 content 944 content
921 name 945 name
922 condition 946 condition
923 expand-env 947 expand-env
924 file 948 load-file
949 save-file
925 keybinding 950 keybinding
926 uuid 951 uuid
927 menu-binding-pair 952 menu-binding-pair
@@ -1081,7 +1106,8 @@ keybinding)."
1081(defun yas--update-template (table template) 1106(defun yas--update-template (table template)
1082 "Add or update TEMPLATE in TABLE. 1107 "Add or update TEMPLATE in TABLE.
1083 1108
1084Also takes care of adding and updating to the associated menu." 1109Also takes care of adding and updating to the associated menu.
1110Return TEMPLATE."
1085 ;; Remove from table by uuid 1111 ;; Remove from table by uuid
1086 ;; 1112 ;;
1087 (yas--remove-template-by-uuid table (yas--template-uuid template)) 1113 (yas--remove-template-by-uuid table (yas--template-uuid template))
@@ -1090,7 +1116,8 @@ Also takes care of adding and updating to the associated menu."
1090 (yas--add-template table template) 1116 (yas--add-template table template)
1091 ;; Take care of the menu 1117 ;; Take care of the menu
1092 ;; 1118 ;;
1093 (yas--update-template-menu table template)) 1119 (yas--update-template-menu table template)
1120 template)
1094 1121
1095(defun yas--update-template-menu (table template) 1122(defun yas--update-template-menu (table template)
1096 "Update every menu-related for TEMPLATE." 1123 "Update every menu-related for TEMPLATE."
@@ -1245,7 +1272,8 @@ Returns (TEMPLATES START END). This function respects
1245 'again) 1272 'again)
1246 (setq methods (cdr methods)))) 1273 (setq methods (cdr methods))))
1247 (t 1274 (t
1248 (yas--warning "Warning invalid element %s in `yas-key-syntaxes'" method))) 1275 (setq methods (cdr methods))
1276 (yas--warning "Invalid element `%s' in `yas-key-syntaxes'" method)))
1249 (let ((possible-key (buffer-substring-no-properties (point) original))) 1277 (let ((possible-key (buffer-substring-no-properties (point) original)))
1250 (save-excursion 1278 (save-excursion
1251 (goto-char original) 1279 (goto-char original)
@@ -1384,7 +1412,7 @@ otherwise we attempt to calculate it from FILE.
1384 1412
1385Return a snippet-definition, i.e. a list 1413Return a snippet-definition, i.e. a list
1386 1414
1387 (KEY TEMPLATE NAME CONDITION GROUP VARS FILE KEYBINDING UUID) 1415 (KEY TEMPLATE NAME CONDITION GROUP VARS LOAD-FILE KEYBINDING UUID)
1388 1416
1389If the buffer contains a line of \"# --\" then the contents above 1417If the buffer contains a line of \"# --\" then the contents above
1390this line are ignored. Directives can set most of these with the syntax: 1418this line are ignored. Directives can set most of these with the syntax:
@@ -1548,6 +1576,9 @@ Optional PROMPT sets the prompt to use."
1548(defun yas-x-prompt (prompt choices &optional display-fn) 1576(defun yas-x-prompt (prompt choices &optional display-fn)
1549 "Display choices in a x-window prompt." 1577 "Display choices in a x-window prompt."
1550 (when (and window-system choices) 1578 (when (and window-system choices)
1579 ;; Let window position be recalculated to ensure that
1580 ;; `posn-at-point' returns non-nil.
1581 (redisplay)
1551 (or 1582 (or
1552 (x-popup-menu 1583 (x-popup-menu
1553 (if (fboundp 'posn-at-point) 1584 (if (fboundp 'posn-at-point)
@@ -1600,42 +1631,10 @@ Optional PROMPT sets the prompt to use."
1600 1631
1601(defun yas--define-snippets-1 (snippet snippet-table) 1632(defun yas--define-snippets-1 (snippet snippet-table)
1602 "Helper for `yas-define-snippets'." 1633 "Helper for `yas-define-snippets'."
1603 ;; X) Calculate some more defaults on the values returned by 1634 ;; Update the appropriate table. Also takes care of adding the
1604 ;; `yas--parse-template'. 1635 ;; key indicators in the templates menu entry, if any.
1605 ;; 1636 (yas--update-template
1606 (let* ((file (seventh snippet)) 1637 snippet-table (apply #'yas--define-snippets-2 snippet-table snippet)))
1607 (key (car snippet))
1608 (name (or (third snippet)
1609 (and file
1610 (file-name-directory file))))
1611 (condition (fourth snippet))
1612 (group (fifth snippet))
1613 (keybinding (yas--read-keybinding (eighth snippet)))
1614 (uuid (or (ninth snippet)
1615 name))
1616 (template (or (gethash uuid (yas--table-uuidhash snippet-table))
1617 (yas--make-template :uuid uuid
1618 :table snippet-table))))
1619 ;; X) populate the template object
1620 ;;
1621 (setf (yas--template-key template) key)
1622 (setf (yas--template-content template) (second snippet))
1623 (setf (yas--template-name template) (or name key))
1624 (setf (yas--template-group template) group)
1625 (setf (yas--template-condition template) condition)
1626 (setf (yas--template-expand-env template) (sixth snippet))
1627 (setf (yas--template-file template) (seventh snippet))
1628 (setf (yas--template-keybinding template) keybinding)
1629
1630 ;; X) Update this template in the appropriate table. This step
1631 ;; also will take care of adding the key indicators in the
1632 ;; templates menu entry, if any
1633 ;;
1634 (yas--update-template snippet-table template)
1635 ;; X) Return the template
1636 ;;
1637 ;;
1638 template))
1639 1638
1640(defun yas-define-snippets (mode snippets) 1639(defun yas-define-snippets (mode snippets)
1641 "Define SNIPPETS for MODE. 1640 "Define SNIPPETS for MODE.
@@ -1643,7 +1642,7 @@ Optional PROMPT sets the prompt to use."
1643SNIPPETS is a list of snippet definitions, each taking the 1642SNIPPETS is a list of snippet definitions, each taking the
1644following form 1643following form
1645 1644
1646 (KEY TEMPLATE NAME CONDITION GROUP EXPAND-ENV FILE KEYBINDING UUID) 1645 (KEY TEMPLATE NAME CONDITION GROUP EXPAND-ENV LOAD-FILE KEYBINDING UUID SAVE-FILE)
1647 1646
1648Within these, only KEY and TEMPLATE are actually mandatory. 1647Within these, only KEY and TEMPLATE are actually mandatory.
1649 1648
@@ -1668,10 +1667,13 @@ the current buffers contents."
1668 (let ((print-length nil)) 1667 (let ((print-length nil))
1669 (insert ";;; Snippet definitions:\n;;;\n") 1668 (insert ";;; Snippet definitions:\n;;;\n")
1670 (dolist (snippet snippets) 1669 (dolist (snippet snippets)
1671 ;; We omit file because the snippet will be loaded from 1670 ;; Fill in missing elements with nil.
1672 ;; the compiled file instead, so deleting or changing 1671 (setq snippet (append snippet (make-list (- 10 (length snippet)) nil)))
1673 ;; the original won't have any effect. 1672 ;; Move LOAD-FILE to SAVE-FILE because we will load from the
1674 (setcar (nthcdr 6 snippet) nil)) 1673 ;; compiled file, not LOAD-FILE.
1674 (let ((load-file (nth 6 snippet)))
1675 (setcar (nthcdr 6 snippet) nil)
1676 (setcar (nthcdr 9 snippet) load-file)))
1675 (insert (pp-to-string 1677 (insert (pp-to-string
1676 `(yas-define-snippets ',mode ',snippets))) 1678 `(yas-define-snippets ',mode ',snippets)))
1677 (insert "\n\n")) 1679 (insert "\n\n"))
@@ -1686,6 +1688,15 @@ the current buffers contents."
1686 1688
1687;;; Loading snippets from files 1689;;; Loading snippets from files
1688 1690
1691(defun yas--template-get-file (template)
1692 "Return TEMPLATE's LOAD-FILE or SAVE-FILE."
1693 (or (yas--template-load-file template)
1694 (let ((file (yas--template-save-file template)))
1695 (when file
1696 (yas--message 2 "%s has no load file, use save file, %s, instead."
1697 (yas--template-name template) file))
1698 file)))
1699
1689(defun yas--load-yas-setup-file (file) 1700(defun yas--load-yas-setup-file (file)
1690 (if (not yas--creating-compiled-snippets) 1701 (if (not yas--creating-compiled-snippets)
1691 ;; Normal case. 1702 ;; Normal case.
@@ -2292,6 +2303,14 @@ Honours `yas-choose-tables-first', `yas-choose-keys-first' and
2292 (remove-duplicates (mapcan #'yas--table-templates tables) 2303 (remove-duplicates (mapcan #'yas--table-templates tables)
2293 :test #'equal)))) 2304 :test #'equal))))
2294 2305
2306(defun yas--lookup-snippet-1 (name mode)
2307 "Get the snippet called NAME in MODE's tables."
2308 (let ((yas-choose-tables-first nil) ; avoid prompts
2309 (yas-choose-keys-first nil))
2310 (cl-find name (yas--all-templates
2311 (yas--get-snippet-tables mode))
2312 :key #'yas--template-name :test #'string=)))
2313
2295(defun yas-lookup-snippet (name &optional mode noerror) 2314(defun yas-lookup-snippet (name &optional mode noerror)
2296 "Get the snippet content for the snippet NAME in MODE's tables. 2315 "Get the snippet content for the snippet NAME in MODE's tables.
2297 2316
@@ -2300,11 +2319,7 @@ is non-nil, then don't signal an error if there isn't any snippet
2300called NAME. 2319called NAME.
2301 2320
2302Honours `yas-buffer-local-condition'." 2321Honours `yas-buffer-local-condition'."
2303 (let* ((yas-choose-tables-first nil) ; avoid prompts 2322 (let ((snippet (yas--lookup-snippet-1 name mode)))
2304 (yas-choose-keys-first nil)
2305 (snippet (cl-find name (yas--all-templates
2306 (yas--get-snippet-tables mode))
2307 :key #'yas--template-name :test #'string=)))
2308 (cond 2323 (cond
2309 (snippet (yas--template-content snippet)) 2324 (snippet (yas--template-content snippet))
2310 (noerror nil) 2325 (noerror nil)
@@ -2356,7 +2371,7 @@ visited file in `snippet-mode'."
2356 2371
2357(defun yas--visit-snippet-file-1 (template) 2372(defun yas--visit-snippet-file-1 (template)
2358 "Helper for `yas-visit-snippet-file'." 2373 "Helper for `yas-visit-snippet-file'."
2359 (let ((file (yas--template-file template))) 2374 (let ((file (yas--template-get-file template)))
2360 (cond ((and file (file-readable-p file)) 2375 (cond ((and file (file-readable-p file))
2361 (find-file-other-window file) 2376 (find-file-other-window file)
2362 (snippet-mode) 2377 (snippet-mode)
@@ -2530,7 +2545,7 @@ When called interactively, prompt for the table name."
2530 ;; template which is already loaded and neatly positioned,... 2545 ;; template which is already loaded and neatly positioned,...
2531 ;; 2546 ;;
2532 (yas--editing-template 2547 (yas--editing-template
2533 (yas--define-snippets-1 (yas--parse-template (yas--template-file yas--editing-template)) 2548 (yas--define-snippets-1 (yas--parse-template (yas--template-load-file yas--editing-template))
2534 (yas--template-table yas--editing-template))) 2549 (yas--template-table yas--editing-template)))
2535 ;; Try to use `yas--guessed-modes'. If we don't have that use the 2550 ;; Try to use `yas--guessed-modes'. If we don't have that use the
2536 ;; value from `yas--compute-major-mode-and-parents' 2551 ;; value from `yas--compute-major-mode-and-parents'
@@ -2560,28 +2575,27 @@ Don't use this from a Lisp program, call `yas-load-snippet-buffer'
2560and `kill-buffer' instead." 2575and `kill-buffer' instead."
2561 (interactive (list (yas--read-table) current-prefix-arg)) 2576 (interactive (list (yas--read-table) current-prefix-arg))
2562 (yas-load-snippet-buffer table t) 2577 (yas-load-snippet-buffer table t)
2563 (when (and (or 2578 (let ((file (yas--template-get-file yas--editing-template)))
2564 ;; Only offer to save this if it looks like a library or new 2579 (when (and (or
2565 ;; snippet (loaded from elisp, from a dir in `yas-snippet-dirs' 2580 ;; Only offer to save this if it looks like a library or new
2566 ;; which is not the first, or from an unwritable file) 2581 ;; snippet (loaded from elisp, from a dir in `yas-snippet-dirs'
2567 ;; 2582 ;; which is not the first, or from an unwritable file)
2568 (not (yas--template-file yas--editing-template)) 2583 ;;
2569 (not (file-writable-p (yas--template-file yas--editing-template))) 2584 (not file)
2570 (and (cdr-safe yas-snippet-dirs) 2585 (not (file-writable-p file))
2571 (not (string-prefix-p (expand-file-name (car yas-snippet-dirs)) 2586 (and (cdr-safe yas-snippet-dirs)
2572 (yas--template-file yas--editing-template))))) 2587 (not (string-prefix-p (expand-file-name (car yas-snippet-dirs)) file))))
2573 (y-or-n-p (yas--format "Looks like a library or new snippet. Save to new file? "))) 2588 (y-or-n-p (yas--format "Looks like a library or new snippet. Save to new file? ")))
2574 (let* ((option (first (yas--guess-snippet-directories (yas--template-table yas--editing-template)))) 2589 (let* ((option (first (yas--guess-snippet-directories (yas--template-table yas--editing-template))))
2575 (chosen (and option 2590 (chosen (and option
2576 (yas--make-directory-maybe option)))) 2591 (yas--make-directory-maybe option))))
2577 (when chosen 2592 (when chosen
2578 (let ((default-file-name (or (and (yas--template-file yas--editing-template) 2593 (let ((default-file-name (or (and file (file-name-nondirectory file))
2579 (file-name-nondirectory (yas--template-file yas--editing-template))) 2594 (yas--template-name yas--editing-template))))
2580 (yas--template-name yas--editing-template)))) 2595 (write-file (concat chosen "/"
2581 (write-file (concat chosen "/" 2596 (read-from-minibuffer (format "File name to create in %s? " chosen)
2582 (read-from-minibuffer (format "File name to create in %s? " chosen) 2597 default-file-name)))
2583 default-file-name))) 2598 (setf (yas--template-load-file yas--editing-template) buffer-file-name))))))
2584 (setf (yas--template-file yas--editing-template) buffer-file-name)))))
2585 (when buffer-file-name 2599 (when buffer-file-name
2586 (save-buffer) 2600 (save-buffer)
2587 (quit-window kill))) 2601 (quit-window kill)))
@@ -4003,11 +4017,10 @@ with their evaluated value into `yas--backquote-markers-and-strings'."
4003 (set-marker marker nil))))) 4017 (set-marker marker nil)))))
4004 4018
4005(defun yas--scan-sexps (from count) 4019(defun yas--scan-sexps (from count)
4006 (condition-case _ 4020 (ignore-errors
4021 (save-match-data ; `scan-sexps' may modify match data.
4007 (with-syntax-table (standard-syntax-table) 4022 (with-syntax-table (standard-syntax-table)
4008 (scan-sexps from count)) 4023 (scan-sexps from count)))))
4009 (error
4010 nil)))
4011 4024
4012(defun yas--make-marker (pos) 4025(defun yas--make-marker (pos)
4013 "Create a marker at POS with nil `marker-insertion-type'." 4026 "Create a marker at POS with nil `marker-insertion-type'."
@@ -4039,9 +4052,8 @@ When multiple expressions are found, only the last one counts."
4039 ;; after the ":", this will be 4052 ;; after the ":", this will be
4040 ;; caught as a mirror with 4053 ;; caught as a mirror with
4041 ;; transform later. 4054 ;; transform later.
4042 (not (save-match-data 4055 (not (string-match-p "\\`\\$[ \t\n]*("
4043 (eq (string-match "$[ \t\n]*(" 4056 (match-string-no-properties 2)))
4044 (match-string-no-properties 2)) 0)))
4045 ;; allow ${0: some exit text} 4057 ;; allow ${0: some exit text}
4046 ;; (not (and number (zerop number))) 4058 ;; (not (and number (zerop number)))
4047 (yas--make-field number 4059 (yas--make-field number