mirror of
https://github.com/joaotavora/yasnippet.git
synced 2025-10-13 21:13:04 +00:00
* More work on yas/load-snippet-buffer, more intuitive now.
This commit is contained in:
parent
dc47c98625
commit
94ca84751d
274
yasnippet.el
274
yasnippet.el
@ -54,7 +54,11 @@
|
|||||||
;; when used for bulk (re)loading of snippets (at startup or
|
;; when used for bulk (re)loading of snippets (at startup or
|
||||||
;; via `yas/reload-all'), directories appearing earlier in
|
;; via `yas/reload-all'), directories appearing earlier in
|
||||||
;; the list shadow other dir's snippets. Also, the first
|
;; the list shadow other dir's snippets. Also, the first
|
||||||
;; directory is taken as the default for storing the user's new snippets.
|
;; directory is taken as the default for storing the user's
|
||||||
|
;; new snippets.
|
||||||
|
;;
|
||||||
|
;; The deprecated `yas/root-directory' aliases this variable
|
||||||
|
;; for backward-compatibility.
|
||||||
;;
|
;;
|
||||||
;; `yas/extra-modes'
|
;; `yas/extra-modes'
|
||||||
;;
|
;;
|
||||||
@ -64,6 +68,9 @@
|
|||||||
;; `yas/snippet-dirs' and is used for deciding which
|
;; `yas/snippet-dirs' and is used for deciding which
|
||||||
;; snippets to consider for the active buffer.
|
;; snippets to consider for the active buffer.
|
||||||
;;
|
;;
|
||||||
|
;; Deprecated `yas/mode-symbol' aliases this variable for
|
||||||
|
;; backward-compatibility.
|
||||||
|
;;
|
||||||
;; Major commands are:
|
;; Major commands are:
|
||||||
;;
|
;;
|
||||||
;; M-x yas/expand
|
;; M-x yas/expand
|
||||||
@ -178,6 +185,8 @@ as the default for storing the user's new snippets."
|
|||||||
(unless (or (not (fboundp 'yas/reload-all))
|
(unless (or (not (fboundp 'yas/reload-all))
|
||||||
(equal old new))
|
(equal old new))
|
||||||
(yas/reload-all)))))
|
(yas/reload-all)))))
|
||||||
|
(defun yas/snippet-dirs ()
|
||||||
|
(if (listp yas/snippet-dirs) yas/snippet-dirs (list yas/snippet-dirs)))
|
||||||
(defvaralias 'yas/root-directory 'yas/snippet-dirs)
|
(defvaralias 'yas/root-directory 'yas/snippet-dirs)
|
||||||
|
|
||||||
(defcustom yas/prompt-functions '(yas/x-prompt
|
(defcustom yas/prompt-functions '(yas/x-prompt
|
||||||
@ -1221,10 +1230,9 @@ Can be a symbol or a list of symbols.
|
|||||||
|
|
||||||
This variable probably makes more sense as buffer-local, so
|
This variable probably makes more sense as buffer-local, so
|
||||||
ensure your use `make-local-variable' when you set it.")
|
ensure your use `make-local-variable' when you set it.")
|
||||||
(defvaralias 'yas/mode-symbol 'yas/extra-modes)
|
|
||||||
(defun yas/extra-modes ()
|
(defun yas/extra-modes ()
|
||||||
(if (listp yas/extra-modes) yas/extra-modes (list yas/extra-modes)))
|
(if (listp yas/extra-modes) yas/extra-modes (list yas/extra-modes)))
|
||||||
|
(defvaralias 'yas/mode-symbol 'yas/extra-modes)
|
||||||
|
|
||||||
(defun yas/table-get-create (mode)
|
(defun yas/table-get-create (mode)
|
||||||
"Get the snippet table corresponding to MODE.
|
"Get the snippet table corresponding to MODE.
|
||||||
@ -1254,19 +1262,18 @@ MODE-SYMBOL or `major-mode'.
|
|||||||
Guessing is done by looking up the MODE-SYMBOL's
|
Guessing is done by looking up the MODE-SYMBOL's
|
||||||
`derived-mode-parent' property, see also `derived-mode-p'."
|
`derived-mode-parent' property, see also `derived-mode-p'."
|
||||||
(let ((mode-tables
|
(let ((mode-tables
|
||||||
(mapcar #'(lambda (mode)
|
(remove nil
|
||||||
(gethash mode yas/tables))
|
(mapcar #'(lambda (mode)
|
||||||
(append (list mode-symbol)
|
(gethash mode yas/tables))
|
||||||
(yas/extra-modes)
|
(remove nil (append (list mode-symbol)
|
||||||
(list major-mode
|
(yas/extra-modes)
|
||||||
(and (not dont-search-parents)
|
(list major-mode
|
||||||
(get major-mode
|
(and (not dont-search-parents)
|
||||||
'derived-mode-parent))))))
|
(get major-mode
|
||||||
(all-tables))
|
'derived-mode-parent)))))))))
|
||||||
(dolist (table (remove nil mode-tables))
|
(remove-duplicates
|
||||||
(push table all-tables)
|
(append mode-tables
|
||||||
(nconc all-tables (yas/table-get-all-parents table)))
|
(mapcan #'yas/table-get-all-parents mode-tables)))))
|
||||||
(remove-duplicates all-tables)))
|
|
||||||
|
|
||||||
(defun yas/menu-keymap-get-create (table)
|
(defun yas/menu-keymap-get-create (table)
|
||||||
"Get or create the main menu keymap correspondong to MODE.
|
"Get or create the main menu keymap correspondong to MODE.
|
||||||
@ -1634,10 +1641,8 @@ content of the file is the template."
|
|||||||
"Reload the directories listed in `yas/snippet-dirs' or
|
"Reload the directories listed in `yas/snippet-dirs' or
|
||||||
prompt the user to select one."
|
prompt the user to select one."
|
||||||
(if yas/snippet-dirs
|
(if yas/snippet-dirs
|
||||||
(if (listp yas/snippet-dirs)
|
(dolist (directory (reverse (yas/snippet-dirs)))
|
||||||
(dolist (directory (reverse yas/snippet-dirs))
|
(yas/load-directory directory))
|
||||||
(yas/load-directory directory))
|
|
||||||
(yas/load-directory yas/snippet-dirs))
|
|
||||||
(call-interactively 'yas/load-directory)))
|
(call-interactively 'yas/load-directory)))
|
||||||
|
|
||||||
(defun yas/reload-all (&optional reset-root-directory)
|
(defun yas/reload-all (&optional reset-root-directory)
|
||||||
@ -1666,12 +1671,7 @@ content of the file is the template."
|
|||||||
;; Reload the directories listed in `yas/snippet-dirs' or prompt
|
;; Reload the directories listed in `yas/snippet-dirs' or prompt
|
||||||
;; the user to select one.
|
;; the user to select one.
|
||||||
;;
|
;;
|
||||||
(if yas/snippet-dirs
|
(yas/load-snippet-dirs)
|
||||||
(if (listp yas/snippet-dirs)
|
|
||||||
(dolist (directory (reverse yas/snippet-dirs))
|
|
||||||
(yas/load-directory directory))
|
|
||||||
(yas/load-directory yas/snippet-dirs))
|
|
||||||
(call-interactively 'yas/load-directory))
|
|
||||||
;; Reload the direct keybindings
|
;; Reload the direct keybindings
|
||||||
;;
|
;;
|
||||||
(yas/direct-keymaps-reload)
|
(yas/direct-keymaps-reload)
|
||||||
@ -2325,18 +2325,16 @@ all the possibly directories where snippets of table might be
|
|||||||
lurking."
|
lurking."
|
||||||
(let ((main-dir (replace-regexp-in-string
|
(let ((main-dir (replace-regexp-in-string
|
||||||
"/+$" ""
|
"/+$" ""
|
||||||
(or (and (listp yas/snippet-dirs)
|
(or (first (yas/snippet-dirs))
|
||||||
(first yas/snippet-dirs))
|
(setq yas/snippet-dirs '("~/.emacs.d/snippets")))))
|
||||||
yas/snippet-dirs
|
|
||||||
(setq yas/snippet-dirs "~/.emacs.d/snippets"))))
|
|
||||||
(tables (or (and table
|
(tables (or (and table
|
||||||
(list table))
|
(list table))
|
||||||
(yas/get-snippet-tables))))
|
(yas/get-snippet-tables))))
|
||||||
;; HACK! the snippet table created here is actually registered!
|
;; HACK! the snippet table created here is actually registered!
|
||||||
;;
|
;;
|
||||||
(unless (or table (gethash major-mode yas/tables))
|
(unless (or table (gethash major-mode yas/tables))
|
||||||
(setq tables (cons (yas/table-get-create major-mode)
|
(push (yas/table-get-create major-mode)
|
||||||
tables)))
|
tables))
|
||||||
|
|
||||||
(mapcar #'(lambda (table)
|
(mapcar #'(lambda (table)
|
||||||
(cons table
|
(cons table
|
||||||
@ -2374,7 +2372,7 @@ lurking."
|
|||||||
(erase-buffer)
|
(erase-buffer)
|
||||||
(set (make-local-variable 'yas/editing-template) nil)
|
(set (make-local-variable 'yas/editing-template) nil)
|
||||||
(snippet-mode)
|
(snippet-mode)
|
||||||
(set (make-local-variable 'yas/guessed-directories) guessed-directories)
|
(set (make-local-variable 'yas/guessed-modes) (mapcar #'car guessed-directories))
|
||||||
(unless (and choose-instead-of-guess
|
(unless (and choose-instead-of-guess
|
||||||
(not (y-or-n-p "Insert a snippet with useful headers? ")))
|
(not (y-or-n-p "Insert a snippet with useful headers? ")))
|
||||||
(yas/expand-snippet "\
|
(yas/expand-snippet "\
|
||||||
@ -2388,7 +2386,7 @@ lurking."
|
|||||||
$0"))))
|
$0"))))
|
||||||
|
|
||||||
(defun yas/find-snippets (&optional same-window )
|
(defun yas/find-snippets (&optional same-window )
|
||||||
"Look for user snippets in guessed current mode's directory.
|
"Find snippet file in guessed current mode's directory.
|
||||||
|
|
||||||
Calls `find-file' interactively in the guessed directory.
|
Calls `find-file' interactively in the guessed directory.
|
||||||
|
|
||||||
@ -2416,9 +2414,7 @@ there, otherwise, proposes to create the first option returned by
|
|||||||
(rest guessed-directories)))))
|
(rest guessed-directories)))))
|
||||||
(unless chosen
|
(unless chosen
|
||||||
(when (y-or-n-p "Having trouble... go to snippet root dir? ")
|
(when (y-or-n-p "Having trouble... go to snippet root dir? ")
|
||||||
(setq chosen (if (listp yas/snippet-dirs)
|
(setq chosen (first (yas/snippet-dirs)))))
|
||||||
(first yas/snippet-dirs)
|
|
||||||
yas/snippet-dirs))))
|
|
||||||
(if chosen
|
(if chosen
|
||||||
(let ((default-directory chosen))
|
(let ((default-directory chosen))
|
||||||
(setq buffer (call-interactively (if same-window
|
(setq buffer (call-interactively (if same-window
|
||||||
@ -2433,7 +2429,11 @@ there, otherwise, proposes to create the first option returned by
|
|||||||
|
|
||||||
(defun yas/compute-major-mode-and-parents (file &optional prompt-if-failed)
|
(defun yas/compute-major-mode-and-parents (file &optional prompt-if-failed)
|
||||||
(let* ((file-dir (and file
|
(let* ((file-dir (and file
|
||||||
(directory-file-name (or (locate-dominating-file file ".yas-make-groups")
|
(directory-file-name (or (some #'(lambda (special)
|
||||||
|
(locate-dominating-file file special))
|
||||||
|
'(".yas-setup.el"
|
||||||
|
".yas-make-groups"
|
||||||
|
".yas-parents"))
|
||||||
(directory-file-name (file-name-directory file))))))
|
(directory-file-name (file-name-directory file))))))
|
||||||
(parents-file-name (concat file-dir "/.yas-parents"))
|
(parents-file-name (concat file-dir "/.yas-parents"))
|
||||||
(major-mode-name (and file-dir
|
(major-mode-name (and file-dir
|
||||||
@ -2459,112 +2459,112 @@ there, otherwise, proposes to create the first option returned by
|
|||||||
(defvar yas/current-template nil
|
(defvar yas/current-template nil
|
||||||
"Holds the current template being expanded into a snippet.")
|
"Holds the current template being expanded into a snippet.")
|
||||||
|
|
||||||
(defvar yas/guessed-directories nil
|
(defvar yas/guessed-modes nil
|
||||||
"Supporting variable for `yas/load-snippet-buffer' and `yas/new-snippet'")
|
"List of guessed modes supporting `yas/load-snippet-buffer'.")
|
||||||
|
|
||||||
(defun yas/load-snippet-buffer (&optional kill)
|
(defun yas/load-snippet-buffer (&optional kill)
|
||||||
"Parse and load current buffer's snippet definition.
|
"Parse and load current buffer's snippet definition.
|
||||||
|
|
||||||
With optional prefix argument KILL quit the window and buffer."
|
With optional prefix argument KILL quit the window and buffer."
|
||||||
(interactive "P")
|
(interactive "P")
|
||||||
(cond
|
|
||||||
;; X) Option 1: We have `yas/editing-template', this buffer's
|
|
||||||
;; content comes from a template which is already loaded and
|
|
||||||
;; neatly positioned,...
|
|
||||||
;;
|
|
||||||
((and (boundp 'yas/editing-template)
|
|
||||||
yas/editing-template
|
|
||||||
(yas/template-p yas/editing-template))
|
|
||||||
|
|
||||||
(let ((parsed (yas/parse-template (yas/template-file yas/editing-template))))
|
(if (not (or yas/editing-template
|
||||||
;; ... just change its template, expand-env, condition, key,
|
yas/guessed-modes))
|
||||||
;; keybinding and name. The group cannot be changed.
|
;; X) Option 1: We have nothing to indicate where this snippet
|
||||||
(yas/populate-template yas/editing-template
|
;; belongs to, guess a mode-list from `buffer-file-name' and
|
||||||
:content (second parsed)
|
;; call `yas/load-snippet-buffer' again with `yas/guessed-modes'
|
||||||
:key (first parsed)
|
;; set to it. If not even `buffer-file-name' then use
|
||||||
:name (third parsed)
|
;; `yas/guessed-modes' set to 'just-prompt.
|
||||||
:condition (fourth parsed)
|
;;
|
||||||
:expand-env (sixth parsed)
|
(let* ((major-mode-and-parent (yas/compute-major-mode-and-parents buffer-file-name))
|
||||||
:keybinding (yas/read-keybinding (eighth parsed)))
|
(yas/ignore-filenames-as-triggers (or yas/ignore-filenames-as-triggers
|
||||||
(yas/update-template (yas/template-table yas/editing-template)
|
(and buffer-file-name
|
||||||
yas/editing-template)))
|
(locate-dominating-file
|
||||||
;; X) Option 2: We have `yas/guessed-directories', but no
|
buffer-file-name
|
||||||
;; `yas/editing-template', which probablt means this buffer's
|
".yas-ignore-filenames-as-triggers"))))
|
||||||
;; content comes from `yas/new-snippet' call. Prompt user for a
|
(yas/guessed-modes (or major-mode-and-parent
|
||||||
;; table, add the template to the table, then call
|
'just-prompt)))
|
||||||
;;
|
(yas/load-snippet-buffer kill))
|
||||||
((and (boundp 'yas/guessed-directories)
|
(cond
|
||||||
yas/guessed-directories)
|
;; X) Option 1: We have `yas/editing-template', this buffer's
|
||||||
(let* ((yas/prompt-functions '(yas/ido-prompt yas/completing-prompt))
|
;; content comes from a template which is already loaded and
|
||||||
(table (or (and yas/guessed-directories
|
;; neatly positioned,...
|
||||||
(y-or-n-p "Let yasnippet guess tables? ")
|
;;
|
||||||
(or (and (second yas/guessed-directories)
|
(yas/editing-template
|
||||||
(car (some #'(lambda (fn)
|
(let ((parsed (yas/parse-template (yas/template-file yas/editing-template))))
|
||||||
(funcall fn "Choose from guessed list of tables: "
|
;; ... just change its template, expand-env, condition, key,
|
||||||
guessed-directories
|
;; keybinding and name. The group cannot be changed.
|
||||||
#'(lambda (option)
|
(yas/populate-template yas/editing-template
|
||||||
(yas/table-name (car option)))))
|
:content (second parsed)
|
||||||
yas/prompt-functions)))
|
:key (first parsed)
|
||||||
(car (first yas/guessed-directories))))
|
:name (third parsed)
|
||||||
(yas/table-get-create (intern (read-from-minibuffer "Enter new/existing table: "))))))
|
:condition (fourth parsed)
|
||||||
(set (make-local-variable 'yas/editing-template)
|
:expand-env (sixth parsed)
|
||||||
(yas/define-snippets-1 (yas/parse-template buffer-file-name)
|
:keybinding (yas/read-keybinding (eighth parsed)))
|
||||||
table
|
(yas/update-template (yas/template-table yas/editing-template)
|
||||||
(and yas/use-menu (yas/menu-keymap-get-create table))))))
|
yas/editing-template)))
|
||||||
(;; X) Option 3: We have a file name, consider this a brand new
|
;; X) Option 2: We have `yas/guessed-modes', but no
|
||||||
;; snippet and calculate name, groups, etc from the current
|
;; `yas/editing-template', which probablt means this buffer's
|
||||||
;; file-name and buffer content
|
;; content comes from `yas/new-snippet' call. Prompt user for a
|
||||||
|
;; table, add the template to the table, then call
|
||||||
|
;;
|
||||||
|
(yas/guessed-modes
|
||||||
|
(if (eq yas/guessed-modes 'just-prompt)
|
||||||
|
(setq yas/guessed-modes nil))
|
||||||
|
(let* ((prompt (if (and (featurep 'ido)
|
||||||
|
ido-mode)
|
||||||
|
'ido-completing-read 'completing-read))
|
||||||
|
(table (yas/table-get-create
|
||||||
|
(intern
|
||||||
|
(funcall prompt (format "Choose or enter a table (yas guesses %s): "
|
||||||
|
(if yas/guessed-modes
|
||||||
|
(first yas/guessed-modes)
|
||||||
|
"nothing"))
|
||||||
|
(mapcar #'symbol-name yas/guessed-modes)
|
||||||
|
nil
|
||||||
|
nil
|
||||||
|
nil
|
||||||
|
nil
|
||||||
|
(if (first yas/guessed-modes)
|
||||||
|
(symbol-name (first yas/guessed-modes))))))))
|
||||||
|
(set (make-local-variable 'yas/editing-template)
|
||||||
|
(yas/define-snippets-1 (yas/parse-template buffer-file-name)
|
||||||
|
table
|
||||||
|
(and yas/use-menu (yas/menu-keymap-get-create table)))))))
|
||||||
|
;; Now, offer to save this shit
|
||||||
|
;;
|
||||||
|
;; 1) if `yas/snippet-dirs' is a list and its first element does not
|
||||||
|
;; match this template's file (i.e. this is a library snippet, not
|
||||||
|
;; a user snippet).
|
||||||
|
;;
|
||||||
|
;; 2) yas/editing-template comes from a file that we cannot write to...
|
||||||
;;
|
;;
|
||||||
buffer-file-name
|
|
||||||
(let ((major-mode-and-parent (yas/compute-major-mode-and-parents buffer-file-name)))
|
|
||||||
(if major-mode-and-parent
|
|
||||||
(let* ((yas/ignore-filenames-as-triggers (or yas/ignore-filenames-as-triggers
|
|
||||||
(locate-dominating-file buffer-file-name ".yas-ignore-filenames-as-triggers")))
|
|
||||||
(parsed (yas/parse-template buffer-file-name))
|
|
||||||
(name (and parsed
|
|
||||||
(third parsed))))
|
|
||||||
(when name
|
|
||||||
(set (make-local-variable 'yas/editing-template)
|
|
||||||
(yas/define-snippets (car major-mode-and-parent)
|
|
||||||
(list parsed)
|
|
||||||
(cdr major-mode-and-parent)))))
|
|
||||||
(message (format "[yas] Unknown major mode for snippet at %s" buffer-file-name)))))
|
|
||||||
(t
|
|
||||||
(message (format "[yas] This case not implemented yet"))))
|
|
||||||
;; Now, offer to save this shit
|
|
||||||
;;
|
|
||||||
;; 1) if `yas/snippet-dirs' is a list and its first element does not
|
|
||||||
;; match this template's file (i.e. this is a library snippet, not
|
|
||||||
;; a user snippet).
|
|
||||||
;;
|
|
||||||
;; 2) yas/editing-template comes from a file that we cannot write to...
|
|
||||||
;;
|
|
||||||
|
|
||||||
(when (or (not (yas/template-file yas/editing-template))
|
(when (or (not (yas/template-file yas/editing-template))
|
||||||
(not (file-writable-p (yas/template-file yas/editing-template)))
|
(not (file-writable-p (yas/template-file yas/editing-template)))
|
||||||
(and (listp yas/snippet-dirs)
|
(and (listp yas/snippet-dirs)
|
||||||
(second yas/snippet-dirs)
|
(second yas/snippet-dirs)
|
||||||
(not (string-match (expand-file-name (first yas/snippet-dirs))
|
(not (string-match (expand-file-name (first yas/snippet-dirs))
|
||||||
(yas/template-file yas/editing-template)))))
|
(yas/template-file yas/editing-template)))))
|
||||||
(set (make-local-variable 'yas/guessed-directories)
|
(set (make-local-variable 'yas/guessed-modes)
|
||||||
(yas/guess-snippet-directories (yas/template-table yas/editing-template)))
|
(yas/guess-snippet-directories (yas/template-table yas/editing-template)))
|
||||||
(when (y-or-n-p "[yas] Also save snippet buffer to new file? ")
|
(when (y-or-n-p "[yas] Also save snippet buffer to new file? ")
|
||||||
(let* ((option (first yas/guessed-directories))
|
(let* ((option (first yas/guessed-modes))
|
||||||
(chosen (and option
|
(chosen (and option
|
||||||
(yas/make-directory-maybe option))))
|
(yas/make-directory-maybe option))))
|
||||||
(when chosen
|
(when chosen
|
||||||
(let ((default-file-name (or (and (yas/template-file yas/editing-template)
|
(let ((default-file-name (or (and (yas/template-file yas/editing-template)
|
||||||
(file-name-nondirectory (yas/template-file yas/editing-template)))
|
(file-name-nondirectory (yas/template-file yas/editing-template)))
|
||||||
(yas/template-name yas/editing-template))))
|
(yas/template-name yas/editing-template))))
|
||||||
(write-file (concat chosen "/"
|
(write-file (concat chosen "/"
|
||||||
(read-from-minibuffer (format "File name to create in %s? " chosen)
|
(read-from-minibuffer (format "File name to create in %s? " chosen)
|
||||||
default-file-name)))
|
default-file-name)))
|
||||||
(setf (yas/template-file yas/editing-template) buffer-file-name))))))
|
(setf (yas/template-file yas/editing-template) buffer-file-name))))))
|
||||||
(when kill
|
(when kill
|
||||||
(quit-window kill))
|
(quit-window kill))
|
||||||
(message "[yas] Snippet \"%s\" loaded for %s."
|
(message "[yas] Snippet \"%s\" loaded for %s."
|
||||||
(yas/template-name yas/editing-template)
|
(yas/template-name yas/editing-template)
|
||||||
(yas/table-name (yas/template-table yas/editing-template))))
|
(yas/table-name (yas/template-table yas/editing-template)))))
|
||||||
|
|
||||||
|
|
||||||
(defun yas/tryout-snippet (&optional debug)
|
(defun yas/tryout-snippet (&optional debug)
|
||||||
@ -2575,8 +2575,8 @@ With optional prefix argument KILL quit the window and buffer."
|
|||||||
(test-mode (or (and (car major-mode-and-parent)
|
(test-mode (or (and (car major-mode-and-parent)
|
||||||
(fboundp (car major-mode-and-parent))
|
(fboundp (car major-mode-and-parent))
|
||||||
(car major-mode-and-parent))
|
(car major-mode-and-parent))
|
||||||
(and yas/guessed-directories
|
(and yas/guessed-modes
|
||||||
(intern (yas/table-name (car (first yas/guessed-directories)))))
|
(intern (yas/table-name (car (first yas/guessed-modes)))))
|
||||||
(intern (read-from-minibuffer "[yas] please input a mode: "))))
|
(intern (read-from-minibuffer "[yas] please input a mode: "))))
|
||||||
(yas/current-template
|
(yas/current-template
|
||||||
(and parsed
|
(and parsed
|
||||||
|
Loading…
x
Reference in New Issue
Block a user