Fix typo.
[bpt/emacs.git] / lisp / icomplete.el
index 6599c14..38fbf8f 100644 (file)
@@ -1,7 +1,7 @@
 ;;; icomplete.el --- minibuffer completion incremental feedback
 
 ;; Copyright (C) 1992, 1993, 1994, 1997, 1999, 2001, 2002, 2003,
-;;   2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+;;   2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 ;; Author: Ken Manheimer <klm@i.am>
 ;; Maintainer: Ken Manheimer <klm@i.am>
 
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs 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.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -22,9 +22,7 @@
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
 
 ;;;_* User Customization variables
 (defcustom icomplete-prospects-length 80
-  "*Length of string displaying the prospects."
+  "Length of string displaying the prospects."
   :type 'integer
   :group 'icomplete)
 
 (defcustom icomplete-compute-delay .3
-  "*Completions-computation stall, used only with large-number
-completions - see `icomplete-delay-completions-threshold'."
+  "Completions-computation stall, used only with large-number completions.
+See `icomplete-delay-completions-threshold'."
   :type 'number
   :group 'icomplete)
 
 (defcustom icomplete-delay-completions-threshold 400
-  "*Pending-completions number over which to apply icomplete-compute-delay."
+  "Pending-completions number over which to apply `icomplete-compute-delay'."
   :type 'integer
   :group 'icomplete)
 
 (defcustom icomplete-max-delay-chars 3
-  "*Maximum number of initial chars to apply icomplete compute delay."
+  "Maximum number of initial chars to apply icomplete compute delay."
   :type 'integer
   :group 'icomplete)
 
 (defcustom icomplete-show-key-bindings t
-  "*If non-nil, show key bindings as well as completion for sole matches."
+  "If non-nil, show key bindings as well as completion for sole matches."
   :type 'boolean
   :group 'icomplete)
 
 (defcustom icomplete-minibuffer-setup-hook nil
-  "*Icomplete-specific customization of minibuffer setup.
+  "Icomplete-specific customization of minibuffer setup.
 
-This hook is run during minibuffer setup iff icomplete will be active.
+This hook is run during minibuffer setup if icomplete is active.
 It is intended for use in customizing icomplete for interoperation
 with other features and packages.  For instance:
 
@@ -147,8 +145,7 @@ is minibuffer."
     (save-excursion
       (let* ((sym (intern func-name))
             (buf (other-buffer nil t))
-            (map (save-excursion (set-buffer buf) (current-local-map)))
-            (keys (where-is-internal sym map)))
+            (keys (with-current-buffer buf (where-is-internal sym))))
        (if keys
            (concat "<"
                    (mapconcat 'key-description
@@ -168,7 +165,8 @@ except those on this list.")
 ;;;###autoload
 (define-minor-mode icomplete-mode
   "Toggle incremental minibuffer completion for this Emacs session.
-With a numeric argument, turn Icomplete mode on iff ARG is positive."
+With a numeric argument, turn Icomplete mode on if ARG is positive,
+otherwise turn it off."
   :global t :group 'icomplete
   (if icomplete-mode
       ;; The following is not really necessary after first time -
@@ -191,6 +189,7 @@ Conditions are:
        (not executing-kbd-macro)
        minibuffer-completion-table
        (or (not (functionp minibuffer-completion-table))
+           (eq icomplete-with-completion-tables t)
            (member minibuffer-completion-table
                    icomplete-with-completion-tables))))
 
@@ -282,39 +281,65 @@ The displays for unambiguous matches have ` [Matched]' appended
 matches exist.  \(Keybindings for uniquely matched commands
 are exhibited within the square braces.)"
 
-  ;; 'all-completions' doesn't like empty
-  ;; minibuffer-completion-table's (ie: (nil))
-  (if (and (listp candidates) (null (car candidates)))
-      (setq candidates nil))
-
-  (let ((comps (all-completions name candidates predicate))
-                                        ; "-determined" - only one candidate
-        (open-bracket-determined (if require-match "(" "["))
-        (close-bracket-determined (if require-match ")" "]")))
+  (let* ((comps (completion-all-completions name candidates predicate
+                                            (length name)))
+         (last (last comps))
+         (base-size (if (consp last) (prog1 (cdr last) (setcdr last nil))))
+         (open-bracket (if require-match "(" "["))
+         (close-bracket (if require-match ")" "]")))
     ;; `concat'/`mapconcat' is the slow part.  With the introduction of
     ;; `icomplete-prospects-length', there is no need for `catch'/`throw'.
-    (if (null comps) (format " %sNo matches%s"
-                            open-bracket-determined
-                            close-bracket-determined)
-      (let* ((most-try (try-completion name (mapcar (function list) comps)))
-            (most (if (stringp most-try) most-try (car comps)))
-            (most-len (length most))
-            (determ (and (> most-len (length name))
-                         (concat open-bracket-determined
-                                 (substring most (length name))
-                                 close-bracket-determined)))
+    (if (null comps)
+        (format " %sNo matches%s" open-bracket close-bracket)
+      (let* ((most-try (completion-try-completion
+                        name
+                       ;; If the `comps' are 0-based, the result should be
+                       ;; the same with `comps'.
+                        (if base-size candidates comps)
+                        predicate
+                        (length name)))
+            (most (if (consp most-try) (car most-try) (car comps)))
+             ;; Compare name and most, so we can determine if name is
+             ;; a prefix of most, or something else.
+            (compare (compare-strings name nil nil
+                                      most nil nil completion-ignore-case))
+            (determ (unless (or (eq t compare) (eq t most-try)
+                                (= (setq compare (1- (abs compare)))
+                                   (length most)))
+                      (concat open-bracket
+                              (cond
+                               ((= compare (length name))
+                                 ;; Typical case: name is a prefix.
+                                (substring most compare))
+                               ((< compare 5) most)
+                               (t (concat "..." (substring most compare))))
+                              close-bracket)))
             ;;"-prospects" - more than one candidate
-            (prospects-len 0)
-            prospects most-is-exact comp)
-       (if (eq most-try t)
+            (prospects-len (+ (length determ) 6)) ;; take {,...} into account
+             (prefix-len
+              ;; Find the common prefix among `comps'.
+             (if (eq t (compare-strings (car comps) nil (length most)
+                                        most nil nil case-fold-search))
+                  ;; Common case.
+                 (length most)
+                ;; Else, use try-completion.
+               (let ((comps-prefix (try-completion "" comps)))
+                  (and (stringp comps-prefix)
+                       (length comps-prefix)))))
+
+            prospects most-is-exact comp limit)
+       (if (or (eq most-try t) (null (cdr comps)))
            (setq prospects nil)
-         (while (and comps (< prospects-len icomplete-prospects-length))
-           (setq comp (substring (car comps) most-len)
+         (while (and comps (not limit))
+           (setq comp
+                  (if prefix-len (substring (car comps) prefix-len) (car comps))
                  comps (cdr comps))
            (cond ((string-equal comp "") (setq most-is-exact t))
                  ((member comp prospects))
-                 (t (setq prospects (cons comp prospects)
-                          prospects-len (+ (length comp) 1 prospects-len))))))
+                 (t (setq prospects-len (+ (length comp) 1 prospects-len))
+                    (if (< prospects-len icomplete-prospects-length)
+                        (setq prospects (cons comp prospects))
+                      (setq limit t))))))
        (if prospects
            (concat determ
                    "{"
@@ -332,10 +357,10 @@ are exhibited within the square braces.)"
                    (if keys (concat "; " keys) ""))
                  "]"))))))
 
-;;;_* Local emacs vars.
-;;;Local variables:
-;;;allout-layout: (-2 :)
-;;;End:
+;;_* Local emacs vars.
+;;Local variables:
+;;allout-layout: (-2 :)
+;;End:
 
 ;; arch-tag: 339ec25a-0741-4eb6-be63-997532e89b0f
 ;;; icomplete.el ends here