X-Git-Url: http://git.kpe.io/?p=cl-readline.git;a=blobdiff_plain;f=readline.lisp;h=18b48c08e1a9240ba576cace714238999c1b5ed2;hp=4e8af262c09fe969a4d58d71974a6809c3b6ae1f;hb=HEAD;hpb=d9393c021044b97301b91b236473b65abab58951 diff --git a/readline.lisp b/readline.lisp index 4e8af26..18b48c0 100644 --- a/readline.lisp +++ b/readline.lisp @@ -1,5 +1,5 @@ ;; Copyright (c) 2003 Nikodemus Siivola -;; +;; ;; Permission is hereby granted, free of charge, to any person obtaining ;; a copy of this software and associated documentation files (the ;; "Software"), to deal in the Software without restriction, including @@ -7,10 +7,10 @@ ;; distribute, sublicense, and/or sell copies of the Software, and to ;; permit persons to whom the Software is furnished to do so, subject to ;; the following conditions: -;; +;; ;; The above copyright notice and this permission notice shall be included ;; in all copies or substantial portions of the Software. -;; +;; ;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. @@ -18,60 +18,126 @@ ;; CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ;; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - + (in-package readline) (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)) - - (defun use-cl-complete () + (setq pkg nil) + (c-clear-completions)) + + (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)) - (add-completion (string-downcase (string sym))))) + (do-symbols (sym (find-package package)) + (add-completion (string-downcase (string sym))))) (use-custom-complete) nil)) ;;; 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*) - (when (and history (not (string= "" str))) - (add-history str)) + (let* ((str (convert-and-free-foreign-string (c-readline c-prompt))) + (str2 (string-trim *whitespace* str))) + (when (and history (not (string= "" str2))) + (add-history str2)) 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)))) + +;; +;; Termios +;; + +(def-function "no_echo" + () + :module "cl-termios" + :returning :void) + +(def-function "restore_term" + () + :module "cl-termios" + :returning :void) + +(defmacro without-echo (&body forms) + `(unwind-protect + (progn + (no-echo) + ,@forms) + (restore-term)))