From 4018c2e8e2499c1a8a625ef717ae9dc242bd83e3 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Mon, 3 Jan 2022 23:36:44 -0800 Subject: [PATCH] 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. --- src/kilo.c | 9 ++++++++- src/ldo.c | 5 +++-- src/teliva.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++------ src/teliva.h | 3 ++- 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 */