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 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:
Edit the item on the current line.
Expand the item under the cursor. With a numeric argument (C-u), flush cached data before expanding.
Contract the item under the cursor.
These functions require that the function
correctly overloaded to work.
Next, register your extension like this;
(speedbar-add-expansion-list '("MyExtension" MyExtension-speedbar-menu-items MyExtension-speedbar-mode-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 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-directory . MyExtension-speedbar-line-directory)))
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.
speedbar-line-directory 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-number (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.
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
ored since each one
nil if it displays a message. They are:
This takes an optional filename parameter. You can derive your own
filename, or it will derive it using a (possibly overloaded) function
speedbar-line-file. It shows details about a file.
If the current line is a tag, then display information about that tag, such as its parent file, and location.
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.