* dired-aux.el (dired-diff): Doc fixup (bug#8816).
[bpt/emacs.git] / lisp / icomplete.el
index 38fbf8f..5f36806 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, 2008 Free Software Foundation, Inc.
+;; Copyright (C) 1992-1994, 1997, 1999, 2001-2011
+;;   Free Software Foundation, Inc.
 
 ;; Author: Ken Manheimer <klm@i.am>
 ;; Maintainer: Ken Manheimer <klm@i.am>
   :prefix "icomplete-"
   :group 'minibuffer)
 
+(defvar icomplete-prospects-length 80)
+(make-obsolete-variable
+ 'icomplete-prospects-length 'icomplete-prospects-height "23.1")
+
 ;;;_* User Customization variables
-(defcustom icomplete-prospects-length 80
-  "Length of string displaying the prospects."
+(defcustom icomplete-prospects-height
+  ;; 20 is an estimated common size for the prompt + minibuffer content, to
+  ;; try to guess the number of lines used up by icomplete-prospects-length.
+  (+ 1 (/ (+ icomplete-prospects-length 20) (window-width)))
+  "Maximum number of lines to use in the minibuffer."
   :type 'integer
-  :group 'icomplete)
+  :group 'icomplete
+  :version "23.1")
 
 (defcustom icomplete-compute-delay .3
   "Completions-computation stall, used only with large-number completions.
@@ -117,9 +125,9 @@ icompletion is occurring."
 
 ;;;_ + Internal Variables
 ;;;_  = icomplete-eoinput nil
-(defvar icomplete-eoinput nil
-  "Point where minibuffer input ends and completion info begins.")
-(make-variable-buffer-local 'icomplete-eoinput)
+(defvar icomplete-overlay (make-overlay (point-min) (point-min) nil t t)
+  "Overlay used to display the list of completions.")
+
 ;;;_  = icomplete-pre-command-hook
 (defvar icomplete-pre-command-hook nil
   "Incremental-minibuffer-completion pre-command-hook.
@@ -138,22 +146,22 @@ minibuffer completion.")
 (add-hook 'icomplete-post-command-hook 'icomplete-exhibit)
 
 (defun icomplete-get-keys (func-name)
-  "Return strings naming keys bound to `func-name', or nil if none.
+  "Return strings naming keys bound to FUNC-NAME, or nil if none.
 Examines the prior, not current, buffer, presuming that current buffer
 is minibuffer."
-  (if (commandp func-name)
+  (when (commandp func-name)
     (save-excursion
       (let* ((sym (intern func-name))
             (buf (other-buffer nil t))
             (keys (with-current-buffer buf (where-is-internal sym))))
-       (if keys
-           (concat "<"
-                   (mapconcat 'key-description
-                              (sort keys
-                                    #'(lambda (x y)
-                                        (< (length x) (length y))))
-                              ", ")
-                   ">"))))))
+       (when keys
+         (concat "<"
+                 (mapconcat 'key-description
+                            (sort keys
+                                  #'(lambda (x y)
+                                      (< (length x) (length y))))
+                            ", ")
+                 ">"))))))
 ;;;_  = icomplete-with-completion-tables
 (defvar icomplete-with-completion-tables '(internal-complete-buffer)
   "Specialized completion tables with which icomplete should operate.
@@ -171,8 +179,11 @@ otherwise turn it off."
   (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)))
+      (progn
+       (setq completion-show-inline-help nil)
+       (add-hook 'minibuffer-setup-hook 'icomplete-minibuffer-setup))
+    (remove-hook 'minibuffer-setup-hook 'icomplete-minibuffer-setup)
+    (setq completion-show-inline-help t)))
 
 ;;;_ > icomplete-simple-completing-p ()
 (defun icomplete-simple-completing-p ()
@@ -215,15 +226,7 @@ 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'."
-  (when (and icomplete-mode icomplete-eoinput)
-
-    (unless (>= icomplete-eoinput (point-max))
-      (let ((buffer-undo-list t) ; prevent entry
-           deactivate-mark)
-       (delete-region icomplete-eoinput (point-max))))
-
-    ;; Reestablish the safe value.
-    (setq icomplete-eoinput nil)))
+  (delete-overlay icomplete-overlay))
 
 ;;;_ > icomplete-exhibit ()
 (defun icomplete-exhibit ()
@@ -233,9 +236,6 @@ and `minibuffer-setup-hook'."
   (when (and icomplete-mode (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:
       (if (and (> (point-max) (minibuffer-prompt-end))
               buffer-undo-list         ; Wait for some user input.
@@ -250,16 +250,21 @@ and `minibuffer-setup-hook'."
                ;; 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)))))
+                         (not minibuffer-completion-confirm))))
                (buffer-undo-list t)
                deactivate-mark)
            ;; Do nothing if while-no-input was aborted.
-           (if (consp text) (insert (car text))))))))
+           (when (stringp text)
+              (move-overlay icomplete-overlay (point) (point) (current-buffer))
+              ;; The current C cursor code doesn't know to use the overlay's
+              ;; marker's stickiness to figure out whether to place the cursor
+              ;; before or after the string, so let's spoon-feed it the pos.
+              (put-text-property 0 1 'cursor t text)
+              (overlay-put icomplete-overlay 'after-string text)))))))
 
 ;;;_ > icomplete-completions (name candidates predicate require-match)
 (defun icomplete-completions (name candidates predicate require-match)
@@ -281,24 +286,27 @@ The displays for unambiguous matches have ` [Matched]' appended
 matches exist.  \(Keybindings for uniquely matched commands
 are exhibited within the square braces.)"
 
-  (let* ((comps (completion-all-completions name candidates predicate
-                                            (length name)))
-         (last (last comps))
-         (base-size (if (consp last) (prog1 (cdr last) (setcdr last nil))))
+  (let* ((non-essential t)
+         (md (completion--field-metadata (field-beginning)))
+        (comps (completion-all-sorted-completions))
+         (last (if (consp comps) (last comps)))
+         (base-size (cdr last))
          (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)
+    ;; `concat'/`mapconcat' is the slow part.
+    (if (not (consp 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)))
+      (if last (setcdr last nil))
+      (let* ((most-try
+              (if (and base-size (> base-size 0))
+                  (completion-try-completion
+                   name candidates predicate (length name) md)
+                ;; If the `comps' are 0-based, the result should be
+                ;; the same with `comps'.
+                (completion-try-completion
+                 name comps nil (length name) md)))
+            (most (if (consp most-try) (car most-try)
+                     (if 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
@@ -315,11 +323,19 @@ are exhibited within the square braces.)"
                                (t (concat "..." (substring most compare))))
                               close-bracket)))
             ;;"-prospects" - more than one candidate
-            (prospects-len (+ (length determ) 6)) ;; take {,...} into account
+            (prospects-len (+ (length determ) 6 ;; take {,...} into account
+                               (string-width (buffer-string))))
+             (prospects-max
+              ;; Max total length to use, including the minibuffer content.
+              (* (+ icomplete-prospects-height
+                    ;; If the minibuffer content already uses up more than
+                    ;; one line, increase the allowable space accordingly.
+                    (/ prospects-len (window-width)))
+                 (window-width)))
              (prefix-len
               ;; Find the common prefix among `comps'.
              (if (eq t (compare-strings (car comps) nil (length most)
-                                        most nil nil case-fold-search))
+                                        most nil nil completion-ignore-case))
                   ;; Common case.
                  (length most)
                 ;; Else, use try-completion.
@@ -328,7 +344,7 @@ are exhibited within the square braces.)"
                        (length comps-prefix)))))
 
             prospects most-is-exact comp limit)
-       (if (or (eq most-try t) (null (cdr comps)))
+       (if (eq most-try t) ;; (or (null (cdr comps))
            (setq prospects nil)
          (while (and comps (not limit))
            (setq comp
@@ -336,18 +352,20 @@ are exhibited within the square braces.)"
                  comps (cdr comps))
            (cond ((string-equal comp "") (setq most-is-exact t))
                  ((member comp prospects))
-                 (t (setq prospects-len (+ (length comp) 1 prospects-len))
-                    (if (< prospects-len icomplete-prospects-length)
-                        (setq prospects (cons comp prospects))
+                 (t (setq prospects-len
+                           (+ (string-width comp) 1 prospects-len))
+                    (if (< prospects-len prospects-max)
+                        (push comp prospects)
                       (setq limit t))))))
+        ;; Restore the base-size info, since completion-all-sorted-completions
+        ;; is cached.
+        (if last (setcdr last base-size))
        (if prospects
            (concat determ
                    "{"
                    (and most-is-exact ",")
-                   (mapconcat 'identity
-                              (sort prospects (function string-lessp))
-                              ",")
-                   (and comps ",...")
+                   (mapconcat 'identity (nreverse prospects) ",")
+                   (and limit ",...")
                    "}")
          (concat determ
                  " [Matched"
@@ -362,5 +380,4 @@ are exhibited within the square braces.)"
 ;;allout-layout: (-2 :)
 ;;End:
 
-;; arch-tag: 339ec25a-0741-4eb6-be63-997532e89b0f
 ;;; icomplete.el ends here