1 ;;; -*- Mode: Emacs-Lisp -*-
4 ;;; Rcs_Info: completer.el,v 3.23 1993/09/03 02:05:07 ivan Rel $
6 ;;; Partial completion mechanism for GNU Emacs and XEmacs. Version 3.05
7 ;;; Copyright (C) 1990, 1991, 1992 Chris McConnell, ccm@cs.cmu.edu.
8 ;;; Copyright (C) 2000 Ben Wing.
9 ;;; Copyright (C) 2002 Marco Antoniotti and the ILISP Maintainers
11 ;;; Author: Chris Mcconnell <chrimc@microsoft.com>
12 ;;; Latest XEmacs Author: Ben Wing
13 ;;; Maintainer: The ILISP Maintainers
14 ;;; Keywords: minibuffer, completion
16 ;;; Thanks to Bjorn Victor for suggestions, testing, and patches for
19 ;;; This file should be part of GNU Emacs and XEmacs.
21 ;;; GNU Emacs and XEmacs are distributed in the hope that they will be useful,
22 ;;; but WITHOUT ANY WARRANTY. No author or distributor
23 ;;; accepts responsibility to anyone for the consequences of using it
24 ;;; or for whether it serves any particular purpose or works at all,
25 ;;; unless he says so in writing. Refer to the GNU Emacs General Public
26 ;;; License for full details.
27 ;;; Everyone is granted permission to copy, modify and redistribute
28 ;;; GNU Emacs and XEmacs, but only under the conditions described in the
29 ;;; GNU Emacs and XEmacs General Public License. A copy of this license is
30 ;;; supposed to have been given to you along with GNU Emacs or XEmacs so you
31 ;;; can know your rights and responsibilities. It should be in a
32 ;;; file named COPYING. Among other things, the copyright notice
33 ;;; and this notice must be preserved on all copies.
35 ;;; When loaded, this file extends the standard completion mechanisms
36 ;;; so that they perform pattern matching completions. There is also
37 ;;; an interface that allows it to be used by other programs. The
38 ;;; completion rules are:
40 ;;; 1) If what has been typed matches any possibility, do normal
43 ;;; 2) Otherwise, generate a regular expression such that
44 ;;; completer-words delimit words and generate all possible matches.
45 ;;; The variable completer-any-delimiter can be set to a character
46 ;;; that matches any delimiter. If it were " ", then "by d" would be
47 ;;; byte-recompile-directory. If completer-use-words is T, a match is
48 ;;; unique if it is the only one with the same number of words. If
49 ;;; completer-use-words is NIL, a match is unique if it is the only
50 ;;; possibility. If you ask the completer to use its best guess, it
51 ;;; will be the shortest match of the possibilities unless
52 ;;; completer-exact is T.
54 ;;; 3) For filenames, if completer-complete-filenames is T, each
55 ;;; pathname component will be individually completed, otherwise only
56 ;;; the final component will be completed. If you are using a
57 ;;; distributed file system like afs, you may want to set up a
58 ;;; symbolic link in your home directory or add pathname components to
59 ;;; completer-file-skip so that the pathname components that go across
60 ;;; machines do not get expanded.
62 ;;; SPACE, TAB, LFD, RET, and ? do normal completion if possible
63 ;;; otherwise they do partial completion. In addition, C-DEL will
64 ;;; undo the last partial expansion or contraction. M-RET will always
65 ;;; complete to the current match before returning. This is useful
66 ;;; when any string is possible, but you want to complete to a string
67 ;;; as when calling find-file. The bindings can be changed by using
68 ;;; completer-load-hook.
70 ;;; Modes that use comint-dynamic-complete (like cmushell and ilisp)
71 ;;; will also do partial completion as will M-tab in Emacs LISP.
74 ;;; a-f auto-fill-mode
75 ;;; b--d *beginning-of-defun or byte-recompile-directory
76 ;;; by d *byte-recompile-directory if completer-any-delimiter is " "
77 ;;; ~/i.e *~/ilisp.el or ~/il-el.el or ~/ilisp.elc
85 (or (fboundp 'file-system-ignore-case-p)
86 (defalias 'file-system-ignore-case-p
87 (if (memq 'system-type '(windows-nt cygwin32 darwin cygwin))
89 #'(lambda (path) nil)))))
93 (defvar completer-load-hook nil
94 "Hook called when minibuffer partial completion is loaded.")
96 (defvar completer-disable nil
97 "*If T, turn off partial completion. Use the command
98 \\[completer-toggle] to set this.")
100 (defvar completer-complete-filenames t
101 "*If T, then each component of a filename will be completed,
102 otherwise just the final component will be completed.")
104 (defvar completer-use-words nil ; jwz: this is HATEFUL!
105 "*If T, then prefer completions with the same number of words as the
108 (defvar completer-words "---. <"
109 "*Delimiters used in partial completions. It should be a set of
110 characters suitable for inclusion in a [] regular expression.")
112 (defvar completer-any-delimiter nil
113 "*If a character, then a delimiter in the pattern that matches the
114 character will match any delimiter in completer-words.")
116 (defvar completer-file-skip "^cs/$\\|@sys\\|.edu/$\\|.gov/$\\|.com/$\\|:/$"
117 "*Regular expression for pathname components to not complete.")
119 (defvar completer-exact nil
120 "*If T, then you must have an exact match. Otherwise, the shortest
121 string that matches the pattern will be used.")
123 (defvar completer-cache-size 100
124 "*Size of cache to use for partially completed pathnames.")
126 (defvar completer-use-cache t
127 "*Set to nil to disable the partially completed pathname cache.")
130 (defvar completer-last-pattern ""
131 "The last pattern expanded.")
133 (defvar completer-message nil
134 "T if temporary message was just displayed.")
136 (defvar completer-path-cache nil
137 "Cache of (path . choices) for completer.")
139 (defvar completer-path-separator-string
140 (if (eq system-type 'windows-nt) "\\" "/"))
142 (defvar completer-path-separator-regexp
143 (if (eq system-type 'windows-nt) "[/\\]" "/"))
145 (defvar completer-path-delimiter-list
146 (if (eq system-type 'windows-nt) '(?\\ ?/) '(?/)))
148 (defvar completer-path-separator-regexp-inside-brackets
149 (if (eq system-type 'windows-nt) "/\\" "/"))
151 (defvar completer-dot-dot-list
152 (if (eq system-type 'windows-nt) '("../" "..\\") '("../")))
154 (defvar completer-string nil "Last completer string.")
155 (defvar completer-table nil "Last completer table.")
156 (defvar completer-pred nil "Last completer pred.")
157 (defvar completer-mode nil "Last completer mode.")
158 (defvar completer-result nil "Last completer result.")
160 (eval-when (eval load compile)
161 (if (not (fboundp 'completion-display-completion-list-function))
162 (setf completion-display-completion-list-function
163 'display-completion-list)))
166 (unless (fboundp 'minibuffer-prompt-end)
167 (defun minibuffer-prompt-end ()
168 "Return the buffer position of the end of the minibuffer prompt.
169 Return (point-min) if current buffer is not a mini-buffer."
173 (defun completer-message (message &optional point)
174 "Display MESSAGE at optional POINT for two seconds."
175 (setq point (or point (point-max))
184 (delete-region point end)
186 (not (string-match "Lucid" emacs-version)))
188 unread-command-char 7))))
191 (defun completer-deleter (regexp choices &optional keep)
192 "Destructively remove strings that match REGEXP in CHOICES.
193 Return the modified list. If optional KEEP, then keep entries that
195 (let* ((choiceb choices)
199 (while (and choiceb (not (string-match regexp (car choiceb))))
200 (setq choiceb (cdr choiceb)))
201 (setq choicep choiceb)
203 (if (string-match regexp (car (cdr choicep)))
204 (setq choicep (cdr choicep))
205 (rplacd choicep (cdr (cdr choicep))))))
206 (while (and choiceb (string-match regexp (car choiceb)))
207 (setq choiceb (cdr choiceb)))
208 (setq choicep choiceb)
210 (if (string-match regexp (car (cdr choicep)))
211 (rplacd choicep (cdr (cdr choicep)))
212 (setq choicep (cdr choicep)))))
216 (defun completer-regexp (string delimiters any)
217 "Convert STRING into a regexp with words delimited by chars in DELIMITERS.
218 Any delimiter in STRING that is the same as ANY will match any delimiter."
219 (let* ((delimiter-reg (concat "[" delimiters "]"))
220 (limit (length string))
223 (while (and (< pos limit) (string-match delimiter-reg string pos))
224 (let* ((begin (match-beginning 0))
226 (delimiter (substring string begin end))
227 (anyp (eq (elt string begin) any)))
229 (format "%s%s[^%s]*%s"
231 (regexp-quote (substring string pos begin))
232 (if anyp delimiters delimiter)
233 (if anyp delimiter-reg (regexp-quote delimiter)))
236 (setq regexp (concat regexp
237 (regexp-quote (substring string pos limit)))))))
240 (defun completer-words (regexp string &optional limit)
241 "Return the number of words matching REGEXP in STRING up to LIMIT."
242 (setq limit (or limit 1000))
245 (while (and (string-match regexp string pos) (<= count limit))
246 (setq count (1+ count)
251 (defun completer-matches (string choices delimiters any)
252 "Return STRING's matches in CHOICES.
253 DELIMITERS and the wildcard ANY are used to segment the strings."
254 (let* ((regexp (concat "[" delimiters "]"))
258 (len (length string))
260 (string-equal-function
262 'equalp ;; We require 'cl above, this is always available.
264 sub sublen choice word wordlen pat)
266 (while (< (or from 0) len)
267 (setq to (or (string-match regexp string (if from (1+ from))) len))
268 (if (eq (elt string (or from 0)) completer-any-delimiter)
269 (setq sub (substring string (if from (1+ from) 0) to)
270 sublen (- (length sub)))
271 (setq sub (substring string (or from 0) to)
272 sublen (length sub)))
273 (setq pattern (cons (cons sub sublen) pattern)
275 (setq pattern (reverse pattern))
276 ;; Find choices that match patterns
277 (setq regexp (concat "[" delimiters "]"))
279 (setq choice (car choices)
282 (while (and word from
284 (if (< (setq wordlen (cdr (setq pat (car word)))) 0)
285 (setq begin (1+ from)
286 end (+ begin (- wordlen)))
288 end (+ begin wordlen)))
289 (and (<= end (length choice))
291 (funcall string-equal-function
293 (substring choice begin end))))))
294 (setq from (string-match regexp choice
295 (if (and (zerop from) (zerop wordlen))
299 (if (not word) (setq matches (cons choice matches)))
300 (setq choices (cdr choices)))
304 (defun completer-choice (string choices delimiters use-words)
305 "Return a list with best match of STRING in CHOICES and T if it is unique.
306 DELIMITERS are used to separate words. A match is unique if it is the only
307 possibility or when USE-WORDS the only possibility with the same
308 number of words. The shortest string of multiple possibilities will be
310 (or (if (null (cdr choices)) (cons (car choices) t))
311 (let* ((regexp (concat "[^" delimiters "]*[" delimiters "]"))
312 (words (if use-words (completer-words regexp string)))
319 (let* ((current (car choice))
320 (length (length current)))
322 (if (= (completer-words regexp current words) words)
325 (if (< length match-len)
329 (= (completer-words regexp current words) words))
334 (if (< length match-len)
336 match-len length)))))
337 (setq choice (cdr choice)))
338 (cons match unique-p))))
342 ;; changed to understand and skip over backslashes
343 (defun completer-region (delimiters)
344 "Return the completion region bounded by characters in DELIMITERS.
345 The search is for the current buffer assuming that point is in it."
346 (let* ((inv (if (string-match "\\^" delimiters)
347 (substring delimiters 1)
348 (concat "^" delimiters)))
349 (re (and (not (equal inv ""))
350 (concat "\\\\[" inv "]"))))
351 (cons (save-excursion
354 (skip-chars-backward delimiters (minibuffer-prompt-end))
356 (> (point) (+ (point-min) 2))
360 (goto-char (match-beginning 0))
366 (skip-chars-forward delimiters)
368 (> (point) (+ (point-min) 1))
372 (goto-char (match-end 0))
377 (defun completer-last-component (string)
378 "Return the start of the last filename component in STRING."
379 (let ((last (1- (length string)))
382 (while (and (setq match (string-match completer-path-separator-regexp string end))
384 (setq end (1+ match)))
388 (defun completer-match-record (string matches delimiters any dir mode)
389 "Return (match lcs choices unique) for STRING in MATCHES.
390 DELIMITERS or ANY wildcards and DIR if a filename when in MODE."
391 (let ((pattern (if dir
392 (substring string (completer-last-component string))
395 (setq matches (completer-matches pattern matches delimiters any)
396 match (try-completion pattern (mapcar 'list matches)))
397 ;; If try-completion produced an exact match for an element in 'matches',
398 ;; then remove any partial matches from 'matches' and set the unique
400 (and (stringp match) (member match matches) (setq matches (list match)))
402 (let ((lcs (concat dir (try-completion "" (mapcar 'list matches)))))
403 (setq match (if (not completer-exact)
405 pattern matches delimiters completer-use-words)))
406 (list (if match (concat dir (car match)))
411 (progn (setq match (concat dir (car matches)))
412 (list match match matches t))
413 (list nil nil nil nil)))))
416 (defun completer-extension-regexp (extensions)
417 "Return a regexp that matches a string ending with any string in EXTENSIONS."
418 (concat "\\(" (mapconcat 'regexp-quote extensions "\\|") "\\)\\'"))
421 (defun completer-flush ()
422 "Flush completer's pathname cache."
424 (setq completer-path-cache nil))
427 (defun completer-cache (path pred words any mode)
428 "Check to see if PATH is in path cache with PRED, WORDS, ANY and MODE."
430 (ptr completer-path-cache)
433 (if completer-use-cache
435 (let ((current (car (car ptr))))
436 (if (string-equal current path)
440 (rplacd last (cdr ptr))
441 (rplacd ptr completer-path-cache)
442 (setq completer-path-cache ptr)))
443 (setq result (cdr (car ptr))
445 (if (cdr ptr) (setq last ptr))
450 (completer path 'read-file-name-internal pred words any
452 (if (and (or (car (cdr (cdr (cdr choices))))
453 (string= path (car choices)))
454 (memq (elt (car choices) (1- (length (car choices))))
455 completer-path-delimiter-list))
457 (if (>= size completer-cache-size) (rplacd last nil))
458 (setq completer-path-cache
459 (cons (cons path choices) completer-path-cache))))
463 (defun completer-file (string pred words any mode)
464 "Return (match common-substring matches unique-p) for STRING.
465 It uses 'READ-FILE-NAME-INTERNAL' for choices that pass PRED using WORDS to
466 delimit words. Optional ANY is a delimiter that matches any of the
467 delimiters in WORD. If optional MODE is nil or 'help then possible
468 matches will always be returned."
469 ;; Canonicalize slashes under windows-nt for proper completion
470 (if (eq system-type 'windows-nt)
471 (setq string (replace-in-string string "/" "\\\\"))
472 (setq string (replace-in-string string "\\\\\\(.\\)" "\\1")))
473 (let* ((case-fold-search completion-ignore-case)
474 (last (and (eq mode 'exit-ok) (completer-last-component string)))
478 ;; Special hack for CMU RFS filenames
479 ;; (if (string-match "^/\\.\\./[^/]*/" string)
481 ;; (string-match "[^~/]" string))
485 ;; Find beginning of first directory component.
486 (cond ((string-match "^/\\.\\./[^/]*/" string)
487 ;; CMU RFS filenames like /../computername/foo/bar.c
490 ((and (memq system-type '(windows-nt cygwin32))
491 (string-match "[/\\][/\\][^/\\]*[/\\]" string))
492 ;; windows-nt filenames like \\computername\foo\bar.c, or
493 ;; cygwin filenames like //d/foo/bar.c
496 ((and (eq system-type 'windows-nt)
497 (string-match "[A-Za-z]:[/\\]?" string))
498 ;; windows-nt filenames like c:\foo\bar.c or c:bar.c
502 ;; normal absolute or relative names, or names beginning
505 (concat "[^~" completer-path-separator-regexp-inside-brackets
508 (new (substring string 0 position))
509 (user (if (string= new "~")
510 (setq new (file-name-directory (expand-file-name new)))))
511 (words (concat words completer-path-separator-regexp-inside-brackets))
512 (len (length string))
515 (old-choices (list nil nil nil nil))
518 (let* ((begin (string-match completer-path-separator-regexp
522 (setq end (when begin (match-end 0))
524 ;; Ends with a /, so check files in directory
525 (if (and (memq mode '(nil help)) (= position len))
526 (completer-match-record
528 ;; This assumes that .. and . come at the end
530 (all-completions new 'read-file-name-internal))
532 (if (member* (first choicep) completer-dot-dot-list
536 (if (member* (second choicep) completer-dot-dot-list
538 (rplacd choicep nil))
539 (setq choicep (cdr choicep)))
542 (if (eq position last)
543 (let ((new (concat new (substring string position))))
544 (list new new nil t))
545 (let ((component (substring string position end)))
547 (string-match completer-file-skip component))
548 ;; Assume component is complete
549 (list (concat new component)
550 (concat new component)
553 (concat new component)
554 pred words any mode))))))
555 ;; Keep going if unique or we match exactly
556 (if (or (car (cdr (cdr (cdr choices))))
558 (string= (concat new (substring string position end))
561 (let* ((lcs (car (cdr choices)))
562 (matches (car (cdr (cdr choices))))
563 ;; (slash (and lcs (string-match "/$" lcs))))
567 (concat completer-path-separator-regexp "$")
571 (if slash (substring lcs 0 slash) lcs)
572 (if (and (cdr matches)
573 (or (eq mode 'help) (not exact-p)))
578 ;; Its ok to not match user names because they may be in
579 ;; different root directories
580 (if (and (= position 1) (= (elt string 0) ?~))
581 (setq new (substring string 0 end)
582 choices (list new new (list new) t)
585 (setq position nil)))))
586 (if (not (car choices))
587 (setq choices old-choices))
588 (if (and (car choices)
589 (not (eq mode 'help))
590 (not (car (cdr (cdr (cdr choices))))))
591 ;; Try removing completion ignored extensions
593 (completer-extension-regexp completion-ignored-extensions))
594 (choiceb (car (cdr (cdr choices))))
599 (if (string-match extensions (car choicep))
602 (if (and isext noext)
603 ;; There are matches besides extensions
604 (setq choiceb (completer-deleter extensions choiceb)
606 (setq choicep (cdr choicep))))
607 (if (and isext noext)
609 (completer-match-record
610 (if end (substring string end) "")
612 (file-name-directory (car (cdr choices)))
615 (let ((match (car choices))
616 (lcs (car (cdr choices)))
619 (cons (if match (concat "~" (substring match len)))
620 (cons (if lcs (concat "~" (substring lcs len)))
621 (cdr (cdr choices)))))))
622 (setq match (nth 0 choices)
623 substr (nth 1 choices)
624 re (concat "\\([" ; "Now you have two problems":
625 "][" ; this has to come first;
626 "\\\\" ; this is one backslash;
627 "\"" ; this is one quote;
628 "^" ; this can't come first;
630 "#$&*?;!|'`()<>" ; easy.
633 (setf (nth 0 choices)
634 (replace-in-string match re "\\\\\\1")))
636 (setf (nth 1 choices)
637 (replace-in-string substr re "\\\\\\1")))
640 ;;;%Exported program interface
642 (defun completer (string table pred words
643 &optional any mode file-p)
644 "Return (match common-substring matches unique-p) for STRING in TABLE.
645 The choices must also pass PRED using WORDS to delimit words. If the
646 flag 'COMPLETER-COMPLETE-FILENAMES' is T and the table is
647 'READ-FILE-NAME-INTERNAL', then filename components will be individually
648 expanded. Optional ANY is a delimiter that can match any delimiter in
649 WORDS. Optional MODE is nil for complete, 'help for help and 'exit
651 (let ((completion-ignore-case
652 (or (and file-p (file-system-ignore-case-p string))
653 completion-ignore-case)))
654 (if (and (stringp completer-string)
655 (string= string completer-string)
656 (eq table completer-table)
657 (eq pred completer-pred)
659 (or (eq mode completer-mode)
660 (not (memq table '(read-file-name-internal
661 read-directory-name-internal)))))
665 completer-table table
669 (if (and completer-complete-filenames
671 (memq table '(read-file-name-internal
672 read-directory-name-internal)))
673 (completer-file string pred words any mode)
674 (let* ((file-p (or file-p
676 '(read-file-name-internal
677 read-directory-name-internal))))
678 (case-fold-search completion-ignore-case)
679 (pattern (concat "[" words "]"))
680 (component (if file-p (completer-last-component string)))
681 (dir (if component (substring string 0 component)))
682 (string (if dir (substring string component) string))
683 (has-words (or (string-match pattern string)
685 (if (and file-p (string-match "^\\$" string))
686 ;; Handle environment variables
688 (getenv (substring string 1
689 ;; (string-match "/" string)))) ; old
691 completer-path-separator-regexp
694 ;; (if match (setq match (concat match "/"))) ; old
698 completer-path-separator-string)))
700 (list match match (list match) match))
703 (concat dir (substring string 0 has-words))
705 (regexp (completer-regexp string words any)))
707 (completer-match-record
709 (completer-deleter regexp choices t)
711 (list nil nil nil nil))))))
712 completer-string string)
716 (defun completer-display-choices (choices &optional match message end
718 "Display the list of possible CHOICES.
719 MATCH, MESSAGE, END and DISPLAY are used optionally. If MATCH is
720 non-nil, it will be flagged as the best guess. If there are no
721 choices, display MESSAGE. END is where to put temporary messages. If
722 DISPLAY is present then it will be called on each possible completion
723 and should return a string."
726 (with-output-to-temp-buffer "*Completions*"
728 (funcall completion-display-completion-list-function
734 (setq new (cons (funcall display (car old)) new)
737 (copy-sequence choices))
738 (function (lambda (x y)
739 (string-lessp (or (car-safe x) x)
740 (or (car-safe y) y)))))))
743 (set-buffer "*Completions*")
744 (goto-char (point-min))
745 (let ((buffer-read-only nil))
746 (insert "Guess = " match (if (cdr choices) ", " "") "\n")))))
748 (completer-message (or message " (No completions)") end)))
751 (defun completer-goto (match lcs choices unique delimiters words
752 &optional mode display)
753 "Go to the part of the string that disambiguates CHOICES.
754 MATCH is the best match, LCS is the longest common substring of all
755 of the matches. CHOICES is a list of the possibilities, UNIQUE
756 indicates if MATCH is unique. DELIMITERS are possible bounding
757 characters for the completion region. WORDS are the characters that
758 delimit the words for partial matches. Replace the region bounded by
759 delimiters with the match if unique and the lcs otherwise unless
760 optional MODE is 'help. Then go to the part of the string that
761 disambiguates CHOICES using WORDS to separate words and display the
762 possibilities if the string was not extended. If optional DISPLAY is
763 present then it will be called on each possible completion and should
765 (setq completer-message nil)
766 (let* ((region (completer-region delimiters))
769 (string (buffer-substring start end))
770 ;; (file-p (string-match "[^ ]*\\(~\\|/\\|$\\)" string))
771 (file-p (string-match (if (eq system-type 'windows-nt)
772 "[^ ]*\\(~\\|/\\|\\\\\\|\\|$\\)"
773 "[^ ]*\\(~\\|/\\|$\\)")
775 (no-insert (eq mode 'help))
777 (new (not (string= (buffer-substring start (point)) lcs))))
782 (completer-display-choices choices match nil end display))
783 (if (string= string match)
785 (progn (goto-char end)
786 (completer-message " (Sole completion)" end)))
787 (completer-insert match delimiters)))
791 ;; (concat "[" words (if file-p "/") "]")
794 (and file-p completer-path-separator-regexp-inside-brackets)
797 (words (completer-words regexp lcs))
799 ;; Go to where its ambiguous
803 (setq completer-last-pattern
804 (list string delimiters (current-buffer) start)
806 end (+ end (length lcs))))
807 ;; Skip to the first delimiter in the original string
808 ;; beyond the ambiguous point and keep from there on
809 (if (re-search-forward regexp end 'move words)
811 (if (and (not no-insert) match)
814 (string-match (regexp-quote lcs) match)
815 (substring match (match-end 0)
816 (1+ (match-end 0))))))
817 (if (string-match regexp delimiter)
818 (insert delimiter))))
821 (setq end (- end (- (point) start)))
822 (delete-region start (point)))))
824 (when (or no-insert (not new))
825 (completer-display-choices choices match nil end display))
827 (when (not (= (point) end)) (forward-char 1))
828 (unless (save-excursion (re-search-forward completer-path-separator-regexp end t))
832 (completer-message (if no-insert
837 ;;;%Exported buffer interface
839 (defun completer-complete-goto (delimiters words table pred
840 &optional no-insert display)
841 "Complete the string bound by DELIMITERS using WORDS to bound words
842 for partial matches in TABLE with PRED and then insert the longest
843 common substring unless optional NO-INSERT and go to the point of
844 ambiguity. If optional DISPLAY, it will be called on each match when
845 possible completions are shown and should return a string."
846 (let* ((region (completer-region delimiters)))
847 (apply 'completer-goto
848 (append (completer (buffer-substring (car region) (cdr region))
849 table pred words completer-any-delimiter
851 (list delimiters words no-insert display)))))
854 (defun completer-insert (match delimiters &optional buffer undo)
855 "Replace the region bounded with characters in DELIMITERS by MATCH.
856 Then save it so that it can be restored by completer-undo."
857 (let* ((region (completer-region delimiters))
860 (if (and undo (or (not (= start undo))
861 (not (eq (current-buffer) buffer))))
862 (error "No previous pattern")
863 (setq completer-last-pattern (list (buffer-substring start end)
867 (delete-region start end)
872 (defun completer-undo ()
873 "Swap the last expansion and the last match pattern."
875 (if completer-last-pattern
876 (apply 'completer-insert completer-last-pattern)
877 (error "No previous pattern")))
879 ;;;%Minibuffer specific code
881 (defun completer-minibuf-string ()
882 "Remove dead filename specs from the minibuffer.
883 Dead filename should be delimited by // or ~ or $ and return the
886 (goto-char (point-max))
887 (if (and (memq minibuffer-completion-table
888 '(read-file-name-internal read-directory-name-internal))
891 (if (memq system-type '(windows-nt cygwin32))
895 (minibuffer-prompt-end)
897 (delete-region (minibuffer-prompt-end) (1+ (point))))
898 (buffer-substring (minibuffer-prompt-end) (point-max))))
901 (defun completer-minibuf-exit ()
902 "Exit the minibuffer and clear completer-last-pattern."
904 (setq completer-last-pattern nil)
908 (defun completer-new-cmd (cmd)
909 "Return T if we can't execute the old minibuffer version of CMD."
910 (if (or completer-disable
911 (let ((string (completer-minibuf-string)))
916 completer-path-separator-regexp-inside-brackets
921 (try-completion string
922 minibuffer-completion-table
923 minibuffer-completion-predicate)))
924 (if (memq minibuffer-completion-table
925 '(read-file-name-internal
926 read-directory-name-internal))
927 ;; Directories complete as themselves
929 (or (not (string= string completion))
930 (file-exists-p completion)))
939 (defun completer-minibuf (&optional mode)
940 "Partial completion of minibuffer expressions.
941 Optional MODE is (quote help) for help and (quote exit) for exit.
943 If what has been typed so far matches any possibility normal
944 completion will be done. Otherwise, the string is considered to be a
945 pattern with words delimited by the characters in
946 completer-words. If completer-exact is T, the best match will be
947 the shortest one with the same number of words as the pattern if
948 possible and otherwise the shortest matching expression. If called
949 with a prefix, caching will be temporarily disabled.
954 b--d *beginning-of-defun or byte-recompile-directory
955 by d *byte-recompile-directory if completer-any-delimiter is \" \"
956 ~/i.e *~/ilisp.el or ~/il-el.el or ~/ilisp.elc
960 (let ((completer-use-cache (not (or (not completer-use-cache)
961 current-prefix-arg))))
962 (completer (completer-minibuf-string)
963 minibuffer-completion-table
964 minibuffer-completion-predicate
966 completer-any-delimiter
968 (list "^" completer-words mode)))
971 (defun completer-toggle ()
972 "Turn partial completion on or off."
974 (setq completer-disable (not completer-disable))
975 (message (if completer-disable
976 "Partial completion OFF"
977 "Partial completion ON")))
980 (defvar completer-old-help
981 (lookup-key minibuffer-local-must-match-map "?")
982 "Old binding of ? in minibuffer completion map.")
983 (defun completer-help ()
984 "Partial completion minibuffer-completion-help.
985 See completer-minibuf for more information."
987 (if (completer-new-cmd completer-old-help)
988 (apply 'completer-goto (completer-minibuf 'help))))
991 (defvar completer-old-completer
992 (lookup-key minibuffer-local-must-match-map "\t")
993 "Old binding of TAB in minibuffer completion map.")
995 (defun completer-complete ()
996 "Partial completion minibuffer-complete.
997 See completer-minibuf for more information."
999 (if (completer-new-cmd completer-old-completer)
1000 (apply 'completer-goto (completer-minibuf))))
1003 (defvar completer-old-word
1004 (lookup-key minibuffer-local-must-match-map " ")
1005 "Old binding of SPACE in minibuffer completion map.")
1006 (defun completer-word ()
1007 "Partial completion minibuffer-complete.
1008 See completer-minibuf for more information."
1010 (if (eq completer-any-delimiter ?\ )
1012 (if (completer-new-cmd completer-old-word)
1013 (apply 'completer-goto (completer-minibuf)))))
1016 (defvar completer-old-exit
1017 (lookup-key minibuffer-local-must-match-map "\n")
1018 "Old binding of RET in minibuffer completion map.")
1019 (defun completer-exit ()
1020 "Partial completion minibuffer-complete-and-exit.
1021 See completer-minibuf for more information."
1023 (if (completer-new-cmd completer-old-exit)
1024 (let* ((completions (completer-minibuf 'exit))
1025 (match (car completions))
1026 (unique-p (car (cdr (cdr (cdr completions))))))
1027 (apply 'completer-goto completions)
1029 (completer-minibuf-exit)
1031 (progn (completer-insert match "^")
1032 (if minibuffer-completion-confirm
1033 (completer-message " (Confirm)")
1034 (completer-minibuf-exit)))
1035 (if (not completer-message) (beep)))))))
1038 (defun completer-match-exit ()
1039 "Exit the minibuffer with the current best match."
1041 (let* ((completions (completer-minibuf 'exit))
1042 (guess (car completions)))
1044 ;; OK if last filename component doesn't match
1045 (setq completions (completer-minibuf 'exit-ok)
1046 guess (car completions)))
1049 (goto-char (minibuffer-prompt-end))
1051 (delete-region (point) (point-max))
1053 (apply 'completer-goto completions))))
1056 ;this interferes with normal undo.
1057 ;(define-key minibuffer-local-completion-map "\C-_" 'completer-undo)
1058 (define-key minibuffer-local-completion-map "\t" 'completer-complete)
1059 (define-key minibuffer-local-completion-map " " 'completer-word)
1060 (define-key minibuffer-local-completion-map "?" 'completer-help)
1061 (define-key minibuffer-local-completion-map "\n" 'completer-minibuf-exit)
1062 (define-key minibuffer-local-completion-map "\r" 'completer-minibuf-exit)
1063 (define-key minibuffer-local-completion-map "\M-\n" 'completer-match-exit)
1064 (define-key minibuffer-local-completion-map "\M-\r" 'completer-match-exit)
1066 ;this interferes with normal undo.
1067 ;(define-key minibuffer-local-must-match-map "\C-_" 'completer-undo)
1068 (define-key minibuffer-local-must-match-map "\t" 'completer-complete)
1069 (define-key minibuffer-local-must-match-map " " 'completer-word)
1070 (define-key minibuffer-local-must-match-map "\n" 'completer-exit)
1071 (define-key minibuffer-local-must-match-map "\r" 'completer-exit)
1072 (define-key minibuffer-local-must-match-map "?" 'completer-help)
1073 (define-key minibuffer-local-must-match-map "\M-\n" 'completer-match-exit)
1074 (define-key minibuffer-local-must-match-map "\M-\r" 'completer-match-exit)
1077 (defun completer-comint-dynamic-list-completions (completions)
1078 "List in help buffer sorted COMPLETIONS.
1079 Typing SPC flushes the help buffer."
1080 (completer-comint-dynamic-complete-1 nil 'help))
1082 (defun completer-comint-dynamic-complete-filename ()
1083 "Dynamically complete the filename at point."
1085 (completer-comint-dynamic-complete-1 nil t))
1088 (defun completer-comint-dynamic-complete-1 (&optional undo mode)
1089 "Complete the previous filename or display possibilities if done
1090 twice in a row. If called with a prefix, undo the last completion."
1094 ;; added by jwz: don't cache completions in shell buffer!
1095 (setq completer-string nil)
1096 (let ((conf (current-window-configuration)));; lemacs change
1097 (completer-complete-goto "^ \t\n\""
1099 'read-file-name-internal
1103 (when (eq mode 'help) (comint-restore-window-config conf))
1106 ;(fset 'comint-dynamic-complete 'completer-comint-dynamic-complete)
1107 (fset 'comint-dynamic-complete-filename
1108 'completer-comint-dynamic-complete-filename)
1109 (fset 'comint-dynamic-list-completions
1110 'completer-comint-dynamic-list-completions)
1112 ;;; Set the functions again if comint is loaded.
1113 (setq comint-load-hook
1114 (cons (function (lambda ()
1115 ;; (fset 'comint-dynamic-complete
1116 ;; 'completer-comint-dynamic-complete)
1117 (fset 'comint-dynamic-complete-filename
1118 'completer-comint-dynamic-complete-filename)
1119 (fset 'comint-dynamic-list-completions
1120 'completer-comint-dynamic-list-completions)))
1121 (when (and (boundp 'comint-load-hook) comint-load-hook)
1122 (if (consp comint-load-hook)
1123 (if (eq (car comint-load-hook) 'lambda)
1124 (list comint-load-hook)
1126 (list comint-load-hook)))))
1128 ;;;%lisp-complete-symbol
1129 (defun lisp-complete-symbol (&optional mode)
1130 "Perform partial completion on Lisp symbol preceding point.
1131 That symbol is compared against the symbols that exist and any additional
1132 characters determined by what is there are inserted. If the symbol
1133 starts just after an open-parenthesis, only symbols with function
1134 definitions are considered. Otherwise, all symbols with function
1135 definitions, values or properties are considered. If called with a
1136 negative prefix, the last completion will be undone."
1138 (if (< (prefix-numeric-value mode) 0)
1140 (let* ((end (save-excursion (skip-chars-forward "^ \t\n)]}\"") (point)))
1141 (beg (save-excursion
1143 (while (= (char-syntax (following-char)) ?\')
1146 (pattern (buffer-substring beg end))
1148 (if (eq (char-after (1- beg)) ?\()
1150 (function (lambda (sym)
1151 (or (boundp sym) (fboundp sym)
1152 (symbol-plist sym))))))
1153 (completion (try-completion pattern obarray predicate)))
1154 (cond ((eq completion t))
1156 (completer-complete-goto
1157 "^ \t\n\(\)[]{}'`" completer-words
1160 (if (not (eq predicate 'fboundp))
1161 (function (lambda (choice)
1162 (if (fboundp (intern choice))
1163 (list choice " <f>")
1165 ((not (string= pattern completion))
1166 (delete-region beg end)
1167 (insert completion))
1169 (message "Making completion list...")
1170 (let ((list (all-completions pattern obarray predicate)))
1171 (or (eq predicate 'fboundp)
1174 (setq new (cons (if (fboundp (intern (car list)))
1175 (list (car list) " <f>")
1178 (setq list (cdr list)))
1179 (setq list (nreverse new))))
1180 (with-output-to-temp-buffer "*Help*"
1181 (funcall completion-display-completion-list-function
1182 (sort list (function (lambda (x y)
1185 (or (car-safe y) y))))))))
1186 (message "Making completion list...%s" "done"))))))
1189 (provide 'completer)
1190 (run-hooks 'completer-load-hook)
1192 ;;; end of file -- completer.el --