diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2022-01-03 23:36:44 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2022-01-03 23:36:44 -0800 |
commit | 4018c2e8e2499c1a8a625ef717ae9dc242bd83e3 (patch) | |
tree | 430bbb12f66159f164b7f3090e36aa46fae42582 /src/teliva.c | |
parent | 7812ebc5f119cd4c47e6a91db0561008c7080bc5 (diff) | |
download | teliva-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.
Diffstat (limited to 'src/teliva.c')
-rw-r--r-- | src/teliva.c | 56 |
1 files changed, 50 insertions, 6 deletions
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() */ |