Re: [Ilisp-help] patcher for completer: please incorporate
"aardvark llama" <[email protected]>
| Newsgroups | gmane.lisp.ilisp.devel |
|---|---|
| Message-ID | <[email protected]> |
The patch from Ben Wing does not apply cleanly to the cvs sources. Please find attached a cleaned up version of this for testing against emacs 20.7. Best Regards, Will _________________________________________________________________ Get your FREE download of MSN Explorer at http://explorer.msn.com/intl.asp.
completer.patch
(application/octet-stream, 16.7 KB)
Index: completer.el
===================================================================
RCS file: /cvsroot/ilisp/ILISP/completer.el,v
retrieving revision 1.2
diff -u -r1.2 completer.el
--- completer.el 25 Oct 2001 19:12:38 -0000 1.2
+++ completer.el 26 Mar 2002 15:44:37 -0000
@@ -121,6 +121,21 @@
(defvar completer-path-cache nil
"Cache of (path . choices) for completer.")
+(defvar completer-path-separator-string
+ (if (eq system-type 'windows-nt) "\\" "/"))
+
+(defvar completer-path-separator-regexp
+ (if (eq system-type 'windows-nt) "[/\\]" "/"))
+
+(defvar completer-path-delimiter-list
+ (if (eq system-type 'windows-nt) '(?\\ ?/) '(?/)))
+
+(defvar completer-path-separator-regexp-inside-brackets
+ (if (eq system-type 'windows-nt) "/\\" "/"))
+
+(defvar completer-dot-dot-list
+ (if (eq system-type 'windows-nt) '("../" "..\\") '("../")))
+
(defvar completer-string nil "Last completer string.")
(defvar completer-table nil "Last completer table.")
(defvar completer-pred nil "Last completer pred.")
@@ -154,15 +169,15 @@
(delete-region point end)
(if (and quit-flag
;;(not (eq 'lucid-19 ilisp-emacs-version-id))
- (not (string-match "Lucid" emacs-version))
+ (not (string-match "XEmacs" emacs-version))
)
(setq quit-flag nil
unread-command-char 7))))
;;;
(defun completer-deleter (regexp choices &optional keep)
- "Destructively remove strings that match REGEXP in CHOICES.
-Return the modified list. If optional KEEP, then keep entries that
+ "Destructively remove strings that match REGEXP in CHOICES and
+return the modified list. If optional KEEP, then keep entries that
match regexp."
(let* ((choiceb choices)
choicep)
@@ -186,8 +201,9 @@
;;;%%Regexp
(defun completer-regexp (string delimiters any)
- "Convert STRING into a regexp with words delimited by chars in DELIMITERS.
-Any delimiter in STRING that is the same as ANY will match any delimiter."
+ "Convert STRING into a regexp with words delimited by characters in
+DELIMITERS. Any delimiter in STRING that is the same as ANY will
+match any delimiter."
(let* ((delimiter-reg (concat "[" delimiters "]"))
(limit (length string))
(pos 0)
@@ -221,8 +237,8 @@
;;;%Matcher
(defun completer-matches (string choices delimiters any)
- "Return STRING's matches in CHOICES.
-DELIMITERS and the wildcard ANY are used to segment the strings."
+ "Return STRING's matches in CHOICES using DELIMITERS and wildcard
+ANY to segment the strings."
(let* ((regexp (concat "[" delimiters "]"))
(from nil)
(to 0)
@@ -270,8 +286,8 @@
;;;
(defun completer-choice (string choices delimiters use-words)
- "Return a list with best match of STRING in CHOICES and T if it is unique.
-DELIMITERS are used to separate words. A match is unique if it is the only
+ "Return the best match of STRING in CHOICES with DELIMITERS between
+words and T if it is unique. A match is unique if it is the only
possibility or when USE-WORDS the only possibility with the same
number of words. The shortest string of multiple possibilities will be
the best match."
@@ -321,13 +337,13 @@
(let ((last (1- (length string)) )
(match 0)
(end 0))
- (while (and (setq match (string-match "/" string end)) (< match last))
+ (while (and (setq match (string-match completer-path-separator-regexp string end)) (< match last))
(setq end (1+ match)))
end))
;;;
(defun completer-match-record (string matches delimiters any dir mode)
- "Return (match lcs choices unique) for STRING in MATCHES.
+ "Return (match lcs choices unique) for STRING in MATCHES with
DELIMITERS or ANY wildcards and DIR if a filename when in MODE."
(let ((pattern (if dir
(substring string (completer-last-component string))
@@ -355,7 +371,7 @@
;;;%%Complete file
(defun completer-extension-regexp (extensions)
- "Return a regexp that matches a string ending with any string in EXTENSIONS."
+ "Return a regexp that matches to a string that ends with any string from EXTENSIONS list."
(concat "\\(" (mapconcat 'regexp-quote extensions "\\|") "\\)\\'"))
;;;
@@ -366,7 +382,8 @@
;;;
(defun completer-cache (path pred words any mode)
- "Check to see if PATH is in path cache with PRED, WORDS, ANY and MODE."
+ "Check to see if PATH is in path cache with PRED, WORDS, ANY and
+MODE."
(let* ((last nil)
(ptr completer-path-cache)
(size 0)
@@ -392,7 +409,8 @@
mode t)))
(if (and (or (car (cdr (cdr (cdr choices))))
(string= path (car choices)))
- (eq (elt (car choices) (1- (length (car choices)))) ?/))
+ (memq (elt (car choices) (1- (length (car choices))))
+ completer-path-delimiter-list))
(progn
(if (>= size completer-cache-size) (rplacd last nil))
(setq completer-path-cache
@@ -401,28 +419,48 @@
;;;
(defun completer-file (string pred words any mode)
- "Return (match common-substring matches unique-p) for STRING.
-It uses 'READ-FILE-NAME-INTERNAL' for choices that pass PRED using WORDS to
+ "Return (match common-substring matches unique-p) for STRING using
+read-file-name-internal for choices that pass PRED using WORDS to
delimit words. Optional ANY is a delimiter that matches any of the
delimiters in WORD. If optional MODE is nil or 'help then possible
matches will always be returned."
+ ;; canonicalize slashes under windows-nt for proper completion
+ (if (eq system-type 'windows-nt)
+ (setq string (replace-in-string string "/" "\\\\")))
(let* ((case-fold-search completion-ignore-case)
(last (and (eq mode 'exit-ok) (completer-last-component string)))
(position
- ;; Special hack for CMU RFS filenames
- (if (string-match "^/\\.\\./[^/]*/" string)
- (match-end 0)
- (string-match "[^~/]" string)))
+ ;; find beginning of first directory component.
+ (cond
+ ;; CMU RFS filenames like /../computername/foo/bar.c
+ ((string-match "^/\\.\\./[^/]*/" string)
+ (match-end 0))
+ ;; windows-nt filenames like \\computername\foo\bar.c, or
+ ;; cygwin filenames like //d/foo/bar.c
+ ((and (memq system-type '(windows-nt cygwin32))
+ (string-match "[/\\][/\\][^/\\]*[/\\]" string))
+ (match-end 0))
+ ;; windows-nt filenames like c:\foo\bar.c or c:bar.c
+ ((and (eq system-type 'windows-nt)
+ (string-match "[A-Za-z]:[/\\]?" string))
+ (match-end 0))
+ (t
+ ;; normal absolute or relative names, or names beginning
+ ;; with ~/
+ (string-match
+ (concat "[^~" completer-path-separator-regexp-inside-brackets
+ "]") string))))
(new (substring string 0 position))
(user (if (string= new "~")
(setq new (file-name-directory (expand-file-name new)))))
- (words (concat words "/"))
+ (words (concat words completer-path-separator-regexp-inside-brackets))
(len (length string))
(choices nil)
end
(old-choices (list nil nil nil nil)))
(while position
- (let* ((begin (string-match "/" string position))
+ (let* ((begin (string-match completer-path-separator-regexp string
+ position))
(exact-p nil))
(setq end (if begin (match-end 0))
choices
@@ -434,10 +472,11 @@
(let* ((choices
(all-completions new 'read-file-name-internal))
(choicep choices))
- (if (string= (car choicep) "../")
+ (if (member (car choicep) completer-dot-dot-list)
(cdr (cdr choicep))
(while (cdr choicep)
- (if (string= (car (cdr choicep)) "../")
+ (if (member (car (cdr choicep))
+ completer-dot-dot-list)
(rplacd choicep nil))
(setq choicep (cdr choicep)))
choices))
@@ -463,7 +502,11 @@
(setq old-choices
(let* ((lcs (car (cdr choices)))
(matches (car (cdr (cdr choices))))
- (slash (and lcs (string-match "/$" lcs))))
+ (slash
+ (and lcs
+ (string-match
+ (concat completer-path-separator-regexp "$")
+ lcs))))
(list nil
(if slash (substring lcs 0 slash) lcs)
(if (and (cdr matches)
@@ -522,13 +565,13 @@
;;;%%Completer
(defun completer (string table pred words
&optional any mode file-p)
- "Return (match common-substring matches unique-p) for STRING in TABLE.
-The choices must also pass PRED using WORDS to delimit words. If the
-flag 'COMPLETER-COMPLETE-FILENAMES' is T and the table is
-'READ-FILE-NAME-INTERNAL', then filename components will be individually
-expanded. Optional ANY is a delimiter that can match any delimiter in
-WORDS. Optional MODE is nil for complete, 'help for help and 'exit
-for exit."
+ "Return (match common-substring matches unique-p) for STRING in
+TABLE for choices that pass PRED using WORDS to delimit words. If the
+flag completer-complete-filenames is T and the table is
+read-file-name-internal or read-directory-name-internal, then filename
+components will be individually expanded. Optional ANY is a delimiter
+that can match any delimiter in WORDS. Optional MODE is nil for
+complete, 'help for help and 'exit for exit."
(if (and (stringp completer-string)
(string= string completer-string)
(eq table completer-table)
@@ -545,9 +588,12 @@
completer-mode mode
completer-result
(if (and completer-complete-filenames
- (not file-p) (eq table 'read-file-name-internal))
+ (not file-p) (memq table '(read-file-name-internal
+ read-directory-name-internal)))
(completer-file string pred words any mode)
- (let* ((file-p (or file-p (eq table 'read-file-name-internal)))
+ (let* ((file-p (or file-p
+ (memq table '(read-file-name-internal
+ read-directory-name-internal))))
(case-fold-search completion-ignore-case)
(pattern (concat "[" words "]"))
(component (if file-p (completer-last-component string)))
@@ -559,8 +605,11 @@
;; Handle environment variables
(let ((match
(getenv (substring string 1
- (string-match "/" string)))))
- (if match (setq match (concat match "/")))
+ (string-match completer-path-separator-regexp string)))))
+ (if match
+ (setq match
+ (concat match
+ completer-path-separator-string)))
(list match match (list match) match))
(let* ((choices
(all-completions
@@ -579,13 +628,11 @@
;;;%%Display choices
(defun completer-display-choices (choices &optional match message end
display)
- "Display the list of possible CHOICES.
-MATCH, MESSAGE, END and DISPLAY are used optionally. If MATCH is
-non-nil, it will be flagged as the best guess. If there are no
-choices, display MESSAGE. END is where to put temporary messages. If
-DISPLAY is present then it will be called on each possible completion
-and should return a string."
-
+ "Display the list of possible CHOICES with optional MATCH, MESSAGE,
+END and DISPLAY. If MATCH is non-nil, it will be flagged as the best
+guess. If there are no choices, display MESSAGE. END is where to put
+temporary messages. If DISPLAY is present then it will be called on
+each possible completion and should return a string."
(if choices
(with-output-to-temp-buffer "*Completions*"
(if (cdr choices)
@@ -614,15 +661,14 @@
;;;%%Goto
(defun completer-goto (match lcs choices unique delimiters words
&optional mode display)
- "Go to the part of the string that disambiguates CHOICES.
-MATCH is the best match, LCS is the longest common substring of all
+ "MATCH is the best match, LCS is the longest common substring of all
of the matches. CHOICES is a list of the possibilities, UNIQUE
indicates if MATCH is unique. DELIMITERS are possible bounding
characters for the completion region. WORDS are the characters that
delimit the words for partial matches. Replace the region bounded by
delimiters with the match if unique and the lcs otherwise unless
optional MODE is 'help. Then go to the part of the string that
-disambiguates CHOICES using WORDS to separate words and display the
+disambiguates choices using WORDS to separate words and display the
possibilities if the string was not extended. If optional DISPLAY is
present then it will be called on each possible completion and should
return a string."
@@ -631,7 +677,9 @@
(start (car region))
(end (cdr region))
(string (buffer-substring start end))
- (file-p (string-match "[^ ]*\\(~\\|/\\|$\\)" string))
+ (file-p (string-match (if (eq system-type 'windows-nt)
+ "[^ ]*\\(~\\|/\\|\\\\\\|\\|$\\)"
+ "[^ ]*\\(~\\|/\\|$\\)") string))
(no-insert (eq mode 'help))
(message t)
(new (not (string= (buffer-substring start (point)) lcs))))
@@ -648,7 +696,7 @@
;;Not unique
(if lcs
(let* ((regexp
- (concat "[" words (if file-p "/") "]"))
+ (concat "[" words (if file-p completer-path-separator-regexp-inside-brackets) "]"))
(words (completer-words regexp lcs))
point)
;; Go to where its ambiguous
@@ -683,7 +731,7 @@
(if file-p
(progn
(if (not (= (point) end)) (forward-char 1))
- (if (not (save-excursion (re-search-forward "/" end t)))
+ (if (not (save-excursion (re-search-forward completer-path-separator-regexp end t)))
(goto-char end))))
(if message
(progn
@@ -711,8 +759,8 @@
;;;%%Undo
(defun completer-insert (match delimiters &optional buffer undo)
- "Replace the region bounded with characters in DELIMITERS by MATCH.
-Then save it so that it can be restored by completer-undo."
+ "Replace the region bounded with characters in DELIMITERS by MATCH
+and save it so that it can be restored by completer-undo."
(let* ((region (completer-region delimiters))
(start (car region))
(end (cdr region)))
@@ -743,8 +791,13 @@
resulting string."
(save-excursion
(goto-char (point-max))
- (if (and (eq minibuffer-completion-table 'read-file-name-internal)
- (re-search-backward "//\\|/~\\|.\\$" (minibuffer-prompt-end) t))
+ (if (and (memq minibuffer-completion-table
+ '(read-file-name-internal
+ read-directory-name-internal))
+ (re-search-backward
+ (if (memq system-type '(windows-nt cygwin32))
+ ; // is meaningful
+ "/~\\|.\\$" "//\\|/~\\|.\\$") nil t))
(delete-region (minibuffer-prompt-end) (1+ (point))))
(buffer-substring (minibuffer-prompt-end) (point-max))))
@@ -762,15 +815,17 @@
(let ((string (completer-minibuf-string)))
(or
(not (string-match
- (concat "[" completer-words "/~]")
+ (concat "[" completer-words
+ completer-path-separator-regexp-inside-brackets "~]")
string))
(condition-case ()
(let ((completion
(try-completion string
minibuffer-completion-table
minibuffer-completion-predicate)))
- (if (eq minibuffer-completion-table
- 'read-file-name-internal)
+ (if (memq minibuffer-completion-table
+ '(read-file-name-internal
+ read-directory-name-internal))
;; Directories complete as themselves
(and completion
(or (not (string= string completion))
@@ -784,8 +839,8 @@
;;;
(defun completer-minibuf (&optional mode)
- "Partial completion of minibuffer expressions.
-Optional MODE is (quote help) for help and (quote exit) for exit.
+ "Partial completion of minibuffer expressions. Optional MODE is
+'help for help and 'exit for exit.
If what has been typed so far matches any possibility normal
completion will be done. Otherwise, the string is considered to be a
@@ -798,7 +853,7 @@
Examples:
a-f auto-fill-mode
r-e rmail-expunge
-b--d *begining-of-defun or byte-recompile-directory
+b--d *beginning-of-defun or byte-recompile-directory
by d *byte-recompile-directory if completer-any-delimiter is \" \"
~/i.e *~/ilisp.el or ~/il-el.el or ~/ilisp.elc
/u/mi/ /usr/misc/"
@@ -838,7 +893,6 @@
(defvar completer-old-completer
(lookup-key minibuffer-local-must-match-map "\t")
"Old binding of TAB in minibuffer completion map.")
-
(defun completer-complete ()
"Partial completion minibuffer-complete.
See completer-minibuf for more information."
@@ -974,8 +1028,8 @@
;;;%lisp-complete-symbol
(defun lisp-complete-symbol (&optional mode)
- "Perform partial completion on Lisp symbol preceding point.
-That symbol is compared against the symbols that exist and any additional
+ "Perform partial 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
@@ -1035,5 +1089,3 @@
;;;%Hooks
(provide 'completer)
(run-hooks 'completer-load-hook)
-
-;;; end of file -- completer.el --