updated on Thu Jan 12 04:00:44 UTC 2012
[aur-mirror.git] / emacs-xcscope / xcscope.el
blobce382a44b17c21ef589b4b51f3aeb7d8a608cf49
1 ; -*-Emacs-Lisp-*-
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4 ; File: xcscope.el
5 ; RCS: $RCSfile: xcscope.el,v $ $Revision: 1.14 $ $Date: 2002/04/10 16:59:00 $ $Author: darrylo $
6 ; Description: cscope interface for (X)Emacs
7 ; Author: Darryl Okahata
8 ; Created: Wed Apr 19 17:03:38 2000
9 ; Modified: Thu Apr 4 17:22:22 2002 (Darryl Okahata) darrylo@soco.agilent.com
10 ; Language: Emacs-Lisp
11 ; Package: N/A
12 ; Status: Experimental
14 ; (C) Copyright 2000, 2001, 2002, Darryl Okahata <darrylo@sonic.net>,
15 ; all rights reserved.
16 ; GNU Emacs enhancements (C) Copyright 2001,
17 ; Triet H. Lai <thlai@mail.usyd.edu.au>
18 ; Fuzzy matching and navigation code (C) Copyright 2001,
19 ; Steven Elliott <selliott4@austin.rr.com>
21 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
22 ;; ALPHA VERSION 0.96
23 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25 ;; This program is free software; you can redistribute it and/or modify
26 ;; it under the terms of the GNU General Public License as published by
27 ;; the Free Software Foundation; either version 2, or (at your option)
28 ;; any later version.
30 ;; This program is distributed in the hope that it will be useful,
31 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
32 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 ;; GNU General Public License for more details.
35 ;; You should have received a copy of the GNU General Public License
36 ;; along with GNU Emacs; see the file COPYING. If not, write to
37 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
39 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
41 ;; This is a cscope interface for (X)Emacs.
42 ;; It currently runs under Unix only.
44 ;; Using cscope, you can easily search for where symbols are used and defined.
45 ;; Cscope is designed to answer questions like:
47 ;; Where is this variable used?
48 ;; What is the value of this preprocessor symbol?
49 ;; Where is this function in the source files?
50 ;; What functions call this function?
51 ;; What functions are called by this function?
52 ;; Where does the message "out of space" come from?
53 ;; Where is this source file in the directory structure?
54 ;; What files include this header file?
56 ;; Send comments to one of: darrylo@soco.agilent.com
57 ;; darryl_okahata@agilent.com
58 ;; darrylo@sonic.net
60 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
62 ;; ***** INSTALLATION *****
64 ;; * NOTE: this interface currently runs under Unix only.
66 ;; This module needs a shell script called "cscope-indexer", which
67 ;; should have been supplied along with this emacs-lisp file. The
68 ;; purpose of "cscope-indexer" is to create and optionally maintain
69 ;; the cscope databases. If all of your source files are in one
70 ;; directory, you don't need this script; it's very nice to have,
71 ;; though, as it handles recursive subdirectory indexing, and can be
72 ;; used in a nightly or weekly cron job to index very large source
73 ;; repositories. See the beginning of the file, "cscope-indexer", for
74 ;; usage information.
76 ;; Installation steps:
78 ;; 0. (It is, of course, assumed that cscope is already properly
79 ;; installed on the current system.)
81 ;; 1. Install the "cscope-indexer" script into some convenient
82 ;; directory in $PATH. The only real constraint is that (X)Emacs
83 ;; must be able to find and execute it. You may also have to edit
84 ;; the value of PATH in the script, although this is unlikely; the
85 ;; majority of people should be able to use the script, "as-is".
87 ;; 2. Make sure that the "cscope-indexer" script is executable. In
88 ;; particular, if you had to ftp this file, it is probably no
89 ;; longer executable.
91 ;; 3. Put this emacs-lisp file somewhere where (X)Emacs can find it. It
92 ;; basically has to be in some directory listed in "load-path".
94 ;; 4. Edit your ~/.emacs file to add the line:
96 ;; (require 'xcscope)
98 ;; 5. If you intend to use xcscope.el often you can optionally edit your
99 ;; ~/.emacs file to add keybindings that reduce the number of keystrokes
100 ;; required. For example, the following will add "C-f#" keybindings, which
101 ;; are easier to type than the usual "C-c s" prefixed keybindings. Note
102 ;; that specifying "global-map" instead of "cscope:map" makes the
103 ;; keybindings available in all buffers:
105 ;; (define-key global-map [(control f3)] 'cscope-set-initial-directory)
106 ;; (define-key global-map [(control f4)] 'cscope-unset-initial-directory)
107 ;; (define-key global-map [(control f5)] 'cscope-find-this-symbol)
108 ;; (define-key global-map [(control f6)] 'cscope-find-global-definition)
109 ;; (define-key global-map [(control f7)]
110 ;; 'cscope-find-global-definition-no-prompting)
111 ;; (define-key global-map [(control f8)] 'cscope-pop-mark)
112 ;; (define-key global-map [(control f9)] 'cscope-next-symbol)
113 ;; (define-key global-map [(control f10)] 'cscope-next-file)
114 ;; (define-key global-map [(control f11)] 'cscope-prev-symbol)
115 ;; (define-key global-map [(control f12)] 'cscope-prev-file)
116 ;; (define-key global-map [(meta f9)] 'cscope-display-buffer)
117 ;; (defin-ekey global-map [(meta f10)] 'cscope-display-buffer-toggle)
119 ;; 6. Restart (X)Emacs. That's it.
122 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
124 ;; ***** USING THIS MODULE *****
126 ;; * Basic usage:
128 ;; If all of your C/C++/lex/yacc source files are in the same
129 ;; directory, you can just start using this module. If your files are
130 ;; spread out over multiple directories, see "Advanced usage", below.
132 ;; Just edit a source file, and use the pull-down or pop-up (button 3)
133 ;; menus to select one of:
135 ;; Find symbol
136 ;; Find global definition
137 ;; Find called functions
138 ;; Find functions calling a function
139 ;; Find text string
140 ;; Find egrep pattern
141 ;; Find a file
142 ;; Find files #including a file
144 ;; The cscope database will be automatically created in the same
145 ;; directory as the source files (assuming that you've never used
146 ;; cscope before), and a buffer will pop-up displaying the results.
147 ;; You can then use button 2 (the middle button) on the mouse to edit
148 ;; the selected file, or you can move the text cursor over a selection
149 ;; and press [Enter].
151 ;; Hopefully, the interface should be fairly intuitive.
154 ;; * Locating the cscope databases:
156 ;; This module will first use the variable, `cscope-database-regexps',
157 ;; to search for a suitable database directory. If a database location
158 ;; cannot be found using this variable then a search is begun at the
159 ;; variable, `cscope-initial-directory', if set, or the current
160 ;; directory otherwise. If the directory is not a cscope database
161 ;; directory then the directory's parent, parent's parent, etc. is
162 ;; searched until a cscope database directory is found, or the root
163 ;; directory is reached. If the root directory is reached, the current
164 ;; directory will be used.
166 ;; A cscope database directory is one in which EITHER a cscope database
167 ;; file (e.g., "cscope.out") OR a cscope file list (e.g.,
168 ;; "cscope.files") exists. If only "cscope.files" exists, the
169 ;; corresponding "cscope.out" will be automatically created by cscope
170 ;; when a search is done. By default, the cscope database file is called
171 ;; "cscope.out", but this can be changed (on a global basis) via the
172 ;; variable, `cscope-database-file'. There is limited support for cscope
173 ;; databases that are named differently than that given by
174 ;; `cscope-database-file', using the variable, `cscope-database-regexps'.
176 ;; Note that the variable, `cscope-database-regexps', is generally not
177 ;; needed, as the normal hierarchical database search is sufficient
178 ;; for placing and/or locating the cscope databases. However, there
179 ;; may be cases where it makes sense to place the cscope databases
180 ;; away from where the source files are kept; in this case, this
181 ;; variable is used to determine the mapping. One use for this
182 ;; variable is when you want to share the database file with other
183 ;; users; in this case, the database may be located in a directory
184 ;; separate from the source files.
186 ;; Setting the variable, `cscope-initial-directory', is useful when a
187 ;; search is to be expanded by specifying a cscope database directory
188 ;; that is a parent of the directory that this module would otherwise
189 ;; use. For example, consider a project that contains the following
190 ;; cscope database directories:
192 ;; /users/jdoe/sources
193 ;; /users/jdoe/sources/proj1
194 ;; /users/jdoe/sources/proj2
196 ;; If a search is initiated from a .c file in /users/jdoe/sources/proj1
197 ;; then (assuming the variable, `cscope-database-regexps', is not set)
198 ;; /users/jdoe/sources/proj1 will be used as the cscope data base directory.
199 ;; Only matches in files in /users/jdoe/sources/proj1 will be found. This
200 ;; can be remedied by typing "C-c s a" and then "M-del" to remove single
201 ;; path element in order to use a cscope database directory of
202 ;; /users/jdoe/sources. Normal searching can be restored by typing "C-c s A".
205 ;; * Keybindings:
207 ;; All keybindings use the "C-c s" prefix, but are usable only while
208 ;; editing a source file, or in the cscope results buffer:
210 ;; C-c s s Find symbol.
211 ;; C-c s d Find global definition.
212 ;; C-c s g Find global definition (alternate binding).
213 ;; C-c s G Find global definition without prompting.
214 ;; C-c s c Find functions calling a function.
215 ;; C-c s C Find called functions (list functions called
216 ;; from a function).
217 ;; C-c s t Find text string.
218 ;; C-c s e Find egrep pattern.
219 ;; C-c s f Find a file.
220 ;; C-c s i Find files #including a file.
222 ;; These pertain to navigation through the search results:
224 ;; C-c s b Display *cscope* buffer.
225 ;; C-c s B Auto display *cscope* buffer toggle.
226 ;; C-c s n Next symbol.
227 ;; C-c s N Next file.
228 ;; C-c s p Previous symbol.
229 ;; C-c s P Previous file.
230 ;; C-c s u Pop mark.
232 ;; These pertain to setting and unsetting the variable,
233 ;; `cscope-initial-directory', (location searched for the cscope database
234 ;; directory):
236 ;; C-c s a Set initial directory.
237 ;; C-c s A Unset initial directory.
239 ;; These pertain to cscope database maintenance:
241 ;; C-c s L Create list of files to index.
242 ;; C-c s I Create list and index.
243 ;; C-c s E Edit list of files to index.
244 ;; C-c s W Locate this buffer's cscope directory
245 ;; ("W" --> "where").
246 ;; C-c s S Locate this buffer's cscope directory.
247 ;; (alternate binding: "S" --> "show").
248 ;; C-c s T Locate this buffer's cscope directory.
249 ;; (alternate binding: "T" --> "tell").
250 ;; C-c s D Dired this buffer's directory.
253 ;; * Advanced usage:
255 ;; If the source files are spread out over multiple directories,
256 ;; you've got a few choices:
258 ;; [ NOTE: you will need to have the script, "cscope-indexer",
259 ;; properly installed in order for the following to work. ]
261 ;; 1. If all of the directories exist below a common directory
262 ;; (without any extraneous, unrelated subdirectories), you can tell
263 ;; this module to place the cscope database into the top-level,
264 ;; common directory. This assumes that you do not have any cscope
265 ;; databases in any of the subdirectories. If you do, you should
266 ;; delete them; otherwise, they will take precedence over the
267 ;; top-level database.
269 ;; If you do have cscope databases in any subdirectory, the
270 ;; following instructions may not work right.
272 ;; It's pretty easy to tell this module to use a top-level, common
273 ;; directory:
275 ;; a. Make sure that the menu pick, "Cscope/Index recursively", is
276 ;; checked (the default value).
278 ;; b. Select the menu pick, "Cscope/Create list and index", and
279 ;; specify the top-level directory. This will run the script,
280 ;; "cscope-indexer", in the background, so you can do other
281 ;; things if indexing takes a long time. A list of files to
282 ;; index will be created in "cscope.files", and the cscope
283 ;; database will be created in "cscope.out".
285 ;; Once this has been done, you can then use the menu picks
286 ;; (described in "Basic usage", above) to search for symbols.
288 ;; Note, however, that, if you add or delete source files, you'll
289 ;; have to either rebuild the database using the above procedure,
290 ;; or edit the file, "cscope.files" to add/delete the names of the
291 ;; source files. To edit this file, you can use the menu pick,
292 ;; "Cscope/Edit list of files to index".
295 ;; 2. If most of the files exist below a common directory, but a few
296 ;; are outside, you can use the menu pick, "Cscope/Create list of
297 ;; files to index", and specify the top-level directory. Make sure
298 ;; that "Cscope/Index recursively", is checked before you do so,
299 ;; though. You can then edit the list of files to index using the
300 ;; menu pick, "Cscope/Edit list of files to index". Just edit the
301 ;; list to include any additional source files not already listed.
303 ;; Once you've created, edited, and saved the list, you can then
304 ;; use the menu picks described under "Basic usage", above, to
305 ;; search for symbols. The first time you search, you will have to
306 ;; wait a while for cscope to fully index the source files, though.
307 ;; If you have a lot of source files, you may want to manually run
308 ;; cscope to build the database:
310 ;; cd top-level-directory # or wherever
311 ;; rm -f cscope.out # not always necessary
312 ;; cscope -b
315 ;; 3. If the source files are scattered in many different, unrelated
316 ;; places, you'll have to manually create cscope.files and put a
317 ;; list of all pathnames into it. Then build the database using:
319 ;; cd some-directory # wherever cscope.files exists
320 ;; rm -f cscope.out # not always necessary
321 ;; cscope -b
323 ;; Next, read the documentation for the variable,
324 ;; "cscope-database-regexps", and set it appropriately, such that
325 ;; the above-created cscope database will be referenced when you
326 ;; edit a related source file.
328 ;; Once this has been done, you can then use the menu picks
329 ;; described under "Basic usage", above, to search for symbols.
332 ;; * Interesting configuration variables:
334 ;; "cscope-truncate-lines"
335 ;; This is the value of `truncate-lines' to use in cscope
336 ;; buffers; the default is the current setting of
337 ;; `truncate-lines'. This variable exists because it can be
338 ;; easier to read cscope buffers with truncated lines, while
339 ;; other buffers do not have truncated lines.
341 ;; "cscope-use-relative-paths"
342 ;; If non-nil, use relative paths when creating the list of files
343 ;; to index. The path is relative to the directory in which the
344 ;; cscope database will be created. If nil, absolute paths will
345 ;; be used. Absolute paths are good if you plan on moving the
346 ;; database to some other directory (if you do so, you'll
347 ;; probably also have to modify `cscope-database-regexps').
348 ;; Absolute paths may also be good if you share the database file
349 ;; with other users (you'll probably want to specify some
350 ;; automounted network path for this).
352 ;; "cscope-index-recursively"
353 ;; If non-nil, index files in the current directory and all
354 ;; subdirectories. If nil, only files in the current directory
355 ;; are indexed. This variable is only used when creating the
356 ;; list of files to index, or when creating the list of files and
357 ;; the corresponding cscope database.
359 ;; "cscope-name-line-width"
360 ;; The width of the combined "function name:line number" field in
361 ;; the cscope results buffer. If negative, the field is
362 ;; left-justified.
364 ;; "cscope-do-not-update-database"
365 ;; If non-nil, never check and/or update the cscope database when
366 ;; searching. Beware of setting this to non-nil, as this will
367 ;; disable automatic database creation, updating, and
368 ;; maintenance.
370 ;; "cscope-display-cscope-buffer"
371 ;; If non-nil, display the *cscope* buffer after each search
372 ;; (default). This variable can be set in order to reduce the
373 ;; number of keystrokes required to navigate through the matches.
375 ;; "cscope-database-regexps"
376 ;; List to force directory-to-cscope-database mappings.
377 ;; This is a list of `(REGEXP DBLIST [ DBLIST ... ])', where:
379 ;; REGEXP is a regular expression matched against the current buffer's
380 ;; current directory. The current buffer is typically some source file,
381 ;; and you're probably searching for some symbol in or related to this
382 ;; file. Basically, this regexp is used to relate the current directory
383 ;; to a cscope database. You need to start REGEXP with "^" if you want
384 ;; to match from the beginning of the current directory.
386 ;; DBLIST is a list that contains one or more of:
388 ;; ( DBDIR )
389 ;; ( DBDIR ( OPTIONS ) )
390 ;; ( t )
391 ;; t
393 ;; Here, DBDIR is a directory (or a file) that contains a cscope
394 ;; database. If DBDIR is a directory, then it is expected that the
395 ;; cscope database, if present, has the filename given by the variable,
396 ;; `cscope-database-file'; if DBDIR is a file, then DBDIR is the path
397 ;; name to a cscope database file (which does not have to be the same as
398 ;; that given by `cscope-database-file'). If only DBDIR is specified,
399 ;; then that cscope database will be searched without any additional
400 ;; cscope command-line options. If OPTIONS is given, then OPTIONS is a
401 ;; list of strings, where each string is a separate cscope command-line
402 ;; option.
404 ;; In the case of "( t )", this specifies that the search is to use the
405 ;; normal hierarchical database search. This option is used to
406 ;; explicitly search using the hierarchical database search either before
407 ;; or after other cscope database directories.
409 ;; If "t" is specified (not inside a list), this tells the searching
410 ;; mechanism to stop searching if a match has been found (at the point
411 ;; where "t" is encountered). This is useful for those projects that
412 ;; consist of many subprojects. You can specify the most-used
413 ;; subprojects first, followed by a "t", and then followed by a master
414 ;; cscope database directory that covers all subprojects. This will
415 ;; cause the most-used subprojects to be searched first (hopefully
416 ;; quickly), and the search will then stop if a match was found. If not,
417 ;; the search will continue using the master cscope database directory.
419 ;; Here, `cscope-database-regexps' is generally not used, as the normal
420 ;; hierarchical database search is sufficient for placing and/or locating
421 ;; the cscope databases. However, there may be cases where it makes
422 ;; sense to place the cscope databases away from where the source files
423 ;; are kept; in this case, this variable is used to determine the
424 ;; mapping.
426 ;; This module searches for the cscope databases by first using this
427 ;; variable; if a database location cannot be found using this variable,
428 ;; then the current directory is searched, then the parent, then the
429 ;; parent's parent, until a cscope database directory is found, or the
430 ;; root directory is reached. If the root directory is reached, the
431 ;; current directory will be used.
433 ;; A cscope database directory is one in which EITHER a cscope database
434 ;; file (e.g., "cscope.out") OR a cscope file list (e.g.,
435 ;; "cscope.files") exists. If only "cscope.files" exists, the
436 ;; corresponding "cscope.out" will be automatically created by cscope
437 ;; when a search is done. By default, the cscope database file is called
438 ;; "cscope.out", but this can be changed (on a global basis) via the
439 ;; variable, `cscope-database-file'. There is limited support for cscope
440 ;; databases that are named differently than that given by
441 ;; `cscope-database-file', using the variable, `cscope-database-regexps'.
443 ;; Here is an example of `cscope-database-regexps':
445 ;; (setq cscope-database-regexps
446 ;; '(
447 ;; ( "^/users/jdoe/sources/proj1"
448 ;; ( t )
449 ;; ( "/users/jdoe/sources/proj2")
450 ;; ( "/users/jdoe/sources/proj3/mycscope.out")
451 ;; ( "/users/jdoe/sources/proj4")
452 ;; t
453 ;; ( "/some/master/directory" ("-d" "-I/usr/local/include") )
454 ;; )
455 ;; ( "^/users/jdoe/sources/gnome/"
456 ;; ( "/master/gnome/database" ("-d") )
457 ;; )
458 ;; ))
460 ;; If the current buffer's directory matches the regexp,
461 ;; "^/users/jdoe/sources/proj1", then the following search will be
462 ;; done:
464 ;; 1. First, the normal hierarchical database search will be used to
465 ;; locate a cscope database.
467 ;; 2. Next, searches will be done using the cscope database
468 ;; directories, "/users/jdoe/sources/proj2",
469 ;; "/users/jdoe/sources/proj3/mycscope.out", and
470 ;; "/users/jdoe/sources/proj4". Note that, instead of the file,
471 ;; "cscope.out", the file, "mycscope.out", will be used in the
472 ;; directory "/users/jdoe/sources/proj3".
474 ;; 3. If a match was found, searching will stop.
476 ;; 4. If a match was not found, searching will be done using
477 ;; "/some/master/directory", and the command-line options "-d"
478 ;; and "-I/usr/local/include" will be passed to cscope.
480 ;; If the current buffer's directory matches the regexp,
481 ;; "^/users/jdoe/sources/gnome", then the following search will be
482 ;; done:
484 ;; The search will be done only using the directory,
485 ;; "/master/gnome/database". The "-d" option will be passed to
486 ;; cscope.
488 ;; If the current buffer's directory does not match any of the above
489 ;; regexps, then only the normal hierarchical database search will be
490 ;; done.
493 ;; * Other notes:
495 ;; 1. The script, "cscope-indexer", uses a sed command to determine
496 ;; what is and is not a C/C++/lex/yacc source file. It's idea of a
497 ;; source file may not correspond to yours.
499 ;; 2. This module is called, "xcscope", because someone else has
500 ;; already written a "cscope.el" (although it's quite old).
503 ;; * KNOWN BUGS:
505 ;; 1. Cannot handle whitespace in directory or file names.
507 ;; 2. By default, colored faces are used to display results. If you happen
508 ;; to use a black background, part of the results may be invisible
509 ;; (because the foreground color may be black, too). There are at least
510 ;; two solutions for this:
512 ;; 2a. Turn off colored faces, by setting `cscope-use-face' to `nil',
513 ;; e.g.:
515 ;; (setq cscope-use-face nil)
517 ;; 2b. Explicitly set colors for the faces used by cscope. The faces
518 ;; are:
520 ;; cscope-file-face
521 ;; cscope-function-face
522 ;; cscope-line-number-face
523 ;; cscope-line-face
524 ;; cscope-mouse-face
526 ;; The face most likely to cause problems (e.g., black-on-black
527 ;; color) is `cscope-line-face'.
529 ;; 3. The support for cscope databases different from that specified by
530 ;; `cscope-database-file' is quirky. If the file does not exist, it
531 ;; will not be auto-created (unlike files names by
532 ;; `cscope-database-file'). You can manually force the file to be
533 ;; created by using touch(1) to create a zero-length file; the
534 ;; database will be created the next time a search is done.
536 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
538 (require 'easymenu)
541 (defgroup cscope nil
542 "Cscope interface for (X)Emacs.
543 Using cscope, you can easily search for where symbols are used and defined.
544 It is designed to answer questions like:
546 Where is this variable used?
547 What is the value of this preprocessor symbol?
548 Where is this function in the source files?
549 What functions call this function?
550 What functions are called by this function?
551 Where does the message \"out of space\" come from?
552 Where is this source file in the directory structure?
553 What files include this header file?
555 :prefix "cscope-"
556 :group 'tools)
559 (defcustom cscope-do-not-update-database nil
560 "*If non-nil, never check and/or update the cscope database when searching.
561 Beware of setting this to non-nil, as this will disable automatic database
562 creation, updating, and maintenance."
563 :type 'boolean
564 :group 'cscope)
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:
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.
578 DBLIST is a list that contains one or more of:
580 ( DBDIR )
581 ( DBDIR ( OPTIONS ) )
582 ( t )
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.
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.
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.
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.
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.
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'.
634 Here is an example of `cscope-database-regexps':
636 (setq cscope-database-regexps
638 ( \"^/users/jdoe/sources/proj1\"
639 ( t )
640 ( \"/users/jdoe/sources/proj2\")
641 ( \"/users/jdoe/sources/proj3/mycscope.out\")
642 ( \"/users/jdoe/sources/proj4\")
644 ( \"/some/master/directory\" (\"-d\" \"-I/usr/local/include\") )
646 ( \"^/users/jdoe/sources/gnome/\"
647 ( \"/master/gnome/database\" (\"-d\") )
651 If the current buffer's directory matches the regexp,
652 \"^/users/jdoe/sources/proj1\", then the following search will be
653 done:
655 1. First, the normal hierarchical database search will be used to
656 locate a cscope database.
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\".
665 3. If a match was found, searching will stop.
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.
671 If the current buffer's directory matches the regexp,
672 \"^/users/jdoe/sources/gnome\", then the following search will be
673 done:
675 The search will be done only using the directory,
676 \"/master/gnome/database\". The \"-d\" option will be passed to
677 cscope.
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.
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")
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)
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)
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)
718 (defcustom cscope-program "cscope"
719 "*The pathname of the cscope executable to use."
720 :type 'string
721 :group 'cscope)
724 (defcustom cscope-index-file "cscope.files"
725 "*The name of the cscope file list file."
726 :type 'string
727 :group 'cscope)
730 (defcustom cscope-database-file "cscope.out"
731 "*The name of the cscope database file."
732 :type 'string
733 :group 'cscope)
736 (defcustom cscope-edit-single-match t
737 "*If non-nil and only one match is output, edit the matched location."
738 :type 'boolean
739 :group 'cscope)
742 (defcustom cscope-display-cscope-buffer t
743 "*If non-nil automatically display the *cscope* buffer after each search."
744 :type 'boolean
745 :group 'cscope)
748 (defcustom cscope-stop-at-first-match-dir nil
749 "*If non-nil, stop searching through multiple databases if a match is found.
750 This option is useful only if multiple cscope database directories are being
751 used. When multiple databases are searched, setting this variable to non-nil
752 will cause searches to stop when a search outputs anything; no databases after
753 this one will be searched."
754 :type 'boolean
755 :group 'cscope)
758 (defcustom cscope-use-relative-paths t
759 "*If non-nil, use relative paths when creating the list of files to index.
760 The path is relative to the directory in which the cscope database
761 will be created. If nil, absolute paths will be used. Absolute paths
762 are good if you plan on moving the database to some other directory
763 (if you do so, you'll probably also have to modify
764 \`cscope-database-regexps\'). Absolute paths may also be good if you
765 share the database file with other users (you\'ll probably want to
766 specify some automounted network path for this)."
767 :type 'boolean
768 :group 'cscope)
771 (defcustom cscope-index-recursively t
772 "*If non-nil, index files in the current directory and all subdirectories.
773 If nil, only files in the current directory are indexed. This
774 variable is only used when creating the list of files to index, or
775 when creating the list of files and the corresponding cscope database."
776 :type 'boolean
777 :group 'cscope)
780 (defcustom cscope-no-mouse-prompts nil
781 "*If non-nil, use the symbol under the cursor instead of prompting.
782 Do not prompt for a value, except for when seaching for a egrep pattern
783 or a file."
784 :type 'boolean
785 :group 'cscope)
788 (defcustom cscope-suppress-empty-matches t
789 "*If non-nil, delete empty matches.")
792 (defcustom cscope-indexing-script "cscope-indexer"
793 "*The shell script used to create cscope indices."
794 :type 'string
795 :group 'cscope)
798 (defcustom cscope-symbol-chars "A-Za-z0-9_"
799 "*A string containing legal characters in a symbol.
800 The current syntax table should really be used for this."
801 :type 'string
802 :group 'cscope)
805 (defcustom cscope-filename-chars "-.,/A-Za-z0-9_~!@#$%&+=\\\\"
806 "*A string containing legal characters in a symbol.
807 The current syntax table should really be used for this."
808 :type 'string
809 :group 'cscope)
812 (defcustom cscope-allow-arrow-overlays t
813 "*If non-nil, use an arrow overlay to show target lines.
814 Arrow overlays are only used when the following functions are used:
816 cscope-show-entry-other-window
817 cscope-show-next-entry-other-window
818 cscope-show-prev-entry-other-window
820 The arrow overlay is removed when other cscope functions are used.
821 Note that the arrow overlay is not an actual part of the text, and can
822 be removed by quitting the cscope buffer."
823 :type 'boolean
824 :group 'cscope)
827 (defcustom cscope-overlay-arrow-string "=>"
828 "*The overlay string to use when displaying arrow overlays."
829 :type 'string
830 :group 'cscope)
833 (defvar cscope-minor-mode-hooks nil
834 "List of hooks to call when entering cscope-minor-mode.")
837 (defconst cscope-separator-line
838 "-------------------------------------------------------------------------------\n"
839 "Line of text to use as a visual separator.
840 Must end with a newline.")
843 ;;;;
844 ;;;; Faces for fontification
845 ;;;;
847 (defcustom cscope-use-face t
848 "*Whether to use text highlighting (à la font-lock) or not."
849 :group 'cscope
850 :type '(boolean))
853 (defface cscope-file-face
854 '((((class color) (background dark))
855 (:foreground "yellow"))
856 (((class color) (background light))
857 (:foreground "blue"))
858 (t (:bold t)))
859 "Face used to highlight file name in the *cscope* buffer."
860 :group 'cscope)
863 (defface cscope-function-face
864 '((((class color) (background dark))
865 (:foreground "cyan"))
866 (((class color) (background light))
867 (:foreground "magenta"))
868 (t (:bold t)))
869 "Face used to highlight function name in the *cscope* buffer."
870 :group 'cscope)
873 (defface cscope-line-number-face
874 '((((class color) (background dark))
875 (:foreground "red"))
876 (((class color) (background light))
877 (:foreground "red"))
878 (t (:bold t)))
879 "Face used to highlight line number in the *cscope* buffer."
880 :group 'cscope)
883 (defface cscope-line-face
884 '((((class color) (background dark))
885 (:foreground "green"))
886 (((class color) (background light))
887 (:foreground "black"))
888 (t (:bold nil)))
889 "Face used to highlight the rest of line in the *cscope* buffer."
890 :group 'cscope)
893 (defface cscope-mouse-face
894 '((((class color) (background dark))
895 (:foreground "white" :background "blue"))
896 (((class color) (background light))
897 (:foreground "white" :background "blue"))
898 (t (:bold nil)))
899 "Face used when mouse pointer is within the region of an entry."
900 :group 'cscope)
902 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
903 ;; Probably, nothing user-customizable past this point.
904 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
905 (defconst cscope-running-in-xemacs (string-match "XEmacs\\|Lucid" emacs-version))
907 (defvar cscope-list-entry-keymap nil
908 "The keymap used in the *cscope* buffer which lists search results.")
909 (if cscope-list-entry-keymap
911 (setq cscope-list-entry-keymap (make-keymap))
912 (suppress-keymap cscope-list-entry-keymap)
913 ;; The following section does not appear in the "Cscope" menu.
914 (if cscope-running-in-xemacs
915 (define-key cscope-list-entry-keymap [button2] 'cscope-mouse-select-entry-other-window)
916 (define-key cscope-list-entry-keymap [mouse-2] 'cscope-mouse-select-entry-other-window))
917 (define-key cscope-list-entry-keymap [return] 'cscope-select-entry-other-window)
918 (define-key cscope-list-entry-keymap " " 'cscope-show-entry-other-window)
919 (define-key cscope-list-entry-keymap "o" 'cscope-select-entry-one-window)
920 (define-key cscope-list-entry-keymap "q" 'cscope-bury-buffer)
921 (define-key cscope-list-entry-keymap "Q" 'cscope-quit)
922 (define-key cscope-list-entry-keymap "h" 'cscope-help)
923 (define-key cscope-list-entry-keymap "?" 'cscope-help)
924 ;; The following line corresponds to be beginning of the "Cscope" menu.
925 (define-key cscope-list-entry-keymap "s" 'cscope-find-this-symbol)
926 (define-key cscope-list-entry-keymap "d" 'cscope-find-this-symbol)
927 (define-key cscope-list-entry-keymap "g" 'cscope-find-global-definition)
928 (define-key cscope-list-entry-keymap "G"
929 'cscope-find-global-definition-no-prompting)
930 (define-key cscope-list-entry-keymap "c" 'cscope-find-functions-calling-this-function)
931 (define-key cscope-list-entry-keymap "C" 'cscope-find-called-functions)
932 (define-key cscope-list-entry-keymap "t" 'cscope-find-this-text-string)
933 (define-key cscope-list-entry-keymap "e" 'cscope-find-egrep-pattern)
934 (define-key cscope-list-entry-keymap "f" 'cscope-find-this-file)
935 (define-key cscope-list-entry-keymap "i" 'cscope-find-files-including-file)
936 ;; --- (The '---' indicates that this line corresponds to a menu separator.)
937 (define-key cscope-list-entry-keymap "n" 'cscope-next-symbol)
938 (define-key cscope-list-entry-keymap "N" 'cscope-next-file)
939 (define-key cscope-list-entry-keymap "p" 'cscope-prev-symbol)
940 (define-key cscope-list-entry-keymap "P" 'cscope-prev-file)
941 (define-key cscope-list-entry-keymap "u" 'cscope-pop-mark)
942 ;; ---
943 (define-key cscope-list-entry-keymap "a" 'cscope-set-initial-directory)
944 (define-key cscope-list-entry-keymap "A" 'cscope-unset-initial-directory)
945 ;; ---
946 (define-key cscope-list-entry-keymap "L" 'cscope-create-list-of-files-to-index)
947 (define-key cscope-list-entry-keymap "I" 'cscope-index-files)
948 (define-key cscope-list-entry-keymap "E" 'cscope-edit-list-of-files-to-index)
949 (define-key cscope-list-entry-keymap "W" 'cscope-tell-user-about-directory)
950 (define-key cscope-list-entry-keymap "S" 'cscope-tell-user-about-directory)
951 (define-key cscope-list-entry-keymap "T" 'cscope-tell-user-about-directory)
952 (define-key cscope-list-entry-keymap "D" 'cscope-dired-directory)
953 ;; The previous line corresponds to be end of the "Cscope" menu.
957 (defvar cscope-list-entry-hook nil
958 "*Hook run after cscope-list-entry-mode entered.")
961 (defun cscope-list-entry-mode ()
962 "Major mode for jumping/showing entry from the list in the *cscope* buffer.
964 \\{cscope-list-entry-keymap}"
965 (use-local-map cscope-list-entry-keymap)
966 (setq buffer-read-only t
967 mode-name "cscope"
968 major-mode 'cscope-list-entry-mode
969 overlay-arrow-string cscope-overlay-arrow-string)
970 (or overlay-arrow-position
971 (setq overlay-arrow-position (make-marker)))
972 (run-hooks 'cscope-list-entry-hook))
974 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
976 (defvar cscope-output-buffer-name "*cscope*"
977 "The name of the cscope output buffer.")
980 (defvar cscope-info-buffer-name "*cscope-info*"
981 "The name of the cscope information buffer.")
984 (defvar cscope-process nil
985 "The current cscope process.")
986 (make-variable-buffer-local 'cscope-process)
989 (defvar cscope-process-output nil
990 "A buffer for holding partial cscope process output.")
991 (make-variable-buffer-local 'cscope-process-output)
994 (defvar cscope-command-args nil
995 "Internal variable for holding major command args to pass to cscope.")
996 (make-variable-buffer-local 'cscope-command-args)
999 (defvar cscope-start-directory nil
1000 "Internal variable used to save the initial start directory.
1001 The results buffer gets reset to this directory when a search has
1002 completely finished.")
1003 (make-variable-buffer-local 'cscope-start-directory)
1006 (defvar cscope-search-list nil
1007 "A list of (DIR . FLAGS) entries.
1008 This is a list of database directories to search. Each entry in the list
1009 is a (DIR . FLAGS) cell. DIR is the directory to search, and FLAGS are the
1010 flags to pass to cscope when using this database directory. FLAGS can be
1011 nil (meaning, \"no flags\").")
1012 (make-variable-buffer-local 'cscope-search-list)
1015 (defvar cscope-searched-dirs nil
1016 "The list of database directories already searched.")
1017 (make-variable-buffer-local 'cscope-searched-dirs)
1020 (defvar cscope-filter-func nil
1021 "Internal variable for holding the filter function to use (if any) when
1022 searching.")
1023 (make-variable-buffer-local 'cscope-filter-func)
1026 (defvar cscope-sentinel-func nil
1027 "Internal variable for holding the sentinel function to use (if any) when
1028 searching.")
1029 (make-variable-buffer-local 'cscope-filter-func)
1032 (defvar cscope-last-file nil
1033 "The file referenced by the last line of cscope process output.")
1034 (make-variable-buffer-local 'cscope-last-file)
1037 (defvar cscope-start-time nil
1038 "The search start time, in seconds.")
1039 (make-variable-buffer-local 'cscope-start-time)
1042 (defvar cscope-first-match nil
1043 "The first match result output by cscope.")
1044 (make-variable-buffer-local 'cscope-first-match)
1047 (defvar cscope-first-match-point nil
1048 "Buffer location of the first match.")
1049 (make-variable-buffer-local 'cscope-first-match-point)
1052 (defvar cscope-item-start nil
1053 "The point location of the start of a search's output, before header info.")
1054 (make-variable-buffer-local 'cscope-output-start)
1057 (defvar cscope-output-start nil
1058 "The point location of the start of a search's output.")
1059 (make-variable-buffer-local 'cscope-output-start)
1062 (defvar cscope-matched-multiple nil
1063 "Non-nil if cscope output multiple matches.")
1064 (make-variable-buffer-local 'cscope-matched-multiple)
1067 (defvar cscope-stop-at-first-match-dir-meta nil
1069 (make-variable-buffer-local 'cscope-stop-at-first-match-dir-meta)
1072 (defvar cscope-symbol nil
1073 "The last symbol searched for.")
1076 (defvar cscope-adjust t
1077 "True if the symbol searched for (cscope-symbol) should be on
1078 the line specified by the cscope database. In such cases the point will be
1079 adjusted if need be (fuzzy matching).")
1082 (defvar cscope-adjust-range 1000
1083 "How far the point should be adjusted if the symbol is not on the line
1084 specified by the cscope database.")
1087 (defvar cscope-marker nil
1088 "The location from which cscope was invoked.")
1091 (defvar cscope-marker-window nil
1092 "The window which should contain cscope-marker. This is the window from
1093 which cscope-marker is set when searches are launched from the *cscope*
1094 buffer.")
1097 (defvar cscope-marker-ring-length 16
1098 "Length of the cscope marker ring.")
1101 (defvar cscope-marker-ring (make-ring cscope-marker-ring-length)
1102 "Ring of markers which are locations from which cscope was invoked.")
1105 (defvar cscope-initial-directory nil
1106 "When set the directory in which searches for the cscope database
1107 directory should begin.")
1110 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1112 (defvar cscope:map nil
1113 "The cscope keymap.")
1114 (if cscope:map
1116 (setq cscope:map (make-sparse-keymap))
1117 ;; The following line corresponds to be beginning of the "Cscope" menu.
1118 (define-key cscope:map "\C-css" 'cscope-find-this-symbol)
1119 (define-key cscope:map "\C-csd" 'cscope-find-global-definition)
1120 (define-key cscope:map "\C-csg" 'cscope-find-global-definition)
1121 (define-key cscope:map "\C-csG" 'cscope-find-global-definition-no-prompting)
1122 (define-key cscope:map "\C-csc" 'cscope-find-functions-calling-this-function)
1123 (define-key cscope:map "\C-csC" 'cscope-find-called-functions)
1124 (define-key cscope:map "\C-cst" 'cscope-find-this-text-string)
1125 (define-key cscope:map "\C-cse" 'cscope-find-egrep-pattern)
1126 (define-key cscope:map "\C-csf" 'cscope-find-this-file)
1127 (define-key cscope:map "\C-csi" 'cscope-find-files-including-file)
1128 ;; --- (The '---' indicates that this line corresponds to a menu separator.)
1129 (define-key cscope:map "\C-csb" 'cscope-display-buffer)
1130 (define-key cscope:map "\C-csB" 'cscope-display-buffer-toggle)
1131 (define-key cscope:map "\C-csn" 'cscope-next-symbol)
1132 (define-key cscope:map "\C-csN" 'cscope-next-file)
1133 (define-key cscope:map "\C-csp" 'cscope-prev-symbol)
1134 (define-key cscope:map "\C-csP" 'cscope-prev-file)
1135 (define-key cscope:map "\C-csu" 'cscope-pop-mark)
1136 ;; ---
1137 (define-key cscope:map "\C-csa" 'cscope-set-initial-directory)
1138 (define-key cscope:map "\C-csA" 'cscope-unset-initial-directory)
1139 ;; ---
1140 (define-key cscope:map "\C-csL" 'cscope-create-list-of-files-to-index)
1141 (define-key cscope:map "\C-csI" 'cscope-index-files)
1142 (define-key cscope:map "\C-csE" 'cscope-edit-list-of-files-to-index)
1143 (define-key cscope:map "\C-csW" 'cscope-tell-user-about-directory)
1144 (define-key cscope:map "\C-csS" 'cscope-tell-user-about-directory)
1145 (define-key cscope:map "\C-csT" 'cscope-tell-user-about-directory)
1146 (define-key cscope:map "\C-csD" 'cscope-dired-directory))
1147 ;; The previous line corresponds to be end of the "Cscope" menu.
1149 (easy-menu-define cscope:menu
1150 (list cscope:map cscope-list-entry-keymap)
1151 "cscope menu"
1152 '("Cscope"
1153 [ "Find symbol" cscope-find-this-symbol t ]
1154 [ "Find global definition" cscope-find-global-definition t ]
1155 [ "Find global definition no prompting"
1156 cscope-find-global-definition-no-prompting t ]
1157 [ "Find functions calling a function"
1158 cscope-find-functions-calling-this-function t ]
1159 [ "Find called functions" cscope-find-called-functions t ]
1160 [ "Find text string" cscope-find-this-text-string t ]
1161 [ "Find egrep pattern" cscope-find-egrep-pattern t ]
1162 [ "Find a file" cscope-find-this-file t ]
1163 [ "Find files #including a file"
1164 cscope-find-files-including-file t ]
1165 "-----------"
1166 [ "Display *cscope* buffer" cscope-display-buffer t ]
1167 [ "Auto display *cscope* buffer toggle"
1168 cscope-display-buffer-toggle t ]
1169 [ "Next symbol" cscope-next-symbol t ]
1170 [ "Next file" cscope-next-file t ]
1171 [ "Previous symbol" cscope-prev-symbol t ]
1172 [ "Previous file" cscope-prev-file t ]
1173 [ "Pop mark" cscope-pop-mark t ]
1174 "-----------"
1175 ( "Cscope Database"
1176 [ "Set initial directory"
1177 cscope-set-initial-directory t ]
1178 [ "Unset initial directory"
1179 cscope-unset-initial-directory t ]
1180 "-----------"
1181 [ "Create list of files to index"
1182 cscope-create-list-of-files-to-index t ]
1183 [ "Create list and index"
1184 cscope-index-files t ]
1185 [ "Edit list of files to index"
1186 cscope-edit-list-of-files-to-index t ]
1187 [ "Locate this buffer's cscope directory"
1188 cscope-tell-user-about-directory t ]
1189 [ "Dired this buffer's cscope directory"
1190 cscope-dired-directory t ]
1192 "-----------"
1193 ( "Options"
1194 [ "Auto edit single match"
1195 (setq cscope-edit-single-match
1196 (not cscope-edit-single-match))
1197 :style toggle :selected cscope-edit-single-match ]
1198 [ "Auto display *cscope* buffer"
1199 (setq cscope-display-cscope-buffer
1200 (not cscope-display-cscope-buffer))
1201 :style toggle :selected cscope-display-cscope-buffer ]
1202 [ "Stop at first matching database"
1203 (setq cscope-stop-at-first-match-dir
1204 (not cscope-stop-at-first-match-dir))
1205 :style toggle
1206 :selected cscope-stop-at-first-match-dir ]
1207 [ "Never update cscope database"
1208 (setq cscope-do-not-update-database
1209 (not cscope-do-not-update-database))
1210 :style toggle :selected cscope-do-not-update-database ]
1211 [ "Index recursively"
1212 (setq cscope-index-recursively
1213 (not cscope-index-recursively))
1214 :style toggle :selected cscope-index-recursively ]
1215 [ "Suppress empty matches"
1216 (setq cscope-suppress-empty-matches
1217 (not cscope-suppress-empty-matches))
1218 :style toggle :selected cscope-suppress-empty-matches ]
1219 [ "Use relative paths"
1220 (setq cscope-use-relative-paths
1221 (not cscope-use-relative-paths))
1222 :style toggle :selected cscope-use-relative-paths ]
1223 [ "No mouse prompts" (setq cscope-no-mouse-prompts
1224 (not cscope-no-mouse-prompts))
1225 :style toggle :selected cscope-no-mouse-prompts ]
1229 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1230 ;; Internal functions and variables
1231 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1233 (defvar cscope-common-text-plist
1234 (let (plist)
1235 (setq plist (plist-put plist 'mouse-face 'cscope-mouse-face))
1236 plist)
1237 "List of common text properties to be added to the entry line.")
1240 (defun cscope-insert-with-text-properties (text filename &optional line-number)
1241 "Insert an entry with given TEXT, add entry attributes as text properties.
1242 The text properties to be added:
1243 - common property: mouse-face,
1244 - properties are used to open target file and its location: cscope-file,
1245 cscope-line-number"
1246 (let ((plist cscope-common-text-plist)
1247 beg end)
1248 (setq beg (point))
1249 (insert text)
1250 (setq end (point)
1251 plist (plist-put plist 'cscope-file filename))
1252 (if line-number
1253 (progn
1254 (if (stringp line-number)
1255 (setq line-number (string-to-number line-number)))
1256 (setq plist (plist-put plist 'cscope-line-number line-number))
1258 (add-text-properties beg end plist)
1262 (if cscope-running-in-xemacs
1263 (progn
1264 (defalias 'cscope-event-window 'event-window)
1265 (defalias 'cscope-event-point 'event-point)
1266 (defalias 'cscope-recenter 'recenter)
1268 (defun cscope-event-window (event)
1269 "Return the window at which the mouse EVENT occurred."
1270 (posn-window (event-start event)))
1271 (defun cscope-event-point (event)
1272 "Return the point at which the mouse EVENT occurred."
1273 (posn-point (event-start event)))
1274 (defun cscope-recenter (&optional n window)
1275 "Center point in WINDOW and redisplay frame. With N, put point on line N."
1276 (save-selected-window
1277 (if (windowp window)
1278 (select-window window))
1279 (recenter n)))
1283 (defun cscope-show-entry-internal (file line-number
1284 &optional save-mark-p window arrow-p)
1285 "Display the buffer corresponding to FILE and LINE-NUMBER
1286 in some window. If optional argument WINDOW is given,
1287 display the buffer in that WINDOW instead. The window is
1288 not selected. Save point on mark ring before goto
1289 LINE-NUMBER if optional argument SAVE-MARK-P is non-nil.
1290 Put `overlay-arrow-string' if arrow-p is non-nil.
1291 Returns the window displaying BUFFER."
1292 (let (buffer old-pos old-point new-point forward-point backward-point
1293 line-end line-length)
1294 (if (and (stringp file)
1295 (integerp line-number))
1296 (progn
1297 (unless (file-readable-p file)
1298 (error "%s is not readable or exists" file))
1299 (setq buffer (find-file-noselect file))
1300 (if (windowp window)
1301 (set-window-buffer window buffer)
1302 (setq window (display-buffer buffer)))
1303 (set-buffer buffer)
1304 (if (> line-number 0)
1305 (progn
1306 (setq old-pos (point))
1307 (goto-line line-number)
1308 (setq old-point (point))
1309 (if (and cscope-adjust cscope-adjust-range)
1310 (progn
1311 ;; Calculate the length of the line specified by cscope.
1312 (end-of-line)
1313 (setq line-end (point))
1314 (goto-char old-point)
1315 (setq line-length (- line-end old-point))
1317 ;; Search forward and backward for the pattern.
1318 (setq forward-point (search-forward
1319 cscope-symbol
1320 (+ old-point
1321 cscope-adjust-range) t))
1322 (goto-char old-point)
1323 (setq backward-point (search-backward
1324 cscope-symbol
1325 (- old-point
1326 cscope-adjust-range) t))
1327 (if forward-point
1328 (progn
1329 (if backward-point
1330 (setq new-point
1331 ;; Use whichever of forward-point or
1332 ;; backward-point is closest to old-point.
1333 ;; Give forward-point a line-length advantage
1334 ;; so that if the symbol is on the current
1335 ;; line the current line is chosen.
1336 (if (<= (- (- forward-point line-length)
1337 old-point)
1338 (- old-point backward-point))
1339 forward-point
1340 backward-point))
1341 (setq new-point forward-point)))
1342 (if backward-point
1343 (setq new-point backward-point)
1344 (setq new-point old-point)))
1345 (goto-char new-point)
1346 (beginning-of-line)
1347 (setq new-point (point)))
1348 (setq new-point old-point))
1349 (set-window-point window new-point)
1350 (if (and cscope-allow-arrow-overlays arrow-p)
1351 (set-marker overlay-arrow-position (point))
1352 (set-marker overlay-arrow-position nil))
1353 (or (not save-mark-p)
1354 (= old-pos (point))
1355 (push-mark old-pos))
1358 (if cscope-marker
1359 (progn ;; The search was successful. Save the marker so it
1360 ;; can be returned to by cscope-pop-mark.
1361 (ring-insert cscope-marker-ring cscope-marker)
1362 ;; Unset cscope-marker so that moving between matches
1363 ;; (cscope-next-symbol, etc.) does not fill
1364 ;; cscope-marker-ring.
1365 (setq cscope-marker nil)))
1366 (setq cscope-marker-window window)
1368 (message "No entry found at point."))
1370 window)
1372 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1373 ;; functions in *cscope* buffer which lists the search results
1374 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1376 (defun cscope-select-entry-other-window ()
1377 "Display the entry at point in other window, select the window.
1378 Push current point on mark ring and select the entry window."
1379 (interactive)
1380 (let ((file (get-text-property (point) 'cscope-file))
1381 (line-number (get-text-property (point) 'cscope-line-number))
1382 window)
1383 (setq window (cscope-show-entry-internal file line-number t))
1384 (if (windowp window)
1385 (select-window window))
1389 (defun cscope-select-entry-one-window ()
1390 "Display the entry at point in one window, select the window."
1391 (interactive)
1392 (let ((file (get-text-property (point) 'cscope-file))
1393 (line-number (get-text-property (point) 'cscope-line-number))
1394 window)
1395 (setq window (cscope-show-entry-internal file line-number t))
1396 (if (windowp window)
1397 (progn
1398 (select-window window)
1399 (sit-for 0) ;; Redisplay hack to allow delete-other-windows
1400 ;; to continue displaying the correct location.
1401 (delete-other-windows window)
1406 (defun cscope-select-entry-specified-window (window)
1407 "Display the entry at point in a specified window, select the window."
1408 (interactive)
1409 (let ((file (get-text-property (point) 'cscope-file))
1410 (line-number (get-text-property (point) 'cscope-line-number)))
1411 (setq window (cscope-show-entry-internal file line-number t window))
1412 (if (windowp window)
1413 (select-window window))
1417 (defun cscope-mouse-select-entry-other-window (event)
1418 "Display the entry over which the mouse event occurred, select the window."
1419 (interactive "e")
1420 (let ((ep (cscope-event-point event))
1421 (win (cscope-event-window event))
1422 buffer file line-number window)
1423 (if ep
1424 (progn
1425 (setq buffer (window-buffer win)
1426 file (get-text-property ep 'cscope-file buffer)
1427 line-number (get-text-property ep 'cscope-line-number buffer))
1428 (select-window win)
1429 (setq window (cscope-show-entry-internal file line-number t))
1430 (if (windowp window)
1431 (select-window window))
1433 (message "No entry found at point.")
1438 (defun cscope-show-entry-other-window ()
1439 "Display the entry at point in other window.
1440 Point is not saved on mark ring."
1441 (interactive)
1442 (let ((file (get-text-property (point) 'cscope-file))
1443 (line-number (get-text-property (point) 'cscope-line-number)))
1444 (cscope-show-entry-internal file line-number nil nil t)
1448 (defun cscope-buffer-search (do-symbol do-next)
1449 "The body of the following four functions."
1450 (let* (line-number old-point point
1451 (search-file (not do-symbol))
1452 (search-prev (not do-next))
1453 (direction (if do-next 1 -1))
1454 (old-buffer (current-buffer))
1455 (old-buffer-window (get-buffer-window old-buffer))
1456 (buffer (get-buffer cscope-output-buffer-name))
1457 (buffer-window (get-buffer-window (or buffer (error "The *cscope* buffer does not exist yet"))))
1459 (set-buffer buffer)
1460 (setq old-point (point))
1461 (forward-line direction)
1462 (setq point (point))
1463 (setq line-number (get-text-property point 'cscope-line-number))
1464 (while (or (not line-number)
1465 (or (and do-symbol (= line-number -1))
1466 (and search-file (/= line-number -1))))
1467 (forward-line direction)
1468 (setq point (point))
1469 (if (or (and do-next (>= point (point-max)))
1470 (and search-prev (<= point (point-min))))
1471 (progn
1472 (goto-char old-point)
1473 (error "The %s of the *cscope* buffer has been reached"
1474 (if do-next "end" "beginning"))))
1475 (setq line-number (get-text-property point 'cscope-line-number)))
1476 (if (eq old-buffer buffer) ;; In the *cscope* buffer.
1477 (cscope-show-entry-other-window)
1478 (cscope-select-entry-specified-window old-buffer-window) ;; else
1479 (if (windowp buffer-window)
1480 (set-window-point buffer-window point)))
1481 (set-buffer old-buffer)
1485 (defun cscope-display-buffer ()
1486 "Display the *cscope* buffer."
1487 (interactive)
1488 (let ((buffer (get-buffer cscope-output-buffer-name)))
1489 (if buffer
1490 (pop-to-buffer buffer)
1491 (error "The *cscope* buffer does not exist yet"))))
1494 (defun cscope-display-buffer-toggle ()
1495 "Toggle cscope-display-cscope-buffer, which corresponds to
1496 \"Auto display *cscope* buffer\"."
1497 (interactive)
1498 (setq cscope-display-cscope-buffer (not cscope-display-cscope-buffer))
1499 (message "The cscope-display-cscope-buffer variable is now %s."
1500 (if cscope-display-cscope-buffer "set" "unset")))
1503 (defun cscope-next-symbol ()
1504 "Move to the next symbol in the *cscope* buffer."
1505 (interactive)
1506 (cscope-buffer-search t t))
1509 (defun cscope-next-file ()
1510 "Move to the next file in the *cscope* buffer."
1511 (interactive)
1512 (cscope-buffer-search nil t))
1515 (defun cscope-prev-symbol ()
1516 "Move to the previous symbol in the *cscope* buffer."
1517 (interactive)
1518 (cscope-buffer-search t nil))
1521 (defun cscope-prev-file ()
1522 "Move to the previous file in the *cscope* buffer."
1523 (interactive)
1524 (cscope-buffer-search nil nil))
1527 (defun cscope-pop-mark ()
1528 "Pop back to where cscope was last invoked."
1529 (interactive)
1531 ;; This function is based on pop-tag-mark, which can be found in
1532 ;; lisp/progmodes/etags.el.
1534 (if (ring-empty-p cscope-marker-ring)
1535 (error "There are no marked buffers in the cscope-marker-ring yet"))
1536 (let* ( (marker (ring-remove cscope-marker-ring 0))
1537 (old-buffer (current-buffer))
1538 (marker-buffer (marker-buffer marker))
1539 marker-window
1540 (marker-point (marker-position marker))
1541 (cscope-buffer (get-buffer cscope-output-buffer-name)) )
1543 ;; After the following both cscope-marker-ring and cscope-marker will be
1544 ;; in the state they were immediately after the last search. This way if
1545 ;; the user now makes a selection in the previously generated *cscope*
1546 ;; buffer things will behave the same way as if that selection had been
1547 ;; made immediately after the last search.
1548 (setq cscope-marker marker)
1550 (if marker-buffer
1551 (if (eq old-buffer cscope-buffer)
1552 (progn ;; In the *cscope* buffer.
1553 (set-buffer marker-buffer)
1554 (setq marker-window (display-buffer marker-buffer))
1555 (set-window-point marker-window marker-point)
1556 (select-window marker-window))
1557 (switch-to-buffer marker-buffer))
1558 (error "The marked buffer has been deleted"))
1559 (goto-char marker-point)
1560 (set-buffer old-buffer)))
1563 (defun cscope-set-initial-directory (cs-id)
1564 "Set the cscope-initial-directory variable. The
1565 cscope-initial-directory variable, when set, specifies the directory
1566 where searches for the cscope database directory should begin. This
1567 overrides the current directory, which would otherwise be used."
1568 (interactive "DCscope Initial Directory: ")
1569 (setq cscope-initial-directory cs-id))
1572 (defun cscope-unset-initial-directory ()
1573 "Unset the cscope-initial-directory variable."
1574 (interactive)
1575 (setq cscope-initial-directory nil)
1576 (message "The cscope-initial-directory variable is now unset."))
1579 (defun cscope-help ()
1580 (interactive)
1581 (message
1582 (format "RET=%s, SPC=%s, o=%s, n=%s, p=%s, q=%s, h=%s"
1583 "Select"
1584 "Show"
1585 "SelectOneWin"
1586 "ShowNext"
1587 "ShowPrev"
1588 "Quit"
1589 "Help")))
1592 (defun cscope-bury-buffer ()
1593 "Clean up cscope, if necessary, and bury the buffer."
1594 (interactive)
1595 (let ()
1596 (if overlay-arrow-position
1597 (set-marker overlay-arrow-position nil))
1598 (setq overlay-arrow-position nil
1599 overlay-arrow-string nil)
1600 (bury-buffer (get-buffer cscope-output-buffer-name))
1604 (defun cscope-quit ()
1605 (interactive)
1606 (cscope-bury-buffer)
1607 (kill-buffer cscope-output-buffer-name)
1610 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1612 (defun cscope-canonicalize-directory (dir)
1613 (or dir
1614 (setq dir default-directory))
1615 (setq dir (file-name-as-directory
1616 (expand-file-name (substitute-in-file-name dir))))
1621 (defun cscope-search-directory-hierarchy (directory)
1622 "Look for a cscope database in the directory hierarchy.
1623 Starting from DIRECTORY, look upwards for a cscope database."
1624 (let (this-directory database-dir)
1625 (catch 'done
1626 (if (file-regular-p directory)
1627 (throw 'done directory))
1628 (setq directory (cscope-canonicalize-directory directory)
1629 this-directory directory)
1630 (while this-directory
1631 (if (or (file-exists-p (concat this-directory cscope-database-file))
1632 (file-exists-p (concat this-directory cscope-index-file)))
1633 (progn
1634 (setq database-dir this-directory)
1635 (throw 'done database-dir)
1637 (if (string-match "^\\(/\\|[A-Za-z]:[\\/]\\)$" this-directory)
1638 (throw 'done directory))
1639 (setq this-directory (file-name-as-directory
1640 (file-name-directory
1641 (directory-file-name this-directory))))
1646 (defun cscope-find-info (top-directory)
1647 "Locate a suitable cscope database directory.
1648 First, `cscope-database-regexps' is used to search for a suitable
1649 database directory. If a database location cannot be found using this
1650 variable, then the current directory is searched, then the parent,
1651 then the parent's parent, until a cscope database directory is found,
1652 or the root directory is reached. If the root directory is reached,
1653 the current directory will be used."
1654 (let (info regexps dir-regexp this-directory)
1655 (setq top-directory (cscope-canonicalize-directory
1656 (or top-directory cscope-initial-directory)))
1657 (catch 'done
1658 ;; Try searching using `cscope-database-regexps' ...
1659 (setq regexps cscope-database-regexps)
1660 (while regexps
1661 (setq dir-regexp (car (car regexps)))
1662 (cond
1663 ( (stringp dir-regexp)
1664 (if (string-match dir-regexp top-directory)
1665 (progn
1666 (setq info (cdr (car regexps)))
1667 (throw 'done t)
1668 )) )
1669 ( (and (symbolp dir-regexp) dir-regexp)
1670 (progn
1671 (setq info (cdr (car regexps)))
1672 (throw 'done t)
1673 ) ))
1674 (setq regexps (cdr regexps))
1677 ;; Try looking in the directory hierarchy ...
1678 (if (setq this-directory
1679 (cscope-search-directory-hierarchy top-directory))
1680 (progn
1681 (setq info (list (list this-directory)))
1682 (throw 'done t)
1685 ;; Should we add any more places to look?
1687 ) ;; end catch
1688 (if (not info)
1689 (setq info (list (list top-directory))))
1690 info
1694 (defun cscope-make-entry-line (func-name line-number line)
1695 ;; The format of entry line:
1696 ;; func-name[line-number]______line
1697 ;; <- cscope-name-line-width ->
1698 ;; `format' of Emacs doesn't have "*s" spec.
1699 (let* ((fmt (format "%%%ds %%s" cscope-name-line-width))
1700 (str (format fmt (format "%s[%s]" func-name line-number) line))
1701 beg end)
1702 (if cscope-use-face
1703 (progn
1704 (setq end (length func-name))
1705 (put-text-property 0 end 'face 'cscope-function-face str)
1706 (setq beg (1+ end)
1707 end (+ beg (length line-number)))
1708 (put-text-property beg end 'face 'cscope-line-number-face str)
1709 (setq end (length str)
1710 beg (- end (length line)))
1711 (put-text-property beg end 'face 'cscope-line-face str)
1713 str))
1716 (defun cscope-process-filter (process output)
1717 "Accept cscope process output and reformat it for human readability.
1718 Magic text properties are added to allow the user to select lines
1719 using the mouse."
1720 (let ( (old-buffer (current-buffer)) )
1721 (unwind-protect
1722 (progn
1723 (set-buffer (process-buffer process))
1724 ;; Make buffer-read-only nil
1725 (let (buffer-read-only line file function-name line-number moving)
1726 (setq moving (= (point) (process-mark process)))
1727 (save-excursion
1728 (goto-char (process-mark process))
1729 ;; Get the output thus far ...
1730 (if cscope-process-output
1731 (setq cscope-process-output (concat cscope-process-output
1732 output))
1733 (setq cscope-process-output output))
1734 ;; Slice and dice it into lines.
1735 ;; While there are whole lines left ...
1736 (while (and cscope-process-output
1737 (string-match "\\([^\n]+\n\\)\\(\\(.\\|\n\\)*\\)"
1738 cscope-process-output))
1739 (setq file nil
1740 glimpse-stripped-directory nil
1742 ;; Get a line
1743 (setq line (substring cscope-process-output
1744 (match-beginning 1) (match-end 1)))
1745 (setq cscope-process-output (substring cscope-process-output
1746 (match-beginning 2)
1747 (match-end 2)))
1748 (if (= (length cscope-process-output) 0)
1749 (setq cscope-process-output nil))
1751 ;; This should always match.
1752 (if (string-match
1753 "^\\([^ \t]+\\)[ \t]+\\([^ \t]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\(.*\\)\n"
1754 line)
1755 (progn
1756 (let (str)
1757 (setq file (substring line (match-beginning 1)
1758 (match-end 1))
1759 function-name (substring line (match-beginning 2)
1760 (match-end 2))
1761 line-number (substring line (match-beginning 3)
1762 (match-end 3))
1763 line (substring line (match-beginning 4)
1764 (match-end 4))
1766 ;; If the current file is not the same as the previous
1767 ;; one ...
1768 (if (not (and cscope-last-file
1769 (string= file cscope-last-file)))
1770 (progn
1771 ;; The current file is different.
1773 ;; Insert a separating blank line if
1774 ;; necessary.
1775 (if cscope-last-file (insert "\n"))
1776 ;; Insert the file name
1777 (setq str (concat "*** " file ":"))
1778 (if cscope-use-face
1779 (put-text-property 0 (length str)
1780 'face 'cscope-file-face
1781 str))
1782 (cscope-insert-with-text-properties
1784 (expand-file-name file)
1785 ;; Yes, -1 is intentional
1787 (insert "\n")
1789 (if (not cscope-first-match)
1790 (setq cscope-first-match-point (point)))
1791 ;; ... and insert the line, with the
1792 ;; appropriate indentation.
1793 (cscope-insert-with-text-properties
1794 (cscope-make-entry-line function-name
1795 line-number
1796 line)
1797 (expand-file-name file)
1798 line-number)
1799 (insert "\n")
1800 (setq cscope-last-file file)
1801 (if cscope-first-match
1802 (setq cscope-matched-multiple t)
1803 (setq cscope-first-match
1804 (cons (expand-file-name file)
1805 (string-to-number line-number))))
1807 (insert line "\n")
1809 (set-marker (process-mark process) (point))
1811 (if moving
1812 (goto-char (process-mark process)))
1813 (set-buffer-modified-p nil)
1815 (set-buffer old-buffer))
1819 (defun cscope-process-sentinel (process event)
1820 "Sentinel for when the cscope process dies."
1821 (let* ( (buffer (process-buffer process)) window update-window
1822 (done t) (old-buffer (current-buffer))
1823 (old-buffer-window (get-buffer-window old-buffer)) )
1824 (set-buffer buffer)
1825 (save-window-excursion
1826 (save-excursion
1827 (if (or (and (setq window (get-buffer-window buffer))
1828 (= (window-point window) (point-max)))
1829 (= (point) (point-max)))
1830 (progn
1831 (setq update-window t)
1833 (delete-process process)
1834 (let (buffer-read-only continue)
1835 (goto-char (point-max))
1836 (if (and cscope-suppress-empty-matches
1837 (= cscope-output-start (point)))
1838 (delete-region cscope-item-start (point-max))
1839 (progn
1840 (if (not cscope-start-directory)
1841 (setq cscope-start-directory default-directory))
1842 (insert cscope-separator-line)
1844 (setq continue
1845 (and cscope-search-list
1846 (not (and cscope-first-match
1847 cscope-stop-at-first-match-dir
1848 (not cscope-stop-at-first-match-dir-meta)))))
1849 (if continue
1850 (setq continue (cscope-search-one-database)))
1851 (if continue
1852 (progn
1853 (setq done nil)
1855 (progn
1856 (insert "\nSearch complete.")
1857 (if cscope-display-times
1858 (let ( (times (current-time)) cscope-stop elapsed-time )
1859 (setq cscope-stop (+ (* (car times) 65536.0)
1860 (car (cdr times))
1861 (* (car (cdr (cdr times))) 1.0E-6)))
1862 (setq elapsed-time (- cscope-stop cscope-start-time))
1863 (insert (format " Search time = %.2f seconds."
1864 elapsed-time))
1866 (setq cscope-process nil)
1867 (if cscope-running-in-xemacs
1868 (setq modeline-process ": Search complete"))
1869 (if cscope-start-directory
1870 (setq default-directory cscope-start-directory))
1871 (if (not cscope-first-match)
1872 (message "No matches were found."))
1875 (set-buffer-modified-p nil)
1877 (if (and done cscope-first-match-point update-window)
1878 (if window
1879 (set-window-point window cscope-first-match-point)
1880 (goto-char cscope-first-match-point))
1882 (cond
1883 ( (not done) ;; we're not done -- do nothing for now
1884 (if update-window
1885 (if window
1886 (set-window-point window (point-max))
1887 (goto-char (point-max))))
1889 ( cscope-first-match
1890 (if cscope-display-cscope-buffer
1891 (if (and cscope-edit-single-match (not cscope-matched-multiple))
1892 (cscope-show-entry-internal(car cscope-first-match)
1893 (cdr cscope-first-match) t))
1894 (cscope-select-entry-specified-window old-buffer-window))
1897 (if (and done (eq old-buffer buffer) cscope-first-match)
1898 (cscope-help))
1899 (set-buffer old-buffer)
1903 (defun cscope-search-one-database ()
1904 "Pop a database entry from cscope-search-list and do a search there."
1905 (let ( next-item options cscope-directory database-file outbuf done
1906 base-database-file-name)
1907 (setq outbuf (get-buffer-create cscope-output-buffer-name))
1908 (save-excursion
1909 (catch 'finished
1910 (set-buffer outbuf)
1911 (setq options '("-L"))
1912 (while (and (not done) cscope-search-list)
1913 (setq next-item (car cscope-search-list)
1914 cscope-search-list (cdr cscope-search-list)
1915 base-database-file-name cscope-database-file
1917 (if (listp next-item)
1918 (progn
1919 (setq cscope-directory (car next-item))
1920 (if (not (stringp cscope-directory))
1921 (setq cscope-directory
1922 (cscope-search-directory-hierarchy
1923 default-directory)))
1924 (if (file-regular-p cscope-directory)
1925 (progn
1926 ;; Handle the case where `cscope-directory' is really
1927 ;; a full path name to a cscope database.
1928 (setq base-database-file-name
1929 (file-name-nondirectory cscope-directory)
1930 cscope-directory
1931 (file-name-directory cscope-directory))
1933 (setq cscope-directory
1934 (file-name-as-directory cscope-directory))
1935 (if (not (member cscope-directory cscope-searched-dirs))
1936 (progn
1937 (setq cscope-searched-dirs (cons cscope-directory
1938 cscope-searched-dirs)
1939 done t)
1942 (progn
1943 (if (and cscope-first-match
1944 cscope-stop-at-first-match-dir
1945 cscope-stop-at-first-match-dir-meta)
1946 (throw 'finished nil))
1949 (if (not done)
1950 (throw 'finished nil))
1951 (if (car (cdr next-item))
1952 (let (newopts)
1953 (setq newopts (car (cdr next-item)))
1954 (if (not (listp newopts))
1955 (error (format "Cscope options must be a list: %s" newopts)))
1956 (setq options (append options newopts))
1958 (if cscope-command-args
1959 (setq options (append options cscope-command-args)))
1960 (setq database-file (concat cscope-directory base-database-file-name)
1961 cscope-searched-dirs (cons cscope-directory
1962 cscope-searched-dirs)
1965 ;; The database file and the directory containing the database file
1966 ;; must both be writable.
1967 (if (or (not (file-writable-p database-file))
1968 (not (file-writable-p (file-name-directory database-file)))
1969 cscope-do-not-update-database)
1970 (setq options (cons "-d" options)))
1972 (goto-char (point-max))
1973 (setq cscope-item-start (point))
1974 (if (string= base-database-file-name cscope-database-file)
1975 (insert "\nDatabase directory: " cscope-directory "\n"
1976 cscope-separator-line)
1977 (insert "\nDatabase directory/file: "
1978 cscope-directory base-database-file-name "\n"
1979 cscope-separator-line))
1980 ;; Add the correct database file to search
1981 (setq options (cons base-database-file-name options))
1982 (setq options (cons "-f" options))
1983 (setq cscope-output-start (point))
1984 (setq default-directory cscope-directory)
1985 (if cscope-filter-func
1986 (progn
1987 (setq cscope-process-output nil
1988 cscope-last-file nil
1990 (setq cscope-process
1991 (apply 'start-process "cscope" outbuf
1992 cscope-program options))
1993 (set-process-filter cscope-process cscope-filter-func)
1994 (set-process-sentinel cscope-process cscope-sentinel-func)
1995 (set-marker (process-mark cscope-process) (point))
1996 (process-kill-without-query cscope-process)
1997 (if cscope-running-in-xemacs
1998 (setq modeline-process ": Searching ..."))
1999 (setq buffer-read-only t)
2001 (apply 'call-process cscope-program nil outbuf t options)
2008 (defun cscope-call (msg args &optional directory filter-func sentinel-func)
2009 "Generic function to call to process cscope requests.
2010 ARGS is a list of command-line arguments to pass to the cscope
2011 process. DIRECTORY is the current working directory to use (generally,
2012 the directory in which the cscope database is located, but not
2013 necessarily), if different that the current one. FILTER-FUNC and
2014 SENTINEL-FUNC are optional process filter and sentinel, respectively."
2015 (let ( (outbuf (get-buffer-create cscope-output-buffer-name))
2016 (old-buffer (current-buffer)) )
2017 (if cscope-process
2018 (error "A cscope search is still in progress -- only one at a time is allowed"))
2019 (setq directory (cscope-canonicalize-directory
2020 (or cscope-initial-directory directory)))
2021 (if (eq outbuf old-buffer) ;; In the *cscope* buffer.
2022 (if cscope-marker-window
2023 (progn
2024 ;; Assume that cscope-marker-window is the window, from the
2025 ;; users perspective, from which the search was launched and the
2026 ;; window that should be returned to upon cscope-pop-mark.
2027 (set-buffer (window-buffer cscope-marker-window))
2028 (setq cscope-marker (point-marker))
2029 (set-buffer old-buffer)))
2030 (progn ;; Not in the *cscope buffer.
2031 ;; Set the cscope-marker-window to whichever window this search
2032 ;; was launched from.
2033 (setq cscope-marker-window (get-buffer-window old-buffer))
2034 (setq cscope-marker (point-marker))))
2035 (save-excursion
2036 (set-buffer outbuf)
2037 (if cscope-display-times
2038 (let ( (times (current-time)) )
2039 (setq cscope-start-time (+ (* (car times) 65536.0) (car (cdr times))
2040 (* (car (cdr (cdr times))) 1.0E-6)))))
2041 (setq default-directory directory
2042 cscope-start-directory nil
2043 cscope-search-list (cscope-find-info directory)
2044 cscope-searched-dirs nil
2045 cscope-command-args args
2046 cscope-filter-func filter-func
2047 cscope-sentinel-func sentinel-func
2048 cscope-first-match nil
2049 cscope-first-match-point nil
2050 cscope-stop-at-first-match-dir-meta (memq t cscope-search-list)
2051 cscope-matched-multiple nil
2052 buffer-read-only nil)
2053 (buffer-disable-undo)
2054 (erase-buffer)
2055 (setq truncate-lines cscope-truncate-lines)
2056 (if msg
2057 (insert msg "\n"))
2058 (cscope-search-one-database)
2060 (if cscope-display-cscope-buffer
2061 (progn
2062 (pop-to-buffer outbuf)
2063 (cscope-help))
2064 (set-buffer outbuf))
2065 (goto-char (point-max))
2066 (cscope-list-entry-mode)
2070 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2072 (defvar cscope-unix-index-process-buffer-name "*cscope-indexing-buffer*"
2073 "The name of the buffer to use for displaying indexing status/progress.")
2076 (defvar cscope-unix-index-process-buffer nil
2077 "The buffer to use for displaying indexing status/progress.")
2080 (defvar cscope-unix-index-process nil
2081 "The current indexing process.")
2084 (defun cscope-unix-index-files-sentinel (process event)
2085 "Simple sentinel to print a message saying that indexing is finished."
2086 (let (buffer)
2087 (save-window-excursion
2088 (save-excursion
2089 (setq buffer (process-buffer process))
2090 (set-buffer buffer)
2091 (goto-char (point-max))
2092 (insert cscope-separator-line "\nIndexing finished\n")
2093 (delete-process process)
2094 (setq cscope-unix-index-process nil)
2095 (set-buffer-modified-p nil)
2100 (defun cscope-unix-index-files-internal (top-directory header-text args)
2101 "Core function to call the indexing script."
2102 (let ()
2103 (save-excursion
2104 (setq top-directory (cscope-canonicalize-directory top-directory))
2105 (setq cscope-unix-index-process-buffer
2106 (get-buffer-create cscope-unix-index-process-buffer-name))
2107 (display-buffer cscope-unix-index-process-buffer)
2108 (set-buffer cscope-unix-index-process-buffer)
2109 (setq buffer-read-only nil)
2110 (setq default-directory top-directory)
2111 (buffer-disable-undo)
2112 (erase-buffer)
2113 (if header-text
2114 (insert header-text))
2115 (setq args (append args
2116 (list "-v"
2117 "-i" cscope-index-file
2118 "-f" cscope-database-file
2119 (if cscope-use-relative-paths
2120 "." top-directory))))
2121 (if cscope-index-recursively
2122 (setq args (cons "-r" args)))
2123 (setq cscope-unix-index-process
2124 (apply 'start-process "cscope-indexer"
2125 cscope-unix-index-process-buffer
2126 cscope-indexing-script args))
2127 (set-process-sentinel cscope-unix-index-process
2128 'cscope-unix-index-files-sentinel)
2129 (process-kill-without-query cscope-unix-index-process)
2134 (defun cscope-index-files (top-directory)
2135 "Index files in a directory.
2136 This function creates a list of files to index, and then indexes
2137 the listed files.
2138 The variable, \"cscope-index-recursively\", controls whether or not
2139 subdirectories are indexed."
2140 (interactive "DIndex files in directory: ")
2141 (let ()
2142 (cscope-unix-index-files-internal
2143 top-directory
2144 (format "Creating cscope index `%s' in:\n\t%s\n\n%s"
2145 cscope-database-file top-directory cscope-separator-line)
2146 nil)
2150 (defun cscope-create-list-of-files-to-index (top-directory)
2151 "Create a list of files to index.
2152 The variable, \"cscope-index-recursively\", controls whether or not
2153 subdirectories are indexed."
2154 (interactive "DCreate file list in directory: ")
2155 (let ()
2156 (cscope-unix-index-files-internal
2157 top-directory
2158 (format "Creating cscope file list `%s' in:\n\t%s\n\n"
2159 cscope-index-file top-directory)
2160 '("-l"))
2164 (defun cscope-edit-list-of-files-to-index ()
2165 "Search for and edit the list of files to index.
2166 If this functions causes a new file to be edited, that means that a
2167 cscope.out file was found without a corresponding cscope.files file."
2168 (interactive)
2169 (let (info directory file)
2170 (setq info (cscope-find-info nil))
2171 (if (/= (length info) 1)
2172 (error "There is no unique cscope database directory!"))
2173 (setq directory (car (car info)))
2174 (if (not (stringp directory))
2175 (setq directory
2176 (cscope-search-directory-hierarchy default-directory)))
2177 (setq file (concat (file-name-as-directory directory) cscope-index-file))
2178 (find-file file)
2179 (message (concat "File: " file))
2183 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2185 (defun cscope-tell-user-about-directory ()
2186 "Display the name of the directory containing the cscope database."
2187 (interactive)
2188 (let (info directory)
2189 (setq info (cscope-find-info nil))
2190 (if (= (length info) 1)
2191 (progn
2192 (setq directory (car (car info)))
2193 (message (concat "Cscope directory: " directory))
2195 (let ( (outbuf (get-buffer-create cscope-info-buffer-name)) )
2196 (display-buffer outbuf)
2197 (save-excursion
2198 (set-buffer outbuf)
2199 (buffer-disable-undo)
2200 (erase-buffer)
2201 (insert "Cscope search directories:\n")
2202 (while info
2203 (if (listp (car info))
2204 (progn
2205 (setq directory (car (car info)))
2206 (if (not (stringp directory))
2207 (setq directory
2208 (cscope-search-directory-hierarchy
2209 default-directory)))
2210 (insert "\t" directory "\n")
2212 (setq info (cdr info))
2219 (defun cscope-dired-directory ()
2220 "Run dired upon the cscope database directory.
2221 If possible, the cursor is moved to the name of the cscope database
2222 file."
2223 (interactive)
2224 (let (info directory buffer p1 p2 pos)
2225 (setq info (cscope-find-info nil))
2226 (if (/= (length info) 1)
2227 (error "There is no unique cscope database directory!"))
2228 (setq directory (car (car info)))
2229 (if (not (stringp directory))
2230 (setq directory
2231 (cscope-search-directory-hierarchy default-directory)))
2232 (setq buffer (dired-noselect directory nil))
2233 (switch-to-buffer buffer)
2234 (set-buffer buffer)
2235 (save-excursion
2236 (goto-char (point-min))
2237 (setq p1 (search-forward cscope-index-file nil t))
2238 (if p1
2239 (setq p1 (- p1 (length cscope-index-file))))
2241 (save-excursion
2242 (goto-char (point-min))
2243 (setq p2 (search-forward cscope-database-file nil t))
2244 (if p2
2245 (setq p2 (- p2 (length cscope-database-file))))
2247 (cond
2248 ( (and p1 p2)
2249 (if (< p1 p2)
2250 (setq pos p1)
2251 (setq pos p2))
2253 ( p1
2254 (setq pos p1)
2256 ( p2
2257 (setq pos p2)
2260 (if pos
2261 (set-window-point (get-buffer-window buffer) pos))
2265 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2267 (defun cscope-extract-symbol-at-cursor (extract-filename)
2268 (let* ( (symbol-chars (if extract-filename
2269 cscope-filename-chars
2270 cscope-symbol-chars))
2271 (symbol-char-regexp (concat "[" symbol-chars "]"))
2273 (save-excursion
2274 (buffer-substring-no-properties
2275 (progn
2276 (if (not (looking-at symbol-char-regexp))
2277 (re-search-backward "\\w" nil t))
2278 (skip-chars-backward symbol-chars)
2279 (point))
2280 (progn
2281 (skip-chars-forward symbol-chars)
2282 (point)
2287 (defun cscope-prompt-for-symbol (prompt extract-filename)
2288 "Prompt the user for a cscope symbol."
2289 (let (sym)
2290 (setq sym (cscope-extract-symbol-at-cursor extract-filename))
2291 (if (or (not sym)
2292 (string= sym "")
2293 (not (and cscope-running-in-xemacs
2294 cscope-no-mouse-prompts current-mouse-event
2295 (or (mouse-event-p current-mouse-event)
2296 (misc-user-event-p current-mouse-event))))
2297 ;; Always prompt for symbol in dired mode.
2298 (eq major-mode 'dired-mode)
2300 (setq sym (read-from-minibuffer prompt sym))
2301 sym)
2305 (defun cscope-find-this-symbol (symbol)
2306 "Locate a symbol in source code."
2307 (interactive (list
2308 (cscope-prompt-for-symbol "Find this symbol: " nil)
2310 (let ( (cscope-adjust t) ) ;; Use fuzzy matching.
2311 (setq cscope-symbol symbol)
2312 (cscope-call (format "Finding symbol: %s" symbol)
2313 (list "-0" symbol) nil 'cscope-process-filter
2314 'cscope-process-sentinel)
2318 (defun cscope-find-global-definition (symbol)
2319 "Find a symbol's global definition."
2320 (interactive (list
2321 (cscope-prompt-for-symbol "Find this global definition: " nil)
2323 (let ( (cscope-adjust t) ) ;; Use fuzzy matching.
2324 (setq cscope-symbol symbol)
2325 (cscope-call (format "Finding global definition: %s" symbol)
2326 (list "-1" symbol) nil 'cscope-process-filter
2327 'cscope-process-sentinel)
2331 (defun cscope-find-global-definition-no-prompting ()
2332 "Find a symbol's global definition without prompting."
2333 (interactive)
2334 (let ( (symbol (cscope-extract-symbol-at-cursor nil))
2335 (cscope-adjust t) ) ;; Use fuzzy matching.
2336 (setq cscope-symbol symbol)
2337 (cscope-call (format "Finding global definition: %s" symbol)
2338 (list "-1" symbol) nil 'cscope-process-filter
2339 'cscope-process-sentinel)
2343 (defun cscope-find-called-functions (symbol)
2344 "Display functions called by a function."
2345 (interactive (list
2346 (cscope-prompt-for-symbol
2347 "Find functions called by this function: " nil)
2349 (let ( (cscope-adjust nil) ) ;; Disable fuzzy matching.
2350 (setq cscope-symbol symbol)
2351 (cscope-call (format "Finding functions called by: %s" symbol)
2352 (list "-2" symbol) nil 'cscope-process-filter
2353 'cscope-process-sentinel)
2357 (defun cscope-find-functions-calling-this-function (symbol)
2358 "Display functions calling a function."
2359 (interactive (list
2360 (cscope-prompt-for-symbol
2361 "Find functions calling this function: " nil)
2363 (let ( (cscope-adjust t) ) ;; Use fuzzy matching.
2364 (setq cscope-symbol symbol)
2365 (cscope-call (format "Finding functions calling: %s" symbol)
2366 (list "-3" symbol) nil 'cscope-process-filter
2367 'cscope-process-sentinel)
2371 (defun cscope-find-this-text-string (symbol)
2372 "Locate where a text string occurs."
2373 (interactive (list
2374 (cscope-prompt-for-symbol "Find this text string: " nil)
2376 (let ( (cscope-adjust t) ) ;; Use fuzzy matching.
2377 (setq cscope-symbol symbol)
2378 (cscope-call (format "Finding text string: %s" symbol)
2379 (list "-4" symbol) nil 'cscope-process-filter
2380 'cscope-process-sentinel)
2384 (defun cscope-find-egrep-pattern (symbol)
2385 "Run egrep over the cscope database."
2386 (interactive (list
2387 (let (cscope-no-mouse-prompts)
2388 (cscope-prompt-for-symbol "Find this egrep pattern: " nil))
2390 (let ( (cscope-adjust t) ) ;; Use fuzzy matching.
2391 (setq cscope-symbol symbol)
2392 (cscope-call (format "Finding egrep pattern: %s" symbol)
2393 (list "-6" symbol) nil 'cscope-process-filter
2394 'cscope-process-sentinel)
2398 (defun cscope-find-this-file (symbol)
2399 "Locate a file."
2400 (interactive (list
2401 (let (cscope-no-mouse-prompts)
2402 (cscope-prompt-for-symbol "Find this file: " t))
2404 (let ( (cscope-adjust nil) ) ;; Disable fuzzy matching.
2405 (setq cscope-symbol symbol)
2406 (cscope-call (format "Finding file: %s" symbol)
2407 (list "-7" symbol) nil 'cscope-process-filter
2408 'cscope-process-sentinel)
2412 (defun cscope-find-files-including-file (symbol)
2413 "Locate all files #including a file."
2414 (interactive (list
2415 (let (cscope-no-mouse-prompts)
2416 (cscope-prompt-for-symbol
2417 "Find files #including this file: " t))
2419 (let ( (cscope-adjust t) ) ;; Use fuzzy matching.
2420 (setq cscope-symbol symbol)
2421 (cscope-call (format "Finding files #including file: %s" symbol)
2422 (list "-8" symbol) nil 'cscope-process-filter
2423 'cscope-process-sentinel)
2427 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2429 (defvar cscope-minor-mode nil
2431 (make-variable-buffer-local 'cscope-minor-mode)
2432 (put 'cscope-minor-mode 'permanent-local t)
2435 (defun cscope-minor-mode (&optional arg)
2437 (progn
2438 (setq cscope-minor-mode (if (null arg) t (car arg)))
2439 (if cscope-minor-mode
2440 (progn
2441 (easy-menu-add cscope:menu cscope:map)
2442 (run-hooks 'cscope-minor-mode-hooks)
2444 cscope-minor-mode
2448 (defun cscope:hook ()
2450 (progn
2451 (cscope-minor-mode)
2455 (or (assq 'cscope-minor-mode minor-mode-map-alist)
2456 (setq minor-mode-map-alist (cons (cons 'cscope-minor-mode cscope:map)
2457 minor-mode-map-alist)))
2459 (add-hook 'c-mode-hook (function cscope:hook))
2460 (add-hook 'c++-mode-hook (function cscope:hook))
2461 (add-hook 'dired-mode-hook (function cscope:hook))
2463 (provide 'xcscope)