public
Description: Everyone else has a private emacs world, so why not me?
Homepage:
Clone URL: git://github.com/stuarthalloway/phoenix-emacs.git
phoenix-emacs / command_t.el
100644 91 lines (72 sloc) 2.812 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
;;;; This is a set of experiments on possible Emacs variants of TextMate's Command-T
 
;; (string-matches "h.*t" '("hot" "post" "heat"))
(defun string-matches (re list)
  (let ((result nil))
    (dolist (item list)
      (if (string-match re item)
          (setq result (cons item result))))
    result))
 
;; find phoenix matches in tags
(defun string-matches-in-tag-files (string)
  (save-excursion
    ;; If we need to ask for the tag table, allow that.
    (let ((enable-recursive-minibuffers t))
      (visit-tags-table-buffer))
    (string-matches (phoenix-search-re string) (tags-table-files))))
 
(defun phoenix-last-path-component-re (string)
  (concat (phoenix-path-component-re string) "$"))
 
;; build a path-component match re
;; (phoenix-path-component-re "12")
(defun phoenix-path-component-re (string)
  (apply 'concat (phoenix-splice (split-string string "" t) "[^/]*")))
 
;; build an re like "1[^/*]2[.*/.*]/3[^/]*4" from "12/34"
;; (phoenix-search-re "12/34")
;; (string-match (phoenix-search-re "12/34") "01/123/789/345")
(defun phoenix-search-re (string)
  (let ((names (split-string string "/" t)))
    (apply 'concat
           (phoenix-splice (mapcar 'phoenix-path-component-re names)
                           ".*/.*"))))
 
;; (phoenix-relevance-re "app/foo")
(defun phoenix-relevance-re (string)
  (apply 'concat (phoenix-splice (split-string string "/" t) "[^/]*/[^/]*")))
 
;; (phoenix-splice '(1 2 3) "+")
(defun phoenix-splice (list splice)
  (let ((result nil))
    (dolist (item list)
      (setf result (cons item result))
      (setf result (cons splice result)))
    (reverse (cdr result))))
 
;; infer the top directory of a project from the location of the
;; current tags file. Is this a reasonable assumption?
(defun phoenix-find-file-top-dir ()
  (file-name-directory tags-file-name))
 
;; sort list by relevance to string
;; early match beats late match beats no match
(defun phoenix-relevance-sort (str list)
  (let ((rel (phoenix-relevance-re str)))
    (sort list
          (lambda (x y)
            (let ((rel-x (string-match rel x))
                  (rel-y (string-match rel y)))
              (cond
               ((not rel-y) t)
               ((not rel-x) nil)
               (t (< rel-x rel-y))))))))
        
 
;; (global-set-key "\M-t" 'find-tag-file)
 
;; this does not work as well as just searching by tags
(defun find-tag-file ()
  (interactive)
  (visit-tags-table-buffer)
  (find-file (completing-read
   "Find a file: "
   'phoenix-tabs-completion
   nil t nil)))
 
(defun phoenix-tabs-completion (string pred flag)
  (let ((matches (string-matches-in-tag-files string)))
    (cond
     (flag matches)
     ; does not yet handle the lambda case correctly
     (t
      (visit-tags-table-buffer)
      (member string (tags-table-files))))))