about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/kilo.c50
-rw-r--r--src/lcurseslib.c4
-rw-r--r--src/lua.c25
3 files changed, 71 insertions, 8 deletions
diff --git a/src/kilo.c b/src/kilo.c
index e07c3f2..b341a86 100644
--- a/src/kilo.c
+++ b/src/kilo.c
@@ -53,6 +53,9 @@
 #include <stdarg.h>
 #include <fcntl.h>
 #include <signal.h>
+#include <stdio.h>
+
+#include "lua.h"
 
 /* Syntax highlight types */
 #define HL_NORMAL 0
@@ -1264,3 +1267,50 @@ void edit(char* filename, char* message) {
     }
     disableRawMode(STDIN_FILENO);
 }
+
+extern void teliva_get_definition(lua_State *L, const char *name);
+extern void stackDump (lua_State *L);
+extern int dostring (lua_State *L, const char *s, const char *name);
+extern char *Image_name;
+void editString(lua_State *L, char *name) {
+    /* write given definition out to tmp file */
+//?     stackDump(L);
+    teliva_get_definition(L, name);
+//?     stackDump(L);
+    char *contents = lua_tostring(L, -1);
+    int outfd = open("teliva_editbuffer", O_WRONLY|O_CREAT|O_TRUNC, 0644);
+    write(outfd, contents, strlen(contents));
+    close(outfd);
+
+    /* edit tmp file */
+    edit("teliva_editbuffer", "");
+
+    /* read contents of tmp file */
+    char new_contents[8192] = {0};
+    int infd = open("teliva_editbuffer", O_RDONLY);
+    read(infd, new_contents, 8190);  /* TODO: handle overly large file */
+    close(infd);
+
+    /* save contents back into image */
+    lua_pop(L, 1);
+    lua_pushstring(L, new_contents);
+    lua_setfield(L, -2, name);
+
+    /* save teliva_program to disk */
+    int table = lua_gettop(L);
+    FILE* fp = fopen(Image_name, "w");
+    fprintf(fp, "teliva_program = {\n");
+    for (lua_pushnil(L); lua_next(L, table) != 0; lua_pop(L, 1)) {
+      const char* key = lua_tostring(L, -2);
+      const char* value = lua_tostring(L, -1);
+      fprintf(fp, "  %s = [[", key);
+      fprintf(fp, "%s", value);
+      fprintf(fp, "]],\n");
+    }
+    fprintf(fp, "}\n");
+    fclose(fp);
+
+    /* reload binding */
+    dostring(L, new_contents, name);
+    /* TODO: handle error */
+}
diff --git a/src/lcurseslib.c b/src/lcurseslib.c
index 67b842f..cab6f1f 100644
--- a/src/lcurseslib.c
+++ b/src/lcurseslib.c
@@ -113,7 +113,7 @@ static int Pcolor_pair (lua_State *L)
 }
 
 
-extern void switch_to_editor(const char *message);
+extern void switch_to_editor(lua_State *L, const char *message);
 static int Pgetch (lua_State *L) {
   int c = wgetch(stdscr);
   if (c == ERR)
@@ -121,7 +121,7 @@ static int Pgetch (lua_State *L) {
   if (c == 24)  /* ctrl-x */
     exit(0);
   if (c == 5)  /* ctrl-e */
-    switch_to_editor("");
+    switch_to_editor(L, "");
   /* handle other standard menu hotkeys here */
   lua_pushinteger(L, c);
   return 1;
diff --git a/src/lua.c b/src/lua.c
index 2600f44..e2f8574 100644
--- a/src/lua.c
+++ b/src/lua.c
@@ -140,7 +140,7 @@ static int dofile (lua_State *L, const char *name) {
 }
 
 
-static int dostring (lua_State *L, const char *s, const char *name) {
+int dostring (lua_State *L, const char *s, const char *name) {
   int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1);
   return report(L, status);
 }
@@ -244,7 +244,7 @@ static int has_extension (const char *filename, const char *extension) {
 }
 
 
-static void stackDump (lua_State *L) {
+void stackDump (lua_State *L) {
   int i;
   int top = lua_gettop(L);
   for (i = 1; i <= top; i++) {  /* repeat for each level */
@@ -274,12 +274,14 @@ static void stackDump (lua_State *L) {
 }
 
 
+char *Image_name = NULL;
 static int handle_image (lua_State *L, char **argv, int n) {
   int status;
   int narg = getargs(L, argv, n);  /* collect arguments */
   lua_setglobal(L, "arg");
   /* parse and load file contents (teliva_program table) */
-  status = luaL_loadfile(L, argv[n]);
+  Image_name = argv[n];
+  status = luaL_loadfile(L, Image_name);
   lua_insert(L, -(narg+1));
   if (status != 0) {
     return status;
@@ -306,13 +308,24 @@ static int handle_image (lua_State *L, char **argv, int n) {
 }
 
 
+/* Push the string corresponding to the definition for 'name' on the stack. */
+void teliva_get_definition(lua_State *L, const char *name) {
+  lua_getglobal(L, "teliva_program");
+  lua_getfield(L, -1, name);
+}
+
+
 /* death and rebirth */
 char *Script_name = NULL;
 char **Argv = NULL;
 extern void edit(char *filename, const char *status);
-void switch_to_editor(const char *message) {
+extern void editString(lua_State *L, char *name);
+void switch_to_editor(lua_State *L, const char *message) {
   endwin();
-  edit(Script_name, message);
+  if (Script_name)
+    edit(Script_name, message);
+  else
+    editString(L, "main");
   execv(Argv[0], Argv);
   /* never returns */
 }
@@ -323,7 +336,7 @@ static int show_error_in_editor (lua_State *L, int status) {
   if (status && !lua_isnil(L, -1)) {
     Previous_error = lua_tostring(L, -1);
     if (Previous_error == NULL) Previous_error = "(error object is not a string)";
-    switch_to_editor(Previous_error);
+    switch_to_editor(L, Previous_error);
   }
   return status;
 }