]> code.delx.au - gnu-emacs/blobdiff - lisp/icomplete.el
(calc-embedded-close-formula, calc-embedded-open-formula,
[gnu-emacs] / lisp / icomplete.el
index 2fd7b2f125040549f28bb2c76f45f111fef93374..085c111d85655a70cd62b65989925a4a16210290 100644 (file)
@@ -1,10 +1,12 @@
-;;; icomplete.el - minibuffer completion incremental feedback
+;;; icomplete.el --- minibuffer completion incremental feedback
 
 
-;; Copyright (C) 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
+;; Copyright (C) 1992, 1993, 1994, 1997, 1999, 2001, 2002, 2003,
+;;   2004, 2005 Free Software Foundation, Inc.
 
 
-;; Author: Ken Manheimer <klm@python.org>
-;; Maintainer: Ken Manheimer <klm@python.org>
-;; Created: Mar 1993 klm@nist.gov - first release to usenet
+;; Author: Ken Manheimer <klm@i.am>
+;; Maintainer: Ken Manheimer <klm@i.am>
+;; Created: Mar 1993 Ken Manheimer, klm@nist.gov - first release to usenet
+;; Last update: Ken Manheimer <klm@i.am>, 11/18/1999.
 ;; Keywords: help, abbrev
 
 ;; This file is part of GNU Emacs.
 ;; Keywords: help, abbrev
 
 ;; This file is part of GNU Emacs.
@@ -21,8 +23,8 @@
 
 ;; 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
 
 ;; 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., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
 ;;; Commentary:
 
 
 ;;; Commentary:
 
 ;; customize icomplete setup for interoperation with other
 ;; minibuffer-oriented packages.
 
 ;; customize icomplete setup for interoperation with other
 ;; minibuffer-oriented packages.
 
-;; To activate icomplete mode, simply add the following to .emacs:
-;; (icomplete-mode)
-;; You can subsequently deactivate it by invoking the function
-;; icomplete-mode with a negative prefix-arg (C-U -1 ESC-x
-;; icomplete-mode).  Also, you can prevent activation of the mode
-;; during package load by first setting the variable `icomplete-mode'
-;; to nil.  Icompletion can be enabled any time after the package is
-;; loaded by invoking icomplete-mode without a prefix arg.
-
-;; This version of icomplete runs on Emacs 19.18 and later.  (It
-;; depends on the incorporation of minibuffer-setup-hook.)  The elisp
-;; archives, ftp://archive.cis.ohio-state.edu/pub/gnu/emacs/elisp-archive,
-;; probably still has a version that works in GNU Emacs v18.
+;; To activate icomplete mode, load the package and use the
+;; `icomplete-mode' function.  You can subsequently deactivate it by
+;; invoking the function icomplete-mode with a negative prefix-arg
+;; (C-U -1 ESC-x icomplete-mode).  Also, you can prevent activation of
+;; the mode during package load by first setting the variable
+;; `icomplete-mode' to nil.  Icompletion can be enabled any time after
+;; the package is loaded by invoking icomplete-mode without a prefix
+;; arg.
 
 ;; Thanks to everyone for their suggestions for refinements of this
 ;; package.  I particularly have to credit Michael Cook, who
 
 ;; Thanks to everyone for their suggestions for refinements of this
 ;; package.  I particularly have to credit Michael Cook, who
   :group 'minibuffer)
 
 ;;;_* User Customization variables
   :group 'minibuffer)
 
 ;;;_* User Customization variables
-(defcustom icomplete-mode nil
-  "*Non-nil enables incremental minibuffer completion.
-As text is typed into the minibuffer, prospective completions are indicated 
-in the minibuffer.
-You must modify via \\[customize] for this variable to have an effect."
-  :set (lambda (symbol value)
-        (icomplete-mode (if value 1 -1)))
-  :initialize 'custom-initialize-default
-  :type 'boolean
-  :group 'icomplete
-  :require 'icomplete)
+(defcustom icomplete-prospects-length 80
+  "*Length of string displaying the prospects."
+  :type 'integer
+  :group 'icomplete)
 
 (defcustom icomplete-compute-delay .3
   "*Completions-computation stall, used only with large-number
 
 (defcustom icomplete-compute-delay .3
   "*Completions-computation stall, used only with large-number
@@ -111,15 +101,15 @@ completions - see `icomplete-delay-completions-threshold'."
 
 This hook is run during minibuffer setup iff icomplete will be active.
 It is intended for use in customizing icomplete for interoperation
 
 This hook is run during minibuffer setup iff icomplete will be active.
 It is intended for use in customizing icomplete for interoperation
-with other packages.  For instance:
+with other features and packages.  For instance:
 
   \(add-hook 'icomplete-minibuffer-setup-hook
            \(function
             \(lambda ()
 
   \(add-hook 'icomplete-minibuffer-setup-hook
            \(function
             \(lambda ()
-              \(make-local-variable 'resize-minibuffer-window-max-height)
-              \(setq resize-minibuffer-window-max-height 3))))
+              \(make-local-variable 'max-mini-window-height)
+              \(setq max-mini-window-height 3))))
 
 
-will constrain rsz-mini to a maximum minibuffer height of 3 lines when
+will constrain Emacs to a maximum minibuffer height of 3 lines when
 icompletion is occurring."
   :type 'hook
   :group 'icomplete)
 icompletion is occurring."
   :type 'hook
   :group 'icomplete)
@@ -128,8 +118,8 @@ icompletion is occurring."
 ;;;_* Initialization
 
 ;;;_ + Internal Variables
 ;;;_* Initialization
 
 ;;;_ + Internal Variables
-;;;_  = icomplete-eoinput 1
-(defvar icomplete-eoinput 1
+;;;_  = icomplete-eoinput nil
+(defvar icomplete-eoinput nil
   "Point where minibuffer input ends and completion info begins.")
 (make-variable-buffer-local 'icomplete-eoinput)
 ;;;_  = icomplete-pre-command-hook
   "Point where minibuffer input ends and completion info begins.")
 (make-variable-buffer-local 'icomplete-eoinput)
 ;;;_  = icomplete-pre-command-hook
@@ -170,17 +160,15 @@ is minibuffer."
 
 ;;;_ > icomplete-mode (&optional prefix)
 ;;;###autoload
 
 ;;;_ > icomplete-mode (&optional prefix)
 ;;;###autoload
-(defun icomplete-mode (&optional prefix)
-  "Activate incremental minibuffer completion for this Emacs session.
-Deactivates with negative universal argument."
-  (interactive "p")
-  (or prefix (setq prefix 0))
-  (cond ((>= prefix 0)
-        (setq icomplete-mode t)
-        ;; The following is not really necessary after first time -
-        ;; no great loss.
-        (add-hook 'minibuffer-setup-hook 'icomplete-minibuffer-setup))
-       (t (setq icomplete-mode nil))))
+(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."
+  :global t :group 'icomplete
+  (if icomplete-mode
+      ;; The following is not really necessary after first time -
+      ;; no great loss.
+      (add-hook 'minibuffer-setup-hook 'icomplete-minibuffer-setup)
+    (remove-hook 'minibuffer-setup-hook 'icomplete-minibuffer-setup)))
 
 ;;;_ > icomplete-simple-completing-p ()
 (defun icomplete-simple-completing-p ()
 
 ;;;_ > icomplete-simple-completing-p ()
 (defun icomplete-simple-completing-p ()
@@ -189,32 +177,31 @@ Deactivates with negative universal argument."
 Conditions are:
    the selected window is a minibuffer,
    and not in the middle of macro execution,
 Conditions are:
    the selected window is a minibuffer,
    and not in the middle of macro execution,
-   and minibuffer-completion-table is not a symbol (which would
+   and `minibuffer-completion-table' is not a symbol (which would
        indicate some non-standard, non-simple completion mechanism,
        like file-name and other custom-func completions)."
 
   (and (window-minibuffer-p (selected-window))
        (not executing-kbd-macro)
        indicate some non-standard, non-simple completion mechanism,
        like file-name and other custom-func completions)."
 
   (and (window-minibuffer-p (selected-window))
        (not executing-kbd-macro)
-       (not (symbolp minibuffer-completion-table))))
+       minibuffer-completion-table
+       ;; (or minibuffer-completing-file-name
+       (not (functionp minibuffer-completion-table)))) ;; )
 
 ;;;_ > icomplete-minibuffer-setup ()
 
 ;;;_ > icomplete-minibuffer-setup ()
-;;;###autoload
 (defun icomplete-minibuffer-setup ()
   "Run in minibuffer on activation to establish incremental completion.
 Usually run by inclusion in `minibuffer-setup-hook'."
 (defun icomplete-minibuffer-setup ()
   "Run in minibuffer on activation to establish incremental completion.
 Usually run by inclusion in `minibuffer-setup-hook'."
-  (cond ((and icomplete-mode (icomplete-simple-completing-p))
-        (make-local-hook 'pre-command-hook)
-        (add-hook 'pre-command-hook
-                  (function (lambda ()
-                              (run-hooks 'icomplete-pre-command-hook)))
-                  nil t)
-        (make-local-hook 'post-command-hook)
-        (add-hook 'post-command-hook
-                  (function (lambda ()
-                              (run-hooks 'icomplete-post-command-hook)))
-                  nil t)
-        (run-hooks 'icomplete-minibuffer-setup-hook))))
-\f
+  (when (and icomplete-mode (icomplete-simple-completing-p))
+    (add-hook 'pre-command-hook
+             (lambda () (run-hooks 'icomplete-pre-command-hook))
+             nil t)
+    (add-hook 'post-command-hook
+             (lambda () (run-hooks 'icomplete-post-command-hook))
+             nil t)
+    (run-hooks 'icomplete-minibuffer-setup-hook)))
+;\f
+
+
 ;;;_* Completion
 
 ;;;_ > icomplete-tidy ()
 ;;;_* Completion
 
 ;;;_ > icomplete-tidy ()
@@ -222,60 +209,49 @@ Usually run by inclusion in `minibuffer-setup-hook'."
   "Remove completions display \(if any) prior to new user input.
 Should be run in on the minibuffer `pre-command-hook'.  See `icomplete-mode'
 and `minibuffer-setup-hook'."
   "Remove completions display \(if any) prior to new user input.
 Should be run in on the minibuffer `pre-command-hook'.  See `icomplete-mode'
 and `minibuffer-setup-hook'."
-  (if (icomplete-simple-completing-p)
-      (if (and (boundp 'icomplete-eoinput)
-              icomplete-eoinput)
+  (when icomplete-eoinput
 
 
-         (if (> icomplete-eoinput (point-max))
-             ;; Oops, got rug pulled out from under us - reinit:
-             (setq icomplete-eoinput (point-max))
-           (let ((buffer-undo-list buffer-undo-list )) ; prevent entry
-             (delete-region icomplete-eoinput (point-max))))
+    (unless (>= icomplete-eoinput (point-max))
+      (let ((buffer-undo-list t)) ; prevent entry
+       (delete-region icomplete-eoinput (point-max))))
 
 
-       ;; Reestablish the local variable 'cause minibuffer-setup is weird:
-       (make-local-variable 'icomplete-eoinput)
-       (setq icomplete-eoinput 1))))
+    ;; Reestablish the safe value.
+    (setq icomplete-eoinput nil)))
 
 ;;;_ > icomplete-exhibit ()
 (defun icomplete-exhibit ()
   "Insert icomplete completions display.
 Should be run via minibuffer `post-command-hook'.  See `icomplete-mode'
 and `minibuffer-setup-hook'."
 
 ;;;_ > icomplete-exhibit ()
 (defun icomplete-exhibit ()
   "Insert icomplete completions display.
 Should be run via minibuffer `post-command-hook'.  See `icomplete-mode'
 and `minibuffer-setup-hook'."
-  (if (icomplete-simple-completing-p)
-      (let ((contents (buffer-substring (point-min)(point-max)))
-           (buffer-undo-list t))
-       (save-excursion
-         (goto-char (point-max))
-                                        ; Register the end of input, so we
-                                        ; know where the extra stuff
-                                        ; (match-status info) begins:
-         (if (not (boundp 'icomplete-eoinput))
-             ;; In case it got wiped out by major mode business:
-             (make-local-variable 'icomplete-eoinput))
-         (setq icomplete-eoinput (point))
+  (when (icomplete-simple-completing-p)
+    (save-excursion
+      (goto-char (point-max))
+      ;; Register the end of input, so we know where the extra stuff
+      ;; (match-status info) begins:
+      (setq icomplete-eoinput (point))
                                         ; Insert the match-status information:
                                         ; Insert the match-status information:
-         (if (and (> (point-max) 1)
-                  (or
-                   ;; Don't bother with delay after certain number of chars:
-                   (> (point-max) icomplete-max-delay-chars)
-                   ;; Don't delay if alternatives number is small enough:
-                   (if minibuffer-completion-table
-                       (cond ((numberp minibuffer-completion-table)
-                              (< minibuffer-completion-table
-                                 icomplete-delay-completions-threshold))
-                             ((sequencep minibuffer-completion-table)
-                              (< (length minibuffer-completion-table)
-                                 icomplete-delay-completions-threshold))
-                             ))
-                   ;; Delay - give some grace time for next keystroke, before
-                   ;; embarking on computing completions:
-                   (sit-for icomplete-compute-delay)))
-             (insert-string
-              (icomplete-completions contents
-                                     minibuffer-completion-table
-                                     minibuffer-completion-predicate
-                                     (not
-                                      minibuffer-completion-confirm))))))))
+      (if (and (> (point-max) (minibuffer-prompt-end))
+              buffer-undo-list         ; Wait for some user input.
+              (or
+               ;; Don't bother with delay after certain number of chars:
+               (> (- (point) (field-beginning)) icomplete-max-delay-chars)
+               ;; Don't delay if alternatives number is small enough:
+               (and (sequencep minibuffer-completion-table)
+                    (< (length minibuffer-completion-table)
+                       icomplete-delay-completions-threshold))
+               ;; Delay - give some grace time for next keystroke, before
+               ;; embarking on computing completions:
+               (sit-for icomplete-compute-delay)))
+         (let ((text (while-no-input
+                       (list
+                        (icomplete-completions
+                         (field-string)
+                         minibuffer-completion-table
+                         minibuffer-completion-predicate
+                         (not minibuffer-completion-confirm)))))
+               (buffer-undo-list t))
+           ;; Do nothing if while-no-input was aborted.
+           (if (consp text) (insert (car text))))))))
 
 ;;;_ > icomplete-completions (name candidates predicate require-match)
 (defun icomplete-completions (name candidates predicate require-match)
 
 ;;;_ > icomplete-completions (name candidates predicate require-match)
 (defun icomplete-completions (name candidates predicate require-match)
@@ -305,83 +281,52 @@ are exhibited within the square braces.)"
   (let ((comps (all-completions name candidates predicate))
                                         ; "-determined" - only one candidate
         (open-bracket-determined (if require-match "(" "["))
   (let ((comps (all-completions name candidates predicate))
                                         ; "-determined" - only one candidate
         (open-bracket-determined (if require-match "(" "["))
-        (close-bracket-determined (if require-match ")" "]"))
-                                        ;"-prospects" - more than one candidate
-        (open-bracket-prospects "{")
-        (close-bracket-prospects "}")
-        )
-    (catch 'input
-      (cond ((null comps) (format " %sNo matches%s"
-                                 open-bracket-determined
-                                 close-bracket-determined))
-           ((null (cdr comps))         ;one match
-            (concat (if (and (> (length (car comps))
-                                (length name)))
-                        (concat open-bracket-determined
-                                (substring (car comps) (length name))
-                                close-bracket-determined)
-                      "")
-                    " [Matched"
-                    (let ((keys (and icomplete-show-key-bindings
-                                     (commandp (intern-soft (car comps)))
-                                     (icomplete-get-keys (car comps)))))
-                      (if keys
-                          (concat "; " keys)
-                        ""))
-                    "]"))
-           (t                          ;multiple matches
-            (let* ((most
-                    (try-completion name candidates
-                                    (and predicate
-                                         ;; Wrap predicate in impatience - ie,
-                                         ;; `throw' up when pending input is
-                                         ;; noticed.  Adds some overhead to
-                                         ;; predicate, but should be worth it.
-                                         (function
-                                          (lambda (item)
-                                            (if (input-pending-p)
-                                                (throw 'input "")
-                                              (apply predicate
-                                                     item nil)))))))
-                   (most-len (length most))
-                   most-is-exact
-                   (alternatives
-                    (substring
-                     (apply (function concat)
-                            (mapcar (function
-                                     (lambda (com)
-                                       (if (input-pending-p)
-                                           (throw 'input ""))
-                                       (if (= (length com) most-len)
-                                           ;; Most is one exact match,
-                                           ;; note that and leave out
-                                           ;; for later indication:
-                                           (progn
-                                             (setq most-is-exact t)
-                                             ())
-                                         (concat ","
-                                                 (substring com
-                                                            most-len)))))
-                                    comps))
-                     1)))
-              (concat (and (> most-len (length name))
-                           (concat open-bracket-determined
-                                   (substring most (length name))
-                                   close-bracket-determined))
-                      open-bracket-prospects
-                      (if most-is-exact
-                          ;; Add a ',' at the front to indicate "complete but
-                          ;; not unique":
-                          (concat "," alternatives)
-                        alternatives)
-                      close-bracket-prospects)))))))
-
-(if icomplete-mode
-    (icomplete-mode 1))
+        (close-bracket-determined (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)))
+            ;;"-prospects" - more than one candidate
+            (prospects-len 0)
+            prospects most-is-exact comp)
+       (if (eq most-try t)
+           (setq prospects nil)
+         (while (and comps (< prospects-len icomplete-prospects-length))
+           (setq comp (substring (car comps) most-len)
+                 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))))))
+       (if prospects
+           (concat determ
+                   "{"
+                   (and most-is-exact ",")
+                   (mapconcat 'identity
+                              (sort prospects (function string-lessp))
+                              ",")
+                   (and comps ",...")
+                   "}")
+         (concat determ
+                 " [Matched"
+                 (let ((keys (and icomplete-show-key-bindings
+                                  (commandp (intern-soft most))
+                                  (icomplete-get-keys most))))
+                   (if keys (concat "; " keys) ""))
+                 "]"))))))
 
 ;;;_* Local emacs vars.
 ;;;Local variables:
 ;;;outline-layout: (-2 :)
 ;;;End:
 
 
 ;;;_* Local emacs vars.
 ;;;Local variables:
 ;;;outline-layout: (-2 :)
 ;;;End:
 
+;; arch-tag: 339ec25a-0741-4eb6-be63-997532e89b0f
 ;;; icomplete.el ends here
 ;;; icomplete.el ends here