summaryrefslogtreecommitdiff
path: root/helm-call-tree.el
blob: d446ec7f2f9655a6d9ce62943d3d12ed82dabdef (plain)
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
;;; helm-call-tree.el --- Helm interface of `simple-call-tree.el'.

;; Copyright (C) 2012 Thierry Volpiatto <thierry.volpiatto@gmail.com>

;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

;; <http://www.emacswiki.org/cgi-bin/wiki/download/simple-call-tree.el>

;;; Code:

(eval-when-compile (require 'cl))
(require 'helm)

(declare-function simple-call-tree-analyze "ext:simple-call-tree.el" (&optional test))

;; Function is called by
(defvar helm-c-source-simple-call-tree-functions-callers
  '((name . "Function is called by")
    (init . helm-c-simple-call-tree-functions-callers-init)
    (multiline)
    (candidates . helm-c-simple-call-tree-candidates)
    (persistent-action . helm-c-simple-call-tree-persistent-action)
    (persistent-help . "Show function definitions by rotation")
    (action ("Find definition selected by persistent-action" .
             helm-c-simple-call-tree-find-definition)))
  "Needs simple-call-tree.el.
http://www.emacswiki.org/cgi-bin/wiki/download/simple-call-tree.el")

(defvar helm-c-simple-call-tree-tick nil)
(make-variable-buffer-local 'helm-c-simple-call-tree-tick)
(defun helm-c-simple-call-tree-analyze-maybe ()
  (unless (eq (buffer-chars-modified-tick) helm-c-simple-call-tree-tick)
    (simple-call-tree-analyze)
    (setq helm-c-simple-call-tree-tick (buffer-chars-modified-tick))))

(defun helm-c-simple-call-tree-init-base (function message)
  (require 'simple-call-tree)
  (with-no-warnings
    (when (helm-current-buffer-is-modified)
      (helm-c-simple-call-tree-analyze-maybe)
      (let ((list (funcall function simple-call-tree-alist)))
        (with-current-buffer (helm-candidate-buffer 'local)
          (dolist (entry list)
            (let ((funcs (concat "  " (mapconcat #'identity (cdr entry) "\n  "))))
              (insert (car entry) message
                      (if (string= funcs "  ")
                          "  no functions."
                          funcs)
                      "\n\n"))))))))

(defun helm-c-simple-call-tree-functions-callers-init ()
  (helm-c-simple-call-tree-init-base 'simple-call-tree-invert
                                     " is called by\n"))

(defun helm-c-simple-call-tree-candidates ()
  (with-current-buffer (helm-candidate-buffer)
    (split-string (buffer-string) "\n\n")))

(defvar helm-c-simple-call-tree-related-functions nil)
(defvar helm-c-simple-call-tree-function-index 0)
(defun helm-c-simple-call-tree-persistent-action (candidate)
  (unless (eq last-command 'helm-execute-persistent-action)
    (setq helm-c-simple-call-tree-related-functions
          (delete "no functions."
                  (split-string
                   (replace-regexp-in-string "  \\| is called by\\| calls "
                                             "" candidate)
                   "\n")))
    (setq helm-c-simple-call-tree-function-index -1))
  (incf helm-c-simple-call-tree-function-index)
  (helm-c-simple-call-tree-find-definition candidate))

(defun helm-c-simple-call-tree-find-definition (candidate)
  (find-function
   (intern
    (nth (mod helm-c-simple-call-tree-function-index
              (length helm-c-simple-call-tree-related-functions))
         helm-c-simple-call-tree-related-functions))))


;;; Function calls
(defvar helm-c-source-simple-call-tree-callers-functions
  '((name . "Function calls")
    (init . helm-c-simple-call-tree-callers-functions-init)
    (multiline)
    (candidates . helm-c-simple-call-tree-candidates)
    (persistent-action . helm-c-simple-call-tree-persistent-action)
    (persistent-help . "Show function definitions by rotation")
    (action ("Find definition selected by persistent-action" .
             helm-c-simple-call-tree-find-definition)))
  "Needs simple-call-tree.el.
http://www.emacswiki.org/cgi-bin/wiki/download/simple-call-tree.el")

(defun helm-c-simple-call-tree-callers-functions-init ()
  (helm-c-simple-call-tree-init-base 'identity " calls \n"))

;;;###autoload
(defun helm-simple-call-tree ()
  "Preconfigured `helm' for simple-call-tree. List function relationships.

Needs simple-call-tree.el.
http://www.emacswiki.org/cgi-bin/wiki/download/simple-call-tree.el"
  (interactive)
  (helm-other-buffer
   '(helm-c-source-simple-call-tree-functions-callers
     helm-c-source-simple-call-tree-callers-functions)
   "*helm simple-call-tree*"))

(provide 'helm-call-tree)

;; Local Variables:
;; coding: utf-8
;; indent-tabs-mode: nil
;; byte-compile-dynamic: t
;; End:

;;; helm-call-tree.el ends here