Commit | Line | Data |
---|---|---|
d462ff97 RS |
1 | ;;; icomplete.el - minibuffer completion incremental feedback |
2 | ;;; This package is in the publid domain. | |
3 | ||
4 | ;;; Author: Ken Manheimer <klm@nist.gov> | |
5 | ;;; Maintainer: Ken Manheimer <klm@nist.gov> | |
6 | ;;; Version: icomplete.el,v 3.2 1993/11/19 18:42:52 klm Exp klm | |
7 | ;;; Created: Mar 1993 klm@nist.gov - first release to usenet | |
8 | ;;; Keywords: help, abbrev | |
9 | ||
10 | ;;; Commentary: | |
11 | ||
12 | ;;; Loading this package implements a more finely-grained completion | |
13 | ;;; feedback scheme, indicating, within the minibuffer, the | |
14 | ;;; prospective minibuffer completion candidates, as you type. See | |
15 | ;;; the documentation string for 'icomplete-prompt' for a specific | |
16 | ;;; description of icompletion. | |
17 | ||
18 | ;;; This will not work on Emacs 18 versions - there may be a version | |
19 | ;;; for v18 in the elisp archives, at archive.cis.ohio-state.edu, in | |
20 | ;;; /pub/gnu/emacs/elisp-archive. | |
21 | ||
22 | ;;; Code: | |
23 | ||
24 | ;;;_ + Provide | |
25 | (provide 'icomplete) | |
26 | ||
27 | ;;;_ + User Customization variables | |
28 | ;;;_ = icomplete-inhibit | |
29 | (defvar icomplete-inhibit nil | |
30 | "*Set this variable to t at any time to inhibit icomplete.") | |
31 | ||
32 | ;;;_ + Setup | |
33 | ;;;_ - Internal Variables | |
34 | ;;;_ = icomplete-eoinput 1 | |
35 | (defvar icomplete-eoinput 1 | |
36 | "Point where minibuffer input ends and completion info begins.") | |
37 | (make-variable-buffer-local 'icomplete-eoinput) | |
38 | ;;;_ > icomplete-prime-session () | |
39 | (defun icomplete-prime-session () | |
40 | ||
41 | "Prep emacs v 19 for icompletion. For emacs v19.18 and later revs, | |
42 | icomplete is installed in 'minibuffer-setup-hook'. Global pre- and | |
43 | post-command-hook functions are used in v19.17 and earlier revs." | |
44 | ||
45 | (let* ((v19-rev (and (string-match "^19\\.\\([0-9]+\\)" emacs-version) | |
46 | (string-to-int (substring emacs-version | |
47 | (match-beginning 1) | |
48 | (match-end 1)))))) | |
49 | ||
50 | (cond ((and v19-rev ; emacs v 19, some rev, | |
51 | (> v19-rev 17)) | |
52 | ;; Post v19rev17, has minibuffer-setup-hook, use it: | |
53 | (add-hook 'minibuffer-setup-hook 'icomplete-prime-minibuffer)) | |
54 | (v19-rev | |
55 | ;; v19rev17 and prior (including lucid): use global | |
56 | ;; pre- and post-command-hooks, instead: | |
57 | (add-hook 'pre-command-hook 'icomplete-pre-command-hook 'append) | |
58 | (add-hook 'post-command-hook | |
59 | 'icomplete-post-command-hook 'append)) | |
60 | ((format "icomplete: non v19 emacs, %s - %s" | |
61 | emacs-version "try elisp-archive icomplete"))))) | |
62 | ;;;_ > icomplete-prime-minibuffer () | |
63 | (defun icomplete-prime-minibuffer () | |
64 | ||
65 | "Prep emacs, v 19.18 or later, for icomplete. \(icomplete-prime- | |
66 | session establishes global hooks, instead, in emacs 19 versions 19.17 | |
67 | and prior.\) Run via minibuffer-setup-hook \(emacs 19.18 or later\), | |
68 | adds icomplete pre- and post-command hooks to do icomplete display | |
69 | management." | |
70 | ||
71 | ;; We append the hooks because preliminary version of blink-paren | |
72 | ;; post-command-hook i have interferes with proper operation of | |
73 | ;; minibuffer quit. | |
74 | (make-local-variable 'pre-command-hook) | |
75 | (make-local-variable 'post-command-hook) | |
76 | (add-hook 'pre-command-hook 'icomplete-pre-command-hook) | |
77 | (add-hook 'post-command-hook 'icomplete-post-command-hook)) | |
78 | ;;;_ > icomplete-window-minibuffer-p () | |
79 | (defmacro icomplete-window-minibuffer-p () | |
80 | ||
81 | "Returns non-nil if current window is a minibuffer window. | |
82 | Trivially equates to '(window-minibuffer-p nil)', with the nil | |
83 | provided in case the argument is not optional in Lucid emacs (which | |
84 | some net correspondance seems to indicate)." | |
85 | ||
86 | '(window-minibuffer-p nil)) | |
87 | ||
88 | ;;;_ + Completion | |
89 | ;;;_ - Completion feedback hooks | |
90 | ;;;_ > icomplete-pre-command-hook () | |
91 | (defun icomplete-pre-command-hook () | |
92 | "Cleanup completions exhibit before user's new input (or whatever) is dealt | |
93 | with." | |
94 | (if (and (icomplete-window-minibuffer-p) | |
95 | (not (symbolp minibuffer-completion-table)) | |
96 | (not icomplete-inhibit)) | |
97 | (if (and (boundp 'icomplete-eoinput) | |
98 | icomplete-eoinput) | |
99 | (if (> icomplete-eoinput (point-max)) | |
100 | ;; Oops, got rug pulled out from under us - reinit: | |
101 | (setq icomplete-eoinput (point-max)) | |
102 | (let ((buffer-undo-list buffer-undo-list )) ; prevent entry | |
103 | (delete-region icomplete-eoinput (point-max)))) | |
104 | (make-local-variable 'icomplete-eoinput) | |
105 | (setq icomplete-eoinput 1)))) | |
106 | ;;;_ > icomplete-post-command-hook () | |
107 | (defun icomplete-post-command-hook () | |
108 | "Exhibit completions, leaving icomplete-eoinput with position where user | |
109 | input leaves off and exhibit begins, so icomplete-pre-command-hook can | |
110 | subsequently cleanup." | |
111 | (if (and (icomplete-window-minibuffer-p) ; ... in a minibuffer. | |
112 | (not icomplete-inhibit) ; ... not specifically inhibited. | |
113 | ;(sit-for 0) ; ... redisplay and if there's input | |
114 | ; waiting, then don't icomplete | |
115 | ; (stigs suggestion) (too jumpy!) | |
116 | ;; Inhibit for file-name and other custom-func completions: | |
117 | (not (symbolp minibuffer-completion-table)) | |
118 | ) | |
119 | (let ((buffer-undo-list buffer-undo-list )) ; prevent entry | |
120 | (icomplete-exhibit)))) | |
121 | ;;;_ > icomplete-window-setup-hook () | |
122 | (defun icomplete-window-setup-hook () | |
123 | "Exhibit completions, leaving icomplete-eoinput with position where user | |
124 | input leaves off and exhibit begins, so icomplete-pre-command-hook can | |
125 | subsequently cleanup." | |
126 | (if (and (icomplete-window-minibuffer-p) ; ... in a minibuffer. | |
127 | ) | |
128 | (message "ic ws doing")(sit-for 1))) | |
129 | ;;;_ > icomplete-exhibit () | |
130 | (defun icomplete-exhibit () | |
131 | "Exhibit completions, leaving icomplete-eoinput with position where user | |
132 | input leaves off and exhibit begins, so icomplete-pre-command-hook can | |
133 | subsequently cleanup." | |
134 | (if (not (symbolp minibuffer-completion-table)) | |
135 | (let ((contents (buffer-substring (point-min)(point-max))) | |
136 | (buffer-undo-list t)) | |
137 | (save-excursion | |
138 | (goto-char (point-max)) | |
139 | ; Register the end of input, so we | |
140 | ; know where the extra stuff | |
141 | ; (match-status info) begins: | |
142 | (if (not (boundp 'icomplete-eoinput)) | |
143 | ;; In case it got wiped out by major mode business: | |
144 | (make-local-variable 'icomplete-eoinput)) | |
145 | (setq icomplete-eoinput (point)) | |
146 | ; Insert the match-status information: | |
147 | (if (> (point-max) 1) | |
148 | (insert-string | |
149 | (icomplete-prompt contents | |
150 | minibuffer-completion-table | |
151 | minibuffer-completion-predicate | |
152 | (not | |
153 | minibuffer-completion-confirm)))))))) | |
154 | ||
155 | ;;;_ - Completion feedback producer | |
156 | ;;;_ > icomplete-prompt (name candidates predicate require-match) | |
157 | (defun icomplete-prompt (name candidates predicate require-match) | |
158 | "Identify prospective candidates for minibuffer completion. | |
159 | ||
160 | The display is updated with each minibuffer keystroke when icomplete | |
161 | is enabled \(by loading the 'icomplete' elisp package\) and doing | |
162 | minibuffer completion. | |
163 | ||
164 | Prospective completion suffixes (if any) are displayed, bracketed by | |
165 | one of \(), \[], or \{} pairs. The choice of brackets is as follows: | |
166 | ||
167 | \(...) - a single prospect is identified and matching is enforced, | |
168 | \[...] - a single prospect is identified but matching is optional, or | |
169 | \{...} - multiple prospects, separated by commas, are indicated, and | |
170 | further input is required to distingish a single one. | |
171 | ||
172 | The displays for disambiguous matches have \" [Matched]\" appended | |
173 | \(whether complete or not), or \" \[No matches]\", if no eligible | |
174 | matches exist." | |
175 | ||
176 | (let ((comps (all-completions name candidates predicate)) | |
177 | ; "-determined" - only one candidate | |
178 | (open-bracket-determined (if require-match "(" "[")) | |
179 | (close-bracket-determined (if require-match ")" "]")) | |
180 | ;"-prospects" - more than one candidate | |
181 | (open-bracket-prospects "{") | |
182 | (close-bracket-prospects "}") | |
183 | ) | |
184 | (cond ((null comps) (format " %sNo matches%s" | |
185 | open-bracket-determined | |
186 | close-bracket-determined)) | |
187 | ((null (cdr comps)) ;one match | |
188 | (concat (if (and (> (length (car comps)) | |
189 | (length name))) | |
190 | (concat open-bracket-determined | |
191 | (substring (car comps) (length name)) | |
192 | close-bracket-determined) | |
193 | "") | |
194 | " [Matched]")) | |
195 | (t ;multiple matches | |
196 | (let* ((most (try-completion name candidates predicate)) | |
197 | (most-len (length most)) | |
198 | most-is-exact | |
199 | (alternatives | |
200 | (apply | |
201 | 'concat | |
202 | (cdr (apply 'append | |
203 | (mapcar '(lambda (com) | |
204 | (if (= (length com) most-len) | |
205 | ;; Most is one exact match, | |
206 | ;; note that and leave out | |
207 | ;; for later indication: | |
208 | (progn | |
209 | (setq most-is-exact t) | |
210 | ()) | |
211 | (list "," | |
212 | (substring com | |
213 | most-len)))) | |
214 | comps)))))) | |
215 | (concat (and (> most-len (length name)) | |
216 | (concat open-bracket-determined | |
217 | (substring most (length name)) | |
218 | close-bracket-determined)) | |
219 | open-bracket-prospects | |
220 | (if most-is-exact | |
221 | (concat "," alternatives) | |
222 | alternatives) | |
223 | close-bracket-prospects)))))) | |
224 | ||
225 | ;;;_ + Initialization | |
226 | (icomplete-prime-session) | |
227 | ||
228 | ;;;_* Local emacs vars. | |
229 | '( | |
230 | Local variables: | |
231 | eval: (save-excursion | |
232 | (if (not (condition-case err (outline-mode t) | |
233 | (wrong-number-of-arguments nil))) | |
234 | (progn | |
235 | (message | |
236 | "Allout outline-mode not loaded, not adjusting buffer exposure") | |
237 | (sit-for 1)) | |
238 | (message "Adjusting '%s' visibility" (buffer-name)) | |
239 | (outline-lead-with-comment-string ";;;_") | |
240 | (goto-char 0) | |
241 | (outline-exposure -1 0))) | |
242 | End:) | |
243 | ||
244 | ;;; icomplete.el ends here |