|
0 |
;;; xcscope.el --- cscope interface for (X)Emacs
|
|
1 |
|
|
2 |
;; Copyright (C) 2000-2002 Darryl Okahata
|
|
3 |
;; 2001 Triet H. Lai
|
|
4 |
;; 2001 Steven Elliott
|
|
5 |
;; 2013 Dima Kogan
|
|
6 |
|
|
7 |
;; Author: Darryl Okahata <darrylo@sonic.net>
|
|
8 |
;; Dima Kogan <dima@secretsauce.net>
|
|
9 |
;; Maintainer: Dima Kogan <dima@secretsauce.net>
|
|
10 |
;; Keywords: languages c
|
|
11 |
;; Homepage: https://github.com/dkogan/xcscope.el
|
|
12 |
;; Package-Version: 1.0
|
|
13 |
|
|
14 |
;; This file is not part of GNU Emacs.
|
|
15 |
|
|
16 |
;;
|
|
17 |
;; This program is free software; you can redistribute it and/or modify
|
|
18 |
;; it under the terms of the GNU General Public License as published by
|
|
19 |
;; the Free Software Foundation; either version 2, or (at your option)
|
|
20 |
;; any later version.
|
|
21 |
;;
|
|
22 |
;; This program is distributed in the hope that it will be useful,
|
|
23 |
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
24 |
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
25 |
;; GNU General Public License for more details.
|
|
26 |
;;
|
|
27 |
;; You should have received a copy of the GNU General Public License
|
|
28 |
;; along with GNU Emacs; see the file COPYING. If not, write to
|
|
29 |
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
30 |
;;
|
|
31 |
|
|
32 |
;;; Commentary:
|
|
33 |
;;
|
|
34 |
;; This is a cscope interface for (X)Emacs.
|
|
35 |
;; It currently runs under Unix only.
|
|
36 |
;;
|
|
37 |
;; Using cscope, you can easily search for where symbols are used and defined.
|
|
38 |
;; Cscope is designed to answer questions like:
|
|
39 |
;;
|
|
40 |
;; Where is this variable used?
|
|
41 |
;; What is the value of this preprocessor symbol?
|
|
42 |
;; Where is this function in the source files?
|
|
43 |
;; What functions call this function?
|
|
44 |
;; What functions are called by this function?
|
|
45 |
;; Where does the message "out of space" come from?
|
|
46 |
;; Where is this source file in the directory structure?
|
|
47 |
;; What files include this header file?
|
|
48 |
;; Where was this variable assigned-to?
|
|
49 |
;;
|
|
50 |
;; Send comments to dima@secretsauce.net
|
|
51 |
;;
|
|
52 |
;;
|
|
53 |
;;
|
|
54 |
;; ***** INSTALLATION *****
|
|
55 |
;;
|
|
56 |
;; * NOTE: this interface currently runs under Unix only.
|
|
57 |
;;
|
|
58 |
;; Installation steps:
|
|
59 |
;;
|
|
60 |
;; 0. (It is, of course, assumed that cscope is already properly
|
|
61 |
;; installed on the current system.)
|
|
62 |
;;
|
|
63 |
;; 1. Install xcscope.el through your system package manager, MELPA or by
|
|
64 |
;; loading the file with
|
|
65 |
;;
|
|
66 |
;; (require 'xcscope)
|
|
67 |
;;
|
|
68 |
;; 2. Call (cscope-setup). This can go into the .emacs to always enable
|
|
69 |
;; xcscope.el at emacs startup
|
|
70 |
;;
|
|
71 |
;; 3. If you intend to use xcscope.el often you can optionally edit your
|
|
72 |
;; ~/.emacs file to add keybindings that reduce the number of keystrokes
|
|
73 |
;; required. For example, the following will add "C-f#" keybindings, which
|
|
74 |
;; are easier to type than the usual "C-c s" prefixed keybindings. Note
|
|
75 |
;; that specifying "global-map" instead of "cscope-minor-mode-keymap" makes the
|
|
76 |
;; keybindings available in all buffers:
|
|
77 |
;;
|
|
78 |
;; (define-key global-map [(control f3)] 'cscope-set-initial-directory)
|
|
79 |
;; (define-key global-map [(control f4)] 'cscope-unset-initial-directory)
|
|
80 |
;; (define-key global-map [(control f5)] 'cscope-find-this-symbol)
|
|
81 |
;; (define-key global-map [(control f6)] 'cscope-find-global-definition)
|
|
82 |
;; (define-key global-map [(control f7)]
|
|
83 |
;; 'cscope-find-global-definition-no-prompting)
|
|
84 |
;; (define-key global-map [(control f8)] 'cscope-pop-mark)
|
|
85 |
;; (define-key global-map [(control f9)] 'cscope-history-forward-line)
|
|
86 |
;; (define-key global-map [(control f10)] 'cscope-history-forward-file)
|
|
87 |
;; (define-key global-map [(control f11)] 'cscope-history-backward-line)
|
|
88 |
;; (define-key global-map [(control f12)] 'cscope-history-backward-file)
|
|
89 |
;; (define-key global-map [(meta f9)] 'cscope-display-buffer)
|
|
90 |
;; (define-key global-map [(meta f10)] 'cscope-display-buffer-toggle)
|
|
91 |
;;
|
|
92 |
;; 6. Restart (X)Emacs. That's it.
|
|
93 |
;;
|
|
94 |
;;
|
|
95 |
;;
|
|
96 |
;;
|
|
97 |
;; ***** USING THIS MODULE *****
|
|
98 |
;;
|
|
99 |
;; * Basic usage:
|
|
100 |
;;
|
|
101 |
;; If all of your C/C++/lex/yacc source files are in the same
|
|
102 |
;; directory, you can just start using this module. If your files are
|
|
103 |
;; spread out over multiple directories, see "Advanced usage", below.
|
|
104 |
;;
|
|
105 |
;; Just edit a source file, and use the pull-down or pop-up (button 3)
|
|
106 |
;; menus to select one of:
|
|
107 |
;;
|
|
108 |
;; Find symbol
|
|
109 |
;; Find global definition
|
|
110 |
;; Find called functions
|
|
111 |
;; Find functions calling a function
|
|
112 |
;; Find text string
|
|
113 |
;; Find egrep pattern
|
|
114 |
;; Find a file
|
|
115 |
;; Find files #including a file
|
|
116 |
;;
|
|
117 |
;; The cscope database will be automatically created in the same
|
|
118 |
;; directory as the source files (assuming that you've never used
|
|
119 |
;; cscope before), and a buffer will pop-up displaying the results.
|
|
120 |
;; You can then use button 2 (the middle button) on the mouse to edit
|
|
121 |
;; the selected file, or you can move the text cursor over a selection
|
|
122 |
;; and press [Enter].
|
|
123 |
;;
|
|
124 |
;; The third mouse button is bound to a popup menu for cscope. Shift-mouse
|
|
125 |
;; button 3 invokes the last find command again. E.g. if you look for the symbol
|
|
126 |
;; 'main' and afterwards you want to look for another symbol, just press Shift
|
|
127 |
;; and click the third button.
|
|
128 |
;;
|
|
129 |
;; Each cscope search adds its results to the *cscope* buffer. These sets of
|
|
130 |
;; results can be navigated and manupulated similar to patches in diff-mode.:
|
|
131 |
;;
|
|
132 |
;; - n/p navigates over individual results
|
|
133 |
;; - k kills individual results
|
|
134 |
;;
|
|
135 |
;; - N/P or M-n/M-p navigates over file results
|
|
136 |
;; - M-k kills file results
|
|
137 |
;;
|
|
138 |
;; - M-N/M-P navigates over result sets
|
|
139 |
;; - M-K kills result sets
|
|
140 |
;;
|
|
141 |
;; - Navigation from outside the *cscope* buffer (C-c s n/p/N/P) is restricted to
|
|
142 |
;; the result set at (point)
|
|
143 |
;;
|
|
144 |
;; Any result set in the *cscope* buffer can be re-run with the 'r' key.
|
|
145 |
;;
|
|
146 |
;;
|
|
147 |
;; * Locating the cscope databases:
|
|
148 |
;;
|
|
149 |
;; This module will first use the variable, `cscope-database-regexps', to search
|
|
150 |
;; for a suitable database directory. If a database location cannot be found
|
|
151 |
;; using this variable then a search is begun at the variable,
|
|
152 |
;; `cscope-initial-directory', if set. If not set and we're running this search
|
|
153 |
;; from the *cscope* buffer, the search is begun from the directory of the
|
|
154 |
;; search at point. Otherwise, the current directory is used. If the directory
|
|
155 |
;; is not a cscope database directory then the directory's parent, parent's
|
|
156 |
;; parent, etc. is searched until a cscope database directory is found, or the
|
|
157 |
;; root directory is reached. If the root directory is reached, the current
|
|
158 |
;; directory will be used.
|
|
159 |
;;
|
|
160 |
;; A cscope database directory is one in which EITHER a cscope database
|
|
161 |
;; file (e.g., "cscope.out") OR a cscope file list (e.g.,
|
|
162 |
;; "cscope.files") exists. If only "cscope.files" exists, the
|
|
163 |
;; corresponding "cscope.out" will be automatically created by cscope
|
|
164 |
;; when a search is done. By default, the cscope database file is called
|
|
165 |
;; "cscope.out", but this can be changed (on a global basis) via the
|
|
166 |
;; variable, `cscope-database-file'. There is limited support for cscope
|
|
167 |
;; databases that are named differently than that given by
|
|
168 |
;; `cscope-database-file', using the variable, `cscope-database-regexps'.
|
|
169 |
;;
|
|
170 |
;; Note that the variable, `cscope-database-regexps', is generally not
|
|
171 |
;; needed, as the normal hierarchical database search is sufficient
|
|
172 |
;; for placing and/or locating the cscope databases. However, there
|
|
173 |
;; may be cases where it makes sense to place the cscope databases
|
|
174 |
;; away from where the source files are kept; in this case, this
|
|
175 |
;; variable is used to determine the mapping. One use for this
|
|
176 |
;; variable is when you want to share the database file with other
|
|
177 |
;; users; in this case, the database may be located in a directory
|
|
178 |
;; separate from the source files.
|
|
179 |
;;
|
|
180 |
;; Setting the variable, `cscope-initial-directory', is useful when a
|
|
181 |
;; search is to be expanded by specifying a cscope database directory
|
|
182 |
;; that is a parent of the directory that this module would otherwise
|
|
183 |
;; use. For example, consider a project that contains the following
|
|
184 |
;; cscope database directories:
|
|
185 |
;;
|
|
186 |
;; /users/jdoe/sources
|
|
187 |
;; /users/jdoe/sources/proj1
|
|
188 |
;; /users/jdoe/sources/proj2
|
|
189 |
;;
|
|
190 |
;; If a search is initiated from a .c file in /users/jdoe/sources/proj1
|
|
191 |
;; then (assuming the variable, `cscope-database-regexps', is not set)
|
|
192 |
;; /users/jdoe/sources/proj1 will be used as the cscope data base directory.
|
|
193 |
;; Only matches in files in /users/jdoe/sources/proj1 will be found. This
|
|
194 |
;; can be remedied by typing "C-c s a" and then "M-del" to remove single
|
|
195 |
;; path element in order to use a cscope database directory of
|
|
196 |
;; /users/jdoe/sources. Normal searching can be restored by typing "C-c s A".
|
|
197 |
;;
|
|
198 |
;;
|
|
199 |
;; * Keybindings:
|
|
200 |
;;
|
|
201 |
;; All keybindings use the "C-c s" prefix, but are usable only while
|
|
202 |
;; editing a source file, or in the cscope results buffer:
|
|
203 |
;;
|
|
204 |
;; C-c s s Find symbol.
|
|
205 |
;; C-c s = Find assignments to this symbol
|
|
206 |
;; C-c s d Find global definition.
|
|
207 |
;; C-c s g Find global definition (alternate binding).
|
|
208 |
;; C-c s G Find global definition without prompting.
|
|
209 |
;; C-c s c Find functions calling a function.
|
|
210 |
;; C-c s C Find called functions (list functions called
|
|
211 |
;; from a function).
|
|
212 |
;; C-c s t Find text string.
|
|
213 |
;; C-c s e Find egrep pattern.
|
|
214 |
;; C-c s f Find a file.
|
|
215 |
;; C-c s i Find files #including a file.
|
|
216 |
;;
|
|
217 |
;; These pertain to navigation through the search results:
|
|
218 |
;;
|
|
219 |
;; C-c s b Display *cscope* buffer.
|
|
220 |
;; C-c s B Auto display *cscope* buffer toggle.
|
|
221 |
;; C-c s n Next symbol.
|
|
222 |
;; C-c s N Next file.
|
|
223 |
;; C-c s p Previous symbol.
|
|
224 |
;; C-c s P Previous file.
|
|
225 |
;; C-c s u Pop mark.
|
|
226 |
;;
|
|
227 |
;; These pertain to setting and unsetting the variable,
|
|
228 |
;; `cscope-initial-directory', (location searched for the cscope database
|
|
229 |
;; directory):
|
|
230 |
;;
|
|
231 |
;; C-c s a Set initial directory.
|
|
232 |
;; C-c s A Unset initial directory.
|
|
233 |
;;
|
|
234 |
;; These pertain to cscope database maintenance:
|
|
235 |
;;
|
|
236 |
;; C-c s L Create list of files to index.
|
|
237 |
;; C-c s I Create list and index.
|
|
238 |
;; C-c s E Edit list of files to index.
|
|
239 |
;; C-c s W Locate this buffer's cscope directory
|
|
240 |
;; ("W" --> "where").
|
|
241 |
;; C-c s S Locate this buffer's cscope directory.
|
|
242 |
;; (alternate binding: "S" --> "show").
|
|
243 |
;; C-c s T Locate this buffer's cscope directory.
|
|
244 |
;; (alternate binding: "T" --> "tell").
|
|
245 |
;; C-c s D Dired this buffer's directory.
|
|
246 |
;;
|
|
247 |
;;
|
|
248 |
;; * Advanced usage:
|
|
249 |
;;
|
|
250 |
;; If the source files are spread out over multiple directories,
|
|
251 |
;; you've got a few choices:
|
|
252 |
;;
|
|
253 |
;; 1. If all of the directories exist below a common directory
|
|
254 |
;; (without any extraneous, unrelated subdirectories), you can tell
|
|
255 |
;; this module to place the cscope database into the top-level,
|
|
256 |
;; common directory. This assumes that you do not have any cscope
|
|
257 |
;; databases in any of the subdirectories. If you do, you should
|
|
258 |
;; delete them; otherwise, they will take precedence over the
|
|
259 |
;; top-level database.
|
|
260 |
;;
|
|
261 |
;; If you do have cscope databases in any subdirectory, the
|
|
262 |
;; following instructions may not work right.
|
|
263 |
;;
|
|
264 |
;; It's pretty easy to tell this module to use a top-level, common
|
|
265 |
;; directory:
|
|
266 |
;;
|
|
267 |
;; a. Make sure that the menu pick, "Cscope/Index recursively", is
|
|
268 |
;; checked (the default value).
|
|
269 |
;;
|
|
270 |
;; b. Select the menu pick, "Cscope/Create list and index", and
|
|
271 |
;; specify the top-level directory. This will index the sources
|
|
272 |
;; in the background, so you can do other things if indexing
|
|
273 |
;; takes a long time. A list of files to index will be created in
|
|
274 |
;; "cscope.files", and the cscope database will be created in
|
|
275 |
;; "cscope.out".
|
|
276 |
;;
|
|
277 |
;; Once this has been done, you can then use the menu picks
|
|
278 |
;; (described in "Basic usage", above) to search for symbols.
|
|
279 |
;;
|
|
280 |
;; Note, however, that, if you add or delete source files, you'll
|
|
281 |
;; have to either rebuild the database using the above procedure,
|
|
282 |
;; or edit the file, "cscope.files" to add/delete the names of the
|
|
283 |
;; source files. To edit this file, you can use the menu pick,
|
|
284 |
;; "Cscope/Edit list of files to index".
|
|
285 |
;;
|
|
286 |
;;
|
|
287 |
;; 2. If most of the files exist below a common directory, but a few
|
|
288 |
;; are outside, you can use the menu pick, "Cscope/Create list of
|
|
289 |
;; files to index", and specify the top-level directory. Make sure
|
|
290 |
;; that "Cscope/Index recursively", is checked before you do so,
|
|
291 |
;; though. You can then edit the list of files to index using the
|
|
292 |
;; menu pick, "Cscope/Edit list of files to index". Just edit the
|
|
293 |
;; list to include any additional source files not already listed.
|
|
294 |
;;
|
|
295 |
;; Once you've created, edited, and saved the list, you can then
|
|
296 |
;; use the menu picks described under "Basic usage", above, to
|
|
297 |
;; search for symbols. The first time you search, you will have to
|
|
298 |
;; wait a while for cscope to fully index the source files, though.
|
|
299 |
;; If you have a lot of source files, you may want to manually run
|
|
300 |
;; cscope to build the database:
|
|
301 |
;;
|
|
302 |
;; cd top-level-directory # or wherever
|
|
303 |
;; rm -f cscope.out # not always necessary
|
|
304 |
;; cscope -b
|
|
305 |
;;
|
|
306 |
;;
|
|
307 |
;; 3. If the source files are scattered in many different, unrelated
|
|
308 |
;; places, you'll have to manually create cscope.files and put a
|
|
309 |
;; list of all pathnames into it. Then build the database using:
|
|
310 |
;;
|
|
311 |
;; cd some-directory # wherever cscope.files exists
|
|
312 |
;; rm -f cscope.out # not always necessary
|
|
313 |
;; cscope -b
|
|
314 |
;;
|
|
315 |
;; Next, read the documentation for the variable,
|
|
316 |
;; "cscope-database-regexps", and set it appropriately, such that
|
|
317 |
;; the above-created cscope database will be referenced when you
|
|
318 |
;; edit a related source file.
|
|
319 |
;;
|
|
320 |
;; Once this has been done, you can then use the menu picks
|
|
321 |
;; described under "Basic usage", above, to search for symbols.
|
|
322 |
;;
|
|
323 |
;;
|
|
324 |
;; * Interesting configuration variables:
|
|
325 |
;;
|
|
326 |
;; "cscope-truncate-lines"
|
|
327 |
;; This is the value of `truncate-lines' to use in cscope
|
|
328 |
;; buffers; the default is the current setting of
|
|
329 |
;; `truncate-lines'. This variable exists because it can be
|
|
330 |
;; easier to read cscope buffers with truncated lines, while
|
|
331 |
;; other buffers do not have truncated lines.
|
|
332 |
;;
|
|
333 |
;; "cscope-use-relative-paths"
|
|
334 |
;; If non-nil, use relative paths when creating the list of files
|
|
335 |
;; to index. The path is relative to the directory in which the
|
|
336 |
;; cscope database will be created. If nil, absolute paths will
|
|
337 |
;; be used. Absolute paths are good if you plan on moving the
|
|
338 |
;; database to some other directory (if you do so, you'll
|
|
339 |
;; probably also have to modify `cscope-database-regexps').
|
|
340 |
;; Absolute paths may also be good if you share the database file
|
|
341 |
;; with other users (you'll probably want to specify some
|
|
342 |
;; automounted network path for this).
|
|
343 |
;;
|
|
344 |
;; "cscope-index-recursively"
|
|
345 |
;; If non-nil, index files in the current directory and all
|
|
346 |
;; subdirectories. If nil, only files in the current directory
|
|
347 |
;; are indexed. This variable is only used when creating the
|
|
348 |
;; list of files to index, or when creating the list of files and
|
|
349 |
;; the corresponding cscope database.
|
|
350 |
;;
|
|
351 |
;; "cscope-name-line-width"
|
|
352 |
;; The width of the combined "function name:line number" field in
|
|
353 |
;; the cscope results buffer. If negative, the field is
|
|
354 |
;; left-justified.
|
|
355 |
;;
|
|
356 |
;; "cscope-option-...." Various options passed to the 'cscope' process. Controls
|
|
357 |
;; things like include directories, database compression, database type,
|
|
358 |
;; etc.
|
|
359 |
;;
|
|
360 |
;; "cscope-display-cscope-buffer"
|
|
361 |
;; If non-nil, display the *cscope* buffer after each search
|
|
362 |
;; (default). This variable can be set in order to reduce the
|
|
363 |
;; number of keystrokes required to navigate through the matches.
|
|
364 |
;;
|
|
365 |
;; "cscope-database-regexps"
|
|
366 |
;; List to force directory-to-cscope-database mappings.
|
|
367 |
;; This is a list of `(REGEXP DBLIST [ DBLIST ... ])', where:
|
|
368 |
;;
|
|
369 |
;; REGEXP is a regular expression matched against the current buffer's
|
|
370 |
;; current directory. The current buffer is typically some source file,
|
|
371 |
;; and you're probably searching for some symbol in or related to this
|
|
372 |
;; file. Basically, this regexp is used to relate the current directory
|
|
373 |
;; to a cscope database. You need to start REGEXP with "^" if you want
|
|
374 |
;; to match from the beginning of the current directory.
|
|
375 |
;;
|
|
376 |
;; DBLIST is a list that contains one or more of:
|
|
377 |
;;
|
|
378 |
;; ( DBDIR )
|
|
379 |
;; ( DBDIR ( OPTIONS ) )
|
|
380 |
;; ( t )
|
|
381 |
;; t
|
|
382 |
;;
|
|
383 |
;; Here, DBDIR is a directory (or a file) that contains a cscope
|
|
384 |
;; database. If DBDIR is a directory, then it is expected that the
|
|
385 |
;; cscope database, if present, has the filename given by the variable,
|
|
386 |
;; `cscope-database-file'; if DBDIR is a file, then DBDIR is the path
|
|
387 |
;; name to a cscope database file (which does not have to be the same as
|
|
388 |
;; that given by `cscope-database-file'). If only DBDIR is specified,
|
|
389 |
;; then that cscope database will be searched without any additional
|
|
390 |
;; cscope command-line options. If OPTIONS is given, then OPTIONS is a
|
|
391 |
;; list of strings, where each string is a separate cscope command-line
|
|
392 |
;; option.
|
|
393 |
;;
|
|
394 |
;; In the case of "( t )", this specifies that the search is to use the
|
|
395 |
;; normal hierarchical database search. This option is used to
|
|
396 |
;; explicitly search using the hierarchical database search either before
|
|
397 |
;; or after other cscope database directories.
|
|
398 |
;;
|
|
399 |
;; If "t" is specified (not inside a list), this tells the searching
|
|
400 |
;; mechanism to stop searching if a match has been found (at the point
|
|
401 |
;; where "t" is encountered). This is useful for those projects that
|
|
402 |
;; consist of many subprojects. You can specify the most-used
|
|
403 |
;; subprojects first, followed by a "t", and then followed by a master
|
|
404 |
;; cscope database directory that covers all subprojects. This will
|
|
405 |
;; cause the most-used subprojects to be searched first (hopefully
|
|
406 |
;; quickly), and the search will then stop if a match was found. If not,
|
|
407 |
;; the search will continue using the master cscope database directory.
|
|
408 |
;;
|
|
409 |
;; Here, `cscope-database-regexps' is generally not used, as the normal
|
|
410 |
;; hierarchical database search is sufficient for placing and/or locating
|
|
411 |
;; the cscope databases. However, there may be cases where it makes
|
|
412 |
;; sense to place the cscope databases away from where the source files
|
|
413 |
;; are kept; in this case, this variable is used to determine the
|
|
414 |
;; mapping.
|
|
415 |
;;
|
|
416 |
;; This module searches for the cscope databases by first using this
|
|
417 |
;; variable; if a database location cannot be found using this variable,
|
|
418 |
;; then the current directory is searched, then the parent, then the
|
|
419 |
;; parent's parent, until a cscope database directory is found, or the
|
|
420 |
;; root directory is reached. If the root directory is reached, the
|
|
421 |
;; current directory will be used.
|
|
422 |
;;
|
|
423 |
;; A cscope database directory is one in which EITHER a cscope database
|
|
424 |
;; file (e.g., "cscope.out") OR a cscope file list (e.g.,
|
|
425 |
;; "cscope.files") exists. If only "cscope.files" exists, the
|
|
426 |
;; corresponding "cscope.out" will be automatically created by cscope
|
|
427 |
;; when a search is done. By default, the cscope database file is called
|
|
428 |
;; "cscope.out", but this can be changed (on a global basis) via the
|
|
429 |
;; variable, `cscope-database-file'. There is limited support for cscope
|
|
430 |
;; databases that are named differently than that given by
|
|
431 |
;; `cscope-database-file', using the variable, `cscope-database-regexps'.
|
|
432 |
;;
|
|
433 |
;; Here is an example of `cscope-database-regexps':
|
|
434 |
;;
|
|
435 |
;; (setq cscope-database-regexps
|
|
436 |
;; '(
|
|
437 |
;; ( "^/users/jdoe/sources/proj1"
|
|
438 |
;; ( t )
|
|
439 |
;; ( "/users/jdoe/sources/proj2")
|
|
440 |
;; ( "/users/jdoe/sources/proj3/mycscope.out")
|
|
441 |
;; ( "/users/jdoe/sources/proj4")
|
|
442 |
;; t
|
|
443 |
;; ( "/some/master/directory" ("-d" "-I/usr/local/include") )
|
|
444 |
;; )
|
|
445 |
;; ( "^/users/jdoe/sources/gnome/"
|
|
446 |
;; ( "/master/gnome/database" ("-d") )
|
|
447 |
;; )
|
|
448 |
;; ))
|
|
449 |
;;
|
|
450 |
;; If the current buffer's directory matches the regexp,
|
|
451 |
;; "^/users/jdoe/sources/proj1", then the following search will be
|
|
452 |
;; done:
|
|
453 |
;;
|
|
454 |
;; 1. First, the normal hierarchical database search will be used to
|
|
455 |
;; locate a cscope database.
|
|
456 |
;;
|
|
457 |
;; 2. Next, searches will be done using the cscope database
|
|
458 |
;; directories, "/users/jdoe/sources/proj2",
|
|
459 |
;; "/users/jdoe/sources/proj3/mycscope.out", and
|
|
460 |
;; "/users/jdoe/sources/proj4". Note that, instead of the file,
|
|
461 |
;; "cscope.out", the file, "mycscope.out", will be used in the
|
|
462 |
;; directory "/users/jdoe/sources/proj3".
|
|
463 |
;;
|
|
464 |
;; 3. If a match was found, searching will stop.
|
|
465 |
;;
|
|
466 |
;; 4. If a match was not found, searching will be done using
|
|
467 |
;; "/some/master/directory", and the command-line options "-d"
|
|
468 |
;; and "-I/usr/local/include" will be passed to cscope.
|
|
469 |
;;
|
|
470 |
;; If the current buffer's directory matches the regexp,
|
|
471 |
;; "^/users/jdoe/sources/gnome", then the following search will be
|
|
472 |
;; done:
|
|
473 |
;;
|
|
474 |
;; The search will be done only using the directory,
|
|
475 |
;; "/master/gnome/database". The "-d" option will be passed to
|
|
476 |
;; cscope.
|
|
477 |
;;
|
|
478 |
;; If the current buffer's directory does not match any of the above
|
|
479 |
;; regexps, then only the normal hierarchical database search will be
|
|
480 |
;; done.
|
|
481 |
;;
|
|
482 |
;;
|
|
483 |
;; * Other notes:
|
|
484 |
;;
|
|
485 |
;; 1. This module is called, "xcscope", because someone else has
|
|
486 |
;; already written a "cscope.el" (although it's quite old).
|
|
487 |
;;
|
|
488 |
;;
|
|
489 |
;; * KNOWN BUGS:
|
|
490 |
;;
|
|
491 |
;; 1. Cannot handle whitespace in directory or file names.
|
|
492 |
;;
|
|
493 |
;; 2. The support for cscope databases different from that specified by
|
|
494 |
;; `cscope-database-file' is quirky. If the file does not exist, it
|
|
495 |
;; will not be auto-created (unlike files names by
|
|
496 |
;; `cscope-database-file'). You can manually force the file to be
|
|
497 |
;; created by using touch(1) to create a zero-length file; the
|
|
498 |
;; database will be created the next time a search is done.
|
|
499 |
;;
|
|
500 |
;;; Code:
|
|
501 |
|
|
502 |
(require 'easymenu)
|
|
503 |
|
|
504 |
|
|
505 |
(defgroup cscope nil
|
|
506 |
"Cscope interface for (X)Emacs.
|
|
507 |
Using cscope, you can easily search for where symbols are used and defined.
|
|
508 |
It is designed to answer questions like:
|
|
509 |
|
|
510 |
Where is this variable used?
|
|
511 |
What is the value of this preprocessor symbol?
|
|
512 |
Where is this function in the source files?
|
|
513 |
What functions call this function?
|
|
514 |
What functions are called by this function?
|
|
515 |
Where does the message \"out of space\" come from?
|
|
516 |
Where is this source file in the directory structure?
|
|
517 |
What files include this header file?
|
|
518 |
"
|
|
519 |
:prefix "cscope-"
|
|
520 |
:group 'tools)
|
|
521 |
|
|
522 |
(defconst cscope-database-directory-prompt "Database directory")
|
|
523 |
|
|
524 |
(defconst cscope-running-in-xemacs (string-match "XEmacs\\|Lucid" emacs-version))
|
|
525 |
|
|
526 |
(defcustom cscope-option-include-directories nil
|
|
527 |
"The -I option in cscope: add these directories to the list of
|
|
528 |
search paths for #include, similar to the -I gcc option"
|
|
529 |
:type '(repeat directory)
|
|
530 |
:group 'cscope)
|
|
531 |
|
|
532 |
(defcustom cscope-option-disable-compression nil
|
|
533 |
"The -c option in cscope: use an uncompressed, ASCII database"
|
|
534 |
:type 'boolean
|
|
535 |
:group 'cscope)
|
|
536 |
|
|
537 |
(defcustom cscope-option-kernel-mode nil
|
|
538 |
"The -k option in cscope: use no system-wide include paths.
|
|
539 |
Useful for self-contained codebases, such as a kernel"
|
|
540 |
:type 'boolean
|
|
541 |
:group 'cscope)
|
|
542 |
|
|
543 |
(defcustom cscope-option-use-inverted-index nil
|
|
544 |
"The -q option in cscope: use an inverted database index. Takes
|
|
545 |
longer to build, but results in faster lookups. Useful for very
|
|
546 |
large codebases"
|
|
547 |
:type 'boolean
|
|
548 |
:group 'cscope)
|
|
549 |
|
|
550 |
(defcustom cscope-option-do-not-update-database nil
|
|
551 |
"The -d option in cscope: never check and/or update the cscope
|
|
552 |
database when searching. Beware of setting this to non-nil, as
|
|
553 |
this will disable automatic database creation, updating, and
|
|
554 |
maintenance."
|
|
555 |
:type 'boolean
|
|
556 |
:group 'cscope)
|
|
557 |
|
|
558 |
(defcustom cscope-option-other nil
|
|
559 |
"Any indexing/lookup options to pass to cscope. These are used
|
|
560 |
both when building the database and when searching. Note that the
|
|
561 |
most common options have specific customization in the
|
|
562 |
cscope-option-* variables, and it is preferable to use those"
|
|
563 |
:type '(repeat string)
|
|
564 |
:group 'cscope)
|
|
565 |
|
|
566 |
|
|
567 |
(defcustom cscope-database-regexps nil
|
|
568 |
"List to force directory-to-cscope-database mappings.
|
|
569 |
This is a list of `(REGEXP DBLIST [ DBLIST ... ])', where:
|
|
570 |
|
|
571 |
REGEXP is a regular expression matched against the current buffer's
|
|
572 |
current directory. The current buffer is typically some source file,
|
|
573 |
and you're probably searching for some symbol in or related to this
|
|
574 |
file. Basically, this regexp is used to relate the current directory
|
|
575 |
to a cscope database. You need to start REGEXP with \"^\" if you want
|
|
576 |
to match from the beginning of the current directory.
|
|
577 |
|
|
578 |
DBLIST is a list that contains one or more of:
|
|
579 |
|
|
580 |
( DBDIR )
|
|
581 |
( DBDIR ( OPTIONS ) )
|
|
582 |
( t )
|
|
583 |
t
|
|
584 |
|
|
585 |
Here, DBDIR is a directory (or a file) that contains a cscope database.
|
|
586 |
If DBDIR is a directory, then it is expected that the cscope database,
|
|
587 |
if present, has the filename given by the variable,
|
|
588 |
`cscope-database-file'; if DBDIR is a file, then DBDIR is the path name
|
|
589 |
to a cscope database file (which does not have to be the same as that
|
|
590 |
given by `cscope-database-file'). If only DBDIR is specified, then that
|
|
591 |
cscope database will be searched without any additional cscope
|
|
592 |
command-line options. If OPTIONS is given, then OPTIONS is a list of
|
|
593 |
strings, where each string is a separate cscope command-line option.
|
|
594 |
|
|
595 |
In the case of \"( t )\", this specifies that the search is to use the
|
|
596 |
normal hierarchical database search. This option is used to
|
|
597 |
explicitly search using the hierarchical database search either before
|
|
598 |
or after other cscope database directories.
|
|
599 |
|
|
600 |
If \"t\" is specified (not inside a list), this tells the searching
|
|
601 |
mechanism to stop searching if a match has been found (at the point
|
|
602 |
where \"t\" is encountered). This is useful for those projects that
|
|
603 |
consist of many subprojects. You can specify the most-used
|
|
604 |
subprojects first, followed by a \"t\", and then followed by a master
|
|
605 |
cscope database directory that covers all subprojects. This will
|
|
606 |
cause the most-used subprojects to be searched first (hopefully
|
|
607 |
quickly), and the search will then stop if a match was found. If not,
|
|
608 |
the search will continue using the master cscope database directory.
|
|
609 |
|
|
610 |
Here, `cscope-database-regexps' is generally not used, as the normal
|
|
611 |
hierarchical database search is sufficient for placing and/or locating
|
|
612 |
the cscope databases. However, there may be cases where it makes
|
|
613 |
sense to place the cscope databases away from where the source files
|
|
614 |
are kept; in this case, this variable is used to determine the
|
|
615 |
mapping.
|
|
616 |
|
|
617 |
This module searches for the cscope databases by first using this
|
|
618 |
variable; if a database location cannot be found using this variable,
|
|
619 |
then the current directory is searched, then the parent, then the
|
|
620 |
parent's parent, until a cscope database directory is found, or the
|
|
621 |
root directory is reached. If the root directory is reached, the
|
|
622 |
current directory will be used.
|
|
623 |
|
|
624 |
A cscope database directory is one in which EITHER a cscope database
|
|
625 |
file (e.g., \"cscope.out\") OR a cscope file list (e.g.,
|
|
626 |
\"cscope.files\") exists. If only \"cscope.files\" exists, the
|
|
627 |
corresponding \"cscope.out\" will be automatically created by cscope
|
|
628 |
when a search is done. By default, the cscope database file is called
|
|
629 |
\"cscope.out\", but this can be changed (on a global basis) via the
|
|
630 |
variable, `cscope-database-file'. There is limited support for cscope
|
|
631 |
databases that are named differently than that given by
|
|
632 |
`cscope-database-file', using the variable, `cscope-database-regexps'.
|
|
633 |
|
|
634 |
Here is an example of `cscope-database-regexps':
|
|
635 |
|
|
636 |
(setq cscope-database-regexps
|
|
637 |
'(
|
|
638 |
( \"^/users/jdoe/sources/proj1\"
|
|
639 |
( t )
|
|
640 |
( \"/users/jdoe/sources/proj2\")
|
|
641 |
( \"/users/jdoe/sources/proj3/mycscope.out\")
|
|
642 |
( \"/users/jdoe/sources/proj4\")
|
|
643 |
t
|
|
644 |
( \"/some/master/directory\" (\"-d\" \"-I/usr/local/include\") )
|
|
645 |
)
|
|
646 |
( \"^/users/jdoe/sources/gnome/\"
|
|
647 |
( \"/master/gnome/database\" (\"-d\") )
|
|
648 |
)
|
|
649 |
))
|
|
650 |
|
|
651 |
If the current buffer's directory matches the regexp,
|
|
652 |
\"^/users/jdoe/sources/proj1\", then the following search will be
|
|
653 |
done:
|
|
654 |
|
|
655 |
1. First, the normal hierarchical database search will be used to
|
|
656 |
locate a cscope database.
|
|
657 |
|
|
658 |
2. Next, searches will be done using the cscope database
|
|
659 |
directories, \"/users/jdoe/sources/proj2\",
|
|
660 |
\"/users/jdoe/sources/proj3/mycscope.out\", and
|
|
661 |
\"/users/jdoe/sources/proj4\". Note that, instead of the file,
|
|
662 |
\"cscope.out\", the file, \"mycscope.out\", will be used in the
|
|
663 |
directory \"/users/jdoe/sources/proj3\".
|
|
664 |
|
|
665 |
3. If a match was found, searching will stop.
|
|
666 |
|
|
667 |
4. If a match was not found, searching will be done using
|
|
668 |
\"/some/master/directory\", and the command-line options \"-d\"
|
|
669 |
and \"-I/usr/local/include\" will be passed to cscope.
|
|
670 |
|
|
671 |
If the current buffer's directory matches the regexp,
|
|
672 |
\"^/users/jdoe/sources/gnome\", then the following search will be
|
|
673 |
done:
|
|
674 |
|
|
675 |
The search will be done only using the directory,
|
|
676 |
\"/master/gnome/database\". The \"-d\" option will be passed to
|
|
677 |
cscope.
|
|
678 |
|
|
679 |
If the current buffer's directory does not match any of the above
|
|
680 |
regexps, then only the normal hierarchical database search will be
|
|
681 |
done.
|
|
682 |
|
|
683 |
"
|
|
684 |
:type '(repeat (list :format "%v"
|
|
685 |
(choice :value ""
|
|
686 |
(regexp :tag "Buffer regexp")
|
|
687 |
string)
|
|
688 |
(choice :value ""
|
|
689 |
(directory :tag "Cscope database directory")
|
|
690 |
string)
|
|
691 |
(string :value ""
|
|
692 |
:tag "Optional cscope command-line arguments")
|
|
693 |
))
|
|
694 |
:group 'cscope)
|
|
695 |
(defcustom cscope-name-line-width -30
|
|
696 |
"The width of the combined \"function name:line number\" field in the
|
|
697 |
cscope results buffer. If negative, the field is left-justified."
|
|
698 |
:type 'integer
|
|
699 |
:group 'cscope)
|
|
700 |
|
|
701 |
|
|
702 |
(defcustom cscope-truncate-lines truncate-lines
|
|
703 |
"The value of `truncate-lines' to use in cscope buffers.
|
|
704 |
This variable exists because it can be easier to read cscope buffers
|
|
705 |
with truncated lines, while other buffers do not have truncated lines."
|
|
706 |
:type 'boolean
|
|
707 |
:group 'cscope)
|
|
708 |
|
|
709 |
|
|
710 |
(defcustom cscope-display-times t
|
|
711 |
"If non-nil, display how long each search took.
|
|
712 |
The elasped times are in seconds. Floating-point support is required
|
|
713 |
for this to work."
|
|
714 |
:type 'boolean
|
|
715 |
:group 'cscope)
|
|
716 |
|
|
717 |
(defcustom cscope-max-cscope-buffer-size 1000000
|
|
718 |
"If >0, limit the size of the *cscope* buffer. Only the
|
|
719 |
'cscope-max-cscope-buffer-size' bytes at the end are kept,
|
|
720 |
rounded up to keep whole sets of cscope output"
|
|
721 |
:type 'integer
|
|
722 |
:group 'cscope)
|
|
723 |
|
|
724 |
(defcustom cscope-program "cscope"
|
|
725 |
"The pathname of the cscope executable to use. This could be a
|
|
726 |
string, or a function. If a function, then this is called every
|
|
727 |
time the program path is needed to retrieve the path. The
|
|
728 |
function takes no arguments, but can use variables such as
|
|
729 |
`default-directory'. This is useful to find cscope in different
|
|
730 |
places on different machines when using TRAMP."
|
|
731 |
:type '(choice
|
|
732 |
(string :tag "Program path")
|
|
733 |
(function :tag "Function that returns the program path"))
|
|
734 |
:group 'cscope)
|
|
735 |
|
|
736 |
|
|
737 |
(defcustom cscope-index-file "cscope.files"
|
|
738 |
"The name of the cscope file list file."
|
|
739 |
:type 'string
|
|
740 |
:group 'cscope)
|
|
741 |
|
|
742 |
|
|
743 |
(defcustom cscope-database-file "cscope.out"
|
|
744 |
"The name of the cscope database file."
|
|
745 |
:type 'string
|
|
746 |
:group 'cscope)
|
|
747 |
|
|
748 |
|
|
749 |
(defcustom cscope-edit-single-match t
|
|
750 |
"If non-nil and only one match is output, edit the matched location."
|
|
751 |
:type 'boolean
|
|
752 |
:group 'cscope)
|
|
753 |
|
|
754 |
|
|
755 |
(defcustom cscope-display-cscope-buffer t
|
|
756 |
"If non-nil automatically display the *cscope* buffer after each search."
|
|
757 |
:type 'boolean
|
|
758 |
:group 'cscope)
|
|
759 |
|
|
760 |
|
|
761 |
(defcustom cscope-stop-at-first-match-dir nil
|
|
762 |
"If non-nil, stop searching through multiple databases if a match is found.
|
|
763 |
This option is useful only if multiple cscope database directories are being
|
|
764 |
used. When multiple databases are searched, setting this variable to non-nil
|
|
765 |
will cause searches to stop when a search outputs anything; no databases after
|
|
766 |
this one will be searched."
|
|
767 |
:type 'boolean
|
|
768 |
:group 'cscope)
|
|
769 |
|
|
770 |
|
|
771 |
(defcustom cscope-use-relative-paths t
|
|
772 |
"If non-nil, use relative paths when creating the list of files to index.
|
|
773 |
The path is relative to the directory in which the cscope database
|
|
774 |
will be created. If nil, absolute paths will be used. Absolute paths
|
|
775 |
are good if you plan on moving the database to some other directory
|
|
776 |
(if you do so, you'll probably also have to modify
|
|
777 |
\`cscope-database-regexps\'). Absolute paths may also be good if you
|
|
778 |
share the database file with other users (you\'ll probably want to
|
|
779 |
specify some automounted network path for this)."
|
|
780 |
:type 'boolean
|
|
781 |
:group 'cscope)
|
|
782 |
|
|
783 |
|
|
784 |
(defcustom cscope-index-recursively t
|
|
785 |
"If non-nil, index files in the current directory and all subdirectories.
|
|
786 |
If nil, only files in the current directory are indexed. This
|
|
787 |
variable is only used when creating the list of files to index, or
|
|
788 |
when creating the list of files and the corresponding cscope database."
|
|
789 |
:type 'boolean
|
|
790 |
:group 'cscope)
|
|
791 |
|
|
792 |
(defcustom cscope-indexer-ignored-directories '("CVS"
|
|
793 |
"RCS"
|
|
794 |
"SCCS"
|
|
795 |
".git"
|
|
796 |
".hg"
|
|
797 |
".bzr"
|
|
798 |
".cdv"
|
|
799 |
".pc"
|
|
800 |
".svn"
|
|
801 |
"_MTN"
|
|
802 |
"_darcs"
|
|
803 |
"_sgbak"
|
|
804 |
"debian")
|
|
805 |
"List of directory names that should be ignored when building a
|
|
806 |
cscope index. These are mostly version-control directories"
|
|
807 |
:type '(repeat string)
|
|
808 |
:group 'cscope)
|
|
809 |
|
|
810 |
(defcustom cscope-indexer-suffixes '("*.[chly]"
|
|
811 |
"*.[ch]xx"
|
|
812 |
"*.[ch]pp"
|
|
813 |
"*.cc"
|
|
814 |
"*.hh")
|
|
815 |
"List of file suffixes to index. By default these are C, C++,
|
|
816 |
Lex and Yacc source. These are globs accepted by 'find -iname'"
|
|
817 |
:type '(repeat string)
|
|
818 |
:group 'cscope)
|
|
819 |
|
|
820 |
(defcustom cscope-symbol-chars "A-Za-z0-9_"
|
|
821 |
"A string containing legal characters in a symbol.
|
|
822 |
The current syntax table should really be used for this."
|
|
823 |
:type 'string
|
|
824 |
:group 'cscope)
|
|
825 |
|
|
826 |
|
|
827 |
(defcustom cscope-filename-chars "-.,/A-Za-z0-9_~!@#$%&+=\\\\"
|
|
828 |
"A string containing legal characters in a symbol.
|
|
829 |
The current syntax table should really be used for this."
|
|
830 |
:type 'string
|
|
831 |
:group 'cscope)
|
|
832 |
|
|
833 |
|
|
834 |
(defcustom cscope-allow-arrow-overlays t
|
|
835 |
"If non-nil, use an arrow overlay to show target lines.
|
|
836 |
Arrow overlays are only used when the following functions are used:
|
|
837 |
|
|
838 |
cscope-show-entry-other-window
|
|
839 |
cscope-show-next-entry-other-window
|
|
840 |
cscope-show-prev-entry-other-window
|
|
841 |
|
|
842 |
The arrow overlay is removed when other cscope functions are used.
|
|
843 |
Note that the arrow overlay is not an actual part of the text, and can
|
|
844 |
be removed by quitting the cscope buffer."
|
|
845 |
:type 'boolean
|
|
846 |
:group 'cscope)
|
|
847 |
|
|
848 |
|
|
849 |
(defcustom cscope-overlay-arrow-string "=>"
|
|
850 |
"The overlay string to use when displaying arrow overlays."
|
|
851 |
:type 'string
|
|
852 |
:group 'cscope)
|
|
853 |
|
|
854 |
|
|
855 |
(defcustom cscope-close-window-after-select nil
|
|
856 |
"If non-nil close the window showing the cscope buffer after an entry has been selected."
|
|
857 |
:type 'boolean
|
|
858 |
:group 'cscope)
|
|
859 |
|
|
860 |
|
|
861 |
(defvar cscope-minor-mode-hooks nil
|
|
862 |
"List of hooks to call when entering cscope-minor-mode.")
|
|
863 |
|
|
864 |
(defvar cscope-display-buffer-args
|
|
865 |
(and (not cscope-running-in-xemacs)
|
|
866 |
(>= emacs-major-version 24)
|
|
867 |
'((display-buffer-use-some-window (inhibit-same-window . t))))
|
|
868 |
"Default arguments to `display-buffer'. This applies to ACTION
|
|
869 |
and FRAME arguments of the newer `display-buffer' in >= GNU Emacs
|
|
870 |
24. This controls how and where the *cscope* buffer is popped up.
|
|
871 |
By default I do not use the current window (so the *cscope*
|
|
872 |
buffer stays active) and I try not to make new windows.")
|
|
873 |
|
|
874 |
(defun cscope--get-cscope-program ()
|
|
875 |
"Retrieves the path to the cscope program. This is the value of
|
|
876 |
the `cscope-program' variable, if it is a string, or the value
|
|
877 |
returned by the `cscope-program' function, if it is a function."
|
|
878 |
(let ((program
|
|
879 |
(cond
|
|
880 |
((stringp cscope-program) cscope-program)
|
|
881 |
((functionp cscope-program) (funcall cscope-program))
|
|
882 |
(t (error "cscope-program must be a string or function: %s"
|
|
883 |
cscope-program)))))
|
|
884 |
(or program (error "cscope-program is nil!"))))
|
|
885 |
|
|
886 |
|
|
887 |
(defun cscope-display-buffer-wrapper (buffer)
|
|
888 |
"Calls `display-buffer' using
|
|
889 |
`cscope-display-buffer-args'"
|
|
890 |
(apply 'display-buffer buffer cscope-display-buffer-args))
|
|
891 |
|
|
892 |
|
|
893 |
(defconst cscope-result-separator
|
|
894 |
"===============================================================================\n"
|
|
895 |
"Line of text to use as a visual separator.
|
|
896 |
Must end with a newline. Must work as a regex without quoting")
|
|
897 |
|
|
898 |
(defconst cscope-file-separator-start-regex
|
|
899 |
"\\*\\*\\* .*:\n"
|
|
900 |
"Regex to match a file-start separator. This has to match the
|
|
901 |
'***' that xcscope.el normally outputs. This is assumed to appear
|
|
902 |
at the start of a line, so the leading ^ must be omitted")
|
|
903 |
|
|
904 |
(defconst cscope-file-separator-end-regex
|
|
905 |
"\n"
|
|
906 |
"Regex to match a file-end separator. This is just an empty
|
|
907 |
line, and this has to match what xcscope.el normally outputs in
|
|
908 |
its 'cscope-process-filter'. This is assumed to appear at the
|
|
909 |
start of a line, so the leading ^ must be omitted")
|
|
910 |
|
|
911 |
;;;;
|
|
912 |
;;;; Faces for fontification
|
|
913 |
;;;;
|
|
914 |
|
|
915 |
(defcustom cscope-use-face t
|
|
916 |
"Whether to use text highlighting (like font-lock) or not."
|
|
917 |
:group 'cscope
|
|
918 |
:type '(boolean))
|
|
919 |
|
|
920 |
|
|
921 |
(defface cscope-file-face
|
|
922 |
'((((class color) (background dark))
|
|
923 |
(:foreground "yellow"))
|
|
924 |
(((class color) (background light))
|
|
925 |
(:foreground "blue"))
|
|
926 |
(t (:bold t)))
|
|
927 |
"Face used to highlight file name in the *cscope* buffer."
|
|
928 |
:group 'cscope)
|
|
929 |
|
|
930 |
|
|
931 |
(defface cscope-function-face
|
|
932 |
'((((class color) (background dark))
|
|
933 |
(:foreground "cyan"))
|
|
934 |
(((class color) (background light))
|
|
935 |
(:foreground "magenta"))
|
|
936 |
(t (:bold t)))
|
|
937 |
"Face used to highlight function name in the *cscope* buffer."
|
|
938 |
:group 'cscope)
|
|
939 |
|
|
940 |
|
|
941 |
(defface cscope-line-number-face
|
|
942 |
'((((class color) (background dark))
|
|
943 |
(:foreground "red"))
|
|
944 |
(((class color) (background light))
|
|
945 |
(:foreground "red"))
|
|
946 |
(t (:bold t)))
|
|
947 |
"Face used to highlight line number in the *cscope* buffer."
|
|
948 |
:group 'cscope)
|
|
949 |
|
|
950 |
(defface cscope-mouse-face
|
|
951 |
'((((class color) (background dark))
|
|
952 |
(:foreground "white" :background "blue"))
|
|
953 |
(((class color) (background light))
|
|
954 |
(:foreground "white" :background "blue"))
|
|
955 |
(t (:bold nil)))
|
|
956 |
"Face used when mouse pointer is within the region of an entry."
|
|
957 |
:group 'cscope)
|
|
958 |
|
|
959 |
(defface cscope-separator-face
|
|
960 |
'((((class color) (background dark))
|
|
961 |
(:bold t :overline t :underline t :foreground "red"))
|
|
962 |
(((class color) (background light))
|
|
963 |
(:bold t :overline t :underline t :foreground "red"))
|
|
964 |
(t (:bold t)))
|
|
965 |
"Face used to highlight the separator in the *cscope* buffer."
|
|
966 |
:group 'cscope)
|
|
967 |
|
|
968 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
969 |
;; Probably, nothing user-customizable past this point.
|
|
970 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
971 |
(defconst cscope-start-file-process (if cscope-running-in-xemacs 'start-process 'start-file-process)
|
|
972 |
"The function used to launch external processes. Xemacs doesn't
|
|
973 |
have full TRAMP support here, so the less featureful function is
|
|
974 |
selected for it")
|
|
975 |
|
|
976 |
(defvar cscope-list-entry-keymap
|
|
977 |
(let ((map (make-keymap)))
|
|
978 |
(suppress-keymap map)
|
|
979 |
;; The following section does not appear in the "Cscope" menu.
|
|
980 |
(if cscope-running-in-xemacs
|
|
981 |
(progn
|
|
982 |
(define-key map [button2] 'cscope-mouse-select-entry-other-window)
|
|
983 |
(define-key map [(shift button2)] 'cscope-mouse-select-entry-inplace))
|
|
984 |
(define-key map [mouse-2] 'cscope-mouse-select-entry-other-window)
|
|
985 |
(define-key map [S-mouse-2] 'cscope-mouse-select-entry-inplace))
|
|
986 |
|
|
987 |
;; \r is for the text-mode console emacs
|
|
988 |
(define-key map [return] 'cscope-select-entry-other-window)
|
|
989 |
(define-key map "\r" 'cscope-select-entry-other-window)
|
|
990 |
|
|
991 |
;; this works for the graphics emacsen-only. Default xterm on Debian does
|
|
992 |
;; not know how to see this key combination
|
|
993 |
(define-key map (kbd "<S-return>") 'cscope-select-entry-inplace)
|
|
994 |
|
|
995 |
(define-key map " " 'cscope-show-entry-other-window)
|
|
996 |
(define-key map "o" 'cscope-select-entry-one-window)
|
|
997 |
(define-key map "q" 'cscope-bury-buffer)
|
|
998 |
(define-key map "Q" 'cscope-quit)
|
|
999 |
(define-key map "h" 'cscope-help)
|
|
1000 |
(define-key map "?" 'cscope-help)
|
|
1001 |
;; The following line corresponds to be beginning of the "Cscope" menu.
|
|
1002 |
(define-key map "s" 'cscope-find-this-symbol)
|
|
1003 |
(define-key map "d" 'cscope-find-this-symbol)
|
|
1004 |
(define-key map "g" 'cscope-find-global-definition)
|
|
1005 |
(define-key map "G" 'cscope-find-global-definition-no-prompting)
|
|
1006 |
(define-key map "=" 'cscope-find-assignments-to-this-symbol)
|
|
1007 |
(define-key map "c" 'cscope-find-functions-calling-this-function)
|
|
1008 |
(define-key map "C" 'cscope-find-called-functions)
|
|
1009 |
(define-key map "t" 'cscope-find-this-text-string)
|
|
1010 |
(define-key map "e" 'cscope-find-egrep-pattern)
|
|
1011 |
(define-key map "f" 'cscope-find-this-file)
|
|
1012 |
(define-key map "i" 'cscope-find-files-including-file)
|
|
1013 |
;; --- (The '---' indicates that this line corresponds to a menu separator.)
|
|
1014 |
(define-key map (kbd "p") 'cscope-history-backward-line)
|
|
1015 |
(define-key map (kbd "M-p") 'cscope-history-backward-file)
|
|
1016 |
(define-key map (kbd "P") 'cscope-history-backward-file)
|
|
1017 |
(define-key map (kbd "M-P") 'cscope-history-backward-result)
|
|
1018 |
(define-key map (kbd "n") 'cscope-history-forward-line)
|
|
1019 |
(define-key map (kbd "M-n") 'cscope-history-forward-file)
|
|
1020 |
(define-key map (kbd "N") 'cscope-history-forward-file)
|
|
1021 |
(define-key map (kbd "M-N") 'cscope-history-forward-result)
|
|
1022 |
(define-key map (kbd "k") 'cscope-history-kill-line)
|
|
1023 |
(define-key map (kbd "M-k") 'cscope-history-kill-file)
|
|
1024 |
(define-key map (kbd "M-K") 'cscope-history-kill-result)
|
|
1025 |
(define-key map "u" 'cscope-pop-mark)
|
|
1026 |
;; ---
|
|
1027 |
(define-key map "r" 'cscope-rerun-search-at-point)
|
|
1028 |
;; ---
|
|
1029 |
(define-key map "a" 'cscope-set-initial-directory)
|
|
1030 |
(define-key map "A" 'cscope-unset-initial-directory)
|
|
1031 |
;; ---
|
|
1032 |
(define-key map "L" 'cscope-create-list-of-files-to-index)
|
|
1033 |
(define-key map "I" 'cscope-index-files)
|
|
1034 |
(define-key map "E" 'cscope-edit-list-of-files-to-index)
|
|
1035 |
(define-key map "W" 'cscope-tell-user-about-directory)
|
|
1036 |
(define-key map "S" 'cscope-tell-user-about-directory)
|
|
1037 |
(define-key map "T" 'cscope-tell-user-about-directory)
|
|
1038 |
(define-key map "D" 'cscope-dired-directory)
|
|
1039 |
;; The previous line corresponds to be end of the "Cscope" menu.
|
|
1040 |
map)
|
|
1041 |
"The *cscope* buffer keymap")
|
|
1042 |
|
|
1043 |
|
|
1044 |
(defvar cscope-list-entry-hook nil
|
|
1045 |
"Hook run after cscope-list-entry-mode entered.")
|
|
1046 |
|
|
1047 |
|
|
1048 |
(defun cscope-list-entry-mode ()
|
|
1049 |
"Major mode for jumping/showing entry from the list in the *cscope* buffer.
|
|
1050 |
|
|
1051 |
\\{cscope-list-entry-keymap}"
|
|
1052 |
(use-local-map cscope-list-entry-keymap)
|
|
1053 |
(easy-menu-add cscope-buffer-menu cscope-list-entry-keymap)
|
|
1054 |
(setq mode-name "cscope"
|
|
1055 |
major-mode 'cscope-list-entry-mode
|
|
1056 |
overlay-arrow-string cscope-overlay-arrow-string)
|
|
1057 |
|
|
1058 |
(add-hook 'kill-buffer-hook 'cscope-cleanup-overlay-arrow)
|
|
1059 |
(run-hooks 'cscope-list-entry-hook))
|
|
1060 |
|
|
1061 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1062 |
|
|
1063 |
(defvar cscope-output-buffer-name "*cscope*"
|
|
1064 |
"The name of the cscope output buffer.")
|
|
1065 |
|
|
1066 |
|
|
1067 |
(defvar cscope-info-buffer-name "*cscope-info*"
|
|
1068 |
"The name of the cscope information buffer.")
|
|
1069 |
|
|
1070 |
|
|
1071 |
(defvar cscope-process nil
|
|
1072 |
"The current cscope process.")
|
|
1073 |
(make-variable-buffer-local 'cscope-process)
|
|
1074 |
|
|
1075 |
|
|
1076 |
(defvar cscope-process-output nil
|
|
1077 |
"A buffer for holding partial cscope process output.")
|
|
1078 |
(make-variable-buffer-local 'cscope-process-output)
|
|
1079 |
|
|
1080 |
(defvar cscope-last-output-point nil
|
|
1081 |
"Location of the last output from the process filter. Normally
|
|
1082 |
this is equivalent to (process-mark cscope-process), but this is
|
|
1083 |
broken in xemacs in the sentinel after the process has
|
|
1084 |
terminated. Also, this is (point-max) unless we're re-running a
|
|
1085 |
search in the middle of the *cscope* buffer")
|
|
1086 |
|
|
1087 |
|
|
1088 |
(defvar cscope-command-args nil
|
|
1089 |
"Internal variable for holding major command args to pass to cscope.")
|
|
1090 |
(make-variable-buffer-local 'cscope-command-args)
|
|
1091 |
|
|
1092 |
|
|
1093 |
(defvar cscope-start-directory nil
|
|
1094 |
"Internal variable used to save the initial start directory.
|
|
1095 |
The results buffer gets reset to this directory when a search has
|
|
1096 |
completely finished.")
|
|
1097 |
(make-variable-buffer-local 'cscope-start-directory)
|
|
1098 |
|
|
1099 |
|
|
1100 |
(defvar cscope-search-list nil
|
|
1101 |
"A list of (DIR . FLAGS) entries.
|
|
1102 |
This is a list of database directories to search. Each entry in the list
|
|
1103 |
is a (DIR . FLAGS) cell. DIR is the directory to search, and FLAGS are the
|
|
1104 |
flags to pass to cscope when using this database directory. FLAGS can be
|
|
1105 |
nil (meaning, \"no flags\").")
|
|
1106 |
(make-variable-buffer-local 'cscope-search-list)
|
|
1107 |
|
|
1108 |
|
|
1109 |
(defvar cscope-searched-dirs nil
|
|
1110 |
"The list of database directories already searched.")
|
|
1111 |
(make-variable-buffer-local 'cscope-searched-dirs)
|
|
1112 |
|
|
1113 |
(defvar cscope-last-file nil
|
|
1114 |
"The file referenced by the last line of cscope process output.")
|
|
1115 |
(make-variable-buffer-local 'cscope-last-file)
|
|
1116 |
|
|
1117 |
|
|
1118 |
(defvar cscope-start-time nil
|
|
1119 |
"The search start time, in seconds.")
|
|
1120 |
(make-variable-buffer-local 'cscope-start-time)
|
|
1121 |
|
|
1122 |
|
|
1123 |
(defvar cscope-first-match-point nil
|
|
1124 |
"Buffer location of the first match.")
|
|
1125 |
(make-variable-buffer-local 'cscope-first-match-point)
|
|
1126 |
|
|
1127 |
|
|
1128 |
(defvar cscope-output-start nil
|
|
1129 |
"The point location of the start of a search's output.")
|
|
1130 |
(make-variable-buffer-local 'cscope-output-start)
|
|
1131 |
|
|
1132 |
|
|
1133 |
(defvar cscope-matched-multiple nil
|
|
1134 |
"Non-nil if cscope output multiple matches.")
|
|
1135 |
(make-variable-buffer-local 'cscope-matched-multiple)
|
|
1136 |
|
|
1137 |
|
|
1138 |
(defvar cscope-stop-at-first-match-dir-meta nil
|
|
1139 |
"")
|
|
1140 |
(make-variable-buffer-local 'cscope-stop-at-first-match-dir-meta)
|
|
1141 |
|
|
1142 |
|
|
1143 |
(defvar cscope-fuzzy-search-range 1000
|
|
1144 |
"How far the point should be adjusted if the symbol is not on the line
|
|
1145 |
specified by the cscope database.")
|
|
1146 |
|
|
1147 |
(defvar cscope-previous-user-search nil
|
|
1148 |
"A form that describes the last search that was executed. For
|
|
1149 |
instance if the last search was to find all uses of the symbol
|
|
1150 |
\"N\", this variable would be set to '(cscope-find-this-symbol
|
|
1151 |
\"N\")")
|
|
1152 |
|
|
1153 |
(defvar cscope-marker nil
|
|
1154 |
"The location from which cscope was invoked.")
|
|
1155 |
|
|
1156 |
|
|
1157 |
(defvar cscope-marker-window nil
|
|
1158 |
"The window which should contain cscope-marker. This is the window from
|
|
1159 |
which cscope-marker is set when searches are launched from the *cscope*
|
|
1160 |
buffer.")
|
|
1161 |
|
|
1162 |
|
|
1163 |
(defvar cscope-marker-ring-length 16
|
|
1164 |
"Length of the cscope marker ring.")
|
|
1165 |
|
|
1166 |
|
|
1167 |
(defvar cscope-marker-ring (make-ring cscope-marker-ring-length)
|
|
1168 |
"Ring of markers which are locations from which cscope was invoked.")
|
|
1169 |
|
|
1170 |
|
|
1171 |
(defvar cscope-initial-directory nil
|
|
1172 |
"When set the directory in which searches for the cscope database
|
|
1173 |
directory should begin.")
|
|
1174 |
|
|
1175 |
(defvar cscope-prompt-minibuffer-history nil
|
|
1176 |
"The history of terms we searched for. This is one common
|
|
1177 |
history for ALL search types.")
|
|
1178 |
|
|
1179 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1180 |
|
|
1181 |
(defvar cscope-command-map
|
|
1182 |
(let ((map (make-sparse-keymap)))
|
|
1183 |
;; The following line corresponds to be beginning of the "Cscope" menu.
|
|
1184 |
(define-key map "s" 'cscope-find-this-symbol)
|
|
1185 |
(define-key map "d" 'cscope-find-global-definition)
|
|
1186 |
(define-key map "g" 'cscope-find-global-definition)
|
|
1187 |
(define-key map "G" 'cscope-find-global-definition-no-prompting)
|
|
1188 |
(define-key map "=" 'cscope-find-assignments-to-this-symbol)
|
|
1189 |
(define-key map "c" 'cscope-find-functions-calling-this-function)
|
|
1190 |
(define-key map "C" 'cscope-find-called-functions)
|
|
1191 |
(define-key map "t" 'cscope-find-this-text-string)
|
|
1192 |
(define-key map "e" 'cscope-find-egrep-pattern)
|
|
1193 |
(define-key map "f" 'cscope-find-this-file)
|
|
1194 |
(define-key map "i" 'cscope-find-files-including-file)
|
|
1195 |
;; --- (The '---' indicates that this line corresponds to a menu separator.)
|
|
1196 |
(define-key map "b" 'cscope-display-buffer)
|
|
1197 |
(define-key map "B" 'cscope-display-buffer-toggle)
|
|
1198 |
(define-key map "n" 'cscope-history-forward-line-current-result)
|
|
1199 |
(define-key map "N" 'cscope-history-forward-file-current-result)
|
|
1200 |
(define-key map "p" 'cscope-history-backward-line-current-result)
|
|
1201 |
(define-key map "P" 'cscope-history-backward-file-current-result)
|
|
1202 |
(define-key map "u" 'cscope-pop-mark)
|
|
1203 |
;; ---
|
|
1204 |
(define-key map "a" 'cscope-set-initial-directory)
|
|
1205 |
(define-key map "A" 'cscope-unset-initial-directory)
|
|
1206 |
;; ---
|
|
1207 |
(define-key map "L" 'cscope-create-list-of-files-to-index)
|
|
1208 |
(define-key map "I" 'cscope-index-files)
|
|
1209 |
(define-key map "E" 'cscope-edit-list-of-files-to-index)
|
|
1210 |
(define-key map "W" 'cscope-tell-user-about-directory)
|
|
1211 |
(define-key map "S" 'cscope-tell-user-about-directory)
|
|
1212 |
(define-key map "T" 'cscope-tell-user-about-directory)
|
|
1213 |
(define-key map "D" 'cscope-dired-directory)
|
|
1214 |
;; The previous line corresponds to be end of the "Cscope" menu.
|
|
1215 |
map)
|
|
1216 |
"The keymap used by cscope. This is defined relative to
|
|
1217 |
`cscope-keymap-prefix'")
|
|
1218 |
|
|
1219 |
(defcustom cscope-keymap-prefix "\C-cs"
|
|
1220 |
"Prefix for key bindings of `cscope-minor-mode'.
|
|
1221 |
|
|
1222 |
Changing this variable outside Customize does not have any
|
|
1223 |
effect. To change the keymap prefix from Lisp, you need to
|
|
1224 |
explicitly re-define the prefix key:
|
|
1225 |
|
|
1226 |
(define-key cscope-minor-mode-keymap cscope-keymap-prefix nil)
|
|
1227 |
(setq cscope-keymap-prefix (kbd \"C-c ,\"))
|
|
1228 |
(define-key cscope-minor-mode-keymap cscope-keymap-prefix
|
|
1229 |
cscope-command-map)"
|
|
1230 |
:group 'cscope
|
|
1231 |
:type 'string
|
|
1232 |
:risky t
|
|
1233 |
:set
|
|
1234 |
(lambda (variable key)
|
|
1235 |
(when (and (boundp variable) (boundp 'cscope-minor-mode-keymap))
|
|
1236 |
(define-key cscope-minor-mode-keymap (symbol-value variable) nil)
|
|
1237 |
(define-key cscope-minor-mode-keymap key cscope-command-map))
|
|
1238 |
(set-default variable key)))
|
|
1239 |
|
|
1240 |
(defvar cscope-minor-mode-keymap
|
|
1241 |
(let ((map (make-sparse-keymap)))
|
|
1242 |
|
|
1243 |
;; xemacs has various issues with (cscope-mouse-popup-menu-or-search), so I
|
|
1244 |
;; don't use that function for xemacs. Its popup menu support won't be as
|
|
1245 |
;; good (cscope will still prompt for the search term)
|
|
1246 |
(if cscope-running-in-xemacs
|
|
1247 |
(progn
|
|
1248 |
(define-key map [(shift button3)] 'cscope-mouse-search-again))
|
|
1249 |
(define-key map [mouse-3] 'cscope-mouse-popup-menu-or-search)
|
|
1250 |
(define-key map [S-mouse-3] 'cscope-mouse-search-again))
|
|
1251 |
|
|
1252 |
(define-key map cscope-keymap-prefix cscope-command-map)
|
|
1253 |
|
|
1254 |
map)
|
|
1255 |
"The global cscope keymap")
|
|
1256 |
|
|
1257 |
(let ((menu-before
|
|
1258 |
'([ "Find symbol" cscope-find-this-symbol t ]
|
|
1259 |
[ "Find global definition" cscope-find-global-definition t ]
|
|
1260 |
[ "Find global definition no prompting"
|
|
1261 |
cscope-find-global-definition-no-prompting t ]
|
|
1262 |
[ "Find assignments to symbol"
|
|
1263 |
cscope-find-assignments-to-this-symbol t ]
|
|
1264 |
[ "Find functions calling a function"
|
|
1265 |
cscope-find-functions-calling-this-function t ]
|
|
1266 |
[ "Find called functions" cscope-find-called-functions t ]
|
|
1267 |
[ "Find text string" cscope-find-this-text-string t ]
|
|
1268 |
[ "Find egrep pattern" cscope-find-egrep-pattern t ]
|
|
1269 |
[ "Find a file" cscope-find-this-file t ]
|
|
1270 |
[ "Find files #including a file"
|
|
1271 |
cscope-find-files-including-file t ]
|
|
1272 |
"-----------"))
|
|
1273 |
|
|
1274 |
(menu-only-global
|
|
1275 |
'([ "Display *cscope* buffer" cscope-display-buffer t ]
|
|
1276 |
"-----------"
|
|
1277 |
[ "Next symbol" cscope-history-forward-line-current-result t ]
|
|
1278 |
[ "Next file" cscope-history-forward-file-current-result t ]
|
|
1279 |
[ "Previous symbol" cscope-history-backward-line-current-result t ]
|
|
1280 |
[ "Previous file" cscope-history-backward-file-current-result t ]
|
|
1281 |
[ "Pop mark" cscope-pop-mark t ]
|
|
1282 |
"-----------"
|
|
1283 |
))
|
|
1284 |
|
|
1285 |
(menu-only-cscope
|
|
1286 |
'([ "Next symbol" cscope-history-forward-line t ]
|
|
1287 |
[ "Next file" cscope-history-forward-file t ]
|
|
1288 |
[ "Next result" cscope-history-forward-result t ]
|
|
1289 |
[ "Previous symbol" cscope-history-backward-line t ]
|
|
1290 |
[ "Previous file" cscope-history-backward-file t ]
|
|
1291 |
[ "Previous result" cscope-history-backward-result t ]
|
|
1292 |
[ "Kill symbol" cscope-history-kill-line t ]
|
|
1293 |
[ "Kill file" cscope-history-kill-file t ]
|
|
1294 |
[ "Kill result" cscope-history-kill-result t ]
|
|
1295 |
[ "Pop mark" cscope-pop-mark t ]
|
|
1296 |
"-----------"
|
|
1297 |
[ "Rerun search at point" cscope-rerun-search-at-point t ]
|
|
1298 |
"-----------"
|
|
1299 |
))
|
|
1300 |
|
|
1301 |
(menu-after
|
|
1302 |
'(( "Cscope Database"
|
|
1303 |
[ "Set initial directory"
|
|
1304 |
cscope-set-initial-directory t ]
|
|
1305 |
[ "Unset initial directory"
|
|
1306 |
cscope-unset-initial-directory t ]
|
|
1307 |
"-----------"
|
|
1308 |
[ "Create list of files to index"
|
|
1309 |
cscope-create-list-of-files-to-index t ]
|
|
1310 |
[ "Create list and index"
|
|
1311 |
cscope-index-files t ]
|
|
1312 |
[ "Edit list of files to index"
|
|
1313 |
cscope-edit-list-of-files-to-index t ]
|
|
1314 |
[ "Locate this buffer's cscope directory"
|
|
1315 |
cscope-tell-user-about-directory t ]
|
|
1316 |
[ "Dired this buffer's cscope directory"
|
|
1317 |
cscope-dired-directory t ]
|
|
1318 |
)
|
|
1319 |
"-----------"
|
|
1320 |
( "Options"
|
|
1321 |
[ "Auto close *cscope* buffer"
|
|
1322 |
(setq cscope-close-window-after-select
|
|
1323 |
(not cscope-close-window-after-select))
|
|
1324 |
:style toggle :selected cscope-close-window-after-select ]
|
|
1325 |
[ "Auto edit single match"
|
|
1326 |
(setq cscope-edit-single-match
|
|
1327 |
(not cscope-edit-single-match))
|
|
1328 |
:style toggle :selected cscope-edit-single-match ]
|
|
1329 |
[ "Auto display *cscope* buffer"
|
|
1330 |
(setq cscope-display-cscope-buffer
|
|
1331 |
(not cscope-display-cscope-buffer))
|
|
1332 |
:style toggle :selected cscope-display-cscope-buffer ]
|
|
1333 |
[ "Stop at first matching database"
|
|
1334 |
(setq cscope-stop-at-first-match-dir
|
|
1335 |
(not cscope-stop-at-first-match-dir))
|
|
1336 |
:style toggle
|
|
1337 |
:selected cscope-stop-at-first-match-dir ]
|
|
1338 |
[ "Never update cscope database"
|
|
1339 |
(setq cscope-option-do-not-update-database
|
|
1340 |
(not cscope-option-do-not-update-database))
|
|
1341 |
:style toggle :selected cscope-option-do-not-update-database ]
|
|
1342 |
[ "Disable cscope database compression"
|
|
1343 |
(setq cscope-option-disable-compression
|
|
1344 |
(not cscope-option-disable-compression))
|
|
1345 |
:style toggle :selected cscope-option-disable-compression ]
|
|
1346 |
[ "Index using 'kernel mode'"
|
|
1347 |
(setq cscope-option-kernel-mode
|
|
1348 |
(not cscope-option-kernel-mode))
|
|
1349 |
:style toggle :selected cscope-option-kernel-mode ]
|
|
1350 |
[ "Build an inverted index"
|
|
1351 |
(setq cscope-option-use-inverted-index
|
|
1352 |
(not cscope-option-use-inverted-index))
|
|
1353 |
:style toggle :selected cscope-option-use-inverted-index ]
|
|
1354 |
[ "Index recursively"
|
|
1355 |
(setq cscope-index-recursively
|
|
1356 |
(not cscope-index-recursively))
|
|
1357 |
:style toggle :selected cscope-index-recursively ]
|
|
1358 |
[ "Use relative paths"
|
|
1359 |
(setq cscope-use-relative-paths
|
|
1360 |
(not cscope-use-relative-paths))
|
|
1361 |
:style toggle :selected cscope-use-relative-paths ]
|
|
1362 |
)
|
|
1363 |
)))
|
|
1364 |
|
|
1365 |
(easy-menu-define cscope-global-menu
|
|
1366 |
cscope-minor-mode-keymap
|
|
1367 |
"cscope menu"
|
|
1368 |
`("Cscope" ,@menu-before ,@menu-only-global ,@menu-after))
|
|
1369 |
|
|
1370 |
(easy-menu-define cscope-buffer-menu
|
|
1371 |
cscope-list-entry-keymap
|
|
1372 |
"cscope menu"
|
|
1373 |
`("Cscope" ,@menu-before ,@menu-only-cscope ,@menu-after)))
|
|
1374 |
|
|
1375 |
|
|
1376 |
(defun cscope-mouse-popup-menu-or-search (event)
|
|
1377 |
"Pop-up the menu or rerun the last search when double-clicked.
|
|
1378 |
EVENT is the mouse event."
|
|
1379 |
(interactive "e")
|
|
1380 |
(mouse-set-point event)
|
|
1381 |
(let ((click-count (event-click-count event)))
|
|
1382 |
(cond
|
|
1383 |
((eq click-count 1) (cscope-popup-menu event))
|
|
1384 |
((eq click-count 2) (cscope-run-last-search-noprompt)))))
|
|
1385 |
|
|
1386 |
(defun cscope-mouse-search-again (event)
|
|
1387 |
"Run the last search type again on the symbol the user clicked
|
|
1388 |
on. EVENT is the mouse event."
|
|
1389 |
(interactive "e")
|
|
1390 |
(mouse-set-point event)
|
|
1391 |
(cscope-run-last-search-noprompt))
|
|
1392 |
|
|
1393 |
(defun cscope-popup-menu (event)
|
|
1394 |
"Pop up MENU and perform an action if something was selected.
|
|
1395 |
EVENT is the mouse event."
|
|
1396 |
(save-selected-window
|
|
1397 |
(select-window (posn-window (event-start event)))
|
|
1398 |
(let ((selection (x-popup-menu event cscope-global-menu))
|
|
1399 |
binding)
|
|
1400 |
(while selection
|
|
1401 |
(setq binding (lookup-key (or binding cscope-global-menu) (vector (car selection)))
|
|
1402 |
selection (cdr selection)))
|
|
1403 |
(when binding
|
|
1404 |
(let (cscope-suppress-user-symbol-prompt)
|
|
1405 |
(call-interactively binding))))))
|
|
1406 |
|
|
1407 |
(defun cscope-run-last-search-noprompt ()
|
|
1408 |
"Run the last search type off of the symbol at point without
|
|
1409 |
prompting the user. This is mostly for mouse-initiated searches."
|
|
1410 |
(when cscope-previous-user-search
|
|
1411 |
(let (cscope-suppress-user-symbol-prompt)
|
|
1412 |
(call-interactively (car cscope-previous-user-search)))))
|
|
1413 |
|
|
1414 |
|
|
1415 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1416 |
;; Internal functions and variables
|
|
1417 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1418 |
|
|
1419 |
(defun cscope-insert-with-text-properties (text filename &optional line-number line)
|
|
1420 |
"Insert an entry with given TEXT, add entry attributes as text
|
|
1421 |
properties. Unlike 'cscope-make-entry-line' this function is
|
|
1422 |
called both for cscope entry lines and cscope file lines
|
|
1423 |
|
|
1424 |
The text properties to be added:
|
|
1425 |
- common property: mouse-face,
|
|
1426 |
- properties are used to open target file and its location: cscope-file,
|
|
1427 |
cscope-line-number"
|
|
1428 |
(let (plist beg end)
|
|
1429 |
|
|
1430 |
(when cscope-use-face
|
|
1431 |
(setq plist (plist-put plist 'mouse-face 'cscope-mouse-face)))
|
|
1432 |
|
|
1433 |
(setq beg (point))
|
|
1434 |
(insert text)
|
|
1435 |
(setq end (point)
|
|
1436 |
plist (plist-put plist 'cscope-file filename))
|
|
1437 |
(when line-number
|
|
1438 |
(when (stringp line-number)
|
|
1439 |
(setq line-number (string-to-number line-number)))
|
|
1440 |
(setq plist (plist-put plist 'cscope-line-number line-number)))
|
|
1441 |
|
|
1442 |
(add-text-properties beg end plist)
|
|
1443 |
))
|
|
1444 |
|
|
1445 |
|
|
1446 |
(if cscope-running-in-xemacs
|
|
1447 |
(progn
|
|
1448 |
(defalias 'cscope-event-window 'event-window)
|
|
1449 |
(defalias 'cscope-event-point 'event-point)
|
|
1450 |
(defalias 'cscope-recenter 'recenter)
|
|
1451 |
)
|
|
1452 |
(defun cscope-event-window (event)
|
|
1453 |
"Return the window at which the mouse EVENT occurred."
|
|
1454 |
(posn-window (event-start event)))
|
|
1455 |
(defun cscope-event-point (event)
|
|
1456 |
"Return the point at which the mouse EVENT occurred."
|
|
1457 |
(posn-point (event-start event)))
|
|
1458 |
(defun cscope-recenter (&optional n window)
|
|
1459 |
"Center point in WINDOW and redisplay frame. With N, put point on line N."
|
|
1460 |
(save-selected-window
|
|
1461 |
(if (windowp window)
|
|
1462 |
(select-window window))
|
|
1463 |
(recenter n)))
|
|
1464 |
)
|
|
1465 |
|
|
1466 |
|
|
1467 |
(defun cscope-show-entry-internal (navprops
|
|
1468 |
&optional save-mark-p window arrow-p)
|
|
1469 |
"Display the buffer corresponding to FILE and LINE-NUMBER
|
|
1470 |
in some window. If optional argument WINDOW is given,
|
|
1471 |
display the buffer in that WINDOW instead. The window is
|
|
1472 |
not selected. Save point on mark ring before goto
|
|
1473 |
LINE-NUMBER if optional argument SAVE-MARK-P is non-nil.
|
|
1474 |
Put `overlay-arrow-string' if arrow-p is non-nil.
|
|
1475 |
Returns the window displaying BUFFER."
|
|
1476 |
(let ( (file (elt navprops 0))
|
|
1477 |
(line-number (or (elt navprops 1) -1))
|
|
1478 |
(fuzzy-search-text-regexp (elt navprops 2))
|
|
1479 |
buffer old-pos old-point new-point forward-point backward-point
|
|
1480 |
line-end line-length)
|
|
1481 |
(if (and (stringp file)
|
|
1482 |
(integerp line-number))
|
|
1483 |
(progn
|
|
1484 |
(unless (file-readable-p file)
|
|
1485 |
(error "%s is not readable or exists" file))
|
|
1486 |
(setq buffer (find-file-noselect file))
|
|
1487 |
(if (windowp window)
|
|
1488 |
(set-window-buffer window buffer)
|
|
1489 |
(setq window (cscope-display-buffer-wrapper buffer)))
|
|
1490 |
(set-buffer buffer)
|
|
1491 |
(if (> line-number 0)
|
|
1492 |
(progn
|
|
1493 |
(setq old-pos (point))
|
|
1494 |
|
|
1495 |
;; this is recommended instead of (goto-line line-number)
|
|
1496 |
(save-restriction
|
|
1497 |
(widen)
|
|
1498 |
(goto-char (point-min))
|
|
1499 |
(forward-line (1- line-number)))
|
|
1500 |
|
|
1501 |
(setq old-point (point))
|
|
1502 |
|
|
1503 |
;; Here I perform a fuzzy search. If the user has edited the
|
|
1504 |
;; sources after building the cscope database, cscope may have
|
|
1505 |
;; the wrong line numbers. Here I try to correct for this by
|
|
1506 |
;; finding the cscope results in the text around where cscope
|
|
1507 |
;; said they should appear. There is a choice here: I could look
|
|
1508 |
;; for the original string the user searched for, or I can look
|
|
1509 |
;; for the longer string that cscope has found. I do the latter
|
|
1510 |
(if (and fuzzy-search-text-regexp cscope-fuzzy-search-range)
|
|
1511 |
(progn
|
|
1512 |
;; Calculate the length of the line specified by cscope.
|
|
1513 |
(end-of-line)
|
|
1514 |
(setq line-end (point))
|
|
1515 |
(goto-char old-point)
|
|
1516 |
(setq line-length (- line-end old-point))
|
|
1517 |
|
|
1518 |
;; Search forward and backward for the pattern.
|
|
1519 |
(setq forward-point (re-search-forward
|
|
1520 |
fuzzy-search-text-regexp
|
|
1521 |
(+ old-point
|
|
1522 |
cscope-fuzzy-search-range) t))
|
|
1523 |
(goto-char old-point)
|
|
1524 |
(setq backward-point (re-search-backward
|
|
1525 |
fuzzy-search-text-regexp
|
|
1526 |
(- old-point
|
|
1527 |
cscope-fuzzy-search-range) t))
|
|
1528 |
(if forward-point
|
|
1529 |
(progn
|
|
1530 |
(if backward-point
|
|
1531 |
(setq new-point
|
|
1532 |
;; Use whichever of forward-point or
|
|
1533 |
;; backward-point is closest to old-point.
|
|
1534 |
;; Give forward-point a line-length advantage
|
|
1535 |
;; so that if the symbol is on the current
|
|
1536 |
;; line the current line is chosen.
|
|
1537 |
(if (<= (- (- forward-point line-length)
|
|
1538 |
old-point)
|
|
1539 |
(- old-point backward-point))
|
|
1540 |
forward-point
|
|
1541 |
backward-point))
|
|
1542 |
(setq new-point forward-point)))
|
|
1543 |
(if backward-point
|
|
1544 |
(setq new-point backward-point)
|
|
1545 |
(setq new-point old-point)))
|
|
1546 |
(goto-char new-point)
|
|
1547 |
(beginning-of-line)
|
|
1548 |
(setq new-point (point)))
|
|
1549 |
(setq new-point old-point))
|
|
1550 |
(set-window-point window new-point)
|
|
1551 |
|
|
1552 |
;; if we're using an arrow overlay....
|
|
1553 |
(if (and cscope-allow-arrow-overlays arrow-p)
|
|
1554 |
(set-marker
|
|
1555 |
|
|
1556 |
;; ... set the existing marker if there is one, or make a
|
|
1557 |
;; new one ...
|
|
1558 |
(or overlay-arrow-position
|
|
1559 |
(setq overlay-arrow-position (make-marker)))
|
|
1560 |
|
|
1561 |
;; ... at point
|
|
1562 |
(point))
|
|
1563 |
|
|
1564 |
;; if we need to remove a marker, do that if there is one
|
|
1565 |
(when overlay-arrow-position
|
|
1566 |
(set-marker overlay-arrow-position nil)))
|
|
1567 |
|
|
1568 |
(or (not save-mark-p)
|
|
1569 |
(= old-pos (point))
|
|
1570 |
(push-mark old-pos))
|
|
1571 |
))
|
|
1572 |
|
|
1573 |
(if cscope-marker
|
|
1574 |
(progn ;; The search was successful. Save the marker so it
|
|
1575 |
;; can be returned to by cscope-pop-mark.
|
|
1576 |
(ring-insert cscope-marker-ring cscope-marker)
|
|
1577 |
;; Unset cscope-marker so that moving between matches does not
|
|
1578 |
;; fill cscope-marker-ring.
|
|
1579 |
(setq cscope-marker nil)))
|
|
1580 |
(setq cscope-marker-window window)
|
|
1581 |
)
|
|
1582 |
(message "No entry found at point."))
|
|
1583 |
)
|
|
1584 |
window)
|
|
1585 |
|
|
1586 |
(defun cscope-find-this-separator-start (separator-regex from &optional strict)
|
|
1587 |
"Finds the start of the given separator before FROM.
|
|
1588 |
If FROM is anywhere in a separator string, this separator is
|
|
1589 |
used. If STRICT is non-nil this function returns nil if no
|
|
1590 |
separator is found. Otherwise '(point-min)' is returned"
|
|
1591 |
|
|
1592 |
;; if we're below (point-min), give up. This can happen when trying to search
|
|
1593 |
;; before eob. For instance, trying to find the prev result from eob
|
|
1594 |
(if (< from (point-min))
|
|
1595 |
(if strict nil (point-min))
|
|
1596 |
|
|
1597 |
(let ((separator-regex-at-bol (concat "^" separator-regex)))
|
|
1598 |
(save-excursion
|
|
1599 |
(goto-char from)
|
|
1600 |
(beginning-of-line)
|
|
1601 |
|
|
1602 |
;; if we're at the separator, use it
|
|
1603 |
(if (looking-at separator-regex) (point)
|
|
1604 |
|
|
1605 |
;; otherwise, find the previous separator
|
|
1606 |
(or
|
|
1607 |
(re-search-backward separator-regex-at-bol nil t nil)
|
|
1608 |
|
|
1609 |
;; if there isn't one, use the start of the buffer
|
|
1610 |
(if strict nil (point-min))))))))
|
|
1611 |
|
|
1612 |
(defun cscope-find-next-separator-start (separator-regex from &optional strict)
|
|
1613 |
"Finds the next start of the given separator after FROM.
|
|
1614 |
If FROM is anywhere in a separator string, the next separator is
|
|
1615 |
used. If STRICT is non-nil this function returns nil if no
|
|
1616 |
separator is found. Otherwise '(point-min)' is returned"
|
|
1617 |
|
|
1618 |
(let ((separator-regex-at-bol (concat "^" separator-regex)))
|
|
1619 |
(save-excursion
|
|
1620 |
(goto-char from)
|
|
1621 |
|
|
1622 |
;; try to find the next separator (start a bit forward to not find
|
|
1623 |
;; the current one).
|
|
1624 |
(if (progn (forward-char)
|
|
1625 |
(re-search-forward separator-regex-at-bol nil t nil))
|
|
1626 |
|
|
1627 |
;; if there is a next one, navigate to its start, and use it
|
|
1628 |
(progn
|
|
1629 |
(forward-line -1)
|
|
1630 |
(beginning-of-line)
|
|
1631 |
(point))
|
|
1632 |
|
|
1633 |
;; otherwise, use the end of the buffer
|
|
1634 |
(if strict nil (point-max))))))
|
|
1635 |
|
|
1636 |
(defun cscope-get-history-bounds-this-result-internal (start-regex &optional end-regex)
|
|
1637 |
"Returns a list of the beginning and the end of the results
|
|
1638 |
at (point). If END-REGEX is nil, the START-REGEX is used for both
|
|
1639 |
the start and end bounds; the region then contains the start
|
|
1640 |
separator, but not the end separator. If END-REGEX is non-nil, it
|
|
1641 |
is used to find the end bound, and the region then contains both
|
|
1642 |
separators. If some error has occured or if (point) isn't within
|
|
1643 |
the computed bounds then nil is returned"
|
|
1644 |
|
|
1645 |
(let* ((beg (cscope-find-this-separator-start start-regex (point)))
|
|
1646 |
(end
|
|
1647 |
(if end-regex
|
|
1648 |
;; we have an end regex
|
|
1649 |
(save-excursion
|
|
1650 |
(goto-char beg)
|
|
1651 |
(re-search-forward (concat "^" end-regex) nil t nil))
|
|
1652 |
|
|
1653 |
;; no end regex given. use the start regex
|
|
1654 |
(cscope-find-next-separator-start start-regex beg))))
|
|
1655 |
|
|
1656 |
;; return the list if both bounds exist, and the original point is
|
|
1657 |
;; within those bounds
|
|
1658 |
(if (and beg
|
|
1659 |
end
|
|
1660 |
(>= (point) beg)
|
|
1661 |
(or (< (point) end)
|
|
1662 |
(and (eobp) (= (point) end))))
|
|
1663 |
(list beg end)
|
|
1664 |
nil)))
|
|
1665 |
|
|
1666 |
(defun cscope-get-history-bounds-this-result (which)
|
|
1667 |
"Convenience wrapper around
|
|
1668 |
'cscope-get-history-bounds-this-result-internal'. WHICH is
|
|
1669 |
'result to ask for result bounds or 'file to ask for file bounds"
|
|
1670 |
(cond
|
|
1671 |
((eq which 'result) (cscope-get-history-bounds-this-result-internal cscope-result-separator))
|
|
1672 |
((eq which 'file) (cscope-get-history-bounds-this-result-internal cscope-file-separator-start-regex
|
|
1673 |
cscope-file-separator-end-regex))
|
|
1674 |
(t (error "cscope-get-history-bounds-this-result knows only about 'result and 'file"))))
|
|
1675 |
|
|
1676 |
|
|
1677 |
(defun cscope-get-navigation-properties (&optional at buffer)
|
|
1678 |
"Reads the cscope navigation properties on this line. The
|
|
1679 |
properties themselves are read from the beginning of the line,
|
|
1680 |
since the trailing newline is NOT propertized."
|
|
1681 |
(with-current-buffer (or buffer (current-buffer))
|
|
1682 |
(save-excursion
|
|
1683 |
(when at (goto-char at))
|
|
1684 |
(beginning-of-line)
|
|
1685 |
(vector (get-text-property (point) 'cscope-file)
|
|
1686 |
(get-text-property (point) 'cscope-line-number)
|
|
1687 |
(get-text-property (point) 'cscope-fuzzy-search-text-regexp)))))
|
|
1688 |
|
|
1689 |
(defun cscope-get-directory (&optional beg-end)
|
|
1690 |
"In a *cscope* buffer, searches for the
|
|
1691 |
|
|
1692 |
Database directory:
|
|
1693 |
|
|
1694 |
string to get the directory of the search at point."
|
|
1695 |
|
|
1696 |
(save-excursion
|
|
1697 |
|
|
1698 |
(when (not beg-end)
|
|
1699 |
(setq beg-end (cscope-get-history-bounds-this-result 'result)))
|
|
1700 |
|
|
1701 |
(end-of-line)
|
|
1702 |
(let ((case-fold-search nil))
|
|
1703 |
(and
|
|
1704 |
(or
|
|
1705 |
(re-search-backward (concat
|
|
1706 |
"^" cscope-database-directory-prompt
|
|
1707 |
"[a-z/]*: \\(.+\\)$")
|
|
1708 |
(car beg-end) t)
|
|
1709 |
(progn
|
|
1710 |
(goto-char (car beg-end))
|
|
1711 |
(re-search-forward (concat
|
|
1712 |
"^" cscope-database-directory-prompt
|
|
1713 |
"[a-z/]*: \\(.+\\)$")
|
|
1714 |
(cadr beg-end) t)))
|
|
1715 |
(match-string-no-properties 1)))))
|
|
1716 |
|
|
1717 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1718 |
;; functions in *cscope* buffer which lists the search results
|
|
1719 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1720 |
|
|
1721 |
(defun cscope-select-entry-other-window ()
|
|
1722 |
"Display the entry at point in other window, select the window.
|
|
1723 |
Push current point on mark ring and select the entry window."
|
|
1724 |
(interactive)
|
|
1725 |
(let ((navprops (cscope-get-navigation-properties))
|
|
1726 |
window)
|
|
1727 |
(setq window (cscope-show-entry-internal navprops t))
|
|
1728 |
(if (windowp window)
|
|
1729 |
(select-window window))
|
|
1730 |
)
|
|
1731 |
(if cscope-close-window-after-select
|
|
1732 |
(delete-windows-on cscope-output-buffer-name)))
|
|
1733 |
|
|
1734 |
(defun cscope-select-entry-inplace ()
|
|
1735 |
"Display the entry in the window currently occupied by the
|
|
1736 |
*cscope* buffer"
|
|
1737 |
(interactive)
|
|
1738 |
|
|
1739 |
(let ((navprops (cscope-get-navigation-properties))
|
|
1740 |
window)
|
|
1741 |
(cscope-show-entry-internal navprops t (selected-window))))
|
|
1742 |
|
|
1743 |
(defun cscope-select-entry-one-window ()
|
|
1744 |
"Display the entry at point in one window, select the window."
|
|
1745 |
(interactive)
|
|
1746 |
(let ((navprops (cscope-get-navigation-properties))
|
|
1747 |
window)
|
|
1748 |
(setq window (cscope-show-entry-internal navprops t))
|
|
1749 |
(if (windowp window)
|
|
1750 |
(progn
|
|
1751 |
(select-window window)
|
|
1752 |
(sit-for 0) ;; Redisplay hack to allow delete-other-windows
|
|
1753 |
;; to continue displaying the correct location.
|
|
1754 |
(delete-other-windows window)
|
|
1755 |
))
|
|
1756 |
))
|
|
1757 |
|
|
1758 |
|
|
1759 |
(defun cscope-select-entry-specified-window (window)
|
|
1760 |
"Display the entry at point in a specified window, select the window."
|
|
1761 |
(interactive)
|
|
1762 |
(let ((navprops (cscope-get-navigation-properties)))
|
|
1763 |
(setq window (cscope-show-entry-internal navprops t window))
|
|
1764 |
(if (windowp window)
|
|
1765 |
(select-window window))
|
|
1766 |
))
|
|
1767 |
|
|
1768 |
|
|
1769 |
(defun cscope-mouse-select-entry-other-window (event)
|
|
1770 |
"Display the entry over which the mouse event occurred, select the window."
|
|
1771 |
(interactive "e")
|
|
1772 |
(let ((ep (cscope-event-point event))
|
|
1773 |
(win (cscope-event-window event))
|
|
1774 |
window)
|
|
1775 |
(if ep
|
|
1776 |
(progn
|
|
1777 |
(let ((navprops (cscope-get-navigation-properties ep (window-buffer win))))
|
|
1778 |
(select-window win)
|
|
1779 |
(setq window (cscope-show-entry-internal navprops t)))
|
|
1780 |
(if (windowp window)
|
|
1781 |
(select-window window)))
|
|
1782 |
(message "No entry found at point.")
|
|
1783 |
)
|
|
1784 |
))
|
|
1785 |
|
|
1786 |
(defun cscope-mouse-select-entry-inplace (event)
|
|
1787 |
"Display the entry over which the mouse event occurred, select the window."
|
|
1788 |
(interactive "e")
|
|
1789 |
(let ((ep (cscope-event-point event))
|
|
1790 |
(win (cscope-event-window event)))
|
|
1791 |
(if ep
|
|
1792 |
(progn
|
|
1793 |
(let ((navprops (cscope-get-navigation-properties ep (window-buffer win))))
|
|
1794 |
(select-window win)
|
|
1795 |
(cscope-show-entry-internal navprops t win)))
|
|
1796 |
(message "No entry found at point.")
|
|
1797 |
)
|
|
1798 |
))
|
|
1799 |
|
|
1800 |
|
|
1801 |
(defun cscope-show-entry-other-window ()
|
|
1802 |
"Display the entry at point in other window.
|
|
1803 |
Point is not saved on mark ring."
|
|
1804 |
(interactive)
|
|
1805 |
(let ((navprops (cscope-get-navigation-properties)))
|
|
1806 |
(cscope-show-entry-internal navprops nil nil t)
|
|
1807 |
))
|
|
1808 |
|
|
1809 |
|
|
1810 |
(defun cscope-display-buffer ()
|
|
1811 |
"Display the *cscope* buffer."
|
|
1812 |
(interactive)
|
|
1813 |
(let ((buffer (get-buffer cscope-output-buffer-name)))
|
|
1814 |
(if buffer
|
|
1815 |
(pop-to-buffer buffer)
|
|
1816 |
(error "The *cscope* buffer does not exist yet"))))
|
|
1817 |
|
|
1818 |
|
|
1819 |
(defun cscope-display-buffer-toggle ()
|
|
1820 |
"Toggle cscope-display-cscope-buffer, which corresponds to
|
|
1821 |
\"Auto display *cscope* buffer\"."
|
|
1822 |
(interactive)
|
|
1823 |
(setq cscope-display-cscope-buffer (not cscope-display-cscope-buffer))
|
|
1824 |
(message "The cscope-display-cscope-buffer variable is now %s."
|
|
1825 |
(if cscope-display-cscope-buffer "set" "unset")))
|
|
1826 |
|
|
1827 |
(defun cscope-navigate-and-show (forms &optional no-show)
|
|
1828 |
"This evaluates the navigation FORMS. These FORMS move the
|
|
1829 |
point in the *cscope* buffer, and this function shows the result
|
|
1830 |
in the source"
|
|
1831 |
|
|
1832 |
(let* (old-point
|
|
1833 |
point
|
|
1834 |
(old-buffer (current-buffer))
|
|
1835 |
(old-buffer-window (get-buffer-window old-buffer))
|
|
1836 |
(cscope-buffer (get-buffer cscope-output-buffer-name))
|
|
1837 |
(buffer-window (get-buffer-window (or cscope-buffer (error "The *cscope* buffer does not exist yet"))))
|
|
1838 |
)
|
|
1839 |
(set-buffer cscope-buffer)
|
|
1840 |
(setq old-point (point))
|
|
1841 |
|
|
1842 |
;; I can now evaluate the forms
|
|
1843 |
(let ((forms-result
|
|
1844 |
|
|
1845 |
;; if we're limiting to this result then ...
|
|
1846 |
(if limit-to-current-result
|
|
1847 |
(let ((bounds (cscope-get-history-bounds-this-result 'result)))
|
|
1848 |
(unless bounds (error "Couldn't find result bounds"))
|
|
1849 |
|
|
1850 |
;; ... narrow to this result before evaluating ...
|
|
1851 |
(save-restriction
|
|
1852 |
(apply 'narrow-to-region bounds)
|
|
1853 |
(eval forms)))
|
|
1854 |
|
|
1855 |
;; ... otherwise just evaluate
|
|
1856 |
(eval forms))))
|
|
1857 |
|
|
1858 |
(unless forms-result
|
|
1859 |
(goto-char old-point)
|
|
1860 |
(error "Can't move further")))
|
|
1861 |
|
|
1862 |
(setq point (point))
|
|
1863 |
|
|
1864 |
(unless no-show
|
|
1865 |
(if (eq old-buffer cscope-buffer) ;; In the *cscope* buffer.
|
|
1866 |
(cscope-show-entry-other-window)
|
|
1867 |
(cscope-select-entry-specified-window old-buffer-window) ;; else
|
|
1868 |
(if (windowp buffer-window)
|
|
1869 |
(set-window-point buffer-window point))))
|
|
1870 |
(set-buffer old-buffer)))
|
|
1871 |
|
|
1872 |
(defun cscope-history-forward-backward (separator-regex do-next)
|
|
1873 |
"Body for 'cscope-history-forward-result'/'cscope-history-backward-result'
|
|
1874 |
and 'cscope-history-forward-file'/'cscope-history-backward-file'"
|
|
1875 |
(let ((target-point
|
|
1876 |
(cond
|
|
1877 |
(do-next (cscope-find-next-separator-start separator-regex (point) t))
|
|
1878 |
(t (cscope-find-this-separator-start separator-regex
|
|
1879 |
(- (point) (if (looking-at separator-regex) 1 0)) t)))))
|
|
1880 |
(when target-point (goto-char target-point))))
|
|
1881 |
|
|
1882 |
(defun cscope-history-forward-result ( &optional limit-to-current-result )
|
|
1883 |
"Navigate to the next stored search results in the *cscope*
|
|
1884 |
buffer."
|
|
1885 |
(interactive)
|
|
1886 |
(cscope-navigate-and-show
|
|
1887 |
'(cscope-history-forward-backward cscope-result-separator t) t))
|
|
1888 |
|
|
1889 |
(defun cscope-history-backward-result ( &optional limit-to-current-result )
|
|
1890 |
"Navigate to the previous stored search results in the *cscope*
|
|
1891 |
buffer."
|
|
1892 |
(interactive)
|
|
1893 |
(cscope-navigate-and-show
|
|
1894 |
'(cscope-history-forward-backward cscope-result-separator nil) t))
|
|
1895 |
|
|
1896 |
(defun cscope-history-kill-result ()
|
|
1897 |
"Delete a cscope result from the *cscope* buffer."
|
|
1898 |
(interactive)
|
|
1899 |
(let ((bounds (cscope-get-history-bounds-this-result 'result)))
|
|
1900 |
(if bounds (apply 'delete-region bounds)
|
|
1901 |
(error "Nothing to kill"))))
|
|
1902 |
|
|
1903 |
(defun cscope-history-forward-file ( &optional limit-to-current-result )
|
|
1904 |
"Navigate to the next file results in the *cscope* buffer."
|
|
1905 |
(interactive)
|
|
1906 |
(cscope-navigate-and-show
|
|
1907 |
'(cscope-history-forward-backward cscope-file-separator-start-regex t)))
|
|
1908 |
|
|
1909 |
(defun cscope-history-forward-file-current-result ()
|
|
1910 |
"Like (cscope-history-forward-file), but limited to the current
|
|
1911 |
result only. This exists for blind navigation. If the user isn't
|
|
1912 |
looking at the *cscope* buffer, they shouldn't be jumping between
|
|
1913 |
results"
|
|
1914 |
(interactive)
|
|
1915 |
(cscope-history-forward-file t))
|
|
1916 |
|
|
1917 |
(defun cscope-history-backward-file ( &optional limit-to-current-result )
|
|
1918 |
"Navigate to the previous file results in the *cscope* buffer."
|
|
1919 |
(interactive)
|
|
1920 |
(cscope-navigate-and-show
|
|
1921 |
'(cscope-history-forward-backward cscope-file-separator-start-regex nil)))
|
|
1922 |
|
|
1923 |
(defun cscope-history-backward-file-current-result ()
|
|
1924 |
"Like (cscope-history-backward-file), but limited to the current
|
|
1925 |
result only. This exists for blind navigation. If the user isn't
|
|
1926 |
looking at the *cscope* buffer, they shouldn't be jumping between
|
|
1927 |
results"
|
|
1928 |
(interactive)
|
|
1929 |
(cscope-history-backward-file t))
|
|
1930 |
|
|
1931 |
(defun cscope-history-kill-file ()
|
|
1932 |
"Delete a cscope file set from the *cscope* buffer."
|
|
1933 |
(interactive)
|
|
1934 |
(let ((bounds (cscope-get-history-bounds-this-result 'file)))
|
|
1935 |
(if bounds
|
|
1936 |
(progn
|
|
1937 |
(apply 'delete-region bounds)
|
|
1938 |
(cscope-history-kill-if-empty 'result))
|
|
1939 |
(error "Nothing to kill"))))
|
|
1940 |
|
|
1941 |
(defun cscope-history-forward-line ( &optional limit-to-current-result )
|
|
1942 |
"Navigate to the next result line in the *cscope* buffer."
|
|
1943 |
(interactive)
|
|
1944 |
|
|
1945 |
(cscope-navigate-and-show
|
|
1946 |
'(let ((target
|
|
1947 |
(let ((at (save-excursion
|
|
1948 |
(end-of-line)
|
|
1949 |
(point))))
|
|
1950 |
(next-single-property-change at 'cscope-line-number))))
|
|
1951 |
(when target (goto-char target)))))
|
|
1952 |
|
|
1953 |
(defun cscope-history-forward-line-current-result ()
|
|
1954 |
"Like (cscope-history-forward-line), but limited to the current
|
|
1955 |
result only. This exists for blind navigation. If the user isn't
|
|
1956 |
looking at the *cscope* buffer, they shouldn't be jumping between
|
|
1957 |
results"
|
|
1958 |
(interactive)
|
|
1959 |
(cscope-history-forward-line t))
|
|
1960 |
|
|
1961 |
(defun cscope-history-backward-line ( &optional limit-to-current-result )
|
|
1962 |
"Navigate to the previous result line in the *cscope* buffer."
|
|
1963 |
(interactive)
|
|
1964 |
|
|
1965 |
(cscope-navigate-and-show
|
|
1966 |
'(let ((target
|
|
1967 |
(let ((at (save-excursion
|
|
1968 |
(beginning-of-line)
|
|
1969 |
(previous-single-property-change (point) 'cscope-line-number))))
|
|
1970 |
(and at (previous-single-property-change at 'cscope-line-number)))))
|
|
1971 |
(when target (goto-char target)))))
|
|
1972 |
|
|
1973 |
(defun cscope-history-backward-line-current-result ()
|
|
1974 |
"Like (cscope-history-backward-line), but limited to the current
|
|
1975 |
result only. This exists for blind navigation. If the user isn't
|
|
1976 |
looking at the *cscope* buffer, they shouldn't be jumping between
|
|
1977 |
results"
|
|
1978 |
(interactive)
|
|
1979 |
(cscope-history-backward-line t))
|
|
1980 |
|
|
1981 |
(defun cscope-history-kill-line ()
|
|
1982 |
"Delete a cscope line from the *cscope* buffer."
|
|
1983 |
(interactive)
|
|
1984 |
(save-excursion
|
|
1985 |
(beginning-of-line)
|
|
1986 |
(if (get-text-property (point) 'cscope-line-number)
|
|
1987 |
(progn
|
|
1988 |
(delete-region (point) (progn (forward-line 1) (point)))
|
|
1989 |
(cscope-history-kill-if-empty 'file))
|
|
1990 |
(error "Nothing to kill"))))
|
|
1991 |
|
|
1992 |
(defun cscope-history-kill-if-empty (which)
|
|
1993 |
"Kills object specified by WHICH, if it is empty. WHICH is
|
|
1994 |
either 'result or 'file"
|
|
1995 |
(let ((bounds (cscope-get-history-bounds-this-result which)))
|
|
1996 |
(unless
|
|
1997 |
;; not-empty condition computed here; different depending on WHICH
|
|
1998 |
(cond
|
|
1999 |
((eq which 'file)
|
|
2000 |
(let ((nextpropchange (next-single-property-change (car bounds) 'cscope-line-number nil (cadr bounds))))
|
|
2001 |
(and nextpropchange
|
|
2002 |
(/= nextpropchange (cadr bounds)))))
|
|
2003 |
((eq which 'result)
|
|
2004 |
|
|
2005 |
(save-excursion
|
|
2006 |
(goto-char (car bounds))
|
|
2007 |
(re-search-forward (concat "^" cscope-file-separator-start-regex) (cadr bounds) t nil)))
|
|
2008 |
(t (error "cscope-history-kill-if-empty given unknown argument")))
|
|
2009 |
|
|
2010 |
(apply 'delete-region bounds)
|
|
2011 |
(when (eq which 'file)
|
|
2012 |
(cscope-history-kill-if-empty 'result)))))
|
|
2013 |
|
|
2014 |
(defun cscope-pop-mark ()
|
|
2015 |
"Pop back to where cscope was last invoked."
|
|
2016 |
(interactive)
|
|
2017 |
|
|
2018 |
;; This function is based on pop-tag-mark, which can be found in
|
|
2019 |
;; lisp/progmodes/etags.el.
|
|
2020 |
|
|
2021 |
(if (ring-empty-p cscope-marker-ring)
|
|
2022 |
(error "There are no marked buffers in the cscope-marker-ring yet"))
|
|
2023 |
(let* ( (marker (ring-remove cscope-marker-ring 0))
|
|
2024 |
(old-buffer (current-buffer))
|
|
2025 |
(marker-buffer (marker-buffer marker))
|
|
2026 |
marker-window
|
|
2027 |
(marker-point (marker-position marker))
|
|
2028 |
(cscope-buffer (get-buffer cscope-output-buffer-name)) )
|
|
2029 |
|
|
2030 |
;; After the following both cscope-marker-ring and cscope-marker will be
|
|
2031 |
;; in the state they were immediately after the last search. This way if
|
|
2032 |
;; the user now makes a selection in the previously generated *cscope*
|
|
2033 |
;; buffer things will behave the same way as if that selection had been
|
|
2034 |
;; made immediately after the last search.
|
|
2035 |
(setq cscope-marker marker)
|
|
2036 |
|
|
2037 |
(if marker-buffer
|
|
2038 |
(if (eq old-buffer cscope-buffer)
|
|
2039 |
(progn ;; In the *cscope* buffer.
|
|
2040 |
(set-buffer marker-buffer)
|
|
2041 |
(setq marker-window (cscope-display-buffer-wrapper marker-buffer))
|
|
2042 |
(set-window-point marker-window marker-point)
|
|
2043 |
(select-window marker-window))
|
|
2044 |
(switch-to-buffer marker-buffer))
|
|
2045 |
(error "The marked buffer has been deleted"))
|
|
2046 |
(goto-char marker-point)
|
|
2047 |
(set-buffer old-buffer)))
|
|
2048 |
|
|
2049 |
(defun cscope-rerun-search-at-point ()
|
|
2050 |
"Re-runs the search at the point of the *cscope* buffer. Result
|
|
2051 |
modified in-place"
|
|
2052 |
(interactive)
|
|
2053 |
|
|
2054 |
(unless (eq (get-buffer cscope-output-buffer-name) (current-buffer))
|
|
2055 |
(error "(cscope-rerun-search-at-point) only makes sense from a *cscope* buffer"))
|
|
2056 |
|
|
2057 |
(when cscope-process
|
|
2058 |
(error "A cscope search is still in progress -- only one at a time is allowed"))
|
|
2059 |
|
|
2060 |
;; move to where we were after the search is done??
|
|
2061 |
(let ((beg-end (cscope-get-history-bounds-this-result 'result)))
|
|
2062 |
(unless beg-end (error "No result at point"))
|
|
2063 |
|
|
2064 |
(let* ((beg (elt beg-end 0))
|
|
2065 |
(end (elt beg-end 1))
|
|
2066 |
(search (get-text-property beg 'cscope-stored-search))
|
|
2067 |
|
|
2068 |
;; try to rerun the search in the same directory as before
|
|
2069 |
(cscope-initial-directory
|
|
2070 |
(or cscope-initial-directory
|
|
2071 |
(cscope-get-directory beg-end)))
|
|
2072 |
cscope-rerunning-search ;; this is bound here to tell cscope-call to not move the point
|
|
2073 |
)
|
|
2074 |
(delete-region beg end)
|
|
2075 |
(goto-char beg)
|
|
2076 |
(eval search))))
|
|
2077 |
|
|
2078 |
(defun cscope-set-initial-directory (cs-id)
|
|
2079 |
"Set the cscope-initial-directory variable. The
|
|
2080 |
cscope-initial-directory variable, when set, specifies the directory
|
|
2081 |
where searches for the cscope database directory should begin. This
|
|
2082 |
overrides the current directory, which would otherwise be used."
|
|
2083 |
(interactive "DCscope Initial Directory: ")
|
|
2084 |
(setq cscope-initial-directory cs-id))
|
|
2085 |
|
|
2086 |
|
|
2087 |
(defun cscope-unset-initial-directory ()
|
|
2088 |
"Unset the cscope-initial-directory variable."
|
|
2089 |
(interactive)
|
|
2090 |
(setq cscope-initial-directory nil)
|
|
2091 |
(message "The cscope-initial-directory variable is now unset."))
|
|
2092 |
|
|
2093 |
|
|
2094 |
(defun cscope-help ()
|
|
2095 |
(interactive)
|
|
2096 |
(message
|
|
2097 |
(format "RET=%s, SPC=%s, o=%s, n=%s, p=%s, q=%s, h=%s"
|
|
2098 |
"Select"
|
|
2099 |
"Show"
|
|
2100 |
"SelectOneWin"
|
|
2101 |
"ShowNext"
|
|
2102 |
"ShowPrev"
|
|
2103 |
"Quit"
|
|
2104 |
"Help")))
|
|
2105 |
|
|
2106 |
(defun cscope-cleanup-overlay-arrow ()
|
|
2107 |
(when overlay-arrow-position
|
|
2108 |
(set-marker overlay-arrow-position nil)
|
|
2109 |
(setq overlay-arrow-position nil
|
|
2110 |
overlay-arrow-string nil)))
|
|
2111 |
|
|
2112 |
(defun cscope-bury-buffer ()
|
|
2113 |
"Clean up cscope, if necessary, and bury the buffer."
|
|
2114 |
(interactive)
|
|
2115 |
(cscope-cleanup-overlay-arrow)
|
|
2116 |
(bury-buffer))
|
|
2117 |
|
|
2118 |
|
|
2119 |
|
|
2120 |
(defun cscope-quit ()
|
|
2121 |
(interactive)
|
|
2122 |
(cscope-bury-buffer)
|
|
2123 |
(kill-buffer cscope-output-buffer-name)
|
|
2124 |
)
|
|
2125 |
|
|
2126 |
|
|
2127 |
(defun cscope-boldify-if-needed (&rest args)
|
|
2128 |
"Returns a string in a bold face that's a concatenation of ARGS.
|
|
2129 |
This is done if 'cscope-use-face' is non-nil. Otherwise a plain
|
|
2130 |
concatenation of ARGS is returned"
|
|
2131 |
(let ((str (apply 'concat args)))
|
|
2132 |
(if cscope-use-face
|
|
2133 |
(propertize str 'face 'bold)
|
|
2134 |
str)))
|
|
2135 |
|
|
2136 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
2137 |
|
|
2138 |
(defun cscope-canonicalize-directory (dir)
|
|
2139 |
(or dir
|
|
2140 |
(setq dir default-directory))
|
|
2141 |
(setq dir (file-name-as-directory
|
|
2142 |
(expand-file-name (substitute-in-file-name dir))))
|
|
2143 |
dir
|
|
2144 |
)
|
|
2145 |
|
|
2146 |
(defun cscope-construct-custom-options-list ()
|
|
2147 |
"Returns a list of cscope options defined by the
|
|
2148 |
cscope-option-* variables"
|
|
2149 |
(append
|
|
2150 |
(mapcar (lambda (dir) (concat "-I" dir)) cscope-option-include-directories)
|
|
2151 |
(when cscope-option-disable-compression '("-c"))
|
|
2152 |
(when cscope-option-kernel-mode '("-k"))
|
|
2153 |
(when cscope-option-use-inverted-index '("-q"))
|
|
2154 |
cscope-option-other))
|
|
2155 |
|
|
2156 |
(defun cscope-search-directory-hierarchy (directory)
|
|
2157 |
"Look for a cscope database in the directory hierarchy.
|
|
2158 |
Starting from DIRECTORY, look upwards for a cscope database."
|
|
2159 |
(let (this-directory database-dir)
|
|
2160 |
(catch 'done
|
|
2161 |
(if (file-regular-p directory)
|
|
2162 |
(throw 'done directory))
|
|
2163 |
(setq directory (cscope-canonicalize-directory directory)
|
|
2164 |
this-directory directory)
|
|
2165 |
(while this-directory
|
|
2166 |
(if (or (file-exists-p (concat this-directory cscope-database-file))
|
|
2167 |
(file-exists-p (concat this-directory cscope-index-file)))
|
|
2168 |
(progn
|
|
2169 |
(setq database-dir this-directory)
|
|
2170 |
(throw 'done database-dir)
|
|
2171 |
))
|
|
2172 |
|
|
2173 |
(let ((parent-directory (file-name-as-directory
|
|
2174 |
(file-name-directory
|
|
2175 |
(directory-file-name this-directory)))))
|
|
2176 |
(if (string= this-directory parent-directory)
|
|
2177 |
(throw 'done directory)
|
|
2178 |
(setq this-directory parent-directory)))))))
|
|
2179 |
|
|
2180 |
|
|
2181 |
(defun cscope-find-info (top-directory)
|
|
2182 |
"Locate a suitable cscope database directory.
|
|
2183 |
First, `cscope-database-regexps' is used to search for a suitable
|
|
2184 |
database directory. If a database location cannot be found using this
|
|
2185 |
variable, then the current directory is searched, then the parent,
|
|
2186 |
then the parent's parent, until a cscope database directory is found,
|
|
2187 |
or the root directory is reached. If the root directory is reached,
|
|
2188 |
the current directory will be used."
|
|
2189 |
(let (info regexps dir-regexp this-directory)
|
|
2190 |
(setq top-directory (cscope-canonicalize-directory
|
|
2191 |
(or top-directory cscope-initial-directory)))
|
|
2192 |
(catch 'done
|
|
2193 |
;; Try searching using `cscope-database-regexps' ...
|
|
2194 |
(setq regexps cscope-database-regexps)
|
|
2195 |
(while regexps
|
|
2196 |
(setq dir-regexp (car (car regexps)))
|
|
2197 |
(cond
|
|
2198 |
( (stringp dir-regexp)
|
|
2199 |
(if (string-match dir-regexp top-directory)
|
|
2200 |
(progn
|
|
2201 |
(setq info (cdr (car regexps)))
|
|
2202 |
(throw 'done t)
|
|
2203 |
)) )
|
|
2204 |
( (and (symbolp dir-regexp) dir-regexp)
|
|
2205 |
(progn
|
|
2206 |
(setq info (cdr (car regexps)))
|
|
2207 |
(throw 'done t)
|
|
2208 |
) ))
|
|
2209 |
(setq regexps (cdr regexps))
|
|
2210 |
)
|
|
2211 |
|
|
2212 |
;; Try looking in the directory hierarchy ...
|
|
2213 |
(if (setq this-directory
|
|
2214 |
(cscope-search-directory-hierarchy top-directory))
|
|
2215 |
(progn
|
|
2216 |
(setq info (list (list this-directory)))
|
|
2217 |
(throw 'done t)
|
|
2218 |
))
|
|
2219 |
|
|
2220 |
;; Should we add any more places to look?
|
|
2221 |
|
|
2222 |
) ;; end catch
|
|
2223 |
(if (not info)
|
|
2224 |
(setq info (list (list top-directory))))
|
|
2225 |
info
|
|
2226 |
))
|
|
2227 |
|
|
2228 |
|
|
2229 |
(defun cscope-make-entry-line (func-name line-number line)
|
|
2230 |
"Makes a propertized line containing a single cscope result.
|
|
2231 |
This function sets up face and the fuzzy-search string"
|
|
2232 |
|
|
2233 |
;; The format of entry line:
|
|
2234 |
;; func-name[line-number]______line
|
|
2235 |
;; <- cscope-name-line-width ->
|
|
2236 |
;; `format' of Emacs doesn't have "*s" spec.
|
|
2237 |
(let ((str (format (format "%%%ds %%s" cscope-name-line-width)
|
|
2238 |
(format "%s[%s]" func-name line-number) line))
|
|
2239 |
(search-type (car cscope-previous-user-search))
|
|
2240 |
(search-symbol (cadr cscope-previous-user-search))
|
|
2241 |
beg end)
|
|
2242 |
|
|
2243 |
;; I set up the 'cscope-fuzzy-search-text-regexp property to allow fuzzy
|
|
2244 |
;; searches to work. cscope collapses spaces for some reason, so I explictly
|
|
2245 |
;; look for an arbitrary amounts of whitespace
|
|
2246 |
(unless (string= line "<unknown>")
|
|
2247 |
(let ((fuzzy-search-text-regexp
|
|
2248 |
(mapconcat 'regexp-quote
|
|
2249 |
(split-string line "[ \f\t\n\r\v]+\\|\\b" t) "\\s-*")))
|
|
2250 |
|
|
2251 |
(put-text-property 0 (length str) 'cscope-fuzzy-search-text-regexp fuzzy-search-text-regexp str)))
|
|
2252 |
|
|
2253 |
;; now I set up the face properties
|
|
2254 |
(when cscope-use-face
|
|
2255 |
(setq end (length func-name))
|
|
2256 |
(put-text-property 0 end 'face 'cscope-function-face str)
|
|
2257 |
(setq beg (1+ end)
|
|
2258 |
end (+ beg (length line-number)))
|
|
2259 |
(put-text-property beg end 'face 'cscope-line-number-face str)
|
|
2260 |
|
|
2261 |
(when (not (string= line "<unknown>"))
|
|
2262 |
(let* ((search-type (car cscope-previous-user-search))
|
|
2263 |
(search-symbol (cadr cscope-previous-user-search))
|
|
2264 |
|
|
2265 |
;; nothing to highlight for search types where the sought symbol isn't
|
|
2266 |
;; expected to appear at a matched result line.
|
|
2267 |
;;
|
|
2268 |
;; test-strings aren't regexes, so quote those. Everything else
|
|
2269 |
;; is a regex, so pass that right on through
|
|
2270 |
(highlight-search-re
|
|
2271 |
(if (or (eq search-type 'cscope-find-this-file)
|
|
2272 |
(eq search-type 'cscope-find-called-functions))
|
|
2273 |
nil
|
|
2274 |
(if (eq search-type 'cscope-find-this-text-string)
|
|
2275 |
(regexp-quote search-symbol)
|
|
2276 |
search-symbol))))
|
|
2277 |
|
|
2278 |
(when highlight-search-re
|
|
2279 |
|
|
2280 |
;; unless we're searching for arbitrary text strings, the tokens we
|
|
2281 |
;; seek are full words. Furthermore, any '.' wildcard in those has
|
|
2282 |
;; to match a C symbol
|
|
2283 |
(unless (or (eq search-type 'cscope-find-egrep-pattern)
|
|
2284 |
(eq search-type 'cscope-find-this-text-string))
|
|
2285 |
|
|
2286 |
(setq highlight-search-re
|
|
2287 |
(replace-regexp-in-string "\\([^\\\\]\\)\\." "\\1[a-zA-Z0-9_]"
|
|
2288 |
(concat "\\b" highlight-search-re "\\b"))))
|
|
2289 |
(let* ((case-fold-search nil)
|
|
2290 |
(start (string-match
|
|
2291 |
highlight-search-re
|
|
2292 |
str (1+ end))))
|
|
2293 |
(when start
|
|
2294 |
(put-text-property start (match-end 0) 'face 'bold str)))))))
|
|
2295 |
|
|
2296 |
str))
|
|
2297 |
|
|
2298 |
|
|
2299 |
(defun cscope-process-filter (process output)
|
|
2300 |
"Accept cscope process output and reformat it for human readability.
|
|
2301 |
Magic text properties are added to allow the user to select lines
|
|
2302 |
using the mouse."
|
|
2303 |
(let ( (old-buffer (current-buffer)) )
|
|
2304 |
(with-current-buffer (process-buffer process)
|
|
2305 |
(let (line file function-name line-number)
|
|
2306 |
(save-excursion
|
|
2307 |
(goto-char cscope-last-output-point)
|
|
2308 |
;; Get the output thus far ...
|
|
2309 |
(if cscope-process-output
|
|
2310 |
(setq cscope-process-output (concat cscope-process-output
|
|
2311 |
output))
|
|
2312 |
(setq cscope-process-output output))
|
|
2313 |
;; Slice and dice it into lines.
|
|
2314 |
;; While there are whole lines left ...
|
|
2315 |
(while (and cscope-process-output
|
|
2316 |
(string-match "\\([^\n]+\n\\)\\(\\(.\\|\n\\)*\\)"
|
|
2317 |
cscope-process-output))
|
|
2318 |
(setq file nil
|
|
2319 |
glimpse-stripped-directory nil
|
|
2320 |
)
|
|
2321 |
;; Get a line
|
|
2322 |
(setq line (substring cscope-process-output
|
|
2323 |
(match-beginning 1) (match-end 1)))
|
|
2324 |
(setq cscope-process-output (substring cscope-process-output
|
|
2325 |
(match-beginning 2)
|
|
2326 |
(match-end 2)))
|
|
2327 |
(if (= (length cscope-process-output) 0)
|
|
2328 |
(setq cscope-process-output nil))
|
|
2329 |
|
|
2330 |
;; This should always match.
|
|
2331 |
(if (string-match
|
|
2332 |
"^\\([^ \t]+\\)[ \t]+\\([^ \t]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\(.*\\)\n"
|
|
2333 |
line)
|
|
2334 |
(progn
|
|
2335 |
(let (str)
|
|
2336 |
(setq file (substring line (match-beginning 1)
|
|
2337 |
(match-end 1))
|
|
2338 |
function-name (substring line (match-beginning 2)
|
|
2339 |
(match-end 2))
|
|
2340 |
line-number (substring line (match-beginning 3)
|
|
2341 |
(match-end 3))
|
|
2342 |
line (substring line (match-beginning 4)
|
|
2343 |
(match-end 4))
|
|
2344 |
)
|
|
2345 |
;; If the current file is not the same as the previous
|
|
2346 |
;; one ...
|
|
2347 |
(if (not (and cscope-last-file
|
|
2348 |
(string= file cscope-last-file)))
|
|
2349 |
(progn
|
|
2350 |
;; The current file is different.
|
|
2351 |
|
|
2352 |
;; Insert a separating blank line if
|
|
2353 |
;; necessary.
|
|
2354 |
(if cscope-last-file (insert "\n"))
|
|
2355 |
;; Insert the file name
|
|
2356 |
(setq str (concat "*** " file ":"))
|
|
2357 |
(if cscope-use-face
|
|
2358 |
(put-text-property 0 (length str)
|
|
2359 |
'face 'cscope-file-face
|
|
2360 |
str))
|
|
2361 |
(cscope-insert-with-text-properties
|
|
2362 |
str
|
|
2363 |
(expand-file-name file))
|
|
2364 |
(insert "\n")))
|
|
2365 |
|
|
2366 |
(if cscope-first-match-point
|
|
2367 |
(setq cscope-matched-multiple t)
|
|
2368 |
(setq cscope-first-match-point (point)))
|
|
2369 |
|
|
2370 |
;; ... and insert the line, with the
|
|
2371 |
;; appropriate indentation.
|
|
2372 |
(cscope-insert-with-text-properties
|
|
2373 |
(cscope-make-entry-line function-name
|
|
2374 |
line-number
|
|
2375 |
line)
|
|
2376 |
(expand-file-name file)
|
|
2377 |
line-number
|
|
2378 |
line)
|
|
2379 |
(insert "\n")
|
|
2380 |
(setq cscope-last-file file)
|
|
2381 |
))
|
|
2382 |
(insert line "\n")
|
|
2383 |
))
|
|
2384 |
(setq cscope-last-output-point (point)))
|
|
2385 |
(set-buffer-modified-p nil)))))
|
|
2386 |
|
|
2387 |
|
|
2388 |
(defun cscope-process-sentinel (process event)
|
|
2389 |
"Sentinel for when the cscope process dies."
|
|
2390 |
(let* ((buffer (process-buffer process)) window update-window
|
|
2391 |
(done t)
|
|
2392 |
(old-buffer (current-buffer))
|
|
2393 |
(old-buffer-window (get-buffer-window old-buffer)) )
|
|
2394 |
|
|
2395 |
(with-current-buffer buffer
|
|
2396 |
(let (continue
|
|
2397 |
(directory-this-search default-directory))
|
|
2398 |
(save-excursion
|
|
2399 |
(goto-char cscope-last-output-point)
|
|
2400 |
|
|
2401 |
(if (or (and (setq window (get-buffer-window buffer))
|
|
2402 |
(= (window-point window) (point-max)))
|
|
2403 |
(= (point) (point-max)))
|
|
2404 |
(setq update-window t))
|
|
2405 |
(delete-process process)
|
|
2406 |
|
|
2407 |
(when (= cscope-output-start (point))
|
|
2408 |
(insert " --- No matches were found ---\n"))
|
|
2409 |
|
|
2410 |
(when (not cscope-start-directory)
|
|
2411 |
(setq cscope-start-directory default-directory))
|
|
2412 |
|
|
2413 |
(setq continue
|
|
2414 |
(and cscope-search-list
|
|
2415 |
(not (and cscope-first-match-point
|
|
2416 |
cscope-stop-at-first-match-dir
|
|
2417 |
(not cscope-stop-at-first-match-dir-meta)))))
|
|
2418 |
(when continue
|
|
2419 |
(setq continue (cscope-search-one-database)))
|
|
2420 |
(if continue
|
|
2421 |
(setq done nil)
|
|
2422 |
(insert "\nSearch complete.")
|
|
2423 |
(if cscope-display-times
|
|
2424 |
(let ( (times (current-time)) cscope-stop elapsed-time )
|
|
2425 |
(setq cscope-stop (+ (* (car times) 65536.0)
|
|
2426 |
(cadr times)
|
|
2427 |
(* (cadr (cdr times)) 1.0E-6)))
|
|
2428 |
(setq elapsed-time (- cscope-stop cscope-start-time))
|
|
2429 |
(insert (format " Search time = %.2f seconds."
|
|
2430 |
elapsed-time))
|
|
2431 |
))
|
|
2432 |
(insert "\n")
|
|
2433 |
(setq cscope-process nil)
|
|
2434 |
(if cscope-running-in-xemacs
|
|
2435 |
(setq modeline-process ": Search complete"))
|
|
2436 |
(when cscope-start-directory
|
|
2437 |
(setq default-directory cscope-start-directory)))
|
|
2438 |
|
|
2439 |
|
|
2440 |
|
|
2441 |
|
|
2442 |
|
|
2443 |
(set-buffer-modified-p nil))
|
|
2444 |
|
|
2445 |
(if (and done cscope-first-match-point update-window)
|
|
2446 |
(if window
|
|
2447 |
(set-window-point window cscope-first-match-point)
|
|
2448 |
(goto-char cscope-first-match-point))
|
|
2449 |
)
|
|
2450 |
|
|
2451 |
(when cscope-first-match-point
|
|
2452 |
(if cscope-display-cscope-buffer
|
|
2453 |
(if (and cscope-edit-single-match (not cscope-matched-multiple))
|
|
2454 |
(cscope-show-entry-internal
|
|
2455 |
(cscope-get-navigation-properties cscope-first-match-point (process-buffer process))
|
|
2456 |
t))
|
|
2457 |
(cscope-select-entry-specified-window old-buffer-window)))
|
|
2458 |
|
|
2459 |
;; if the *cscope* buffer is too long, truncate it
|
|
2460 |
(with-current-buffer (process-buffer process)
|
|
2461 |
(when (and done
|
|
2462 |
(> cscope-max-cscope-buffer-size 0)
|
|
2463 |
(> (- (point-max) (point-min)) cscope-max-cscope-buffer-size))
|
|
2464 |
|
|
2465 |
(save-excursion
|
|
2466 |
(goto-char (point-max))
|
|
2467 |
(let ((cut-at-point (cscope-find-this-separator-start
|
|
2468 |
cscope-result-separator
|
|
2469 |
(- (point-max) cscope-max-cscope-buffer-size)
|
|
2470 |
t)))
|
|
2471 |
(when cut-at-point
|
|
2472 |
(delete-region (point-min) cut-at-point))))))
|
|
2473 |
|
|
2474 |
(if (and done (eq old-buffer buffer) cscope-first-match-point)
|
|
2475 |
(cscope-help))))))
|
|
2476 |
|
|
2477 |
|
|
2478 |
|
|
2479 |
(defun cscope-search-one-database ()
|
|
2480 |
"Pop a database entry from `cscope-search-list' and do a search there."
|
|
2481 |
|
|
2482 |
(let ( next-item options cscope-directory database-file outbuf done
|
|
2483 |
base-database-file-name)
|
|
2484 |
(setq outbuf (get-buffer-create cscope-output-buffer-name))
|
|
2485 |
(save-excursion
|
|
2486 |
(catch 'finished
|
|
2487 |
(set-buffer outbuf)
|
|
2488 |
(setq options '("-L"))
|
|
2489 |
(while (and (not done) cscope-search-list)
|
|
2490 |
(setq next-item (car cscope-search-list)
|
|
2491 |
cscope-search-list (cdr cscope-search-list)
|
|
2492 |
base-database-file-name cscope-database-file
|
|
2493 |
)
|
|
2494 |
(if (listp next-item)
|
|
2495 |
(progn
|
|
2496 |
(setq cscope-directory (car next-item))
|
|
2497 |
(if (not (stringp cscope-directory))
|
|
2498 |
(setq cscope-directory
|
|
2499 |
(cscope-search-directory-hierarchy
|
|
2500 |
default-directory)))
|
|
2501 |
(if (file-regular-p cscope-directory)
|
|
2502 |
(progn
|
|
2503 |
;; Handle the case where `cscope-directory' is really
|
|
2504 |
;; a full path name to a cscope database.
|
|
2505 |
(setq base-database-file-name
|
|
2506 |
(file-name-nondirectory cscope-directory)
|
|
2507 |
cscope-directory
|
|
2508 |
(file-name-directory cscope-directory))
|
|
2509 |
))
|
|
2510 |
(setq cscope-directory
|
|
2511 |
(file-name-as-directory cscope-directory))
|
|
2512 |
(when (not (member cscope-directory cscope-searched-dirs))
|
|
2513 |
(push cscope-directory cscope-searched-dirs)
|
|
2514 |
(setq done t))
|
|
2515 |
)
|
|
2516 |
(progn
|
|
2517 |
(if (and cscope-first-match-point
|
|
2518 |
cscope-stop-at-first-match-dir
|
|
2519 |
cscope-stop-at-first-match-dir-meta)
|
|
2520 |
(throw 'finished nil))
|
|
2521 |
))
|
|
2522 |
)
|
|
2523 |
(if (not done)
|
|
2524 |
(throw 'finished nil))
|
|
2525 |
|
|
2526 |
(when (cadr next-item)
|
|
2527 |
(let ((newopts (cadr next-item)))
|
|
2528 |
(unless (listp newopts)
|
|
2529 |
(error (format "Cscope options must be a list: %s" newopts)))
|
|
2530 |
(setq options (append options newopts))))
|
|
2531 |
(if cscope-command-args
|
|
2532 |
(setq options (append options cscope-command-args))
|
|
2533 |
(error "Tried to do a search without 'cscope-command-args' set. Something is wrong..."))
|
|
2534 |
|
|
2535 |
|
|
2536 |
(setq database-file (concat cscope-directory base-database-file-name)
|
|
2537 |
cscope-searched-dirs (cons cscope-directory
|
|
2538 |
cscope-searched-dirs)
|
|
2539 |
)
|
|
2540 |
|
|
2541 |
;; The database file and the directory containing the database file
|
|
2542 |
;; must both be writable.
|
|
2543 |
(if (or (not (file-writable-p database-file))
|
|
2544 |
(not (file-writable-p (file-name-directory database-file)))
|
|
2545 |
cscope-option-do-not-update-database)
|
|
2546 |
(setq options (cons "-d" options)))
|
|
2547 |
|
|
2548 |
|
|
2549 |
;; is this require for multiple databases?
|
|
2550 |
;; (goto-char (point-max))
|
|
2551 |
(if (string= base-database-file-name cscope-database-file)
|
|
2552 |
(insert (concat "\n" cscope-database-directory-prompt ": ")
|
|
2553 |
(cscope-boldify-if-needed cscope-directory)
|
|
2554 |
"\n\n")
|
|
2555 |
(insert (concat "\n" cscope-database-directory-prompt "/file: ")
|
|
2556 |
(cscope-boldify-if-needed cscope-directory base-database-file-name)
|
|
2557 |
"\n\n"))
|
|
2558 |
;; Add the correct database file to search
|
|
2559 |
(setq options (cons base-database-file-name options))
|
|
2560 |
(setq options (cons "-f" options))
|
|
2561 |
(setq cscope-output-start (point))
|
|
2562 |
(setq default-directory cscope-directory)
|
|
2563 |
|
|
2564 |
(setq cscope-process-output nil
|
|
2565 |
cscope-last-file nil
|
|
2566 |
)
|
|
2567 |
(setq cscope-process
|
|
2568 |
;; Communicate with a pipe. Slightly more efficient than
|
|
2569 |
;; a TTY
|
|
2570 |
(let ((process-connection-type nil))
|
|
2571 |
(apply cscope-start-file-process "cscope" outbuf
|
|
2572 |
(cscope--get-cscope-program)
|
|
2573 |
(append (cscope-construct-custom-options-list) options))))
|
|
2574 |
(set-process-filter cscope-process 'cscope-process-filter)
|
|
2575 |
(set-process-sentinel cscope-process 'cscope-process-sentinel)
|
|
2576 |
(setq cscope-last-output-point (point))
|
|
2577 |
(process-kill-without-query cscope-process)
|
|
2578 |
(if cscope-running-in-xemacs
|
|
2579 |
(setq modeline-process ": Searching ..."))
|
|
2580 |
t
|
|
2581 |
))
|
|
2582 |
))
|
|
2583 |
|
|
2584 |
(defun cscope-call (basemsg search-id symbol)
|
|
2585 |
"Generic function to call to process cscope requests.
|
|
2586 |
BASEMSG is a message describing this search; SEARCH-ID is a
|
|
2587 |
numeric id indicating to the cscope backend what kind of search
|
|
2588 |
this is."
|
|
2589 |
(let* ( (outbuf (get-buffer-create cscope-output-buffer-name))
|
|
2590 |
(old-buffer (current-buffer))
|
|
2591 |
(directory
|
|
2592 |
(cscope-canonicalize-directory
|
|
2593 |
|
|
2594 |
;; if we have an initial directory, use it. Otherwise if we're in
|
|
2595 |
;; *cscope*, try to use the directory of the search at point
|
|
2596 |
(or cscope-initial-directory
|
|
2597 |
(and (eq outbuf old-buffer)
|
|
2598 |
(cscope-get-directory)))))
|
|
2599 |
(msg (concat basemsg " "
|
|
2600 |
(cscope-boldify-if-needed symbol)))
|
|
2601 |
(args (list (format "-%d" search-id) symbol)))
|
|
2602 |
(if cscope-process
|
|
2603 |
(error "A cscope search is still in progress -- only one at a time is allowed"))
|
|
2604 |
(if (eq outbuf old-buffer) ;; In the *cscope* buffer.
|
|
2605 |
(let ((marker-buf (window-buffer cscope-marker-window)))
|
|
2606 |
(when marker-buf
|
|
2607 |
;; Assume that cscope-marker-window is the window, from the
|
|
2608 |
;; users perspective, from which the search was launched and the
|
|
2609 |
;; window that should be returned to upon cscope-pop-mark.
|
|
2610 |
(with-current-buffer marker-buf
|
|
2611 |
(setq cscope-marker (point-marker)))))
|
|
2612 |
|
|
2613 |
;; Not in the *cscope buffer.
|
|
2614 |
;; Set the cscope-marker-window to whichever window this search
|
|
2615 |
;; was launched from.
|
|
2616 |
(setq cscope-marker-window (get-buffer-window old-buffer))
|
|
2617 |
(setq cscope-marker (point-marker)))
|
|
2618 |
(with-current-buffer outbuf
|
|
2619 |
(if cscope-display-times
|
|
2620 |
(let ( (times (current-time)) )
|
|
2621 |
(setq cscope-start-time (+ (* (car times) 65536.0) (cadr times)
|
|
2622 |
(* (cadr (cdr times)) 1.0E-6)))))
|
|
2623 |
(setq default-directory directory
|
|
2624 |
cscope-start-directory nil
|
|
2625 |
cscope-search-list (cscope-find-info directory)
|
|
2626 |
cscope-searched-dirs nil
|
|
2627 |
cscope-command-args args
|
|
2628 |
cscope-first-match-point nil
|
|
2629 |
cscope-stop-at-first-match-dir-meta (memq t cscope-search-list)
|
|
2630 |
cscope-matched-multiple nil)
|
|
2631 |
(setq truncate-lines cscope-truncate-lines)
|
|
2632 |
|
|
2633 |
;; insert the separator at the start of the result set
|
|
2634 |
(unless (boundp 'cscope-rerunning-search) (goto-char (point-max)))
|
|
2635 |
(when (not (bolp))
|
|
2636 |
(insert "\n"))
|
|
2637 |
|
|
2638 |
;; don't apply the face to the trailing newline in the separator
|
|
2639 |
(let ((separator-start (point)))
|
|
2640 |
(insert cscope-result-separator)
|
|
2641 |
(when cscope-use-face
|
|
2642 |
(put-text-property separator-start (1- (point)) 'face 'cscope-separator-face)
|
|
2643 |
(put-text-property separator-start (1- (point)) 'cscope-stored-search cscope-previous-user-search)))
|
|
2644 |
|
|
2645 |
(insert msg)
|
|
2646 |
(cscope-search-one-database))
|
|
2647 |
|
|
2648 |
(if cscope-display-cscope-buffer
|
|
2649 |
(progn
|
|
2650 |
(pop-to-buffer outbuf)
|
|
2651 |
(cscope-help))
|
|
2652 |
(set-buffer outbuf))
|
|
2653 |
(cscope-list-entry-mode)
|
|
2654 |
))
|
|
2655 |
|
|
2656 |
|
|
2657 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
2658 |
|
|
2659 |
(defvar cscope-unix-index-process nil
|
|
2660 |
"The current indexing process.")
|
|
2661 |
|
|
2662 |
(defvar cscope-indexing-status-string nil
|
|
2663 |
"The string returned by the indexer. This receives the indexer
|
|
2664 |
output as it comes over time")
|
|
2665 |
|
|
2666 |
(defun cscope-display-message-or-buffer (message buffer)
|
|
2667 |
"Calls `display-message-or-buffer' in GNU emacs. In xemacs this
|
|
2668 |
isn't available, so it simply displays the MESSAGE in the BUFFER"
|
|
2669 |
|
|
2670 |
(if (not cscope-running-in-xemacs) (display-message-or-buffer message buffer)
|
|
2671 |
(with-current-buffer (get-buffer-create buffer)
|
|
2672 |
(erase-buffer)
|
|
2673 |
(insert message)
|
|
2674 |
(goto-char (point-min))
|
|
2675 |
(cscope-display-buffer-wrapper (current-buffer)))))
|
|
2676 |
|
|
2677 |
|
|
2678 |
(defun cscope-unix-index-files-filter (process output)
|
|
2679 |
"Called when the indexing process says 'output'. I pop up a
|
|
2680 |
message in a buffer or the echo area"
|
|
2681 |
|
|
2682 |
;; add the new string
|
|
2683 |
(setq cscope-indexing-status-string
|
|
2684 |
(concat cscope-indexing-status-string output))
|
|
2685 |
|
|
2686 |
;; and display
|
|
2687 |
(cscope-display-message-or-buffer cscope-indexing-status-string "*cscope-indexing-buffer*"))
|
|
2688 |
|
|
2689 |
(defun cscope-unix-index-files-sentinel (process event)
|
|
2690 |
"Simple sentinel to print a message saying that indexing is finished."
|
|
2691 |
(setq cscope-indexing-status-string
|
|
2692 |
(concat cscope-indexing-status-string
|
|
2693 |
cscope-result-separator
|
|
2694 |
"\n"
|
|
2695 |
(if (equal event "finished\n")
|
|
2696 |
"Indexing finished\n"
|
|
2697 |
(concat "Indexing process received signal: " event "Stopping indexing"))))
|
|
2698 |
|
|
2699 |
(cscope-display-message-or-buffer cscope-indexing-status-string "*cscope-indexing-buffer*")
|
|
2700 |
(delete-process process)
|
|
2701 |
(setq cscope-unix-index-process nil)
|
|
2702 |
(setq cscope-indexing-status-string nil))
|
|
2703 |
|
|
2704 |
(defun cscope-make-index-command (dir only-create-list-of-files)
|
|
2705 |
"Return a string that is a shell script that runs the cscope
|
|
2706 |
indexer"
|
|
2707 |
|
|
2708 |
(let ((findargs
|
|
2709 |
|
|
2710 |
;; This is really ugly. GNU emacs has find-cmd.el to make things just like
|
|
2711 |
;; this less ugly, but I want to support xemacs too, and thus I just live with
|
|
2712 |
;; the uglyness
|
|
2713 |
(mapcar 'shell-quote-argument
|
|
2714 |
`(,dir
|
|
2715 |
|
|
2716 |
;; limit the search depth if we're not searching recursively
|
|
2717 |
,@(when (not cscope-index-recursively)
|
|
2718 |
'("-maxdepth" "1"))
|
|
2719 |
|
|
2720 |
;; apply -prune to any directory we're supposed to ignore
|
|
2721 |
"(" "-type" "d" "("
|
|
2722 |
,@(apply 'append (mapcar (lambda (dir) (list "-name" dir "-o") )
|
|
2723 |
cscope-indexer-ignored-directories))
|
|
2724 |
"-false"
|
|
2725 |
")" "-prune" ")" "-o"
|
|
2726 |
|
|
2727 |
;; accept only files that match the patterns we want
|
|
2728 |
"("
|
|
2729 |
,@(apply 'append (mapcar (lambda (suffix) (list "-iname" suffix "-o"))
|
|
2730 |
cscope-indexer-suffixes))
|
|
2731 |
"-false"
|
|
2732 |
")"
|
|
2733 |
|
|
2734 |
;; accept files and symlinks
|
|
2735 |
"(" "-type" "f" "-o" "-type" "l" ")"
|
|
2736 |
|
|
2737 |
;; if we made it here, take the result
|
|
2738 |
"-print"))))
|
|
2739 |
|
|
2740 |
(let ((findcmds
|
|
2741 |
(concat "echo 'Creating list of files to index ...'\n"
|
|
2742 |
|
|
2743 |
"find "
|
|
2744 |
(mapconcat 'identity findargs " ") " > "
|
|
2745 |
(shell-quote-argument cscope-index-file) "\n"
|
|
2746 |
|
|
2747 |
"echo 'Creating list of files to index ... done'\n"))
|
|
2748 |
|
|
2749 |
(indexcmds
|
|
2750 |
(concat "echo 'Indexing files ...'\n"
|
|
2751 |
|
|
2752 |
(shell-quote-argument (cscope--get-cscope-program))
|
|
2753 |
" "
|
|
2754 |
(mapconcat 'shell-quote-argument
|
|
2755 |
(cscope-construct-custom-options-list)
|
|
2756 |
" ")
|
|
2757 |
" -b -i "
|
|
2758 |
(shell-quote-argument cscope-index-file)
|
|
2759 |
" -f " (shell-quote-argument cscope-database-file) "\n"
|
|
2760 |
|
|
2761 |
"echo 'Indexing files ... done'\n")))
|
|
2762 |
|
|
2763 |
(if only-create-list-of-files
|
|
2764 |
findcmds
|
|
2765 |
(concat findcmds indexcmds)))))
|
|
2766 |
|
|
2767 |
(defun cscope-unix-index-files-internal (top-directory header-text only-create-list-of-files)
|
|
2768 |
"Core function to call the indexing script."
|
|
2769 |
(save-excursion
|
|
2770 |
(setq cscope-indexing-status-string
|
|
2771 |
(or header-text ""))
|
|
2772 |
(setq cscope-unix-index-process
|
|
2773 |
(let* ((default-directory (cscope-canonicalize-directory top-directory))
|
|
2774 |
(index-command
|
|
2775 |
(cscope-make-index-command (if cscope-use-relative-paths
|
|
2776 |
"." default-directory)
|
|
2777 |
only-create-list-of-files)))
|
|
2778 |
;; Communicate with a pipe. Slightly more efficient than
|
|
2779 |
;; a TTY
|
|
2780 |
(let ((process-connection-type nil))
|
|
2781 |
(funcall cscope-start-file-process "cscope-indexer"
|
|
2782 |
nil
|
|
2783 |
"sh" "-c" index-command))))
|
|
2784 |
(set-process-filter cscope-unix-index-process 'cscope-unix-index-files-filter)
|
|
2785 |
(set-process-sentinel cscope-unix-index-process
|
|
2786 |
'cscope-unix-index-files-sentinel)
|
|
2787 |
(process-kill-without-query cscope-unix-index-process)))
|
|
2788 |
|
|
2789 |
|
|
2790 |
(defun cscope-index-files (top-directory)
|
|
2791 |
"Index files in a directory.
|
|
2792 |
This function creates a list of files to index, and then indexes
|
|
2793 |
the listed files.
|
|
2794 |
The variable, \"cscope-index-recursively\", controls whether or not
|
|
2795 |
subdirectories are indexed."
|
|
2796 |
(interactive "DIndex files in directory: ")
|
|
2797 |
(let ()
|
|
2798 |
(cscope-unix-index-files-internal
|
|
2799 |
top-directory
|
|
2800 |
(format "Creating cscope index `%s' in:\n\t%s\n\n%s"
|
|
2801 |
cscope-database-file top-directory cscope-result-separator)
|
|
2802 |
nil)
|
|
2803 |
))
|
|
2804 |
|
|
2805 |
|
|
2806 |
(defun cscope-create-list-of-files-to-index (top-directory)
|
|
2807 |
"Create a list of files to index.
|
|
2808 |
The variable, \"cscope-index-recursively\", controls whether or not
|
|
2809 |
subdirectories are indexed."
|
|
2810 |
(interactive "DCreate file list in directory: ")
|
|
2811 |
(let ()
|
|
2812 |
(cscope-unix-index-files-internal
|
|
2813 |
top-directory
|
|
2814 |
(format "Creating cscope file list `%s' in:\n\t%s\n\n"
|
|
2815 |
cscope-index-file top-directory)
|
|
2816 |
t)
|
|
2817 |
))
|
|
2818 |
|
|
2819 |
|
|
2820 |
(defun cscope-edit-list-of-files-to-index ()
|
|
2821 |
"Search for and edit the list of files to index.
|
|
2822 |
If this functions causes a new file to be edited, that means that a
|
|
2823 |
cscope.out file was found without a corresponding cscope.files file."
|
|
2824 |
(interactive)
|
|
2825 |
(let (info directory file)
|
|
2826 |
(setq info (cscope-find-info nil))
|
|
2827 |
(if (/= (length info) 1)
|
|
2828 |
(error "There is no unique cscope database directory!"))
|
|
2829 |
(setq directory (car (car info)))
|
|
2830 |
(if (not (stringp directory))
|
|
2831 |
(setq directory
|
|
2832 |
(cscope-search-directory-hierarchy default-directory)))
|
|
2833 |
(setq file (concat (file-name-as-directory directory) cscope-index-file))
|
|
2834 |
(find-file file)
|
|
2835 |
(message (concat "File: " file))
|
|
2836 |
))
|
|
2837 |
|
|
2838 |
|
|
2839 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
2840 |
|
|
2841 |
(defun cscope-tell-user-about-directory ()
|
|
2842 |
"Display the name of the directory containing the cscope database."
|
|
2843 |
(interactive)
|
|
2844 |
(let (info directory)
|
|
2845 |
(setq info (cscope-find-info nil))
|
|
2846 |
(if (= (length info) 1)
|
|
2847 |
(progn
|
|
2848 |
(setq directory (car (car info)))
|
|
2849 |
(message (concat "Cscope directory: " directory))
|
|
2850 |
)
|
|
2851 |
(let ( (outbuf (get-buffer-create cscope-info-buffer-name)) )
|
|
2852 |
(cscope-display-buffer-wrapper outbuf)
|
|
2853 |
(with-current-buffer outbuf
|
|
2854 |
(buffer-disable-undo)
|
|
2855 |
(erase-buffer)
|
|
2856 |
(insert "Cscope search directories:\n")
|
|
2857 |
(while info
|
|
2858 |
(if (listp (car info))
|
|
2859 |
(progn
|
|
2860 |
(setq directory (car (car info)))
|
|
2861 |
(if (not (stringp directory))
|
|
2862 |
(setq directory
|
|
2863 |
(cscope-search-directory-hierarchy
|
|
2864 |
default-directory)))
|
|
2865 |
(insert "\t" directory "\n")
|
|
2866 |
))
|
|
2867 |
(setq info (cdr info))))))))
|
|
2868 |
|
|
2869 |
|
|
2870 |
(defun cscope-dired-directory ()
|
|
2871 |
"Run dired upon the cscope database directory.
|
|
2872 |
If possible, the cursor is moved to the name of the cscope database
|
|
2873 |
file."
|
|
2874 |
(interactive)
|
|
2875 |
(let (info directory buffer p1 p2 pos)
|
|
2876 |
(setq info (cscope-find-info nil))
|
|
2877 |
(if (/= (length info) 1)
|
|
2878 |
(error "There is no unique cscope database directory!"))
|
|
2879 |
(setq directory (car (car info)))
|
|
2880 |
(if (not (stringp directory))
|
|
2881 |
(setq directory
|
|
2882 |
(cscope-search-directory-hierarchy default-directory)))
|
|
2883 |
(setq buffer (dired-noselect directory nil))
|
|
2884 |
(switch-to-buffer buffer)
|
|
2885 |
(set-buffer buffer)
|
|
2886 |
(save-excursion
|
|
2887 |
(goto-char (point-min))
|
|
2888 |
(setq p1 (search-forward cscope-index-file nil t))
|
|
2889 |
(if p1
|
|
2890 |
(setq p1 (- p1 (length cscope-index-file))))
|
|
2891 |
)
|
|
2892 |
(save-excursion
|
|
2893 |
(goto-char (point-min))
|
|
2894 |
(setq p2 (search-forward cscope-database-file nil t))
|
|
2895 |
(if p2
|
|
2896 |
(setq p2 (- p2 (length cscope-database-file))))
|
|
2897 |
)
|
|
2898 |
(cond
|
|
2899 |
( (and p1 p2)
|
|
2900 |
(if (< p1 p2)
|
|
2901 |
(setq pos p1)
|
|
2902 |
(setq pos p2))
|
|
2903 |
)
|
|
2904 |
( p1
|
|
2905 |
(setq pos p1)
|
|
2906 |
)
|
|
2907 |
( p2
|
|
2908 |
(setq pos p2)
|
|
2909 |
)
|
|
2910 |
)
|
|
2911 |
(if pos
|
|
2912 |
(set-window-point (get-buffer-window buffer) pos))
|
|
2913 |
))
|
|
2914 |
|
|
2915 |
|
|
2916 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
2917 |
|
|
2918 |
(defun cscope-extract-symbol-at-cursor (extract-filename try-to-use-region)
|
|
2919 |
(if (and try-to-use-region (use-region-p))
|
|
2920 |
|
|
2921 |
;; We have a region and we were asked to use it. This usually happens when
|
|
2922 |
;; looking for text strings or regular expressions
|
|
2923 |
(buffer-substring-no-properties (region-beginning) (region-end))
|
|
2924 |
|
|
2925 |
;; Try to infer symbol from the text
|
|
2926 |
(let* ( (symbol-chars (if extract-filename
|
|
2927 |
cscope-filename-chars
|
|
2928 |
cscope-symbol-chars))
|
|
2929 |
(symbol-char-regexp (concat "[" symbol-chars "]"))
|
|
2930 |
)
|
|
2931 |
(save-excursion
|
|
2932 |
(buffer-substring-no-properties
|
|
2933 |
(progn
|
|
2934 |
(if (not (looking-at symbol-char-regexp))
|
|
2935 |
(re-search-backward "\\w" nil t))
|
|
2936 |
(skip-chars-backward symbol-chars)
|
|
2937 |
(point))
|
|
2938 |
(progn
|
|
2939 |
(skip-chars-forward symbol-chars)
|
|
2940 |
(point)
|
|
2941 |
)))
|
|
2942 |
)))
|
|
2943 |
|
|
2944 |
|
|
2945 |
(defun cscope-prompt-for-symbol (prompt extract-filename try-to-use-region is-regex)
|
|
2946 |
"Prompt the user for a cscope symbol."
|
|
2947 |
(let ((sym (cscope-extract-symbol-at-cursor extract-filename try-to-use-region)))
|
|
2948 |
(if (or (not sym)
|
|
2949 |
(string= sym "")
|
|
2950 |
(not (boundp 'cscope-suppress-user-symbol-prompt))
|
|
2951 |
|
|
2952 |
;; Always prompt for symbol in dired mode.
|
|
2953 |
(eq major-mode 'dired-mode))
|
|
2954 |
(let ((full-prompt (concat prompt
|
|
2955 |
(when sym
|
|
2956 |
(concat "("
|
|
2957 |
(when is-regex "regex; ")
|
|
2958 |
"default '"
|
|
2959 |
sym
|
|
2960 |
"'): ")))))
|
|
2961 |
(setq sym (read-string full-prompt nil 'cscope-prompt-minibuffer-history sym)))
|
|
2962 |
sym)
|
|
2963 |
))
|
|
2964 |
|
|
2965 |
|
|
2966 |
(defun cscope-find-this-symbol (symbol)
|
|
2967 |
"Locate a symbol in source code."
|
|
2968 |
(interactive (list
|
|
2969 |
(cscope-prompt-for-symbol "Find this symbol " nil nil t)
|
|
2970 |
))
|
|
2971 |
(setq cscope-previous-user-search `(cscope-find-this-symbol ,symbol))
|
|
2972 |
(cscope-call "Finding symbol:" 0 symbol)
|
|
2973 |
)
|
|
2974 |
|
|
2975 |
|
|
2976 |
(defun cscope-find-global-definition (symbol)
|
|
2977 |
"Find a symbol's global definition."
|
|
2978 |
(interactive (list
|
|
2979 |
(cscope-prompt-for-symbol "Find this global definition " nil nil t)
|
|
2980 |
))
|
|
2981 |
(setq cscope-previous-user-search `(cscope-find-global-definition ,symbol))
|
|
2982 |
(cscope-call "Finding global definition:" 1 symbol)
|
|
2983 |
)
|
|
2984 |
|
|
2985 |
|
|
2986 |
(defun cscope-find-global-definition-no-prompting ()
|
|
2987 |
"Find a symbol's global definition without prompting."
|
|
2988 |
(interactive)
|
|
2989 |
(let ( (symbol (cscope-extract-symbol-at-cursor nil nil)))
|
|
2990 |
(setq cscope-previous-user-search `(cscope-find-global-definition-no-prompting ,symbol))
|
|
2991 |
(cscope-call "Finding global definition:" 1 symbol)
|
|
2992 |
))
|
|
2993 |
|
|
2994 |
|
|
2995 |
(defun cscope-find-called-functions (symbol)
|
|
2996 |
"Display functions called by a function."
|
|
2997 |
(interactive (list
|
|
2998 |
(cscope-prompt-for-symbol
|
|
2999 |
"Find functions called by this function " nil nil t)
|
|
3000 |
))
|
|
3001 |
(setq cscope-previous-user-search `(cscope-find-called-functions ,symbol))
|
|
3002 |
(cscope-call "Finding functions called by:" 2 symbol)
|
|
3003 |
)
|
|
3004 |
|
|
3005 |
|
|
3006 |
(defun cscope-find-functions-calling-this-function (symbol)
|
|
3007 |
"Display functions calling a function."
|
|
3008 |
(interactive (list
|
|
3009 |
(cscope-prompt-for-symbol
|
|
3010 |
"Find functions calling this function " nil nil t)
|
|
3011 |
))
|
|
3012 |
(setq cscope-previous-user-search `(cscope-find-functions-calling-this-function ,symbol))
|
|
3013 |
(cscope-call "Finding functions calling:" 3 symbol)
|
|
3014 |
)
|
|
3015 |
|
|
3016 |
|
|
3017 |
(defun cscope-find-this-text-string (symbol)
|
|
3018 |
"Locate where a text string occurs."
|
|
3019 |
(interactive (list
|
|
3020 |
(cscope-prompt-for-symbol "Find this text string " nil t nil)
|
|
3021 |
))
|
|
3022 |
(setq cscope-previous-user-search `(cscope-find-this-text-string ,symbol))
|
|
3023 |
(cscope-call "Finding text string:" 4 symbol)
|
|
3024 |
)
|
|
3025 |
|
|
3026 |
|
|
3027 |
(defun cscope-find-egrep-pattern (symbol)
|
|
3028 |
"Run egrep over the cscope database."
|
|
3029 |
(interactive (list
|
|
3030 |
(let (cscope-no-mouse-prompts)
|
|
3031 |
(cscope-prompt-for-symbol "Find this egrep pattern " nil t t))
|
|
3032 |
))
|
|
3033 |
(setq cscope-previous-user-search `(cscope-find-egrep-pattern ,symbol))
|
|
3034 |
(cscope-call "Finding egrep pattern:" 6 symbol)
|
|
3035 |
)
|
|
3036 |
|
|
3037 |
|
|
3038 |
(defun cscope-find-this-file (symbol)
|
|
3039 |
"Locate a file."
|
|
3040 |
(interactive (list
|
|
3041 |
(let (cscope-no-mouse-prompts)
|
|
3042 |
(cscope-prompt-for-symbol "Find this file " t nil t))
|
|
3043 |
))
|
|
3044 |
|
|
3045 |
(setq cscope-previous-user-search `(cscope-find-this-file ,symbol))
|
|
3046 |
(cscope-call "Finding file:" 7 symbol)
|
|
3047 |
)
|
|
3048 |
|
|
3049 |
|
|
3050 |
(defun cscope-find-files-including-file (symbol)
|
|
3051 |
"Locate all files #including a file."
|
|
3052 |
(interactive (list
|
|
3053 |
(let (cscope-no-mouse-prompts)
|
|
3054 |
(cscope-prompt-for-symbol
|
|
3055 |
"Find files #including this file " t nil nil))
|
|
3056 |
))
|
|
3057 |
(setq cscope-previous-user-search `(cscope-find-files-including-file ,symbol))
|
|
3058 |
(cscope-call "Finding files #including file:" 8 symbol)
|
|
3059 |
)
|
|
3060 |
|
|
3061 |
|
|
3062 |
(defun cscope-find-assignments-to-this-symbol (symbol)
|
|
3063 |
"Locate assignments to a symbol in the source code."
|
|
3064 |
(interactive (list
|
|
3065 |
(cscope-prompt-for-symbol "Find assignments to this symbol " nil nil t)
|
|
3066 |
))
|
|
3067 |
(setq cscope-previous-user-search `(cscope-find-assignments-to-this-symbol ,symbol))
|
|
3068 |
(cscope-call "Finding assignments to symbol:" 9 symbol)
|
|
3069 |
)
|
|
3070 |
|
|
3071 |
|
|
3072 |
|
|
3073 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
3074 |
|
|
3075 |
;;;###autoload
|
|
3076 |
(define-minor-mode cscope-minor-mode
|
|
3077 |
"This cscope minor mode maps cscope keybindings to make cscope
|
|
3078 |
functions more accessible.
|
|
3079 |
|
|
3080 |
Key bindings:
|
|
3081 |
\\{cscope-minor-mode-keymap}"
|
|
3082 |
nil nil cscope-minor-mode-keymap
|
|
3083 |
(when cscope-minor-mode
|
|
3084 |
(easy-menu-add cscope-global-menu cscope-minor-mode-keymap)
|
|
3085 |
(run-hooks 'cscope-minor-mode-hooks)))
|
|
3086 |
|
|
3087 |
;;;###autoload
|
|
3088 |
(defun cscope-setup ()
|
|
3089 |
"Automatically turns on cscope-minor-mode when editing C and
|
|
3090 |
C++ sources"
|
|
3091 |
(interactive)
|
|
3092 |
(add-hook 'c-mode-hook (function cscope-minor-mode))
|
|
3093 |
(add-hook 'c++-mode-hook (function cscope-minor-mode))
|
|
3094 |
(add-hook 'dired-mode-hook (function cscope-minor-mode)))
|
|
3095 |
|
|
3096 |
(provide 'xcscope)
|
|
3097 |
|
|
3098 |
;;; xcscope.el ends here
|