Ah gotcha. Thanks! On Mon, Aug 19, 2019 at 11:01 PM Mark H Weaver <m...@netris.org> wrote:
> 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 >