[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Speedbar can run different types of Major display modes such as Files (see section 3. File Mode), and Buffers (see section 4. Buffer Mode). It can also manage different minor display modes for use with buffers handling specialized data.
These major and minor display modes are handled through an extension
system which permits specialized keymaps and menu extensions, in
addition to a unique rendering function. You can also specify a wide
range of tagging functions. The default uses imenu
, but new
tagging methods can be easily added. In this chapter, you will
learn how to write your own major or minor display modes, and how to
create specialized tagging functions.
7.1 Minor Display Modes | How to create a minor display mode. | |
7.2 Major Display Modes | How to create a major display mode. | |
7.3 Tagging Extensions | How to create your own tagging methods. | |
7.4 Creating a display | How to insert buttons and hierarchies. |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A minor display mode is a mode useful when using a specific type of buffer. This mode might not be useful for any other kind of data or mode, or may just be more useful that a files or buffers based mode when working with a specialized mode.
Examples that already exist for speedbar include RMAIL, Info, and gdb. These modes display information specific to the major mode shown in the attached frame.
To enable a minor display mode in your favorite Major mode, follow these steps. The string `name' is the name of the major mode being augmented with speedbar.
name-speedbar-key-map
.
(setq name-speedbar-key-map (speedbar-make-specialized-keymap)) |
This function creates a special keymap for use in speedbar.
(if (featurep 'speedbar) (name-install-speedbar-variables) (add-hook 'speedbar-load-hook 'name-install-speedbar-variables)) |
name-speedbar-menu-items
. This will be spliced into
speedbar's control menu.
name-speedbar-buttons
. This function
should take one variable, which is the buffer for which it will create
buttons. At this time (current-buffer)
will point to the
uncleared speedbar buffer.
When writing name-speedbar-buttons
, the first thing you will
want to do is execute a check to see if you need to re-create your
display. If it needs to be cleared, you need to erase the speedbar
buffer yourself, and start drawing buttons. See section 7.4 Creating a display.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Creating a Major Display Mode for speedbar requires authoring a keymap, an easy-menu segment, and writing several functions. These items can be given any name, and are made the same way as in a minor display mode (see section 7.1 Minor Display Modes). Once this is done, these items need to be registered.
Because this setup activity may or may not have speedbar available when it is being loaded, it is necessary to create an install function. This function should create and initialize the keymap, and add your expansions into the customization tables.
When creating the keymap, use the function
speedbar-make-specialized-keymap
instead of other keymap making
functions. This will provide you with the initial bindings needed.
Some common speedbar functions you might want to bind are:
speedbar-edit-line
speedbar-expand-line
speedbar-contract-line
These function require that function speedbar-line-path
be
correctly overloaded to work.
Next, register your extension like this;
(speedbar-add-expansion-list '("MyExtension" MyExtension-speedbar-menu-items MyExtension-speedbar-key-map MyExtension-speedbar-buttons)) |
There are no limitations to the names you use.
The first parameter is the string representing your display mode. The second parameter is a variable name containing an easymenu compatible menu definition. This will be stuck in the middle of speedbar's menu. The third parameter is the variable name containing the keymap we discussed earlier. The last parameter is a function which draws buttons for your mode. This function must take two parameters. The directory currently being displayed, and the depth at which you should start rendering buttons. The function will then draw (starting at the current cursor position) any buttons deemed necessary based on the input parameters. See section 7.4 Creating a display.
Next, you need to register function overrides. This may look something like this:
(speedbar-add-mode-functions-list '("MYEXTENSION" (speedbar-item-info . MyExtension-speedbar-item-info) (speedbar-line-path . MyExtension-speedbar-line-path))) |
The first element in the list is the name of you extension. The second is an alist of functions to overload. The function to overload is first, followed by what you want called instead.
For speedbar-line-path
your function should take an optional DEPTH
parameter. This is the starting depth for heavily indented lines. If
it is not provided, you can derive it like this:
(save-match-data (if (not depth) (progn (beginning-of-line) (looking-at "^\\([0-9]+\\):") (setq depth (string-to-int (match-string 1))))) |
where the depth is stored as invisible text at the beginning of each line.
The path returned should be the full path name of the file associated with that line. If the cursor is on a tag, then the file containing that tag should be returned. This is critical for built in file based functions to work (meaning less code for you to write). If your display does not deal in files, you do not need to overload this function.
The function speedbar-item-info
, however, is very likely to need
overloading. This function takes no parameters and must derive a text
summary to display in the minibuffer.
There are several helper functions you can use if you are going to use
built in tagging. These functions can be or
ed since each one
returns non-nil if it displays a message. They are:
speedbar-item-info-file-helper
speedbar-line-file
. It shows details about a file.
speedbar-item-info-tag-helper
Your custom function might look like this:
(defun MyExtension-item-info () "Display information about the current line." (or (speedbar-item-info-tag-helper) (message "Interesting detail."))) |
Once you have done all this, speedbar will show an entry in the `Displays' menu declaring that your extension is available.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
It is possible to create new methods for tagging files in speedbar. To do this, you need two basic functions, one function to fetch the tags from a buffer, the other to insert them below the filename.
t
if
there was an error. file is not necessarily available as an
buffer when your function is called. Be sure to load it if it is needed
with code like this:
(save-excursion (set-buffer (find-file-noselect file)) ... ) |
The non-error return value can be anything, as long as it can be inserted by its paired function:
It is often useful to use speedbar-create-tag-hierarchy
on your
token list. See that function's documentation for details on what it
requires.
Once these two functions are written, modify the variable
speedbar-dynamic-tags-function-list
to include your parser at the
beginning, like this:
(add-to-list 'speedbar-dynamic-tags-function-list '(my-fetch-dynamic-tags . my-insert-tag-list)) |
If your parser is only good for a few types of files, make sure that it
is either a buffer local modification, or that the tag generator returns
t
for non valid buffers.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Rendering a display in speedbar is completely flexible. When your
button function is called, see 7.1 Minor Display Modes, and 7.2 Major Display Modes, you have control to insert
anything you want.
The conventions allow almost anything to be inserted, but several helper functions are provided to make it easy to create the standardized buttons.
To understand the built in functions, each `button' in speedbar consists of four important pieces of data. The text to be displayed, token data to be associated with the text, a function to call, and some face to display it in.
When a function is provided, then that text becomes mouse activated, meaning the mouse will highlight the text.
Additionally, for data which can form deep trees, each line is given a depth which indicates how far down the tree it is. This information is stored in invisible text at the beginning of each line, and is used by the navigation commands.
The optional argument token is extra data to associated with the text. Lastly prevline should be non-nil if you want this line to appear directly after the last button which was created instead of on the next line.
Create a tag line with exp-button-type for the small expansion
button. This is the button that expands or contracts a node (if
applicable), and exp-button-char the character in it (`+',
`-', `?',
etc). exp-button-function is the function to call if it's clicked
on. Button types are 'bracket
, 'angle
, 'curly
,
'expandtag
, 'statictag
, or nil. exp-button-data is
extra data attached to the text forming the expansion button.
Next, tag-button is the text of the tag. tag-button-function is the function to call if clicked on, and tag-button-data is the data to attach to the text field (such a tag positioning, etc). tag-button-face is a face used for this type of tag.
Lastly, depth shows the depth of expansion.
This function assumes that the cursor is in the speedbar window at the position to insert a new item, and that the new item will end with a CR.
At level, (the current indentation level desired) insert a generic
multi-level alist list. Associations with lists get `{+}'
tags (to expand into more nodes) and those with positions or other data
just get a `>' as the indicator. `{+}' buttons will have the
function expand-fun and the token is the cdr
list. The
token name will have the function find-fun and not token.
Each element of the list can have one of these forms:
(name . marker-or-number)
(name (name . marker-or-number) (name . marker-or-number) ... )
(name marker-or-number (name . marker-or-number) ... )
When you use speedbar-insert-generic-list
, there are some
variables you can set buffer-locally to change the behavior. The most
obvious is speedbar-tag-hierarchy-method
.
See section 6.2 Tag Hierarchy Methods.
'curly
and 'expandtag
. Curly is the default button, and
'expandtag
is useful if the groups also has a position.
nil
and 'statictag
.
nil
is the default, and 'statictag
has the same width as
'expandtag
.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |