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.
This commit is contained in:
Kartik K. Agaram 2022-01-03 23:36:44 -08:00
parent 7812ebc5f1
commit 4018c2e8e2
4 changed files with 63 additions and 10 deletions

View File

@ -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;

View File

@ -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);
}

View File

@ -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() */

View File

@ -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 */