* More work on yas/load-snippet-buffer, more intuitive now.

This commit is contained in:
capitaomorte 2010-04-16 15:53:23 +00:00
parent dc47c98625
commit 94ca84751d

View File

@ -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
(remove nil
(mapcar #'(lambda (mode) (mapcar #'(lambda (mode)
(gethash mode yas/tables)) (gethash mode yas/tables))
(append (list mode-symbol) (remove nil (append (list mode-symbol)
(yas/extra-modes) (yas/extra-modes)
(list major-mode (list major-mode
(and (not dont-search-parents) (and (not dont-search-parents)
(get major-mode (get major-mode
'derived-mode-parent)))))) 'derived-mode-parent)))))))))
(all-tables)) (remove-duplicates
(dolist (table (remove nil mode-tables)) (append mode-tables
(push table all-tables) (mapcan #'yas/table-get-all-parents mode-tables)))))
(nconc all-tables (yas/table-get-all-parents table)))
(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,23 +2459,38 @@ 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")
(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 (cond
;; X) Option 1: We have `yas/editing-template', this buffer's ;; X) Option 1: We have `yas/editing-template', this buffer's
;; content comes from a template which is already loaded and ;; content comes from a template which is already loaded and
;; neatly positioned,... ;; neatly positioned,...
;; ;;
((and (boundp 'yas/editing-template) (yas/editing-template
yas/editing-template
(yas/template-p yas/editing-template))
(let ((parsed (yas/parse-template (yas/template-file yas/editing-template)))) (let ((parsed (yas/parse-template (yas/template-file yas/editing-template))))
;; ... just change its template, expand-env, condition, key, ;; ... just change its template, expand-env, condition, key,
;; keybinding and name. The group cannot be changed. ;; keybinding and name. The group cannot be changed.
@ -2488,49 +2503,34 @@ With optional prefix argument KILL quit the window and buffer."
:keybinding (yas/read-keybinding (eighth parsed))) :keybinding (yas/read-keybinding (eighth parsed)))
(yas/update-template (yas/template-table yas/editing-template) (yas/update-template (yas/template-table yas/editing-template)
yas/editing-template))) yas/editing-template)))
;; X) Option 2: We have `yas/guessed-directories', but no ;; X) Option 2: We have `yas/guessed-modes', but no
;; `yas/editing-template', which probablt means this buffer's ;; `yas/editing-template', which probablt means this buffer's
;; content comes from `yas/new-snippet' call. Prompt user for a ;; content comes from `yas/new-snippet' call. Prompt user for a
;; table, add the template to the table, then call ;; table, add the template to the table, then call
;; ;;
((and (boundp 'yas/guessed-directories) (yas/guessed-modes
yas/guessed-directories) (if (eq yas/guessed-modes 'just-prompt)
(let* ((yas/prompt-functions '(yas/ido-prompt yas/completing-prompt)) (setq yas/guessed-modes nil))
(table (or (and yas/guessed-directories (let* ((prompt (if (and (featurep 'ido)
(y-or-n-p "Let yasnippet guess tables? ") ido-mode)
(or (and (second yas/guessed-directories) 'ido-completing-read 'completing-read))
(car (some #'(lambda (fn) (table (yas/table-get-create
(funcall fn "Choose from guessed list of tables: " (intern
guessed-directories (funcall prompt (format "Choose or enter a table (yas guesses %s): "
#'(lambda (option) (if yas/guessed-modes
(yas/table-name (car option))))) (first yas/guessed-modes)
yas/prompt-functions))) "nothing"))
(car (first yas/guessed-directories)))) (mapcar #'symbol-name yas/guessed-modes)
(yas/table-get-create (intern (read-from-minibuffer "Enter new/existing table: ")))))) nil
nil
nil
nil
(if (first yas/guessed-modes)
(symbol-name (first yas/guessed-modes))))))))
(set (make-local-variable 'yas/editing-template) (set (make-local-variable 'yas/editing-template)
(yas/define-snippets-1 (yas/parse-template buffer-file-name) (yas/define-snippets-1 (yas/parse-template buffer-file-name)
table table
(and yas/use-menu (yas/menu-keymap-get-create 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
;;
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 ;; Now, offer to save this shit
;; ;;
;; 1) if `yas/snippet-dirs' is a list and its first element does not ;; 1) if `yas/snippet-dirs' is a list and its first element does not
@ -2546,10 +2546,10 @@ With optional prefix argument KILL quit the window and buffer."
(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
@ -2564,7 +2564,7 @@ With optional prefix argument KILL quit the window and buffer."
(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