[plt-scheme] Bug in readline?
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!
(case-lambda
- [(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))))))
complete))
+(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