(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))
;;; 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))))
+
+
+