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
|
||||
;; via `yas/reload-all'), directories appearing earlier in
|
||||
;; 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'
|
||||
;;
|
||||
@ -64,6 +68,9 @@
|
||||
;; `yas/snippet-dirs' and is used for deciding which
|
||||
;; snippets to consider for the active buffer.
|
||||
;;
|
||||
;; Deprecated `yas/mode-symbol' aliases this variable for
|
||||
;; backward-compatibility.
|
||||
;;
|
||||
;; Major commands are:
|
||||
;;
|
||||
;; 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))
|
||||
(equal old new))
|
||||
(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)
|
||||
|
||||
(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
|
||||
ensure your use `make-local-variable' when you set it.")
|
||||
(defvaralias 'yas/mode-symbol 'yas/extra-modes)
|
||||
(defun 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)
|
||||
"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
|
||||
`derived-mode-parent' property, see also `derived-mode-p'."
|
||||
(let ((mode-tables
|
||||
(mapcar #'(lambda (mode)
|
||||
(gethash mode yas/tables))
|
||||
(append (list mode-symbol)
|
||||
(yas/extra-modes)
|
||||
(list major-mode
|
||||
(and (not dont-search-parents)
|
||||
(get major-mode
|
||||
'derived-mode-parent))))))
|
||||
(all-tables))
|
||||
(dolist (table (remove nil mode-tables))
|
||||
(push table all-tables)
|
||||
(nconc all-tables (yas/table-get-all-parents table)))
|
||||
(remove-duplicates all-tables)))
|
||||
(remove nil
|
||||
(mapcar #'(lambda (mode)
|
||||
(gethash mode yas/tables))
|
||||
(remove nil (append (list mode-symbol)
|
||||
(yas/extra-modes)
|
||||
(list major-mode
|
||||
(and (not dont-search-parents)
|
||||
(get major-mode
|
||||
'derived-mode-parent)))))))))
|
||||
(remove-duplicates
|
||||
(append mode-tables
|
||||
(mapcan #'yas/table-get-all-parents mode-tables)))))
|
||||
|
||||
(defun yas/menu-keymap-get-create (table)
|
||||
"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
|
||||
prompt the user to select one."
|
||||
(if yas/snippet-dirs
|
||||
(if (listp yas/snippet-dirs)
|
||||
(dolist (directory (reverse yas/snippet-dirs))
|
||||
(yas/load-directory directory))
|
||||
(yas/load-directory yas/snippet-dirs))
|
||||
(dolist (directory (reverse (yas/snippet-dirs)))
|
||||
(yas/load-directory directory))
|
||||
(call-interactively 'yas/load-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
|
||||
;; the user to select one.
|
||||
;;
|
||||
(if yas/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))
|
||||
(yas/load-snippet-dirs)
|
||||
;; Reload the direct keybindings
|
||||
;;
|
||||
(yas/direct-keymaps-reload)
|
||||
@ -2325,18 +2325,16 @@ all the possibly directories where snippets of table might be
|
||||
lurking."
|
||||
(let ((main-dir (replace-regexp-in-string
|
||||
"/+$" ""
|
||||
(or (and (listp yas/snippet-dirs)
|
||||
(first yas/snippet-dirs))
|
||||
yas/snippet-dirs
|
||||
(setq yas/snippet-dirs "~/.emacs.d/snippets"))))
|
||||
(or (first (yas/snippet-dirs))
|
||||
(setq yas/snippet-dirs '("~/.emacs.d/snippets")))))
|
||||
(tables (or (and table
|
||||
(list table))
|
||||
(yas/get-snippet-tables))))
|
||||
;; HACK! the snippet table created here is actually registered!
|
||||
;;
|
||||
(unless (or table (gethash major-mode yas/tables))
|
||||
(setq tables (cons (yas/table-get-create major-mode)
|
||||
tables)))
|
||||
(push (yas/table-get-create major-mode)
|
||||
tables))
|
||||
|
||||
(mapcar #'(lambda (table)
|
||||
(cons table
|
||||
@ -2374,7 +2372,7 @@ lurking."
|
||||
(erase-buffer)
|
||||
(set (make-local-variable 'yas/editing-template) nil)
|
||||
(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
|
||||
(not (y-or-n-p "Insert a snippet with useful headers? ")))
|
||||
(yas/expand-snippet "\
|
||||
@ -2388,7 +2386,7 @@ lurking."
|
||||
$0"))))
|
||||
|
||||
(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.
|
||||
|
||||
@ -2416,9 +2414,7 @@ there, otherwise, proposes to create the first option returned by
|
||||
(rest guessed-directories)))))
|
||||
(unless chosen
|
||||
(when (y-or-n-p "Having trouble... go to snippet root dir? ")
|
||||
(setq chosen (if (listp yas/snippet-dirs)
|
||||
(first yas/snippet-dirs)
|
||||
yas/snippet-dirs))))
|
||||
(setq chosen (first (yas/snippet-dirs)))))
|
||||
(if chosen
|
||||
(let ((default-directory chosen))
|
||||
(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)
|
||||
(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))))))
|
||||
(parents-file-name (concat file-dir "/.yas-parents"))
|
||||
(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
|
||||
"Holds the current template being expanded into a snippet.")
|
||||
|
||||
(defvar yas/guessed-directories nil
|
||||
"Supporting variable for `yas/load-snippet-buffer' and `yas/new-snippet'")
|
||||
(defvar yas/guessed-modes nil
|
||||
"List of guessed modes supporting `yas/load-snippet-buffer'.")
|
||||
|
||||
(defun yas/load-snippet-buffer (&optional kill)
|
||||
"Parse and load current buffer's snippet definition.
|
||||
|
||||
With optional prefix argument KILL quit the window and buffer."
|
||||
(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))))
|
||||
;; ... just change its template, expand-env, condition, key,
|
||||
;; keybinding and name. The group cannot be changed.
|
||||
(yas/populate-template yas/editing-template
|
||||
:content (second parsed)
|
||||
:key (first parsed)
|
||||
:name (third parsed)
|
||||
:condition (fourth parsed)
|
||||
:expand-env (sixth parsed)
|
||||
:keybinding (yas/read-keybinding (eighth parsed)))
|
||||
(yas/update-template (yas/template-table yas/editing-template)
|
||||
yas/editing-template)))
|
||||
;; X) Option 2: We have `yas/guessed-directories', but no
|
||||
;; `yas/editing-template', which probablt means this buffer's
|
||||
;; content comes from `yas/new-snippet' call. Prompt user for a
|
||||
;; table, add the template to the table, then call
|
||||
;;
|
||||
((and (boundp 'yas/guessed-directories)
|
||||
yas/guessed-directories)
|
||||
(let* ((yas/prompt-functions '(yas/ido-prompt yas/completing-prompt))
|
||||
(table (or (and yas/guessed-directories
|
||||
(y-or-n-p "Let yasnippet guess tables? ")
|
||||
(or (and (second yas/guessed-directories)
|
||||
(car (some #'(lambda (fn)
|
||||
(funcall fn "Choose from guessed list of tables: "
|
||||
guessed-directories
|
||||
#'(lambda (option)
|
||||
(yas/table-name (car option)))))
|
||||
yas/prompt-functions)))
|
||||
(car (first yas/guessed-directories))))
|
||||
(yas/table-get-create (intern (read-from-minibuffer "Enter new/existing table: "))))))
|
||||
(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))))))
|
||||
(;; X) Option 3: We have a file name, consider this a brand new
|
||||
;; snippet and calculate name, groups, etc from the current
|
||||
;; file-name and buffer content
|
||||
(if (not (or yas/editing-template
|
||||
yas/guessed-modes))
|
||||
;; X) Option 1: We have nothing to indicate where this snippet
|
||||
;; belongs to, guess a mode-list from `buffer-file-name' and
|
||||
;; call `yas/load-snippet-buffer' again with `yas/guessed-modes'
|
||||
;; set to it. If not even `buffer-file-name' then use
|
||||
;; `yas/guessed-modes' set to 'just-prompt.
|
||||
;;
|
||||
(let* ((major-mode-and-parent (yas/compute-major-mode-and-parents buffer-file-name))
|
||||
(yas/ignore-filenames-as-triggers (or yas/ignore-filenames-as-triggers
|
||||
(and buffer-file-name
|
||||
(locate-dominating-file
|
||||
buffer-file-name
|
||||
".yas-ignore-filenames-as-triggers"))))
|
||||
(yas/guessed-modes (or major-mode-and-parent
|
||||
'just-prompt)))
|
||||
(yas/load-snippet-buffer kill))
|
||||
(cond
|
||||
;; X) Option 1: We have `yas/editing-template', this buffer's
|
||||
;; content comes from a template which is already loaded and
|
||||
;; neatly positioned,...
|
||||
;;
|
||||
(yas/editing-template
|
||||
(let ((parsed (yas/parse-template (yas/template-file yas/editing-template))))
|
||||
;; ... just change its template, expand-env, condition, key,
|
||||
;; keybinding and name. The group cannot be changed.
|
||||
(yas/populate-template yas/editing-template
|
||||
:content (second parsed)
|
||||
:key (first parsed)
|
||||
:name (third parsed)
|
||||
:condition (fourth parsed)
|
||||
:expand-env (sixth parsed)
|
||||
:keybinding (yas/read-keybinding (eighth parsed)))
|
||||
(yas/update-template (yas/template-table yas/editing-template)
|
||||
yas/editing-template)))
|
||||
;; X) Option 2: We have `yas/guessed-modes', but no
|
||||
;; `yas/editing-template', which probablt means this buffer's
|
||||
;; 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))
|
||||
(not (file-writable-p (yas/template-file yas/editing-template)))
|
||||
(and (listp yas/snippet-dirs)
|
||||
(second yas/snippet-dirs)
|
||||
(not (string-match (expand-file-name (first yas/snippet-dirs))
|
||||
(yas/template-file yas/editing-template)))))
|
||||
(set (make-local-variable 'yas/guessed-directories)
|
||||
(yas/guess-snippet-directories (yas/template-table yas/editing-template)))
|
||||
(when (y-or-n-p "[yas] Also save snippet buffer to new file? ")
|
||||
(let* ((option (first yas/guessed-directories))
|
||||
(chosen (and option
|
||||
(yas/make-directory-maybe option))))
|
||||
(when chosen
|
||||
(let ((default-file-name (or (and (yas/template-file yas/editing-template)
|
||||
(file-name-nondirectory (yas/template-file yas/editing-template)))
|
||||
(yas/template-name yas/editing-template))))
|
||||
(write-file (concat chosen "/"
|
||||
(read-from-minibuffer (format "File name to create in %s? " chosen)
|
||||
default-file-name)))
|
||||
(setf (yas/template-file yas/editing-template) buffer-file-name))))))
|
||||
(when kill
|
||||
(quit-window kill))
|
||||
(message "[yas] Snippet \"%s\" loaded for %s."
|
||||
(yas/template-name yas/editing-template)
|
||||
(yas/table-name (yas/template-table yas/editing-template))))
|
||||
(when (or (not (yas/template-file yas/editing-template))
|
||||
(not (file-writable-p (yas/template-file yas/editing-template)))
|
||||
(and (listp yas/snippet-dirs)
|
||||
(second yas/snippet-dirs)
|
||||
(not (string-match (expand-file-name (first yas/snippet-dirs))
|
||||
(yas/template-file yas/editing-template)))))
|
||||
(set (make-local-variable 'yas/guessed-modes)
|
||||
(yas/guess-snippet-directories (yas/template-table yas/editing-template)))
|
||||
(when (y-or-n-p "[yas] Also save snippet buffer to new file? ")
|
||||
(let* ((option (first yas/guessed-modes))
|
||||
(chosen (and option
|
||||
(yas/make-directory-maybe option))))
|
||||
(when chosen
|
||||
(let ((default-file-name (or (and (yas/template-file yas/editing-template)
|
||||
(file-name-nondirectory (yas/template-file yas/editing-template)))
|
||||
(yas/template-name yas/editing-template))))
|
||||
(write-file (concat chosen "/"
|
||||
(read-from-minibuffer (format "File name to create in %s? " chosen)
|
||||
default-file-name)))
|
||||
(setf (yas/template-file yas/editing-template) buffer-file-name))))))
|
||||
(when kill
|
||||
(quit-window kill))
|
||||
(message "[yas] Snippet \"%s\" loaded for %s."
|
||||
(yas/template-name yas/editing-template)
|
||||
(yas/table-name (yas/template-table yas/editing-template)))))
|
||||
|
||||
|
||||
(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)
|
||||
(fboundp (car major-mode-and-parent))
|
||||
(car major-mode-and-parent))
|
||||
(and yas/guessed-directories
|
||||
(intern (yas/table-name (car (first yas/guessed-directories)))))
|
||||
(and yas/guessed-modes
|
||||
(intern (yas/table-name (car (first yas/guessed-modes)))))
|
||||
(intern (read-from-minibuffer "[yas] please input a mode: "))))
|
||||
(yas/current-template
|
||||
(and parsed
|
||||
|
Loading…
x
Reference in New Issue
Block a user