X-Git-Url: http://git.kpe.io/?a=blobdiff_plain;ds=sidebyside;f=readline.lisp;h=95c460f235689d2629427a40d1f57de72a0a39b2;hb=1640f89acdd00711a4b1dd29d53a3bf4168da433;hp=4e8af262c09fe969a4d58d71974a6809c3b6ae1f;hpb=d9393c021044b97301b91b236473b65abab58951;p=cl-readline.git diff --git a/readline.lisp b/readline.lisp index 4e8af26..95c460f 100644 --- a/readline.lisp +++ b/readline.lisp @@ -23,25 +23,67 @@ (defvar *whitespace* (list #\Space #\Tab)) -(let (cl-complete) +(defun convert-and-free-foreign-string (foreign-string) + (let ((lisp-string (convert-from-foreign-string foreign-string))) + (free-foreign-object foreign-string) + lisp-string)) + +(defmacro ignore-end-of-file (&body forms) + `(catch 'end-of-file + (handler-bind ((end-of-file (lambda (e) + (declare (ignore e)) + (throw 'end-of-file nil)))) + ,@forms))) + +(def-function ("readline" c-readline) + ((prompt :cstring)) + :module "readline" + :returning (* :char)) + +(def-function ("add_history" c-add-history) + ((str :cstring)) + :module "readline" + :returning :void) + +(def-function ("add_completion" c-add-completion) + ((str :cstring)) + :module "cl-readline" + :returning :int) + +(def-function ("clear_completions" c-clear-completions) + () + :module "cl-readline" + :returning :void) + +(def-function "use_custom_complete" + () + :module "cl-readline" + :returning :void) + +(def-function "use_filename_complete" + () + :module "cl-readline" + :returning :void) + +(let (pkg) (defun add-completion (string) "Add STRING as a custom-completion." - (setq cl-complete nil) + (setq pkg nil) (with-cstring (c-str string) - (= 1 (libreadline::add-completion c-str)))) + (= 1 (c-add-completion c-str)))) (defun clear-completions () "Clear all custom-completions." - (setq cl-complete nil) - (libreadline::clear-completions)) + (setq pkg nil) + (c-clear-completions)) - (defun use-cl-complete () + (defun use-package-complete (package) "Load symbols in package CL-USER as custom-completions." - (unless cl-complete - (setq cl-complete t) + (unless (eql pkg package) + (setq pkg package) (clear-completions) - (do-symbols (sym (find-package :cl-user)) + (do-symbols (sym (find-package package)) (add-completion (string-downcase (string sym))))) (use-custom-complete) nil)) @@ -49,29 +91,32 @@ ;;; Everything that affects the custom-completion collection goes ;;; above. -(defun use-custom-complete () - "Use custom-competions." - (libreadline::use-custom-complete) - nil) - -(defun use-filename-complete () - "Use default completion system. (filename)" - (libreadline::use-filename-complete) - nil) (defun add-history (string) "Add STRING to history." (with-cstring (c-string string) - (libreadline::add-history c-string)) + (c-add-history c-string)) string) (defun readline (&key (prompt "") (history t)) "Read a line from current TTY with line-editing." (with-cstring (c-prompt prompt) - (let* ((char* (libreadline::readline c-prompt)) - (str (string-trim *whitespace* - (convert-from-foreign-string char*)))) - (free-foreign-object char*) + (let ((str (string-trim *whitespace* + (convert-and-free-foreign-string (c-readline c-prompt))))) (when (and history (not (string= "" str))) (add-history str)) str))) + +(defun readexpr (&key (primary-prompt "=> ") (secondary-prompt "| ") (history t)) + "Read an expression from current TTY with line-editing." + (let (expr) + (do* ((str (readline :prompt primary-prompt :history history) + (readline :prompt secondary-prompt :history history)) + (input str (concatenate 'string input " " str))) + ((ignore-end-of-file + (setq expr (with-input-from-string (in input) + (read in nil nil)))) + expr)))) + + +