fix completion bug, added namespace-based completion (forgot to commit these files last time)
svn: r6137
This commit is contained in:
parent
9bf2deaa49
commit
943967a4ce
|
@ -5,7 +5,7 @@
|
||||||
add-history add-history-bytes
|
add-history add-history-bytes
|
||||||
set-completion-function!)
|
set-completion-function!)
|
||||||
|
|
||||||
;; libtermcap maybe needed
|
;; libtermcap needed on some platforms
|
||||||
(define libtermcap (with-handlers ([exn:fail? void]) (ffi-lib "libtermcap")))
|
(define libtermcap (with-handlers ([exn:fail? void]) (ffi-lib "libtermcap")))
|
||||||
(define libreadline (ffi-lib "libreadline"))
|
(define libreadline (ffi-lib "libreadline"))
|
||||||
|
|
||||||
|
@ -42,25 +42,29 @@
|
||||||
(define add-history-bytes
|
(define add-history-bytes
|
||||||
(get-ffi-obj "add_history" libreadline (_fun _bytes -> _void)))
|
(get-ffi-obj "add_history" libreadline (_fun _bytes -> _void)))
|
||||||
|
|
||||||
;; Simple completion: use this with a (string -> list-of string) function that
|
;; Simple completion: use this with a (string -> (list-of string)) function
|
||||||
;; returns the completions for a given string. (should clean up bytes/string)
|
;; that returns the completions for a given string (can be used with other
|
||||||
|
;; input string types too, depending on the `type' argument). Use #f to remove
|
||||||
|
;; a completion function that was previously set.
|
||||||
(define set-completion-function!
|
(define set-completion-function!
|
||||||
(case-lambda
|
(case-lambda
|
||||||
[(func) (set-completion-function! _string)]
|
[(func) (set-completion-function! func _string)]
|
||||||
[(func type)
|
[(func type)
|
||||||
(if func
|
(if func
|
||||||
(set-ffi-obj! "rl_completion_entry_function" libreadline
|
(set-ffi-obj! "rl_completion_entry_function" libreadline
|
||||||
(_fun type _int -> _pointer)
|
(_fun type _int -> _pointer)
|
||||||
(completion-function func))
|
(completion-function func))
|
||||||
(set-ffi-obj! "rl_completion_entry_function" libreadline _pointer #f))]))
|
(set-ffi-obj! "rl_completion_entry_function" libreadline _pointer #f))]))
|
||||||
|
|
||||||
(define (completion-function func)
|
(define (completion-function func)
|
||||||
(let ([cur '()])
|
(let ([cur '()])
|
||||||
(define (complete str state)
|
(define (complete str state)
|
||||||
(if (zero? state)
|
(if (zero? state)
|
||||||
(begin (set! cur (func str)) (complete str 1))
|
(begin (set! cur (func str)) (complete #f 1))
|
||||||
(and (pair? cur)
|
(and (pair? cur)
|
||||||
(begin0 (malloc (add1 (bytes-length (car cur))) (car cur) 'raw)
|
(let* ([cur (begin0 (car cur) (set! cur (cdr cur)))]
|
||||||
(set! cur (cdr cur))))))
|
[cur (if (string? cur) (string->bytes/utf-8 cur) cur)])
|
||||||
|
(malloc (add1 (bytes-length cur)) cur 'raw)))))
|
||||||
complete))
|
complete))
|
||||||
|
|
||||||
(set-ffi-obj! "rl_readline_name" libreadline _bytes #"mzscheme")
|
(set-ffi-obj! "rl_readline_name" libreadline _bytes #"mzscheme")
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
(module pread mzscheme
|
(module pread mzscheme
|
||||||
(require (lib "readline.ss" "readline") (lib "file.ss"))
|
(require (lib "readline.ss" "readline") (lib "file.ss")
|
||||||
|
(lib "list.ss") (lib "string.ss"))
|
||||||
|
|
||||||
|
;; --------------------------------------------------------------------------
|
||||||
|
;; Configuration
|
||||||
|
|
||||||
;; configuration
|
|
||||||
(define current-prompt (make-parameter #"> "))
|
(define current-prompt (make-parameter #"> "))
|
||||||
(define show-all-prompts (make-parameter #t))
|
(define show-all-prompts (make-parameter #t))
|
||||||
(define max-history (make-parameter 100))
|
(define max-history (make-parameter 100))
|
||||||
|
@ -10,6 +13,40 @@
|
||||||
(provide current-prompt show-all-prompts
|
(provide current-prompt show-all-prompts
|
||||||
max-history keep-duplicates keep-blanks)
|
max-history keep-duplicates keep-blanks)
|
||||||
|
|
||||||
|
;; --------------------------------------------------------------------------
|
||||||
|
;; Simple namespace-based completion
|
||||||
|
|
||||||
|
;; efficiently convert symbols to byte strings
|
||||||
|
(define symbol->bstring
|
||||||
|
(let ([t (make-hash-table 'weak)])
|
||||||
|
(lambda (sym)
|
||||||
|
(or (hash-table-get t sym #f)
|
||||||
|
(let ([bstr (string->bytes/utf-8 (symbol->string sym))])
|
||||||
|
(hash-table-put! t sym bstr)
|
||||||
|
bstr)))))
|
||||||
|
|
||||||
|
;; get a list of byte strings for current bindings, cache last result
|
||||||
|
(define get-namespace-bstrings
|
||||||
|
(let ([last-syms #f] [last-bstrs #f])
|
||||||
|
(lambda ()
|
||||||
|
(let ([syms (namespace-mapped-symbols)])
|
||||||
|
(unless (equal? syms last-syms)
|
||||||
|
(set! last-syms syms)
|
||||||
|
(set! last-bstrs (sort! (map symbol->bstring syms) bytes<?)))
|
||||||
|
last-bstrs))))
|
||||||
|
|
||||||
|
(define (namespace-completion pat)
|
||||||
|
(let* ([pat (if (string? pat) (string->bytes/utf-8 pat) pat)]
|
||||||
|
[pat (regexp-quote pat)]
|
||||||
|
[pat (regexp-replace* #px#"(\\w)\\b" pat #"\\1\\\\w*")]
|
||||||
|
[pat (byte-pregexp (bytes-append #"^" pat))])
|
||||||
|
(filter (lambda (bstr) (regexp-match pat bstr))
|
||||||
|
(get-namespace-bstrings))))
|
||||||
|
|
||||||
|
(set-completion-function! namespace-completion)
|
||||||
|
|
||||||
|
|
||||||
|
;; --------------------------------------------------------------------------
|
||||||
;; History management
|
;; History management
|
||||||
|
|
||||||
(define local-history
|
(define local-history
|
||||||
|
@ -45,7 +82,8 @@
|
||||||
(let ([old (exit-handler)])
|
(let ([old (exit-handler)])
|
||||||
(lambda (v) (save-history) (old v))))
|
(lambda (v) (save-history) (old v))))
|
||||||
|
|
||||||
;; implement an input port that goes through readline
|
;; --------------------------------------------------------------------------
|
||||||
|
;; An input port that goes through readline
|
||||||
|
|
||||||
;; readline-prompt can be
|
;; readline-prompt can be
|
||||||
;; #f: no prompt (normal state),
|
;; #f: no prompt (normal state),
|
||||||
|
@ -106,6 +144,9 @@
|
||||||
(add1 left)]))])))
|
(add1 left)]))])))
|
||||||
(make-input-port 'readline reader #f close!)))
|
(make-input-port 'readline reader #f close!)))
|
||||||
|
|
||||||
|
;; --------------------------------------------------------------------------
|
||||||
|
;; Reading functions
|
||||||
|
|
||||||
;; like read-syntax, but waits until valid input is ready
|
;; like read-syntax, but waits until valid input is ready
|
||||||
(define read-complete-syntax
|
(define read-complete-syntax
|
||||||
(let ([leftovers '()]
|
(let ([leftovers '()]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user