Speedbar is another frame which displays information about the current buffer, allowing you to better navigate your sources. In a way, it’s similar to ImenuMode, but much more powerful. It is a part of GNU Emacs since version 23.2.
Speedbar can use etags, imenu, or the SemanticBovinator to parse C, C++, Java, texinfo, Makefiles, etc. and provides alternate views into each individual files. For example, for C files, function list and variable lists are provided for quick navigation within files.
Speedbar also supports special displays for buffers, rmail, info, projects, xslt, vhdl, and others which use the speedbar extension API.
To automatically start speedbar from your InitFile, just call the speedbar function with a positive argument like this:
If you use emacs both on the console and in X a lot, you may want to disable speedbar when you’re not in X. To do that use the following in your InitFile:
(when window-system ; start speedbar if we're using a window system (speedbar t))
Something that might annoy you under certain X window managers (WindowMaker?, for example) and in Carbon Emacs when speedbar starts is that it’s window will appear to have focus but keyboard input goes to the original Emacs window. You can make things look right again by defining this mode hook before starting speedbar:
(setq speedbar-mode-hook '(lambda () (interactive) (other-frame 0)))
If this fails, you can call other-frame right after you call speedbar.
Beware: doing this may make your MousePointer jump somewhere you don’t expect it to in X.
The default behavior of speedbar is to create a second emacs frame, separate from the main editing frame. As with all things emacs, this default behavior can be modified so that no separate frame is created, and the speedbar becomes just another buffer within a single emacs frame.
The following function will only work with the latest versions of speedbar (I have tested it with the version that comes bundled as part of cedet-1.0beta2a):
(defconst my-speedbar-buffer-name "SPEEDBAR") ; (defconst my-speedbar-buffer-name " SPEEDBAR") ; try this if you get "Wrong type argument: stringp, nil"
(defun my-speedbar-no-separate-frame () (interactive) (when (not (buffer-live-p speedbar-buffer)) (setq speedbar-buffer (get-buffer-create my-speedbar-buffer-name) speedbar-frame (selected-frame) dframe-attached-frame (selected-frame) speedbar-select-frame-method 'attached speedbar-verbosity-level 0 speedbar-last-selected-file nil) (set-buffer speedbar-buffer) (speedbar-mode) (speedbar-reconfigure-keymaps) (speedbar-update-contents) (speedbar-set-timer 1) (make-local-hook 'kill-buffer-hook) (add-hook 'kill-buffer-hook (lambda () (when (eq (current-buffer) speedbar-buffer) (setq speedbar-frame nil dframe-attached-frame nil speedbar-buffer nil) (speedbar-set-timer nil))))) (set-window-buffer (selected-window) (get-buffer my-speedbar-buffer-name)))
Hmmm... I can't seem to get this to work... little help?
This is the code from above with little extensions (splitting the window and remember it, modifying the speedbars was of finding files). Everything seems to work as expected for me if speedbar is displaying files. (current version of emacs22 and speedbar as in Debian testing). Thanks for the hints from above :-) I was sitting here writing my own speedbar, which turned out to be a huge pile of work. Toggeling works fine now. Just use sr-speedbar-toggle().
The Code: Lisp:sr-speedbar.el
Also see the comment about EmacsCodeBrowser (ECB) below.
;; This plain hack probably will not work with versions other than speedbar v 1.0 (defun speedbar-timer-fn () "Run whenever Emacs is idle to update the speedbar item." (if (or (not (speedbar-current-frame)) (not (frame-live-p (speedbar-current-frame)))) (speedbar-set-timer nil) ;; Save all the match data so that we don't mess up executing fns (save-match-data ;; Only do stuff if the frame is visible, not an icon, and if ;; it is currently flagged to do something. (if (and speedbar-update-flag (speedbar-current-frame) (frame-visible-p (speedbar-current-frame)) (not (eq (frame-visible-p (speedbar-current-frame)) 'icon))) (let ((af (selected-frame))) (dframe-select-attached-frame speedbar-frame) ;; make sure we at least choose a window to ;; get a good directory from (if (window-minibuffer-p (selected-window)) nil ;; Check for special modes (speedbar-maybe-add-localized-support (current-buffer)) ;; Update for special mode all the time! (if (and speedbar-mode-specific-contents-flag (consp speedbar-special-mode-expansion-list) (local-variable-p 'speedbar-special-mode-expansion-list (current-buffer))) ;;(eq (get major-mode 'mode-class 'special))) (progn (if (<= 2 speedbar-verbosity-level) (speedbar-message "Updating speedbar to special mode: %s..." major-mode)) (speedbar-update-special-contents) (if (<= 2 speedbar-verbosity-level) (progn (speedbar-message "Updating speedbar to special mode: %s...done" major-mode) (speedbar-message nil)))) ;; Update all the contents if directories change! (unless (and (or (member major-mode speedbar-ignored-modes) (string-equal "*SPEEDBAR*" (buffer-name)) (not (buffer-file-name))) ;; Always update for GUD. (not (string-equal "GUD" speedbar-initial-expansion-list-name))) (speedbar-update-localized-contents))) (select-frame af)) ;; Now run stealthy updates of time-consuming items (speedbar-stealthy-updates))))) (run-hooks 'speedbar-timer-hook))
(defun speedbar-expand-all-lines () "Expand all items in the speedbar buffer. But be careful: this opens all the files to parse them." (interactive) (goto-char (point-min)) (while (not (eobp)) (forward-line) (speedbar-expand-line)))
(speedbar-add-supported-extension ".js") (add-to-list 'speedbar-fetch-etags-parse-list '("\\.js" . speedbar-parse-c-or-c++tag))
SqlMode does have Imenu support; but by default the regular expressions don’t match PL/SQL stuff. At work I have code that does it. But then again, I switched to using PlsqlMode for PL/SQL stuff. Perhaps it reuses the SqlMode imenu code, I can’t remember. -- AlexSchroeder
EmacsCodeBrowser (ecb) overlaps much of Speedbar, and requires Speedbar and other parts of the CEDET suite to function. In fact, ecb will display Speedbar without a separate frame in one of its supplied configurations. Its built-in directory and class browsers (which you can hide/not use, if you only want Speedbar in your editing frame) are similar in function but different in look/feel from Speedbar’s. I’ve used it on Win32/GNU Emacs successfully. --yary h
(add-to-list 'default-frame-alist '(font . "-schumacher-clean-medium-r-normal--8-*-*-*-c-50-iso8859-1"))
(speedbar 1)line so that when the speedbar is created, it uses the font I selected before.
To override the the default behavior that identifies files by extension, you can set the variable ‘speedbar-file-regexp’ to something like “.*”. I just tried it, and it seems to work ok. This variable will be re-set when speedbar loads, or if the supported extension list is customized.
Thanks, it seems to work and I will give it a try. If I don’t come back to this page, it will be a good solution ;-)
Try this tip, from the help text for
‘speedbar-supported-extension-expressions’: “You should use the function
‘speedbar-add-supported-extension’ to add a new extension at runtime, or use the configuration dialog to set it in your InitFile.” Just now I menued Options > Customize Emacs > Settings Matching Regexp, typed in “speedbar”, and got a good listing of options. Adding
(speedbar 1) (speedbar-add-supported-extension ".js")
(speedbar 1) or
(speedbar 0) has to come first to load the package. -yary h