root/lang/elisp/anything-c-yasnippet/anything-c-yasnippet.el @ 8612

Revision 8612, 15.0 kB (checked in by imakado, 5 years ago)

lang/elisp/anything-c-yasnippet/anything-c-yasnippet.el:
defvar -> defcustom
ActionsにCreate? new snippet on region、Reload All Snippts、Rename snippet file、Delete snippet fileを追加。
ライセンスを書いた。
バージョンを書いた。(0.3)

Line 
1;;; anything-c-yasnippet.el --- anything config for yasnippet.el
2
3;; Author: Kenji.I (Kenji Imakado) <ken.imakaado@gmail.com>
4;; Version: 0.3
5;; Keywords: anything yasnippet
6
7;; This file is free software; you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
9;; the Free Software Foundation; either version 2, or (at your option)
10;; any later version.
11
12;; This file is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15;; GNU General Public License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GNU Emacs; see the file COPYING.  If not, write to the
19;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20;; Boston, MA 02110-1301, USA.
21
22;;; Commentary:
23
24;; anything-source name  => anything-c-source-yasnippet
25;;
26;; Actions: Insert snippet, Open snippet file, Open snippet file other window
27;; C-z: execute-persistent-action
28
29;; here's my yasnippet's configuration
30;; (require 'yasnippet)
31;; (require 'anything-c-yasnippet)
32;; (setq anything-c-yas-space-match-any-greedy t) ;[default: nil]
33;; (global-set-key (kbd "C-c y") 'anything-c-yas-complete)
34;; (yas/initialize)
35;; (yas/load-directory "<path>/<to>/snippets/")
36;; (add-to-list 'yas/extra-mode-hooks 'ruby-mode-hook)
37;; (add-to-list 'yas/extra-mode-hooks 'cperl-mode-hook)
38
39(require 'cl)
40(require 'anything)
41(require 'yasnippet)
42
43;;; Compatibility code
44;; written by rubikitch see http://d.hatena.ne.jp/rubikitch/20071228/anythingpersistent (japanese)
45(unless (fboundp 'anything-execute-persistent-action)
46  (defun anything-execute-persistent-action ()
47    "If a candidate was selected then perform the associated action without quitting anything."
48    (interactive)
49    (save-selected-window
50      (select-window (get-buffer-window anything-buffer))
51      (select-window (setq minibuffer-scroll-window
52                           (if (one-window-p t) (split-window) (next-window (selected-window) 1))))
53      (let* ((anything-window (get-buffer-window anything-buffer))
54             (selection (if anything-saved-sources
55                            ;; the action list is shown
56                            anything-saved-selection
57                          (anything-get-selection)))
58             (default-action (anything-get-action))
59             (action (assoc-default 'persistent-action (anything-get-current-source))))
60        (setq action (or action default-action))
61        (if (and (listp action)
62                 (not (functionp action))) ; lambda
63            ;; select the default action
64            (setq action (cdar action)))
65        (set-window-dedicated-p anything-window t)
66        (unwind-protect
67            (and action selection (funcall action selection))
68          (set-window-dedicated-p anything-window nil))))))
69
70(define-key anything-map "\C-z" 'anything-execute-persistent-action)
71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
72
73;;; Code
74(defvar anything-c-yas-version "0.3" "Version of anything-c-yasnippet")
75
76(defgroup anything-c-yasnippet nil
77  "anything config yasnippet")
78
79(defcustom anything-c-yas-not-display-dups t
80  "if non-nil not display duplicate snippet otherwise display all snippet"
81  :type 'boolean
82  :group 'anything-c-yasnippet)
83
84(defcustom anything-c-yas-display-msg-after-complete t
85  "if non-nil display snippet key message in minibuffer after Complete"
86  :type 'boolean
87  :group 'anything-c-yasnippet)
88
89;(defvar anything-c-yas-snippets-dir-list nil) ;;customizable list of path(string) for finding snippet file in Action
90(defcustom anything-c-yas-snippets-dir-list nil
91  "list of directory used to find snippet file"
92  :type '(repeat (directory
93                  :tag "snippet-directory"))
94  :group 'anything-c-yasnippet)
95
96(defcustom anything-c-yas-space-match-any-greedy nil
97  "if non-nil anything pattern space match anyword greedy.
98pattern regexp: \"if else\" replace to \"if.*else\"
99match \"if (...) { ... } else { ... }\" and \"if, elsif, else ...\"
100quite convenience
101Default: nil"
102  :type 'boolean
103  :group 'anything-c-yasnippet)
104
105
106(defvar anything-c-yas-snippets-dir-list nil)
107(defadvice yas/load-directory-1 (around anything-yas-build-alist activate)
108  (let ((directory (ad-get-arg 0)))
109    (when (stringp directory)
110      (add-to-list 'anything-c-yas-snippets-dir-list directory)))
111  ad-do-it)
112
113
114(defun anything-c-yas-create-new-snippet (selected-text)
115  (let* ((mode-name (symbol-name anything-c-yas-cur-major-mode))
116         (root-dir (expand-file-name yas/root-directory))
117         (default-snippet-dir (anything-c-yas-find-recursively mode-name root-dir 'dir))
118         (dir (read-file-name "create snippet : " default-snippet-dir default-snippet-dir)))
119    (condition-case e
120        (progn (when (file-exists-p dir)
121                 (error "can't create file [%s] already exists" (file-name-nondirectory dir)))
122               ;; create buffer, insert template
123               (find-file dir)
124               (insert "#name : \n# --\n " selected-text))
125      (message "%s" (error-message-string e)))))
126
127(defun anything-c-yas-find-recursively (regexp &optional directory predicate)
128  (let ((directory (or directory default-directory))
129        (predfunc (case predicate
130                    (dir 'file-directory-p)
131                    (file 'file-regular-p)
132                    (otherwise 'identity)))
133        (files (remove-if (lambda (s) (string-match "^\\." (file-name-nondirectory  s))) (directory-files directory t)))
134        (found nil)
135        (result nil))
136    (loop for file in files
137          unless found
138          do (if (and (funcall predfunc file)
139                      (string-match regexp file))
140                 (progn (setq found t)
141                        (return (file-name-as-directory file)))
142               (when (file-directory-p file)
143                 (setq result (anything-c-yas-find-recursively regexp file predicate))))
144          finally (return result))))
145
146(defun anything-c-yas-build-cur-snippets-alist (&optional table)
147  (let* ((result-alist '((candidates) (transformed) (template-key-alist)))
148         (hash-value-alist nil)
149         (cur-table (or table (yas/snippet-table anything-c-yas-cur-major-mode)))
150         (parent-table (yas/snippet-table-parent cur-table)) ;`yas/snippet-table-parent'
151         (hash-table (yas/snippet-table-hash cur-table))) ;`yas/snippet-table-hash'
152    (maphash (lambda (k v) (setq hash-value-alist (append v hash-value-alist))) hash-table)
153    (loop with transformed
154          with templates
155          with template-key-alist
156          for lst in hash-value-alist
157          for key = (car lst)
158          for template-struct = (cdr lst)
159          for name = (yas/template-name template-struct) ;`yas/template-name'
160          for template = (yas/template-content template-struct) ;`yas/template-content'
161          do (progn (push template templates)
162                    (push `(,name . ,template) transformed)
163                    (push `(,template . ,key) template-key-alist))
164          finally (progn (push `(candidates . ,templates) result-alist)
165                         (push `(transformed . ,transformed) result-alist)
166                         (push `(template-key-alist . ,template-key-alist) result-alist)))
167    ;; if cur-table has parent build recursively
168    (when parent-table
169      (let ((rec-ret (anything-c-yas-build-cur-snippets-alist parent-table))
170            (alist-keys '(candidates transformed template-key-alist)))
171        (mapc (lambda (key)
172                (let ((res-list (assq key result-alist))
173                      (rec-val (assoc-default key rec-ret)))
174                  (setcdr res-list (nconc rec-val (cdr res-list)))))
175              alist-keys)))
176    result-alist))
177
178(defun anything-c-yas-get-modes ()
179  (let ((cur-major-mode anything-c-yas-cur-major-mode))
180    (list cur-major-mode)))
181
182(defun anything-c-yas-get-cmp-context ()
183  "Return list (initial-input point-start point-end)
184like `yas/current-key'"
185  (let ((start (point))
186        (end (point))
187        (syntax "w_"))
188    (condition-case nil
189        (save-excursion
190          (when mark-active
191            (error ""))
192          (skip-syntax-backward syntax)
193          (setq start (point))
194          (values (buffer-substring-no-properties start end) start end))
195      (error (values "" (point) (point))))))
196
197(defun anything-c-yas-get-key-by-template (template alist) ;str template
198  "Return key"
199  (assoc-default template (assoc-default 'template-key-alist alist)))
200
201(defun anything-c-yas-get-candidates (alist)
202  "Return list of template"
203  (assoc-default 'candidates alist 'eq))
204
205(defun anything-c-yas-get-transformed-list (alist initial-input)
206  "Return list of dotlist, (DISPLAY . REAL) DISPLAY is name of snippet, REAL is template of snippet"
207  (let ((transformed-list (assoc-default 'transformed alist 'eq)))
208    (setq transformed-list (remove-if-not (lambda (lst)
209                                            (string-match (concat "^" (regexp-quote initial-input)) (car lst)))
210                                          transformed-list))
211    (when anything-c-yas-not-display-dups
212      (setq transformed-list (delete-dups transformed-list)))
213    ;; sort
214    (setq transformed-list (sort* transformed-list 'string< :key 'car))
215    transformed-list))
216
217(defun anything-c-yas-find-snippet-file-by-key (key)
218  (let ((modes (anything-c-yas-get-modes))
219        (snippet-dirs (add-to-list 'anything-c-yas-snippets-dir-list yas/root-directory)))
220    (let ((found-path (loop for mode in modes
221                            for test-re = (concat (symbol-name mode) "/" key "$")
222                            for path =  (anything-c-yas-find-snippet-file-aux test-re snippet-dirs)
223                            when path return path)))
224      ;; if not found in major-mode try to find in all dirs
225      (unless found-path
226        (setq found-path (anything-c-yas-find-snippet-file-aux (concat "/" key "$") snippet-dirs)))
227      found-path)))
228
229(defun anything-c-yas-find-snippet-file-aux (test-re dirs)
230  (loop with done
231        with path
232        for directory in dirs
233        for files = (directory-files directory t)
234        unless done
235        do (loop for file in files
236                 when (string-match test-re file)
237                 return (setq done t
238                              path file))
239        finally return path))
240
241(defun anything-c-yas-find-file-snippet-by-template (template &optional other-window)
242  (let* ((path (anything-c-yas-get-path-by-template template))
243         (ff-func (if other-window 'find-file-other-window 'find-file)))
244    (if path
245        (funcall ff-func path)
246      (message "not found snippet file"))))
247
248(defun anything-c-yas-get-path-by-template (template)
249  (let* ((key (anything-c-yas-get-key-by-template template anything-c-yas-cur-snippets-alist))
250         (path (anything-c-yas-find-snippet-file-by-key key)))
251    path))
252
253(defun anything-c-yas-match (candidate)
254  "if customize variable `anything-c-yas-space-match-any-greedy' is non-nil
255space match anyword greedy"
256  (cond
257   (anything-c-yas-space-match-any-greedy
258    (let ((re (replace-regexp-in-string "[ \t]+" ".*" anything-pattern)))
259      (string-match re candidate)))
260   (t
261    (string-match anything-pattern candidate))))
262
263(defvar anything-c-yas-cur-snippets-alist nil)
264(defvar anything-c-yas-initial-input "")
265(defvar anything-c-yas-point-start nil)
266(defvar anything-c-yas-point-end nil)
267(defvar anything-c-yas-cur-major-mode nil)
268(defvar anything-c-yas-selected-text "" "region text if mark-active otherwise \"\"")
269(defvar anything-c-source-yasnippet
270  `((name . "Yasnippet")
271    (init . (lambda ()
272              (setq anything-c-yas-cur-major-mode major-mode)
273              (setq anything-c-yas-selected-text (if mark-active (buffer-substring-no-properties (region-beginning) (region-end)) ""))
274              (multiple-value-setq
275                  (anything-c-yas-initial-input anything-c-yas-point-start anything-c-yas-point-end) (anything-c-yas-get-cmp-context)) ;return values(str point point)
276              (setq anything-c-yas-cur-snippets-alist (anything-c-yas-build-cur-snippets-alist))))
277;;     (candidates . (lambda ()
278;;                     (anything-c-yas-get-candidates anything-c-yas-cur-snippets-alist)))
279    (candidates . (anything-c-yas-get-candidates anything-c-yas-cur-snippets-alist))
280    (candidate-transformer . (lambda (candidates)
281                               (anything-c-yas-get-transformed-list anything-c-yas-cur-snippets-alist anything-c-yas-initial-input)))
282    (action . (("Insert snippet" . (lambda (template)
283                                     (yas/expand-snippet anything-c-yas-point-start anything-c-yas-point-end template)
284                                     (when anything-c-yas-display-msg-after-complete
285                                       (message "this snippet is bound to [ %s ]"
286                                                (anything-c-yas-get-key-by-template template anything-c-yas-cur-snippets-alist)))))
287               ("Open snippet file" . (lambda (template)
288                                        (anything-c-yas-find-file-snippet-by-template template)))
289               ("Open snippet file other window" . (lambda (template)
290                                                     (anything-c-yas-find-file-snippet-by-template template t)))
291               ("Create new snippet on region" . (lambda (template)
292                                                   (anything-c-yas-create-new-snippet anything-c-yas-selected-text)))
293               ("Reload All Snippts" . (lambda (template)
294                                         (yas/reload-all)
295                                         (message "Reload All Snippts done")))
296               ("Rename snippet file" . (lambda (template)
297                                       (let* ((path (or (anything-c-yas-get-path-by-template template) ""))
298                                              (dir (file-name-directory path))
299                                              (filename (file-name-nondirectory path))
300                                              (rename-to (read-string (concat "rename [" filename "] to: "))))
301                                         (rename-file path (concat dir rename-to))
302                                         (yas/reload-all))))
303               ("Delete snippet file" . (lambda (template)
304                                          (let ((path (or (anything-c-yas-get-path-by-template template) "")))
305                                            (when (y-or-n-p "really delete?")
306                                              (delete-file path)
307                                              (yas/reload-all)))))))
308    (persistent-action . (lambda (template)
309                           (anything-c-yas-find-file-snippet-by-template template)))
310    (match . (anything-c-yas-match))))
311
312
313;;; Commands
314(defun anything-c-yas-complete ()
315  (interactive)
316  (let ((anything-sources (list anything-c-source-yasnippet)))
317    (anything)))
318
319(defun anything-c-yas-create-snippet-on-regin (&optional start end)
320  (interactive "r")
321  (let ((str (buffer-substring-no-properties start end)))
322    (anything-c-yas-create-new-snippet str)))
323 
324
325(provide 'anything-c-yasnippet)
326;; anything-c-yasnippet.el ends here
Note: See TracBrowser for help on using the browser.