Merge from emacs-24; up to 2012-05-04T19:17:01Z!monnier@iro.umontreal.ca
[bpt/emacs.git] / lisp / speedbar.el
index dad2a4c..16993ce 100644 (file)
@@ -1,6 +1,6 @@
 ;;; speedbar --- quick access to files and tags in a frame
 
-;; Copyright (C) 1996-201 Free Software Foundation, Inc.
+;; Copyright (C) 1996-2012 Free Software Foundation, Inc.
 
 ;; Author: Eric M. Ludlam <zappo@gnu.org>
 ;; Keywords: file, tags, tools
@@ -35,7 +35,7 @@ this version is not backward compatible to 0.14 or earlier.")
 ;;
 ;;; Customizing and Developing for speedbar
 ;;
-;; Please see the speedbar manual for informaion.
+;; Please see the speedbar manual for information.
 ;;
 ;;; Notes:
 ;;
@@ -125,7 +125,6 @@ this version is not backward compatible to 0.14 or earlier.")
 ;;; TODO:
 ;; - Timeout directories we haven't visited in a while.
 
-(require 'assoc)
 (require 'easymenu)
 (require 'dframe)
 (require 'sb-image)
@@ -471,7 +470,7 @@ Possible values are:
  'trim - trim large directories to only show the last few.
  nil   - no trimming."
   :group 'speedbar
-  :type '(radio (const :tag "Span large directories over mutiple lines."
+  :type '(radio (const :tag "Span large directories over multiple lines."
                       span)
                (const :tag "Trim large directories to only show the last few."
                       trim)
@@ -631,8 +630,8 @@ with `.' followed by extensions, followed by full-filenames."
                               (substring (car extlist) 1)))
        (setq regex2 (concat regex2 (if regex2 "\\|" "") (car extlist))))
       (setq extlist (cdr extlist)))
-    ;; concat all the sub-exressions together, making sure all types
-    ;; of parts exist during concatination.
+    ;; Concatenate all the subexpressions together, making sure all types
+    ;; of parts exist during concatenation.
     (concat "\\("
            (if regex1 (concat "\\(\\.\\(" regex1 "\\)\\)") "")
            (if (and regex1 regex2) "\\|" "")
@@ -659,7 +658,7 @@ speedbar is loaded.  You may place anything you like in this list
 before speedbar has been loaded."
   :group 'speedbar
   :type '(repeat (regexp :tag "Directory Regexp"))
-  :set (lambda (sym val)
+  :set (lambda (_sym val)
         (setq speedbar-ignored-directory-expressions val
               speedbar-ignored-directory-regexp
               (speedbar-extension-list-to-regex val))))
@@ -696,7 +695,7 @@ function `speedbar-extension-list-to-regex'.")
   (append '(".[ch]\\(\\+\\+\\|pp\\|c\\|h\\|xx\\)?" ".tex\\(i\\(nfo\\)?\\)?"
            ".el" ".emacs" ".l" ".lsp" ".p" ".java" ".js" ".f\\(90\\|77\\|or\\)?")
          (if speedbar-use-imenu-flag
-             '(".ada" ".p[lm]" ".tcl" ".m" ".scm" ".pm" ".py" ".g"
+             '(".ad[abs]" ".p[lm]" ".tcl" ".m" ".scm" ".pm" ".py" ".g"
                ;; html is not supported by default, but an imenu tags package
                ;; is available.  Also, html files are nice to be able to see.
                ".s?html"
@@ -713,7 +712,7 @@ need to also modify `completion-ignored-extension' which will also help
 file completion."
   :group 'speedbar
   :type '(repeat (regexp :tag "Extension Regexp"))
-  :set (lambda (sym val)
+  :set (lambda (_sym val)
         (set 'speedbar-supported-extension-expressions val)
         (set 'speedbar-file-regexp (speedbar-extension-list-to-regex val))))
 
@@ -775,6 +774,8 @@ If you want to change this while speedbar is active, either use
 (defvar speedbar-update-flag-disable nil
   "Permanently disable changing of the update flag.")
 
+(define-obsolete-variable-alias
+  'speedbar-syntax-table 'speedbar-mode-syntax-table "24.1")
 (defvar speedbar-mode-syntax-table
   (let ((st (make-syntax-table)))
     ;; Turn off paren matching around here.
@@ -788,10 +789,9 @@ If you want to change this while speedbar is active, either use
     (modify-syntax-entry ?\]  " " st)
     st)
   "Syntax-table used on the speedbar.")
-(define-obsolete-variable-alias
-  'speedbar-syntax-table 'speedbar-mode-syntax-table "24.1")
 
 
+(define-obsolete-variable-alias 'speedbar-key-map 'speedbar-mode-map "24.1")
 (defvar speedbar-mode-map
   (let ((map (make-keymap)))
     (suppress-keymap map t)
@@ -826,7 +826,6 @@ If you want to change this while speedbar is active, either use
     (dframe-update-keymap map)
     map)
   "Keymap used in speedbar buffer.")
-(define-obsolete-variable-alias 'speedbar-key-map 'speedbar-mode-map "24.1")
 
 (defun speedbar-make-specialized-keymap ()
   "Create a keymap for use with a speedbar major or minor display mode.
@@ -1004,7 +1003,7 @@ supported at a time.
                     #'speedbar-frame-mode
                     (if (featurep 'xemacs)
                         (append speedbar-frame-plist
-                                ;; This is a hack to get speedbar to iconfiy
+                                ;; This is a hack to get speedbar to iconify
                                 ;; with the selected frame.
                                 (list 'parent (selected-frame)))
                       speedbar-frame-parameters)
@@ -1022,7 +1021,7 @@ supported at a time.
   (set (make-local-variable 'dframe-delete-frame-function)
        'speedbar-handle-delete-frame)
   ;; hscroll
-  (set (make-local-variable 'automatic-hscrolling) nil) ; Emacs 21
+  (set (make-local-variable 'auto-hscroll-mode) nil)
   ;; reset the selection variable
   (setq speedbar-last-selected-file nil))
 
@@ -1413,9 +1412,10 @@ Argument ARG represents to force a refresh past any caches that may exist."
        (dframe-power-click arg)
        deactivate-mark)
     ;; We need to hack something so this works in detached frames.
-    (while dl
-      (adelete 'speedbar-directory-contents-alist (car dl))
-      (setq dl (cdr dl)))
+    (dolist (d dl)
+      (setq speedbar-directory-contents-alist
+            (delq (assoc d speedbar-directory-contents-alist)
+                  speedbar-directory-contents-alist)))
     (if (<= 1 speedbar-verbosity-level)
        (speedbar-message "Refreshing speedbar..."))
     (speedbar-update-contents)
@@ -1622,7 +1622,7 @@ Files can be renamed to new names or moved to new directories."
   (let ((f (speedbar-line-file)))
     (if f
        (let* ((basedir (file-name-directory f))
-              (nd (read-file-name "Create directory: "
+              (nd (read-directory-name "Create directory: "
                                   basedir)))
          ;; Make the directory
          (make-directory nd t)
@@ -1862,11 +1862,9 @@ of the special mode functions."
            (if (not v)
                (setq speedbar-special-mode-expansion-list t)
              ;; If it is autoloaded, we need to load it now so that
-             ;; we have access to the varialbe -speedbar-menu-items.
+             ;; we have access to the variable -speedbar-menu-items.
              ;; Is this XEmacs safe?
-             (let ((sf (symbol-function v)))
-               (if (and (listp sf) (eq (car sf) 'autoload))
-                   (load-library (car (cdr sf)))))
+              (autoload-do-load (symbol-function v) v)
              (setq speedbar-special-mode-expansion-list (list v))
              (setq v (intern-soft (concat ms "-speedbar-key-map")))
              (if (not v)
@@ -1898,12 +1896,9 @@ matching ignored headers.  Cache any directory files found in
 `speedbar-directory-contents-alist' and use that cache before scanning
 the file-system."
   (setq directory (expand-file-name directory))
-  ;; If in powerclick mode, then the directory we are getting
-  ;; should be rescanned.
-  (if dframe-power-click
-      (adelete 'speedbar-directory-contents-alist directory))
   ;; find the directory, either in the cache, or build it.
-  (or (cdr-safe (assoc directory speedbar-directory-contents-alist))
+  (or (and (not dframe-power-click) ;; In powerclick mode, always rescan.
+           (cdr-safe (assoc directory speedbar-directory-contents-alist)))
       (let ((default-directory directory)
            (dir (directory-files directory nil))
            (dirs nil)
@@ -1917,12 +1912,15 @@ the file-system."
                  (setq dirs (cons (car dir) dirs))
                (setq files (cons (car dir) files))))
          (setq dir (cdr dir)))
-       (let ((nl (cons (nreverse dirs) (list (nreverse files)))))
-         (aput 'speedbar-directory-contents-alist directory nl)
+       (let ((nl (cons (nreverse dirs) (list (nreverse files))))
+              (ae (assoc directory speedbar-directory-contents-alist)))
+          (if ae (setcdr ae nl)
+            (push (cons directory nl)
+                  speedbar-directory-contents-alist))
          nl))
       ))
 
-(defun speedbar-directory-buttons (directory index)
+(defun speedbar-directory-buttons (directory _index)
   "Insert a single button group at point for DIRECTORY.
 Each directory part is a different button.  If part of the directory
 matches the user directory ~, then it is replaced with a ~.
@@ -2100,12 +2098,12 @@ cell of the form ( 'DIRLIST . 'FILELIST )."
   (if (= index 0)
       ;; If the shown files variable has extra directories, then
       ;; it is our responsibility to redraw them all
-      ;; Luckilly, the nature of inserting items into this list means
-      ;; that by reversing it, we can easilly go in the right order
+      ;; Luckily, the nature of inserting items into this list means
+      ;; that by reversing it, we can easily go in the right order
       (let ((sf (cdr (reverse speedbar-shown-directories))))
        (setq speedbar-shown-directories
              (list (expand-file-name default-directory)))
-       ;; exand them all as we find them
+       ;; Expand them all as we find them.
        (while sf
          (if (speedbar-goto-this-file (car sf))
              (progn
@@ -2219,7 +2217,7 @@ passes some tests."
        ;; Go through all our bins  Stick singles into our
        ;; junk-list, everything else as sublsts in work-list.
        ;; If two neighboring lists are both small, make a grouped
-       ;; group combinding those two sub-lists.
+       ;; group combining those two sub-lists.
        (setq diff-idx 0)
        (while (> 256 diff-idx)
          ;; The bins contents are currently in forward order.
@@ -3063,7 +3061,7 @@ a function if appropriate."
   (let* ((speedbar-frame (speedbar-current-frame))
         (fn (get-text-property (point) 'speedbar-function))
         (tok (get-text-property (point) 'speedbar-token))
-        ;; The 1-,+ is safe because scaning starts AFTER the point
+        ;; The 1-,+ is safe because scanning starts AFTER the point
         ;; specified.  This lets the search include the character the
         ;; cursor is on.
         (tp (previous-single-property-change
@@ -3292,7 +3290,7 @@ With universal argument ARG, flush cached data."
 Optional argument ARG indicates that any cache should be flushed."
   (interactive "P")
   (speedbar-expand-line arg)
-  ;; Now, inside the area expaded here, expand all subnodes of
+  ;; Now, inside the area expanded here, expand all subnodes of
   ;; the same descendant type.
   (save-excursion
     (speedbar-next 1) ;; Move into the list.
@@ -3313,7 +3311,7 @@ Optional argument ARG indicates that any cache should be flushed."
   ;; hidden by default anyway.  Yay!  It's easy.
   )
 
-(defun speedbar-find-file (text token indent)
+(defun speedbar-find-file (text _token indent)
   "Speedbar click handler for filenames.
 TEXT, the file will be displayed in the attached frame.
 TOKEN is unused, but required by the click handler.  INDENT is the
@@ -3327,13 +3325,13 @@ current indentation level."
     (speedbar-find-file-in-frame (concat cdd text))
     (speedbar-stealthy-updates)
     (run-hooks 'speedbar-visiting-file-hook)
-    ;; Reset the timer with a new timeout when cliking a file
+    ;; Reset the timer with a new timeout when clicking a file
     ;; in case the user was navigating directories, we can cancel
     ;; that other timer.
     (speedbar-set-timer dframe-update-speed))
   (dframe-maybee-jump-to-attached-frame))
 
-(defun speedbar-dir-follow (text token indent)
+(defun speedbar-dir-follow (text _token indent)
   "Speedbar click handler for directory names.
 Clicking a directory will cause the speedbar to list files in
 the subdirectory TEXT.  TOKEN is an unused requirement.  The
@@ -3401,7 +3399,7 @@ expanded.  INDENT is the current indentation level."
   (speedbar-center-buffer-smartly)
   (save-excursion (speedbar-stealthy-updates)))
 
-(defun speedbar-directory-buttons-follow (text token indent)
+(defun speedbar-directory-buttons-follow (_text token _indent)
   "Speedbar click handler for default directory buttons.
 TEXT is the button clicked on.  TOKEN is the directory to follow.
 INDENT is the current indentation level and is unused."
@@ -3422,7 +3420,6 @@ indentation level."
   (cond ((string-match "+" text)       ;we have to expand this file
         (let* ((fn (expand-file-name (concat (speedbar-line-directory indent)
                                              token)))
-               (mode nil)
                (lst (speedbar-fetch-dynamic-tags fn)))
           ;; if no list, then remove expando button
           (if (not lst)
@@ -3438,7 +3435,7 @@ indentation level."
        (t (error "Ooops...  not sure what to do")))
   (speedbar-center-buffer-smartly))
 
-(defun speedbar-tag-find (text token indent)
+(defun speedbar-tag-find (_text token indent)
   "For the tag TEXT in a file TOKEN, go to that position.
 INDENT is the current indentation level."
   (let ((file (speedbar-line-directory indent)))
@@ -3448,7 +3445,7 @@ INDENT is the current indentation level."
       (select-frame f))
     (speedbar-find-file-in-frame file)
     (save-excursion (speedbar-stealthy-updates))
-    ;; Reset the timer with a new timeout when cliking a file
+    ;; Reset the timer with a new timeout when clicking a file
     ;; in case the user was navigating directories, we can cancel
     ;; that other timer.
     (speedbar-set-timer dframe-update-speed)
@@ -3838,12 +3835,12 @@ regular expression EXPR."
     )
   "Menu item elements shown when displaying a buffer list.")
 
-(defun speedbar-buffer-buttons (directory zero)
+(defun speedbar-buffer-buttons (_directory _zero)
   "Create speedbar buttons based on the buffers currently loaded.
 DIRECTORY is the directory of the currently active buffer, and ZERO is 0."
   (speedbar-buffer-buttons-engine nil))
 
-(defun speedbar-buffer-buttons-temp (directory zero)
+(defun speedbar-buffer-buttons-temp (_directory _zero)
   "Create speedbar buttons based on the buffers currently loaded.
 DIRECTORY is the directory of the currently active buffer, and ZERO is 0."
   (speedbar-buffer-buttons-engine t))
@@ -3901,11 +3898,8 @@ If TEMP is non-nil, then clicking on a buffer restores the previous display."
 (defun speedbar-buffers-tail-notes (buffer)
   "Add a note to the end of the last tag line.
 Argument BUFFER is the buffer being tested."
-  (let (mod ro)
-    (with-current-buffer buffer
-      (setq mod (buffer-modified-p)
-           ro buffer-read-only))
-    (if ro (speedbar-insert-button "%" nil nil nil nil t))))
+  (when (with-current-buffer buffer buffer-read-only)
+    (speedbar-insert-button "%" nil nil nil nil t)))
 
 (defun speedbar-buffers-item-info ()
   "Display information about the current buffer on the current line."
@@ -3920,7 +3914,7 @@ Argument BUFFER is the buffer being tested."
                               (with-current-buffer buffer (buffer-size))
                               (or (buffer-file-name buffer) "<No file>"))))))
 
-(defun speedbar-buffers-line-directory (&optional depth)
+(defun speedbar-buffers-line-directory (&optional _depth)
   "Fetch the directory of the file (buffer) specified on the current line.
 Optional argument DEPTH specifies the current depth of the back search."
   (save-excursion
@@ -3937,7 +3931,7 @@ Optional argument DEPTH specifies the current depth of the back search."
                      "")
                (buffer-file-name buffer))))))))
 
-(defun speedbar-buffer-click (text token indent)
+(defun speedbar-buffer-click (text token _indent)
   "When the users clicks on a buffer-button in speedbar.
 TEXT is the buffer's name, TOKEN and INDENT are unused."
   (if dframe-power-click
@@ -3991,11 +3985,11 @@ TEXT is the buffer's name, TOKEN and INDENT are unused."
 
 (defun speedbar-unhighlight-one-tag-line ()
   "Unhighlight the currently highlighted line."
-  (if speedbar-highlight-one-tag-line
-      (progn
-       (speedbar-delete-overlay speedbar-highlight-one-tag-line)
-       (setq speedbar-highlight-one-tag-line nil)))
-  (remove-hook 'pre-command-hook 'speedbar-unhighlight-one-tag-line))
+  (when (and speedbar-highlight-one-tag-line
+            (not (eq this-command 'handle-switch-frame)))
+    (speedbar-delete-overlay speedbar-highlight-one-tag-line)
+    (setq speedbar-highlight-one-tag-line nil)
+    (remove-hook 'pre-command-hook 'speedbar-unhighlight-one-tag-line)))
 
 (defun speedbar-recenter-to-top ()
   "Recenter the current buffer so point is on the top of the window."
@@ -4009,73 +4003,68 @@ TEXT is the buffer's name, TOKEN and INDENT are unused."
 ;;; Color loading section.
 ;;
 (defface speedbar-button-face '((((class color) (background light))
-                                (:foreground "green4"))
+                                :foreground "green4")
                                (((class color) (background dark))
-                                (:foreground "green3")))
-  "Face used for +/- buttons."
+                                :foreground "green3"))
+  "Speedbar face for +/- buttons."
   :group 'speedbar-faces)
 
 (defface speedbar-file-face '((((class color) (background light))
-                              (:foreground "cyan4"))
+                              :foreground "cyan4")
                              (((class color) (background dark))
-                              (:foreground "cyan"))
-                             (t (:bold t)))
-  "Face used for file names."
+                              :foreground "cyan")
+                             (t :weight bold))
+  "Speedbar face for file names."
   :group 'speedbar-faces)
 
 (defface speedbar-directory-face '((((class color) (background light))
-                                   (:foreground "blue4"))
+                                   :foreground "blue4")
                                   (((class color) (background dark))
-                                   (:foreground "light blue")))
-  "Face used for directory names."
+                                   :foreground "light blue"))
+  "Speedbar face for directory names."
   :group 'speedbar-faces)
+
 (defface speedbar-tag-face '((((class color) (background light))
-                             (:foreground "brown"))
+                             :foreground "brown")
                             (((class color) (background dark))
-                             (:foreground "yellow")))
-  "Face used for displaying tags."
+                             :foreground "yellow"))
+  "Speedbar face for tags."
   :group 'speedbar-faces)
 
 (defface speedbar-selected-face '((((class color) (background light))
-                                   (:foreground "red" :underline t))
+                                  :foreground "red" :underline t)
                                  (((class color) (background dark))
-                                  (:foreground "red" :underline t))
-                                 (t (:underline t)))
-  "Face used to underline the file in the active window."
+                                  :foreground "red" :underline t)
+                                 (t :underline t))
+  "Speedbar face for the file in the active window."
   :group 'speedbar-faces)
 
 (defface speedbar-highlight-face '((((class color) (background light))
-                                   (:background "green"))
+                                   :background "green")
                                   (((class color) (background dark))
-                                   (:background "sea green"))
-                                  (((class grayscale monochrome)
-                                    (background light))
-                                   (:background "black"))
-                                  (((class grayscale monochrome)
-                                    (background dark))
-                                   (:background "white")))
-  "Face used for highlighting buttons with the mouse."
+                                   :background "sea green"))
+  "Speedbar face for highlighting buttons with the mouse."
   :group 'speedbar-faces)
 
 (defface speedbar-separator-face '((((class color) (background light))
-                                   (:background "blue"
-                                    :foreground "white"
-                                    :overline "gray"))
+                                   :background "blue"
+                                   :foreground "white"
+                                   :overline "gray")
                                   (((class color) (background dark))
-                                   (:background "blue"
-                                    :foreground "white"
-                                    :overline "gray"))
+                                   :background "blue"
+                                   :foreground "white"
+                                   :overline "gray")
                                   (((class grayscale monochrome)
                                     (background light))
-                                   (:background "black"
-                                    :foreground "white"
-                                    :overline "white"))
+                                   :background "black"
+                                   :foreground "white"
+                                   :overline "white")
                                   (((class grayscale monochrome)
                                     (background dark))
-                                   (:background "white"
-                                    :foreground "black"
-                                    :overline "black")))
-  "Face used for separator labels in a display."
+                                   :background "white"
+                                   :foreground "black"
+                                   :overline "black"))
+  "Speedbar face for separator labels in a display."
   :group 'speedbar-faces)
 
 ;; some edebug hooks