update watch file
[cl-readline.git] / readline.lisp
index 2685c4b374367145cb37c3ad5b923446d84e6604..18b48c08e1a9240ba576cace714238999c1b5ed2 100644 (file)
@@ -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.
 ;; 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-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 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)
-
-  (defun add-history (string)
-    "Add STRING to history."
-    (with-cstring (c-string string)
-      (libreadline::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 ((str (string-trim
-                 *whitespace*
-                 (convert-from-cstring (libreadline::readline c-prompt)))))
-       (when (and history (not (string= "" str)))
-         (add-history str))))))
+    nil))
+
+;;; Everything that affects the custom-completion collection goes
+;;; above.
+
+
+(defun add-history (string)
+  "Add STRING to history."
+  (with-cstring (c-string 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* ((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)))