From 991f8ff925f51fd5598db72885f8cca1a1a79bed Mon Sep 17 00:00:00 2001 From: Simeon Simeonov Date: Thu, 16 Jun 2016 09:07:53 +0200 Subject: Upgrade all modes, include snippets/html-mode, snippets/nxml-mode and snippets/prog-mode --- .emacs.d/lisp/yasnippet.el | 290 ++++++++++++++++++++++++++------------------- 1 file changed, 166 insertions(+), 124 deletions(-) (limited to '.emacs.d/lisp/yasnippet.el') diff --git a/.emacs.d/lisp/yasnippet.el b/.emacs.d/lisp/yasnippet.el index 3446060..5164754 100644 --- a/.emacs.d/lisp/yasnippet.el +++ b/.emacs.d/lisp/yasnippet.el @@ -5,7 +5,7 @@ ;; João Távora , ;; Noam Postavsky ;; Maintainer: Noam Postavsky -;; Version: 0.9.1 +;; Version: 0.10.0 ;; X-URL: http://github.com/capitaomorte/yasnippet ;; Keywords: convenience, emulation ;; URL: http://github.com/capitaomorte/yasnippet @@ -202,14 +202,12 @@ created with `yas-new-snippet'. " (t (error "[yas] invalid element %s in `yas-snippet-dirs'" e))))) -(defvaralias 'yas/root-directory 'yas-snippet-dirs) - (defcustom yas-new-snippet-default "\ # -*- mode: snippet -*- # name: $1 # key: ${2:${1:$(yas--key-from-desc yas-text)}} # -- -$0" +$0`yas-selected-text`" "Default snippet to use when creating a new snippet. If nil, don't use any snippet." :type 'string @@ -386,6 +384,12 @@ the trigger key itself." :type '(repeat function) :group 'yasnippet) +(defcustom yas-alias-to-yas/prefix-p t + "If non-nil make aliases for the old style yas/ prefixed symbols. +It must be set to nil before loading yasnippet to take effect." + :type 'boolean + :group 'yasnippet) + ;; Only two faces, and one of them shouldn't even be used... ;; (defface yas-field-highlight-face @@ -530,7 +534,7 @@ snippet itself contains a condition that returns the symbol ;;; Internal variables -(defvar yas--version "0.9.1") +(defconst yas--version "0.10.0") (defvar yas--menu-table (make-hash-table) "A hash table of MAJOR-MODE symbols to menu keymaps.") @@ -776,7 +780,7 @@ Key bindings: ;; The indicator for the mode line. " yas" :group 'yasnippet - (cond (yas-minor-mode + (cond ((and yas-minor-mode (featurep 'yasnippet)) ;; Install the direct keymaps in `emulation-mode-map-alists' ;; (we use `add-hook' even though it's not technically a hook, ;; but it works). Then define variables named after modes to @@ -884,7 +888,9 @@ Honour `yas-dont-activate-functions', which see." (defvar yas--font-lock-keywords (append '(("^#.*$" . font-lock-comment-face)) (with-temp-buffer - (ignore-errors (emacs-lisp-mode)) + (let ((prog-mode-hook nil) + (emacs-lisp-mode-hook nil)) + (ignore-errors (emacs-lisp-mode))) (font-lock-set-defaults) (if (eq t (car-safe font-lock-keywords)) ;; They're "compiled", so extract the source. @@ -1362,7 +1368,7 @@ return an expression that when evaluated will issue an error." (read-kbd-macro keybinding 'need-vector)))) res) (error - (yas--message 3 "warning: keybinding \"%s\" invalid since %s." + (yas--message 2 "warning: keybinding \"%s\" invalid since %s." keybinding (error-message-string err)) nil)))) @@ -1697,14 +1703,14 @@ the current buffers contents." (or (yas--template-load-file template) (let ((file (yas--template-save-file template))) (when file - (yas--message 2 "%s has no load file, use save file, %s, instead." + (yas--message 3 "%s has no load file, using save file, %s, instead." (yas--template-name template) file)) file))) (defun yas--load-yas-setup-file (file) (if (not yas--creating-compiled-snippets) ;; Normal case. - (load file 'noerror (<= yas-verbosity 2)) + (load file 'noerror (<= yas-verbosity 4)) (let ((elfile (concat file ".el"))) (when (file-exists-p elfile) (insert ";;; contents of the .yas-setup.el support file:\n;;;\n") @@ -1760,7 +1766,7 @@ With prefix argument USE-JIT do jit-loading of snippets." (cl-loop for buffer in (buffer-list) do (with-current-buffer buffer (when (eq major-mode mode-sym) - (yas--message 3 "Discovered there was already %s in %s" buffer mode-sym) + (yas--message 4 "Discovered there was already %s in %s" buffer mode-sym) (push buffer impatient-buffers))))))) ;; ...after TOP-LEVEL-DIR has been completely loaded, call ;; `yas--load-pending-jits' in these impatient buffers. @@ -1784,8 +1790,8 @@ With prefix argument USE-JIT do jit-loading of snippets." ;; Normal case. (unless (file-exists-p (expand-file-name ".yas-skip" directory)) (unless (and (load (expand-file-name ".yas-compiled-snippets" directory) 'noerror (<= yas-verbosity 3)) - (progn (yas--message 2 "Loaded compiled snippets from %s" directory) t)) - (yas--message 2 "Loading snippet files from %s" directory) + (progn (yas--message 4 "Loaded compiled snippets from %s" directory) t)) + (yas--message 4 "Loading snippet files from %s" directory) (yas--load-directory-2 directory mode-sym))))) (defun yas--load-directory-2 (directory mode-sym) @@ -1799,7 +1805,10 @@ With prefix argument USE-JIT do jit-loading of snippets." (with-temp-buffer (dolist (file (yas--subdirs directory 'no-subdirs-just-files)) (when (file-readable-p file) - (insert-file-contents file nil nil nil t) + ;; Erase the buffer instead of passing non-nil REPLACE to + ;; `insert-file-contents' (avoids Emacs bug #23659). + (erase-buffer) + (insert-file-contents file) (push (yas--parse-template file) snippet-defs)))) (when snippet-defs @@ -1823,8 +1832,8 @@ prompt the user to select one." (cond ((file-directory-p directory) (yas-load-directory directory (not nojit)) (if nojit - (yas--message 3 "Loaded %s" directory) - (yas--message 3 "Prepared just-in-time loading for %s" directory))) + (yas--message 4 "Loaded %s" directory) + (yas--message 4 "Prepared just-in-time loading for %s" directory))) (t (push (yas--message 0 "Check your `yas-snippet-dirs': %s is not a directory" directory) errors))))) errors)) @@ -1889,9 +1898,9 @@ prefix argument." (yas-direct-keymaps-reload) (run-hooks 'yas-after-reload-hook) - (yas--message 3 "Reloaded everything%s...%s." - (if no-jit "" " (snippets will load just-in-time)") - (if errors " (some errors, check *Messages*)" ""))))) + (yas--message (if errors 2 3) "Reloaded everything%s...%s." + (if no-jit "" " (snippets will load just-in-time)") + (if errors " (some errors, check *Messages*)" ""))))) (defvar yas-after-reload-hook nil "Hooks run after `yas-reload-all'.") @@ -1901,7 +1910,7 @@ prefix argument." (let ((funs (reverse (gethash mode yas--scheduled-jit-loads)))) ;; must reverse to maintain coherence with `yas-snippet-dirs' (dolist (fun funs) - (yas--message 3 "Loading for `%s', just-in-time: %s!" mode fun) + (yas--message 4 "Loading for `%s', just-in-time: %s!" mode fun) (funcall fun)) (remhash mode yas--scheduled-jit-loads)))) @@ -2096,7 +2105,7 @@ omitted from MODE's menu, even if they're manually loaded." (define-key menu-keymap (vector (gensym)) '(menu-item "----"))) (t - (yas--message 3 "Don't know anything about menu entry %s" (first e)))))) + (yas--message 1 "Don't know anything about menu entry %s" (first e)))))) (defun yas--define (mode key template &optional name condition group) "Define a snippet. Expanding KEY into TEMPLATE. @@ -2359,7 +2368,7 @@ by condition." (car where) (cdr where) (yas--template-expand-env yas--current-template)) - (yas--message 3 "No snippets can be inserted here!")))) + (yas--message 1 "No snippets can be inserted here!")))) (defun yas-visit-snippet-file () "Choose a snippet to edit, selection like `yas-insert-snippet'. @@ -2467,7 +2476,11 @@ where snippets of table might exist." Expands a snippet-writing snippet, unless the optional prefix arg NO-TEMPLATE is non-nil." (interactive "P") - (let ((guessed-directories (yas--guess-snippet-directories))) + (let ((guessed-directories (yas--guess-snippet-directories)) + (yas-selected-text (or yas-selected-text + (and (region-active-p) + (buffer-substring-no-properties + (region-beginning) (region-end)))))) (switch-to-buffer "*new snippet*") (erase-buffer) @@ -2542,10 +2555,8 @@ neither do the elements of PARENTS." (defun yas-load-snippet-buffer (table &optional interactive) "Parse and load current buffer's snippet definition into TABLE. - -TABLE is a symbol naming a passed to `yas--table-get-create'. - -When called interactively, prompt for the table name." +TABLE is a symbol name passed to `yas--table-get-create'. When +called interactively, prompt for the table name." (interactive (list (yas--read-table) t)) (cond ;; We have `yas--editing-template', this buffer's content comes from a @@ -2570,11 +2581,10 @@ When called interactively, prompt for the table name." (yas--table-name (yas--template-table yas--editing-template))))) (defun yas-load-snippet-buffer-and-close (table &optional kill) - "Load the snippet with `yas-load-snippet-buffer', possibly - save, then `quit-window' if saved. - -If the snippet is new, ask the user whether (and where) to save -it. If the snippet already has a file, just save it. + "Load and save the snippet, then `quit-window' if saved. +Loading is performed by `yas-load-snippet-buffer'. If the +snippet is new, ask the user whether (and where) to save it. If +the snippet already has a file, just save it. The prefix argument KILL is passed to `quit-window'. @@ -2642,7 +2652,7 @@ and `kill-buffer' instead." (require 'yasnippet-debug nil t)) (add-hook 'post-command-hook 'yas-debug-snippet-vars nil t)))) (t - (yas--message 3 "Cannot test snippet for unknown major mode"))))) + (yas--message 1 "Cannot test snippet for unknown major mode"))))) (defun yas-active-keys () "Return all active trigger keys for current buffer and point." @@ -2654,58 +2664,49 @@ and `kill-buffer' instead." (car (last (or (yas--template-group template) (yas--template-perm-group template))))) -(defun yas-describe-tables (&optional choose) +(defun yas-describe-table-by-namehash () + "Display snippet tables by NAMEHASH." + (interactive) + (with-current-buffer (get-buffer-create "*YASnippet Tables by NAMEHASH*") + (let ((inhibit-read-only t)) + (erase-buffer) + (insert "YASnippet tables by NAMEHASH: \n") + (maphash + (lambda (_mode table) + (insert (format "\nSnippet table `%s':\n\n" (yas--table-name table))) + (maphash + (lambda (key _v) + (insert (format " key %s maps snippets: %s\n" key + (let ((names)) + (maphash #'(lambda (k _v) + (push k names)) + (gethash key (yas--table-hash table))) + names)))) + (yas--table-hash table))) + yas--tables)) + (view-mode +1) + (goto-char 1) + (display-buffer (current-buffer)))) + +(defun yas-describe-tables (&optional with-nonactive) "Display snippets for each table." (interactive "P") - (let* ((by-name-hash (and choose - (y-or-n-p "Show by namehash? "))) - (buffer (get-buffer-create "*YASnippet tables*")) - (active-tables (yas--get-snippet-tables)) - (remain-tables (let ((all)) - (maphash #'(lambda (_k v) - (unless (find v active-tables) - (push v all))) - yas--tables) - all)) - (table-lists (list active-tables remain-tables)) - (original-buffer (current-buffer)) - (continue t) - (yas--condition-cache-timestamp (current-time))) - (with-current-buffer buffer - (setq buffer-read-only nil) - (erase-buffer) - (cond ((not by-name-hash) - (insert "YASnippet tables:\n") - (while (and table-lists - continue) - (dolist (table (car table-lists)) - (yas--describe-pretty-table table original-buffer)) - (setq table-lists (cdr table-lists)) - (when table-lists - (yas--create-snippet-xrefs) - (display-buffer buffer) - (setq continue (and choose (y-or-n-p "Show also non-active tables? "))))) - (yas--create-snippet-xrefs) - (help-mode) - (goto-char 1)) - (t - (insert "\n\nYASnippet tables by NAMEHASH: \n") - (dolist (table (append active-tables remain-tables)) - (insert (format "\nSnippet table `%s':\n\n" (yas--table-name table))) - (let ((keys)) - (maphash #'(lambda (k _v) - (push k keys)) - (yas--table-hash table)) - (dolist (key keys) - (insert (format " key %s maps snippets: %s\n" key - (let ((names)) - (maphash #'(lambda (k _v) - (push k names)) - (gethash key (yas--table-hash table))) - names)))))))) - (goto-char 1) - (setq buffer-read-only t)) - (display-buffer buffer))) + (let ((original-buffer (current-buffer)) + (tables (yas--get-snippet-tables))) + (with-current-buffer (get-buffer-create "*YASnippet Tables*") + (let ((inhibit-read-only t)) + (when with-nonactive + (maphash #'(lambda (_k v) + (cl-pushnew v tables)) + yas--tables)) + (erase-buffer) + (insert "YASnippet tables:\n") + (dolist (table tables) + (yas--describe-pretty-table table original-buffer)) + (yas--create-snippet-xrefs)) + (help-mode) + (goto-char 1) + (display-buffer (current-buffer))))) (defun yas--describe-pretty-table (table &optional original-buffer) (insert (format "\nSnippet table `%s'" @@ -2969,7 +2970,6 @@ If there is a transform but it returns nil, return the empty string iff EMPTY-ON-NIL-P is true." (let* ((yas-text (yas--field-text-for-display field)) (yas-modified-p (yas--field-modified-p field)) - (yas-moving-away-p nil) (transform (if (yas--mirror-p field-or-mirror) (yas--mirror-transform field-or-mirror) (yas--field-transform field-or-mirror))) @@ -3098,13 +3098,11 @@ If there's none, exit the snippet." (let* ((snippet (car (yas--snippets-at-point))) (active-field (overlay-get yas--active-field-overlay 'yas--field)) (target-field (yas--find-next-field arg snippet active-field))) - ;; First check if we're moving out of a field with a transform. - (when (and active-field (yas--field-transform active-field)) - (let* ((yas-moving-away-p t) - (yas-text (yas--field-text-for-display active-field)) - (yas-modified-p (yas--field-modified-p active-field))) - ;; primary field transform: exit call to field-transform - (yas--eval-lisp (yas--field-transform active-field)))) + ;; Apply transform to active field. + (when active-field + (let ((yas-moving-away-p t)) + (when (yas--field-update-display active-field) + (yas--update-mirrors snippet)))) ;; Now actually move... (if target-field (yas--move-to-field snippet target-field) @@ -3225,7 +3223,7 @@ This renders the snippet as ordinary text." (condition-case error (run-hooks hook-var) (error - (yas--message 3 "%s error: %s" hook-var (error-message-string error))))) + (yas--message 2 "%s error: %s" hook-var (error-message-string error))))) (defun yas--check-commit-snippet () @@ -3483,7 +3481,7 @@ Move the overlays, or create them if they do not exit." (= length (- end beg)) ; deletion or insertion (yas--undo-in-progress)) (let ((snippets (yas--snippets-at-point))) - (yas--message 3 "Comitting snippets. Action would destroy a protection overlay.") + (yas--message 2 "Committing snippets. Action would destroy a protection overlay.") (cl-loop for snippet in snippets do (yas--commit-snippet snippet))))) @@ -3572,14 +3570,21 @@ considered when expanding the snippet." ;; them mostly to make the undo information ;; (setq yas--start-column (current-column)) - (let ((yas--inhibit-overlay-hooks t)) + (let ((yas--inhibit-overlay-hooks t) + ;; Avoid major-mode's syntax propertizing function, + ;; since we mess with the syntax-table and also + ;; insert things that are not valid in the + ;; major-mode language syntax anyway. + (syntax-propertize-function nil)) (setq snippet (if expand-env (eval `(let* ,expand-env (insert content) (yas--snippet-create start (point)))) (insert content) - (yas--snippet-create start (point)))))) + (yas--snippet-create start (point))))) + ;; Invalidate any syntax-propertizing done while `syntax-propertize-function' was nil + (syntax-ppss-flush-cache start)) ;; stacked-expansion: This checks for stacked expansion, save the ;; `yas--previous-active-field' and advance its boundary. @@ -3619,7 +3624,7 @@ considered when expanding the snippet." (when first-field (sit-for 0) ;; fix issue 125 (yas--move-to-field snippet first-field))) - (yas--message 3 "snippet expanded.") + (yas--message 4 "snippet expanded.") t)))) (defun yas--take-care-of-redo (_beg _end snippet) @@ -3826,6 +3831,9 @@ cons cells to this var.") backquoted Lisp expressions should be inserted at the end of expansion.") +(defvar yas--indent-markers nil + "List of markers for manual indentation.") + (defun yas--snippet-parse-create (snippet) "Parse a recently inserted snippet template, creating all necessary fields, mirrors and exit points. @@ -3845,6 +3853,9 @@ Meant to be called in a narrowed buffer, does various passes" ;; protect escaped characters ;; (yas--protect-escapes) + ;; Parse indent markers: `$>'. + (goto-char parse-start) + (yas--indent-parse-create snippet) ;; parse fields with {} ;; (goto-char parse-start) @@ -3918,7 +3929,8 @@ The SNIPPET's markers are preserved." (goto-char from) (save-restriction (widen) - (cl-loop do + ;; Indent each non-empty line. + (cl-loop if (/= (line-beginning-position) (line-end-position)) do (back-to-indentation) (let ((trouble-markers ; The markers at (point). (cl-remove (point) snippet-markers :test #'/=))) @@ -3931,14 +3943,17 @@ The SNIPPET's markers are preserved." (defvar yas--indent-original-column nil) (defun yas--indent (snippet) - ;; Look for those `$>'. + ;; Indent lines that had indent markers (`$>') on them. (save-excursion - (while (re-search-forward "$>" nil t) - (delete-region (match-beginning 0) (match-end 0)) + (dolist (marker yas--indent-markers) (unless (eq yas-indent-line 'auto) + (goto-char marker) (yas--indent-region (line-beginning-position) (line-end-position) - snippet)))) + snippet)) + ;; Finished with this marker. + (set-marker marker nil)) + (setq yas--indent-markers nil)) ;; Now do stuff for `fixed' and `auto'. (save-excursion (cond ((eq yas-indent-line 'fixed) @@ -4002,20 +4017,34 @@ With optional string TEXT do it in string instead of the buffer." (defun yas--save-backquotes () "Save all the \"`(lisp-expression)`\"-style expressions with their evaluated value into `yas--backquote-markers-and-strings'." - (while (re-search-forward yas--backquote-lisp-expression-regexp nil t) - (let ((current-string (match-string-no-properties 1)) transformed) - (save-restriction (widen) - (delete-region (match-beginning 0) (match-end 0))) - (setq transformed (yas--eval-lisp (yas--read-lisp (yas--restore-escapes current-string '(?`))))) - (goto-char (match-beginning 0)) - (when transformed - (let ((marker (make-marker))) - (save-restriction - (widen) - (insert "Y") ;; quite horrendous, I love it :) - (set-marker marker (point)) - (insert "Y")) - (push (cons marker transformed) yas--backquote-markers-and-strings)))))) + ;; Gather `(lisp-expression)`s. + (let ((end (point-max))) + (save-restriction + (widen) + (while (re-search-forward yas--backquote-lisp-expression-regexp end t) + (let ((expr (yas--read-lisp (yas--restore-escapes + (match-string-no-properties 1)))) + (marker (make-marker))) + (delete-region (match-beginning 0) (match-end 0)) + (insert "Y") ;; quite horrendous, I love it :) + (set-marker marker (point)) + (insert "Y") + (push (cons marker expr) yas--backquote-markers-and-strings))))) + ;; Evaluate them. + (dolist (m-e yas--backquote-markers-and-strings) + (let* ((marker (car m-e)) + (expr (cdr m-e)) + (result (save-excursion + (goto-char marker) + (yas--eval-lisp expr)))) + (setcdr m-e result) + (unless result + (save-restriction (widen) + (delete-region (1- marker) (1+ marker))) + (set-marker marker nil)))) + ;; Drop the nil results. + (setq yas--backquote-markers-and-strings + (cl-delete-if-not #'cdr yas--backquote-markers-and-strings))) (defun yas--restore-backquotes () "Replace markers in `yas--backquote-markers-and-strings' with their values." @@ -4044,6 +4073,16 @@ with their evaluated value into `yas--backquote-markers-and-strings'." (set-marker-insertion-type marker nil) marker)) +(defun yas--indent-parse-create (snippet) + "Parse the \"$>\" indentation markers in SNIPPET." + (setq yas--indent-markers ()) + (while (search-forward "$>" nil t) + (delete-region (match-beginning 0) (match-end 0)) + ;; Mark the beginning of the line. + (push (yas--make-marker (line-beginning-position)) + yas--indent-markers)) + (setq yas--indent-markers (nreverse yas--indent-markers))) + (defun yas--field-parse-create (snippet &optional parent-field) "Parse most field expressions in SNIPPET, except for the simple one \"$n\". @@ -4384,7 +4423,7 @@ object satisfying `yas--field-p' to restrict the expansion to."))) ;;; Utils -(defvar yas-verbosity 4 +(defvar yas-verbosity 3 "Log level for `yas--message' 4 means trace most anything, 0 means nothing.") (defun yas--message (level message &rest args) @@ -4575,14 +4614,17 @@ and return the directory. Return nil if not found." They are mapped to \"yas/*\" variants.") -(dolist (sym yas--backported-syms) - (let ((backported (intern (replace-regexp-in-string "\\`yas-" "yas/" (symbol-name sym))))) - (when (boundp sym) - (make-obsolete-variable backported sym "yasnippet 0.8") - (defvaralias backported sym)) - (when (fboundp sym) - (make-obsolete backported sym "yasnippet 0.8") - (defalias backported sym)))) +(when yas-alias-to-yas/prefix-p + (dolist (sym yas--backported-syms) + (let ((backported (intern (replace-regexp-in-string "\\`yas-" "yas/" (symbol-name sym))))) + (when (boundp sym) + (make-obsolete-variable backported sym "yasnippet 0.8") + (defvaralias backported sym)) + (when (fboundp sym) + (make-obsolete backported sym "yasnippet 0.8") + (defalias backported sym)))) + (make-obsolete 'yas/root-directory 'yas-snippet-dirs "yasnippet 0.8") + (defvaralias 'yas/root-directory 'yas-snippet-dirs)) (defvar yas--exported-syms (let (exported) -- cgit v1.3