Mercurial > hg > xemacs-beta
diff lisp/utils/speedbspec.el @ 167:85ec50267440 r20-3b10
Import from CVS: tag r20-3b10
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:45:46 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/utils/speedbspec.el Mon Aug 13 09:45:46 2007 +0200 @@ -0,0 +1,305 @@ +;;; speedbspec --- Buffer specialized configurations for speedbar + +;; Copyright (C) 1997 Eric M. Ludlam +;; +;; Author: Eric M. Ludlam <zappo@gnu.ai.mit.edu> +;; Version: 0.1 +;; Keywords: file, tags, tools +;; X-RCS: $Id: speedbspec.el,v 1.1 1997/06/29 23:13:34 steve Exp $ +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, you can either send email to this +;; program's author (see below) or write to: +;; +;; The Free Software Foundation, Inc. +;; 675 Mass Ave. +;; Cambridge, MA 02139, USA. +;; +;; Please send bug reports, etc. to zappo@gnu.ai.mit.edu. +;; + +;;; Commentary: +;; +;; Speedbar provides a frame in which files, and locations in +;; files are displayed. These functions provide some mode-specific +;; displays for some existing emacs modes. +;; +;; To provide special service to all the modes supported by this file, +;; put the following in your .emacs file. +;; +;; (require 'speedbspec) +;; +;; This will load in the known functions, and the mode-enabling code +;; into 'change-major-mode-hook. +;; +;; This file requires speedbar. + +;;; Change log: +;; 0.1 - Initial revision requiring speedbar 0.5 + +;;; Code: +(require 'speedbar) + +;;; Generic add-new-special-mode stuff +;; +(defvar speedbar-localized-buffer-queue nil + "List of buffers to localize for speedbar.") + +(defun speedbar-add-localized-speedbar-support-to-q () + "Add speedbar support to all buffers in `speedbar-localized-buffer-queue'." + (remove-hook 'post-command-hook + 'speedbar-add-localized-speedbar-support-to-q) + (while speedbar-localized-buffer-queue + (speedbar-add-localized-speedbar-support + (car speedbar-localized-buffer-queue)) + (setq speedbar-localized-buffer-queue + (cdr speedbar-localized-buffer-queue)))) + +(defun speedbar-add-localized-speedbar-support (buffer) + "Add localized speedbar support to BUFFER's mode if it is available." + (if (not (buffer-live-p buffer)) + nil + (save-excursion + (set-buffer buffer) + (save-match-data + (let ((ms (symbol-name major-mode)) + v tmp) + (if (not (string-match "-mode$" ms)) + nil ;; do nothing to broken mode + (setq ms (substring ms 0 (match-beginning 0))) + (setq v (intern-soft (concat ms "-speedbar-buttons"))) + (if (not v) + nil ;; do nothing if not defined + (make-local-variable 'speedbar-special-mode-expansion-list) + (setq speedbar-special-mode-expansion-list (list v)) + (setq v (intern-soft (concat ms "-speedbar-menu-items"))) + (if (not v) + nil ;; don't add special menus + (make-local-variable 'speedbar-easymenu-definition-special) + (setq speedbar-easymenu-definition-special + (symbol-value v)))))))))) + +(defun speedbar-change-major-mode () + "Run when the major mode is changed." + (setq speedbar-localized-buffer-queue + (add-to-list 'speedbar-localized-buffer-queue (current-buffer))) + (add-hook 'post-command-hook 'speedbar-add-localized-speedbar-support-to-q)) + +(add-hook 'change-major-mode-hook 'speedbar-change-major-mode) +(add-hook 'find-file-hooks 'speedbar-change-major-mode) + +;;; Info specific code +;; +(defvar Info-last-speedbar-node nil + "Last node viewed with speedbar in the form '(NODE FILE).") + +(defvar Info-speedbar-menu-items + '(["Browse Item On Line" speedbar-edit-line t]) + "Additional menu-items to add to speedbar frame.") + +(defun Info-speedbar-buttons (buffer) + "Create a speedbar display to help navigation in an Info file. +BUFFER is the buffer speedbar is requesting buttons for." + (goto-char (point-min)) + (if (and (looking-at "<Directory>") + (save-excursion + (set-buffer buffer) + (and (equal (car Info-last-speedbar-node) Info-current-node) + (equal (cdr Info-last-speedbar-node) Info-current-file)))) + nil + (erase-buffer) + (speedbar-insert-button "<Directory>" 'info-xref 'highlight + 'Info-speedbar-button + 'Info-directory) + (speedbar-insert-button "<Top>" 'info-xref 'highlight + 'Info-speedbar-button + 'Info-top-node) + (speedbar-insert-button "<Last>" 'info-xref 'highlight + 'Info-speedbar-button + 'Info-last) + (speedbar-insert-button "<Up>" 'info-xref 'highlight + 'Info-speedbar-button + 'Info-up) + (speedbar-insert-button "<Next>" 'info-xref 'highlight + 'Info-speedbar-button + 'Info-next) + (speedbar-insert-button "<Prev>" 'info-xref 'highlight + 'Info-speedbar-button + 'Info-prev) + (let ((completions nil)) + (save-excursion + (set-buffer buffer) + (setq Info-last-speedbar-node + (cons Info-current-node Info-current-file)) + (goto-char (point-min)) + ;; Always skip the first one... + (re-search-forward "\n\\* \\([^:\t\n]*\\):" nil t) + (while (re-search-forward "\n\\* \\([^:\t\n]*\\):" nil t) + (setq completions (cons (buffer-substring (match-beginning 1) + (match-end 1)) + completions)))) + (setq completions (nreverse completions)) + (while completions + (speedbar-make-tag-line nil nil nil nil + (car completions) 'Info-speedbar-menu + nil 'info-node 0) + (setq completions (cdr completions)))))) + +(defun Info-speedbar-button (text token indent) + "Called when user clicks <Directory> from speedbar. +TEXT, TOKEN, and INDENT are unused." + (speedbar-with-attached-buffer + (funcall token) + (setq Info-last-speedbar-node nil) + (speedbar-update-contents))) + +(defun Info-speedbar-menu (text token indent) + "Goto the menu node specified in TEXT. +TOKEN and INDENT are not used." + (speedbar-with-attached-buffer + (Info-menu text) + (setq Info-last-speedbar-node nil) + (speedbar-update-contents))) + +;;; RMAIL specific code +;; +(defvar rmail-speedbar-last-user nil + "The last user to be displayed in the speedbar.") + +(defvar rmail-speedbar-menu-items + '(["Browse Item On Line" speedbar-edit-line t] + ["Move message to folder" rmail-move-message-to-folder-on-line + (save-excursion (beginning-of-line) + (looking-at "<M> "))]) + "Additional menu-items to add to speedbar frame.") + +(defun rmail-speedbar-buttons (buffer) + "Create buttons for BUFFER containing rmail messages. +Click on the address under Reply to: to reply to this person. +Under Folders: Click a name to read it, or on the <M> to move the +current message into that RMAIL folder." + (let ((from nil)) + (save-excursion + (set-buffer buffer) + (goto-char (point-min)) + (if (not (re-search-forward "^Reply-To: " nil t)) + (if (not (re-search-forward "^From:? " nil t)) + (setq from t))) + (if from + nil + (setq from (buffer-substring (point) (save-excursion + (end-of-line) + (point)))))) + (goto-char (point-min)) + (if (and (looking-at "Reply to:") + (equal from rmail-speedbar-last-user)) + nil + (setq rmail-speedbar-last-user from) + (erase-buffer) + (insert "Reply To:\n") + (if (stringp from) + (speedbar-insert-button from 'speedbar-directory-face 'highlight + 'rmail-speedbar-button 'rmail-reply)) + (insert "Folders:\n") + (let* ((case-fold-search nil) + (df (directory-files (save-excursion (set-buffer buffer) + default-directory) + nil "^[A-Z0-9]+\\(\\.[A-Z0-9]+\\)?$"))) + (while df + (speedbar-insert-button "<M>" 'speedbar-button-face 'highlight + 'rmail-speedbar-move-message (car df)) + (speedbar-insert-button (car df) 'speedbar-file-face 'highlight + 'rmail-speedbar-find-file nil t) + (setq df (cdr df))))))) + +(defun rmail-speedbar-button (text token indent) + "Execute an rmail command specified by TEXT. +The command used is TOKEN. INDENT is not used." + (speedbar-with-attached-buffer + (funcall token t))) + +(defun rmail-speedbar-find-file (text token indent) + "Load in the rmail file TEXT. +TOKEN and INDENT are not used." + (speedbar-with-attached-buffer + (message "Loading in RMAIL file %s..." text) + (find-file text))) + +(defun rmail-move-message-to-folder-on-line () + "If the current line is a folder, move current message to it." + (interactive) + (save-excursion + (beginning-of-line) + (if (re-search-forward "<M> " (save-excursion (end-of-line) (point)) t) + (progn + (forward-char -2) + (speedbar-do-function-pointer))))) + +(defun rmail-speedbar-move-message (text token indent) + "From button TEXT, copy current message to the rmail file specified by TOKEN. +TEXT and INDENT are not used." + (speedbar-with-attached-buffer + (message "Moving message to %s" token) + (rmail-output-to-rmail-file token))) + +;;; W3 speedbar help +(defvar w3-speedbar-last-buffer nil + "The last buffer shown by w3-speedbar.") + +(defun w3-speedbar-buttons (buffer) + "Create speedbar buttons for the current web BUFFER displayed in w3 mode." + (save-excursion + (goto-char (point-min)) + (if (and (looking-at "History:") (equal w3-speedbar-last-buffer buffer)) + nil + (setq w3-speedbar-last-buffer buffer) + (erase-buffer) + (let ((links (save-excursion (set-buffer buffer) (w3-only-links))) + (part nil)) + (insert "History:\n") + ;; This taken out of w3 which was used to create the history list, + ;; and is here modified to create the speedbar buttons + (cl-maphash + (function + (lambda (url desc) + (speedbar-insert-button (w3-speedbar-shorten-button url) + 'speedbar-directory-face 'highlight + 'w3-speedbar-link url))) + url-history-list) + (insert "Links:\n") + (while links + (setq part (car (cdr (member 'href (car links)))) + links (cdr links)) + (speedbar-insert-button (w3-speedbar-shorten-button part) + 'speedbar-file-face 'highlight + 'w3-speedbar-link part)))))) + +(defun w3-speedbar-shorten-button (button) + "Takes text BUTTON and shortens it as much as possible." + ;; I should make this more complex, but I'm not sure how... + (let ((fnnd (file-name-nondirectory button))) + (if (< 0 (length fnnd)) + fnnd + (if (string-match "\\(ht\\|f\\)tp://" button) + (setq button (substring button (match-end 0)))) + (if (string-match "/$" button) + (setq button (substring button 0 (match-beginning 0)))) + button))) + +(defun w3-speedbar-link (text token indent) + "Follow link described by TEXT which has the URL TOKEN. +INDENT is not used." + (speedbar-with-attached-buffer (w3-fetch token))) + +(provide 'speedbspec) +;;; speedbspec ends here