Mercurial > hg > xemacs-beta
comparison lisp/utils/speedbar.el @ 167:85ec50267440 r20-3b10
Import from CVS: tag r20-3b10
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:45:46 +0200 |
parents | 4be1180a9e89 |
children | 6075d714658b |
comparison
equal
deleted
inserted
replaced
166:7a77eb660975 | 167:85ec50267440 |
---|---|
1 ;;; speedbar - quick access to files and tags | 1 ;;; speedbar --- quick access to files and tags -*-byte-compile-warnings:nil;-*- |
2 ;;; | 2 |
3 ;;; Copyright (C) 1996 Eric M. Ludlam | 3 ;; Copyright (C) 1996, 1997 Eric M. Ludlam |
4 ;;; | 4 ;; |
5 ;;; Author: Eric M. Ludlam <zappo@gnu.ai.mit.edu> | 5 ;; Author: Eric M. Ludlam <zappo@gnu.ai.mit.edu> |
6 ;;; RCS: $Id: speedbar.el,v 1.1 1997/02/17 06:40:14 steve Exp $ | 6 ;; Version: 0.5 |
7 ;;; Version: 0.3.1 | 7 ;; Keywords: file, tags, tools |
8 ;;; Keywords: file, tags, tools | 8 ;; X-RCS: $Id: speedbar.el,v 1.2 1997/06/29 23:13:33 steve Exp $ |
9 ;;; | 9 ;; |
10 ;;; This program is free software; you can redistribute it and/or modify | 10 ;; This program is free software; you can redistribute it and/or modify |
11 ;;; it under the terms of the GNU General Public License as published by | 11 ;; it under the terms of the GNU General Public License as published by |
12 ;;; the Free Software Foundation; either version 2, or (at your option) | 12 ;; the Free Software Foundation; either version 2, or (at your option) |
13 ;;; any later version. | 13 ;; any later version. |
14 ;;; | 14 ;; |
15 ;;; This program is distributed in the hope that it will be useful, | 15 ;; This program is distributed in the hope that it will be useful, |
16 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 ;;; GNU General Public License for more details. | 18 ;; GNU General Public License for more details. |
19 ;;; | 19 ;; |
20 ;;; You should have received a copy of the GNU General Public License | 20 ;; You should have received a copy of the GNU General Public License |
21 ;;; along with this program; if not, you can either send email to this | 21 ;; along with this program; if not, you can either send email to this |
22 ;;; program's author (see below) or write to: | 22 ;; program's author (see below) or write to: |
23 ;;; | 23 ;; |
24 ;;; The Free Software Foundation, Inc. | 24 ;; The Free Software Foundation, Inc. |
25 ;;; 675 Mass Ave. | 25 ;; 675 Mass Ave. |
26 ;;; Cambridge, MA 02139, USA. | 26 ;; Cambridge, MA 02139, USA. |
27 ;;; | 27 ;; |
28 ;;; Please send bug reports, etc. to zappo@gnu.ai.mit.edu. | 28 ;; Please send bug reports, etc. to zappo@gnu.ai.mit.edu. |
29 ;;; | 29 ;; |
30 | 30 |
31 ;;; Commentary: | 31 ;;; Commentary: |
32 ;;; | 32 ;; |
33 ;;; The speedbar provides a frame in which files, and locations in | 33 ;; The speedbar provides a frame in which files, and locations in |
34 ;;; files are displayed. These items can be clicked on with mouse-2 | 34 ;; files are displayed. These items can be clicked on with mouse-2 |
35 ;;; in order to make the last active frame display that file location. | 35 ;; in order to make the last active frame display that file location. |
36 ;;; | 36 ;; |
37 ;;; If you want to choose it from a menu or something, do this: | 37 ;; To use speedbar, add this to your .emacs file: |
38 ;;; | 38 ;; |
39 ;;; (autoload 'speedbar-frame-mode "speedbar" "Popup a speedbar frame" t) | 39 ;; (autoload 'speedbar-frame-mode "speedbar" "Popup a speedbar frame" t) |
40 ;;; (define-key-after (lookup-key global-map [menu-bar tools]) | 40 ;; (autoload 'speedbar-get-focus "speedbar" "Jump to speedbar frame" t) |
41 ;;; [speedbar] '("Speedbar" . speedbar-frame-mode) [calendar]) | 41 ;; |
42 ;;; | 42 ;; If you want to choose it from a menu or something, do this: |
43 ;;; To activate speedbar without the menu, type: M-x speedbar-frame-mode RET | 43 ;; |
44 ;;; | 44 ;; (define-key-after (lookup-key global-map [menu-bar tools]) |
45 ;;; Once a speedbar frame is active, it takes advantage of idle time | 45 ;; [speedbar] '("Speedbar" . speedbar-frame-mode) [calendar]) |
46 ;;; to keep it's contents updated. The contents is usually a list of | 46 ;; |
47 ;;; files in the directory of the currently active buffer. When | 47 ;; If you want to access speedbar using only the keyboard, do this: |
48 ;;; applicable, tags in the active file can be expanded. | 48 ;; |
49 ;;; | 49 ;; (define-key global-map [f4] 'speedbar-get-focus) |
50 ;;; Speedbar uses multiple methods for creating tags to jump to. | 50 ;; |
51 ;;; When the variable `speedbar-use-imenu-package' is set, then | 51 ;; This will let you hit f4 (or whatever key you choose) to jump |
52 ;;; speedbar will first try to use imenu to get tags. If the mode of | 52 ;; focus to the speedbar frame. Pressing RET or e to jump to a file |
53 ;;; the buffer doesn't support imenu, then etags is used. Using Imenu | 53 ;; or tag will move you back to the attached frame. The command |
54 ;;; has the advantage that tags are cached, so opening and closing | 54 ;; `speedbar-get-fucus' will also create a speedbar frame if it does |
55 ;;; tags lists is faster. Speedbar-imenu will also load the file into | 55 ;; not exist. |
56 ;;; a non-selected buffer so clicking the file later will be faster. | 56 ;; |
57 ;;; | 57 ;; Once a speedbar frame is active, it takes advantage of idle time |
58 ;;; To add new files types into the speedbar, modify | 58 ;; to keep it's contents updated. The contents is usually a list of |
59 ;;; `speedbar-file-regexp' to include the extension of the file type | 59 ;; files in the directory of the currently active buffer. When |
60 ;;; you wish to include. If speedbar complains that the file type is | 60 ;; applicable, tags in the active file can be expanded. |
61 ;;; not supported, that means there is no built in support from imenu, | 61 ;; |
62 ;;; and the etags part wasn't set up right. | 62 ;; To add new supported files types into speedbar, use the function |
63 ;;; | 63 ;; `speedbar-add-supported-extension' If speedbar complains that the |
64 ;;; To add new file types to imenu, see the documentation in the | 64 ;; file type is not supported, that means there is no built in |
65 ;;; file imenu.el that comes with emacs. To add new file types which | 65 ;; support from imenu, and the etags part wasn't set up correctly. You |
66 ;;; etags supports, you need to modify the variable | 66 ;; may add elements to `speedbar-supported-extension-expressions' as long |
67 ;;; `speedbar-fetch-etags-parse-list'. This variable is an | 67 ;; as it is done before speedbar is loaded. |
68 ;;; association list with each element of the form: (extension-regex | 68 ;; |
69 ;;; . parse-one-line) The extension-regex would be something like | 69 ;; To prevent speedbar from following you into certain directories |
70 ;;; "\\.c$" for a .c file, and the parse-one-line would be either a | 70 ;; use the function `speedbar-add-ignored-path-regexp' too add a new |
71 ;;; regular expression where match tag 1 is the element you wish | 71 ;; regular expression matching a type of path. You may add list |
72 ;;; displayed as a tag. If you need to do something more complex, | 72 ;; elements to `speedbar-ignored-path-expressions' as long as it is |
73 ;;; then you can also write a function which parses one line, and put | 73 ;; done before speedbar is loaded. |
74 ;;; its symbol there instead. | 74 ;; |
75 ;;; | 75 ;; To add new file types to imenu, see the documentation in the |
76 ;;; If the updates are going to slow for you, modify the variable | 76 ;; file imenu.el that comes with emacs. To add new file types which |
77 ;;; `speedbar-update-speed' to a longer idle time before updates. | 77 ;; etags supports, you need to modify the variable |
78 ;;; | 78 ;; `speedbar-fetch-etags-parse-list'. |
79 ;;; If you navigate directories, you will probably notice that you | 79 ;; |
80 ;;; will navigate to a directory which is eventually replaced after | 80 ;; If the updates are going too slow for you, modify the variable |
81 ;;; you go back to editing a file (unless you pull up a new file.) | 81 ;; `speedbar-update-speed' to a longer idle time before updates. |
82 ;;; The delay time before this happens is in | 82 ;; |
83 ;;; `speedbar-navigating-speed', and defaults to 20 seconds. | 83 ;; If you navigate directories, you will probably notice that you |
84 ;;; | 84 ;; will navigate to a directory which is eventually replaced after |
85 ;;; XEmacs users may want to change the default timeouts for | 85 ;; you go back to editing a file (unless you pull up a new file.) |
86 ;;; `speedbar-update-speed' to something longer as XEmacs doesn't have | 86 ;; The delay time before this happens is in |
87 ;;; idle timers, the speedbar timer keeps going off arbitrarilly while | 87 ;; `speedbar-navigating-speed', and defaults to 10 seconds. |
88 ;;; you're typing. It's quite pesky. | 88 ;; |
89 ;;; | 89 ;; XEmacs users may want to change the default timeouts for |
90 ;;; To get speedbar-configure-faces to work, you will need to | 90 ;; `speedbar-update-speed' to something longer as XEmacs doesn't have |
91 ;;; download my eieio package from my ftp site. | 91 ;; idle timers, the speedbar timer keeps going off arbitrarilly while |
92 ;;; | 92 ;; you're typing. It's quite pesky. |
93 ;;; EIEIO is NOT required when using speedbar. It is ONLY needed | 93 ;; |
94 ;;; if you want to use a fancy dialog face editor for speedbar. | 94 ;; Users of emacs previous to to v 19.31 (when idle timers |
95 ;; where introduced) will not have speedbar updating automatically. | |
96 ;; Use "r" to refresh the display after changing directories. | |
97 ;; Remember, do not interrupt the stealthy updates or you display may | |
98 ;; not be completely refreshed. | |
99 ;; | |
100 ;; See optional file `speedbspec.el' for additional configurations | |
101 ;; which allow speedbar to create specialized lists for special modes | |
102 ;; that are not file-related. | |
103 ;; | |
104 ;; See optional file `speedbcfg.el' for interactive buffers | |
105 ;; allowing simple configuration of colors and features of speedbar. | |
106 ;; | |
107 ;; AUC-TEX users: The imenu tags for AUC-TEX mode don't work very | |
108 ;; well. Use the imenu keywords from tex-mode.el for better results. | |
109 ;; | |
110 ;; This file requires the library package assoc (association lists) | |
95 | 111 |
96 ;;; Speedbar updates can be found at: | 112 ;;; Speedbar updates can be found at: |
97 ;;; ftp://ftp.ultranet.com/pub/zappo/speedbar.*.el | 113 ;; ftp://ftp.ultranet.com/pub/zappo/speedbar*.tar.gz |
98 ;;; | 114 ;; |
99 | 115 |
100 ;;; HISTORY: | 116 ;;; Change log: |
101 ;;; 0.1 Initial Revision | 117 ;; 0.1 Initial Revision |
102 ;;; 0.2 Fixed problem with x-pointer-shape causing future frames not | 118 ;; 0.2 Fixed problem with x-pointer-shape causing future frames not |
103 ;;; to be created. | 119 ;; to be created. |
104 ;;; Fixed annoying habit of `speedbar-update-contents' to make | 120 ;; Fixed annoying habit of `speedbar-update-contents' to make |
105 ;;; it possible to accidentally kill the speedbar buffer. | 121 ;; it possible to accidentally kill the speedbar buffer. |
106 ;;; Clicking directory names now only changes the contents of | 122 ;; Clicking directory names now only changes the contents of |
107 ;;; the speedbar, and does not cause a dired mode to appear. | 123 ;; the speedbar, and does not cause a dired mode to appear. |
108 ;;; Clicking the <+> next to the directory does cause dired to | 124 ;; Clicking the <+> next to the directory does cause dired to |
109 ;;; be run. | 125 ;; be run. |
110 ;;; Added XEmacs support, which means timer support moved to a | 126 ;; Added XEmacs support, which means timer support moved to a |
111 ;;; platform independant call. | 127 ;; platform independant call. |
112 ;;; Added imenu support. Now modes are supported by imenu | 128 ;; Added imenu support. Now modes are supported by imenu |
113 ;;; first, and etags only if the imenu call doesn't work. | 129 ;; first, and etags only if the imenu call doesn't work. |
114 ;;; Imenu is a little faster than etags, and is more emacs | 130 ;; Imenu is a little faster than etags, and is more emacs |
115 ;;; friendly. | 131 ;; friendly. |
116 ;;; Added more user control variables described in the commentary. | 132 ;; Added more user control variables described in the commentary. |
117 ;;; Added smart recentering when nodes are opened and closed. | 133 ;; Added smart recentering when nodes are opened and closed. |
118 ;;; 0.3 x-pointer-shape fixed for emacs 19.35, so I put that check in. | 134 ;; 0.3 x-pointer-shape fixed for emacs 19.35, so I put that check in. |
119 ;;; Added invisible codes to the beginning of each line. | 135 ;; Added invisible codes to the beginning of each line. |
120 ;;; Added list aproach to node expansion for easier addition of new | 136 ;; Added list aproach to node expansion for easier addition of new |
121 ;;; types of things to expand by | 137 ;; types of things to expand by |
122 ;;; Added multi-level path name support | 138 ;; Added multi-level path name support |
123 ;;; Added multi-level tag name support. | 139 ;; Added multi-level tag name support. |
124 ;;; Only mouse-2 is now used for node expansion | 140 ;; Only mouse-2 is now used for node expansion |
125 ;;; Added keys e + - to edit expand, and contract node lines | 141 ;; Added keys e + - to edit expand, and contract node lines |
126 ;;; Added longer legal file regexp for all those modes which support | 142 ;; Added longer legal file regexp for all those modes which support |
127 ;;; imenu. (pascal, fortran90, ada, pearl) | 143 ;; imenu. (pascal, fortran90, ada, pearl) |
128 ;;; Fixed centering algorithm | 144 ;; Added pascal support to etags from Dave Penkler <dave_penkler@grenoble.hp.com> |
129 ;;; Tried to choose background independent colors. Made more robust. | 145 ;; Fixed centering algorithm |
130 ;;; Rearranged code into a more logical order | 146 ;; Tried to choose background independent colors. Made more robust. |
131 ;;; 0.3.1 Fixed doc & broken keybindings | 147 ;; Rearranged code into a more logical order |
132 ;;; Added mode hooks. | 148 ;; 0.3.1 Fixed doc & broken keybindings |
133 ;;; Improved color selection to be background mode smart | 149 ;; Added mode hooks. |
134 ;;; `nil' passed to `speedbar-frame-mode' now toggles the frame as | 150 ;; Improved color selection to be background mode smart |
135 ;;; advertised in the doc string | 151 ;; `nil' passed to `speedbar-frame-mode' now toggles the frame as |
136 ;;; | 152 ;; advertised in the doc string |
153 ;; 0.4a Added modified patch from Dan Schmidt <dfan@lglass.com> allowing a | |
154 ;; directory cache to be maintained speeding up revisiting of files. | |
155 ;; Default raise-lower behavior is now off by default. | |
156 ;; Added some menu items for edit expand and contract. | |
157 ;; Pre 19.31 emacsen can run without idle timers. | |
158 ;; Added some patch information from Farzin Guilak <farzin@protocol.com> | |
159 ;; adding xemacs specifics, and some etags upgrades. | |
160 ;; Added ability to set a faces symbol-value to a string | |
161 ;; representing the desired foreground color. (idea from | |
162 ;; Farzin Guilak, but implemented differently) | |
163 ;; Fixed problem with 1 character buttons. | |
164 ;; Added support for new Imenu marker technique. | |
165 ;; Added `speedbar-load-hooks' for things to run only once on | |
166 ;; load such as updating one of the many lists. | |
167 ;; Added `speedbar-supported-extension-expressions' which is a | |
168 ;; list of extensions that speedbar will tag. This variable | |
169 ;; should only be updated with `speedbar-add-supported-extension' | |
170 ;; Moved configure dialog support to a separate file so | |
171 ;; speedbar is not dependant on eieio to run | |
172 ;; Fixed list-contraction problem when the item was at the end | |
173 ;; of a sublist. | |
174 ;; Fixed XEmacs multi-frame timer selecting bug problem. | |
175 ;; Added `speedbar-ignored-modes' which is a list of major modes | |
176 ;; speedbar will not follow when it is displayed in the selected frame | |
177 ;; 0.4 When the file being edited is not in the list, and is a file | |
178 ;; that should be in the list, the speedbar cache is replaced. | |
179 ;; Temp buffers are now shown in the attached frame not the | |
180 ;; speedbar frame | |
181 ;; New variables `speedbar-vc-*' and `speedbar-stealthy-function-list' | |
182 ;; added. `speedbar-update-current-file' is now a member of | |
183 ;; the stealthy list. New function `speedbar-check-vc' will | |
184 ;; examine each file and mark it if it is checked out. To | |
185 ;; add new version control types, override the function | |
186 ;; `speedbar-this-file-in-vc' and `speedbar-vc-check-dir-p'. | |
187 ;; The stealth list is interruptible so that long operations | |
188 ;; do not interrupt someones editing flow. Other long | |
189 ;; speedbar updates will be added to the stealthy list in the | |
190 ;; future should interesting ones be needed. | |
191 ;; Added many new functions including: | |
192 ;; `speedbar-item-byte-compile' `speedbar-item-load' | |
193 ;; `speedbar-item-copy' `speedbar-item-rename' `speedbar-item-delete' | |
194 ;; and `speedbar-item-info' | |
195 ;; If the user kills the speedbar buffer in some way, the frame will | |
196 ;; be removed. | |
197 ;; 0.4.1 Bug fixes | |
198 ;; <mark.jeffries@nomura.co.uk> added `speedbar-update-flag', | |
199 ;; XEmacs fixes for menus, and tag sorting, and quit key. | |
200 ;; Modeline now updates itself based on window-width. | |
201 ;; Frame is cached when closed to make pulling it up again faster. | |
202 ;; Speedbars window is now marked as dedicated. | |
203 ;; Added bindings: <grossjoh@charly.informatik.uni-dortmund.de> | |
204 ;; Long directories are now span multiple lines autmoatically | |
205 ;; Added `speedbar-directory-button-trim-method' to specify how to | |
206 ;; sorten the directory button to fit on the screen. | |
207 ;; 0.4.2 Add one level of full-text cache. | |
208 ;; Add `speedbar-get-focus' to switchto/raise the speedbar frame. | |
209 ;; Editing thing-on-line will auto-raise the attached frame. | |
210 ;; Bound `U' to `speedbar-up-directory' command. | |
211 ;; Refresh will now maintain all subdirectories that were open | |
212 ;; when the refresh was requested. (This does not include the | |
213 ;; tags, only the directories) | |
214 ;; 0.4.3 Bug fixes | |
215 ;; 0.4.4 Added `speedbar-ignored-path-expressions' and friends. | |
216 ;; Configuration menu items not displayed if dialog-mode not present | |
217 ;; Speedbar buffer now starts with a space, and is not deleted | |
218 ;; ewhen the speedbar frame is closed. This prevents the invisible | |
219 ;; frame from preventing buffer switches with other buffers. | |
220 ;; Fixed very bad bug in the -add-[extension|path] functions. | |
221 ;; Added `speedbar-find-file-in-frame' which will always pop up a frame | |
222 ;; that is already display a buffer selected in the speedbar buffer. | |
223 ;; Added S-mouse2 as "power click" for always poping up a new frame. | |
224 ;; and always rescanning with imenu (ditching the imenu cache), and | |
225 ;; always rescanning directories. | |
226 ;; 0.4.5 XEmacs bugfixes and enhancements. | |
227 ;; Window Title simplified. | |
228 ;; 0.4.6 Fixed problems w/ dedicated minibuffer frame. | |
229 ;; Fixed errors reported by checkdoc. | |
230 ;; 0.5 Mode-specific contents added. Controlled w/ the variable | |
231 ;; `speedbar-mode-specific-contents-flag'. See speedbspec | |
232 ;; for info on enabling this feature. | |
233 ;; `speedbar-load-hook' name change and pointer check against | |
234 ;; major-mode. Suggested by Sam Steingold <sds@ptc.com> | |
235 ;; Quit auto-selects the attached frame. | |
236 ;; Ranamed `speedbar-do-updates' to `speedbar-update-flag' | |
237 ;; Passes checkdoc. | |
238 | |
137 ;;; TODO: | 239 ;;; TODO: |
138 ;;; 1) Rember contents of directories when leaving them so it's faster | 240 ;; 1) More functions to create buttons and options |
139 ;;; when returning. | 241 ;; 2) filtering algoritms to reduce the number of tags/files displayed. |
140 ;;; 2) List of directories to never visit. (User might be browsing | 242 ;; 3) Timeout directories we haven't visited in a while. |
141 ;;; there temporarilly such as info files, documentation and the | 243 ;; 4) Remeber tags when refreshing the display. (Refresh tags too?) |
142 ;;; like) | 244 ;; 5) More 'special mode support. |
143 ;;; 3) Implement SHIFT-mouse2 to rescan buffers with imenu. | 245 ;; 6) Smart way to auto-expand instead of directory switch |
144 ;;; 4) Better XEmacs support of menus and button-bar | 246 |
145 ;;; 5) More functions to create buttons and options | 247 ;;; Code: |
146 ;;; 6) filtering algoritms to reduce the number of tags/files | 248 (require 'assoc) |
147 ;;; displayed. | 249 (require 'easymenu) |
148 ;;; 7) Build `speedbar-file-regexp' on the fly. | 250 |
149 ;;; 8) More intelligent current file highlighting. | 251 (defvar speedbar-xemacsp (string-match "XEmacs" emacs-version) |
150 | 252 "Non-nil if we are running in the XEmacs environment.") |
151 (defvar speedbar-xemacsp (string-match "XEmacs" emacs-version)) | |
152 | 253 |
153 (defvar speedbar-initial-expansion-list | 254 (defvar speedbar-initial-expansion-list |
154 '(speedbar-directory-buttons speedbar-default-directory-list) | 255 '(speedbar-directory-buttons speedbar-default-directory-list) |
155 "*List of functions to call to fill in the speedbar buffer whenever | 256 "List of functions to call to fill in the speedbar buffer. |
156 a top level update is issued. These functions will allways get the | 257 Whenever a top level update is issued all functions in this list are |
157 default directory to use passed in as the first parameter, and a 0 as | 258 run. These functions will always get the default directory to use |
158 the second parameter. They must assume that the cursor is at the | 259 passed in as the first parameter, and a 0 as the second parameter. |
159 postion where they start inserting buttons.") | 260 The 0 indicates the uppermost indentation level. They must assume |
261 that the cursor is at the position where they start inserting | |
262 buttons.") | |
263 | |
264 (defvar speedbar-stealthy-function-list | |
265 '(speedbar-update-current-file speedbar-check-vc) | |
266 "List of functions to periodically call stealthily. | |
267 Each function must return nil if interrupted, or t if completed. | |
268 Stealthy functions which have a single operation should always return | |
269 t. Functions which take a long time should maintain a state (where | |
270 they are in their speedbar related calculations) and permit | |
271 interruption. See `speedbar-check-vc' as a good example.") | |
272 | |
273 (defvar speedbar-mode-specific-contents-flag t | |
274 "*Non-nil means speedbar will show specail-mode contents. | |
275 This permits some modes to create customized contents for the speedbar | |
276 frame.") | |
277 | |
278 (defvar speedbar-special-mode-expansion-list nil | |
279 "Mode specific list of functions to call to fill in speedbar. | |
280 Some modes, such as Info or RMAIL, do not relate quite as easily into | |
281 a simple list of files. When this variable is non-nil and buffer-local, | |
282 then these functions are used, creating specialized contents. These | |
283 functions are called each time the speedbar timer is called. This | |
284 allows a mode to update it's contents regularly. | |
285 | |
286 Each function is called with the default and frame belonging to | |
287 speedbar, and with one parameter; the buffer requesting | |
288 the speedbar display.") | |
289 | |
290 (defvar speedbar-load-hook nil | |
291 "Hooks run when speedbar is loaded.") | |
292 | |
293 (defvar speedbar-desired-buffer nil | |
294 "Non-nil when speedbar is showing buttons specific a special mode. | |
295 In this case it is the originating buffer.") | |
160 | 296 |
161 (defvar speedbar-show-unknown-files nil | 297 (defvar speedbar-show-unknown-files nil |
162 "*Non-nil shows files with a ? in the expansion tag for files we can't | 298 "*Non-nil show files we can't expand with a ? in the expand button. |
163 expand. `nil' means don't show the file in the list.") | 299 nil means don't show the file in the list.") |
164 | 300 |
165 ;; Xemacs timers aren't based on idleness. Therefore tune it down a little | 301 ;; Xemacs timers aren't based on idleness. Therefore tune it down a little |
166 ;; or suffer mightilly! | 302 ;; or suffer mightilly! |
167 (defvar speedbar-update-speed (if speedbar-xemacsp 5 1) | 303 (defvar speedbar-update-speed (if speedbar-xemacsp 5 1) |
168 "*Time in seconds of idle time needed before speedbar will update | 304 "*Idle time in seconds needed before speedbar will update itself. |
169 it's buffer to match what you've been doing in your other frame.") | 305 Updates occur to allow speedbar to display directory information |
306 relevant to the buffer you are currently editing.") | |
170 (defvar speedbar-navigating-speed 10 | 307 (defvar speedbar-navigating-speed 10 |
171 "*Idle time to wait before re-running the timer proc to pick up any new | 308 "*Idle time to wait after navigation commands in speedbar are executed. |
172 activity if the user has started navigating directories in the speedbar.") | 309 Navigation commands included expanding/contracting nodes, and moving |
173 | 310 between different directories.") |
174 (defvar speedbar-width 20 | 311 |
175 "*Initial size of the speedbar window") | 312 (defvar speedbar-frame-parameters (list |
176 | 313 ;; Xemacs fails to delete speedbar |
177 (defvar speedbar-scrollbar-width 10 | 314 ;; if minibuffer is off. |
178 "*Initial sizeo of the speedbar scrollbar. The thinner, the more | 315 ;(cons 'minibuffer |
179 display room you will have.") | 316 ; (if speedbar-xemacsp t nil)) |
180 | 317 ;; The above behavior seems to have fixed |
181 (defvar speedbar-raise-lower t | 318 ;; itself somewhere along the line. |
182 "*Non-nil means speedbar will auto raise and lower itself. When this | 319 ;; let me know if any problems arise. |
183 is set, you can have only a tiny strip visible under your main emacs, | 320 '(minibuffer . nil) |
184 and it will raise and lower itself when you put the pointer in it.") | 321 '(width . 20) |
185 | 322 '(scroll-bar-width . 10) |
186 (defvar speedbar-use-imenu-package (not speedbar-xemacsp) | 323 '(border-width . 0) |
187 "*Optionally use the imenu package instead of etags for parsing. This | 324 '(unsplittable . t) ) |
188 is experimental for performace testing.") | 325 "*Parameters to use when creating the speedbar frame. |
326 Parameters not listed here which will be added automatically are | |
327 `height' which will be initialized to the height of the frame speedbar | |
328 is attached to. To add more frame defaults, `cons' new alist members | |
329 onto this variable through the `speedbar-load-hook'") | |
330 | |
331 (defvar speedbar-use-imenu-flag (stringp (locate-library "imenu")) | |
332 "*Non-nil means use imenu for file parsing. nil to use etags. | |
333 XEmacs doesn't support imenu, therefore the default is to use etags | |
334 instead. Etags support is not as robust as imenu support.") | |
335 | |
336 (defvar speedbar-sort-tags nil | |
337 "*If Non-nil, sort tags in the speedbar display. (Etags only) | |
338 See imenu.el source for how imenu does sorting.") | |
339 | |
340 (defvar speedbar-directory-button-trim-method 'span | |
341 "*Indicates how the directory button will be displayed. | |
342 Possible values are: | |
343 'span - span large directories over multiple lines. | |
344 'trim - trim large directories to only show the last few. | |
345 nil - no trimming.") | |
189 | 346 |
190 (defvar speedbar-before-delete-hook nil | 347 (defvar speedbar-before-delete-hook nil |
191 "*Hooks called before deletiing the speedbar frame.") | 348 "*Hooks called before deleting the speedbar frame.") |
192 | 349 |
193 (defvar speedbar-mode-hook nil | 350 (defvar speedbar-mode-hook nil |
194 "*Hooks called after creating a speedbar buffer") | 351 "*Hooks called after creating a speedbar buffer.") |
195 | 352 |
196 (defvar speedbar-timer-hook nil | 353 (defvar speedbar-timer-hook nil |
197 "*Hooks called after running the speedbar timer function") | 354 "*Hooks called after running the speedbar timer function.") |
355 | |
356 (defvar speedbar-verbosity-level 1 | |
357 "*Verbosity level of the speedbar. 0 means say nothing. | |
358 1 means medium level verbosity. 2 and higher are higher levels of | |
359 verbosity.") | |
360 | |
361 (defvar speedbar-vc-indicator " *" | |
362 "*Text used to mark files which are currently checked out. | |
363 Currently only RCS is supported. Other version control systems can be | |
364 added by examining the function `speedbar-this-file-in-vc' and | |
365 `speedbar-vc-check-dir-p'") | |
366 | |
367 (defvar speedbar-vc-do-check t | |
368 "*Non-nil check all files in speedbar to see if they have been checked out. | |
369 Any file checked out is marked with `speedbar-vc-indicator'") | |
370 | |
371 (defvar speedbar-vc-to-do-point nil | |
372 "Local variable maintaining the current version control check position.") | |
373 | |
374 (defvar speedbar-ignored-modes nil | |
375 "*List of major modes which speedbar will not switch directories for.") | |
376 | |
377 (defvar speedbar-ignored-path-expressions | |
378 '("/log/$") | |
379 "*List of regular expressions matching directories speedbar will ignore. | |
380 They should included paths to directories which are notoriously very | |
381 large and take a long time to load in. Use the function | |
382 `speedbar-add-ignored-path-regexp' to add new items to this list after | |
383 speedbar is loaded. You may place anything you like in this list | |
384 before speedbar has been loaded.") | |
198 | 385 |
199 (defvar speedbar-file-unshown-regexp | 386 (defvar speedbar-file-unshown-regexp |
200 (let ((nstr "") (noext completion-ignored-extensions)) | 387 (let ((nstr "") (noext completion-ignored-extensions)) |
201 (while noext | 388 (while noext |
202 (setq nstr (concat nstr (regexp-quote (car noext)) "$" | 389 (setq nstr (concat nstr (regexp-quote (car noext)) "$" |
203 (if (cdr noext) "\\|" "")) | 390 (if (cdr noext) "\\|" "")) |
204 noext (cdr noext))) | 391 noext (cdr noext))) |
205 (concat nstr "\\|#[^#]+#$\\|\\.\\.?$")) | 392 (concat nstr "\\|#[^#]+#$\\|\\.\\.?$")) |
206 "*Regular expression matching files we don't want to display in a | 393 "*Regexp matching files we don't want displayed in a speedbar buffer. |
207 speedbar buffer") | 394 It is generated from the variable `completion-ignored-extensions'") |
208 | 395 |
209 (defvar speedbar-file-regexp | 396 (defvar speedbar-supported-extension-expressions |
210 (if speedbar-use-imenu-package | 397 (append '(".[CcHh]\\(++\\|pp\\|c\\|h\\)?" ".tex\\(i\\(nfo\\)?\\)?" |
211 "\\(\\.\\([CchH]\\|c\\(++\\|pp\\)\\|f90\\|ada\\|pl?\\|el\\|t\\(ex\\(i\\(nfo\\)?\\)?\\|cl\\)\\|emacs\\)$\\)\\|[Mm]akefile\\(\\.in\\)?" | 398 ".el" ".emacs" ".p" ".java") |
212 "\\.\\([CchH]\\|c\\(++\\|pp\\)\\|p\\|el\\|tex\\(i\\(nfo\\)?\\)?\\|emacs\\)$") | 399 (if speedbar-use-imenu-flag |
213 "*Regular expresson matching files we know how to expand.") | 400 '(".f90" ".ada" ".pl" ".tcl" ".m" |
401 "Makefile\\(\\.in\\)?"))) | |
402 "*List of regular expressions which will match files supported by tagging. | |
403 Do not prefix the `.' char with a double \\ to quote it, as the period | |
404 will be stripped by a simplified optimizer when compiled into a | |
405 singular expression. This variable will be turned into | |
406 `speedbar-file-regexp' for use with speedbar. You should use the | |
407 function `speedbar-add-supported-extension' to add a new extension at | |
408 runtime, or use the configuration dialog to set it in your .emacs | |
409 file.") | |
410 | |
411 (defun speedbar-extension-list-to-regex (extlist) | |
412 "Takes EXTLIST, a list of extensions and transforms it into regexp. | |
413 All the preceding . are stripped for an optimized expression starting | |
414 with . followed by extensions, followed by full-filenames." | |
415 (let ((regex1 nil) (regex2 nil)) | |
416 (while extlist | |
417 (if (= (string-to-char (car extlist)) ?.) | |
418 (setq regex1 (concat regex1 (if regex1 "\\|" "") | |
419 (substring (car extlist) 1))) | |
420 (setq regex2 (concat regex2 (if regex2 "\\|" "") (car extlist)))) | |
421 (setq extlist (cdr extlist))) | |
422 ;; concat all the sub-exressions together, making sure all types | |
423 ;; of parts exist during concatination. | |
424 (concat "\\(" | |
425 (if regex1 (concat "\\(\\.\\(" regex1 "\\)\\)") "") | |
426 (if (and regex1 regex2) "\\|" "") | |
427 (if regex2 (concat "\\(" regex2 "\\)") "") | |
428 "\\)$"))) | |
429 | |
430 (defvar speedbar-ignored-path-regexp | |
431 (speedbar-extension-list-to-regex speedbar-ignored-path-expressions) | |
432 "Regular expression matching paths speedbar will not switch to. | |
433 Created from `speedbar-ignored-path-expressions' with the function | |
434 `speedbar-extension-list-to-regex' (A misnamed function in this case.) | |
435 Use the function `speedbar-add-ignored-path-regexp' to modify this | |
436 variable.") | |
437 | |
438 (defvar speedbar-file-regexp | |
439 (speedbar-extension-list-to-regex speedbar-supported-extension-expressions) | |
440 "Regular expression matching files we know how to expand. | |
441 Created from `speedbar-supported-extension-expression' with the | |
442 function `speedbar-extension-list-to-regex'") | |
443 | |
444 (defun speedbar-add-supported-extension (extension) | |
445 "Add EXTENSION as a new supported extension for speedbar tagging. | |
446 This should start with a `.' if it is not a complete file name, and | |
447 the dot should NOT be quoted in with \\. Other regular expression | |
448 matchers are allowed however. EXTENSION may be a single string or a | |
449 list of strings." | |
450 (if (not (listp extension)) (setq extension (list extension))) | |
451 (while extension | |
452 (if (member (car extension) speedbar-supported-extension-expressions) | |
453 nil | |
454 (setq speedbar-supported-extension-expressions | |
455 (cons (car extension) speedbar-supported-extension-expressions))) | |
456 (setq extension (cdr extension))) | |
457 (setq speedbar-file-regexp (speedbar-extension-list-to-regex | |
458 speedbar-supported-extension-expressions))) | |
459 | |
460 (defun speedbar-add-ignored-path-regexp (path-expression) | |
461 "Add PATH-EXPRESSION as a new ignored path for speedbar tracking. | |
462 This function will modify `speedbar-ignored-path-regexp' and add | |
463 PATH-EXPRESSION to `speedbar-ignored-path-expressions'." | |
464 (if (not (listp path-expression)) | |
465 (setq path-expression (list path-expression))) | |
466 (while path-expression | |
467 (if (member (car path-expression) speedbar-ignored-path-expressions) | |
468 nil | |
469 (setq speedbar-ignored-path-expressions | |
470 (cons (car path-expression) speedbar-ignored-path-expressions))) | |
471 (setq path-expression (cdr path-expression))) | |
472 (setq speedbar-ignored-path-regexp (speedbar-extension-list-to-regex | |
473 speedbar-ignored-path-expressions))) | |
474 | |
475 (defvar speedbar-update-flag (or (not (fboundp 'run-with-idle-timer)) | |
476 (not (fboundp 'start-itimer))) | |
477 "*Non-nil means to automatically update the display. | |
478 When this is nil then speedbar will not follow the attached frame's path. | |
479 When speedbar is active, use: | |
480 | |
481 \\<speedbar-key-map> `\\[speedbar-toggle-updates]' | |
482 | |
483 to toggle this value.") | |
214 | 484 |
215 (defvar speedbar-syntax-table nil | 485 (defvar speedbar-syntax-table nil |
216 "Syntax-table used on the speedbar") | 486 "Syntax-table used on the speedbar.") |
217 | 487 |
218 (if speedbar-syntax-table | 488 (if speedbar-syntax-table |
219 nil | 489 nil |
220 (setq speedbar-syntax-table (make-syntax-table)) | 490 (setq speedbar-syntax-table (make-syntax-table)) |
221 ;; turn off paren matching around here. | 491 ;; turn off paren matching around here. |
223 (modify-syntax-entry ?\" " " speedbar-syntax-table) | 493 (modify-syntax-entry ?\" " " speedbar-syntax-table) |
224 (modify-syntax-entry ?( " " speedbar-syntax-table) | 494 (modify-syntax-entry ?( " " speedbar-syntax-table) |
225 (modify-syntax-entry ?) " " speedbar-syntax-table) | 495 (modify-syntax-entry ?) " " speedbar-syntax-table) |
226 (modify-syntax-entry ?[ " " speedbar-syntax-table) | 496 (modify-syntax-entry ?[ " " speedbar-syntax-table) |
227 (modify-syntax-entry ?] " " speedbar-syntax-table)) | 497 (modify-syntax-entry ?] " " speedbar-syntax-table)) |
228 | 498 |
229 | 499 |
230 (defvar speedbar-key-map nil | 500 (defvar speedbar-key-map nil |
231 "Keymap used in speedbar buffer.") | 501 "Keymap used in speedbar buffer.") |
232 (defvar speedbar-menu-map nil | 502 |
233 "Keymap used in speedbar menu buffer.") | 503 (autoload 'speedbar-configure-options "speedbcfg" "Configure speedbar variables" t) |
504 (autoload 'speedbar-configure-faces "speedbcfg" "Configure speedbar faces" t) | |
234 | 505 |
235 (if speedbar-key-map | 506 (if speedbar-key-map |
236 nil | 507 nil |
237 (setq speedbar-key-map (make-keymap)) | 508 (setq speedbar-key-map (make-keymap)) |
238 (suppress-keymap speedbar-key-map t) | 509 (suppress-keymap speedbar-key-map t) |
239 | 510 |
511 ;; control | |
240 (define-key speedbar-key-map "e" 'speedbar-edit-line) | 512 (define-key speedbar-key-map "e" 'speedbar-edit-line) |
513 (define-key speedbar-key-map "\C-m" 'speedbar-edit-line) | |
241 (define-key speedbar-key-map "+" 'speedbar-expand-line) | 514 (define-key speedbar-key-map "+" 'speedbar-expand-line) |
242 (define-key speedbar-key-map "-" 'speedbar-contract-line) | 515 (define-key speedbar-key-map "-" 'speedbar-contract-line) |
516 (define-key speedbar-key-map "g" 'speedbar-refresh) | |
517 (define-key speedbar-key-map "t" 'speedbar-toggle-updates) | |
518 (define-key speedbar-key-map "q" 'speedbar-close-frame) | |
519 (define-key speedbar-key-map "U" 'speedbar-up-directory) | |
520 | |
521 ;; navigation | |
522 (define-key speedbar-key-map "n" 'speedbar-next) | |
523 (define-key speedbar-key-map "p" 'speedbar-prev) | |
524 (define-key speedbar-key-map " " 'speedbar-scroll-up) | |
525 (define-key speedbar-key-map "\C-?" 'speedbar-scroll-down) | |
526 | |
527 ;; After much use, I suddenly desired in my heart to perform dired | |
528 ;; style operations since the directory was RIGHT THERE! | |
529 (define-key speedbar-key-map "I" 'speedbar-item-info) | |
530 (define-key speedbar-key-map "B" 'speedbar-item-byte-compile) | |
531 (define-key speedbar-key-map "L" 'speedbar-item-load) | |
532 (define-key speedbar-key-map "C" 'speedbar-item-copy) | |
533 (define-key speedbar-key-map "D" 'speedbar-item-delete) | |
534 (define-key speedbar-key-map "R" 'speedbar-item-rename) | |
243 | 535 |
244 (if (string-match "XEmacs" emacs-version) | 536 (if (string-match "XEmacs" emacs-version) |
245 (progn | 537 (progn |
246 ;; bind mouse bindings so we can manipulate the items on each line | 538 ;; bind mouse bindings so we can manipulate the items on each line |
247 (define-key speedbar-key-map 'button2 'speedbar-click) | 539 (define-key speedbar-key-map 'button2 'speedbar-click) |
248 | 540 (define-key speedbar-key-map '(shift button2) 'speedbar-power-click) |
249 ;; Xemacs users. You probably want your own toolbar for | 541 (define-key speedbar-key-map '(meta button3) 'speedbar-mouse-item-info) |
250 ;; the speedbar frame or mode or whatever. Make some buttons | 542 |
251 ;; and mail me how to do it! | 543 ;; Setup XEmacs Menubar w/ etags specific items |
252 ;; Also, how do you disable all those menu items? Email me that too | 544 (defvar speedbar-menu |
253 ;; as it would be most helpful. | 545 '("Speed Bar" |
546 ["Run Speedbar" (speedbar-frame-mode 1) t] | |
547 ["Refresh" speedbar-refresh t] | |
548 ["Allow Auto Updates" | |
549 speedbar-toggle-updates | |
550 :style toggle | |
551 :selected speedbar-update-flag] | |
552 "-----" | |
553 ["Sort etags in Speedbar" | |
554 (speedbar-toggle-etags "sort") | |
555 :style toggle | |
556 :selected speedbar-sort-tags] | |
557 ["Show unknown files" | |
558 (speedbar-toggle-etags "show") | |
559 :style toggle | |
560 :selected speedbar-show-unknown-files] | |
561 "-----" | |
562 ["Use C++ Tagging" | |
563 (speedbar-toggle-etags "-C") | |
564 :style toggle | |
565 :selected (member "-C" speedbar-fetch-etags-arguments)] | |
566 ["Tag preprocessor defs" | |
567 (speedbar-toggle-etags "-D") | |
568 :style toggle | |
569 :selected (not (member "-D" speedbar-fetch-etags-arguments))] | |
570 ["Use indentation" | |
571 (speedbar-toggle-etags "-S") | |
572 :style toggle | |
573 :selected (not (member "-S" speedbar-fetch-etags-arguments))])) | |
574 | |
575 (add-submenu '("Tools") speedbar-menu nil) | |
576 | |
254 ) | 577 ) |
255 ;; bind mouse bindings so we can manipulate the items on each line | 578 ;; bind mouse bindings so we can manipulate the items on each line |
256 (define-key speedbar-key-map [mouse-2] 'speedbar-click) | 579 (define-key speedbar-key-map [mouse-2] 'speedbar-click) |
257 (define-key speedbar-key-map [down-mouse-2] 'speedbar-quick-mouse) | 580 ;; This is the power click for poping up new frames |
258 | 581 (define-key speedbar-key-map [S-mouse-2] 'speedbar-power-click) |
259 ;; this was meant to do a rescan or something | 582 ;; This adds a small unecessary visual effect |
260 ;;(define-key speedbar-key-map [shift-mouse-2] 'speedbar-hard-click) | 583 ;;(define-key speedbar-key-map [down-mouse-2] 'speedbar-quick-mouse) |
584 (define-key speedbar-key-map [M-mouse-2] 'speedbar-mouse-item-info) | |
261 | 585 |
262 ;; disable all menus - we don't have a lot of space to play with | 586 ;; disable all menus - we don't have a lot of space to play with |
263 ;; in such a skinny frame. | 587 ;; in such a skinny frame. This will cleverly find and nuke some |
264 (define-key speedbar-key-map [menu-bar buffer] 'undefined) | 588 ;; user-defined menus as well if they are there. Too bad it |
265 (define-key speedbar-key-map [menu-bar files] 'undefined) | 589 ;; rely's on the structure of a keymap to work. |
266 (define-key speedbar-key-map [menu-bar tools] 'undefined) | 590 (let ((k (lookup-key global-map [menu-bar]))) |
267 (define-key speedbar-key-map [menu-bar edit] 'undefined) | 591 (while k |
268 (define-key speedbar-key-map [menu-bar search] 'undefined) | 592 (if (and (listp (car k)) (listp (cdr (car k)))) |
269 (define-key speedbar-key-map [menu-bar help-menu] 'undefined) | 593 (define-key speedbar-key-map (vector 'menu-bar (car (car k))) |
594 'undefined)) | |
595 (setq k (cdr k)))) | |
270 | 596 |
271 ;; This lets the user scroll as if we had a scrollbar... well maybe not | 597 ;; This lets the user scroll as if we had a scrollbar... well maybe not |
272 (define-key speedbar-key-map [mode-line mouse-2] 'speedbar-mouse-hscroll) | 598 (define-key speedbar-key-map [mode-line mouse-2] 'speedbar-mouse-hscroll) |
273 | |
274 ;; Create a menu for speedbar | |
275 (setq speedbar-menu-map (make-sparse-keymap)) | |
276 (define-key speedbar-key-map [menu-bar speedbar] | |
277 (cons "Speedbar" speedbar-menu-map)) | |
278 (define-key speedbar-menu-map [close] | |
279 (cons "Close" 'speedbar-close-frame)) | |
280 (define-key speedbar-menu-map [clonfigure] | |
281 (cons "Configure Faces" 'speedbar-configure-faces)) | |
282 (define-key speedbar-menu-map [configopt] | |
283 (cons "Configure Options" 'speedbar-configure-options)) | |
284 (define-key speedbar-menu-map [Update] | |
285 (cons "Update" 'speedbar-update-contents)) | |
286 )) | 599 )) |
287 | 600 |
288 (put 'speedbar-configure-faces 'menu-enable '(featurep 'dialog)) | 601 (defvar speedbar-easymenu-definition-base |
289 (put 'speedbar-configure-options 'menu-enable '(featurep 'dialog)) | 602 '("Speedbar" |
603 ["Update" speedbar-refresh t] | |
604 ["Auto Update" speedbar-toggle-updates | |
605 :style toggle :selected speedbar-update-flag] | |
606 ) | |
607 "Base part of the speedbar menu.") | |
608 | |
609 (defvar speedbar-easymenu-definition-special | |
610 '(["Edit Item On Line" speedbar-edit-line t] | |
611 ["Show All Files" speedbar-toggle-show-all-files | |
612 :style toggle :selected speedbar-show-unknown-files] | |
613 ["Expand Item" speedbar-expand-line | |
614 (save-excursion (beginning-of-line) | |
615 (looking-at "[0-9]+: *.\\+. "))] | |
616 ["Contract Item" speedbar-contract-line | |
617 (save-excursion (beginning-of-line) | |
618 (looking-at "[0-9]+: *.-. "))] | |
619 "----" | |
620 ["Item Information" speedbar-item-info t] | |
621 ["Load Lisp File" speedbar-item-load | |
622 (save-excursion | |
623 (beginning-of-line) | |
624 (looking-at "[0-9]+: *\\[[+-]\\] .+\\(\\.el\\)\\( \\*\\)?$"))] | |
625 ["Byte Compile File" speedbar-item-byte-compile | |
626 (save-excursion | |
627 (beginning-of-line) | |
628 (looking-at "[0-9]+: *\\[[+-]\\] .+\\(\\.el\\)\\( \\*\\)?$"))] | |
629 ["Copy Item" speedbar-item-copy | |
630 (save-excursion (beginning-of-line) (looking-at "[0-9]+: *\\["))] | |
631 ["Rename Item" speedbar-item-rename | |
632 (save-excursion (beginning-of-line) (looking-at "[0-9]+: *[[<]"))] | |
633 ["Delete Item" speedbar-item-delete | |
634 (save-excursion (beginning-of-line) (looking-at "[0-9]+: *[[<]"))]) | |
635 "Additional menu items while in file-mode.") | |
636 | |
637 (defvar speedbar-easymenu-definition-trailer | |
638 '("----" | |
639 ["Close" speedbar-close-frame t]) | |
640 "Menu items appearing at the end of the speedbar menu.") | |
290 | 641 |
291 (defvar speedbar-buffer nil | 642 (defvar speedbar-buffer nil |
292 "The buffer displaying the speedbar.") | 643 "The buffer displaying the speedbar.") |
293 (defvar speedbar-frame nil | 644 (defvar speedbar-frame nil |
294 "The frame displaying speedbar.") | 645 "The frame displaying speedbar.") |
646 (defvar speedbar-cached-frame nil | |
647 "The frame that was last created, then removed from the display.") | |
648 (defvar speedbar-full-text-cache nil | |
649 "The last open directory is saved in it's entirety for ultra-fast switching.") | |
295 (defvar speedbar-timer nil | 650 (defvar speedbar-timer nil |
296 "The speedbar timer used for updating the buffer.") | 651 "The speedbar timer used for updating the buffer.") |
297 (defvar speedbar-attached-frame nil | 652 (defvar speedbar-attached-frame nil |
298 "The frame which started speedbar mode. This is the frame from | 653 "The frame which started speedbar mode. |
299 which all data displayed in the speedbar is gathered, and in which files | 654 This is the frame from which all data displayed in the speedbar is |
300 and such are displayed.") | 655 gathered, and in which files and such are displayed.") |
301 | 656 |
302 (defvar speedbar-last-selected-file nil | 657 (defvar speedbar-last-selected-file nil |
303 "The last file which was selected in speedbar buffer") | 658 "The last file which was selected in speedbar buffer.") |
304 | 659 |
305 (defvar speedbar-shown-directories nil | 660 (defvar speedbar-shown-directories nil |
306 "Used to maintain list of directories simultaneously open in the current | 661 "Maintain list of directories simultaneously open in the current speedbar.") |
307 speedbar.") | 662 |
663 (defvar speedbar-directory-contents-alist nil | |
664 "An association list of directories and their contents. | |
665 Each sublist was returned by `speedbar-file-lists'. This list is | |
666 maintained to speed up the refresh rate when switching between | |
667 directories.") | |
668 | |
669 (defvar speedbar-power-click nil | |
670 "Never set this by hand. Value is t when S-mouse activity occurs.") | |
308 | 671 |
309 | 672 |
310 ;;; | |
311 ;;; Mode definitions/ user commands | 673 ;;; Mode definitions/ user commands |
312 ;;; | 674 ;; |
313 ;;;###autoload | 675 ;;###autoload |
676 (defalias 'speedbar 'speedbar-frame-mode) | |
314 (defun speedbar-frame-mode (&optional arg) | 677 (defun speedbar-frame-mode (&optional arg) |
315 "Enable or disable use of a speedbar. Positive number means turn | 678 "Enable or disable speedbar. Positive ARG means turn on, negative turn off. |
316 on, negative turns speedbar off, and nil means toggle. Once the | 679 nil means toggle. Once the speedbar frame is activated, a buffer in |
317 speedbar frame is activated, a buffer in `speedbar-mode' will be | 680 `speedbar-mode' will be displayed. Currently, only one speedbar is |
318 displayed. Currently, only one speedbar is supported at a time." | 681 supported at a time." |
319 (interactive "P") | 682 (interactive "P") |
320 (if (not window-system) | 683 (if (not window-system) |
321 (error "Speedbar is not useful outside of a windowing environement")) | 684 (error "Speedbar is not useful outside of a windowing environment")) |
322 ;; toggle frame on and off. | 685 ;; toggle frame on and off. |
323 (if (not arg) (if speedbar-frame (setq arg -1) (setq arg 1))) | 686 (if (not arg) (if speedbar-frame (setq arg -1) (setq arg 1))) |
324 ;; turn the frame off on neg number | 687 ;; turn the frame off on neg number |
325 (if (and (numberp arg) (< arg 0)) | 688 (if (and (numberp arg) (< arg 0)) |
326 (progn | 689 (progn |
327 (run-hooks 'speedbar-before-delete-hook) | 690 (run-hooks 'speedbar-before-delete-hook) |
328 (if (and speedbar-frame (frame-live-p speedbar-frame)) | 691 (if (and speedbar-frame (frame-live-p speedbar-frame)) |
329 (delete-frame speedbar-frame)) | 692 (if speedbar-xemacsp |
693 (delete-frame speedbar-frame) | |
694 (setq speedbar-cached-frame speedbar-frame) | |
695 (modify-frame-parameters speedbar-frame '((visibility . nil))))) | |
696 (setq speedbar-frame nil) | |
330 (speedbar-set-timer nil) | 697 (speedbar-set-timer nil) |
331 (setq speedbar-frame nil) | 698 ;; Used to delete the buffer. This has the annoying affect of |
332 (if (bufferp speedbar-buffer) | 699 ;; preventing whatever took it's place from ever appearing |
333 (kill-buffer speedbar-buffer))) | 700 ;; as the default after a C-x b was typed |
701 ;;(if (bufferp speedbar-buffer) | |
702 ;; (kill-buffer speedbar-buffer)) | |
703 ) | |
334 ;; Set this as our currently attached frame | 704 ;; Set this as our currently attached frame |
335 (setq speedbar-attached-frame (selected-frame)) | 705 (setq speedbar-attached-frame (selected-frame)) |
336 ;; Get the buffer to play with | |
337 (speedbar-mode) | |
338 ;; Get the frame to work in | 706 ;; Get the frame to work in |
339 (if (and speedbar-frame (frame-live-p speedbar-frame)) | 707 (if (frame-live-p speedbar-cached-frame) |
340 (raise-frame speedbar-frame) | 708 (progn |
341 (let ((params (list | 709 (setq speedbar-frame speedbar-cached-frame) |
342 ;; Xemacs fails to delete speedbar | 710 (modify-frame-parameters speedbar-frame '((visibility . t))) |
343 ;; if minibuffer is off. | 711 ;; Get the buffer to play with |
344 ;; JTL <<<< Seems to be OK for 19.15. | 712 (speedbar-mode) |
345 ;; removed tool- & menubar. | 713 (select-frame speedbar-frame) |
346 ;; <<<< JTL | 714 (if (not (eq (current-buffer) speedbar-buffer)) |
347 (cons 'minibuffer nil) | 715 (switch-to-buffer speedbar-buffer)) |
348 (cons 'width speedbar-width) | 716 (set-window-dedicated-p (selected-window) t) |
349 (cons 'height (frame-height)) | 717 (raise-frame speedbar-frame) |
350 (cons 'scroll-bar-width speedbar-scrollbar-width) | 718 (speedbar-set-timer speedbar-update-speed) |
351 (cons 'auto-raise speedbar-raise-lower) | 719 ) |
352 (cons 'auto-lower speedbar-raise-lower) | 720 (if (frame-live-p speedbar-frame) |
353 '(modeline . nil) | 721 (raise-frame speedbar-frame) |
354 '(border-width . 0) | 722 (let ((params (cons (cons 'height (frame-height)) |
355 '(unsplittable . t) | 723 speedbar-frame-parameters))) |
356 '(default-toolbar-visible-p . nil) | 724 (setq speedbar-frame |
357 '(menubar-visible-p . nil)))) | 725 (if (< emacs-major-version 20) ;a bug is fixed in v20 & later |
358 (setq speedbar-frame | 726 (make-frame params) |
359 (if (< emacs-minor-version 35) | 727 (let ((x-pointer-shape x-pointer-top-left-arrow) |
360 (make-frame params) | 728 (x-sensitive-text-pointer-shape x-pointer-hand2)) |
361 (let ((x-pointer-shape x-pointer-top-left-arrow) | 729 (make-frame params))))) |
362 (x-sensitive-text-pointer-shape x-pointer-hand2)) | 730 ;; reset the selection variable |
363 (make-frame params))))) | 731 (setq speedbar-last-selected-file nil) |
364 ;; reset the selection variable | 732 ;; Put the buffer into the frame |
365 (setq speedbar-last-selected-file nil) | 733 (save-window-excursion |
366 ;; Put the buffer into the frame | 734 ;; Get the buffer to play with |
367 (save-window-excursion | 735 (speedbar-mode) |
368 (select-frame speedbar-frame) | 736 (select-frame speedbar-frame) |
369 (switch-to-buffer speedbar-buffer) | 737 (switch-to-buffer speedbar-buffer) |
370 (setq default-minibuffer-frame speedbar-attached-frame)) | 738 (set-window-dedicated-p (selected-window) t) |
371 (speedbar-set-timer speedbar-update-speed) | 739 ;; Turn off toolbar and menubar under XEmacs |
372 ))) | 740 (if speedbar-xemacsp |
741 (progn | |
742 (set-specifier default-toolbar-visible-p | |
743 (cons (selected-frame) nil)) | |
744 ;; These lines make the menu-bar go away nicely, but | |
745 ;; they also cause xemacs much heartache. | |
746 ;;(set-specifier menubar-visible-p (cons (selected-frame) nil)) | |
747 ;;(make-local-variable 'current-menubar) | |
748 ;;(setq current-menubar speedbar-menu) | |
749 ;;(add-submenu nil speedbar-menu nil) | |
750 ))) | |
751 (speedbar-set-timer speedbar-update-speed) | |
752 )))) | |
373 | 753 |
374 (defun speedbar-close-frame () | 754 (defun speedbar-close-frame () |
375 "Turn off speedbar mode" | 755 "Turn off a currently active speedbar." |
376 (interactive) | 756 (interactive) |
377 (speedbar-frame-mode -1)) | 757 (speedbar-frame-mode -1) |
758 (select-frame speedbar-attached-frame) | |
759 (other-frame 0)) | |
760 | |
761 (defun speedbar-frame-width () | |
762 "Return the width of the speedbar frame in characters. | |
763 nil if it doesn't exist." | |
764 (and speedbar-frame (cdr (assoc 'width (frame-parameters speedbar-frame))))) | |
378 | 765 |
379 (defun speedbar-mode () | 766 (defun speedbar-mode () |
380 "Create and return a SPEEDBAR buffer. The speedbar buffer allows | 767 "Major mode for managing a display of directories and tags. |
381 the user to manage a list of directories and paths at different | 768 \\<speedbar-key-map> |
382 depths. The first line represents the default path of the speedbar | 769 The first line represents the default path of the speedbar frame. |
383 frame. Each directory segment is a button which jumps speedbar's | 770 Each directory segment is a button which jumps speedbar's default |
384 default directory to that path. Buttons are activated by clicking | 771 directory to that path. Buttons are activated by clicking `\\[speedbar-click]'. |
385 mouse-2. | 772 In some situations using `\\[speedbar-power-click]' is a `power click' which will |
773 rescan cached items, or pop up new frames. | |
386 | 774 |
387 Each line starting with <+> represents a directory. Click on the <+> | 775 Each line starting with <+> represents a directory. Click on the <+> |
388 to insert the directory listing into the current tree. Click on the | 776 to insert the directory listing into the current tree. Click on the |
389 <-> to retract that list. Click on the directory name to go to that | 777 <-> to retract that list. Click on the directory name to go to that |
390 directory as the default. | 778 directory as the default. |
393 `speedbar-show-unknown-files' is t, the lines starting with [?] are | 781 `speedbar-show-unknown-files' is t, the lines starting with [?] are |
394 files which don't have imenu support, but are not expressly ignored. | 782 files which don't have imenu support, but are not expressly ignored. |
395 Files are completely ignored if they match `speedbar-file-unshown-regexp' | 783 Files are completely ignored if they match `speedbar-file-unshown-regexp' |
396 which is generated from `completion-ignored-extensions'. | 784 which is generated from `completion-ignored-extensions'. |
397 | 785 |
786 Files with a `*' character after their name are files checked out of a | |
787 version control system. (currently only RCS is supported.) New | |
788 version control systems can be added by examining the documentation | |
789 for `speedbar-this-file-in-vc' and `speedbar-vc-check-dir-p' | |
790 | |
398 Click on the [+] to display a list of tags from that file. Click on | 791 Click on the [+] to display a list of tags from that file. Click on |
399 the [-] to retract the list. Click on the file name to edit the file | 792 the [-] to retract the list. Click on the file name to edit the file |
400 in the attached frame. | 793 in the attached frame. |
401 | 794 |
402 If you open tags, you might find a node starting with {+}, which is a | 795 If you open tags, you might find a node starting with {+}, which is a |
403 category of tags. Click the {+} to expand the category. Jumpable | 796 category of tags. Click the {+} to expand the category. Jump-able |
404 tags start with >. Click the name of the tag to go to that position | 797 tags start with >. Click the name of the tag to go to that position |
405 in the selected file. | 798 in the selected file. |
406 | 799 |
407 Keybindings: \\<speedbar-key-map> | 800 \\{speedbar-key-map}" |
408 \\[speedbar-click] Activate the button under the mouse. | 801 ;; NOT interactive |
409 \\[speedbar-edit-line] Edit the file/directory on this line. Same as clicking | 802 (save-excursion |
410 on the name on the selected line.) | 803 (setq speedbar-buffer (set-buffer (get-buffer-create " SPEEDBAR"))) |
411 \\[speedbar-expand-line] Expand the current line. Same as clicking on the + on a line. | 804 (kill-all-local-variables) |
412 \\[speedbar-contract-line] Contract the current line. Same as clicking on the - on a line." | 805 (setq major-mode 'speedbar-mode) |
413 (setq speedbar-buffer (set-buffer (get-buffer-create "SPEEDBAR"))) | 806 (setq mode-name "Speedbar") |
414 (kill-all-local-variables) | 807 (use-local-map speedbar-key-map) |
415 (setq major-mode 'speedbar-mode) | 808 (set-syntax-table speedbar-syntax-table) |
416 (setq mode-name "SB") | 809 (setq font-lock-keywords nil) ;; no font-locking please |
417 (use-local-map speedbar-key-map) | 810 (setq truncate-lines t) |
418 (set-syntax-table speedbar-syntax-table) | 811 (make-local-variable 'frame-title-format) |
419 (setq mode-line-format | 812 (setq frame-title-format "Speedbar") |
420 '("<< SPEEDBAR " (line-number-mode " %3l ") " >>")) | 813 ;; Set this up special just for the speedbar buffer |
421 (setq font-lock-keywords nil) ;; no font-locking please | 814 (if (null default-minibuffer-frame) |
422 (setq truncate-lines t) | 815 (progn |
423 (if (not speedbar-xemacsp) (setq auto-show-mode nil)) ;no auto-show for FSF | 816 (make-local-variable 'default-minibuffer-frame) |
424 (run-hooks 'speedbar-mode-hook) | 817 (setq default-minibuffer-frame speedbar-attached-frame))) |
818 (make-local-variable 'temp-buffer-show-function) | |
819 (setq temp-buffer-show-function 'speedbar-temp-buffer-show-function) | |
820 (setq kill-buffer-hook '(lambda () (let ((skilling (boundp 'skilling))) | |
821 (if skilling | |
822 nil | |
823 (if (eq (current-buffer) | |
824 speedbar-buffer) | |
825 (speedbar-frame-mode -1)))))) | |
826 (speedbar-set-mode-line-format) | |
827 (if (not speedbar-xemacsp) | |
828 (setq auto-show-mode nil)) ;no auto-show for Emacs | |
829 (run-hooks 'speedbar-mode-hook)) | |
425 (speedbar-update-contents) | 830 (speedbar-update-contents) |
426 ) | 831 speedbar-buffer) |
427 | 832 |
833 (defun speedbar-set-mode-line-format () | |
834 "Set the format of the mode line based on the current speedbar environment. | |
835 This gives visual indications of what is up. It EXPECTS the speedbar | |
836 frame and window to be the currently active frame and window." | |
837 (if (frame-live-p speedbar-frame) | |
838 (save-excursion | |
839 (set-buffer speedbar-buffer) | |
840 (let* ((w (or (speedbar-frame-width) 20)) | |
841 (p1 "<<") | |
842 (p5 ">>") | |
843 (p3 (if speedbar-update-flag "SPEEDBAR" "SLOWBAR")) | |
844 (blank (- w (length p1) (length p3) (length p5) | |
845 (if line-number-mode 4 0))) | |
846 (p2 (if (> blank 0) | |
847 (make-string (/ blank 2) ? ) | |
848 "")) | |
849 (p4 (if (> blank 0) | |
850 (make-string (+ (/ blank 2) (% blank 2)) ? ) | |
851 "")) | |
852 (tf | |
853 (if line-number-mode | |
854 (list (concat p1 p2 p3) '(line-number-mode " %3l") | |
855 (concat p4 p5)) | |
856 (list (concat p1 p2 p3 p4 p5))))) | |
857 (if (not (equal mode-line-format tf)) | |
858 (progn | |
859 (setq mode-line-format tf) | |
860 (force-mode-line-update))))))) | |
861 | |
862 (defun speedbar-temp-buffer-show-function (buffer) | |
863 "Placed in the variable `temp-buffer-show-function' in `speedbar-mode'. | |
864 If a user requests help using \\[help-command] <Key> the temp BUFFER will be | |
865 redirected into a window on the attached frame." | |
866 (if speedbar-attached-frame (select-frame speedbar-attached-frame)) | |
867 (pop-to-buffer buffer nil) | |
868 (other-window -1) | |
869 (run-hooks 'temp-buffer-show-hook)) | |
870 | |
871 (defun speedbar-reconfigure-menubar () | |
872 "Reconfigure the menu-bar in a speedbar frame. | |
873 Different menu items are displayed depending on the current display mode | |
874 and the existence of packages." | |
875 (let ((km (make-sparse-keymap)) | |
876 (cf (selected-frame)) | |
877 (md (append speedbar-easymenu-definition-base | |
878 (if speedbar-shown-directories | |
879 ;; file display mode version | |
880 speedbar-easymenu-definition-special | |
881 (save-excursion | |
882 (select-frame speedbar-attached-frame) | |
883 (if (local-variable-p | |
884 'speedbar-easymenu-definition-special) | |
885 ;; If bound locally, we can use it | |
886 speedbar-easymenu-definition-special))) | |
887 ;; The trailer | |
888 speedbar-easymenu-definition-trailer))) | |
889 (easy-menu-define speedbar-menu-map speedbar-key-map "Speedbar menu" md) | |
890 (if speedbar-xemacsp (set-buffer-menubar (list km))))) | |
891 | |
892 | |
893 ;;; User Input stuff | |
894 ;; | |
428 (defun speedbar-mouse-hscroll (e) | 895 (defun speedbar-mouse-hscroll (e) |
429 "Read a mouse event from the mode line, and horizontally scroll if the | 896 "Read a mouse event E from the mode line, and horizontally scroll. |
430 mouse is being clicked on the far left, or far right of the modeline." | 897 If the mouse is being clicked on the far left, or far right of the |
898 mode-line. This is only useful for non-XEmacs" | |
431 (interactive "e") | 899 (interactive "e") |
432 (let* ((xp (car (nth 2 (car (cdr e))))) | 900 (let* ((xp (car (nth 2 (car (cdr e))))) |
433 (cpw (/ (frame-pixel-width) | 901 (cpw (/ (frame-pixel-width) |
434 (frame-width))) | 902 (frame-width))) |
435 (oc (1+ (/ xp cpw))) | 903 (oc (1+ (/ xp cpw))) |
440 (scroll-right 2)) | 908 (scroll-right 2)) |
441 (t (message "Click on the edge of the modeline to scroll left/right"))) | 909 (t (message "Click on the edge of the modeline to scroll left/right"))) |
442 ;;(message "X: Pixel %d Char Pixels %d On char %d" xp cpw oc) | 910 ;;(message "X: Pixel %d Char Pixels %d On char %d" xp cpw oc) |
443 )) | 911 )) |
444 | 912 |
913 (defun speedbar-get-focus () | |
914 "Change frame focus to or from the speedbar frame. | |
915 If the selected frame is not speedbar, then speedbar frame is | |
916 selected. If the speedbar frame is active, then select the attached frame." | |
917 (interactive) | |
918 (if (eq (selected-frame) speedbar-frame) | |
919 (if (frame-live-p speedbar-attached-frame) | |
920 (select-frame speedbar-attached-frame)) | |
921 ;; make sure we have a frame | |
922 (if (not (frame-live-p speedbar-frame)) (speedbar-frame-mode 1)) | |
923 ;; go there | |
924 (select-frame speedbar-frame)) | |
925 (other-frame 0)) | |
926 | |
927 (defun speedbar-next (arg) | |
928 "Move to the next ARGth line in a speedbar buffer." | |
929 (interactive "p") | |
930 (forward-line (or arg 1)) | |
931 (speedbar-item-info) | |
932 (speedbar-position-cursor-on-line)) | |
933 | |
934 (defun speedbar-prev (arg) | |
935 "Move to the previous ARGth line in a speedbar buffer." | |
936 (interactive "p") | |
937 (speedbar-next (if arg (- arg) -1))) | |
938 | |
939 (defun speedbar-scroll-up (&optional arg) | |
940 "Page down one screen-full of the speedbar, or ARG lines." | |
941 (interactive "P") | |
942 (scroll-up arg) | |
943 (speedbar-position-cursor-on-line)) | |
944 | |
945 (defun speedbar-scroll-down (&optional arg) | |
946 "Page up one screen-full of the speedbar, or ARG lines." | |
947 (interactive "P") | |
948 (scroll-down arg) | |
949 (speedbar-position-cursor-on-line)) | |
950 | |
951 (defun speedbar-up-directory () | |
952 "Keyboard accelerator for moving the default directory up one. | |
953 Assumes that the current buffer is the speedbar buffer" | |
954 (interactive) | |
955 (setq default-directory (expand-file-name (concat default-directory "../"))) | |
956 (speedbar-update-contents)) | |
445 | 957 |
446 ;;; | 958 ;;; Speedbar file activity |
959 ;; | |
960 (defun speedbar-refresh () | |
961 "Refresh the current speedbar display, disposing of any cached data." | |
962 (interactive) | |
963 (let ((dl speedbar-shown-directories)) | |
964 (while dl | |
965 (adelete 'speedbar-directory-contents-alist (car dl)) | |
966 (setq dl (cdr dl)))) | |
967 (if (<= 1 speedbar-verbosity-level) (message "Refreshing speedbar...")) | |
968 (speedbar-update-contents) | |
969 (speedbar-stealthy-updates) | |
970 ;; Reset the timer in case it got really hosed for some reason... | |
971 (speedbar-set-timer speedbar-update-speed) | |
972 (if (<= 1 speedbar-verbosity-level) (message "Refreshing speedbar...done"))) | |
973 | |
974 (defun speedbar-item-load () | |
975 "Byte compile the item under the cursor or mouse if it is a lisp file." | |
976 (interactive) | |
977 (let ((f (speedbar-line-file))) | |
978 (if (and (file-exists-p f) (string-match "\\.el$" f)) | |
979 (if (and (file-exists-p (concat f "c")) | |
980 (y-or-n-p (format "Load %sc? " f))) | |
981 ;; If the compiled version exists, load that instead... | |
982 (load-file (concat f "c")) | |
983 (load-file f)) | |
984 (error "Not a loadable file...")))) | |
985 | |
986 (defun speedbar-item-byte-compile () | |
987 "Byte compile the item under the cursor or mouse if it is a lisp file." | |
988 (interactive) | |
989 (let ((f (speedbar-line-file)) | |
990 (sf (selected-frame))) | |
991 (if (and (file-exists-p f) (string-match "\\.el$" f)) | |
992 (progn | |
993 (select-frame speedbar-attached-frame) | |
994 (byte-compile-file f nil) | |
995 (select-frame sf))) | |
996 )) | |
997 | |
998 (defun speedbar-mouse-item-info (event) | |
999 "Provide information about what the user clicked on. | |
1000 This should be bound to a mouse EVENT." | |
1001 (interactive "e") | |
1002 (mouse-set-point event) | |
1003 (speedbar-item-info)) | |
1004 | |
1005 (defun speedbar-item-info () | |
1006 "Display info in the mini-buffer about the button the mouse is over." | |
1007 (interactive) | |
1008 (if (not speedbar-shown-directories) | |
1009 nil | |
1010 (let* ((item (speedbar-line-file)) | |
1011 (attr (if item (file-attributes item) nil))) | |
1012 (if item (message "%s %d %s" (nth 8 attr) (nth 7 attr) item) | |
1013 (save-excursion | |
1014 (beginning-of-line) | |
1015 (looking-at "\\([0-9]+\\):") | |
1016 (setq item (speedbar-line-path (string-to-int (match-string 1)))) | |
1017 (if (re-search-forward "> \\([^ ]+\\)$" | |
1018 (save-excursion(end-of-line)(point)) t) | |
1019 (progn | |
1020 (setq attr (get-text-property (match-beginning 1) | |
1021 'speedbar-token)) | |
1022 (message "Tag %s in %s at position %s" | |
1023 (match-string 1) item (if attr attr 0))) | |
1024 (message "No special info for this line."))) | |
1025 )))) | |
1026 | |
1027 (defun speedbar-item-copy () | |
1028 "Copy the item under the cursor. | |
1029 Files can be copied to new names or places." | |
1030 (interactive) | |
1031 (let ((f (speedbar-line-file))) | |
1032 (if (not f) (error "Not a file.")) | |
1033 (if (file-directory-p f) | |
1034 (error "Cannot copy directory.") | |
1035 (let* ((rt (read-file-name (format "Copy %s to: " | |
1036 (file-name-nondirectory f)) | |
1037 (file-name-directory f))) | |
1038 (refresh (member (expand-file-name (file-name-directory rt)) | |
1039 speedbar-shown-directories))) | |
1040 ;; Create the right file name part | |
1041 (if (file-directory-p rt) | |
1042 (setq rt | |
1043 (concat (expand-file-name rt) | |
1044 (if (string-match "/$" rt) "" "/") | |
1045 (file-name-nondirectory f)))) | |
1046 (if (or (not (file-exists-p rt)) | |
1047 (y-or-n-p (format "Overwrite %s with %s? " rt f))) | |
1048 (progn | |
1049 (copy-file f rt t t) | |
1050 ;; refresh display if the new place is currently displayed. | |
1051 (if refresh | |
1052 (progn | |
1053 (speedbar-refresh) | |
1054 (if (not (speedbar-goto-this-file rt)) | |
1055 (speedbar-goto-this-file f)))) | |
1056 )))))) | |
1057 | |
1058 (defun speedbar-item-rename () | |
1059 "Rename the item under the cursor or mouse. | |
1060 Files can be renamed to new names or moved to new directories." | |
1061 (interactive) | |
1062 (let ((f (speedbar-line-file))) | |
1063 (if f | |
1064 (let* ((rt (read-file-name (format "Rename %s to: " | |
1065 (file-name-nondirectory f)) | |
1066 (file-name-directory f))) | |
1067 (refresh (member (expand-file-name (file-name-directory rt)) | |
1068 speedbar-shown-directories))) | |
1069 ;; Create the right file name part | |
1070 (if (file-directory-p rt) | |
1071 (setq rt | |
1072 (concat (expand-file-name rt) | |
1073 (if (string-match "/$" rt) "" "/") | |
1074 (file-name-nondirectory f)))) | |
1075 (if (or (not (file-exists-p rt)) | |
1076 (y-or-n-p (format "Overwrite %s with %s? " rt f))) | |
1077 (progn | |
1078 (rename-file f rt t) | |
1079 ;; refresh display if the new place is currently displayed. | |
1080 (if refresh | |
1081 (progn | |
1082 (speedbar-refresh) | |
1083 (speedbar-goto-this-file rt) | |
1084 ))))) | |
1085 (error "Not a file.")))) | |
1086 | |
1087 (defun speedbar-item-delete () | |
1088 "Delete the item under the cursor. Files are removed from disk." | |
1089 (interactive) | |
1090 (let ((f (speedbar-line-file))) | |
1091 (if (not f) (error "Not a file.")) | |
1092 (if (y-or-n-p (format "Delete %s? " f)) | |
1093 (progn | |
1094 (if (file-directory-p f) | |
1095 (delete-directory f) | |
1096 (delete-file f)) | |
1097 (message "Okie dokie..") | |
1098 (let ((p (point))) | |
1099 (speedbar-refresh) | |
1100 (goto-char p)) | |
1101 )) | |
1102 )) | |
1103 | |
1104 (defun speedbar-enable-update () | |
1105 "Enable automatic updating in speedbar via timers." | |
1106 (interactive) | |
1107 (setq speedbar-update-flag t) | |
1108 (speedbar-set-mode-line-format) | |
1109 (speedbar-set-timer speedbar-update-speed)) | |
1110 | |
1111 (defun speedbar-disable-update () | |
1112 "Disable automatic updating and stop consuming resources." | |
1113 (interactive) | |
1114 (setq speedbar-update-flag nil) | |
1115 (speedbar-set-mode-line-format) | |
1116 (speedbar-set-timer nil)) | |
1117 | |
1118 (defun speedbar-toggle-updates () | |
1119 "Toggle automatic update for the speedbar frame." | |
1120 (interactive) | |
1121 (if speedbar-update-flag | |
1122 (speedbar-disable-update) | |
1123 (speedbar-enable-update))) | |
1124 | |
1125 (defun speedbar-toggle-show-all-files () | |
1126 "Toggle display of files speedbar can not tag." | |
1127 (interactive) | |
1128 (setq speedbar-show-unknown-files (not speedbar-show-unknown-files)) | |
1129 (speedbar-refresh)) | |
1130 | |
447 ;;; Utility functions | 1131 ;;; Utility functions |
448 ;;; | 1132 ;; |
449 (defun speedbar-set-timer (timeout) | 1133 (defun speedbar-set-timer (timeout) |
450 "Unset an old timer (if there is one) and activate a new timer with the | 1134 "Unset an old timer (if there is one) and activate a new timer with TIMEOUT. |
451 given timeout value." | 1135 TIMEOUT is the number of seconds until the speedbar timer is called |
452 (cond | 1136 again." |
1137 (cond | |
453 ;; Xemacs | 1138 ;; Xemacs |
454 (speedbar-xemacsp | 1139 (speedbar-xemacsp |
455 (if speedbar-timer | 1140 (if speedbar-timer |
456 (progn (delete-itimer speedbar-timer) | 1141 (progn (delete-itimer speedbar-timer) |
457 (setq speedbar-timer nil))) | 1142 (setq speedbar-timer nil))) |
458 (if timeout | 1143 (if timeout |
459 (setq speedbar-timer (start-itimer "speedbar" | 1144 (setq speedbar-timer (start-itimer "speedbar" |
460 'speedbar-timer-fn | 1145 'speedbar-timer-fn |
461 timeout | 1146 timeout |
462 nil)))) | 1147 nil)))) |
463 ;; GNU emacs | 1148 ;; Post 19.31 Emacs |
464 (t | 1149 ((fboundp 'run-with-idle-timer) |
465 (if speedbar-timer | 1150 (if speedbar-timer |
466 (progn (cancel-timer speedbar-timer) | 1151 (progn (cancel-timer speedbar-timer) |
467 (setq speedbar-timer nil))) | 1152 (setq speedbar-timer nil))) |
468 (if timeout | 1153 (if timeout |
469 (setq speedbar-timer | 1154 (setq speedbar-timer |
470 (run-with-idle-timer timeout nil 'speedbar-timer-fn)))) | 1155 (run-with-idle-timer timeout nil 'speedbar-timer-fn)))) |
471 )) | 1156 ;; Older or other Emacsen with no timers. Set up so that it's |
1157 ;; obvious this emacs can't handle the updates | |
1158 (t | |
1159 (setq speedbar-update-flag nil))) | |
1160 ;; change this if it changed for some reason | |
1161 (speedbar-set-mode-line-format)) | |
472 | 1162 |
473 (defmacro speedbar-with-writable (&rest forms) | 1163 (defmacro speedbar-with-writable (&rest forms) |
474 "Allow the buffer to be writable and evaluate forms. Turn read-only back | 1164 "Allow the buffer to be writable and evaluate FORMS. |
475 on when done." | 1165 Turn read only back on when done." |
476 (list 'let '((speedbar-with-writable-buff (current-buffer))) | 1166 (list 'let '((speedbar-with-writable-buff (current-buffer))) |
477 '(toggle-read-only -1) | 1167 '(toggle-read-only -1) |
478 (cons 'progn forms) | 1168 (cons 'progn forms) |
479 '(save-excursion (set-buffer speedbar-with-writable-buff) | 1169 '(save-excursion (set-buffer speedbar-with-writable-buff) |
480 (toggle-read-only 1)))) | 1170 (toggle-read-only 1)))) |
481 (put 'speedbar-with-writable 'lisp-indent-function 0) | 1171 (put 'speedbar-with-writable 'lisp-indent-function 0) |
482 | 1172 |
1173 (defun speedbar-select-window (buffer) | |
1174 "Select a window in which BUFFER is show. | |
1175 If it is not shown, force it to appear in the default window." | |
1176 (let ((win (get-buffer-window buffer speedbar-attached-frame))) | |
1177 (if win | |
1178 (select-window win) | |
1179 (show-buffer (selected-window) buffer)))) | |
1180 | |
1181 (defmacro speedbar-with-attached-buffer (&rest forms) | |
1182 "Execute FORMS in the attached frame's special buffer. | |
1183 Optionally select that frame if necessary." | |
1184 ;; Reset the timer with a new timeout when cliking a file | |
1185 ;; in case the user was navigating directories, we can cancel | |
1186 ;; that other timer. | |
1187 (list | |
1188 'progn | |
1189 '(speedbar-set-timer speedbar-update-speed) | |
1190 (list | |
1191 'let '((cf (selected-frame))) | |
1192 '(select-frame speedbar-attached-frame) | |
1193 '(speedbar-select-window speedbar-desired-buffer) | |
1194 (cons 'progn forms) | |
1195 '(select-frame cf) | |
1196 '(speedbar-maybee-jump-to-attached-frame) | |
1197 ))) | |
1198 | |
1199 (defun speedbar-insert-button (text face mouse function | |
1200 &optional token prevline) | |
1201 "Insert TEXT as the next logical speedbar button. | |
1202 FACE is the face to put on the button, MOUSE is the highlight face to use. | |
1203 When the user clicks on TEXT, FUNCTION is called with the TOKEN parameter. | |
1204 This function assumes that the current buffer is the speedbar buffer. | |
1205 If PREVLINE, then put this button on the previous line. | |
1206 | |
1207 This is a convenience function for special mode that create their own | |
1208 specialized speedbar displays." | |
1209 (goto-char (point-max)) | |
1210 (if (/= (current-column) 0) (insert "\n")) | |
1211 (if prevline (progn (delete-char -1) (insert " "))) ;back up if desired... | |
1212 (let ((start (point))) | |
1213 (insert text) | |
1214 (speedbar-make-button start (point) face mouse function token)) | |
1215 (let ((start (point))) | |
1216 (insert "\n") | |
1217 (put-text-property start (point) 'face nil) | |
1218 (put-text-property start (point) 'mouse-face nil))) | |
1219 | |
483 (defun speedbar-make-button (start end face mouse function &optional token) | 1220 (defun speedbar-make-button (start end face mouse function &optional token) |
484 "Create a button from START to END, with FACE as the display face | 1221 "Create a button from START to END, with FACE as the display face. |
485 and MOUSE and the mouse face. When this button is clicked on FUNCTION | 1222 MOUSE is the mouse face. When this button is clicked on FUNCTION |
486 will be run with the token parameter of TOKEN (any lisp object)" | 1223 will be run with the TOKEN parameter (any lisp object)" |
487 (put-text-property start end 'face face) | 1224 (put-text-property start end 'face face) |
488 (put-text-property start end 'mouse-face mouse) | 1225 (put-text-property start end 'mouse-face mouse) |
489 (put-text-property start end 'invisible nil) | 1226 (put-text-property start end 'invisible nil) |
490 (if function (put-text-property start end 'speedbar-function function)) | 1227 (if function (put-text-property start end 'speedbar-function function)) |
491 (if token (put-text-property start end 'speedbar-token token)) | 1228 (if token (put-text-property start end 'speedbar-token token)) |
492 ) | 1229 ) |
493 | 1230 |
1231 ;;; File button management | |
1232 ;; | |
494 (defun speedbar-file-lists (directory) | 1233 (defun speedbar-file-lists (directory) |
495 "Create file lists for DIRECTORY. The car is the list of | 1234 "Create file lists for DIRECTORY. |
496 directories, the cdr is list of files not matching ignored headers." | 1235 The car is the list of directories, the cdr is list of files not |
497 (let ((default-directory directory) | 1236 matching ignored headers. Cache any directory files found in |
498 (dir (directory-files directory nil)) | 1237 `speedbar-directory-contents-alist' and use that cache before scanning |
499 (dirs nil) | 1238 the file-system" |
500 (files nil)) | 1239 (setq directory (expand-file-name directory)) |
501 (while dir | 1240 ;; If in powerclick mode, then the directory we are getting |
502 (if (not (string-match speedbar-file-unshown-regexp (car dir))) | 1241 ;; should be rescanned. |
503 (if (file-directory-p (car dir)) | 1242 (if speedbar-power-click |
504 (setq dirs (cons (car dir) dirs)) | 1243 (adelete 'speedbar-directory-contents-alist directory)) |
505 (setq files (cons (car dir) files)))) | 1244 ;; find the directory, either in the cache, or build it. |
506 (setq dir (cdr dir))) | 1245 (or (cdr-safe (assoc directory speedbar-directory-contents-alist)) |
507 (cons (nreverse dirs) (list (nreverse files)))) | 1246 (let ((default-directory directory) |
508 ) | 1247 (dir (directory-files directory nil)) |
1248 (dirs nil) | |
1249 (files nil)) | |
1250 (while dir | |
1251 (if (not (string-match speedbar-file-unshown-regexp (car dir))) | |
1252 (if (file-directory-p (car dir)) | |
1253 (setq dirs (cons (car dir) dirs)) | |
1254 (setq files (cons (car dir) files)))) | |
1255 (setq dir (cdr dir))) | |
1256 (let ((nl (cons (nreverse dirs) (list (nreverse files))))) | |
1257 (aput 'speedbar-directory-contents-alist directory nl) | |
1258 nl)) | |
1259 )) | |
509 | 1260 |
510 (defun speedbar-directory-buttons (directory index) | 1261 (defun speedbar-directory-buttons (directory index) |
511 "Inserts a single button group at point for DIRECTORY. Each directory | 1262 "Insert a single button group at point for DIRECTORY. |
512 path part is a different button. If part of the path matches the user | 1263 Each directory path part is a different button. If part of the path |
513 directory ~, then it is replaced with a ~" | 1264 matches the user directory ~, then it is replaced with a ~. |
1265 INDEX is not used, but is required by the caller." | |
514 (let* ((tilde (expand-file-name "~")) | 1266 (let* ((tilde (expand-file-name "~")) |
515 (dd (expand-file-name directory)) | 1267 (dd (expand-file-name directory)) |
516 (junk (string-match (regexp-quote tilde) dd)) | 1268 (junk (string-match (regexp-quote tilde) dd)) |
517 (displayme (if junk | 1269 (displayme (if junk |
518 (concat "~" (substring dd (match-end 0))) | 1270 (concat "~" (substring dd (match-end 0))) |
528 'speedbar-highlight-face | 1280 'speedbar-highlight-face |
529 'speedbar-directory-buttons-follow | 1281 'speedbar-directory-buttons-follow |
530 (if (= (match-beginning 1) p) | 1282 (if (= (match-beginning 1) p) |
531 (expand-file-name "~/") ;the tilde | 1283 (expand-file-name "~/") ;the tilde |
532 (buffer-substring-no-properties | 1284 (buffer-substring-no-properties |
533 p (match-end 0)))))) | 1285 p (match-end 0))))) |
1286 ;; Nuke the beginning of the directory if it's too long... | |
1287 (cond ((eq speedbar-directory-button-trim-method 'span) | |
1288 (beginning-of-line) | |
1289 (let ((ww (or (speedbar-frame-width) 20))) | |
1290 (move-to-column ww nil) | |
1291 (while (>= (current-column) ww) | |
1292 (re-search-backward "/" nil t) | |
1293 (if (<= (current-column) 2) | |
1294 (progn | |
1295 (re-search-forward "/" nil t) | |
1296 (if (< (current-column) 4) | |
1297 (re-search-forward "/" nil t)) | |
1298 (forward-char -1))) | |
1299 (if (looking-at "/?$") | |
1300 (beginning-of-line) | |
1301 (insert "/...\n ") | |
1302 (move-to-column ww nil))))) | |
1303 ((eq speedbar-directory-button-trim-method 'trim) | |
1304 (end-of-line) | |
1305 (let ((ww (or (speedbar-frame-width) 20)) | |
1306 (tl (current-column))) | |
1307 (if (< ww tl) | |
1308 (progn | |
1309 (move-to-column (- tl ww)) | |
1310 (if (re-search-backward "/" nil t) | |
1311 (progn | |
1312 (delete-region (point-min) (point)) | |
1313 (insert "$") | |
1314 ))))))) | |
1315 ) | |
534 (if (string-match "^/[^/]+/$" displayme) | 1316 (if (string-match "^/[^/]+/$" displayme) |
535 (progn | 1317 (progn |
536 (insert " ") | 1318 (insert " ") |
537 (let ((p (point))) | 1319 (let ((p (point))) |
538 (insert "<root>") | 1320 (insert "<root>") |
539 (speedbar-make-button p (point) | 1321 (speedbar-make-button p (point) |
540 'speedbar-directory-face | 1322 'speedbar-directory-face |
541 'speedbar-highlight-face | 1323 'speedbar-highlight-face |
542 'speedbar-directory-buttons-follow | 1324 'speedbar-directory-buttons-follow |
543 "/")))) | 1325 "/")))) |
1326 (end-of-line) | |
544 (insert-char ?\n 1 nil))) | 1327 (insert-char ?\n 1 nil))) |
545 | 1328 |
546 (defun speedbar-make-tag-line (exp-button-type | 1329 (defun speedbar-make-tag-line (exp-button-type |
547 exp-button-char exp-button-function | 1330 exp-button-char exp-button-function |
548 exp-button-data | 1331 exp-button-data |
549 tag-button tag-button-function tag-button-data | 1332 tag-button tag-button-function tag-button-data |
550 tag-button-face depth) | 1333 tag-button-face depth) |
551 "Creates a tag line with BUTTON-TYPE for the small button that | 1334 "Create a tag line with EXP-BUTTON-TYPE for the small expansion button. |
552 expands or contracts a node (if applicable), and BUTTON-CHAR the | 1335 This is the button that expands or contracts a node (if applicable), |
553 character in it (+, -, ?, etc). BUTTON-FUNCTION is the function to | 1336 and EXP-BUTTON-CHAR the character in it (+, -, ?, etc). EXP-BUTTON-FUNCTION |
554 call if it's clicked on. Button types are 'bracket, 'angle, 'curly, or nil. | 1337 is the function to call if it's clicked on. Button types are |
555 | 1338 'bracket, 'angle, 'curly, or nil. EXP-BUTTON-DATA is extra data |
556 Next, TAG-BUTTON is the text of the tag. TAG-FUNCTION is the function | 1339 attached to the text forming the expansion button. |
557 to call if clicked on, and TAG-DATA is the data to attach to the text | 1340 |
558 field (such a tag positioning, etc). TAG-FACE is a face used for this | 1341 Next, TAG-BUTTON is the text of the tag. TAG-BUTTON-FUNCTION is the |
559 type of tag. | 1342 function to call if clicked on, and TAG-BUTTON-DATA is the data to |
1343 attach to the text field (such a tag positioning, etc). | |
1344 TAG-BUTTON-FACE is a face used for this type of tag. | |
560 | 1345 |
561 Lastly, DEPTH shows the depth of expansion. | 1346 Lastly, DEPTH shows the depth of expansion. |
562 | 1347 |
563 This function assumes that the cursor is in the speecbar window at the | 1348 This function assumes that the cursor is in the speedbar window at the |
564 position to insert a new item, and that the new item will end with a CR" | 1349 position to insert a new item, and that the new item will end with a CR" |
565 (let ((start (point)) | 1350 (let ((start (point)) |
566 (end (progn | 1351 (end (progn |
567 (insert (int-to-string depth) ":") | 1352 (insert (int-to-string depth) ":") |
568 (point)))) | 1353 (point)))) |
586 (put-text-property (1- (point)) (point) 'invisible nil) | 1371 (put-text-property (1- (point)) (point) 'invisible nil) |
587 (let ((start (point)) | 1372 (let ((start (point)) |
588 (end (progn (insert tag-button) (point)))) | 1373 (end (progn (insert tag-button) (point)))) |
589 (insert-char ?\n 1 nil) | 1374 (insert-char ?\n 1 nil) |
590 (put-text-property (1- (point)) (point) 'invisible nil) | 1375 (put-text-property (1- (point)) (point) 'invisible nil) |
591 (speedbar-make-button start end tag-button-face | 1376 (speedbar-make-button start end tag-button-face |
592 (if tag-button-function 'speedbar-highlight-face nil) | 1377 (if tag-button-function 'speedbar-highlight-face nil) |
593 tag-button-function tag-button-data)) | 1378 tag-button-function tag-button-data)) |
594 ) | 1379 ) |
595 | 1380 |
596 (defun speedbar-change-expand-button-char (char) | 1381 (defun speedbar-change-expand-button-char (char) |
597 "Change the expanson button character to CHAR for the current line." | 1382 "Change the expansion button character to CHAR for the current line." |
598 (save-excursion | 1383 (save-excursion |
599 (beginning-of-line) | 1384 (beginning-of-line) |
600 (if (re-search-forward ":\\s-*.\\([-+?]\\)" (save-excursion (end-of-line) | 1385 (if (re-search-forward ":\\s-*.\\([-+?]\\)" (save-excursion (end-of-line) |
601 (point)) t) | 1386 (point)) t) |
602 (speedbar-with-writable | 1387 (speedbar-with-writable |
603 (goto-char (match-beginning 1)) | 1388 (goto-char (match-beginning 1)) |
604 (delete-char 1) | 1389 (delete-char 1) |
605 (insert-char char 1 t))))) | 1390 (insert-char char 1 t))))) |
606 | 1391 |
607 | 1392 |
608 ;;; | |
609 ;;; Build button lists | 1393 ;;; Build button lists |
610 ;;; | 1394 ;; |
611 (defun speedbar-insert-files-at-point (files level) | 1395 (defun speedbar-insert-files-at-point (files level) |
612 "Insert list of FILES starting at point, and indenting all files to LEVEL | 1396 "Insert list of FILES starting at point, and indenting all files to LEVEL. |
613 depth. Tag exapndable items with a +, otherwise a ?. Don't highlight ? as | 1397 Tag expandable items with a +, otherwise a ?. Don't highlight ? as we |
614 we don't know how to manage them. The input parameter FILES is a cons | 1398 don't know how to manage them. The input parameter FILES is a cons |
615 cell of the form ( 'dir-list . 'file-list )" | 1399 cell of the form ( 'DIRLIST . 'FILELIST )" |
616 ;; Start inserting all the directories | 1400 ;; Start inserting all the directories |
617 (let ((dirs (car files))) | 1401 (let ((dirs (car files))) |
618 (while dirs | 1402 (while dirs |
619 (speedbar-make-tag-line 'angle ?+ 'speedbar-dired (car dirs) | 1403 (speedbar-make-tag-line 'angle ?+ 'speedbar-dired (car dirs) |
620 (car dirs) 'speedbar-dir-follow nil | 1404 (car dirs) 'speedbar-dir-follow nil |
630 (car lst) 'speedbar-find-file nil | 1414 (car lst) 'speedbar-find-file nil |
631 'speedbar-file-face level))) | 1415 'speedbar-file-face level))) |
632 (setq lst (cdr lst))))) | 1416 (setq lst (cdr lst))))) |
633 | 1417 |
634 (defun speedbar-default-directory-list (directory index) | 1418 (defun speedbar-default-directory-list (directory index) |
635 "Inserts files for DIRECTORY with level INDEX at point" | 1419 "Insert files for DIRECTORY with level INDEX at point." |
636 (speedbar-insert-files-at-point | 1420 (speedbar-insert-files-at-point |
637 (speedbar-file-lists directory) index) | 1421 (speedbar-file-lists directory) index) |
638 ) | 1422 (speedbar-reset-scanners) |
1423 (if (= index 0) | |
1424 ;; If the shown files variable has extra directories, then | |
1425 ;; it is our responsibility to redraw them all | |
1426 ;; Luckilly, the nature of inserting items into this list means | |
1427 ;; that by reversing it, we can easilly go in the right order | |
1428 (let ((sf (cdr (reverse speedbar-shown-directories)))) | |
1429 (setq speedbar-shown-directories | |
1430 (list (expand-file-name default-directory))) | |
1431 ;; exand them all as we find them | |
1432 (while sf | |
1433 (if (speedbar-goto-this-file (car sf)) | |
1434 (progn | |
1435 (beginning-of-line) | |
1436 (if (looking-at "[0-9]+:[ ]*<") | |
1437 (progn | |
1438 (goto-char (match-end 0)) | |
1439 (speedbar-do-function-pointer))) | |
1440 (setq sf (cdr sf))))) | |
1441 ))) | |
639 | 1442 |
640 (defun speedbar-insert-generic-list (level lst expand-fun find-fun) | 1443 (defun speedbar-insert-generic-list (level lst expand-fun find-fun) |
641 "At LEVEL, inserts a generic multi-level alist LIST. Associations with | 1444 "At LEVEL, insert a generic multi-level alist LST. |
642 lists get {+} tags (to expand into more nodes) and those with positions | 1445 Associations with lists get {+} tags (to expand into more nodes) and |
643 just get a > as the indicator. {+} buttons will have the function | 1446 those with positions just get a > as the indicator. {+} buttons will |
644 EXPAND-FUN and the token is the CDR list. The token name will have the | 1447 have the function EXPAND-FUN and the token is the CDR list. The token |
645 function FIND-FUN and not token." | 1448 name will have the function FIND-FUN and not token." |
646 ;; Remove imenu rescan button | 1449 ;; Remove imenu rescan button |
647 (if (string= (car (car lst)) "*Rescan*") | 1450 (if (string= (car (car lst)) "*Rescan*") |
648 (setq lst (cdr lst))) | 1451 (setq lst (cdr lst))) |
649 ;; insert the parts | 1452 ;; insert the parts |
650 (while lst | 1453 (while lst |
651 (cond ((null (car-safe lst)) nil) ;this would be a separator | 1454 (cond ((null (car-safe lst)) nil) ;this would be a separator |
652 ((numberp (cdr-safe (car-safe lst))) | 1455 ((or (numberp (cdr-safe (car-safe lst))) |
1456 (markerp (cdr-safe (car-safe lst)))) | |
653 (speedbar-make-tag-line nil nil nil nil ;no expand button data | 1457 (speedbar-make-tag-line nil nil nil nil ;no expand button data |
654 (car (car lst)) ;button name | 1458 (car (car lst)) ;button name |
655 find-fun ;function | 1459 find-fun ;function |
656 (cdr (car lst)) ;token is position | 1460 (cdr (car lst)) ;token is position |
657 'speedbar-tag-face | 1461 'speedbar-tag-face |
658 (1+ level))) | 1462 (1+ level))) |
659 ((listp (cdr-safe (car-safe lst))) | 1463 ((listp (cdr-safe (car-safe lst))) |
660 (speedbar-make-tag-line 'curly ?+ expand-fun (cdr (car lst)) | 1464 (speedbar-make-tag-line 'curly ?+ expand-fun (cdr (car lst)) |
661 (car (car lst)) ;button name | 1465 (car (car lst)) ;button name |
662 nil nil 'speedbar-tag-face | 1466 nil nil 'speedbar-tag-face |
663 (1+ level))) | 1467 (1+ level))) |
664 (t (message "Ooops!"))) | 1468 (t (message "Ooops!"))) |
665 (setq lst (cdr lst)))) | 1469 (setq lst (cdr lst)))) |
666 | 1470 |
667 ;;; | |
668 ;;; Timed functions | 1471 ;;; Timed functions |
669 ;;; | 1472 ;; |
670 (defun speedbar-update-contents () | 1473 (defun speedbar-update-contents () |
671 "Update the contents of the speedbar buffer." | 1474 "Generically update the contents of the speedbar buffer." |
672 (interactive) | 1475 (interactive) |
673 (setq speedbar-last-selected-file nil) | 1476 ;; Set the current special buffer |
674 (setq speedbar-shown-directories (list (expand-file-name default-directory))) | 1477 (setq speedbar-desired-buffer nil) |
675 (let ((cbd default-directory) | 1478 (if (and speedbar-mode-specific-contents-flag |
676 (funclst speedbar-initial-expansion-list)) | 1479 speedbar-special-mode-expansion-list |
1480 (local-variable-p | |
1481 'speedbar-special-mode-expansion-list)) | |
1482 ;(eq (get major-mode 'mode-class 'special))) | |
1483 (speedbar-update-special-contents) | |
1484 (speedbar-update-directory-contents))) | |
1485 | |
1486 (defun speedbar-update-directory-contents () | |
1487 "Update the contents of the speedbar buffer based on the current directory." | |
1488 (let ((cbd (expand-file-name default-directory)) | |
1489 (funclst speedbar-initial-expansion-list) | |
1490 (cache speedbar-full-text-cache) | |
1491 ;; disable stealth during update | |
1492 (speedbar-stealthy-function-list nil) | |
1493 (use-cache nil) | |
1494 ;; Because there is a bug I can't find just yet | |
1495 (inhibit-quit nil)) | |
677 (save-excursion | 1496 (save-excursion |
678 (set-buffer speedbar-buffer) | 1497 (set-buffer speedbar-buffer) |
1498 ;; If we are updating contents to a where we are, then this is | |
1499 ;; really a request to update existing contents, so we must be | |
1500 ;; careful with our text cache! | |
1501 (if (member cbd speedbar-shown-directories) | |
1502 (setq cache nil) | |
1503 ;; If this directory is NOT in the current list of available | |
1504 ;; paths, then use the cache, and set the cache to our new | |
1505 ;; value. Make sure to unhighlight the current file, or if we | |
1506 ;; come back to this directory, it might be a different file | |
1507 ;; and then we get a mess! | |
1508 (if (> (point-max) 1) | |
1509 (progn | |
1510 (speedbar-clear-current-file) | |
1511 (setq speedbar-full-text-cache | |
1512 (cons speedbar-shown-directories (buffer-string))))) | |
1513 | |
1514 ;; Check if our new directory is in the list of directories | |
1515 ;; show in the text-cahce | |
1516 (if (member cbd (car cache)) | |
1517 (setq speedbar-shown-directories (car cache) | |
1518 use-cache t) | |
1519 ;; default the shown directories to this list... | |
1520 (setq speedbar-shown-directories (list cbd))) | |
1521 ) | |
1522 (setq speedbar-last-selected-file nil) | |
679 (speedbar-with-writable | 1523 (speedbar-with-writable |
680 (setq default-directory cbd) | 1524 (setq default-directory cbd) |
681 (delete-region (point-min) (point-max)) | 1525 (erase-buffer) |
1526 (if use-cache | |
1527 (insert (cdr cache)) | |
1528 (while funclst | |
1529 (funcall (car funclst) cbd 0) | |
1530 (setq funclst (cdr funclst))))) | |
1531 (goto-char (point-min)))) | |
1532 (speedbar-reconfigure-menubar)) | |
1533 | |
1534 (defun speedbar-update-special-contents () | |
1535 "Used the mode-specific variable to fill in the speedbar buffer. | |
1536 This should only be used by modes classified as special." | |
1537 (let ((funclst speedbar-special-mode-expansion-list) | |
1538 (specialbuff (current-buffer))) | |
1539 (save-excursion | |
1540 (setq speedbar-desired-buffer specialbuff) | |
1541 (set-buffer speedbar-buffer) | |
1542 ;; If we are leaving a directory, cache it. | |
1543 (if (not speedbar-shown-directories) | |
1544 ;; Do nothing | |
1545 nil | |
1546 ;; Clean up directory maintenance stuff | |
1547 (speedbar-clear-current-file) | |
1548 (setq speedbar-full-text-cache | |
1549 (cons speedbar-shown-directories (buffer-string)) | |
1550 speedbar-shown-directories nil)) | |
1551 ;; Now fill in the buffer with our newly found specialized list. | |
1552 (speedbar-with-writable | |
682 (while funclst | 1553 (while funclst |
683 (funcall (car funclst) cbd 0) | 1554 ;; We do not erase the buffer because these functions may |
684 (setq funclst (cdr funclst))))))) | 1555 ;; decide NOT to update themselves. |
1556 (funcall (car funclst) specialbuff) | |
1557 (setq funclst (cdr funclst)))) | |
1558 (goto-char (point-min)))) | |
1559 (speedbar-reconfigure-menubar)) | |
685 | 1560 |
686 (defun speedbar-timer-fn () | 1561 (defun speedbar-timer-fn () |
687 "Run whenever emacs is idle to update the speedbar item" | 1562 "Run whenever emacs is idle to update the speedbar item." |
688 (if (not (and speedbar-frame | 1563 (if (not (and (frame-live-p speedbar-frame) |
689 (frame-live-p speedbar-frame) | |
690 speedbar-attached-frame | |
691 (frame-live-p speedbar-attached-frame))) | 1564 (frame-live-p speedbar-attached-frame))) |
692 (speedbar-set-timer nil) | 1565 (speedbar-set-timer nil) |
693 (unwind-protect | 1566 (condition-case nil |
694 (if (frame-visible-p speedbar-frame) | 1567 ;; Save all the match data so that we don't mess up executing fns |
695 (let ((af (selected-frame))) | 1568 (save-match-data |
696 (save-window-excursion | 1569 (if (and (frame-visible-p speedbar-frame) speedbar-update-flag) |
697 (select-frame speedbar-attached-frame) | 1570 (let ((af (selected-frame))) |
698 ;; make sure we at least choose a window to | 1571 (save-window-excursion |
699 ;; get a good directory from | 1572 (select-frame speedbar-attached-frame) |
700 (if (string-match "\\*Minibuf-[0-9]+\\*" (buffer-name)) | 1573 ;; make sure we at least choose a window to |
701 (other-window 1)) | 1574 ;; get a good directory from |
702 ;; Update all the contents if directories change! | 1575 (if (string-match "\\*Minibuf-[0-9]+\\*" (buffer-name)) |
703 (if (or (member (expand-file-name default-directory) | 1576 (other-window 1)) |
704 speedbar-shown-directories) | 1577 ;; Update for special mode all the time! |
705 (eq af speedbar-frame) | 1578 (if (and speedbar-mode-specific-contents-flag |
706 (not (buffer-file-name)) | 1579 speedbar-special-mode-expansion-list |
707 ) | 1580 (local-variable-p |
708 nil | 1581 'speedbar-special-mode-expansion-list)) |
709 (message "Updating speedbar to: %s..." default-directory) | 1582 ;(eq (get major-mode 'mode-class 'special))) |
710 (speedbar-update-contents) | 1583 (speedbar-update-special-contents) |
711 (message "Updating speedbar to: %s...done" default-directory))))) | 1584 ;; Update all the contents if directories change! |
712 ;; Reset the timer | 1585 (if (or (member (expand-file-name default-directory) |
713 (speedbar-set-timer speedbar-update-speed) | 1586 speedbar-shown-directories) |
714 ;; Ok, un-underline old file, underline current file | 1587 (string-match speedbar-ignored-path-regexp |
715 (speedbar-update-current-file))) | 1588 (expand-file-name default-directory)) |
1589 (member major-mode speedbar-ignored-modes) | |
1590 (eq af speedbar-frame) | |
1591 (not (buffer-file-name))) | |
1592 nil | |
1593 (if (<= 1 speedbar-verbosity-level) | |
1594 (message "Updating speedbar to: %s..." | |
1595 default-directory)) | |
1596 (speedbar-update-directory-contents) | |
1597 (if (<= 1 speedbar-verbosity-level) | |
1598 (message "Updating speedbar to: %s...done" | |
1599 default-directory)))) | |
1600 (select-frame af)) | |
1601 ;; Now run stealthy updates of time-consuming items | |
1602 (speedbar-stealthy-updates)))) | |
1603 ;; errors that might occur | |
1604 (error (message "Speedbar error!"))) | |
1605 ;; Reset the timer | |
1606 (speedbar-set-timer speedbar-update-speed)) | |
716 (run-hooks 'speedbar-timer-hook) | 1607 (run-hooks 'speedbar-timer-hook) |
717 ) | 1608 ) |
718 | 1609 |
1610 | |
1611 ;;; Stealthy activities | |
1612 ;; | |
1613 (defun speedbar-stealthy-updates () | |
1614 "For a given speedbar, run all items in the stealthy function list. | |
1615 Each item returns t if it completes successfully, or nil if | |
1616 interrupted by the user." | |
1617 (let ((l speedbar-stealthy-function-list)) | |
1618 (unwind-protect | |
1619 (while (and l (funcall (car l))) | |
1620 (sit-for 0) | |
1621 (setq l (cdr l))) | |
1622 ;(message "Exit with %S" (car l)) | |
1623 ))) | |
1624 | |
1625 (defun speedbar-reset-scanners () | |
1626 "Reset any variables used by functions in the stealthy list as state. | |
1627 If new functions are added, their state needs to be updated here." | |
1628 (setq speedbar-vc-to-do-point t) | |
1629 ) | |
1630 | |
1631 (defun speedbar-clear-current-file () | |
1632 "Locate the file thought to be current, and unhighlight it." | |
1633 (save-excursion | |
1634 (set-buffer speedbar-buffer) | |
1635 (if speedbar-last-selected-file | |
1636 (speedbar-with-writable | |
1637 (goto-char (point-min)) | |
1638 (if (and | |
1639 speedbar-last-selected-file | |
1640 (re-search-forward | |
1641 (concat " \\(" (regexp-quote speedbar-last-selected-file) | |
1642 "\\)\\(" (regexp-quote speedbar-vc-indicator) | |
1643 "\\)?\n") | |
1644 nil t)) | |
1645 (put-text-property (match-beginning 1) | |
1646 (match-end 1) | |
1647 'face | |
1648 'speedbar-file-face)))))) | |
1649 | |
719 (defun speedbar-update-current-file () | 1650 (defun speedbar-update-current-file () |
720 "Find out what the current file is, and update our visuals to indicate | 1651 "Find the current file is, and update our visuals to indicate its name. |
721 what it is. This is specific to file names." | 1652 This is specific to file names. If the file name doesn't show up, but |
1653 it should be in the list, then the directory cache needs to be | |
1654 updated." | |
722 (let* ((lastf (selected-frame)) | 1655 (let* ((lastf (selected-frame)) |
723 (newcf (save-excursion | 1656 (newcfd (save-excursion |
724 (select-frame speedbar-attached-frame) | 1657 (select-frame speedbar-attached-frame) |
725 (let ((rf (if (buffer-file-name) | 1658 (let ((rf (if (buffer-file-name) |
726 (file-name-nondirectory (buffer-file-name)) | 1659 (buffer-file-name) |
727 nil))) | 1660 nil))) |
728 (select-frame lastf) | 1661 (select-frame lastf) |
729 rf))) | 1662 rf))) |
730 (lastb (current-buffer))) | 1663 (newcf (if newcfd (file-name-nondirectory newcfd))) |
731 (if (and newcf (not (string= newcf speedbar-last-selected-file))) | 1664 (lastb (current-buffer)) |
1665 (sucf-recursive (boundp 'sucf-recursive))) | |
1666 (if (and newcf | |
1667 ;; check here, that way we won't refresh to newcf until | |
1668 ;; its been written, thus saving ourselves some time | |
1669 (file-exists-p newcf) | |
1670 (not (string= newcf speedbar-last-selected-file))) | |
732 (progn | 1671 (progn |
1672 ;; It is important to select the frame, otherwise the window | |
1673 ;; we want the cursor to move in will not be updated by the | |
1674 ;; search-forward command. | |
733 (select-frame speedbar-frame) | 1675 (select-frame speedbar-frame) |
1676 ;; Remove the old file... | |
1677 (speedbar-clear-current-file) | |
1678 ;; now highlight the new one. | |
734 (set-buffer speedbar-buffer) | 1679 (set-buffer speedbar-buffer) |
735 (speedbar-with-writable | 1680 (speedbar-with-writable |
736 (goto-char (point-min)) | 1681 (goto-char (point-min)) |
737 (if (and | 1682 (if (re-search-forward |
738 speedbar-last-selected-file | 1683 (concat " \\(" (regexp-quote newcf) "\\)\\(" |
739 (re-search-forward | 1684 (regexp-quote speedbar-vc-indicator) |
740 (concat " \\(" (regexp-quote speedbar-last-selected-file) "\\)\n") | 1685 "\\)?\n") nil t) |
741 nil t)) | 1686 ;; put the property on it |
742 (put-text-property (match-beginning 1) | 1687 (put-text-property (match-beginning 1) |
743 (match-end 1) | 1688 (match-end 1) |
744 'face | 1689 'face |
745 'speedbar-file-face)) | 1690 'speedbar-selected-face) |
746 (goto-char (point-min)) | 1691 ;; Oops, it's not in the list. Should it be? |
747 (if (re-search-forward | 1692 (if (and (string-match speedbar-file-regexp newcf) |
748 (concat " \\(" (regexp-quote newcf) "\\)\n") nil t) | 1693 (string= (file-name-directory newcfd) |
749 (put-text-property (match-beginning 1) | 1694 (expand-file-name default-directory))) |
750 (match-end 1) | 1695 ;; yes, it is (we will ignore unknowns for now...) |
751 'face | 1696 (progn |
752 'speedbar-selected-face)) | 1697 (speedbar-refresh) |
1698 (if (re-search-forward | |
1699 (concat " \\(" (regexp-quote newcf) "\\)\n") nil t) | |
1700 ;; put the property on it | |
1701 (put-text-property (match-beginning 1) | |
1702 (match-end 1) | |
1703 'face | |
1704 'speedbar-selected-face))) | |
1705 ;; if it's not in there now, whatever... | |
1706 )) | |
753 (setq speedbar-last-selected-file newcf)) | 1707 (setq speedbar-last-selected-file newcf)) |
754 (forward-line -1) | 1708 (if (not sucf-recursive) |
755 (speedbar-position-cursor-on-line) | 1709 (progn |
1710 (forward-line -1) | |
1711 (speedbar-position-cursor-on-line))) | |
756 (set-buffer lastb) | 1712 (set-buffer lastb) |
757 (select-frame lastf))))) | 1713 (select-frame lastf) |
1714 ))) | |
1715 ;; return that we are done with this activity. | |
1716 t) | |
1717 | |
1718 ;; If it's being used, check for it | |
1719 (eval-when-compile (or (featurep 'xemacs) (require 'ange-ftp))) | |
1720 | |
1721 (defun speedbar-check-vc () | |
1722 "Scan all files in a directory, and for each see if it's checked out. | |
1723 See `speedbar-this-file-in-vc' and `speedbar-vc-check-dir-p' for how | |
1724 to add more types of version control systems." | |
1725 ;; Check for to-do to be reset. If reset but no RCS is available | |
1726 ;; then set to nil (do nothing) otherwise, start at the beginning | |
1727 (save-excursion | |
1728 (set-buffer speedbar-buffer) | |
1729 (if (and speedbar-vc-do-check (eq speedbar-vc-to-do-point t) | |
1730 (speedbar-vc-check-dir-p default-directory) | |
1731 (not (and (featurep 'ange-ftp) | |
1732 (string-match (car | |
1733 (if speedbar-xemacsp | |
1734 ange-ftp-path-format | |
1735 ange-ftp-name-format)) | |
1736 (expand-file-name default-directory))))) | |
1737 (setq speedbar-vc-to-do-point 0)) | |
1738 (if (numberp speedbar-vc-to-do-point) | |
1739 (progn | |
1740 (goto-char speedbar-vc-to-do-point) | |
1741 (while (and (not (input-pending-p)) | |
1742 (re-search-forward "^\\([0-9]+\\):\\s-*\\[[+-]\\] " nil t)) | |
1743 (setq speedbar-vc-to-do-point (point)) | |
1744 (if (speedbar-check-vc-this-line) | |
1745 (speedbar-with-writable | |
1746 (insert speedbar-vc-indicator)))) | |
1747 (if (input-pending-p) | |
1748 ;; return that we are incomplete | |
1749 nil | |
1750 ;; we are done, set to-do to nil | |
1751 (setq speedbar-vc-to-do-point nil) | |
1752 ;; and return t | |
1753 t)) | |
1754 t))) | |
1755 | |
1756 (defun speedbar-check-vc-this-line () | |
1757 "Return t if the file on this line is check of of a version control system. | |
1758 The one caller-requirement is that the last regexp matching operation | |
1759 has the current depth stored in (MATCHSTRING 1), and that the cursor | |
1760 is right in front of the file name." | |
1761 (let* ((d (string-to-int (match-string 1))) | |
1762 (f (speedbar-line-path d)) | |
1763 (fn (buffer-substring-no-properties | |
1764 (point) (progn (end-of-line) (point)))) | |
1765 (fulln (concat f fn))) | |
1766 (if (<= 2 speedbar-verbosity-level) | |
1767 (message "Speedbar vc check...%s" fulln)) | |
1768 (and (file-writable-p fulln) | |
1769 (speedbar-this-file-in-vc f fn)))) | |
1770 | |
1771 (defun speedbar-vc-check-dir-p (path) | |
1772 "Return t if we should bother checking PATH for version control files. | |
1773 This can be overloaded to add new types of version control systems." | |
1774 (or | |
1775 (file-exists-p (concat path "RCS/")) | |
1776 ;; If SCCS is added in `speedbar-this-file-in-vc' | |
1777 ;; (file-exists-p (concat path "SCCS/")) | |
1778 ;; (file-exists-p (getenv "SCCSPATHTHINGIDONTREMEMBER")) | |
1779 )) | |
1780 | |
1781 (defun speedbar-this-file-in-vc (path name) | |
1782 "Check to see if the file in PATH with NAME is in a version control system. | |
1783 You can add new VC systems by overriding this function. You can | |
1784 optimize this function by overriding it and only doing those checks | |
1785 that will occur on your system." | |
1786 (or | |
1787 (file-exists-p (concat path "RCS/" name ",v")) | |
1788 ;; Is this right? I don't recall | |
1789 ;;(file-exists-p (concat path "SCCS/," fn)) | |
1790 ;;(file-exists-p (concat (getenv "SCCSPATHTHING") "/SCCS/," fn)) | |
1791 )) | |
758 | 1792 |
759 ;;; | |
760 ;;; Clicking Activity | 1793 ;;; Clicking Activity |
761 ;;; | 1794 ;; |
762 (defun speedbar-quick-mouse (e) | 1795 (defun speedbar-quick-mouse (e) |
763 "Since mouse events are strange, this will keep the mouse nicely | 1796 "Since mouse events are strange, this will keep the mouse nicely positioned. |
764 positioned." | 1797 This should be bound to mouse event E." |
765 (interactive "e") | 1798 (interactive "e") |
766 (mouse-set-point e) | 1799 (mouse-set-point e) |
767 (beginning-of-line) | 1800 (speedbar-position-cursor-on-line) |
768 (forward-char 3) | |
769 ) | 1801 ) |
770 | 1802 |
771 (defun speedbar-position-cursor-on-line () | 1803 (defun speedbar-position-cursor-on-line () |
772 "Position the cursor on a line." | 1804 "Position the cursor on a line." |
773 (beginning-of-line) | 1805 (let ((oldpos (point))) |
774 (re-search-forward "[]>}]" (save-excursion (end-of-line) (point)) t)) | 1806 (beginning-of-line) |
1807 (if (looking-at "[0-9]+:\\s-*..?.? ") | |
1808 (goto-char (1- (match-end 0))) | |
1809 (goto-char oldpos)))) | |
1810 | |
1811 (defun speedbar-power-click (e) | |
1812 "Activate any speedbar button as a power click. | |
1813 This should be bound to mouse event E." | |
1814 (interactive "e") | |
1815 (let ((speedbar-power-click t)) | |
1816 (speedbar-click e))) | |
1817 | |
1818 (defun speedbar-click (e) | |
1819 "Activate any speedbar buttons where the mouse is clicked. | |
1820 This must be bound to a mouse event. A button is any location of text | |
1821 with a mouse face that has a text property called `speedbar-function'. | |
1822 This should be bound to mouse event E." | |
1823 (interactive "e") | |
1824 (mouse-set-point e) | |
1825 (speedbar-do-function-pointer) | |
1826 (speedbar-quick-mouse e)) | |
1827 | |
1828 (defun speedbar-do-function-pointer () | |
1829 "Look under the cursor and examine the text properties. | |
1830 From this extract the file/tag name, token, indentation level and call | |
1831 a function if appropriate" | |
1832 (let* ((fn (get-text-property (point) 'speedbar-function)) | |
1833 (tok (get-text-property (point) 'speedbar-token)) | |
1834 ;; The 1-,+ is safe because scaning starts AFTER the point | |
1835 ;; specified. This lets the search include the character the | |
1836 ;; cursor is on. | |
1837 (tp (previous-single-property-change | |
1838 (1+ (point)) 'speedbar-function)) | |
1839 (np (next-single-property-change | |
1840 (point) 'speedbar-function)) | |
1841 (txt (buffer-substring-no-properties (or tp (point-min)) | |
1842 (or np (point-max)))) | |
1843 (dent (save-excursion (beginning-of-line) | |
1844 (string-to-number | |
1845 (if (looking-at "[0-9]+") | |
1846 (buffer-substring-no-properties | |
1847 (match-beginning 0) (match-end 0)) | |
1848 "0"))))) | |
1849 ;;(message "%S:%S:%S:%s" fn tok txt dent) | |
1850 (and fn (funcall fn txt tok dent))) | |
1851 (speedbar-position-cursor-on-line)) | |
1852 | |
1853 ;;; Reading info from the speedbar buffer | |
1854 ;; | |
1855 (defun speedbar-line-file (&optional p) | |
1856 "Retrieve the file or whatever from the line at P point. | |
1857 The return value is a string representing the file. If it is a | |
1858 directory, then it is the directory name." | |
1859 (save-excursion | |
1860 (save-match-data | |
1861 (beginning-of-line) | |
1862 (if (looking-at (concat | |
1863 "\\([0-9]+\\): *[[<][-+][]>] \\([^ \n]+\\)\\(" | |
1864 (regexp-quote speedbar-vc-indicator) | |
1865 "\\)?")) | |
1866 (let* ((depth (string-to-int (match-string 1))) | |
1867 (path (speedbar-line-path depth)) | |
1868 (f (match-string 2))) | |
1869 (concat path f)) | |
1870 nil)))) | |
1871 | |
1872 (defun speedbar-goto-this-file (file) | |
1873 "If FILE is displayed, goto this line and return t. | |
1874 Otherwise do not move and return nil." | |
1875 (let ((path (substring (file-name-directory (expand-file-name file)) | |
1876 (length (expand-file-name default-directory)))) | |
1877 (dest (point))) | |
1878 (save-match-data | |
1879 (goto-char (point-min)) | |
1880 ;; scan all the directories | |
1881 (while (and path (not (eq path t))) | |
1882 (if (string-match "^/?\\([^/]+\\)" path) | |
1883 (let ((pp (match-string 1 path))) | |
1884 (if (save-match-data | |
1885 (re-search-forward (concat "> " (regexp-quote pp) "$") | |
1886 nil t)) | |
1887 (setq path (substring path (match-end 1))) | |
1888 (setq path nil))) | |
1889 (setq path t))) | |
1890 ;; find the file part | |
1891 (if (or (not path) (string= (file-name-nondirectory file) "")) | |
1892 ;; only had a dir part | |
1893 (if path | |
1894 (progn | |
1895 (speedbar-position-cursor-on-line) | |
1896 t) | |
1897 (goto-char dest) nil) | |
1898 ;; find the file part | |
1899 (let ((nd (file-name-nondirectory file))) | |
1900 (if (re-search-forward | |
1901 (concat "] \\(" (regexp-quote nd) | |
1902 "\\)\\(" (regexp-quote speedbar-vc-indicator) "\\)?$") | |
1903 nil t) | |
1904 (progn | |
1905 (speedbar-position-cursor-on-line) | |
1906 t) | |
1907 (goto-char dest) | |
1908 nil)))))) | |
775 | 1909 |
776 (defun speedbar-line-path (depth) | 1910 (defun speedbar-line-path (depth) |
777 "Retrieve the pathname associated with the current line. This may | 1911 "Retrieve the pathname associated with the current line. |
778 require traversing backwards and combinding the default directory with | 1912 This may require traversing backwards from DEPTH and combining the default |
779 these items." | 1913 directory with these items." |
780 (save-excursion | 1914 (save-excursion |
781 (let ((path nil)) | 1915 (save-match-data |
782 (setq depth (1- depth)) | 1916 (let ((path nil)) |
783 (while (/= depth -1) | 1917 (setq depth (1- depth)) |
784 (if (not (re-search-backward (format "^%d:" depth) nil t)) | 1918 (while (/= depth -1) |
785 (error "Error building path of tag") | 1919 (if (not (re-search-backward (format "^%d:" depth) nil t)) |
786 (cond ((looking-at "[0-9]+:\\s-*<->\\s-+\\([^\n]+\\)$") | 1920 (error "Error building path of tag") |
787 (setq path (concat (buffer-substring-no-properties | 1921 (cond ((looking-at "[0-9]+:\\s-*<->\\s-+\\([^\n]+\\)$") |
788 (match-beginning 1) (match-end 1)) | 1922 (setq path (concat (buffer-substring-no-properties |
789 "/" | 1923 (match-beginning 1) (match-end 1)) |
790 path))) | 1924 "/" |
791 ((looking-at "[0-9]+:\\s-*[-]\\s-+\\([^\n]+\\)$") | 1925 path))) |
792 ;; This is the start of our path. | 1926 ((looking-at "[0-9]+:\\s-*[-]\\s-+\\([^\n]+\\)$") |
793 (setq path (buffer-substring-no-properties | 1927 ;; This is the start of our path. |
794 (match-beginning 1) (match-end 1)))))) | 1928 (setq path (buffer-substring-no-properties |
795 (setq depth (1- depth))) | 1929 (match-beginning 1) (match-end 1)))))) |
796 (concat default-directory path)))) | 1930 (setq depth (1- depth))) |
1931 (if (and path | |
1932 (string-match (concat (regexp-quote speedbar-vc-indicator) "$") | |
1933 path)) | |
1934 (setq path (substring path 0 (match-beginning 0)))) | |
1935 (concat default-directory path))))) | |
797 | 1936 |
798 (defun speedbar-edit-line () | 1937 (defun speedbar-edit-line () |
799 "Edit whatever tag or file is on the current speedbar line." | 1938 "Edit whatever tag or file is on the current speedbar line." |
800 (interactive) | 1939 (interactive) |
801 (beginning-of-line) | 1940 (save-excursion |
802 (re-search-forward "[]>}] [a-zA-Z0-9]" (save-excursion (end-of-line) (point))) | 1941 (beginning-of-line) |
803 (speedbar-do-function-pointer)) | 1942 ;; If this fails, then it is a non-standard click, and as such, |
1943 ;; perfectly allowed. | |
1944 (re-search-forward "[]>}] [a-zA-Z0-9]" | |
1945 (save-excursion (end-of-line) (point)) t) | |
1946 (speedbar-do-function-pointer))) | |
804 | 1947 |
805 (defun speedbar-expand-line () | 1948 (defun speedbar-expand-line () |
806 "Expand the line under the cursor." | 1949 "Expand the line under the cursor." |
807 (interactive) | 1950 (interactive) |
808 (beginning-of-line) | 1951 (beginning-of-line) |
809 (re-search-forward ":\\s-*.\\+. " (save-excursion (end-of-line) (point))) | 1952 (re-search-forward ":\\s-*.\\+. " (save-excursion (end-of-line) (point))) |
810 (forward-char -2) | 1953 (forward-char -2) |
811 (speedbar-do-function-pointer)) | 1954 (speedbar-do-function-pointer)) |
812 | 1955 |
813 (defun speedbar-contract-line () | 1956 (defun speedbar-contract-line () |
814 "Expand the line under the cursor." | 1957 "Contract the line under the cursor." |
815 (interactive) | 1958 (interactive) |
816 (beginning-of-line) | 1959 (beginning-of-line) |
817 (re-search-forward ":\\s-*.-. " (save-excursion (end-of-line) (point))) | 1960 (re-search-forward ":\\s-*.-. " (save-excursion (end-of-line) (point))) |
818 (forward-char -2) | 1961 (forward-char -2) |
819 (speedbar-do-function-pointer)) | 1962 (speedbar-do-function-pointer)) |
820 | 1963 |
821 (defun speedbar-click (e) | 1964 (defun speedbar-maybee-jump-to-attached-frame () |
822 "When the user clicks mouse 1 on our speedbar, we must decide what | 1965 "Jump to the attached frame ONLY if this was not a mouse event." |
823 we want to do! The entire speedbar has functions attached to | 1966 (if (numberp last-input-char) |
824 buttons. All we have to do is extract from the buffer the information | 1967 (progn |
825 we need. See `speedbar-mode' for the type of behaviour we want to achieve" | 1968 (select-frame speedbar-attached-frame) |
826 (interactive "e") | 1969 (other-frame 0)))) |
827 (mouse-set-point e) | |
828 (speedbar-do-function-pointer)) | |
829 | |
830 (defun speedbar-do-function-pointer () | |
831 "Look under the cursor and examine the text properties. From this extract | |
832 the file/tag name, token, indentation level and call a function if apropriate" | |
833 (let* ((fn (get-text-property (point) 'speedbar-function)) | |
834 (tok (get-text-property (point) 'speedbar-token)) | |
835 ;; The 1-,+ is safe because scaning starts AFTER the point | |
836 ;; specified. This lets the search include the character the | |
837 ;; cursor is on. | |
838 (tp (previous-single-property-change | |
839 (if (get-text-property (1+ (point)) 'speedbar-function) | |
840 (1+ (point)) (point)) 'speedbar-function)) | |
841 (np (next-single-property-change | |
842 (if (and (> (point) 1) (get-text-property (1- (point)) 'speedbar-function)) | |
843 (1- (point)) (point)) 'speedbar-function)) | |
844 (txt (buffer-substring-no-properties (or tp (point-min)) | |
845 (or np (point-max)))) | |
846 (dent (save-excursion (beginning-of-line) | |
847 (string-to-number | |
848 (if (looking-at "[0-9]+") | |
849 (buffer-substring-no-properties | |
850 (match-beginning 0) (match-end 0)) | |
851 "0"))))) | |
852 ;;(message "%S:%S:%S:%s" fn tok txt dent) | |
853 (and fn (funcall fn txt tok dent))) | |
854 (speedbar-position-cursor-on-line)) | |
855 | 1970 |
856 (defun speedbar-find-file (text token indent) | 1971 (defun speedbar-find-file (text token indent) |
857 "Speedbar click handler for filenames. Clicking the filename loads | 1972 "Speedbar click handler for filenames. |
858 that file into the attached buffer." | 1973 TEXT, the file will be displayed in the attached frame. |
1974 TOKEN is unused, but required by the click handler. INDENT is the | |
1975 current indentation level." | |
859 (let ((cdd (speedbar-line-path indent))) | 1976 (let ((cdd (speedbar-line-path indent))) |
860 (select-frame speedbar-attached-frame) | 1977 (speedbar-find-file-in-frame (concat cdd text)) |
861 (find-file (concat cdd text)) | 1978 (speedbar-stealthy-updates) |
862 (speedbar-update-current-file) | |
863 ;; Reset the timer with a new timeout when cliking a file | 1979 ;; Reset the timer with a new timeout when cliking a file |
864 ;; in case the user was navigating directories, we can cancel | 1980 ;; in case the user was navigating directories, we can cancel |
865 ;; that other timer. | 1981 ;; that other timer. |
866 (speedbar-set-timer speedbar-update-speed))) | 1982 (speedbar-set-timer speedbar-update-speed)) |
1983 (speedbar-maybee-jump-to-attached-frame)) | |
867 | 1984 |
868 (defun speedbar-dir-follow (text token indent) | 1985 (defun speedbar-dir-follow (text token indent) |
869 "Speedbar click handler for directory names. Clicking a directory will | 1986 "Speedbar click handler for directory names. |
870 cause the speedbar to list files in the selected subdirectory." | 1987 Clicking a directory will cause the speedbar to list files in the |
871 (setq default-directory | 1988 the subdirectory TEXT. TOKEN is an unused requirement. The |
1989 subdirectory chosen will be at INDENT level." | |
1990 (setq default-directory | |
872 (concat (expand-file-name (concat (speedbar-line-path indent) text)) | 1991 (concat (expand-file-name (concat (speedbar-line-path indent) text)) |
873 "/")) | 1992 "/")) |
874 ;; Because we leave speedbar as the current buffer, | 1993 ;; Because we leave speedbar as the current buffer, |
875 ;; update contents will change directory without | 1994 ;; update contents will change directory without |
876 ;; having to touch the attached frame. | 1995 ;; having to touch the attached frame. |
877 (speedbar-update-contents) | 1996 (speedbar-update-contents) |
878 (speedbar-set-timer speedbar-navigating-speed) | 1997 (speedbar-set-timer speedbar-navigating-speed) |
879 (setq speedbar-last-selected-file nil) | 1998 (setq speedbar-last-selected-file nil) |
880 (speedbar-update-current-file)) | 1999 (speedbar-stealthy-updates)) |
881 | 2000 |
2001 (defun speedbar-delete-subblock (indent) | |
2002 "Delete text from point to indentation level INDENT or greater. | |
2003 Handles end-of-sublist smartly." | |
2004 (speedbar-with-writable | |
2005 (save-excursion | |
2006 (end-of-line) (forward-char 1) | |
2007 (while (and (not (save-excursion | |
2008 (re-search-forward (format "^%d:" indent) | |
2009 nil t))) | |
2010 (>= indent 0)) | |
2011 (setq indent (1- indent))) | |
2012 (delete-region (point) (if (>= indent 0) | |
2013 (match-beginning 0) | |
2014 (point-max)))))) | |
882 | 2015 |
883 (defun speedbar-dired (text token indent) | 2016 (defun speedbar-dired (text token indent) |
884 "Speedbar click handler for filenames. Clicking the filename loads | 2017 "Speedbar click handler for directory expand button. |
885 that file into the attached buffer." | 2018 Clicking this button expands or contracts a directory. TEXT is the |
886 (cond ((string-match "+" text) ;we have to expand this file | 2019 button clicked which has either a + or -. TOKEN is the directory to be |
887 (setq speedbar-shown-directories | 2020 expanded. INDENT is the current indentation level." |
888 (cons (expand-file-name | 2021 (cond ((string-match "+" text) ;we have to expand this dir |
2022 (setq speedbar-shown-directories | |
2023 (cons (expand-file-name | |
889 (concat (speedbar-line-path indent) token "/")) | 2024 (concat (speedbar-line-path indent) token "/")) |
890 speedbar-shown-directories)) | 2025 speedbar-shown-directories)) |
891 (speedbar-change-expand-button-char ?-) | 2026 (speedbar-change-expand-button-char ?-) |
2027 (speedbar-reset-scanners) | |
892 (save-excursion | 2028 (save-excursion |
893 (end-of-line) (forward-char 1) | 2029 (end-of-line) (forward-char 1) |
894 (speedbar-with-writable | 2030 (speedbar-with-writable |
895 (speedbar-default-directory-list | 2031 (speedbar-default-directory-list |
896 (concat (speedbar-line-path indent) token "/") | 2032 (concat (speedbar-line-path indent) token "/") |
897 (1+ indent))))) | 2033 (1+ indent))))) |
898 ((string-match "-" text) ;we have to contract this node | 2034 ((string-match "-" text) ;we have to contract this node |
2035 (speedbar-reset-scanners) | |
899 (let ((oldl speedbar-shown-directories) | 2036 (let ((oldl speedbar-shown-directories) |
900 (newl nil) | 2037 (newl nil) |
901 (td (expand-file-name | 2038 (td (expand-file-name |
902 (concat (speedbar-line-path indent) token)))) | 2039 (concat (speedbar-line-path indent) token)))) |
903 (while oldl | 2040 (while oldl |
904 (if (not (string-match (concat "^" (regexp-quote td)) (car oldl))) | 2041 (if (not (string-match (concat "^" (regexp-quote td)) (car oldl))) |
905 (setq newl (cons (car oldl) newl))) | 2042 (setq newl (cons (car oldl) newl))) |
906 (setq oldl (cdr oldl))) | 2043 (setq oldl (cdr oldl))) |
907 (setq speedbar-shown-directories newl)) | 2044 (setq speedbar-shown-directories newl)) |
908 (speedbar-change-expand-button-char ?+) | 2045 (speedbar-change-expand-button-char ?+) |
909 (save-excursion | 2046 (speedbar-delete-subblock indent) |
910 (end-of-line) (forward-char 1) | |
911 (speedbar-with-writable | |
912 (if (save-excursion (re-search-forward (format "^%d:" indent) nil t)) | |
913 (delete-region (point) (match-beginning 0)) | |
914 (delete-region (point) (point-max))))) | |
915 ) | 2047 ) |
916 (t (error "Ooops... not sure what to do."))) | 2048 (t (error "Ooops... not sure what to do."))) |
917 (speedbar-center-buffer-smartly) | 2049 (speedbar-center-buffer-smartly) |
918 (setq speedbar-last-selected-file nil) | 2050 (setq speedbar-last-selected-file nil) |
919 (save-excursion (speedbar-update-current-file))) | 2051 (save-excursion (speedbar-stealthy-updates))) |
920 | 2052 |
921 (defun speedbar-directory-buttons-follow (text token ident) | 2053 (defun speedbar-directory-buttons-follow (text token indent) |
922 "Speedbar click handler for default directory buttons." | 2054 "Speedbar click handler for default directory buttons. |
2055 TEXT is the button clicked on. TOKEN is the directory to follow. | |
2056 INDENT is the current indentation level and is unused." | |
923 (setq default-directory token) | 2057 (setq default-directory token) |
924 ;; Because we leave speedbar as the current buffer, | 2058 ;; Because we leave speedbar as the current buffer, |
925 ;; update contents will change directory without | 2059 ;; update contents will change directory without |
926 ;; having to touch the attached frame. | 2060 ;; having to touch the attached frame. |
927 (speedbar-update-contents) | 2061 (speedbar-update-contents) |
928 (speedbar-set-timer speedbar-navigating-speed)) | 2062 (speedbar-set-timer speedbar-navigating-speed)) |
929 | 2063 |
930 (defun speedbar-tag-file (text token indent) | 2064 (defun speedbar-tag-file (text token indent) |
931 "The cursor is on a selected line. Expand the tags in the specified | 2065 "The cursor is on a selected line. Expand the tags in the specified file. |
932 file. The parameter TXT and TOK are required, where TXT is the button | 2066 The parameter TEXT and TOKEN are required, where TEXT is the button |
933 clicked, and TOK is the file to expand." | 2067 clicked, and TOKEN is the file to expand. INDENT is the current |
2068 indentation level." | |
934 (cond ((string-match "+" text) ;we have to expand this file | 2069 (cond ((string-match "+" text) ;we have to expand this file |
935 (let* ((fn (expand-file-name (concat (speedbar-line-path indent) | 2070 (let* ((fn (expand-file-name (concat (speedbar-line-path indent) |
936 token))) | 2071 token))) |
937 (lst (if speedbar-use-imenu-package | 2072 (lst (if speedbar-use-imenu-flag |
938 (let ((tim (speedbar-fetch-dynamic-imenu fn))) | 2073 (let ((tim (speedbar-fetch-dynamic-imenu fn))) |
939 (if (eq tim t) | 2074 (if (eq tim t) |
940 (speedbar-fetch-dynamic-etags fn) | 2075 (speedbar-fetch-dynamic-etags fn) |
941 tim)) | 2076 tim)) |
942 (speedbar-fetch-dynamic-etags fn)))) | 2077 (speedbar-fetch-dynamic-etags fn)))) |
950 (speedbar-insert-generic-list indent | 2085 (speedbar-insert-generic-list indent |
951 lst 'speedbar-tag-expand | 2086 lst 'speedbar-tag-expand |
952 'speedbar-tag-find)))))) | 2087 'speedbar-tag-find)))))) |
953 ((string-match "-" text) ;we have to contract this node | 2088 ((string-match "-" text) ;we have to contract this node |
954 (speedbar-change-expand-button-char ?+) | 2089 (speedbar-change-expand-button-char ?+) |
955 (speedbar-with-writable | 2090 (speedbar-delete-subblock indent)) |
956 (save-excursion | |
957 (end-of-line) (forward-char 1) | |
958 (if (save-excursion (re-search-forward (format "^%d:" indent) nil t)) | |
959 (delete-region (point) (match-beginning 0)) | |
960 (delete-region (point) (point-max)))))) | |
961 (t (error "Ooops... not sure what to do."))) | 2091 (t (error "Ooops... not sure what to do."))) |
962 (speedbar-center-buffer-smartly)) | 2092 (speedbar-center-buffer-smartly)) |
963 | 2093 |
964 (defun speedbar-tag-find (text token indent) | 2094 (defun speedbar-tag-find (text token indent) |
965 "For the tag in a file, goto that position" | 2095 "For the tag TEXT in a file TOKEN, goto that position. |
2096 INDENT is the current indentation level." | |
966 (let ((file (speedbar-line-path indent))) | 2097 (let ((file (speedbar-line-path indent))) |
967 (select-frame speedbar-attached-frame) | 2098 (speedbar-find-file-in-frame file) |
968 (find-file file) | 2099 (save-excursion (speedbar-stealthy-updates)) |
969 (save-excursion (speedbar-update-current-file)) | |
970 ;; Reset the timer with a new timeout when cliking a file | 2100 ;; Reset the timer with a new timeout when cliking a file |
971 ;; in case the user was navigating directories, we can cancel | 2101 ;; in case the user was navigating directories, we can cancel |
972 ;; that other timer. | 2102 ;; that other timer. |
973 (speedbar-set-timer speedbar-update-speed) | 2103 (speedbar-set-timer speedbar-update-speed) |
974 (goto-char token))) | 2104 (goto-char token) |
2105 ;;(recenter) | |
2106 (speedbar-maybee-jump-to-attached-frame) | |
2107 )) | |
975 | 2108 |
976 (defun speedbar-tag-expand (text token indent) | 2109 (defun speedbar-tag-expand (text token indent) |
977 "For the tag in a file which is really a list of tags of a certain type, | 2110 "Expand a tag sublist. Imenu will return sub-lists of specialized tag types. |
978 expand or contract that list." | 2111 Etags does not support this feature. TEXT will be the button |
2112 string. TOKEN will be the list, and INDENT is the current indentation | |
2113 level." | |
979 (cond ((string-match "+" text) ;we have to expand this file | 2114 (cond ((string-match "+" text) ;we have to expand this file |
980 (speedbar-change-expand-button-char ?-) | 2115 (speedbar-change-expand-button-char ?-) |
981 (speedbar-with-writable | 2116 (speedbar-with-writable |
982 (save-excursion | 2117 (save-excursion |
983 (end-of-line) (forward-char 1) | 2118 (end-of-line) (forward-char 1) |
984 (speedbar-insert-generic-list indent | 2119 (speedbar-insert-generic-list indent |
985 token 'speedbar-tag-expand | 2120 token 'speedbar-tag-expand |
986 'speedbar-tag-find)))) | 2121 'speedbar-tag-find)))) |
987 ((string-match "-" text) ;we have to contract this node | 2122 ((string-match "-" text) ;we have to contract this node |
988 (speedbar-change-expand-button-char ?+) | 2123 (speedbar-change-expand-button-char ?+) |
989 (speedbar-with-writable | 2124 (speedbar-delete-subblock indent)) |
990 (save-excursion | |
991 (end-of-line) (forward-char 1) | |
992 (if (save-excursion (re-search-forward (format "^%d:" indent) nil t)) | |
993 (delete-region (point) (match-beginning 0)))))) | |
994 (t (error "Ooops... not sure what to do."))) | 2125 (t (error "Ooops... not sure what to do."))) |
995 (speedbar-center-buffer-smartly)) | 2126 (speedbar-center-buffer-smartly)) |
996 | 2127 |
997 ;;; | 2128 ;;; Loading files into the attached frame. |
2129 ;; | |
2130 (defun speedbar-find-file-in-frame (file) | |
2131 "This will load FILE into the speedbar attached frame. | |
2132 If the file is being displayed in a different frame already, then raise that | |
2133 frame instead." | |
2134 (let* ((buff (find-file-noselect file)) | |
2135 (bwin (get-buffer-window buff 0))) | |
2136 (if bwin | |
2137 (progn | |
2138 (select-window bwin) | |
2139 (raise-frame (window-frame bwin))) | |
2140 (if speedbar-power-click | |
2141 (let ((pop-up-frames t)) (select-window (display-buffer buff))) | |
2142 (select-frame speedbar-attached-frame) | |
2143 (switch-to-buffer buff)))) | |
2144 ) | |
2145 | |
998 ;;; Centering Utility | 2146 ;;; Centering Utility |
999 ;;; | 2147 ;; |
1000 (defun speedbar-center-buffer-smartly () | 2148 (defun speedbar-center-buffer-smartly () |
1001 "Look at the buffer, and center it so that which the user is most | 2149 "Recenter a speedbar buffer so the current indentation level is all visible. |
1002 interested in (as far as we can tell) is all visible. This assumes | 2150 This assumes that the cursor is on a file, or tag of a file which the user is |
1003 that the cursor is on a file, or tag of a file which the user is | |
1004 interested in." | 2151 interested in." |
1005 (if (<= (count-lines (point-min) (point-max)) | 2152 (if (<= (count-lines (point-min) (point-max)) |
1006 (window-height (selected-window))) | 2153 (window-height (selected-window))) |
1007 ;; whole buffer fits | 2154 ;; whole buffer fits |
1008 (let ((cp (point))) | 2155 (let ((cp (point))) |
1009 (goto-char (point-min)) | 2156 (goto-char (point-min)) |
1010 (recenter 0) | 2157 (recenter 0) |
1056 lte 1))) | 2203 lte 1))) |
1057 (recenter newcent)))) | 2204 (recenter newcent)))) |
1058 (goto-char cp))))) | 2205 (goto-char cp))))) |
1059 | 2206 |
1060 | 2207 |
1061 ;;; | |
1062 ;;; Tag Management -- Imenu | 2208 ;;; Tag Management -- Imenu |
1063 ;;; | 2209 ;; |
2210 (if (string-match "XEmacs" emacs-version) | |
2211 | |
2212 nil | |
2213 | |
2214 (eval-when-compile (if (locate-library "imenu") (require 'imenu))) | |
2215 | |
1064 (defun speedbar-fetch-dynamic-imenu (file) | 2216 (defun speedbar-fetch-dynamic-imenu (file) |
1065 "Use the imenu package to load in file, and extract all the items | 2217 "Load FILE into a buffer, and generate tags using Imenu. |
1066 tags we wish to display in the speedbar package." | 2218 Returns the tag list, or t for an error." |
1067 ;; (eval-when-compile (require 'imenu)) | 2219 ;; Load this AND compile it in |
2220 (require 'imenu) | |
1068 (save-excursion | 2221 (save-excursion |
1069 (set-buffer (find-file-noselect file)) | 2222 (set-buffer (find-file-noselect file)) |
1070 (condition-case nil | 2223 (condition-case nil |
1071 (imenu--make-index-alist t) | 2224 (progn |
2225 (if speedbar-power-click (setq imenu--index-alist nil)) | |
2226 (imenu--make-index-alist t)) | |
1072 (error t)))) | 2227 (error t)))) |
1073 | 2228 ) |
1074 | 2229 |
1075 ;;; | 2230 ;;; Tag Management -- etags (XEmacs compatibility part) |
1076 ;;; Tag Management -- etags (Not useful for FSF emacs) | 2231 ;; |
1077 ;;; | |
1078 (defvar speedbar-fetch-etags-parse-list | 2232 (defvar speedbar-fetch-etags-parse-list |
1079 '(("\\.\\([cChH]\\|c++\\|cpp\\|cc\\)$" . speedbar-parse-c-or-c++tag) | 2233 '(;; Note that java has the same parse-group as c |
1080 ("\\.el\\|\\.emacs" . | 2234 ("\\.\\([cChH]\\|c++\\|cpp\\|cc\\|hh\\|java\\)$" . speedbar-parse-c-or-c++tag) |
1081 "defun\\s-+\\(\\(\\w\\|[-_]\\)+\\)\\s-*\C-?") | 2235 ("\\.el\\|\\.emacs" . "defun\\s-+\\(\\(\\w\\|[-_]\\)+\\)\\s-*\C-?") |
1082 ("\\.tex$" . speedbar-parse-tex-string) | 2236 ("\\.tex$" . speedbar-parse-tex-string) |
1083 ("\\.p" . | 2237 ("\\.p" . |
1084 "\\(\\(FUNCTION\\|function\\|PROCEDURE\\|procedure\\)\\s-+\\([a-zA-Z0-9_.:]+\\)\\)\\s-*(?^?") | 2238 "\\(\\(FUNCTION\\|function\\|PROCEDURE\\|procedure\\)\\s-+\\([a-zA-Z0-9_.:]+\\)\\)\\s-*(?^?") |
1085 | 2239 |
1086 ) | 2240 ) |
1087 "*Alist matching extension vs an expression which will extract the | 2241 "Associations of file extensions and expressions for extracting tags. |
1088 symbol name we wish to display as match 1. To add a new file type, you | 2242 To add a new file type, you would want to add a new association to the |
1089 would want to add a new association to the list, where the car | 2243 list, where the car is the file match, and the cdr is the way to |
1090 is the file match, and the cdr is the way to extract an element from | 2244 extract an element from the tags output. If the output is complex, |
1091 the tags output. If the output is complex, use a function symbol | 2245 use a function symbol instead of regexp. The function should expect |
1092 instead of regexp. The function should expect to be at the beginning | 2246 to be at the beginning of a line in the etags buffer. |
1093 of a line in the etags buffer. | 2247 |
1094 | 2248 This variable is ignored if `speedbar-use-imenu-flag' is t") |
1095 This variable is ignored if `speedbar-use-imenu-package' is `t'") | |
1096 | 2249 |
1097 (defvar speedbar-fetch-etags-command "etags" | 2250 (defvar speedbar-fetch-etags-command "etags" |
1098 "*Command used to create an etags file. | 2251 "*Command used to create an etags file. |
1099 | 2252 |
1100 This variable is ignored if `speedbar-use-imenu-package' is `t'") | 2253 This variable is ignored if `speedbar-use-imenu-flag' is t") |
1101 | 2254 |
1102 (defvar speedbar-fetch-etags-arguments '("-D" "-I" "-o" "-") | 2255 (defvar speedbar-fetch-etags-arguments '("-D" "-I" "-o" "-") |
1103 "*List of arguments to use with `speedbar-fetch-etags-command' to create | 2256 "*List of arguments to use with `speedbar-fetch-etags-command'. |
1104 an etags output buffer. | 2257 This creates an etags output buffer. Use `speedbar-toggle-etags' to |
1105 | 2258 modify this list conveniently. |
1106 This variable is ignored if `speedbar-use-imenu-package' is `t'") | 2259 |
2260 This variable is ignored if `speedbar-use-imenu-flag' is t") | |
2261 | |
2262 (defun speedbar-toggle-etags (flag) | |
2263 "Toggle FLAG in `speedbar-fetch-etags-arguments'. | |
2264 FLAG then becomes a member of etags command line arguments. If flag | |
2265 is \"sort\", then toggle the value of `speedbar-sort-tags'. If it's | |
2266 value is \"show\" then toggle the value of | |
2267 `speedbar-show-unknown-files'. | |
2268 | |
2269 This function is a convenience function for XEmacs menu created by | |
2270 Farzin Guilak <farzin@protocol.com>" | |
2271 (interactive) | |
2272 (cond | |
2273 ((equal flag "sort") | |
2274 (setq speedbar-sort-tags (not speedbar-sort-tags))) | |
2275 ((equal flag "show") | |
2276 (setq speedbar-show-unknown-files (not speedbar-show-unknown-files))) | |
2277 ((or (equal flag "-C") | |
2278 (equal flag "-S") | |
2279 (equal flag "-D")) | |
2280 (if (member flag speedbar-fetch-etags-arguments) | |
2281 (setq speedbar-fetch-etags-arguments | |
2282 (delete flag speedbar-fetch-etags-arguments)) | |
2283 (add-to-list 'speedbar-fetch-etags-arguments flag))) | |
2284 (t nil))) | |
1107 | 2285 |
1108 (defun speedbar-fetch-dynamic-etags (file) | 2286 (defun speedbar-fetch-dynamic-etags (file) |
1109 "For the complete file definition FILE, run etags as a subprocess, | 2287 "For FILE, run etags and create a list of symbols extracted. |
1110 fetch it's output, and create a list of symbols extracted, and their | 2288 Each symbol will be associated with it's line position in FILE." |
1111 position in FILE." | |
1112 (let ((newlist nil)) | 2289 (let ((newlist nil)) |
1113 (unwind-protect | 2290 (unwind-protect |
1114 (save-excursion | 2291 (save-excursion |
1115 (if (get-buffer "*etags tmp*") | 2292 (if (get-buffer "*etags tmp*") |
1116 (kill-buffer "*etags tmp*")) ;kill to clean it up | 2293 (kill-buffer "*etags tmp*")) ;kill to clean it up |
2294 (if (<= 1 speedbar-verbosity-level) (message "Fetching etags...")) | |
1117 (set-buffer (get-buffer-create "*etags tmp*")) | 2295 (set-buffer (get-buffer-create "*etags tmp*")) |
1118 (apply 'call-process speedbar-fetch-etags-command nil | 2296 (apply 'call-process speedbar-fetch-etags-command nil |
1119 (current-buffer) nil | 2297 (current-buffer) nil |
1120 (append speedbar-fetch-etags-arguments (list file))) | 2298 (append speedbar-fetch-etags-arguments (list file))) |
1121 (goto-char (point-min)) | 2299 (goto-char (point-min)) |
1122 (let ((expr | 2300 (if (<= 1 speedbar-verbosity-level) (message "Fetching etags...")) |
2301 (let ((expr | |
1123 (let ((exprlst speedbar-fetch-etags-parse-list) | 2302 (let ((exprlst speedbar-fetch-etags-parse-list) |
1124 (ans nil)) | 2303 (ans nil)) |
1125 (while (and (not ans) exprlst) | 2304 (while (and (not ans) exprlst) |
1126 (if (string-match (car (car exprlst)) file) | 2305 (if (string-match (car (car exprlst)) file) |
1127 (setq ans (car exprlst))) | 2306 (setq ans (car exprlst))) |
1134 (setq tnl (speedbar-extract-one-symbol expr))) | 2313 (setq tnl (speedbar-extract-one-symbol expr))) |
1135 (if tnl (setq newlist (cons tnl newlist))) | 2314 (if tnl (setq newlist (cons tnl newlist))) |
1136 (forward-line 1))) | 2315 (forward-line 1))) |
1137 (message "Sorry, no support for a file of that extension")))) | 2316 (message "Sorry, no support for a file of that extension")))) |
1138 ) | 2317 ) |
1139 (reverse newlist))) | 2318 (if speedbar-sort-tags |
2319 (sort newlist (lambda (a b) (string< (car a) (car b)))) | |
2320 (reverse newlist)))) | |
2321 | |
2322 ;; This bit donated by Farzin Guilak <farzin@protocol.com> but I'm not | |
2323 ;; sure it's needed with the different sorting method. | |
2324 ;; | |
2325 ;(defun speedbar-clean-etags() | |
2326 ; "Removes spaces before the ^? character, and removes `#define', | |
2327 ;return types, etc. preceding tags. This ensures that the sort operation | |
2328 ;works on the tags, not the return types." | |
2329 ; (save-excursion | |
2330 ; (goto-char (point-min)) | |
2331 ; (while | |
2332 ; (re-search-forward "(?[ \t](?\C-?" nil t) | |
2333 ; (replace-match "\C-?" nil nil)) | |
2334 ; (goto-char (point-min)) | |
2335 ; (while | |
2336 ; (re-search-forward "\\(.*[ \t]+\\)\\([^ \t\n]+.*\C-?\\)" nil t) | |
2337 ; (delete-region (match-beginning 1) (match-end 1))))) | |
1140 | 2338 |
1141 (defun speedbar-extract-one-symbol (expr) | 2339 (defun speedbar-extract-one-symbol (expr) |
1142 "At point in current buffer, return nil, or one alist of the form | 2340 "At point, return nil, or one alist in the form: ( symbol . position ) |
1143 of a dotted pair: ( symbol . position ) from etags output. Parse the | 2341 The line should contain output from etags. Parse the output using the |
1144 output using the regular expression EXPR" | 2342 regular expression EXPR" |
1145 (let* ((sym (if (stringp expr) | 2343 (let* ((sym (if (stringp expr) |
1146 (if (save-excursion | 2344 (if (save-excursion |
1147 (re-search-forward expr (save-excursion | 2345 (re-search-forward expr (save-excursion |
1148 (end-of-line) | 2346 (end-of-line) |
1149 (point)) t)) | 2347 (point)) t)) |
1150 (buffer-substring-no-properties (match-beginning 1) | 2348 (buffer-substring-no-properties (match-beginning 1) |
1151 (match-end 1))) | 2349 (match-end 1))) |
1152 (funcall expr))) | 2350 (funcall expr))) |
1155 (end-of-line) | 2353 (end-of-line) |
1156 (point)) | 2354 (point)) |
1157 t))) | 2355 t))) |
1158 (if (and j sym) | 2356 (if (and j sym) |
1159 (1+ (string-to-int (buffer-substring-no-properties | 2357 (1+ (string-to-int (buffer-substring-no-properties |
1160 (match-beginning 2) | 2358 (match-beginning 2) |
1161 (match-end 2)))) | 2359 (match-end 2)))) |
1162 0)))) | 2360 0)))) |
1163 (if (/= pos 0) | 2361 (if (/= pos 0) |
1164 (cons sym pos) | 2362 (cons sym pos) |
1165 nil))) | 2363 nil))) |
1179 (match-end 1))) | 2377 (match-end 1))) |
1180 (t nil)) | 2378 (t nil)) |
1181 ))) | 2379 ))) |
1182 | 2380 |
1183 (defun speedbar-parse-tex-string () | 2381 (defun speedbar-parse-tex-string () |
1184 "Parse a tex string. Only find data which is relevant" | 2382 "Parse a Tex string. Only find data which is relevant." |
1185 (save-excursion | 2383 (save-excursion |
1186 (let ((bound (save-excursion (end-of-line) (point)))) | 2384 (let ((bound (save-excursion (end-of-line) (point)))) |
1187 (cond ((re-search-forward "\\(section\\|chapter\\|cite\\)\\s-*{[^\C-?}]*}?" bound t) | 2385 (cond ((re-search-forward "\\(section\\|chapter\\|cite\\)\\s-*{[^\C-?}]*}?" bound t) |
1188 (buffer-substring-no-properties (match-beginning 0) | 2386 (buffer-substring-no-properties (match-beginning 0) |
1189 (match-end 0))) | 2387 (match-end 0))) |
1190 (t nil))))) | 2388 (t nil))))) |
1191 | 2389 |
1192 | 2390 |
1193 ;;; | 2391 ;;; Color loading section This is messy *Blech!* |
1194 ;;; configuration scripts (optional) | 2392 ;; |
1195 ;;; | |
1196 (defun speedbar-configure-options () | |
1197 "Configure variable options for the speedbar program using dlg-config" | |
1198 (interactive) | |
1199 (require 'dlg-config) | |
1200 (save-excursion | |
1201 (select-frame speedbar-attached-frame) | |
1202 (dlg-init) | |
1203 (let ((oframe (create-widget "Speedbar Options" widget-frame | |
1204 widget-toplevel-shell | |
1205 :x 2 :y -3 | |
1206 :frame-label "Speedbar Options")) | |
1207 ) | |
1208 (create-widget "show-unknown" widget-toggle-button oframe | |
1209 :x 1 :y 1 :label-value "Show files that are not supported by imenu" | |
1210 :state (data-object-symbol "speedbar-show-unknown-files" | |
1211 :value speedbar-show-unknown-files | |
1212 :symbol 'speedbar-show-unknown-files)) | |
1213 | |
1214 (create-widget "raiselower" widget-toggle-button oframe | |
1215 :x 1 :y -1 :label-value "Use frame auto raise/lower property" | |
1216 :state (data-object-symbol "speedbar-raise-lower" | |
1217 :value speedbar-raise-lower | |
1218 :symbol 'speedbar-raise-lower)) | |
1219 | |
1220 (create-widget "update-speed" widget-label oframe | |
1221 :x 1 :y -2 :label-value "Update Delay :") | |
1222 (create-widget "update-speed-txt" widget-text-field oframe | |
1223 :width 5 :height 1 :x -2 :y t | |
1224 :value (data-object-symbol-string-to-int | |
1225 "update-speed" | |
1226 :symbol 'speedbar-update-speed | |
1227 :value (int-to-string speedbar-update-speed))) | |
1228 (create-widget "update-speed-unit" widget-label oframe | |
1229 :x -3 :y t :label-value "Seconds") | |
1230 | |
1231 (create-widget "navigating-speed" widget-label oframe | |
1232 :x 1 :y -1 :label-value "Navigating Delay:") | |
1233 (create-widget "navigating-speed-txt" widget-text-field oframe | |
1234 :width 5 :height 1 :x -2 :y t | |
1235 :value (data-object-symbol-string-to-int | |
1236 "navigating-speed" | |
1237 :symbol 'speedbar-navigating-speed | |
1238 :value (int-to-string speedbar-navigating-speed))) | |
1239 (create-widget "navigating-speed-unit" widget-label oframe | |
1240 :x -3 :y t :label-value "Seconds") | |
1241 | |
1242 (create-widget "width" widget-label oframe | |
1243 :x 1 :y -2 :label-value "Display Width :") | |
1244 (create-widget "width-txt" widget-text-field oframe | |
1245 :width 5 :height 1 :x -2 :y t | |
1246 :value (data-object-symbol-string-to-int | |
1247 "width" | |
1248 :symbol 'speedbar-width | |
1249 :value (int-to-string speedbar-width))) | |
1250 (create-widget "width-unit" widget-label oframe | |
1251 :x -3 :y t :label-value "Characters") | |
1252 | |
1253 (create-widget "scrollbar-width" widget-label oframe | |
1254 :x 1 :y -1 :label-value "Scrollbar Width :") | |
1255 (create-widget "scrollbar-width-txt" widget-text-field oframe | |
1256 :width 5 :height 1 :x -2 :y t | |
1257 :value (data-object-symbol-string-to-int | |
1258 "width" | |
1259 :symbol 'speedbar-width | |
1260 :value (int-to-string speedbar-scrollbar-width))) | |
1261 (create-widget "scrollbar-width-unit" widget-label oframe | |
1262 :x -3 :y t :label-value "Pixels") | |
1263 | |
1264 | |
1265 ) | |
1266 (dlg-end) | |
1267 (dialog-refresh) | |
1268 )) | |
1269 | |
1270 (defun speedbar-configure-faces () | |
1271 "Configure faces for the speedbar program using dlg-config." | |
1272 (interactive) | |
1273 (require 'dlg-config) | |
1274 (save-excursion | |
1275 (select-frame speedbar-attached-frame) | |
1276 (dlg-faces '(speedbar-button-face | |
1277 speedbar-file-face | |
1278 speedbar-directory-face | |
1279 speedbar-tag-face | |
1280 speedbar-highlight-face | |
1281 speedbar-selected-face)))) | |
1282 | |
1283 ;;; | |
1284 ;;; Color loading section This is message *Blech!* | |
1285 ;;; | |
1286 (defun speedbar-load-color (sym l-fg l-bg d-fg d-bg &optional bold italic underline) | 2393 (defun speedbar-load-color (sym l-fg l-bg d-fg d-bg &optional bold italic underline) |
1287 "Create a color for SYM with a L-FG and L-BG color, or D-FG and | 2394 "Create a color for SYM with a L-FG and L-BG color, or D-FG and D-BG. |
1288 D-BG. Optionally make BOLD, ITALIC, or UNDERLINED if applicable. If | 2395 Optionally make BOLD, ITALIC, or UNDERLINE if applicable. If the background |
1289 the background attribute of the current frame is determined to be | 2396 attribute of the current frame is determined to be light (white, for example) |
1290 light (white, for example) then L-FG and L-BG is used. If not, then | 2397 then L-FG and L-BG is used. If not, then D-FG and D-BG is used. This will |
1291 D-FG and D-BG is used. This will allocate the colors in the best | 2398 allocate the colors in the best possible manor. This will allow me to store |
1292 possible mannor. This will allow me to store multiple defaults and | 2399 multiple defaults and dynamically determine which colors to use." |
1293 dynamically determine which colors to use." | |
1294 (let* ((params (frame-parameters)) | 2400 (let* ((params (frame-parameters)) |
1295 (disp-res (if (fboundp 'x-get-resource) | 2401 (disp-res (if (fboundp 'x-get-resource) |
1296 (if speedbar-xemacsp | 2402 (if speedbar-xemacsp |
1297 (x-get-resource ".displayType" "DisplayType" 'string) | 2403 (x-get-resource ".displayType" "DisplayType" 'string) |
1298 (x-get-resource ".displayType" "DisplayType")) | 2404 (x-get-resource ".displayType" "DisplayType")) |
1306 (x-get-resource ".backgroundMode" "BackgroundMode" 'string) | 2412 (x-get-resource ".backgroundMode" "BackgroundMode" 'string) |
1307 (x-get-resource ".backgroundMode" "BackgroundMode")) | 2413 (x-get-resource ".backgroundMode" "BackgroundMode")) |
1308 nil)) | 2414 nil)) |
1309 (bgmode | 2415 (bgmode |
1310 (cond (bg-res (intern (downcase bg-res))) | 2416 (cond (bg-res (intern (downcase bg-res))) |
1311 ((and params | 2417 ((let* ((bgc (or (cdr (assq 'background-color params)) |
1312 (fboundp 'x-color-values) | 2418 (if speedbar-xemacsp |
1313 (< (apply '+ (x-color-values | 2419 (x-get-resource ".background" |
1314 (cdr (assq 'background-color params)))) | 2420 "Background" 'string) |
1315 (/ (apply '+ (x-color-values "white")) 3))) | 2421 (x-get-resource ".background" |
2422 "Background")) | |
2423 ;; if no other options, default is white | |
2424 "white")) | |
2425 (bgcr (if speedbar-xemacsp | |
2426 (color-instance-rgb-components | |
2427 (make-color-instance bgc)) | |
2428 (x-color-values bgc))) | |
2429 (wcr (if speedbar-xemacsp | |
2430 (color-instance-rgb-components | |
2431 (make-color-instance "white")) | |
2432 (x-color-values "white")))) | |
2433 (< (apply '+ bgcr) (/ (apply '+ wcr) 3))) | |
1316 'dark) | 2434 'dark) |
1317 (t 'light))) ;our default | 2435 (t 'light))) ;our default |
1318 (set-p (function (lambda (face-name resource) | 2436 (set-p (function (lambda (face-name resource) |
1319 (if speedbar-xemacsp | 2437 (if speedbar-xemacsp |
1320 (x-get-resource | 2438 (x-get-resource |
1321 (concat face-name ".attribute" resource) | 2439 (concat face-name ".attribute" resource) |
1322 (concat "Face.Attribute" resource) | 2440 (concat "Face.Attribute" resource) |
1323 'string) | 2441 'string) |
1324 (x-get-resource | 2442 (x-get-resource |
1325 (concat face-name ".attribute" resource) | 2443 (concat face-name ".attribute" resource) |
1326 (concat "Face.Attribute" resource))) | 2444 (concat "Face.Attribute" resource))) |
1327 ))) | 2445 ))) |
1328 (nbg (cond ((eq bgmode 'dark) d-bg) | 2446 (nbg (cond ((eq bgmode 'dark) d-bg) |
1329 (t l-bg))) | 2447 (t l-bg))) |
1330 (nfg (cond ((eq bgmode 'dark) d-fg) | 2448 (nfg (cond ((eq bgmode 'dark) d-fg) |
1331 (t l-fg)))) | 2449 (t l-fg)))) |
1332 | 2450 |
1333 (if (not (eq display-type 'color)) | 2451 (if (not (eq display-type 'color)) |
1334 ;; we need a face of some sort, so just make due with default | 2452 ;; we need a face of some sort, so just make due with default |
1335 (progn | 2453 (progn |
1336 (copy-face 'default sym) | 2454 (copy-face 'default sym) |
1337 (if bold (condition-case nil | 2455 (if bold (condition-case nil |
1338 (make-face-bold sym) | 2456 (make-face-bold sym) |
1339 (error (message "Cannot make face %s bold!" | 2457 (error (message "Cannot make face %s bold!" |
1340 (symbol-name sym))))) | 2458 (symbol-name sym))))) |
1341 (if italic (condition-case nil | 2459 (if italic (condition-case nil |
1342 (make-face-italic sym) | 2460 (make-face-italic sym) |
1343 (error (message "Cannot make face %s italic!" | 2461 (error (message "Cannot make face %s italic!" |
1344 (symbol-name sym))))) | 2462 (symbol-name sym))))) |
1347 ;; make a colorized version of a face. Be sure to check Xdefaults | 2465 ;; make a colorized version of a face. Be sure to check Xdefaults |
1348 ;; for possible overrides first! | 2466 ;; for possible overrides first! |
1349 (let ((newface (make-face sym))) | 2467 (let ((newface (make-face sym))) |
1350 ;; For each attribute, check if it might already be set by Xdefaults | 2468 ;; For each attribute, check if it might already be set by Xdefaults |
1351 (if (and nfg (not (funcall set-p (symbol-name sym) "Foreground"))) | 2469 (if (and nfg (not (funcall set-p (symbol-name sym) "Foreground"))) |
1352 (set-face-foreground sym nfg)) | 2470 (set-face-foreground newface nfg)) |
1353 (if (and nbg (not (funcall set-p (symbol-name sym) "Background"))) | 2471 (if (and nbg (not (funcall set-p (symbol-name sym) "Background"))) |
1354 (set-face-background sym nbg)) | 2472 (set-face-background newface nbg)) |
1355 | 2473 |
1356 (if bold (condition-case nil | 2474 (if bold (condition-case nil |
1357 (make-face-bold sym) | 2475 (make-face-bold newface) |
1358 (error (message "Cannot make face %s bold!" | 2476 (error (message "Cannot make face %s bold!" |
1359 (symbol-name sym))))) | 2477 (symbol-name sym))))) |
1360 (if italic (condition-case nil | 2478 (if italic (condition-case nil |
1361 (make-face-italic sym) | 2479 (make-face-italic newface) |
1362 (error (message "Cannot make face %s italic!" | 2480 (error (message "Cannot make face %s italic!" |
1363 (symbol-name sym))))) | 2481 (symbol-name newface))))) |
1364 (set-face-underline-p sym underline) | 2482 (set-face-underline-p newface underline) |
1365 )))) | 2483 )))) |
1366 | 2484 |
1367 ;; JTL <<<< | 2485 (if (x-display-color-p) |
1368 (if nil ;;(x-display-color-p) ;; just a quick hack so it will run. | |
1369 ;; we can use customize for this. | |
1370 ;; <<<< JTL | |
1371 (progn | 2486 (progn |
1372 (speedbar-load-color 'speedbar-button-face "green4" "default" "green3" "default") | 2487 (speedbar-load-color 'speedbar-button-face "green4" nil "green3" nil nil nil nil) |
1373 (speedbar-load-color 'speedbar-file-face "cyan4" nil "cyan" nil nil nil nil) | 2488 (speedbar-load-color 'speedbar-file-face "cyan4" nil "cyan" nil nil nil nil) |
1374 (speedbar-load-color 'speedbar-directory-face "blue4" nil "light blue" nil nil nil nil) | 2489 (speedbar-load-color 'speedbar-directory-face "blue4" nil "light blue" nil nil nil nil) |
1375 (speedbar-load-color 'speedbar-tag-face "brown" nil "yellow" nil nil nil nil) | 2490 (speedbar-load-color 'speedbar-tag-face "brown" nil "yellow" nil nil nil nil) |
1376 (speedbar-load-color 'speedbar-selected-face "red" nil "red" nil nil nil t) | 2491 (speedbar-load-color 'speedbar-selected-face "red" nil "red" nil nil nil t) |
1377 (speedbar-load-color 'speedbar-highlight-face nil "green" nil "sea green" nil nil nil) | 2492 (speedbar-load-color 'speedbar-highlight-face nil "green" nil "sea green" nil nil nil) |
1386 ;;(make-face 'speedbar-highlight-face) | 2501 ;;(make-face 'speedbar-highlight-face) |
1387 (copy-face 'highlight 'speedbar-highlight-face) | 2502 (copy-face 'highlight 'speedbar-highlight-face) |
1388 | 2503 |
1389 ) ;; monochrome | 2504 ) ;; monochrome |
1390 | 2505 |
1391 ;;; end of lisp | 2506 ;; some edebug hooks |
2507 (add-hook 'edebug-setup-hook | |
2508 (lambda () | |
2509 (def-edebug-spec speedbar-with-writable def-body))) | |
2510 | |
2511 ;; run load-time hooks | |
2512 (run-hooks 'speedbar-load-hook) | |
2513 | |
1392 (provide 'speedbar) | 2514 (provide 'speedbar) |
1393 | 2515 ;;; speedbar ends here |
1394 ;;; speedbar.el ends here |