1 ;;; -*- Mode: Emacs-Lisp -*-
5 ;;; This file is part of ILISP.
6 ;;; Please refer to the file COPYING for copyrights and licensing
8 ;;; Please refer to the file ACKNOWLEGDEMENTS for an (incomplete) list
9 ;;; of present and past contributors.
11 ;;; $Id: ilisp-imenu.el,v 1.3 2002-06-03 23:37:01 wbd Exp $
16 ;;; modified for a better display of function+arglist!
17 ;;; let tokens contain spaces and test with string-equal.
19 (defun imenu--completion-buffer (index-alist &optional prompt)
20 "Let the user select from INDEX-ALIST in a completion buffer with PROMPT.
22 Returns t for rescan and otherwise a position number."
23 ;; Create a list for this buffer only when needed.
24 (let ((name (thing-at-point 'symbol))
27 ((and name (imenu--in-alist name index-alist))
28 (setq prompt (format "Index item (default %s): " name)))
29 (t (setq prompt "Index item: ")))
30 (if (eq imenu-always-use-completion-buffer-p 'never)
31 (setq name (completing-read prompt
33 nil t nil 'imenu--history-list name))
34 (save-window-excursion
35 ;; Display the completion buffer
36 (with-output-to-temp-buffer "*Completions*"
37 (display-completion-list
38 (all-completions "" index-alist )))
39 (let ((minibuffer-setup-hook
42 (let ((buffer (current-buffer)))
44 (set-buffer "*Completions*")
45 (setq completion-reference-buffer buffer)))))))
46 ;; Make a completion question
47 (setq name (completing-read prompt
50 t nil 'imenu--history-list name)))))
51 (cond ((not (stringp name))
53 ((string= name (car imenu--rescan-item))
56 (setq choice (assoc name index-alist))
57 (if (imenu--subalist-p choice)
58 (imenu--completion-buffer (cdr choice) prompt)
63 ;;; Patch for ilisp-imenu
66 ;; Intent is to allow users to customize what forms can
67 ;; define types, variables, etc. At the moment, this is
68 ;; hardcoded in ilisp-imenu-create-lisp-index.
69 ;; This file replaces and enhances that. function.
71 (defvar ilisp-*defining-form-regexp* "^(def"
72 "Regular expression indicating that the form will define something.")
74 (defvar ilisp-*type-defining-forms*
75 '(deftype defstruct defclass define-condition)
76 "Symbols that announce the definition of a new lisp type.
77 Don't change this variable -- rather
78 customize ilisp-*user-type-defining-forms*")
80 (defvar ilisp-*user-type-defining-forms* nil
81 "*List of user defined symbols which define new lisp types.")
83 (defvar ilisp-*variable-defining-forms*
84 '(defvar defconstant defparameter)
85 "Symbols that announce the definition of a lisp variable.
86 Don't change this variable -- rather customize
87 ilisp-*user-variable-defining-forms*")
89 (defvar ilisp-*user-variable-defining-forms* nil
90 "*List of user defined symbols which define new lisp variables.")
92 (defvar ilisp-*function-defining-forms* '(defun defmethod defmacro defgeneric)
93 "Symbols that announce the definition of a new new lisp function.
94 Don't change this variable -- rather customize
95 ilisp-*user-function-defining-forms*")
98 (defvar ilisp-*user-function-defining-forms* nil
99 "*List of user defined symbols which define new lisp functions.")
102 (defun ilisp-build-optimal-regexp (key)
103 "Build an optimal regular expression to match tokens used to define
104 things of class KEY, which can be `:types' or `:variables'."
105 (regexp-opt (mapcar #'symbol-name
108 (:types (append ilisp-*type-defining-forms*
109 ilisp-*user-type-defining-forms*))
110 (:variables (append ilisp-*variable-defining-forms*
111 ilisp-*user-variable-defining-forms*))
112 (:functions (append ilisp-*function-defining-forms*
113 ilisp-*user-function-defining-forms*)))))))
116 (defun ilisp-imenu-create-lisp-index ()
117 ;; `imenu-create-index-function' is set to this.
118 ;; generates a nested index of definitions.
119 (let ((index-fun-alist '())
120 (index-var-alist '())
121 (index-const-alist '())
122 (index-type-alist '())
123 (index-unknown-alist '())
126 (goto-char (point-max))
127 (imenu-progress-message prev-pos 0)
129 ;; This will be a bit slower at runtime, but hey, we don't
130 ;; rebuild the index very often, and at least this way,
131 ;; we'll get it right. [ap 13/5/2001]
132 (let ((type-defining-form-regexp (ilisp-build-optimal-regexp :types))
133 (variable-defining-form-regexp (ilisp-build-optimal-regexp :variables))
134 (function-defining-form-regexp (ilisp-build-optimal-regexp :functions)))
135 ;; Search for the function
136 (while (beginning-of-defun)
137 (imenu-progress-message prev-pos nil t)
139 (and (looking-at ilisp-*defining-form-regexp*)
142 (cond ((looking-at variable-defining-form-regexp)
144 (push (ilisp-imenu-general--name-and-position)
146 ((looking-at type-defining-form-regexp)
148 (push (ilisp-imenu-general--name-and-position)
150 ((looking-at function-defining-form-regexp)
152 (push (ilisp-imenu-function--name-and-position)
156 (push (ilisp-imenu-general--name-and-position)
157 index-unknown-alist)))))))
158 (imenu-progress-message prev-pos 100)
159 (when index-var-alist
160 (push (cons "Variables" index-var-alist) index-fun-alist))
161 (when index-type-alist
162 (push (cons "Types" index-type-alist) index-fun-alist))
163 (when index-unknown-alist
164 (push (cons "Syntax-unknown" index-unknown-alist) index-fun-alist))
169 ;; Return the previous+current sexp and the location of the sexp (its
170 ;; beginning) without moving the point.
171 (defun ilisp-imenu-function--name-and-position ()
174 ;; [ydi] modified for imenu-use-markers
175 (let* ((beg (if imenu-use-markers (point-marker) (point)))
176 (end (progn (forward-sexp) (point)))
177 (name (buffer-substring beg end))
178 (beg2 (progn (forward-sexp) (forward-sexp -1) (point)))
179 (end2 (progn (forward-sexp) (point)))
180 (args (buffer-substring beg2 end2)))
181 (cons (concat name " " args)
185 (defun ilisp-imenu-general--name-and-position ()
188 ;; [ydi] modified for imenu-use-markers
189 (let ((beg (if imenu-use-markers (point-marker) (point)))
190 (end (progn (forward-sexp) (point))))
191 (cons (buffer-substring beg end)
195 (defun ilisp-imenu-extract-index-name ()
196 ;; `imenu-extract-index-name-function' is set to this.
197 ;; generates a flat index of definitions in a lisp file.
199 (and (looking-at "(def")
205 (end (progn (forward-sexp -1) (point))))
206 (buffer-substring beg end)))
212 (defun ilisp-imenu-add-menubar-index ()
213 "Add an Imenu \"Index\" entry on the menu bar for the current buffer.
215 A trivial interface to `imenu-add-to-menubar' suitable for use in a hook."
217 (imenu-add-to-menubar "Index"))
220 (add-hook 'lisp-mode-hook
222 (when (featurep 'imenu)
223 (setq imenu-extract-index-name-function
224 'ilisp-imenu-extract-index-name)
225 (setq imenu-create-index-function
226 'ilisp-imenu-create-lisp-index)
227 (ilisp-imenu-add-menubar-index))))
229 ;;; end of file -- ilisp-imenu.el --