about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2022-01-03 23:36:44 -0800
committerKartik K. Agaram <vc@akkartik.com>2022-01-03 23:36:44 -0800
commit4018c2e8e2499c1a8a625ef717ae9dc242bd83e3 (patch)
tree430bbb12f66159f164b7f3090e36aa46fae42582
parent7812ebc5f119cd4c47e6a91db0561008c7080bc5 (diff)
downloadteliva-4018c2e8e2499c1a8a625ef717ae9dc242bd83e3.tar.gz
when editing a function, show its callers
No way to select between them. That complicates the UI too much when we
do so much with the cursor. But it's still useful to suggest things to
type in after ctrl-g.
-rw-r--r--src/kilo.c9
-rw-r--r--src/ldo.c5
-rw-r--r--src/teliva.c56
-rw-r--r--src/teliva.h3
4 files changed, 63 insertions, 10 deletions
diff --git a/src/kilo.c b/src/kilo.c
index 3864acd..76c5348 100644
--- a/src/kilo.c
+++ b/src/kilo.c
@@ -737,7 +737,8 @@ static void editorRefreshScreen(void (*menu_func)(void)) {
     erow *r;
     int current_color = -1;
     curs_set(0);
-    clear();
+    mvaddstr(E.startrow, 0, "");
+    clrtobot();
     attrset(A_NORMAL);
     /* Draw all line numbers first so they don't mess up curses state later
      * when rendering lines. */
@@ -1053,6 +1054,9 @@ static void editorGo(lua_State* L) {
               save_to_current_definition_and_editor_buffer(L, query);
               clearEditor();
               editorOpen("teliva_editor_buffer");
+              attrset(A_NORMAL);
+              clear();
+              draw_callers_of_current_definition(L);
             }
             return;
         } else if (c == CTRL_U) {
@@ -1201,6 +1205,9 @@ int edit(lua_State* L, char* filename) {
     Back_to_big_picture = 0;
     initEditor();
     editorOpen(filename);
+    attrset(A_NORMAL);
+    clear();
+    draw_callers_of_current_definition(L);
     while(!Quit) {
         /* update on resize */
         E.startcol = LINE_NUMBER_SPACE;
diff --git a/src/ldo.c b/src/ldo.c
index 6316b24..e1bf316 100644
--- a/src/ldo.c
+++ b/src/ldo.c
@@ -283,9 +283,10 @@ void record_metadata_about_function_call (lua_State *L, CallInfo *ci) {
     return;
   int g = GETARG_Bx(i);  /* global index */
   lua_assert(ttisstring(&p->k[g]));
+  int call_graph_depth = ci - L->base_ci;
   const char* function_name = svalue(&p->k[g]);
-  assign_call_graph_depth_to_name(L, ci - L->base_ci, function_name);
-  save_caller(L, function_name);
+  assign_call_graph_depth_to_name(L, call_graph_depth, function_name);
+  save_caller(L, function_name, call_graph_depth);
 }
 
 
diff --git a/src/teliva.c b/src/teliva.c
index 1dc68ae..b136f8d 100644
--- a/src/teliva.c
+++ b/src/teliva.c
@@ -301,11 +301,16 @@ void append_string_to_array(lua_State* L, int array_index, const char* s) {
   lua_rawseti(L, array_index, new_index);
 }
 
-void save_caller(lua_State* L, const char* name) {
+extern void save_caller_as(lua_State* L, const char* name, const char* caller_name);
+void save_caller(lua_State* L, const char* name, int call_graph_depth) {
   lua_Debug ar;
-  lua_getstack(L, 2, &ar);
+  lua_getstack(L, 1, &ar);
   lua_getinfo(L, "n", &ar);
-  if (!ar.name) return;
+  if (ar.name) save_caller_as(L, name, ar.name);
+  else if (call_graph_depth == 2) save_caller_as(L, name, "main");  // the way Teliva calls `main` messes with debug info
+}
+
+void save_caller_as(lua_State* L, const char* name, const char* caller_name) {
   // push table of caller tables
   luaL_newmetatable(L, "__teliva_caller");
   int ct = lua_gettop(L);
@@ -320,12 +325,28 @@ void save_caller(lua_State* L, const char* name) {
   lua_getfield(L, ct, name);  // new value = caller table
   int curr_caller_index = lua_gettop(L);
   lua_pushboolean(L, true);
-  lua_setfield(L, curr_caller_index, ar.name);
+  lua_setfield(L, curr_caller_index, caller_name);
   // clean up
   lua_pop(L, 1);  // caller table
   lua_pop(L, 1);  // table of caller tables
 }
 
+static void clear_caller(lua_State* L) {
+  int oldtop = lua_gettop(L);
+  luaL_newmetatable(L, "__teliva_caller");
+  int ct = lua_gettop(L);
+  lua_pushnil(L);
+  while (lua_next(L, ct) != 0) {
+    lua_pop(L, 1);  /* old value */
+    lua_pushvalue(L, -1);  /* duplicate key */
+    lua_pushnil(L);  /* new value */
+    lua_settable(L, ct);
+    /* one copy of key left for lua_next */
+  }
+  lua_pop(L, 1);
+  assert(lua_gettop(L) == oldtop);
+}
+
 /* return true if submitted */
 static int edit_current_definition(lua_State* L);
 static void recent_changes_view(lua_State* L);
@@ -583,6 +604,30 @@ int editor_view_in_progress(lua_State* L) {
   return result;
 }
 
+char Current_definition[CURRENT_DEFINITION_LEN+1] = {0};
+
+void draw_callers_of_current_definition(lua_State* L) {
+  int oldtop = lua_gettop(L);
+  luaL_newmetatable(L, "__teliva_caller");
+  int ct = lua_gettop(L);
+  lua_getfield(L, ct, Current_definition);
+  if (lua_isnil(L, -1)) {
+    lua_pop(L, 2);
+    assert(oldtop == lua_gettop(L));
+    return;
+  }
+  int ctc = lua_gettop(L);
+  attron(COLOR_PAIR(COLOR_PAIR_FADE));
+  mvaddstr(0, 0, "callers: ");
+  attroff(COLOR_PAIR(COLOR_PAIR_FADE));
+  for (lua_pushnil(L); lua_next(L, ctc) != 0; lua_pop(L, 1)) {
+    const char* caller_name = lua_tostring(L, -2);
+    draw_definition_name(caller_name);
+  }
+  lua_pop(L, 2);  // caller table, __teliva_caller
+  assert(oldtop == lua_gettop(L));
+}
+
 extern int load_editor_buffer_to_current_definition_in_image(lua_State* L);
 extern int resumeEdit(lua_State* L);
 extern int editFrom(lua_State* L, char* filename, int rowoff, int coloff, int cy, int cx);
@@ -648,8 +693,6 @@ void developer_mode(lua_State* L) {
   /* never returns */
 }
 
-char Current_definition[CURRENT_DEFINITION_LEN+1] = {0};
-
 extern int mkstemp(char* template);
 extern FILE* fdopen(int fd, const char* mode);
 void save_editor_state(int rowoff, int coloff, int cy, int cx) {
@@ -1539,6 +1582,7 @@ int handle_image(lua_State* L, char** argv, int n) {
   if (status != 0) return report_in_developer_mode(L, status);
   /* clear callgraph stats from running tests */
   clear_call_graph(L);
+  clear_caller(L);
   /* initialize permissions */
   load_permissions_from_user_configuration(L);
   /* call main() */
diff --git a/src/teliva.h b/src/teliva.h
index 6484298..2821c49 100644
--- a/src/teliva.h
+++ b/src/teliva.h
@@ -163,7 +163,8 @@ extern void save_to_current_definition_and_editor_buffer(lua_State* L, const cha
 extern void save_editor_state(int rowoff, int coloff, int cy, int cx);
 
 extern void assign_call_graph_depth_to_name(lua_State* L, int depth, const char* name);
-extern void save_caller(lua_State* L, const char* name);
+extern void save_caller(lua_State* L, const char* name, int call_graph_depth);
+extern void draw_callers_of_current_definition(lua_State* L);
 extern void append_to_audit_log(lua_State* L, const char* buffer);
 
 /* Standard UI elements */