;;; 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.
;;;_ + 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.
(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.
(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 ()
"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 ()
(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.
;; 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)
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)
+ (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)
+ (if last (setcdr last nil))
(let* ((most-try
(if (and base-size (> base-size 0))
(completion-try-completion
;; the same with `comps'.
(completion-try-completion
name comps nil (length name))))
- (most (if (consp most-try) (car most-try) (car comps)))
+ (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
(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.
(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
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"
;;allout-layout: (-2 :)
;;End:
-;; arch-tag: 339ec25a-0741-4eb6-be63-997532e89b0f
;;; icomplete.el ends here