[slime-devel] ilisp-style symbol completion patch

xach at xach.com xach at xach.com
Wed Nov 26 22:39:59 UTC 2003


Attached is a patch that, along with completer.el from ILISP, adds
partial ILISP-style symbol completion to SLIME.

Zach

-------------- next part --------------
? completer.el
Index: slime.el
===================================================================
RCS file: /project/slime/cvsroot/slime/slime.el,v
retrieving revision 1.110
diff -u -r1.110 slime.el
--- slime.el	25 Nov 2003 21:28:23 -0000	1.110
+++ slime.el	26 Nov 2003 22:36:30 -0000
@@ -58,6 +58,7 @@
 (require 'hideshow)
 (require 'hyperspec)
 (require 'font-lock)
+(require 'completer)
 (when (featurep 'xemacs)
   (require 'overlay))
 (eval-when (compile load eval)
@@ -2389,33 +2390,27 @@
   ;; NB: It is only the name part of the symbol that we actually want
   ;; to complete -- the package prefix, if given, is just context.
   (interactive)
-  (let* ((end (point))
+  (let* ((end (slime-symbol-end-pos))
          (beg (slime-symbol-start-pos))
          (prefix (buffer-substring-no-properties beg end))
-         (completions (slime-completions prefix))
-         (completions-alist (slime-bogus-completion-alist completions))
-         (completion (try-completion prefix completions-alist nil)))
-    (cond ((eq completion t)
-           (message "[Sole completion]")
-           (slime-complete-restore-window-configuration))
-          ((null completion)
-           (message "Can't find completion for \"%s\"" prefix)
-           (ding)
-           (slime-complete-restore-window-configuration))
-          ((not (string= prefix completion))
-           (delete-region beg end)
-           (insert-and-inherit completion)
-           (cond ((null (cdr completions))
-                  (slime-complete-restore-window-configuration))
-                 (t (slime-complete-delay-restoration))))
-          (t
-           (message "Making completion list...")
-           (let ((list (all-completions prefix completions-alist nil)))
+         (completions (slime-completions prefix)))
+    (destructuring-bind (match common-substring matches unique-p)
+        (completer prefix completions nil "-")
+      (cond ((eq unique-p t)
+             (message "[Sole completion]")
+             (delete-region beg end)
+             (insert match)
+             (slime-complete-restore-window-configuration))
+            ((null match)
+             (message "Can't find completion for \"%s\"" prefix)
+             (ding)
+             (slime-complete-restore-window-configuration))
+            (t 
              (slime-complete-maybe-save-window-configuration)
-             (with-output-to-temp-buffer "*Completions*"
-               (display-completion-list list))
-             (slime-complete-delay-restoration))
-           (message "Making completion list...done")))))
+             (completer-display-choices completions)
+             (slime-complete-delay-restoration)
+             (completer-goto match common-substring 
+                             matches unique-p "^ \t\n\('\"#.\)<>" "-"))))))
 
 (defun slime-completing-read-internal (string default-package flag)
   ;; We misuse the predicate argument to pass the default-package.
@@ -2471,6 +2466,11 @@
     (backward-sexp 1)
     (skip-syntax-forward "'")
     (point)))
+
+(defun slime-symbol-end-pos ()
+  (save-excursion
+    (skip-syntax-forward "_")
+    (min (1+ (point)) (point-max))))
 
 (defun slime-bogus-completion-alist (list)
   "Make an alist out of list.
Index: swank.lisp
===================================================================
RCS file: /project/slime/cvsroot/slime/swank.lisp,v
retrieving revision 1.65
diff -u -r1.65 swank.lisp
--- swank.lisp	24 Nov 2003 03:23:32 -0000	1.65
+++ swank.lisp	26 Nov 2003 22:36:30 -0000
@@ -473,7 +473,7 @@
                          (find-package (case-convert n))
                          *buffer-package* ))))
       (flet ((symbol-matches-p (symbol)
-               (and (string-prefix-p name (symbol-name symbol))
+               (and (compound-string-match name (symbol-name symbol))
                     (or (or internal-p (null package-name))
                         (symbol-external-p symbol package)))))
         (when package
@@ -533,6 +533,42 @@
 \(This includes the case where S1 is equal to S2.)"
   (and (<= (length s1) (length s2))
        (string-equal s1 s2 :end2 (length s1))))
+
+(defun subword-prefix-p (s1 s2 &key (start1 0) end1 (start2 0))
+  "Return true if the subsequence in S1 bounded by START1 and END1
+is found in S1 at START1."
+  (let ((end2 (min (length s2)
+                   (+ start2 (- (or end1 (length s1))
+                                start1)))))
+    (string-equal s1 s2
+                  :start1 start1 :end1 end1
+                  :start2 start2 :end2 end2)))
+
+(defun word-points (string)
+  (declare (string string))
+  (loop for pos = -1 then (position #\- string :start (1+ pos))
+        while pos
+        collect (1+ pos)))
+
+(defun compound-string-match (string1 string2)
+  "Return true if STRING1 is a prefix of STRING2, or if STRING1
+represents a pattern of prefixes and delimiters matching full strings
+and delimiters in STRING2.
+Examples:
+\(compound-string-match \"foo\" \"foobar\") => t
+\(compound-string-match \"m-v-b\" \"multiple-value-bind\") => t
+\(compound-string-match \"m-v-c\" \"multiple-value-bind\") => NIL"
+  (when (<= (length string1) (length string2))
+    (let ((s1-word-points (word-points string1))
+          (s2-word-points (word-points string2)))
+      (when (<= (length s1-word-points) (length s2-word-points))
+        (loop for (start1 end1) on s1-word-points
+              for start2 in s2-word-points
+              always (subword-prefix-p string1 string2
+                                       :start1 start1
+                                       :end1 (and end1 (1- end1))
+                                       :start2 start2))))))
+
 
 
 ;;;; Documentation


More information about the slime-devel mailing list