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 --
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.