;;; 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
;; 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:
(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
;;;###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 -
(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))))
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
"{"
(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