about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--advent.tlv1
-rw-r--r--chesstv.tlv1
-rw-r--r--counter.tlv1
-rw-r--r--hanoi.tlv1
-rw-r--r--life.tlv1
-rw-r--r--src/kilo.c38
-rw-r--r--src/lua.c73
7 files changed, 69 insertions, 47 deletions
diff --git a/advent.tlv b/advent.tlv
index 2acb5dd..f3b9fa9 100644
--- a/advent.tlv
+++ b/advent.tlv
@@ -137,6 +137,7 @@ function init_colors()
   curses.init_pair(13, 7, 5)
   curses.init_pair(14, 7, 6)
   curses.init_pair(15, -1, 15)
+  curses.init_pair(255, 15, 1)  -- reserved for Teliva error messages
 end]==],
   },
   {
diff --git a/chesstv.tlv b/chesstv.tlv
index 9776653..e64b3e2 100644
--- a/chesstv.tlv
+++ b/chesstv.tlv
@@ -219,6 +219,7 @@ function init_colors()
   curses.init_pair(6, dark_piece, light_last_moved_square)
   curses.init_pair(7, light_piece, dark_last_moved_square)
   curses.init_pair(8, dark_piece, dark_last_moved_square)
+  curses.init_pair(255, 15, 1)  -- reserved for Teliva error messages
 end]==],
   },
   {
diff --git a/counter.tlv b/counter.tlv
index 31fed56..0c16d75 100644
--- a/counter.tlv
+++ b/counter.tlv
@@ -51,6 +51,7 @@ function main()
   for i=1,7 do
     curses.init_pair(i, 0, i)
   end
+  curses.init_pair(255, 15, 1)  -- reserved for Teliva error messages
 
   while true do
     render(window)
diff --git a/hanoi.tlv b/hanoi.tlv
index 06537f6..f529831 100644
--- a/hanoi.tlv
+++ b/hanoi.tlv
@@ -88,6 +88,7 @@ function main()
   for i=1,7 do
     curses.init_pair(i, 0, i)
   end
+  curses.init_pair(255, 15, 1)  -- reserved for Teliva error messages
 
   while true do
     render(window)
diff --git a/life.tlv b/life.tlv
index 08307e8..4c948c7 100644
--- a/life.tlv
+++ b/life.tlv
@@ -266,6 +266,7 @@ function main()
   for i=1,7 do
     curses.init_pair(i, i, -1)
   end
+  curses.init_pair(255, 15, 1)  -- reserved for Teliva error messages
 
   -- initialize grid based on commandline args
   if (#arg == 0) then
diff --git a/src/kilo.c b/src/kilo.c
index 7349537..df7359a 100644
--- a/src/kilo.c
+++ b/src/kilo.c
@@ -95,15 +95,11 @@ struct editorConfig {
     erow *row;      /* Rows */
     int dirty;      /* File modified but not saved. */
     char *filename; /* Currently open filename */
-    char statusmsg[80];
-    time_t statusmsg_time;
     struct editorSyntax *syntax;    /* Current syntax highlight, or NULL. */
 };
 
 static struct editorConfig E;
 
-static void editorSetStatusMessage(const char *fmt, ...);
-
 /* =========================== Syntax highlights DB =========================
  *
  * In order to add a new syntax, define two arrays with a list of file name
@@ -642,13 +638,16 @@ static int editorSaveToDisk(void) {
     close(fd);
     free(buf);
     E.dirty = 0;
-    memset(E.statusmsg, '\0', 80);
     return 0;
 
 writeerr:
     free(buf);
     if (fd != -1) close(fd);
-    editorSetStatusMessage("Can't save! I/O error: %s",strerror(errno));
+    /* TODO: better error handling. */
+    /* I haven't gotten to this yet since we have version control. */
+    endwin();
+    printf("Can't save! I/O error: %s",strerror(errno));
+    exit(1);
     return 1;
 }
 
@@ -720,6 +719,7 @@ static void editorGoMenu(void) {
     attrset(A_NORMAL);
 }
 
+extern int render_previous_error();
 static void editorRefreshScreen(void (*menu_func)(void)) {
     int y;
     erow *r;
@@ -771,12 +771,9 @@ static void editorRefreshScreen(void (*menu_func)(void)) {
         }
     }
 
-    (*menu_func)();
+    render_previous_error();
 
-    attrset(A_REVERSE);
-    addstr("    ");
-    addstr(E.statusmsg);
-    attrset(A_NORMAL);
+    (*menu_func)();
 
     /* Put cursor at its current position. Note that the horizontal position
      * at which the cursor is displayed may be different compared to 'E.cx'
@@ -795,16 +792,6 @@ static void editorRefreshScreen(void (*menu_func)(void)) {
     curs_set(1);
 }
 
-/* Set an editor status message for the second line of the status, at the
- * end of the screen. */
-static void editorSetStatusMessage(const char *fmt, ...) {
-    va_list ap;
-    va_start(ap,fmt);
-    vsnprintf(E.statusmsg,sizeof(E.statusmsg),fmt,ap);
-    va_end(ap);
-    E.statusmsg_time = time(NULL);
-}
-
 /* =============================== Find mode ================================ */
 
 #define KILO_QUERY_LEN 256
@@ -843,7 +830,6 @@ static void editorFind() {
                 E.coloff = saved_coloff; E.rowoff = saved_rowoff;
             }
             FIND_RESTORE_HL;
-            editorSetStatusMessage("");
             return;
         } else if (c == CTRL_U) {
             qlen = 0;
@@ -1040,7 +1026,6 @@ static void editorGo(lua_State* L) {
         if (c == KEY_BACKSPACE || c == DELETE || c == CTRL_H) {
             if (qlen != 0) query[--qlen] = '\0';
         } else if (c == CTRL_X || c == ENTER) {
-            editorSetStatusMessage("");
             if (c == ENTER) {
               save_to_current_definition_and_editor_buffer(L, query);
               clearEditor();
@@ -1182,12 +1167,11 @@ static void initEditor(void) {
 }
 
 /* return true if user chose to back into the big picture view */
-int edit(lua_State* L, char* filename, const char* message) {
+int edit(lua_State* L, char* filename) {
     Quit = 0;
     Back_to_big_picture = 0;
     initEditor();
     editorOpen(filename);
-    editorSetStatusMessage(message);
     while(!Quit) {
         editorRefreshScreen(editorMenu);
         editorProcessKeypress(L);
@@ -1196,7 +1180,7 @@ int edit(lua_State* L, char* filename, const char* message) {
 }
 
 /* return true if user chose to back into the big picture view */
-int edit_from(lua_State* L, char* filename, const char* message, int rowoff, int coloff, int cy, int cx) {
+int edit_from(lua_State* L, char* filename, int rowoff, int coloff, int cy, int cx) {
     Quit = 0;
     Back_to_big_picture = 0;
     initEditor();
@@ -1205,7 +1189,6 @@ int edit_from(lua_State* L, char* filename, const char* message, int rowoff, int
     E.cy = cy;
     E.cx = cx;
     editorOpen(filename);
-    editorSetStatusMessage(message);
     while(!Quit) {
         editorRefreshScreen(editorMenu);
         editorProcessKeypress(L);
@@ -1216,7 +1199,6 @@ int edit_from(lua_State* L, char* filename, const char* message, int rowoff, int
 int resumeEdit(lua_State* L) {
     Quit = 0;
     Back_to_big_picture = 0;
-    editorSetStatusMessage(Previous_error);
     while(!Quit) {
         editorRefreshScreen(editorMenu);
         editorProcessKeypress(L);
diff --git a/src/lua.c b/src/lua.c
index e73ac49..f00b4ae 100644
--- a/src/lua.c
+++ b/src/lua.c
@@ -81,21 +81,56 @@ static int report (lua_State *L, int status) {
 }
 
 
-char *strdup(const char *s);
-extern void developer_mode (lua_State *L, const char *status_message);
+/* return final y containing text */
+static int render_wrapped_text (int y, int xmin, int xmax, const char *text) {
+  int x = xmin;
+  move(y, x);
+  for (int j = 0; j < strlen(text); ++j) {
+    char c = text[j];
+    if (c != '\n') {
+      addch(text[j]);
+      ++x;
+      if (x >= xmax) {
+        ++y;
+        x = xmin;
+        move(y, x);
+      }
+    }
+    else {
+      /* newline */
+      ++y;
+      x = xmin;
+      move(y, x);
+    }
+  }
+  return y;
+}
+
+
+const char *Previous_error = NULL;
+void render_previous_error (void) {
+  if (!Previous_error) return;
+  attrset(COLOR_PAIR(255));
+  render_wrapped_text(LINES-10, COLS/2, COLS, Previous_error);
+  attrset(A_NORMAL);
+}
+
+
+extern char *strdup(const char *s);
+extern void developer_mode (lua_State *L);
 static int report_in_developer_mode (lua_State *L, int status) {
   if (status && !lua_isnil(L, -1)) {
-    const char *msg = strdup(lua_tostring(L, -1));  /* memory leak */
-    if (msg == NULL) msg = "(error object is not a string)";
+    Previous_error = strdup(lua_tostring(L, -1));  /* memory leak */
+    if (Previous_error == NULL) Previous_error = "(error object is not a string)";
     lua_pop(L, 1);
     for (int x = 0; x < COLS; ++x) {
       mvaddch(LINES-2, x, ' ');
       mvaddch(LINES-1, x, ' ');
     }
-    mvaddstr(LINES-2, 0, msg);
+    render_previous_error();
     mvaddstr(LINES-1, 0, "press any key to continue");
     getch();
-    developer_mode(L, msg);
+    developer_mode(L);
   }
   return status;
 }
@@ -413,11 +448,10 @@ int load_editor_buffer_to_current_definition_in_image(lua_State *L) {
 
 /* return true if user chose to back into the big picture view */
 /* But only if there are no errors. Otherwise things can get confusing. */
-const char *Previous_error = NULL;
-extern int edit (lua_State *L, char *filename, const char *message);
+extern int edit (lua_State *L, char *filename);
 extern int resumeEdit (lua_State *L);
 int edit_current_definition (lua_State *L) {
-  int back_to_big_picture = edit(L, "teliva_editor_buffer", /*status message*/ "");
+  int back_to_big_picture = edit(L, "teliva_editor_buffer");
   // error handling
   while (1) {
     int status;
@@ -482,7 +516,7 @@ static int render_wrapped_lua_text (int y, int xmin, int xmax, const char *text)
     else {
       /* newline */
       ++y;
-      x = 0;
+      x = xmin;
       move(y, x);
       attroff(FG(6));
     }
@@ -625,7 +659,7 @@ void recent_changes_view (lua_State *L) {
         save_note_to_editor_buffer(L, cursor);
         /* big picture hotkey unnecessarily available here */
         /* TODO: go hotkey is misleading. edits will not be persisted until you return to recent changes */
-        edit(L, "teliva_editor_buffer", /*status message*/ "");
+        edit(L, "teliva_editor_buffer");
         load_note_from_editor_buffer(L, cursor);
         save_image(L);
         break;
@@ -697,7 +731,7 @@ void draw_definition_name (const char *definition_name) {
 }
 
 /* return true if submitted */
-void big_picture_view (lua_State *L, const char *status_message) {
+void big_picture_view (lua_State *L) {
 restart:
   clear();
   luaL_newmetatable(L, "__teliva_call_graph_depth");
@@ -804,7 +838,7 @@ restart:
   }
 
   lua_settop(L, 0);
-  mvprintw(LINES-3, 0, status_message);
+  render_previous_error();
 
   char query[CURRENT_DEFINITION_LEN+1] = {0};
   int qlen = 0;
@@ -858,8 +892,8 @@ int editor_view_in_progress (lua_State *L) {
   return result;
 }
 
-extern int edit_from(lua_State *L, char *filename, const char *message, int rowoff, int coloff, int cy, int cx);
-int restore_editor_view (lua_State *L, const char *status_message) {
+extern int edit_from(lua_State *L, char *filename, int rowoff, int coloff, int cy, int cx);
+int restore_editor_view (lua_State *L) {
   lua_getglobal(L, "__teliva_editor_state");
   int editor_state_index = lua_gettop(L);
   lua_getfield(L, editor_state_index, "definition");
@@ -874,7 +908,7 @@ int restore_editor_view (lua_State *L, const char *status_message) {
   lua_getfield(L, editor_state_index, "cx");
   int cx = lua_tointeger(L, -1);
   lua_settop(L, editor_state_index);
-  int back_to_big_picture = edit_from(L, "teliva_editor_buffer", status_message, rowoff, coloff, cy, cx);
+  int back_to_big_picture = edit_from(L, "teliva_editor_buffer", rowoff, coloff, cy, cx);
   // error handling
   while (1) {
     int status;
@@ -892,18 +926,19 @@ int restore_editor_view (lua_State *L, const char *status_message) {
 
 char **Argv = NULL;
 extern void cleanup_curses (void);
-void developer_mode (lua_State *L, const char *status_message) {
+void developer_mode (lua_State *L) {
   /* clobber the app's ncurses colors; we'll restart the app when we rerun it. */
   for (int i = 0; i < 8; ++i)
     init_pair(i, i, 15);
   for (int i = 0; i < 8; ++i)
     init_pair(i+8, 0, i);
+  init_pair(255, /*white fg*/ 15, /*red bg*/ 1);  /* for teliva error messages */
   nodelay(stdscr, 0);  /* make getch() block */
   int switch_to_big_picture_view = 1;
   if (editor_view_in_progress(L))
-    switch_to_big_picture_view = restore_editor_view(L, status_message);
+    switch_to_big_picture_view = restore_editor_view(L);
   if (switch_to_big_picture_view)
-    big_picture_view(L, status_message);
+    big_picture_view(L);
   cleanup_curses();
   execv(Argv[0], Argv);
   /* never returns */