2008-12-20 19:43:28 -05:00
|
|
|
|
;;; fuel-xref.el -- showing cross-reference info
|
|
|
|
|
|
2009-01-03 10:37:28 -05:00
|
|
|
|
;; Copyright (C) 2008, 2009 Jose Antonio Ortega Ruiz
|
2008-12-20 19:43:28 -05:00
|
|
|
|
;; See http://factorcode.org/license.txt for BSD license.
|
|
|
|
|
|
|
|
|
|
;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
|
|
|
|
|
;; Keywords: languages, fuel, factor
|
|
|
|
|
;; Start date: Sat Dec 20, 2008 22:00
|
|
|
|
|
|
|
|
|
|
;;; Comentary:
|
|
|
|
|
|
|
|
|
|
;; A mode and utilities for showing cross-reference information.
|
|
|
|
|
|
|
|
|
|
;;; Code:
|
|
|
|
|
|
2009-01-08 12:47:17 -05:00
|
|
|
|
(require 'fuel-edit)
|
|
|
|
|
(require 'fuel-completion)
|
2009-01-05 01:08:45 -05:00
|
|
|
|
(require 'fuel-help)
|
2008-12-21 11:33:53 -05:00
|
|
|
|
(require 'fuel-eval)
|
2008-12-21 12:39:59 -05:00
|
|
|
|
(require 'fuel-syntax)
|
2008-12-21 11:33:53 -05:00
|
|
|
|
(require 'fuel-popup)
|
|
|
|
|
(require 'fuel-font-lock)
|
2008-12-20 19:43:28 -05:00
|
|
|
|
(require 'fuel-base)
|
|
|
|
|
|
|
|
|
|
(require 'button)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; Customization:
|
|
|
|
|
|
|
|
|
|
(defgroup fuel-xref nil
|
|
|
|
|
"FUEL's cross-referencing engine."
|
|
|
|
|
:group 'fuel)
|
|
|
|
|
|
2008-12-21 12:39:59 -05:00
|
|
|
|
(defcustom fuel-xref-follow-link-to-word-p t
|
|
|
|
|
"Whether, when following a link to a caller, we position the
|
|
|
|
|
cursor at the first ocurrence of the used word."
|
|
|
|
|
:group 'fuel-xref
|
|
|
|
|
:type 'boolean)
|
|
|
|
|
|
2009-01-22 03:55:39 -05:00
|
|
|
|
(fuel-edit--define-custom-visit
|
|
|
|
|
fuel-xref-follow-link-method
|
|
|
|
|
fuel-xref
|
|
|
|
|
"How new buffers are opened when following a crossref link.")
|
|
|
|
|
|
2008-12-21 11:33:53 -05:00
|
|
|
|
(fuel-font-lock--defface fuel-font-lock-xref-link
|
|
|
|
|
'link fuel-xref "highlighting links in cross-reference buffers")
|
|
|
|
|
|
|
|
|
|
(fuel-font-lock--defface fuel-font-lock-xref-vocab
|
|
|
|
|
'italic fuel-xref "vocabulary names in cross-reference buffers")
|
|
|
|
|
|
2008-12-20 19:43:28 -05:00
|
|
|
|
|
|
|
|
|
;;; Buttons:
|
|
|
|
|
|
|
|
|
|
(define-button-type 'fuel-xref--button-type
|
|
|
|
|
'action 'fuel-xref--follow-link
|
|
|
|
|
'follow-link t
|
2008-12-21 11:33:53 -05:00
|
|
|
|
'face 'fuel-font-lock-xref-link)
|
2008-12-20 19:43:28 -05:00
|
|
|
|
|
|
|
|
|
(defun fuel-xref--follow-link (button)
|
|
|
|
|
(let ((file (button-get button 'file))
|
|
|
|
|
(line (button-get button 'line)))
|
|
|
|
|
(when (not file)
|
|
|
|
|
(error "No file for this ref"))
|
|
|
|
|
(when (not (file-readable-p file))
|
|
|
|
|
(error "File '%s' is not readable" file))
|
2008-12-21 12:39:59 -05:00
|
|
|
|
(let ((word fuel-xref--word))
|
2009-01-22 03:55:39 -05:00
|
|
|
|
(fuel-edit--visit-file file fuel-xref-follow-link-method)
|
2008-12-21 12:39:59 -05:00
|
|
|
|
(when (numberp line) (goto-line line))
|
|
|
|
|
(when (and word fuel-xref-follow-link-to-word-p)
|
2009-01-22 03:55:39 -05:00
|
|
|
|
(and (re-search-forward (format "\\_<%s\\_>" word)
|
|
|
|
|
(fuel-syntax--end-of-defun-pos)
|
|
|
|
|
t)
|
2008-12-21 12:39:59 -05:00
|
|
|
|
(goto-char (match-beginning 0)))))))
|
2008-12-20 19:43:28 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; The xref buffer:
|
|
|
|
|
|
2008-12-21 10:04:39 -05:00
|
|
|
|
(fuel-popup--define fuel-xref--buffer
|
|
|
|
|
"*fuel xref*" 'fuel-xref-mode)
|
2008-12-20 19:43:28 -05:00
|
|
|
|
|
2008-12-21 12:39:59 -05:00
|
|
|
|
(make-local-variable (defvar fuel-xref--word nil))
|
|
|
|
|
|
2009-01-05 01:08:45 -05:00
|
|
|
|
(defvar fuel-xref--help-string
|
|
|
|
|
"(Press RET or click to follow crossrefs, or h for help on word at point)")
|
2008-12-20 19:43:28 -05:00
|
|
|
|
|
2009-01-22 15:13:38 -05:00
|
|
|
|
(defun fuel-xref--title (word cc count thing)
|
2009-01-03 20:36:58 -05:00
|
|
|
|
(put-text-property 0 (length word) 'font-lock-face 'bold word)
|
2009-01-22 15:13:38 -05:00
|
|
|
|
(cond ((zerop count) (format "No known %s %s %s" thing cc word))
|
|
|
|
|
((= 1 count) (format "1 %s %s %s:" thing cc word))
|
|
|
|
|
(t (format "%s %ss %s %s:" count thing cc word))))
|
2008-12-21 12:39:59 -05:00
|
|
|
|
|
2009-01-08 12:47:17 -05:00
|
|
|
|
(defun fuel-xref--insert-ref (ref &optional no-vocab)
|
2008-12-21 12:39:59 -05:00
|
|
|
|
(when (and (stringp (first ref))
|
|
|
|
|
(stringp (third ref))
|
|
|
|
|
(numberp (fourth ref)))
|
|
|
|
|
(insert " ")
|
|
|
|
|
(insert-text-button (first ref)
|
|
|
|
|
:type 'fuel-xref--button-type
|
|
|
|
|
'help-echo (format "File: %s (%s)"
|
|
|
|
|
(third ref)
|
|
|
|
|
(fourth ref))
|
|
|
|
|
'file (third ref)
|
|
|
|
|
'line (fourth ref))
|
2009-01-08 12:47:17 -05:00
|
|
|
|
(when (and (not no-vocab) (stringp (second ref)))
|
2008-12-21 12:39:59 -05:00
|
|
|
|
(insert (format " (in %s)" (second ref))))
|
|
|
|
|
(newline)
|
|
|
|
|
t))
|
2008-12-21 11:33:53 -05:00
|
|
|
|
|
2009-01-22 15:13:38 -05:00
|
|
|
|
(defun fuel-xref--fill-buffer (word cc refs &optional no-vocab app thing)
|
2008-12-21 11:33:53 -05:00
|
|
|
|
(let ((inhibit-read-only t)
|
|
|
|
|
(count 0))
|
2008-12-21 10:04:39 -05:00
|
|
|
|
(with-current-buffer (fuel-xref--buffer)
|
2009-01-08 12:47:17 -05:00
|
|
|
|
(let ((start (if app (goto-char (point-max))
|
|
|
|
|
(erase-buffer)
|
|
|
|
|
(point-min))))
|
|
|
|
|
(dolist (ref refs)
|
|
|
|
|
(when (fuel-xref--insert-ref ref no-vocab) (setq count (1+ count))))
|
|
|
|
|
(newline)
|
|
|
|
|
(goto-char start)
|
|
|
|
|
(save-excursion
|
2009-01-22 15:13:38 -05:00
|
|
|
|
(insert (fuel-xref--title word cc count (or thing "word")) "\n\n"))
|
2009-01-08 12:47:17 -05:00
|
|
|
|
count))))
|
|
|
|
|
|
2009-01-22 15:13:38 -05:00
|
|
|
|
(defun fuel-xref--fill-and-display (word cc refs &optional no-vocab thing)
|
|
|
|
|
(let ((count (fuel-xref--fill-buffer word cc refs no-vocab nil (or thing "word"))))
|
2008-12-21 12:39:59 -05:00
|
|
|
|
(if (zerop count)
|
2009-01-22 15:13:38 -05:00
|
|
|
|
(error (fuel-xref--title word cc 0 (or thing "word")))
|
2008-12-21 12:39:59 -05:00
|
|
|
|
(message "")
|
|
|
|
|
(fuel-popup--display (fuel-xref--buffer)))))
|
2008-12-20 19:43:28 -05:00
|
|
|
|
|
2009-01-22 17:25:17 -05:00
|
|
|
|
(defun fuel-xref--callers (word)
|
|
|
|
|
(let ((cmd `(:fuel* (((:quote ,word) fuel-callers-xref)))))
|
|
|
|
|
(fuel-eval--retort-result (fuel-eval--send/wait cmd))))
|
|
|
|
|
|
2008-12-20 19:43:28 -05:00
|
|
|
|
(defun fuel-xref--show-callers (word)
|
2009-01-22 17:25:17 -05:00
|
|
|
|
(let ((refs (fuel-xref--callers word)))
|
2009-01-22 03:55:39 -05:00
|
|
|
|
(with-current-buffer (fuel-xref--buffer) (setq fuel-xref--word word))
|
2009-01-22 17:25:17 -05:00
|
|
|
|
(fuel-xref--fill-and-display word "using" refs)))
|
|
|
|
|
|
|
|
|
|
(defun fuel-xref--word-callers-files (word)
|
|
|
|
|
(mapcar 'third (fuel-xref--callers word)))
|
2008-12-20 19:43:28 -05:00
|
|
|
|
|
|
|
|
|
(defun fuel-xref--show-callees (word)
|
|
|
|
|
(let* ((cmd `(:fuel* (((:quote ,word) fuel-callees-xref))))
|
2008-12-21 11:33:53 -05:00
|
|
|
|
(res (fuel-eval--retort-result (fuel-eval--send/wait cmd))))
|
2009-01-22 03:55:39 -05:00
|
|
|
|
(with-current-buffer (fuel-xref--buffer) (setq fuel-xref--word nil))
|
2009-01-03 20:36:58 -05:00
|
|
|
|
(fuel-xref--fill-and-display word "used by" res)))
|
|
|
|
|
|
|
|
|
|
(defun fuel-xref--apropos (str)
|
|
|
|
|
(let* ((cmd `(:fuel* ((,str fuel-apropos-xref))))
|
|
|
|
|
(res (fuel-eval--retort-result (fuel-eval--send/wait cmd))))
|
2009-01-22 03:55:39 -05:00
|
|
|
|
(with-current-buffer (fuel-xref--buffer) (setq fuel-xref--word nil))
|
2009-01-03 20:36:58 -05:00
|
|
|
|
(fuel-xref--fill-and-display str "containing" res)))
|
2008-12-20 19:43:28 -05:00
|
|
|
|
|
2009-01-08 12:47:17 -05:00
|
|
|
|
(defun fuel-xref--show-vocab (vocab &optional app)
|
|
|
|
|
(let* ((cmd `(:fuel* ((,vocab fuel-vocab-xref)) ,vocab))
|
|
|
|
|
(res (fuel-eval--retort-result (fuel-eval--send/wait cmd))))
|
2009-01-22 03:55:39 -05:00
|
|
|
|
(with-current-buffer (fuel-xref--buffer) (setq fuel-xref--word nil))
|
2009-01-08 12:47:17 -05:00
|
|
|
|
(fuel-xref--fill-buffer vocab "in vocabulary" res t app)))
|
|
|
|
|
|
|
|
|
|
(defun fuel-xref--show-vocab-words (vocab &optional private)
|
|
|
|
|
(fuel-xref--show-vocab vocab)
|
|
|
|
|
(when private
|
|
|
|
|
(fuel-xref--show-vocab (format "%s.private" (substring-no-properties vocab))
|
|
|
|
|
t))
|
|
|
|
|
(fuel-popup--display (fuel-xref--buffer))
|
|
|
|
|
(goto-char (point-min)))
|
|
|
|
|
|
2009-01-22 15:13:38 -05:00
|
|
|
|
(defun fuel-xref--show-vocab-usage (vocab)
|
|
|
|
|
(let* ((cmd `(:fuel* ((,vocab fuel-vocab-usage-xref))))
|
|
|
|
|
(res (fuel-eval--retort-result (fuel-eval--send/wait cmd))))
|
|
|
|
|
(with-current-buffer (fuel-xref--buffer) (setq fuel-xref--word nil))
|
|
|
|
|
(fuel-xref--fill-and-display vocab "using" res t "vocab")))
|
|
|
|
|
|
|
|
|
|
(defun fuel-xref--show-vocab-uses (vocab)
|
|
|
|
|
(let* ((cmd `(:fuel* ((,vocab fuel-vocab-uses-xref))))
|
|
|
|
|
(res (fuel-eval--retort-result (fuel-eval--send/wait cmd))))
|
|
|
|
|
(with-current-buffer (fuel-xref--buffer) (setq fuel-xref--word nil))
|
|
|
|
|
(fuel-xref--fill-and-display vocab "used by" res t "vocab")))
|
|
|
|
|
|
2009-01-08 12:47:17 -05:00
|
|
|
|
|
|
|
|
|
;;; User commands:
|
|
|
|
|
|
|
|
|
|
(defvar fuel-xref--word-history nil)
|
|
|
|
|
|
|
|
|
|
(defun fuel-show-callers (&optional arg)
|
2009-01-22 15:13:38 -05:00
|
|
|
|
"Show a list of callers of word or vocabulary at point.
|
2009-01-08 12:47:17 -05:00
|
|
|
|
With prefix argument, ask for word."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(let ((word (if arg (fuel-completion--read-word "Find callers for: "
|
|
|
|
|
(fuel-syntax-symbol-at-point)
|
|
|
|
|
fuel-xref--word-history)
|
|
|
|
|
(fuel-syntax-symbol-at-point))))
|
|
|
|
|
(when word
|
2009-01-22 15:13:38 -05:00
|
|
|
|
(message "Looking up %s's users ..." word)
|
|
|
|
|
(if (and (not arg)
|
|
|
|
|
(fuel-edit--looking-at-vocab))
|
|
|
|
|
(fuel-xref--show-vocab-usage word)
|
|
|
|
|
(fuel-xref--show-callers word)))))
|
2009-01-08 12:47:17 -05:00
|
|
|
|
|
|
|
|
|
(defun fuel-show-callees (&optional arg)
|
2009-01-22 15:13:38 -05:00
|
|
|
|
"Show a list of callers of word or vocabulary at point.
|
2009-01-08 12:47:17 -05:00
|
|
|
|
With prefix argument, ask for word."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(let ((word (if arg (fuel-completion--read-word "Find callees for: "
|
|
|
|
|
(fuel-syntax-symbol-at-point)
|
|
|
|
|
fuel-xref--word-history)
|
|
|
|
|
(fuel-syntax-symbol-at-point))))
|
|
|
|
|
(when word
|
|
|
|
|
(message "Looking up %s's callees ..." word)
|
2009-01-22 15:13:38 -05:00
|
|
|
|
(if (and (not arg)
|
|
|
|
|
(fuel-edit--looking-at-vocab))
|
|
|
|
|
(fuel-xref--show-vocab-uses word)
|
|
|
|
|
(fuel-xref--show-callees word)))))
|
|
|
|
|
|
|
|
|
|
(defvar fuel-xref--vocab-history nil)
|
|
|
|
|
|
|
|
|
|
(defun fuel-vocab-uses (&optional arg)
|
|
|
|
|
"Show a list of vocabularies used by a given one.
|
|
|
|
|
With prefix argument, force reload of vocabulary list."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(let ((vocab (fuel-completion--read-vocab arg
|
|
|
|
|
(fuel-syntax-symbol-at-point)
|
|
|
|
|
fuel-xref--vocab-history)))
|
|
|
|
|
(fuel-xref--show-vocab-uses vocab)))
|
|
|
|
|
|
|
|
|
|
(defun fuel-vocab-usage (&optional arg)
|
|
|
|
|
"Show a list of vocabularies that use a given one.
|
|
|
|
|
With prefix argument, force reload of vocabulary list."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(let ((vocab (fuel-completion--read-vocab arg
|
|
|
|
|
(fuel-syntax-symbol-at-point)
|
|
|
|
|
fuel-xref--vocab-history)))
|
|
|
|
|
(fuel-xref--show-vocab-usage vocab)))
|
2009-01-08 12:47:17 -05:00
|
|
|
|
|
|
|
|
|
(defun fuel-apropos (str)
|
|
|
|
|
"Show a list of words containing the given substring."
|
|
|
|
|
(interactive "MFind words containing: ")
|
|
|
|
|
(message "Looking up %s's references ..." str)
|
|
|
|
|
(fuel-xref--apropos str))
|
|
|
|
|
|
|
|
|
|
(defun fuel-show-file-words (&optional arg)
|
|
|
|
|
"Show a list of words in current file.
|
|
|
|
|
With prefix argument, ask for the vocab."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(let ((vocab (or (and (not arg) (fuel-syntax--current-vocab))
|
2009-02-05 04:28:57 -05:00
|
|
|
|
(fuel-completion--read-vocab nil))))
|
2009-01-08 12:47:17 -05:00
|
|
|
|
(when vocab
|
|
|
|
|
(fuel-xref--show-vocab-words vocab
|
|
|
|
|
(fuel-syntax--file-has-private)))))
|
|
|
|
|
|
|
|
|
|
|
2008-12-20 19:43:28 -05:00
|
|
|
|
|
|
|
|
|
;;; Xref mode:
|
|
|
|
|
|
2009-01-05 01:08:45 -05:00
|
|
|
|
(defun fuel-xref-show-help ()
|
|
|
|
|
(interactive)
|
|
|
|
|
(let ((fuel-help-always-ask nil))
|
|
|
|
|
(fuel-help)))
|
|
|
|
|
|
2008-12-20 19:43:28 -05:00
|
|
|
|
(defvar fuel-xref-mode-map
|
|
|
|
|
(let ((map (make-sparse-keymap)))
|
|
|
|
|
(suppress-keymap map)
|
|
|
|
|
(set-keymap-parent map button-buffer-map)
|
2009-01-05 01:08:45 -05:00
|
|
|
|
(define-key map "h" 'fuel-xref-show-help)
|
2008-12-20 19:43:28 -05:00
|
|
|
|
map))
|
|
|
|
|
|
|
|
|
|
(defun fuel-xref-mode ()
|
|
|
|
|
"Mode for displaying FUEL cross-reference information.
|
|
|
|
|
\\{fuel-xref-mode-map}"
|
|
|
|
|
(interactive)
|
|
|
|
|
(kill-all-local-variables)
|
|
|
|
|
(buffer-disable-undo)
|
|
|
|
|
(use-local-map fuel-xref-mode-map)
|
2009-01-08 12:47:17 -05:00
|
|
|
|
(set-syntax-table fuel-syntax--syntax-table)
|
2008-12-20 19:43:28 -05:00
|
|
|
|
(setq mode-name "FUEL Xref")
|
|
|
|
|
(setq major-mode 'fuel-xref-mode)
|
2008-12-21 11:33:53 -05:00
|
|
|
|
(font-lock-add-keywords nil '(("(in \\(.+\\))" 1 'fuel-font-lock-xref-vocab)))
|
2008-12-20 19:43:28 -05:00
|
|
|
|
(setq buffer-read-only t))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(provide 'fuel-xref)
|
|
|
|
|
;;; fuel-xref.el ends here
|