Readline patch?

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Readline patch?

Magnus Lie Hetland
Hi!

Does anyone have a patch integrating the GNU readline library
with the interactive lua interpreter? I tried doing one
myself but didn't do too well ;)

I know there are readline wrappers out there -- I just thought
I would check...

--

  Magnus Lie Hetland      (magnus at hetland dot org)

 "Reality is what refuses to disappear when you stop
  believing in it"                 -- Philip K. Dick



Reply | Threaded
Open this post in threaded view
|

Re: Readline patch?

Luiz Henrique de Figueiredo
>Does anyone have a patch integrating the GNU readline library
>with the interactive lua interpreter?

Here it is. I don't know much about readline, but at least this supports
history, which I think is what most people want.

1. Add -lreadline in the Makefile:

$T: $(OBJS) $(LIB)/liblua.a $(LIB)/liblualib.a
	$(CC) -o $@ $(OBJS) -L$(LIB) -llua -llualib $(EXTRA_LIBS) -lreadline

2. Replace manual_input in lua.c by this:

#include <readline/readline.h>
#include <readline/history.h>

static void manual_input (int version, int prompt) {
  if (version) print_version();
  for (;;) {
    char *buffer;
    if (prompt) {
      const char *s;
      lua_getglobal(L, "_PROMPT");
      s = lua_tostring(L, -1);
      if (!s) s = PROMPT;
      buffer=readline(s);
      lua_pop(L, 1);  /* remove global */
    }
    else
      buffer=readline(NULL);
    if (buffer==NULL) break;
    add_history(buffer);
    ldo(lua_dostring, buffer);
    free(buffer);
    lua_settop(L, 0);  /* remove eventual results */
  }
  printf("\n");
}


--lhf

Reply | Threaded
Open this post in threaded view
|

Re: Readline patch?

Adolf Mathias
Luiz Henrique de Figueiredo wrote:

> 1. Add -lreadline in the Makefile:
> 
> $T: $(OBJS) $(LIB)/liblua.a $(LIB)/liblualib.a
>         $(CC) -o $@ $(OBJS) -L$(LIB) -llua -llualib $(EXTRA_LIBS) -lreadline

I also had to add -ltermcap:

$T: $(OBJS) $(LIB)/liblua.a $(LIB)/liblualib.a
        $(CC) -o $@ $(OBJS) -L$(LIB) -llua -llualib $(EXTRA_LIBS)
-lreadline -ltermcap

> 2. Replace manual_input in lua.c by this:
> 
> #include <readline/readline.h>
> #include <readline/history.h>
> 
> static void manual_input (int version, int prompt) {
...
...
>       buffer=readline(NULL);
>     if (buffer==NULL) break;

>     add_history(buffer);

It's rather convenient to change the add_history line to

if(buffer[0]) add_history(buffer);

This way, empty lines won't be added to the history.

Dolfi

Reply | Threaded
Open this post in threaded view
|

Re: Readline patch?

Reuben Thomas-3
In reply to this post by Magnus Lie Hetland
> Does anyone have a patch integrating the GNU readline library
> with the interactive lua interpreter? I tried doing one
> myself but didn't do too well ;)

Yes, I've done this. Here's the diff (-u):

--- lua/src/lua/lua.c	Fri Oct 20 17:36:32 2000
+++ ../lua-4.0/src/lua/lua.c	Tue Jan 30 11:13:00 2001
@@ -10,6 +10,9 @@
 #include <stdlib.h>
 #include <string.h>

+#include <readline/readline.h>
+#include <readline/history.h>
+
 #include "lua.h"

 #include "luadebug.h"
@@ -55,6 +58,8 @@
   lua_mathlibopen(L);
   lua_dblibopen(L);
   /* add your libraries here */
+  lua_rexlibopen(L);
+  lua_bitlibopen(L);
 }


@@ -170,40 +175,24 @@
 #endif

 static void manual_input (int version, int prompt) {
-  int cont = 1;
+  char *buffer;
   if (version) print_version();
-  while (cont) {
-    char buffer[MAXINPUT];
-    int i = 0;
+  do {
+    const char *s = NULL;
     if (prompt) {
-      const char *s;
       lua_getglobal(L, "_PROMPT");
       s = lua_tostring(L, -1);
       if (!s) s = PROMPT;
-      fputs(s, stdout);
       lua_pop(L, 1);  /* remove global */
     }
-    for(;;) {
-      int c = getchar();
-      if (c == EOF) {
-        cont = 0;
-        break;
-      }
-      else if (c == '\n') {
-        if (i>0 && buffer[i-1] == '\\')
-          buffer[i-1] = '\n';
-        else break;
-      }
-      else if (i >= MAXINPUT-1) {
-        fprintf(stderr, "lua: input line too long\n");
-        break;
-      }
-      else buffer[i++] = (char)c;
+    buffer = readline(s);
+    if (buffer) {
+      add_history(buffer);
+      ldo(lua_dostring, buffer);
+      free(buffer);
     }
-    buffer[i] = '\0';
-    ldo(lua_dostring, buffer);
     lua_settop(L, 0);  /* remove eventual results */
-  }
+  } while (buffer);
   printf("\n");
 }

@@ -319,4 +308,3 @@
     lua_close(L);
   return status;
 }
-

-- 
http://sc3d.org/rrt/ | humour, n.  unexpected recognition


Reply | Threaded
Open this post in threaded view
|

Re: Readline patch?

Reuben Thomas-3
On Mon, 12 Feb 2001, Reuben Thomas wrote:

> > Does anyone have a patch integrating the GNU readline library
> > with the interactive lua interpreter? I tried doing one
> > myself but didn't do too well ;)
>
> Yes, I've done this. Here's the diff (-u):

Woops. I hadn't yet seen the "official" version. So to atone, here's a
better patch: first, I call using_history, which I forgot before, secondly,
the lines you type are only entered into the history if they are non-empty,
and thirdly, if you enter a line that you've already entered, then the
previous copy is deleted from the history, and a new one added to the end,
so if you type:

this
that
theother
this

then the history is now

that
theother
this

rather than

this
that
theother
this

which is like setting IGNOREDUPS in bash, and can be most helpful for
navigating in long histories.

Here's the diff:

--- /home/rrt/comp/lang/lua/archives/lua/src/lua/lua.c	Fri Oct 20 17:36:32 2000
+++ lua.c	Mon Feb 12 12:20:09 2001
@@ -10,6 +10,9 @@
 #include <stdlib.h>
 #include <string.h>

+#include <readline/readline.h>
+#include <readline/history.h>
+
 #include "lua.h"

 #include "luadebug.h"
@@ -55,6 +58,8 @@
   lua_mathlibopen(L);
   lua_dblibopen(L);
   /* add your libraries here */
+  lua_rexlibopen(L);
+  lua_bitlibopen(L);
 }


@@ -170,40 +175,32 @@
 #endif

 static void manual_input (int version, int prompt) {
-  int cont = 1;
+  char *buffer;
   if (version) print_version();
-  while (cont) {
-    char buffer[MAXINPUT];
-    int i = 0;
+  do {
+    const char *s = NULL;
     if (prompt) {
-      const char *s;
       lua_getglobal(L, "_PROMPT");
       s = lua_tostring(L, -1);
       if (!s) s = PROMPT;
-      fputs(s, stdout);
       lua_pop(L, 1);  /* remove global */
     }
-    for(;;) {
-      int c = getchar();
-      if (c == EOF) {
-        cont = 0;
-        break;
-      }
-      else if (c == '\n') {
-        if (i>0 && buffer[i-1] == '\\')
-          buffer[i-1] = '\n';
-        else break;
-      }
-      else if (i >= MAXINPUT-1) {
-        fprintf(stderr, "lua: input line too long\n");
-        break;
+    buffer = readline(s);
+    if (buffer) {
+      if (buffer[0]) {
+	  int pos = where_history(), newpos = history_search(buffer, -1);
+	  if (newpos > -1) {
+	      HIST_ENTRY *h = remove_history(newpos);
+	      free(h->line); free(h->data); free(h);
+	      history_set_pos(pos);
+	  }
+	  add_history(buffer);
       }
-      else buffer[i++] = (char)c;
+      ldo(lua_dostring, buffer);
+      free(buffer);
     }
-    buffer[i] = '\0';
-    ldo(lua_dostring, buffer);
     lua_settop(L, 0);  /* remove eventual results */
-  }
+  } while (buffer);
   printf("\n");
 }

@@ -313,10 +310,10 @@
   getstacksize(argc, argv, &opt);  /* handle option `-s' */
   L = lua_open(opt.stacksize);  /* create state */
   userinit();  /* open libraries */
+  using_history();  /* init history library */
   register_getargs(argv);  /* create `getargs' function */
   status = handle_argv(argv+1, &opt);
   if (opt.toclose)
     lua_close(L);
   return status;
 }
-

-- 
http://sc3d.org/rrt/ | humour, n.  unexpected recognition