* lisp/simple.el (choose-completion): Use quit-window.
[bpt/emacs.git] / lisp / speedbar.el
index dd5efd2..28879fe 100644 (file)
@@ -1,8 +1,6 @@
 ;;; speedbar --- quick access to files and tags in a frame
 
-;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-;;   2005, 2006, 2007, 2008, 2009, 2010, 2011
-;;   Free Software Foundation, Inc.
+;; Copyright (C) 1996-2012 Free Software Foundation, Inc.
 
 ;; Author: Eric M. Ludlam <zappo@gnu.org>
 ;; Keywords: file, tags, tools
@@ -37,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:
 ;;
@@ -127,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)
@@ -473,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)
@@ -616,8 +613,11 @@ state data."
   :group 'speedbar
   :type 'hook)
 
-(defvar speedbar-ignored-modes '(fundamental-mode)
-  "*List of major modes which speedbar will not switch directories for.")
+(defcustom speedbar-ignored-modes '(fundamental-mode)
+  "List of major modes which speedbar will not switch directories for."
+  :group 'speedbar
+  :type '(choice (const nil)
+                (repeat :tag "List of modes" (symbol :tag "Major mode"))))
 
 (defun speedbar-extension-list-to-regex (extlist)
   "Takes EXTLIST, a list of extensions and transforms it into regexp.
@@ -630,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) "\\|" "")
@@ -658,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))))
@@ -671,7 +671,7 @@ directories here; see `vc-directory-exclusion-list'."
   :group 'speedbar
   :type 'string)
 
-(defvar speedbar-file-unshown-regexp
+(defcustom speedbar-file-unshown-regexp
   (let ((nstr "") (noext completion-ignored-extensions))
     (while noext
       (setq nstr (concat nstr (regexp-quote (car noext)) "\\'"
@@ -679,8 +679,10 @@ directories here; see `vc-directory-exclusion-list'."
            noext (cdr noext)))
     ;;               backup      refdir      lockfile
     (concat nstr "\\|#[^#]+#$\\|\\.\\.?\\'\\|\\.#"))
-  "*Regexp matching files we don't want displayed in a speedbar buffer.
-It is generated from the variable `completion-ignored-extensions'.")
+  "Regexp matching files we don't want displayed in a speedbar buffer.
+It is generated from the variable `completion-ignored-extensions'."
+  :group 'speedbar
+  :type 'string)
 
 (defvar speedbar-file-regexp nil
   "Regular expression matching files we know how to expand.
@@ -693,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"
@@ -710,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))))
 
@@ -757,18 +759,23 @@ DIRECTORY-EXPRESSION to `speedbar-ignored-directory-expressions'."
          speedbar-ignored-directory-regexp (speedbar-extension-list-to-regex
                                        speedbar-ignored-directory-expressions)))
 
-(defvar speedbar-update-flag dframe-have-timer-flag
-  "*Non-nil means to automatically update the display.
+(defcustom speedbar-update-flag dframe-have-timer-flag
+  "Non-nil means to automatically update the display.
 When this is nil then speedbar will not follow the attached frame's directory.
-When speedbar is active, use:
-
-\\<speedbar-key-map> `\\[speedbar-toggle-updates]'
-
-to toggle this value.")
+If you want to change this while speedbar is active, either use
+\\[customize] or call \\<speedbar-key-map> `\\[speedbar-toggle-updates]'."
+  :group 'speedbar
+  :initialize 'custom-initialize-default
+  :set (lambda (sym val)
+        (set sym val)
+        (speedbar-toggle-updates))
+  :type 'boolean)
 
 (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.
@@ -782,10 +789,9 @@ to toggle this value.")
     (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)
@@ -820,7 +826,6 @@ to toggle this value.")
     (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.
@@ -998,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)
@@ -1016,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))
 
@@ -1407,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)
@@ -1616,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)
@@ -1856,7 +1862,7 @@ 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))
@@ -1892,12 +1898,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)
@@ -1911,12 +1914,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 ~.
@@ -2094,12 +2100,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
@@ -2213,7 +2219,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.
@@ -3057,7 +3063,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
@@ -3286,7 +3292,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.
@@ -3307,7 +3313,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
@@ -3321,13 +3327,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
@@ -3395,7 +3401,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."
@@ -3416,7 +3422,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)
@@ -3432,7 +3437,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)))
@@ -3442,7 +3447,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)
@@ -3645,17 +3650,20 @@ to be at the beginning of a line in the etags buffer.
 
 This variable is ignored if `speedbar-use-imenu-flag' is non-nil.")
 
-(defvar speedbar-fetch-etags-command "etags"
-  "*Command used to create an etags file.
-
-This variable is ignored if `speedbar-use-imenu-flag' is t.")
+(defcustom speedbar-fetch-etags-command "etags"
+  "Command used to create an etags file.
+This variable is ignored if `speedbar-use-imenu-flag' is t."
+  :group 'speedbar
+  :type 'string)
 
-(defvar speedbar-fetch-etags-arguments '("-D" "-I" "-o" "-")
-  "*List of arguments to use with `speedbar-fetch-etags-command'.
+(defcustom speedbar-fetch-etags-arguments '("-D" "-I" "-o" "-")
+  "List of arguments to use with `speedbar-fetch-etags-command'.
 This creates an etags output buffer.  Use `speedbar-toggle-etags' to
 modify this list conveniently.
-
-This variable is ignored if `speedbar-use-imenu-flag' is t.")
+This variable is ignored if `speedbar-use-imenu-flag' is t."
+  :group 'speedbar
+  :type '(choice (const nil)
+                (repeat :tag "List of arguments" string)))
 
 (defun speedbar-toggle-etags (flag)
   "Toggle FLAG in `speedbar-fetch-etags-arguments'.
@@ -3829,12 +3837,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))
@@ -3892,11 +3900,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."
@@ -3911,7 +3916,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
@@ -3928,7 +3933,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
@@ -3982,11 +3987,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."