(defgroup partial-completion nil
"Partial Completion of items."
:prefix "pc-"
:group 'minibuffer
:group 'convenience)
(defcustom PC-first-char 'find-file
"*Control how the first character of a string is to be interpreted.
If nil, the first character of a string is not taken literally if it is a word
delimiter, so that \".e\" matches \"*.e*\".
If t, the first character of a string is always taken literally even if it is a
word delimiter, so that \".e\" matches \".e*\".
If non-nil and non-t, the first character is taken literally only for file name
completion."
:type '(choice (const :tag "delimiter" nil)
(const :tag "literal" t)
(other :tag "find-file" find-file))
:group 'partial-completion)
(defcustom PC-meta-flag t
"*If non-nil, TAB means PC completion and M-TAB means normal completion.
Otherwise, TAB means normal completion and M-TAB means Partial Completion."
:type 'boolean
:group 'partial-completion)
(defcustom PC-word-delimiters "-_. "
"*A string of characters treated as word delimiters for completion.
Some arcane rules:
If `]' is in this string, it must come first.
If `^' is in this string, it must not come first.
If `-' is in this string, it must come first or right after `]'.
In other words, if S is this string, then `[S]' must be a legal Emacs regular
expression (not containing character ranges like `a-z')."
:type 'string
:group 'partial-completion)
(defcustom PC-include-file-path '("/usr/include" "/usr/local/include")
"*A list of directories in which to look for include files.
If nil, means use the colon-separated path in the variable $INCPATH instead."
:type '(repeat directory)
:group 'partial-completion)
(defcustom PC-disable-includes nil
"*If non-nil, include-file support in \\[find-file] is disabled."
:type 'boolean
:group 'partial-completion)
(defvar PC-default-bindings t
"If non-nil, default partial completion key bindings are suppressed.")
(defvar PC-env-vars-alist nil
"A list of the environment variable names and values.")
(defvar PC-old-read-file-name-internal nil)
(defun PC-bindings (bind)
(let ((completion-map minibuffer-local-completion-map)
(must-match-map minibuffer-local-must-match-map))
(cond ((not bind)
(define-key completion-map "\t" 'minibuffer-complete)
(define-key completion-map " " 'minibuffer-complete-word)
(define-key completion-map "?" 'minibuffer-completion-help)
(define-key must-match-map "\t" 'minibuffer-complete)
(define-key must-match-map " " 'minibuffer-complete-word)
(define-key must-match-map "\r" 'minibuffer-complete-and-exit)
(define-key must-match-map "\n" 'minibuffer-complete-and-exit)
(define-key must-match-map "?" 'minibuffer-completion-help)
(define-key global-map "\e\t" 'complete-symbol))
(PC-default-bindings
(define-key completion-map "\t" 'PC-complete)
(define-key completion-map " " 'PC-complete-word)
(define-key completion-map "?" 'PC-completion-help)
(define-key completion-map "\e\t" 'PC-complete)
(define-key completion-map "\e " 'PC-complete-word)
(define-key completion-map "\e\r" 'PC-force-complete-and-exit)
(define-key completion-map "\e\n" 'PC-force-complete-and-exit)
(define-key completion-map "\e?" 'PC-completion-help)
(define-key must-match-map "\t" 'PC-complete)
(define-key must-match-map " " 'PC-complete-word)
(define-key must-match-map "\r" 'PC-complete-and-exit)
(define-key must-match-map "\n" 'PC-complete-and-exit)
(define-key must-match-map "?" 'PC-completion-help)
(define-key must-match-map "\e\t" 'PC-complete)
(define-key must-match-map "\e " 'PC-complete-word)
(define-key must-match-map "\e\r" 'PC-complete-and-exit)
(define-key must-match-map "\e\n" 'PC-complete-and-exit)
(define-key must-match-map "\e?" 'PC-completion-help)
(define-key global-map "\e\t" 'PC-lisp-complete-symbol)))))
(define-minor-mode partial-completion-mode
"Toggle Partial Completion mode.
With prefix ARG, turn Partial Completion mode on if ARG is positive.
When Partial Completion mode is enabled, TAB (or M-TAB if `PC-meta-flag' is
nil) is enhanced so that if some string is divided into words and each word is
delimited by a character in `PC-word-delimiters', partial words are completed
as much as possible and `*' characters are treated likewise in file names.
For example, M-x p-c-m expands to M-x partial-completion-mode since no other
command begins with that sequence of characters, and
\\[find-file] f_b.c TAB might complete to foo_bar.c if that file existed and no
other file in that directory begin with that sequence of characters.
Unless `PC-disable-includes' is non-nil, the `<...>' sequence is interpreted
specially in \\[find-file]. For example,
\\[find-file] <sys/time.h> RET finds the file `/usr/include/sys/time.h'.
See also the variable `PC-include-file-path'."
:global t :group 'partial-completion
(PC-bindings partial-completion-mode)
(cond ((not partial-completion-mode)
(remove-hook 'find-file-not-found-hooks 'PC-look-for-include-file))
((not PC-disable-includes)
(add-hook 'find-file-not-found-hooks 'PC-look-for-include-file)))
(cond ((and (not partial-completion-mode)
(functionp PC-old-read-file-name-internal))
(fset 'read-file-name-internal PC-old-read-file-name-internal))
((and (not PC-disable-includes) (not PC-old-read-file-name-internal))
(setq PC-old-read-file-name-internal
(symbol-function 'read-file-name-internal))
(fset 'read-file-name-internal
'PC-read-include-file-name-internal)))
(when (and partial-completion-mode (null PC-env-vars-alist))
(setq PC-env-vars-alist
(mapcar (lambda (string)
(let ((d (string-match "=" string)))
(cons (concat "$" (substring string 0 d))
(and d (substring string (1+ d))))))
process-environment))))
(defun PC-complete ()
"Like minibuffer-complete, but allows \"b--di\"-style abbreviations.
For example, \"M-x b--di\" would match `byte-recompile-directory', or any
name which consists of three or more words, the first beginning with \"b\"
and the third beginning with \"di\".
The pattern \"b--d\" is ambiguous for `byte-recompile-directory' and
`beginning-of-defun', so this would produce a list of completions
just like when normal Emacs completions are ambiguous.
Word-delimiters for the purposes of Partial Completion are \"-\", \"_\",
\".\", and SPC."
(interactive)
(if (PC-was-meta-key)
(minibuffer-complete)
(or (eq last-command this-command)
(setq minibuffer-scroll-window nil))
(let ((window minibuffer-scroll-window))
(if (and window (window-buffer window)
(buffer-name (window-buffer window)))
(save-excursion
(set-buffer (window-buffer window))
(if (pos-visible-in-window-p (point-max) window)
(set-window-start window (point-min) nil)
(scroll-other-window)))
(PC-do-completion nil)))))
(defun PC-complete-word ()
"Like `minibuffer-complete-word', but allows \"b--di\"-style abbreviations.
See `PC-complete' for details.
This can be bound to other keys, like `-' and `.', if you wish."
(interactive)
(if (eq (PC-was-meta-key) PC-meta-flag)
(if (eq last-command-char ? )
(minibuffer-complete-word)
(self-insert-command 1))
(self-insert-command 1)
(if (eobp)
(PC-do-completion 'word))))
(defun PC-complete-space ()
"Like `minibuffer-complete-word', but allows \"b--di\"-style abbreviations.
See `PC-complete' for details.
This is suitable for binding to other keys which should act just like SPC."
(interactive)
(if (eq (PC-was-meta-key) PC-meta-flag)
(minibuffer-complete-word)
(insert " ")
(if (eobp)
(PC-do-completion 'word))))
(defun PC-complete-and-exit ()
"Like `minibuffer-complete-and-exit', but allows \"b--di\"-style abbreviations.
See `PC-complete' for details."
(interactive)
(if (eq (PC-was-meta-key) PC-meta-flag)
(minibuffer-complete-and-exit)
(PC-do-complete-and-exit)))
(defun PC-force-complete-and-exit ()
"Like `minibuffer-complete-and-exit', but allows \"b--di\"-style abbreviations.
See `PC-complete' for details."
(interactive)
(let ((minibuffer-completion-confirm nil))
(PC-do-complete-and-exit)))
(defun PC-do-complete-and-exit ()
(if (= (point-max) (minibuffer-prompt-end)) (exit-minibuffer)
(let ((flag (PC-do-completion 'exit)))
(and flag
(if (or (eq flag 'complete)
(not minibuffer-completion-confirm))
(exit-minibuffer)
(PC-temp-minibuffer-message " [Confirm]"))))))
(defun PC-completion-help ()
"Like `minibuffer-completion-help', but allows \"b--di\"-style abbreviations.
See `PC-complete' for details."
(interactive)
(if (eq (PC-was-meta-key) PC-meta-flag)
(minibuffer-completion-help)
(PC-do-completion 'help)))
(defun PC-was-meta-key ()
(or (/= (length (this-command-keys)) 1)
(let ((key (aref (this-command-keys) 0)))
(if (integerp key)
(>= key 128)
(not (null (memq 'meta (event-modifiers key))))))))
(defvar PC-ignored-extensions 'empty-cache)
(defvar PC-delims 'empty-cache)
(defvar PC-ignored-regexp nil)
(defvar PC-word-failed-flag nil)
(defvar PC-delim-regex nil)
(defvar PC-ndelims-regex nil)
(defvar PC-delims-list nil)
(defvar PC-completion-as-file-name-predicate
(function
(lambda ()
(memq minibuffer-completion-table
'(read-file-name-internal read-directory-name-internal))))
"A function testing whether a minibuffer completion now will work filename-style.
The function takes no arguments, and typically looks at the value
of `minibuffer-completion-table' and the minibuffer contents.")
(defun PC-do-completion (&optional mode beg end)
(or beg (setq beg (minibuffer-prompt-end)))
(or end (setq end (point-max)))
(let* ((table minibuffer-completion-table)
(pred minibuffer-completion-predicate)
(filename (funcall PC-completion-as-file-name-predicate))
(dirname nil)
(dirlength 0)
(str (buffer-substring beg end))
(incname (and filename (string-match "<\\([^\"<>]*\\)>?$" str)))
(ambig nil)
basestr
env-on
regex
p offset
(poss nil)
helpposs
(case-fold-search completion-ignore-case))
(if (and (eq mode 'exit)
(PC-is-complete-p str table pred))
'complete
(and filename
(setq basestr (or (file-name-directory str) ""))
(setq dirlength (length basestr))
(setq p (substitute-in-file-name basestr))
(not (string-equal basestr p))
(setq str (concat p (file-name-nondirectory str)))
(progn
(delete-region beg end)
(insert str)
(setq end (+ beg (length str)))))
(or (equal PC-word-delimiters PC-delims)
(setq PC-delims PC-word-delimiters
PC-delim-regex (concat "[" PC-delims "]")
PC-ndelims-regex (concat "[^" PC-delims "]*")
PC-delims-list (append PC-delims nil)))
(and filename
(string-match "\\*.*/" str)
(let ((pat str)
files)
(setq p (1+ (string-match "/[^/]*\\'" pat)))
(while (setq p (string-match PC-delim-regex pat p))
(setq pat (concat (substring pat 0 p)
"*"
(substring pat p))
p (+ p 2)))
(setq files (PC-expand-many-files (concat pat "*")))
(if files
(let ((dir (file-name-directory (car files)))
(p files))
(while (and (setq p (cdr p))
(equal dir (file-name-directory (car p)))))
(if p
(setq filename nil table nil pred nil
ambig t)
(delete-region beg end)
(setq str (concat dir (file-name-nondirectory str)))
(insert str)
(setq end (+ beg (length str)))))
(setq filename nil table nil pred nil))))
(if filename
(if incname
(setq basestr (substring str incname)
dirname (substring str 0 incname))
(setq basestr (file-name-nondirectory str)
dirname (file-name-directory str))
(setq str (concat dirname basestr)))
(setq basestr str))
(setq regex (regexp-quote basestr)
offset (if (and (> (length regex) 0)
(not (eq (aref basestr 0) ?\*))
(or (eq PC-first-char t)
(and PC-first-char filename))) 1 0)
p offset)
(while (setq p (string-match PC-delim-regex regex p))
(if (eq (aref regex p) ? )
(setq regex (concat (substring regex 0 p)
PC-ndelims-regex
PC-delim-regex
(substring regex (1+ p)))
p (+ p (length PC-ndelims-regex) (length PC-delim-regex)))
(let ((bump (if (memq (aref regex p)
'(?$ ?^ ?\. ?* ?+ ?? ?[ ?] ?\\))
-1 0)))
(setq regex (concat (substring regex 0 (+ p bump))
PC-ndelims-regex
(substring regex (+ p bump)))
p (+ p (length PC-ndelims-regex) 1)))))
(setq p 0)
(if filename
(while (setq p (string-match "\\\\\\*" regex p))
(setq regex (concat (substring regex 0 p)
"[^/]*"
(substring regex (+ p 2))))))
(setq regex (concat "\\`" regex))
(and (> (length basestr) 0)
(= (aref basestr 0) ?$)
(setq env-on t
table PC-env-vars-alist
pred nil))
(if (not (setq p (string-match (concat PC-delim-regex
(if filename "\\|\\*" ""))
str
(+ (length dirname) offset))))
(setq poss (all-completions (if env-on
basestr str)
table
pred))
(let ((compl (all-completions (if env-on
(file-name-nondirectory (substring str 0 p))
(substring str 0 p))
table
pred)))
(setq p compl)
(while p
(and (string-match regex (car p))
(progn
(set-text-properties 0 (length (car p)) '() (car p))
(setq poss (cons (car p) poss))))
(setq p (cdr p)))))
(cond
((null poss)
(if (and (eq mode 'word)
(not PC-word-failed-flag))
(let ((PC-word-failed-flag t))
(delete-backward-char 1)
(PC-do-completion 'word))
(beep)
(PC-temp-minibuffer-message (if ambig
" [Ambiguous dir name]"
(if (eq mode 'help)
" [No completions]"
" [No match]")))
nil))
((or (cdr (setq helpposs poss))
(memq mode '(help word)))
(and filename
(not (eq mode 'help))
(let ((p2 poss))
(or (equal completion-ignored-extensions PC-ignored-extensions)
(setq PC-ignored-regexp
(concat "\\("
(mapconcat
'regexp-quote
(setq PC-ignored-extensions
completion-ignored-extensions)
"\\|")
"\\)\\'")))
(setq p nil)
(while p2
(or (string-match PC-ignored-regexp (car p2))
(string-match "\\(\\`\\|/\\)[.][.]?/?\\'" (car p2))
(setq p (cons (car p2) p)))
(setq p2 (cdr p2)))
(and p (setq poss p))))
(setq p (and (not (eq mode 'help)) poss))
(while (and p
(not (string-equal (car p) basestr)))
(setq p (cdr p)))
(and p (null mode)
(PC-temp-minibuffer-message " [Complete, but not unique]"))
(if (and p
(not (and (null mode)
(eq this-command last-command))))
t
(let ((improved nil)
prefix
(pt nil)
(skip "\\`"))
(if (and (not (eq mode 'help))
(setq prefix (try-completion "" (mapcar 'list poss))))
(let ((first t) i)
(if (eq mode 'word)
(setq prefix (PC-chop-word prefix basestr)))
(goto-char (+ beg (length dirname)))
(while (and (progn
(setq i 0)
(while (< i (length prefix))
(if (and (< (point) end)
(eq (aref prefix i)
(following-char)))
(forward-char 1)
(if (and (< (point) end)
(or (and (looking-at " ")
(memq (aref prefix i)
PC-delims-list))
(eq (downcase (aref prefix i))
(downcase
(following-char)))))
(progn
(delete-char 1)
(setq end (1- end)))
(and filename (looking-at "\\*")
(progn
(delete-char 1)
(setq end (1- end))))
(setq improved t))
(insert (substring prefix i (1+ i)))
(setq end (1+ end)))
(setq i (1+ i)))
(or pt (equal (point) beg)
(setq pt (point)))
(looking-at PC-delim-regex))
(setq skip (concat skip
(regexp-quote prefix)
PC-ndelims-regex)
prefix (try-completion
""
(mapcar
(function
(lambda (x)
(list
(and (string-match skip x)
(substring
x
(match-end 0))))))
poss)))
(or (> i 0) (> (length prefix) 0))
(or (not (eq mode 'word))
(and first (> (length prefix) 0)
(setq first nil
prefix (substring prefix 0 1))))))
(goto-char (if (eq mode 'word) end
(or pt beg)))))
(if (and (eq mode 'word)
(not PC-word-failed-flag))
(if improved
(if (PC-is-complete-p (buffer-substring 1 (1- end))
table pred)
(delete-region (1- end) end)))
(if improved
(and (eq mode 'exit)
(PC-is-complete-p (field-string) table pred))
(if (or (eq completion-auto-help t)
(and completion-auto-help
(eq last-command this-command))
(eq mode 'help))
(with-output-to-temp-buffer "*Completions*"
(display-completion-list (sort helpposs 'string-lessp))
(save-excursion
(set-buffer standard-output)
(setq completion-base-size dirlength)))
(PC-temp-minibuffer-message " [Next char not unique]"))
nil)))))
(t
(if (and (equal basestr (car poss))
(not (and env-on filename)))
(if (null mode)
(PC-temp-minibuffer-message " [Sole completion]"))
(delete-region beg end)
(insert (format "%s"
(if filename
(substitute-in-file-name (concat dirname (car poss)))
(car poss)))))
t)))))
(defun PC-is-complete-p (str table pred)
(let ((res (if (listp table)
(assoc str table)
(if (vectorp table)
(or (equal str "nil") (intern-soft str table))
(funcall table str pred 'lambda)))))
(and res
(or (not pred)
(and (not (listp table)) (not (vectorp table)))
(funcall pred res))
res)))
(defun PC-chop-word (new old)
(let ((i -1)
(j -1))
(while (and (setq i (string-match PC-delim-regex old (1+ i)))
(setq j (string-match PC-delim-regex new (1+ j)))))
(if (and j
(or (not PC-word-failed-flag)
(setq j (string-match PC-delim-regex new (1+ j)))))
(substring new 0 (1+ j))
new)))
(defvar PC-not-minibuffer nil)
(defun PC-temp-minibuffer-message (message)
"A Lisp version of `temp_minibuffer_message' from minibuf.c."
(cond (PC-not-minibuffer
(message message)
(sit-for 2)
(message ""))
((fboundp 'temp-minibuffer-message)
(temp-minibuffer-message message))
(t
(let ((point-max (point-max)))
(save-excursion
(goto-char point-max)
(insert message))
(let ((inhibit-quit t))
(sit-for 2)
(delete-region point-max (point-max))
(when quit-flag
(setq quit-flag nil
unread-command-events '(7))))))))
(defun PC-lisp-complete-symbol ()
"Perform completion on Lisp symbol preceding point.
That symbol is compared against the symbols that exist
and any additional characters determined by what is there
are inserted.
If the symbol starts just after an open-parenthesis,
only symbols with function definitions are considered.
Otherwise, all symbols with function definitions, values
or properties are considered."
(interactive)
(let* ((end (point))
(buffer-syntax (syntax-table))
(beg (unwind-protect
(save-excursion
(if lisp-mode-syntax-table
(set-syntax-table lisp-mode-syntax-table))
(backward-sexp 1)
(while (= (char-syntax (following-char)) ?\')
(forward-char 1))
(point))
(set-syntax-table buffer-syntax)))
(minibuffer-completion-table obarray)
(minibuffer-completion-predicate
(if (eq (char-after (1- beg)) ?\()
'fboundp
(function (lambda (sym)
(or (boundp sym) (fboundp sym)
(symbol-plist sym))))))
(PC-not-minibuffer t))
(PC-do-completion nil beg end)))
(defun PC-complete-as-file-name ()
"Perform completion on file names preceding point.
Environment vars are converted to their values."
(interactive)
(let* ((end (point))
(beg (if (re-search-backward "[^\\][ \t\n\"\`\'][^ \t\n\"\`\']"
(point-min) t)
(+ (point) 2)
(point-min)))
(minibuffer-completion-table 'read-file-name-internal)
(minibuffer-completion-predicate "")
(PC-not-minibuffer t))
(goto-char end)
(PC-do-completion nil beg end)))
(defun PC-expand-many-files (name)
(save-excursion
(set-buffer (generate-new-buffer " *Glob Output*"))
(erase-buffer)
(shell-command (concat "echo " name) t)
(goto-char (point-min))
(if (looking-at ".*No match")
nil
(insert "(\"")
(while (search-forward " " nil t)
(delete-backward-char 1)
(insert "\" \""))
(goto-char (point-max))
(delete-backward-char 1)
(insert "\")")
(goto-char (point-min))
(let ((files (read (current-buffer))) (p nil))
(kill-buffer (current-buffer))
(or (equal completion-ignored-extensions PC-ignored-extensions)
(setq PC-ignored-regexp
(concat "\\("
(mapconcat
'regexp-quote
(setq PC-ignored-extensions
completion-ignored-extensions)
"\\|")
"\\)\\'")))
(setq p nil)
(while files
(or (string-match PC-ignored-regexp (car files))
(setq p (cons (car files) p)))
(setq files (cdr files)))
p))))
(defun PC-look-for-include-file ()
(if (string-match "[\"<]\\([^\"<>]*\\)[\">]?$" (buffer-file-name))
(let ((name (substring (buffer-file-name)
(match-beginning 1) (match-end 1)))
(punc (aref (buffer-file-name) (match-beginning 0)))
(path nil)
new-buf)
(kill-buffer (current-buffer))
(if (equal name "")
(save-excursion
(set-buffer (car (buffer-list)))
(save-excursion
(beginning-of-line)
(if (looking-at
"[ \t]*#[ \t]*include[ \t]+[<\"]\\(.+\\)[>\"][ \t]*[\n/]")
(setq name (buffer-substring (match-beginning 1)
(match-end 1))
punc (char-after (1- (match-beginning 1))))
(if (or (looking-at
"[ \t]*([ \t]*load[ \t]+\"\\([^\"]+\\)\"")
(looking-at
"[ \t]*([ \t]*load-library[ \t]+\"\\([^\"]+\\)\"")
(looking-at
"[ \t]*([ \t]*require[ \t]+'\\([^\t )]+\\)[\t )]"))
(progn
(setq name (buffer-substring (match-beginning 1)
(match-end 1))
punc ?\<
path load-path)
(if (string-match "\\.elc$" name)
(setq name (substring name 0 -1))
(or (string-match "\\.el$" name)
(setq name (concat name ".el")))))
(error "Not on an #include line"))))))
(or (string-match "\\.[[:alnum:]]+$" name)
(setq name (concat name ".h")))
(if (eq punc ?\<)
(let ((path (or path (PC-include-file-path))))
(while (and path
(not (file-exists-p
(concat (file-name-as-directory (car path))
name))))
(setq path (cdr path)))
(if path
(setq name (concat (file-name-as-directory (car path)) name))
(error "No such include file: <%s>" name)))
(let ((dir (save-excursion
(set-buffer (car (buffer-list)))
default-directory)))
(if (file-exists-p (concat dir name))
(setq name (concat dir name))
(error "No such include file: `%s'" name))))
(setq new-buf (get-file-buffer name))
(if new-buf
(set-buffer new-buf)
(setq new-buf (create-file-buffer name))
(set-buffer new-buf)
(erase-buffer)
(insert-file-contents name t))
t)
nil))
(defun PC-include-file-path ()
(or PC-include-file-path
(let ((env (getenv "INCPATH"))
(path nil)
pos)
(or env (error "No include file path specified"))
(while (setq pos (string-match ":[^:]+$" env))
(setq path (cons (substring env (1+ pos)) path)
env (substring env 0 pos)))
path)))
(defun PC-include-file-all-completions (file search-path &optional full)
"Return all completions for FILE in any directory on SEARCH-PATH.
If optional third argument FULL is non-nil, returned pathnames should be
absolute rather than relative to some directory on the SEARCH-PATH."
(setq search-path
(mapcar (lambda (dir)
(if dir (file-name-as-directory dir) default-directory))
search-path))
(if (file-name-absolute-p file)
(progn
(setq file (expand-file-name file))
(file-name-all-completions
(file-name-nondirectory file) (file-name-directory file)))
(let ((subdir (file-name-directory file))
(ndfile (file-name-nondirectory file))
file-lists)
(if subdir
(setq search-path
(mapcar (lambda (dir) (concat dir subdir))
search-path)
file ))
(while search-path
(let* ((dir (car search-path))
(subdir (if full dir subdir)))
(if (file-directory-p dir)
(progn
(setq file-lists
(cons
(mapcar (lambda (file) (concat subdir file))
(file-name-all-completions ndfile
(car search-path)))
file-lists))))
(setq search-path (cdr search-path))))
(let ((sorted (sort (apply 'nconc file-lists)
(lambda (x y) (not (string-lessp x y)))))
compressed)
(while sorted
(if (equal (car sorted) (car compressed)) nil
(setq compressed (cons (car sorted) compressed)))
(setq sorted (cdr sorted)))
compressed))))
(defun PC-read-include-file-name-internal (string dir action)
(if (string-match "<\\([^\"<>]*\\)>?$" string)
(let* ((name (substring string (match-beginning 1) (match-end 1)))
(str2 (substring string (match-beginning 0)))
(completion-table
(mapcar (function (lambda (x) (list (format "<%s>" x))))
(PC-include-file-all-completions
name (PC-include-file-path)))))
(cond
((not completion-table) nil)
((eq action nil) (try-completion str2 completion-table nil))
((eq action t) (all-completions str2 completion-table nil))
((eq action 'lambda)
(eq (try-completion str2 completion-table nil) t))))
(funcall PC-old-read-file-name-internal string dir action)))
(provide 'complete)