[plt-scheme] Bug in readline?

From: Dimitris Vyzovitis (vyzo at media.mit.edu)
Date: Thu Apr 26 13:22:12 EDT 2007

On Thu, 26 Apr 2007, Christophe Poucet wrote:

> Dear,
> I am used to using the nice readline wrapper script in mzscheme.  In fact, I
> have it in my .mzschemerc as suggested in a post I once found on the NG:
> (dynamic-require '(lib "rep.ss" "readline") #f)
> However it seems that this is affecting the outputting of text.  If I enable
> this in my .mzschemerc then all output (due to DISPLAY or PRINT) is delayed
> until mzscheme is finished.

Speaking of which, the custom completion function is broken -
set-completion-function! self loops. I posted a patch for it a while ago,
but it probably fell through the cracks.

Not sure if it is related to your problem (you don't happen to use a
custom completion, do you?), but here is a version of the
patch for current svn (6051).

-- vyzo
-------------- next part --------------
Index: collects/readline/mzrl.ss
--- collects/readline/mzrl.ss	(revision 6051)
+++ collects/readline/mzrl.ss	(working copy)
@@ -1,9 +1,12 @@
 (module mzrl mzscheme
 (require (lib "foreign.ss")) (unsafe!)
+(require (only (lib "string.ss" "srfi" "13") string-prefix?)
+         (only (lib "list.ss" "srfi" "1") filter-map))
 (provide readline readline-bytes
          add-history add-history-bytes
-         set-completion-function!)
+         set-completion-function!
+         default-completion default-word-break)
 ;; libtermcap maybe needed
 (define libtermcap  (with-handlers ([exn:fail? void]) (ffi-lib "libtermcap")))
@@ -43,26 +46,44 @@
   (get-ffi-obj "add_history" libreadline (_fun _bytes -> _void)))
 ;; Simple completion: use this with a (string -> list-of string) function that
-;; returns the completions for a given string.  (should clean up bytes/string)
+;; returns the completions for a given string.
 (define set-completion-function!
-    [(func) (set-completion-function! _string)]
-    [(func type)
+    [(func) (set-completion-function! func default-word-break)]
+    [(func wbreak)
      (if func
-       (set-ffi-obj! "rl_completion_entry_function" libreadline
-                     (_fun type _int -> _pointer)
-                     (completion-function func))
+       (begin
+         (set-ffi-obj! "rl_completion_entry_function" libreadline
+                       (_fun _bytes _int -> _pointer)
+                       (completion-function func))
+         (set-ffi-obj! "rl_basic_word_break_characters" libreadline
+                       _bytes (string->bytes/utf-8 wbreak)))
        (set-ffi-obj! "rl_completion_entry_function" libreadline _pointer #f))]))
+(define (string->raw str)
+  (let ((bs (string->bytes/utf-8 str)))
+    (malloc (add1 (bytes-length bs)) bs 'raw)))
 (define (completion-function func)
   (let ([cur '()])
     (define (complete str state)
       (if (zero? state)
-        (begin (set! cur (func str)) (complete str 1))
+        (begin (set! cur (func (bytes->string/utf-8 str))) (complete #f 1))
         (and (pair? cur)
-             (begin0 (malloc (add1 (bytes-length (car cur))) (car cur) 'raw)
+             (begin0 (string->raw (car cur)) 
                (set! cur (cdr cur))))))
+(define default-word-break " \t\n\"([{'`,")
+(define (default-completion text)
+  (filter-map (lambda (sym) 
+                (let ((str (symbol->string sym)))
+                  (and (string-prefix? text str) str)))
+              (namespace-mapped-symbols)))
+(set-completion-function! default-completion default-word-break)
 (set-ffi-obj! "rl_readline_name" libreadline _bytes #"mzscheme")
 ;; need to capture the real input port below

Posted on the users mailing list.