icomplete.el 10.4 KB
Newer Older
Richard M. Stallman's avatar
Richard M. Stallman committed
1
;;; icomplete.el - minibuffer completion incremental feedback
2
;;; This package is in the public domain.
Richard M. Stallman's avatar
Richard M. Stallman committed
3 4 5

;;; Author: Ken Manheimer <klm@nist.gov>
;;; Maintainer: Ken Manheimer <klm@nist.gov>
6
;;; Version: icomplete.el,v 3.3 1993/12/11 11:27:35 klm Exp klm
Richard M. Stallman's avatar
Richard M. Stallman committed
7 8 9 10 11 12 13 14 15 16 17
;;; Created: Mar 1993 klm@nist.gov - first release to usenet
;;; Keywords: help, abbrev

;;; Commentary:

;;; Loading this package implements a more finely-grained completion
;;; feedback scheme, indicating, within the minibuffer, the
;;; prospective minibuffer completion candidates, as you type.  See
;;; the documentation string for 'icomplete-prompt' for a specific
;;; description of icompletion.

18 19 20 21 22 23 24 25 26 27 28
;;; It should run on most version of Emacs 19 (including Lucid emacs
;;; 19 - thanks to the efforts of Colin Rafferty (craffert@lehman.com)
;;; - thanks, Colin!)  This version of icomplete will *not* work on
;;; Emacs 18 versions - the elisp archives, at
;;; archive.cis.ohio-state.edu:/pub/gnu/emacs/elisp-archive, probably
;;; still has a version that works in GNU Emacs v18.

;;; Thanks to Colin Rafferty for assistance reconciling for lemacs,
;;; and to Michael Cook, who implemented an incremental completion
;;; style in his 'iswitch' functions that served as the basis for
;;; icomplete.
Richard M. Stallman's avatar
Richard M. Stallman committed
29 30 31

;;; Code:

32 33
;;;_* (Allout outline root topic.  Please leave this in.)

Richard M. Stallman's avatar
Richard M. Stallman committed
34 35 36 37 38 39 40 41
;;;_ + Provide
(provide 'icomplete)

;;;_ + User Customization variables
;;;_  = icomplete-inhibit
(defvar icomplete-inhibit nil
  "*Set this variable to t at any time to inhibit icomplete.")

42 43
;;;_ + Internal Variables
;;;_  = icomplete-eoinput 1
Richard M. Stallman's avatar
Richard M. Stallman committed
44 45 46
(defvar icomplete-eoinput 1
  "Point where minibuffer input ends and completion info begins.")
(make-variable-buffer-local 'icomplete-eoinput)
47 48 49

;;;_ > icomplete-prime-session ()
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
50 51
(defun icomplete-prime-session ()

52 53 54 55
  "Prep emacs v 19 for more finely-grained minibuffer completion-feedback.

You can inhibit icomplete after loading by setting icomplete-inhibit
non-nil.  Set the var back to nil to re-enable icomplete."
Richard M. Stallman's avatar
Richard M. Stallman committed
56

57 58 59 60 61
  ;; For emacs v19.18 and later revs, the icomplete key function is
  ;; installed in 'minibuffer-setup-hook'.  Global pre- and post-
  ;; command-hook functions are used in v19.17 and earlier v19 revs."

  (let* ((v19-rev (and (string-match "^19\\.\\([0-9]+\\)" emacs-version)
Richard M. Stallman's avatar
Richard M. Stallman committed
62 63 64 65
		       (string-to-int (substring emacs-version
						 (match-beginning 1)
						 (match-end 1))))))

66 67 68 69 70 71 72 73 74 75 76 77 78
    (cond ((and v19-rev			; emacs v 19, some rev,
		(> v19-rev 17))
	   ;; Post v19rev17, has minibuffer-setup-hook, use it:
	   (add-hook 'minibuffer-setup-hook 'icomplete-prime-minibuffer))
	  (v19-rev
	   ;; v19rev17 and prior (including lucid): use global
	   ;; pre- and post-command-hooks, instead:
	   (add-hook 'pre-command-hook 'icomplete-pre-command-hook 'append)
	   (add-hook 'post-command-hook
		     'icomplete-post-command-hook 'append))
	  ((format "icomplete: non v19 emacs, %s - %s"
		   emacs-version "try elisp-archive icomplete")))))
;;;_ > icomplete-prime-minibuffer ()
Richard M. Stallman's avatar
Richard M. Stallman committed
79 80
(defun icomplete-prime-minibuffer ()

81 82 83 84 85 86 87
  "Prep emacs, v 19.18 or later, for icomplete.

\(In emacs v19.17 and earlier, and in lemacs, icomplete-prime-session
is used, instead to establish global hooks.\)

Run via minibuffer-setup-hook, adds icomplete pre- and post-command
hooks at the start of each minibuffer."
Richard M. Stallman's avatar
Richard M. Stallman committed
88

89 90
  ;; Append the hooks to avoid as much as posssible interference from
  ;; other hooks that foul up minibuffer quit.
Richard M. Stallman's avatar
Richard M. Stallman committed
91 92 93 94
  (make-local-variable 'pre-command-hook)
  (make-local-variable 'post-command-hook)
  (add-hook 'pre-command-hook 'icomplete-pre-command-hook)
  (add-hook 'post-command-hook 'icomplete-post-command-hook))
95
;;;_ > icomplete-window-minibuffer-p ()
Richard M. Stallman's avatar
Richard M. Stallman committed
96 97 98 99
(defmacro icomplete-window-minibuffer-p ()

  "Returns non-nil if current window is a minibuffer window.

100 101 102 103
Trivially equates to '(window-minibuffer-p (selected-window))', with
the argument definitely provided for emacsen that require it, eg Lucid."

  '(window-minibuffer-p (selected-window)))
Richard M. Stallman's avatar
Richard M. Stallman committed
104 105

;;;_ + Completion
106

Richard M. Stallman's avatar
Richard M. Stallman committed
107 108 109
;;;_  - Completion feedback hooks
;;;_   > icomplete-pre-command-hook ()
(defun icomplete-pre-command-hook ()
110
  "Cleanup completions display before user's new command is dealt with."
Richard M. Stallman's avatar
Richard M. Stallman committed
111
  (if (and (icomplete-window-minibuffer-p)
112
	   (not executing-macro)
Richard M. Stallman's avatar
Richard M. Stallman committed
113 114 115 116 117 118 119
	   (not (symbolp minibuffer-completion-table))
	   (not icomplete-inhibit))
      (if (and (boundp 'icomplete-eoinput)
	       icomplete-eoinput)
	  (if (> icomplete-eoinput (point-max))
	      ;; Oops, got rug pulled out from under us - reinit:
	      (setq icomplete-eoinput (point-max))
120
	    (let ((buffer-undo-list buffer-undo-list )) ; prevent entry
Richard M. Stallman's avatar
Richard M. Stallman committed
121
	      (delete-region icomplete-eoinput (point-max))))
122
	;; Reestablish the local variable 'cause minibuffer-setup is weird:
Richard M. Stallman's avatar
Richard M. Stallman committed
123 124 125 126
	(make-local-variable 'icomplete-eoinput)
	(setq icomplete-eoinput 1))))
;;;_   > icomplete-post-command-hook ()
(defun icomplete-post-command-hook ()
127 128
  "Exhibit completions, leaving bookkeeping so pre- hook can tidy up."

Richard M. Stallman's avatar
Richard M. Stallman committed
129
  (if (and (icomplete-window-minibuffer-p)	; ... in a minibuffer.
130
	   (not executing-macro)
Richard M. Stallman's avatar
Richard M. Stallman committed
131 132 133 134 135 136 137 138 139 140 141
	   (not icomplete-inhibit)	; ... not specifically inhibited.
	   ;(sit-for 0)			; ... redisplay and if there's input
					; waiting, then don't icomplete
					; (stigs suggestion) (too jumpy!)
	   ;; Inhibit for file-name and other custom-func completions:
	   (not (symbolp minibuffer-completion-table))
	   )
      (let ((buffer-undo-list buffer-undo-list ))	; prevent entry
	(icomplete-exhibit))))
;;;_   > icomplete-window-setup-hook ()
(defun icomplete-window-setup-hook ()
142 143
  "Exhibit completions, leaving bookkeeping so pre- hook can tidy up."

Richard M. Stallman's avatar
Richard M. Stallman committed
144 145 146 147 148
  (if (and (icomplete-window-minibuffer-p)	; ... in a minibuffer.
	   )
      (message "ic ws doing")(sit-for 1)))
;;;_   > icomplete-exhibit ()
(defun icomplete-exhibit ()
149
  "Insert icomplete completions display."
Richard M. Stallman's avatar
Richard M. Stallman committed
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
  (if (not (symbolp minibuffer-completion-table))
      (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))
                                        ; Insert the match-status information:
	  (if (> (point-max) 1)
	      (insert-string
		(icomplete-prompt contents
				  minibuffer-completion-table
				  minibuffer-completion-predicate
				  (not
				   minibuffer-completion-confirm))))))))

;;;_  - Completion feedback producer
;;;_   > icomplete-prompt (name candidates predicate require-match)
(defun icomplete-prompt (name candidates predicate require-match)
  "Identify prospective candidates for minibuffer completion.

176
The display is updated with each minibuffer keystroke during
Richard M. Stallman's avatar
Richard M. Stallman committed
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
minibuffer completion.

Prospective completion suffixes (if any) are displayed, bracketed by
one of \(), \[], or \{} pairs.  The choice of brackets is as follows:

  \(...) - a single prospect is identified and matching is enforced,
  \[...] - a single prospect is identified but matching is optional, or
  \{...} - multiple prospects, separated by commas, are indicated, and
          further input is required to distingish a single one.

The displays for disambiguous matches have \" [Matched]\" appended
\(whether complete or not), or \" \[No matches]\", if no eligible
matches exist."

  (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 "}")
        )
    (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]"))
          (t                            ;multiple matches
           (let* ((most (try-completion name candidates predicate))
                  (most-len (length most))
                  most-is-exact
                  (alternatives
                   (apply
                    'concat
                    (cdr (apply 'append
                                (mapcar '(lambda (com)
                                           (if (= (length com) most-len)
                                               ;; Most is one exact match,
                                               ;; note that and leave out
                                               ;; for later indication:
                                               (progn
                                                 (setq most-is-exact t)
                                                 ())
                                             (list ","
                                                   (substring com
                                                              most-len))))
                                        comps))))))
             (concat (and (> most-len (length name))
                          (concat open-bracket-determined
                                  (substring most (length name))
                                  close-bracket-determined))
                     open-bracket-prospects
                     (if most-is-exact
                         (concat "," alternatives)
                       alternatives)
                     close-bracket-prospects))))))

240
;;;_  - Initialization
Richard M. Stallman's avatar
Richard M. Stallman committed
241 242
(icomplete-prime-session)

243 244

;;;_ + Local emacs vars.
Richard M. Stallman's avatar
Richard M. Stallman committed
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
'(
Local variables:
eval: (save-excursion
        (if (not (condition-case err (outline-mode t)
                   (wrong-number-of-arguments nil)))
            (progn
              (message
               "Allout outline-mode not loaded, not adjusting buffer exposure")
              (sit-for 1))
          (message "Adjusting '%s' visibility" (buffer-name))
          (outline-lead-with-comment-string ";;;_")
          (goto-char 0)
          (outline-exposure -1 0)))
End:)

;;; icomplete.el ends here
261