mirror of
https://github.com/joaotavora/yasnippet.git
synced 2025-10-14 05:23:04 +00:00
* Implement per-snippet keybinding using "keybinding: " keyword
* Fix random bugs * Fix some whitespace * `yas/use-menu' can now be 'real-modes' or 'abbreviate' * Changed prototype of `yas/expand-snippet' to be more user-friendly (this breaks backward compatibility) * Renamed keyword "env" to "expand-env" * TODO: fix more bugs, write more documentation
This commit is contained in:
parent
4cc4d0c578
commit
d153d84010
434
yasnippet.el
434
yasnippet.el
@ -118,7 +118,7 @@
|
|||||||
;; your .emacs file, for example:
|
;; your .emacs file, for example:
|
||||||
;;
|
;;
|
||||||
;; (require 'dropdown-list)
|
;; (require 'dropdown-list)
|
||||||
;; (setq 'yas/prompt-functions '(yas/dropdown-prompt
|
;; (setq yas/prompt-functions '(yas/dropdown-prompt
|
||||||
;; yas/ido-prompt
|
;; yas/ido-prompt
|
||||||
;; yas/completing-prompt))
|
;; yas/completing-prompt))
|
||||||
;;
|
;;
|
||||||
@ -132,6 +132,7 @@
|
|||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(require 'cl)
|
(require 'cl)
|
||||||
|
(require 'assoc)
|
||||||
(require 'easymenu)
|
(require 'easymenu)
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
@ -252,9 +253,9 @@ arguments."
|
|||||||
:group 'yasnippet)
|
:group 'yasnippet)
|
||||||
|
|
||||||
(defcustom yas/choose-keys-first t
|
(defcustom yas/choose-keys-first t
|
||||||
"If non-nil, prompts for key first, then for template if more than one.
|
"If non-nil, prompt for snippet key first, then for template.
|
||||||
|
|
||||||
Otherwise prompts for all possible templates
|
Otherwise prompts for all possible snippet names.
|
||||||
|
|
||||||
This affects `yas/insert-snippet' and `yas/visit-snippet-file'."
|
This affects `yas/insert-snippet' and `yas/visit-snippet-file'."
|
||||||
:type 'boolean
|
:type 'boolean
|
||||||
@ -270,13 +271,21 @@ This affects `yas/insert-snippet', `yas/visit-snippet-file'"
|
|||||||
:type 'boolean
|
:type 'boolean
|
||||||
:group 'yasnippet)
|
:group 'yasnippet)
|
||||||
|
|
||||||
(defcustom yas/use-menu t
|
(defcustom yas/use-menu 'real-modes
|
||||||
"Display a YASnippet menu in the menu bar.
|
"Display a YASnippet menu in the menu bar.
|
||||||
|
|
||||||
When non-nil, snippet templates will be listed under the menu
|
When non-nil, submenus for each snippet table will be listed
|
||||||
\"Yasnippet\". If set to `abbreviate', only the current major-mode
|
under the menu \"Yasnippet\".
|
||||||
menu and the modes set in `yas/mode-symbol' are listed."
|
|
||||||
|
If set to `real-modes' only submenus whose name more or less
|
||||||
|
corresponds to a major mode are listed.
|
||||||
|
|
||||||
|
If set to `abbreviate', only the current major-mode
|
||||||
|
menu and the modes set in `yas/mode-symbol' are listed.
|
||||||
|
|
||||||
|
Any other non-nil value, every submenu is listed."
|
||||||
:type '(choice (const :tag "Full" t)
|
:type '(choice (const :tag "Full" t)
|
||||||
|
(const :tag "Real modes only" real-modes)
|
||||||
(const :tag "Abbreviate" abbreviate))
|
(const :tag "Abbreviate" abbreviate))
|
||||||
:group 'yasnippet)
|
:group 'yasnippet)
|
||||||
|
|
||||||
@ -411,14 +420,16 @@ Here's an example:
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Internal variables
|
;; Internal variables
|
||||||
;;
|
;;
|
||||||
|
(defvar yas/version "0.6.1b")
|
||||||
(defvar yas/version "0.6.0b")
|
|
||||||
|
|
||||||
(defvar yas/snippet-tables (make-hash-table)
|
(defvar yas/snippet-tables (make-hash-table)
|
||||||
"A hash table of snippet tables corresponding to each major mode.")
|
"A hash table of MAJOR-MODE symbols to `yas/snippet-table' objects.")
|
||||||
|
|
||||||
(defvar yas/menu-table (make-hash-table)
|
(defvar yas/menu-table (make-hash-table)
|
||||||
"A hash table of menus of corresponding major mode.")
|
"A hash table of MAJOR-MODE symbols to menu keymaps.")
|
||||||
|
|
||||||
|
(defvar yas/active-keybindings nil
|
||||||
|
"A list of cons (KEYMAP . KEY) setup from defining snippets.")
|
||||||
|
|
||||||
(defvar yas/known-modes
|
(defvar yas/known-modes
|
||||||
'(ruby-mode rst-mode markdown-mode)
|
'(ruby-mode rst-mode markdown-mode)
|
||||||
@ -463,12 +474,12 @@ Here's an example:
|
|||||||
(defvar last-buffer-undo-list nil)
|
(defvar last-buffer-undo-list nil)
|
||||||
|
|
||||||
(defvar yas/minor-mode-map (make-sparse-keymap)
|
(defvar yas/minor-mode-map (make-sparse-keymap)
|
||||||
"The keymap used when function `yas/minor-mode' is active.")
|
"The keymap used when `yas/minor-mode' is active.")
|
||||||
|
|
||||||
(defvar yas/minor-mode-menu (make-sparse-keymap)
|
(defvar yas/minor-mode-menu (make-sparse-keymap)
|
||||||
"Holds the YASnippet menu. For use with `easy-menu-define'.")
|
"Holds the YASnippet menu. For use with `easy-menu-define'.")
|
||||||
|
|
||||||
(defun yas/init-keymap-and-menu ()
|
(defun yas/init-minor-keymap ()
|
||||||
(easy-menu-define yas/minor-mode-menu
|
(easy-menu-define yas/minor-mode-menu
|
||||||
yas/minor-mode-map
|
yas/minor-mode-map
|
||||||
"Menu used when YAS/minor-mode is active."
|
"Menu used when YAS/minor-mode is active."
|
||||||
@ -478,13 +489,19 @@ Here's an example:
|
|||||||
(define-key yas/minor-mode-map (third ent) (second ent)))
|
(define-key yas/minor-mode-map (third ent) (second ent)))
|
||||||
(vector (first ent) (second ent) t))
|
(vector (first ent) (second ent) t))
|
||||||
(list (list "--")
|
(list (list "--")
|
||||||
(list "Expand trigger" 'yas/expand (when yas/trigger-key (read-kbd-macro yas/trigger-key)))
|
(list "Expand trigger" 'yas/expand (when yas/trigger-key
|
||||||
|
(read-kbd-macro yas/trigger-key)))
|
||||||
(list "Insert at point..." 'yas/insert-snippet "\C-c&\C-s")
|
(list "Insert at point..." 'yas/insert-snippet "\C-c&\C-s")
|
||||||
|
(list "New snippet..." 'yas/new-snippet "\C-c&\C-n")
|
||||||
(list "Visit snippet file..." 'yas/visit-snippet-file "\C-c&\C-v")
|
(list "Visit snippet file..." 'yas/visit-snippet-file "\C-c&\C-v")
|
||||||
(list "Find snippets..." 'yas/find-snippets "\C-c&\C-f")
|
(list "Find snippets..." 'yas/find-snippets "\C-c&\C-f")
|
||||||
(list "About" 'yas/about)
|
(list "--")
|
||||||
(list "Reload-all-snippets" 'yas/reload-all)
|
(list "Load snippets..." 'yas/load-directory)
|
||||||
(list "Load snippets..." 'yas/load-directory))))))
|
(list "Reload everything" 'yas/reload-all)
|
||||||
|
(list "About" 'yas/about))))))
|
||||||
|
|
||||||
|
(progn
|
||||||
|
(yas/init-minor-keymap))
|
||||||
|
|
||||||
(define-minor-mode yas/minor-mode
|
(define-minor-mode yas/minor-mode
|
||||||
"Toggle YASnippet mode.
|
"Toggle YASnippet mode.
|
||||||
@ -507,11 +524,11 @@ Key bindings:
|
|||||||
(when yas/minor-mode
|
(when yas/minor-mode
|
||||||
;; when turning on theminor mode, re-read the `yas/trigger-key'
|
;; when turning on theminor mode, re-read the `yas/trigger-key'
|
||||||
;; if a `yas/minor-mode-map' is already built. Else, call
|
;; if a `yas/minor-mode-map' is already built. Else, call
|
||||||
;; `yas/init-keymap-and-menu' to build it
|
;; `yas/init-minor-keymap' to build it
|
||||||
(if (and (cdr yas/minor-mode-map)
|
(if (and (cdr yas/minor-mode-map)
|
||||||
yas/trigger-key)
|
yas/trigger-key)
|
||||||
(define-key yas/minor-mode-map (read-kbd-macro yas/trigger-key) 'yas/expand)
|
(define-key yas/minor-mode-map (read-kbd-macro yas/trigger-key) 'yas/expand)
|
||||||
(yas/init-keymap-and-menu))))
|
(yas/init-minor-keymap))))
|
||||||
|
|
||||||
(defun yas/minor-mode-on ()
|
(defun yas/minor-mode-on ()
|
||||||
"Turn on YASnippet minor mode."
|
"Turn on YASnippet minor mode."
|
||||||
@ -546,17 +563,36 @@ Key bindings:
|
|||||||
("}"
|
("}"
|
||||||
(0 font-lock-keyword-face)))))
|
(0 font-lock-keyword-face)))))
|
||||||
|
|
||||||
(defvar snippet-mode-map (make-sparse-keymap))
|
(defvar snippet-mode-map (make-sparse-keymap)
|
||||||
(define-key snippet-mode-map "\C-c\C-c" 'yas/load-snippet-buffer)
|
"The keymap used when `snippet-mode' is active")
|
||||||
(define-key snippet-mode-map "\C-c\C-t" 'yas/tryout-snippet)
|
|
||||||
|
|
||||||
|
(defvar yas/major-mode-menu (make-sparse-keymap)
|
||||||
|
"Holds the snippet-mode menu. For use with `easy-menu-define'.")
|
||||||
|
|
||||||
(define-derived-mode snippet-mode text-mode "YASnippet"
|
(defun yas/init-major-keymap ()
|
||||||
|
(easy-menu-define yas/major-mode-menu
|
||||||
|
snippet-mode-map
|
||||||
|
"Menu used when snippet-mode is active."
|
||||||
|
(cons "Snippet"
|
||||||
|
(mapcar #'(lambda (ent)
|
||||||
|
(when (third ent)
|
||||||
|
(define-key snippet-mode-map (third ent) (second ent)))
|
||||||
|
(vector (first ent) (second ent) t))
|
||||||
|
(list
|
||||||
|
(list "Load this snippet" 'yas/load-snippet-buffer "\C-c\C-c")
|
||||||
|
(list "Try out this snippet" 'yas/tryout-snippet "\C-c\C-t"))))))
|
||||||
|
|
||||||
|
(progn
|
||||||
|
(yas/init-major-keymap))
|
||||||
|
|
||||||
|
(define-derived-mode snippet-mode text-mode "Snippet"
|
||||||
"A mode for editing yasnippets"
|
"A mode for editing yasnippets"
|
||||||
(set-syntax-table (standard-syntax-table))
|
(set-syntax-table (standard-syntax-table))
|
||||||
(setq font-lock-defaults '(yas/font-lock-keywords))
|
(setq font-lock-defaults '(yas/font-lock-keywords))
|
||||||
(set (make-local-variable 'require-final-newline) nil)
|
(set (make-local-variable 'require-final-newline) nil)
|
||||||
(use-local-map snippet-mode-map))
|
(use-local-map snippet-mode-map)
|
||||||
|
(unless (cdr snippet-mode-map)
|
||||||
|
(yas/init-major-keymap)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -565,16 +601,17 @@ Key bindings:
|
|||||||
;;
|
;;
|
||||||
|
|
||||||
(defstruct (yas/template (:constructor yas/make-template
|
(defstruct (yas/template (:constructor yas/make-template
|
||||||
(content name condition env file)))
|
(content name condition env file keybinding)))
|
||||||
"A template for a snippet."
|
"A template for a snippet."
|
||||||
content
|
content
|
||||||
name
|
name
|
||||||
condition
|
condition
|
||||||
env
|
env
|
||||||
file)
|
file
|
||||||
|
keybinding)
|
||||||
|
|
||||||
(defstruct (yas/snippet-table (:constructor yas/make-snippet-table (name)))
|
(defstruct (yas/snippet-table (:constructor yas/make-snippet-table (name)))
|
||||||
"A table to store snippets for a perticular mode."
|
"A table to store snippets for a particular mode."
|
||||||
name
|
name
|
||||||
(hash (make-hash-table :test 'equal))
|
(hash (make-hash-table :test 'equal))
|
||||||
(parents nil))
|
(parents nil))
|
||||||
@ -642,6 +679,19 @@ This function implements the rules described in
|
|||||||
|
|
||||||
(defun yas/snippet-table-store (table full-key key template)
|
(defun yas/snippet-table-store (table full-key key template)
|
||||||
"Store a snippet template in the TABLE."
|
"Store a snippet template in the TABLE."
|
||||||
|
;; If replacing a snippet template, remember to remove its
|
||||||
|
;; keybinding first.
|
||||||
|
;;
|
||||||
|
(let ((existing (aget (gethash key (yas/snippet-table-hash table))
|
||||||
|
full-key)))
|
||||||
|
(when (and existing
|
||||||
|
(yas/template-keybinding existing))
|
||||||
|
(define-key
|
||||||
|
(car (yas/template-keybinding existing))
|
||||||
|
(cdr (yas/template-keybinding existing))
|
||||||
|
nil)))
|
||||||
|
;; Now store the new template
|
||||||
|
;;
|
||||||
(puthash key
|
(puthash key
|
||||||
(yas/modify-alist (gethash key
|
(yas/modify-alist (gethash key
|
||||||
(yas/snippet-table-hash table))
|
(yas/snippet-table-hash table))
|
||||||
@ -792,7 +842,8 @@ Here's a list of currently recognized variables:
|
|||||||
bound
|
bound
|
||||||
condition
|
condition
|
||||||
group
|
group
|
||||||
env)
|
env
|
||||||
|
binding)
|
||||||
(if (re-search-forward "^# --\n" nil t)
|
(if (re-search-forward "^# --\n" nil t)
|
||||||
(progn (setq template
|
(progn (setq template
|
||||||
(buffer-substring-no-properties (point)
|
(buffer-substring-no-properties (point)
|
||||||
@ -806,13 +857,15 @@ Here's a list of currently recognized variables:
|
|||||||
(setq condition (read (match-string-no-properties 2))))
|
(setq condition (read (match-string-no-properties 2))))
|
||||||
(when (string= "group" (match-string-no-properties 1))
|
(when (string= "group" (match-string-no-properties 1))
|
||||||
(setq group (match-string-no-properties 2)))
|
(setq group (match-string-no-properties 2)))
|
||||||
(when (string= "env" (match-string-no-properties 1))
|
(when (string= "expand-env" (match-string-no-properties 1))
|
||||||
(setq env (match-string-no-properties 2)))
|
(setq env (match-string-no-properties 2)))
|
||||||
(when (string= "key" (match-string-no-properties 1))
|
(when (string= "key" (match-string-no-properties 1))
|
||||||
(setq key (match-string-no-properties 2)))))
|
(setq key (match-string-no-properties 2)))
|
||||||
|
(when (string= "binding" (match-string-no-properties 1))
|
||||||
|
(setq binding (match-string-no-properties 2)))))
|
||||||
(setq template
|
(setq template
|
||||||
(buffer-substring-no-properties (point-min) (point-max))))
|
(buffer-substring-no-properties (point-min) (point-max))))
|
||||||
(list key template name condition group env file)))
|
(list key template name condition group env file binding)))
|
||||||
|
|
||||||
(defun yas/subdirs (directory &optional file?)
|
(defun yas/subdirs (directory &optional file?)
|
||||||
"Return subdirs or files of DIRECTORY according to FILE?."
|
"Return subdirs or files of DIRECTORY according to FILE?."
|
||||||
@ -833,9 +886,9 @@ Here's a list of currently recognized variables:
|
|||||||
(let ((where (if mark-active
|
(let ((where (if mark-active
|
||||||
(cons (region-beginning) (region-end))
|
(cons (region-beginning) (region-end))
|
||||||
(cons (point) (point)))))
|
(cons (point) (point)))))
|
||||||
(yas/expand-snippet (car where)
|
(yas/expand-snippet (yas/template-content template)
|
||||||
(cdr where)
|
(car where)
|
||||||
(yas/template-content template))))
|
(cdr where))))
|
||||||
|
|
||||||
(defun yas/modify-alist (alist key value)
|
(defun yas/modify-alist (alist key value)
|
||||||
"Modify ALIST to map KEY to VALUE. return the new alist."
|
"Modify ALIST to map KEY to VALUE. return the new alist."
|
||||||
@ -975,32 +1028,52 @@ content of the file is the template."
|
|||||||
(interactive "DSelect the root directory: ")
|
(interactive "DSelect the root directory: ")
|
||||||
(unless (file-directory-p directory)
|
(unless (file-directory-p directory)
|
||||||
(error "Error %s not a directory" directory))
|
(error "Error %s not a directory" directory))
|
||||||
(add-to-list 'yas/root-directory directory)
|
(unless yas/root-directory
|
||||||
|
(setq yas/root-directory directory))
|
||||||
(dolist (dir (yas/subdirs directory))
|
(dolist (dir (yas/subdirs directory))
|
||||||
(yas/load-directory-1 dir nil 'no-hierarchy-parents))
|
(yas/load-directory-1 dir nil 'no-hierarchy-parents))
|
||||||
(when (interactive-p)
|
(when (interactive-p)
|
||||||
(message "done.")))
|
(message "done.")))
|
||||||
|
|
||||||
|
(defun yas/kill-snippet-keybindings ()
|
||||||
|
"Remove the all active snippet keybindings."
|
||||||
|
(interactive)
|
||||||
|
(dolist (keybinding yas/active-keybindings)
|
||||||
|
(define-key (car keybinding) (cdr keybinding) nil))
|
||||||
|
(setq yas/active-keybindings nil))
|
||||||
|
|
||||||
(defun yas/reload-all ()
|
(defun yas/reload-all ()
|
||||||
"Reload all snippets and rebuild the YASnippet menu. "
|
"Reload all snippets and rebuild the YASnippet menu. "
|
||||||
|
|
||||||
(interactive)
|
(interactive)
|
||||||
(let ((restore-global-mode nil)
|
;; Turn off global modes and minor modes, save their state though
|
||||||
(restore-minor-mode nil))
|
;;
|
||||||
|
(let ((restore-global-mode (prog1 yas/global-mode
|
||||||
|
(yas/global-mode -1)))
|
||||||
|
(restore-minor-mode (prog1 yas/minor-mode
|
||||||
|
(yas/minor-mode -1))))
|
||||||
|
;; Empty all snippet tables and all menu tables
|
||||||
|
;;
|
||||||
(setq yas/snippet-tables (make-hash-table))
|
(setq yas/snippet-tables (make-hash-table))
|
||||||
(setq yas/menu-table (make-hash-table))
|
(setq yas/menu-table (make-hash-table))
|
||||||
|
|
||||||
|
;; The minor mode and major mode keymap's cdr set to nil (this is
|
||||||
|
;; the same as `make-sparse-keymap;)
|
||||||
(setf (cdr yas/minor-mode-menu) nil)
|
(setf (cdr yas/minor-mode-menu) nil)
|
||||||
(setf (cdr yas/minor-mode-map) nil)
|
(setf (cdr yas/minor-mode-map) nil)
|
||||||
(when yas/global-mode
|
(setf (cdr yas/major-mode-menu) nil)
|
||||||
(yas/global-mode -1)
|
(setf (cdr snippet-mode-map) nil)
|
||||||
(setq restore-global-mode t))
|
|
||||||
|
|
||||||
(when yas/minor-mode
|
;; Initialize both keymaps
|
||||||
(yas/minor-mode -1)
|
;;
|
||||||
(setq restore-minor-mode t))
|
(yas/init-minor-keymap)
|
||||||
|
(yas/init-major-keymap)
|
||||||
|
|
||||||
(yas/init-keymap-and-menu)
|
;; Now, clean up the other keymaps we might have cluttered up.
|
||||||
|
(yas/kill-snippet-keybindings)
|
||||||
|
|
||||||
|
;; Reload the directories listed in `yas/root-directory' or prompt
|
||||||
|
;; the user to select one.
|
||||||
|
;;
|
||||||
(if yas/root-directory
|
(if yas/root-directory
|
||||||
(if (listp yas/root-directory)
|
(if (listp yas/root-directory)
|
||||||
(dolist (directory yas/root-directory)
|
(dolist (directory yas/root-directory)
|
||||||
@ -1008,10 +1081,10 @@ content of the file is the template."
|
|||||||
(yas/load-directory yas/root-directory))
|
(yas/load-directory yas/root-directory))
|
||||||
(call-interactively 'yas/load-directory))
|
(call-interactively 'yas/load-directory))
|
||||||
|
|
||||||
|
;; Restore the mode configuration
|
||||||
|
;;
|
||||||
(when restore-minor-mode
|
(when restore-minor-mode
|
||||||
(yas/minor-mode 1))
|
(yas/minor-mode 1))
|
||||||
|
|
||||||
(when restore-global-mode
|
(when restore-global-mode
|
||||||
(yas/global-mode 1))
|
(yas/global-mode 1))
|
||||||
|
|
||||||
@ -1144,12 +1217,14 @@ Here's the default value for all the parameters:
|
|||||||
") -- pluskid <pluskid@gmail.com>/joaotavora <joaotavora@gmail.com>")))
|
") -- pluskid <pluskid@gmail.com>/joaotavora <joaotavora@gmail.com>")))
|
||||||
|
|
||||||
(defun yas/define-snippets (mode snippets &optional parent-mode)
|
(defun yas/define-snippets (mode snippets &optional parent-mode)
|
||||||
"Define snippets for MODE. SNIPPETS is a list of
|
"Define SNIPPETS for MODE.
|
||||||
snippet definitions, each taking the following form:
|
|
||||||
|
|
||||||
(KEY TEMPLATE NAME CONDITION GROUP)
|
SNIPPETS is a list of snippet definitions, each taking the
|
||||||
|
following form:
|
||||||
|
|
||||||
NAME, CONDITION or GROUP may be omitted.
|
(KEY TEMPLATE NAME CONDITION GROUP VARS FILE KEYBINDING)
|
||||||
|
|
||||||
|
Within these, only TEMPLATE is actually mandatory.
|
||||||
|
|
||||||
Optional PARENT-MODE can be used to specify the parent modes of
|
Optional PARENT-MODE can be used to specify the parent modes of
|
||||||
MODE. It can be a mode symbol of a list of mode symbols. It does
|
MODE. It can be a mode symbol of a list of mode symbols. It does
|
||||||
@ -1165,6 +1240,8 @@ its parent modes."
|
|||||||
(keymap (if yas/use-menu
|
(keymap (if yas/use-menu
|
||||||
(yas/menu-keymap-get-create mode)
|
(yas/menu-keymap-get-create mode)
|
||||||
nil)))
|
nil)))
|
||||||
|
;; Setup the menu
|
||||||
|
;;
|
||||||
(when parent-tables
|
(when parent-tables
|
||||||
(setf (yas/snippet-table-parents snippet-table)
|
(setf (yas/snippet-table-parents snippet-table)
|
||||||
parent-tables)
|
parent-tables)
|
||||||
@ -1176,35 +1253,81 @@ its parent modes."
|
|||||||
parent-mode)
|
parent-mode)
|
||||||
'((parent-mode . "parent mode")))))
|
'((parent-mode . "parent mode")))))
|
||||||
(mapc #'(lambda (sym-and-name)
|
(mapc #'(lambda (sym-and-name)
|
||||||
(define-key keymap (vector (intern (replace-regexp-in-string " " "_" (cdr sym-and-name))))
|
(define-key keymap
|
||||||
|
(vector (intern (replace-regexp-in-string " " "_" (cdr sym-and-name))))
|
||||||
(list 'menu-item (cdr sym-and-name)
|
(list 'menu-item (cdr sym-and-name)
|
||||||
(yas/menu-keymap-get-create (car sym-and-name)))))
|
(yas/menu-keymap-get-create (car sym-and-name)))))
|
||||||
(reverse parent-menu-syms-and-names)))))
|
(reverse parent-menu-syms-and-names)))))
|
||||||
(when (and yas/use-menu
|
(when yas/use-menu
|
||||||
(yas/real-mode? mode))
|
|
||||||
(define-key yas/minor-mode-menu (vector mode)
|
(define-key yas/minor-mode-menu (vector mode)
|
||||||
`(menu-item ,(symbol-name mode) ,keymap
|
`(menu-item ,(symbol-name mode) ,keymap
|
||||||
:visible (yas/show-menu-p ',mode))))
|
:visible (yas/show-menu-p ',mode))))
|
||||||
|
;; Iterate the recently parsed snippets definition
|
||||||
|
;;
|
||||||
(dolist (snippet snippets)
|
(dolist (snippet snippets)
|
||||||
(let* ((full-key (car snippet))
|
(let* ((full-key (car snippet))
|
||||||
(key (file-name-sans-extension full-key))
|
(key (file-name-sans-extension full-key))
|
||||||
(name (or (nth 2 snippet) (file-name-extension full-key)))
|
(name (or (third snippet) (file-name-extension full-key)))
|
||||||
(condition (nth 3 snippet))
|
(condition (fourth snippet))
|
||||||
(group (nth 4 snippet))
|
(group (fifth snippet))
|
||||||
(template (yas/make-template (nth 1 snippet)
|
(keybinding (eighth snippet))
|
||||||
|
(template nil))
|
||||||
|
;; Read the snippet's "binding :" expression
|
||||||
|
;;
|
||||||
|
(condition-case err
|
||||||
|
(when keybinding
|
||||||
|
(setq keybinding (read (eighth snippet)))
|
||||||
|
(let* ((mode-map-symbol (intern (concat (symbol-name mode) "-map")))
|
||||||
|
(keys (or (and (consp keybinding)
|
||||||
|
(read-kbd-macro (cdr keybinding)))
|
||||||
|
(read-kbd-macro keybinding)))
|
||||||
|
(keymap (or (and (consp keybinding)
|
||||||
|
(boundp (car keybinding))
|
||||||
|
(symbol-value (car keybinding)))
|
||||||
|
(and (boundp mode-map-symbol)
|
||||||
|
(symbol-value mode-map-symbol)))))
|
||||||
|
(if (keymapp keymap)
|
||||||
|
(progn
|
||||||
|
(setq keybinding (cons keymap keys))
|
||||||
|
(push keybinding yas/active-keybindings))
|
||||||
|
(setq keybinding nil))))
|
||||||
|
(error
|
||||||
|
(message "[yas] warning: could not read keybinding %s for snippet \"%s\""
|
||||||
|
keybinding name)
|
||||||
|
(setf keybinding nil)))
|
||||||
|
|
||||||
|
;; Create the `yas/template' object and store in the
|
||||||
|
;; appropriate snippet table
|
||||||
|
;;
|
||||||
|
(setq template (yas/make-template (second snippet)
|
||||||
(or name key)
|
(or name key)
|
||||||
condition
|
condition
|
||||||
(nth 5 snippet)
|
(sixth snippet)
|
||||||
(nth 6 snippet))))
|
(seventh snippet)
|
||||||
|
keybinding))
|
||||||
(yas/snippet-table-store snippet-table
|
(yas/snippet-table-store snippet-table
|
||||||
full-key
|
full-key
|
||||||
key
|
key
|
||||||
template)
|
template)
|
||||||
|
|
||||||
|
;; Now register the keybinding if it does not conflict!
|
||||||
|
;;
|
||||||
|
(unless (or (not (consp keybinding))
|
||||||
|
(lookup-key (car keybinding) (cdr keybinding)))
|
||||||
|
(define-key
|
||||||
|
(car keybinding)
|
||||||
|
(cdr keybinding)
|
||||||
|
`(lambda () (interactive) (yas/expand-snippet ,(second snippet)))))
|
||||||
|
|
||||||
|
;; Setup the menu groups, reorganizing from group to group if
|
||||||
|
;; necessary
|
||||||
|
;;
|
||||||
(when yas/use-menu
|
(when yas/use-menu
|
||||||
(let ((group-keymap keymap))
|
(let ((group-keymap keymap))
|
||||||
;; delete this entry from another group if already exists
|
;; Delete this entry from another group if already exists
|
||||||
;; in some other group. An entry is considered as existing
|
;; in some other group. An entry is considered as existing
|
||||||
;; in another group if its name string-matches.
|
;; in another group if its name string-matches.
|
||||||
|
;;
|
||||||
(yas/delete-from-keymap group-keymap name)
|
(yas/delete-from-keymap group-keymap name)
|
||||||
|
|
||||||
;; ... then add this entry to the correct group
|
;; ... then add this entry to the correct group
|
||||||
@ -1227,11 +1350,15 @@ its parent modes."
|
|||||||
|
|
||||||
(defun yas/show-menu-p (mode)
|
(defun yas/show-menu-p (mode)
|
||||||
(message "what")
|
(message "what")
|
||||||
(or (not (eq yas/use-menu 'abbreviate))
|
(cond ((eq yas/use-menu 'abbreviate)
|
||||||
(find mode (cons major-mode
|
(find mode (cons major-mode
|
||||||
(if (listp yas/mode-symbol)
|
(if (listp yas/mode-symbol)
|
||||||
yas/mode-symbol
|
yas/mode-symbol
|
||||||
(list yas/mode-symbol))))))
|
(list yas/mode-symbol)))))
|
||||||
|
((eq yas/use-menu 'real-modes)
|
||||||
|
(yas/real-mode? mode))
|
||||||
|
(t
|
||||||
|
t)))
|
||||||
|
|
||||||
(defun yas/delete-from-keymap (keymap name)
|
(defun yas/delete-from-keymap (keymap name)
|
||||||
"Recursively delete items name NAME from KEYMAP and its submenus.
|
"Recursively delete items name NAME from KEYMAP and its submenus.
|
||||||
@ -1250,7 +1377,8 @@ Skip any submenus named \"parent mode\""
|
|||||||
;;
|
;;
|
||||||
(when (keymapp keymap)
|
(when (keymapp keymap)
|
||||||
(let ((pos-in-keymap))
|
(let ((pos-in-keymap))
|
||||||
(while (setq pos-in-keymap (position-if #'(lambda (item)
|
(while (setq pos-in-keymap
|
||||||
|
(position-if #'(lambda (item)
|
||||||
(and (listp item)
|
(and (listp item)
|
||||||
(or
|
(or
|
||||||
;; the menu item we want to delete
|
;; the menu item we want to delete
|
||||||
@ -1260,7 +1388,8 @@ Skip any submenus named \"parent mode\""
|
|||||||
;; a stale subgroup
|
;; a stale subgroup
|
||||||
(and (keymapp (fourth item))
|
(and (keymapp (fourth item))
|
||||||
(not (and (stringp (third item))
|
(not (and (stringp (third item))
|
||||||
(string-match "parent mode" (third item))))
|
(string-match "parent mode"
|
||||||
|
(third item))))
|
||||||
(null (rest (fourth item)))))))
|
(null (rest (fourth item)))))))
|
||||||
keymap))
|
keymap))
|
||||||
(setf (nthcdr pos-in-keymap keymap)
|
(setf (nthcdr pos-in-keymap keymap)
|
||||||
@ -1320,9 +1449,9 @@ defined in `yas/fallback-behavior'"
|
|||||||
(yas/prompt-for-template (mapcar #'cdr templates)))
|
(yas/prompt-for-template (mapcar #'cdr templates)))
|
||||||
(cdar templates))))
|
(cdar templates))))
|
||||||
(when template
|
(when template
|
||||||
(yas/expand-snippet start
|
(yas/expand-snippet (yas/template-content template)
|
||||||
|
start
|
||||||
end
|
end
|
||||||
(yas/template-content template)
|
|
||||||
(yas/template-env template))))
|
(yas/template-env template))))
|
||||||
(cond ((eq yas/fallback-behavior 'return-nil)
|
(cond ((eq yas/fallback-behavior 'return-nil)
|
||||||
;; return nil
|
;; return nil
|
||||||
@ -1382,9 +1511,9 @@ by condition."
|
|||||||
(cons (region-beginning) (region-end))
|
(cons (region-beginning) (region-end))
|
||||||
(cons (point) (point)))))
|
(cons (point) (point)))))
|
||||||
(if template
|
(if template
|
||||||
(yas/expand-snippet (car where)
|
(yas/expand-snippet (yas/template-content template)
|
||||||
|
(car where)
|
||||||
(cdr where)
|
(cdr where)
|
||||||
(yas/template-content template)
|
|
||||||
(yas/template-env template))
|
(yas/template-env template))
|
||||||
(message "[yas] No snippets can be inserted here!"))))
|
(message "[yas] No snippets can be inserted here!"))))
|
||||||
|
|
||||||
@ -1427,14 +1556,15 @@ also the current active tables."
|
|||||||
;; Next lookup the main active table
|
;; Next lookup the main active table
|
||||||
;;
|
;;
|
||||||
(let ((active-tables (first (yas/get-snippet-tables)))
|
(let ((active-tables (first (yas/get-snippet-tables)))
|
||||||
(other-path-alternative main-dir))
|
other-path-alternative)
|
||||||
(when active-tables
|
(when active-tables
|
||||||
(setq active-tables (cons active-tables
|
(setq active-tables (cons active-tables
|
||||||
(yas/snippet-table-get-all-parents active-tables))))
|
(yas/snippet-table-get-all-parents active-tables))))
|
||||||
(dolist (table (reverse active-tables))
|
(dolist (table (reverse active-tables))
|
||||||
(setq other-path-alternative
|
(setq other-path-alternative
|
||||||
(concat other-path-alternative "/" (yas/snippet-table-name table))))
|
(concat main-dir "/" (yas/snippet-table-name table))))
|
||||||
(push other-path-alternative options))
|
(when other-path-alternative
|
||||||
|
(push other-path-alternative options)))
|
||||||
;; Finally add to the options the guessed parent of major-mode
|
;; Finally add to the options the guessed parent of major-mode
|
||||||
;; (this is almost never works out)
|
;; (this is almost never works out)
|
||||||
(when (get mode 'derived-mode-parent)
|
(when (get mode 'derived-mode-parent)
|
||||||
@ -1465,14 +1595,23 @@ one of these exists, it is taken and `find-file' is called there,
|
|||||||
otherwise, proposes to create the first option returned by
|
otherwise, proposes to create the first option returned by
|
||||||
`yas/guess-directory'."
|
`yas/guess-directory'."
|
||||||
(interactive "P")
|
(interactive "P")
|
||||||
(let* ((guessed-directories (yas/guess-snippet-directory))
|
(let* ((guessed-directories (append (yas/guess-snippet-directory)
|
||||||
(target-directory (first (remove-if-not #'file-exists-p guessed-directories)))
|
(if (listp yas/root-directory)
|
||||||
|
yas/root-directory
|
||||||
|
(list yas/root-directory))))
|
||||||
|
(target-directory (first guessed-directories))
|
||||||
(buffer))
|
(buffer))
|
||||||
|
|
||||||
(unless target-directory
|
(while (and guessed-directories
|
||||||
(when (y-or-n-p (format "Guessed directory (%s) does not exist! Create? " (first guessed-directories)))
|
(or (not target-directory)
|
||||||
|
(not (file-exists-p target-directory))))
|
||||||
|
(if (y-or-n-p (format "Guessed directory (%s) does not exist! Create? "
|
||||||
|
(first guessed-directories)))
|
||||||
|
(progn
|
||||||
(setq target-directory (first guessed-directories))
|
(setq target-directory (first guessed-directories))
|
||||||
(make-directory target-directory 'also-make-parents)))
|
(make-directory target-directory 'also-make-parents))
|
||||||
|
(setq guessed-directories (cdr guessed-directories))
|
||||||
|
(setq target-directory (first guessed-directories))))
|
||||||
|
|
||||||
(when target-directory
|
(when target-directory
|
||||||
(let ((default-directory target-directory))
|
(let ((default-directory target-directory))
|
||||||
@ -1502,7 +1641,8 @@ otherwise, proposes to create the first option returned by
|
|||||||
(major-mode-sym (or (and major-mode-name
|
(major-mode-sym (or (and major-mode-name
|
||||||
(intern major-mode-name))
|
(intern major-mode-name))
|
||||||
(when prompt-if-failed
|
(when prompt-if-failed
|
||||||
(read-from-minibuffer "[yas] Cannot auto-detect major mode! Enter a major mode: "))))
|
(read-from-minibuffer
|
||||||
|
"[yas] Cannot auto-detect major mode! Enter a major mode: "))))
|
||||||
(parent-mode-sym (and parent-mode-name
|
(parent-mode-sym (and parent-mode-name
|
||||||
(intern parent-mode-name)))
|
(intern parent-mode-name)))
|
||||||
(extra-parents-file-name (concat file-dir "/.yas-parents"))
|
(extra-parents-file-name (concat file-dir "/.yas-parents"))
|
||||||
@ -1510,7 +1650,7 @@ otherwise, proposes to create the first option returned by
|
|||||||
(mapcar #'intern
|
(mapcar #'intern
|
||||||
(split-string
|
(split-string
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
(insert-file extra-parents-file-name)
|
(insert-file-contents extra-parents-file-name)
|
||||||
(buffer-substring-no-properties (point-min)
|
(buffer-substring-no-properties (point-min)
|
||||||
(point-max))))))))
|
(point-max))))))))
|
||||||
(when major-mode-sym
|
(when major-mode-sym
|
||||||
@ -1537,7 +1677,9 @@ With optional prefix argument KILL quit the window and buffer."
|
|||||||
(save-buffer))
|
(save-buffer))
|
||||||
(if kill
|
(if kill
|
||||||
(quit-window kill)
|
(quit-window kill)
|
||||||
(message "[yas] Snippet \"%s\" loaded for %s." name (car major-mode-and-parent)))))
|
(message "[yas] Snippet \"%s\" loaded for %s."
|
||||||
|
name
|
||||||
|
(car major-mode-and-parent)))))
|
||||||
(message "[yas] Cannot load snippet for unknown major mode")))
|
(message "[yas] Cannot load snippet for unknown major mode")))
|
||||||
(message "Save the buffer as a file first!")))
|
(message "Save the buffer as a file first!")))
|
||||||
|
|
||||||
@ -1549,14 +1691,22 @@ With optional prefix argument KILL quit the window and buffer."
|
|||||||
(fboundp (car major-mode-and-parent))
|
(fboundp (car major-mode-and-parent))
|
||||||
(yas/parse-template (symbol-name (car major-mode-and-parent)))))
|
(yas/parse-template (symbol-name (car major-mode-and-parent)))))
|
||||||
(template (and parsed
|
(template (and parsed
|
||||||
(yas/make-template (second parsed) (third parsed) nil (sixth parsed) nil))))
|
(yas/make-template (second parsed)
|
||||||
|
(third parsed)
|
||||||
|
nil
|
||||||
|
(sixth parsed)
|
||||||
|
nil
|
||||||
|
nil))))
|
||||||
(cond (template
|
(cond (template
|
||||||
(let ((buffer-name (format "*YAS TEST: %s*" (yas/template-name template))))
|
(let ((buffer-name (format "*YAS TEST: %s*" (yas/template-name template))))
|
||||||
(set-buffer (switch-to-buffer buffer-name))
|
(set-buffer (switch-to-buffer buffer-name))
|
||||||
(erase-buffer)
|
(erase-buffer)
|
||||||
(setq buffer-undo-list nil)
|
(setq buffer-undo-list nil)
|
||||||
(funcall (car major-mode-and-parent))
|
(funcall (car major-mode-and-parent))
|
||||||
(yas/expand-snippet (point-min) (point-max) (yas/template-content template) (yas/template-env template))
|
(yas/expand-snippet (yas/template-content template)
|
||||||
|
(point-min)
|
||||||
|
(point-max)
|
||||||
|
(yas/template-env template))
|
||||||
(when debug
|
(when debug
|
||||||
(add-hook 'post-command-hook 'yas/debug-some-vars 't 'local))))
|
(add-hook 'post-command-hook 'yas/debug-some-vars 't 'local))))
|
||||||
(t
|
(t
|
||||||
@ -1621,9 +1771,13 @@ Otherwise throw exception."
|
|||||||
(when field
|
(when field
|
||||||
(yas/field-text-for-display field))))
|
(yas/field-text-for-display field))))
|
||||||
|
|
||||||
(defun yas/oni (text oni-regexp)
|
;; (defun yas/oni (text regexp format &optional options)
|
||||||
"Runs ruby to parse TEXT with Oniguruma regexp ONI-REGEXP."
|
;; "Pipes TEXT thru ruby Oniguruma regexp"
|
||||||
(shell-command-to-string (format "ruby -e 'print \"%s\".gsub(\"a\",\"b\")'" "aha")))
|
;; (replace-regexp-in-string
|
||||||
|
;; "\n$"
|
||||||
|
;; ""
|
||||||
|
;; (shell-command-to-string (format "ruby -e 'puts \"%s\".gsub(\"a\",\"b\")'" text))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
@ -1834,6 +1988,15 @@ Also create some protection overlays"
|
|||||||
(yas/exit-marker (yas/snippet-exit snippet))
|
(yas/exit-marker (yas/snippet-exit snippet))
|
||||||
(overlay-end (yas/snippet-control-overlay snippet)))))
|
(overlay-end (yas/snippet-control-overlay snippet)))))
|
||||||
|
|
||||||
|
(defun yas/exit-all-snippets ()
|
||||||
|
"Exit all snippets."
|
||||||
|
(interactive)
|
||||||
|
(mapc #'(lambda (snippet)
|
||||||
|
(yas/exit-snippet snippet)
|
||||||
|
(yas/check-commit-snippet))
|
||||||
|
(yas/snippets-at-point)))
|
||||||
|
|
||||||
|
|
||||||
;;; Apropos markers-to-points:
|
;;; Apropos markers-to-points:
|
||||||
;;;
|
;;;
|
||||||
;;; This was found useful for performance reasons, so that an
|
;;; This was found useful for performance reasons, so that an
|
||||||
@ -1875,14 +2038,19 @@ the original marker object with the position set to nil."
|
|||||||
"Convert all cons (POINT . MARKER) in SNIPPET to markers. This
|
"Convert all cons (POINT . MARKER) in SNIPPET to markers. This
|
||||||
is done by setting MARKER to POINT with `set-marker'."
|
is done by setting MARKER to POINT with `set-marker'."
|
||||||
(dolist (field (yas/snippet-fields snippet))
|
(dolist (field (yas/snippet-fields snippet))
|
||||||
(setf (yas/field-start field) (set-marker (cdr (yas/field-start field)) (car (yas/field-start field))))
|
(setf (yas/field-start field) (set-marker (cdr (yas/field-start field))
|
||||||
(setf (yas/field-end field) (set-marker (cdr (yas/field-end field)) (car (yas/field-end field))))
|
(car (yas/field-start field))))
|
||||||
|
(setf (yas/field-end field) (set-marker (cdr (yas/field-end field))
|
||||||
|
(car (yas/field-end field))))
|
||||||
(dolist (mirror (yas/field-mirrors field))
|
(dolist (mirror (yas/field-mirrors field))
|
||||||
(setf (yas/mirror-start mirror) (set-marker (cdr (yas/mirror-start mirror)) (car (yas/mirror-start mirror))))
|
(setf (yas/mirror-start mirror) (set-marker (cdr (yas/mirror-start mirror))
|
||||||
(setf (yas/mirror-end mirror) (set-marker (cdr (yas/mirror-end mirror)) (car (yas/mirror-end mirror))))))
|
(car (yas/mirror-start mirror))))
|
||||||
|
(setf (yas/mirror-end mirror) (set-marker (cdr (yas/mirror-end mirror))
|
||||||
|
(car (yas/mirror-end mirror))))))
|
||||||
(let ((snippet-exit (yas/snippet-exit snippet)))
|
(let ((snippet-exit (yas/snippet-exit snippet)))
|
||||||
(when snippet-exit
|
(when snippet-exit
|
||||||
(setf (yas/exit-marker snippet-exit) (set-marker (cdr (yas/exit-marker snippet-exit)) (car (yas/exit-marker snippet-exit)))))))
|
(setf (yas/exit-marker snippet-exit) (set-marker (cdr (yas/exit-marker snippet-exit))
|
||||||
|
(car (yas/exit-marker snippet-exit)))))))
|
||||||
|
|
||||||
(defun yas/commit-snippet (snippet &optional no-hooks)
|
(defun yas/commit-snippet (snippet &optional no-hooks)
|
||||||
"Commit SNIPPET, but leave point as it is. This renders the
|
"Commit SNIPPET, but leave point as it is. This renders the
|
||||||
@ -2038,8 +2206,10 @@ Move the overlay, or create it if it does not exit."
|
|||||||
(overlay-put yas/active-field-overlay 'face 'yas/field-highlight-face)
|
(overlay-put yas/active-field-overlay 'face 'yas/field-highlight-face)
|
||||||
(overlay-put yas/active-field-overlay 'yas/snippet snippet)
|
(overlay-put yas/active-field-overlay 'yas/snippet snippet)
|
||||||
(overlay-put yas/active-field-overlay 'modification-hooks '(yas/on-field-overlay-modification))
|
(overlay-put yas/active-field-overlay 'modification-hooks '(yas/on-field-overlay-modification))
|
||||||
(overlay-put yas/active-field-overlay 'insert-in-front-hooks '(yas/on-field-overlay-modification))
|
(overlay-put yas/active-field-overlay 'insert-in-front-hooks
|
||||||
(overlay-put yas/active-field-overlay 'insert-behind-hooks '(yas/on-field-overlay-modification))))
|
'(yas/on-field-overlay-modification))
|
||||||
|
(overlay-put yas/active-field-overlay 'insert-behind-hooks
|
||||||
|
'(yas/on-field-overlay-modification))))
|
||||||
|
|
||||||
(defun yas/on-field-overlay-modification (overlay after? beg end &optional length)
|
(defun yas/on-field-overlay-modification (overlay after? beg end &optional length)
|
||||||
"Clears the field and updates mirrors, conditionally.
|
"Clears the field and updates mirrors, conditionally.
|
||||||
@ -2119,7 +2289,9 @@ Move the overlays, or create them if they do not exit."
|
|||||||
"When non-nil, signals attempts to erronesly exit or modify the snippet.
|
"When non-nil, signals attempts to erronesly exit or modify the snippet.
|
||||||
|
|
||||||
Functions in the `post-command-hook', for example
|
Functions in the `post-command-hook', for example
|
||||||
`yas/post-command-handler' can check it and reset its value to nil. The variables value is the point where the violation originated")
|
`yas/post-command-handler' can check it and reset its value to
|
||||||
|
nil. The variables value is the point where the violation
|
||||||
|
originated")
|
||||||
|
|
||||||
(defun yas/on-protection-overlay-modification (overlay after? beg end &optional length)
|
(defun yas/on-protection-overlay-modification (overlay after? beg end &optional length)
|
||||||
"Signals a snippet violation, then issues error.
|
"Signals a snippet violation, then issues error.
|
||||||
@ -2155,22 +2327,39 @@ The error should be ignored in `debug-ignored-errors'"
|
|||||||
;;; they should account for all situations...
|
;;; they should account for all situations...
|
||||||
;;;
|
;;;
|
||||||
|
|
||||||
(defun yas/expand-snippet (start end template &optional snippet-vars)
|
(defun yas/expand-snippet (template &optional start end snippet-vars)
|
||||||
"Expand snippet at current point. Text between START and END
|
"Expand snippet at current point. Text between START and END
|
||||||
will be deleted before inserting template."
|
will be deleted before inserting template."
|
||||||
(run-hooks 'yas/before-expand-snippet-hook)
|
(run-hooks 'yas/before-expand-snippet-hook)
|
||||||
(goto-char start)
|
|
||||||
|
;; If a region is active, set `yas/selected-text'
|
||||||
|
(setq yas/selected-text
|
||||||
|
(when mark-active
|
||||||
|
(prog1 (buffer-substring-no-properties (region-beginning)
|
||||||
|
(region-end))
|
||||||
|
(unless start (setq start (region-beginning))
|
||||||
|
(unless end (setq end (region-end)))))))
|
||||||
|
|
||||||
|
(when start
|
||||||
|
(goto-char start))
|
||||||
|
|
||||||
;; stacked expansion: shoosh the overlay modification hooks
|
;; stacked expansion: shoosh the overlay modification hooks
|
||||||
;;
|
;;
|
||||||
(let ((key (buffer-substring-no-properties start end))
|
(let ((to-delete (and start end (buffer-substring-no-properties start end)))
|
||||||
|
(start (or start (point)))
|
||||||
|
(end (or end (point)))
|
||||||
(inhibit-modification-hooks t)
|
(inhibit-modification-hooks t)
|
||||||
(column (current-column))
|
(column (current-column))
|
||||||
snippet)
|
snippet)
|
||||||
|
|
||||||
;; Delete the trigger key, this *does* get undo-recorded.
|
|
||||||
|
|
||||||
|
|
||||||
|
;; Delete the region to delete, this *does* get undo-recorded.
|
||||||
;;
|
;;
|
||||||
|
(when to-delete
|
||||||
(delete-region start end)
|
(delete-region start end)
|
||||||
|
(setq yas/deleted-text to-delete))
|
||||||
|
|
||||||
;; Narrow the region down to the template, shoosh the
|
;; Narrow the region down to the template, shoosh the
|
||||||
;; `buffer-undo-list', and create the snippet, the new snippet
|
;; `buffer-undo-list', and create the snippet, the new snippet
|
||||||
@ -2186,12 +2375,14 @@ will be deleted before inserting template."
|
|||||||
;;
|
;;
|
||||||
(setq yas/start-column (save-restriction (widen) (current-column)))
|
(setq yas/start-column (save-restriction (widen) (current-column)))
|
||||||
(insert template)
|
(insert template)
|
||||||
(setq yas/deleted-text key)
|
|
||||||
(setq yas/selected-text (when mark-active key))
|
|
||||||
(setq snippet
|
(setq snippet
|
||||||
(if snippet-vars
|
(if snippet-vars
|
||||||
(eval `(let ,(read snippet-vars)
|
(let ((read-vars (condition-case err
|
||||||
(yas/snippet-create (point-min) (point-max))))
|
(read snippet-vars)
|
||||||
|
(error nil))))
|
||||||
|
(eval `(let ,read-vars
|
||||||
|
(yas/snippet-create (point-min) (point-max)))))
|
||||||
(yas/snippet-create (point-min) (point-max))))))
|
(yas/snippet-create (point-min) (point-max))))))
|
||||||
|
|
||||||
;; stacked-expansion: This checks for stacked expansion, save the
|
;; stacked-expansion: This checks for stacked expansion, save the
|
||||||
@ -2210,7 +2401,7 @@ will be deleted before inserting template."
|
|||||||
(yas/exit-snippet snippet))
|
(yas/exit-snippet snippet))
|
||||||
|
|
||||||
;; Push two undo actions: the deletion of the inserted contents of
|
;; Push two undo actions: the deletion of the inserted contents of
|
||||||
;; the new snippet (whitout the "key") followed by an apply of
|
;; the new snippet (without the "key") followed by an apply of
|
||||||
;; `yas/take-care-of-redo' on the newly inserted snippet boundaries
|
;; `yas/take-care-of-redo' on the newly inserted snippet boundaries
|
||||||
;;
|
;;
|
||||||
(let ((start (overlay-start (yas/snippet-control-overlay snippet)))
|
(let ((start (overlay-start (yas/snippet-control-overlay snippet)))
|
||||||
@ -2280,7 +2471,8 @@ Returns the newly created snippet."
|
|||||||
(yas/update-mirrors snippet)
|
(yas/update-mirrors snippet)
|
||||||
|
|
||||||
;; Create keymap overlay for snippet
|
;; Create keymap overlay for snippet
|
||||||
(setf (yas/snippet-control-overlay snippet) (yas/make-control-overlay snippet (point-min) (point-max)))
|
(setf (yas/snippet-control-overlay snippet)
|
||||||
|
(yas/make-control-overlay snippet (point-min) (point-max)))
|
||||||
|
|
||||||
;; Move to end
|
;; Move to end
|
||||||
(goto-char (point-max))
|
(goto-char (point-max))
|
||||||
@ -2588,7 +2780,8 @@ When multiple expressions are found, only the last one counts."
|
|||||||
(string-to-number (match-string-no-properties 1))))
|
(string-to-number (match-string-no-properties 1))))
|
||||||
(brand-new-field (and real-match-end-0
|
(brand-new-field (and real-match-end-0
|
||||||
(not (save-match-data
|
(not (save-match-data
|
||||||
(eq (string-match "$[ \t\n]*(" (match-string-no-properties 2)) 0)))
|
(eq (string-match "$[ \t\n]*("
|
||||||
|
(match-string-no-properties 2)) 0)))
|
||||||
(not (and number (zerop number)))
|
(not (and number (zerop number)))
|
||||||
(yas/make-field number
|
(yas/make-field number
|
||||||
(yas/make-marker (match-beginning 2))
|
(yas/make-marker (match-beginning 2))
|
||||||
@ -2610,7 +2803,8 @@ When multiple expressions are found, only the last one counts."
|
|||||||
(while (re-search-forward yas/multi-dollar-lisp-expression-regexp nil t)
|
(while (re-search-forward yas/multi-dollar-lisp-expression-regexp nil t)
|
||||||
(let* ((real-match-end-1 (yas/scan-sexps (match-beginning 1) 1)))
|
(let* ((real-match-end-1 (yas/scan-sexps (match-beginning 1) 1)))
|
||||||
(when real-match-end-1
|
(when real-match-end-1
|
||||||
(let ((lisp-expression-string (buffer-substring-no-properties (match-beginning 1) real-match-end-1)))
|
(let ((lisp-expression-string (buffer-substring-no-properties (match-beginning 1)
|
||||||
|
real-match-end-1)))
|
||||||
(setf (yas/field-transform parent-field) (yas/restore-escapes lisp-expression-string)))
|
(setf (yas/field-transform parent-field) (yas/restore-escapes lisp-expression-string)))
|
||||||
(yas/add-to-list dollar-regions
|
(yas/add-to-list dollar-regions
|
||||||
(cons (match-beginning 0) real-match-end-1))))))))
|
(cons (match-beginning 0) real-match-end-1))))))))
|
||||||
@ -2627,7 +2821,8 @@ When multiple expressions are found, only the last one counts."
|
|||||||
field)
|
field)
|
||||||
(push (yas/make-mirror (yas/make-marker (match-beginning 0))
|
(push (yas/make-mirror (yas/make-marker (match-beginning 0))
|
||||||
(yas/make-marker (match-beginning 0))
|
(yas/make-marker (match-beginning 0))
|
||||||
(yas/restore-escapes (buffer-substring-no-properties (match-beginning 2)
|
(yas/restore-escapes
|
||||||
|
(buffer-substring-no-properties (match-beginning 2)
|
||||||
(1- real-match-end-0))))
|
(1- real-match-end-0))))
|
||||||
(yas/field-mirrors field))
|
(yas/field-mirrors field))
|
||||||
(yas/add-to-list dollar-regions
|
(yas/add-to-list dollar-regions
|
||||||
@ -2693,7 +2888,8 @@ When multiple expressions are found, only the last one counts."
|
|||||||
(let ((reflection (or (yas/apply-transform mirror field)
|
(let ((reflection (or (yas/apply-transform mirror field)
|
||||||
(yas/field-text-for-display field))))
|
(yas/field-text-for-display field))))
|
||||||
(when (and reflection
|
(when (and reflection
|
||||||
(not (string= reflection (buffer-substring-no-properties (yas/mirror-start mirror) (yas/mirror-end mirror)))))
|
(not (string= reflection (buffer-substring-no-properties (yas/mirror-start mirror)
|
||||||
|
(yas/mirror-end mirror)))))
|
||||||
(goto-char (yas/mirror-start mirror))
|
(goto-char (yas/mirror-start mirror))
|
||||||
(insert reflection)
|
(insert reflection)
|
||||||
(if (> (yas/mirror-end mirror) (point))
|
(if (> (yas/mirror-end mirror) (point))
|
||||||
@ -2708,7 +2904,8 @@ When multiple expressions are found, only the last one counts."
|
|||||||
(transformed (yas/apply-transform field field))
|
(transformed (yas/apply-transform field field))
|
||||||
(point (point)))
|
(point (point)))
|
||||||
(when (and transformed
|
(when (and transformed
|
||||||
(not (string= transformed (buffer-substring-no-properties (yas/field-start field) (yas/field-end field)))))
|
(not (string= transformed (buffer-substring-no-properties (yas/field-start field)
|
||||||
|
(yas/field-end field)))))
|
||||||
(setf (yas/field-modified-p field) t)
|
(setf (yas/field-modified-p field) t)
|
||||||
(goto-char (yas/field-start field))
|
(goto-char (yas/field-start field))
|
||||||
(insert transformed)
|
(insert transformed)
|
||||||
@ -2759,7 +2956,24 @@ When multiple expressions are found, only the last one counts."
|
|||||||
;; shit)))
|
;; shit)))
|
||||||
;;
|
;;
|
||||||
|
|
||||||
(defun yas/debug-some-vars ()
|
(defun yas/debug-tables ()
|
||||||
|
(interactive)
|
||||||
|
(with-output-to-temp-buffer "*YASnippet tables*"
|
||||||
|
(dolist (symbol (remove nil (append (list major-mode)
|
||||||
|
(if (listp yas/mode-symbol)
|
||||||
|
yas/mode-symbol
|
||||||
|
(list yas/mode-symbol)))))
|
||||||
|
(princ (format "Snippet table hash keys for %s:\n\n" symbol))
|
||||||
|
(let ((keys))
|
||||||
|
(maphash #'(lambda (k v)
|
||||||
|
(push k keys))
|
||||||
|
(yas/snippet-table-hash (gethash symbol yas/snippet-tables)))
|
||||||
|
(princ keys))
|
||||||
|
|
||||||
|
(princ (format "Keymap for %s:\n\n" symbol))
|
||||||
|
(princ (gethash symbol yas/menu-table)))))
|
||||||
|
|
||||||
|
(defun yas/debug-snippet-vars ()
|
||||||
"Debug snippets, fields, mirrors and the `buffer-undo-list'."
|
"Debug snippets, fields, mirrors and the `buffer-undo-list'."
|
||||||
(interactive)
|
(interactive)
|
||||||
(with-output-to-temp-buffer "*YASnippet trace*"
|
(with-output-to-temp-buffer "*YASnippet trace*"
|
||||||
@ -2853,7 +3067,7 @@ When multiple expressions are found, only the last one counts."
|
|||||||
(setq abbrev "$f")
|
(setq abbrev "$f")
|
||||||
(insert abbrev))
|
(insert abbrev))
|
||||||
(unless quiet
|
(unless quiet
|
||||||
(add-hook 'post-command-hook 'yas/debug-some-vars 't 'local)))
|
(add-hook 'post-command-hook 'yas/debug-snippet-vars 't 'local)))
|
||||||
|
|
||||||
(provide 'yasnippet)
|
(provide 'yasnippet)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user