]> gitweb.factorcode.org Git - factor.git/blob - misc/fuel/fuel-xref.el
FUEL: Display lists of callers/callees, linked to their source.
[factor.git] / misc / fuel / fuel-xref.el
1 ;;; fuel-xref.el -- showing cross-reference info
2
3 ;; Copyright (C) 2008 Jose Antonio Ortega Ruiz
4 ;; See http://factorcode.org/license.txt for BSD license.
5
6 ;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
7 ;; Keywords: languages, fuel, factor
8 ;; Start date: Sat Dec 20, 2008 22:00
9
10 ;;; Comentary:
11
12 ;; A mode and utilities for showing cross-reference information.
13
14 ;;; Code:
15
16 (require 'fuel-base)
17
18 (require 'button)
19
20 \f
21 ;;; Customization:
22
23 (defgroup fuel-xref nil
24   "FUEL's cross-referencing engine."
25   :group 'fuel)
26
27 \f
28 ;;; Buttons:
29
30 (define-button-type 'fuel-xref--button-type
31   'action 'fuel-xref--follow-link
32   'follow-link t
33   'face 'default)
34
35 (defun fuel-xref--follow-link (button)
36   (let ((file (button-get button 'file))
37         (line (button-get button 'line)))
38     (when (not file)
39       (error "No file for this ref"))
40     (when (not (file-readable-p file))
41       (error "File '%s' is not readable" file))
42     (find-file-other-window file)
43     (when (numberp line) (goto-line line))))
44
45 \f
46 ;;; The xref buffer:
47
48 (defvar fuel-xref--buffer-name "*fuel xref*")
49
50 (defun fuel-xref--get-buffer ()
51   (let ((buffer (get-buffer fuel-xref--buffer-name)))
52     (or (and (buffer-live-p buffer) buffer)
53         (prog1
54             (set-buffer (get-buffer-create fuel-xref--buffer-name))
55           (fuel-xref-mode)))))
56
57 (defvar fuel-xref--help-string "(Press RET or click to follow crossrefs)")
58
59 (defun fuel-xref--fill-buffer (title refs)
60   (let ((inhibit-read-only t))
61     (with-current-buffer (fuel-xref--get-buffer)
62       (erase-buffer)
63       (insert title "\n\n")
64       (dolist (ref refs)
65         (when (and (first ref) (second ref) (numberp (third ref)))
66           (insert "  ")
67           (insert-text-button (first ref)
68                               :type 'fuel-xref--button-type
69                               'help-echo (format "File: %s (%s)"
70                                                  (second ref)
71                                                  (third ref))
72                               'file (second ref)
73                               'line (third ref))
74           (newline)))
75       (when refs
76         (insert "\n\n" fuel-xref--help-string "\n"))
77       (goto-char (point-min)))))
78
79 (defun fuel-xref--show-callers (word)
80   (let* ((cmd `(:fuel* (((:quote ,word) fuel-callers-xref))))
81          (res (fuel-eval--retort-result (fuel-eval--send/wait cmd)))
82          (title (format (if res "Callers of '%s':"
83                           "No callers found for '%s'")
84                         word)))
85     (fuel-xref--fill-buffer title res)
86     (pop-to-buffer (fuel-xref--get-buffer))))
87
88 (defun fuel-xref--show-callees (word)
89   (let* ((cmd `(:fuel* (((:quote ,word) fuel-callees-xref))))
90          (res (fuel-eval--retort-result (fuel-eval--send/wait cmd)))
91          (title (format (if res "Words called by '%s':"
92                           "No callees found for '%s'")
93                         word)))
94     (fuel-xref--fill-buffer title res)
95     (pop-to-buffer (fuel-xref--get-buffer))))
96
97 \f
98 ;;; Xref mode:
99
100 (defvar fuel-xref-mode-map
101   (let ((map (make-sparse-keymap)))
102     (suppress-keymap map)
103     (set-keymap-parent map button-buffer-map)
104     (define-key map "q" 'bury-buffer)
105     map))
106
107 (defun fuel-xref-mode ()
108   "Mode for displaying FUEL cross-reference information.
109 \\{fuel-xref-mode-map}"
110   (interactive)
111   (kill-all-local-variables)
112   (buffer-disable-undo)
113   (use-local-map fuel-xref-mode-map)
114   (setq mode-name "FUEL Xref")
115   (setq major-mode 'fuel-xref-mode)
116   (fuel-font-lock--font-lock-setup)
117   (setq buffer-read-only t))
118
119 \f
120 (provide 'fuel-xref)
121 ;;; fuel-xref.el ends here