tags 37086 + notabug close 37086 thanks Hi Matthew,
Matthew Henry <mcthe...@gmail.com> writes: > Seen in: guile (GNU Guile) 2.2.4 > > When using the with-readline-completion-function, the passed readline > uses the default (apropos) completion function instead of the one > provided to with-readline-completion-function. > > I believe that this is because root/guile-readline/ice-9/readline.scm > has defined with-readline-completion-function as a function instead of > as a macro. The readline provided in thunk is executed before the > body of with-readline-completion-function executes and overrides > *readline-completion-function*. > > As an aside, I think the API would be better if the completion > function could be provided to readline directly. > > Attached is a sample program. > > Below is sample output of a run of the attached program. You can see > that it's autocompleting Guile functions and variables (the default > apropos completion) rather than the provided one which should have had > only 3 options with just one starting in "th". > > ;;;;;;;;;;;;;;;;;;;;;;;;;;; > Prompt: > Display all 1859 possibilities? (y or n) > Prompt: th > the-eof-object the-scm-module thread-exited? thunk? > the-root-module thread? throw > Prompt: th > > (use-modules (ice-9 readline)) > > (with-readline-completion-function > (make-completion-function '("one" "two" "three")) > (readline "Prompt: ")) The problem is that 'with-readline-completion-function' expects a "thunk" as the second argument. A "thunk" is a procedure that takes no arguments. Typically this means that you wrap the relevant code within (lambda () ...), like this: (use-modules (ice-9 readline)) (with-readline-completion-function (make-completion-function '("one" "two" "three")) (lambda () (readline "Prompt: "))) > I'm early in my Scheme journey, but here's a suggested fix: > > (define-syntax-rule (with-readline-completion-function completer expr ...) > "With @var{completer} as readline completion function, call @var{expr ...}." > (let ((old-completer *readline-completion-function*)) > (dynamic-wind > (lambda () > (set! *readline-completion-function* completer)) > (lambda () expr ...) > (lambda () > (set! *readline-completion-function* old-completer))))) > > (export with-readline-completion-function) This is fine, but it's a different API. It's true that you need to use a macro if you want to avoid wrapping the body within (lambda () ...), but just like 'dynamic-wind' itself, 'with-readline-completion-function' was designed to be an ordinary procedure that accepts the body expression(s) as a THUNK. Happy hacking! Mark