From: Kevin M. Rosenberg Date: Fri, 9 May 2003 03:46:13 +0000 (+0000) Subject: r4886: Automatic commit for debian_version_0_2_0-1 X-Git-Tag: debian-0.2.0-4~14 X-Git-Url: http://git.kpe.io/?p=cl-readline.git;a=commitdiff_plain;h=1640f89acdd00711a4b1dd29d53a3bf4168da433 r4886: Automatic commit for debian_version_0_2_0-1 --- diff --git a/Makefile b/Makefile index d1eb82e..9a68259 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,9 @@ -VERSION=0.1 -NAME=cl-readline-$(VERSION) +basename:=cl-readline -all: libreadline-cl.o +all: $(basename).o all: - gcc -fPIC -DPIC -c libreadline-cl.c -o libreadline-cl.o - gcc -shared libreadline-cl.o -lreadline -o libreadline-cl.so + gcc -fPIC -DPIC -c $(basename).c -o $(basename).o + gcc -shared $(basename).o -lreadline -o $(basename).so diff --git a/README b/README index d71dd79..2f536ac 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -CL-READLINE 0.1.1 +CL-READLINE 0.2.0 CL-READLINE is a simple UFFI-based wrapper for the GNU Readline library. @@ -26,6 +26,18 @@ Functions: not. Note that history is available in any case. Currently there is no way to erase history. + READEXPR &key primary-prompt secondary-prompt history + + primary-prompt -- a string (default "=> ") + secondary-prompt -- a string (default "| ") + history -- a boolean (default t) + + As READLINE, except reads enough lines to complete a lisp + expression. + + Primary-prompt controls the prompt of the first line, + secondary prompt the prompt of the rest of the lines. + ADD-HISTORY string Adds the given string to history. @@ -34,10 +46,10 @@ Functions: Use the Readline's default filename-completion system. - USE-CL-COMPLETE + USE-PACKAGE-COMPLETE name - Insert symbols in CL-USER to the custom completion pool, - and start using the custom completion system. + Insert symbols in package designated by NAME to the custom + completion pool, and start using the custom completion system. USE-CUSTOM-COMPLETE diff --git a/cl-readline.c b/cl-readline.c new file mode 100644 index 0000000..63874f6 --- /dev/null +++ b/cl-readline.c @@ -0,0 +1,128 @@ +/* + * 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 + * without limitation the rights to use, copy, modify, merge, publish, + * 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. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * 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. + */ + +#include +#include +#include + +typedef struct { + char * str; + void * next; +} +node_t; + +node_t * collection = NULL; + +int +add_completion (char * str) +{ + node_t * tmp = collection; + node_t * pre = NULL; + node_t * node; + while (tmp) + { + int cmp = strcmp (str, tmp->str); + if (0 == cmp) + return 1; + + if (0 < cmp) + break; + + /* printf ("-skip- (%s)\n", tmp->str);*/ + + pre = tmp; + tmp = tmp->next; + } + + node = malloc (sizeof (node_t)); + if (!node) + return 0; + + node->next = tmp; + node->str = strdup (str); + + if (! pre) + collection = node; + else + pre->next = node; + + return 1; +} + +node_t * root = NULL; + +char * +custom_completer (const char * str, int target) +{ + size_t len = strlen (str); + if (0 == target) + { + root = NULL; + node_t * tmp = collection; + while (len && tmp) + { + if (0 == strncmp (str, tmp->str, len)) + { + root = tmp; + return strdup (root->str); + } + else + tmp = tmp->next; + } + return (char *)NULL; + } + else if (root && (0 == strncmp (str, root->str, len))) + { + node_t * tmp = root; + root = root->next; + return strdup (tmp->str); + } + else + return (char *)NULL; +} + +void +clear_completions () +{ + node_t * tmp; + while (collection) + { + /* printf ("-del- (%s)\n", collection->str); */ + tmp = collection->next; + free (collection->str); + free (collection); + collection = tmp; + } +} + +void +use_custom_complete (void) +{ + rl_completion_entry_function = custom_completer; +} + +void +use_filename_complete (void) +{ + rl_completion_entry_function = rl_filename_completion_function; +} diff --git a/debian/changelog b/debian/changelog index 5d43831..32dbfab 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,13 @@ +cl-readline (0.2.0-1) unstable; urgency=low + + * New upstream + * Initial upload (closes: 191916) + + -- Kevin M. Rosenberg Thu, 8 May 2003 21:35:49 -0600 + cl-readline (0.1.1kmr-1) unstable; urgency=low - * New upstream (closes: 191916) + * New upstream -- Kevin M. Rosenberg Mon, 5 May 2003 16:15:45 -0600 diff --git a/debian/rules b/debian/rules index 5f9dab6..f78f849 100755 --- a/debian/rules +++ b/debian/rules @@ -42,7 +42,7 @@ install: build dh_installdirs $(clc-systems) $(clc-files) $(clc-tests) dh_install $(pkg).asd $(source-files) $(clc-files) dh_link $(clc-files)/$(pkg).asd $(clc-systems)/$(pkg).asd - dh_install "libreadline-cl.so" $(lib-dir) + dh_install *.so $(lib-dir) # Build architecture-independent files here. binary-indep: build install diff --git a/libreadline-cl.c b/libreadline-cl.c deleted file mode 100644 index 63874f6..0000000 --- a/libreadline-cl.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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 - * without limitation the rights to use, copy, modify, merge, publish, - * 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. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * 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. - */ - -#include -#include -#include - -typedef struct { - char * str; - void * next; -} -node_t; - -node_t * collection = NULL; - -int -add_completion (char * str) -{ - node_t * tmp = collection; - node_t * pre = NULL; - node_t * node; - while (tmp) - { - int cmp = strcmp (str, tmp->str); - if (0 == cmp) - return 1; - - if (0 < cmp) - break; - - /* printf ("-skip- (%s)\n", tmp->str);*/ - - pre = tmp; - tmp = tmp->next; - } - - node = malloc (sizeof (node_t)); - if (!node) - return 0; - - node->next = tmp; - node->str = strdup (str); - - if (! pre) - collection = node; - else - pre->next = node; - - return 1; -} - -node_t * root = NULL; - -char * -custom_completer (const char * str, int target) -{ - size_t len = strlen (str); - if (0 == target) - { - root = NULL; - node_t * tmp = collection; - while (len && tmp) - { - if (0 == strncmp (str, tmp->str, len)) - { - root = tmp; - return strdup (root->str); - } - else - tmp = tmp->next; - } - return (char *)NULL; - } - else if (root && (0 == strncmp (str, root->str, len))) - { - node_t * tmp = root; - root = root->next; - return strdup (tmp->str); - } - else - return (char *)NULL; -} - -void -clear_completions () -{ - node_t * tmp; - while (collection) - { - /* printf ("-del- (%s)\n", collection->str); */ - tmp = collection->next; - free (collection->str); - free (collection); - collection = tmp; - } -} - -void -use_custom_complete (void) -{ - rl_completion_entry_function = custom_completer; -} - -void -use_filename_complete (void) -{ - rl_completion_entry_function = rl_filename_completion_function; -} diff --git a/libreadline.lisp b/libreadline.lisp deleted file mode 100644 index 53fd105..0000000 --- a/libreadline.lisp +++ /dev/null @@ -1,46 +0,0 @@ -;; 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 -;; without limitation the rights to use, copy, modify, merge, publish, -;; 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. -;; IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -;; 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 libreadline) - -(def-function "readline" ((prompt :cstring)) - :module "readline" - :returning (* :char)) - -(def-function "add_history" ((str :cstring)) - :module "readline" - :returning :void) - -(def-function "add_completion" ((str :cstring)) - :module "readline-cl" - :returning :int) - -(def-function "clear_completions" () - :module "readline-cl" - :returning :void) - -(def-function "use_custom_complete" () - :module "readline-cl" - :returning :void) - -(def-function "use_filename_complete" () - :module "readline-cl" - :returning :void) diff --git a/packages.lisp b/packages.lisp index 8b497e4..dd801cf 100644 --- a/packages.lisp +++ b/packages.lisp @@ -19,9 +19,6 @@ ;; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -(defpackage libreadline - (:use cl uffi)) - (defpackage readline (:nicknames rl) (:use cl uffi) @@ -30,11 +27,13 @@ add-history clear-completions readline - use-cl-complete + readexpr + repl + use-package-complete use-custom-complete use-filename-complete )) -(uffi:load-foreign-library "/usr/lib/cl-readline/libreadline-cl.so" - :module "readline-cl") +(uffi:load-foreign-library "/usr/lib/cl-readline/cl-readline.so" + :module "cl-readline") diff --git a/readline.asd b/readline.asd index a4e3f9a..835529c 100644 --- a/readline.asd +++ b/readline.asd @@ -23,7 +23,5 @@ (asdf:defsystem readline :depends-on (:uffi) :components ((:file "packages") - (:file "libreadline" :depends-on ("packages")) - (:file "readline" :depends-on ("packages" "libreadline")))) + (:file "readline" :depends-on ("packages")))) - 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)))) + + +