From a3062dfeb1fb466ac3f36c83042184c9a31b1841 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 21 Feb 2025 19:15:26 -0800 Subject: [PATCH] watch-window-defined/driven query lister completion --- src/raddbg/generated/raddbg.meta.c | 6 +- src/raddbg/generated/raddbg.meta.h | 3 +- src/raddbg/raddbg.mdesk | 1 + src/raddbg/raddbg_core.c | 131 +++++++++++++++++++++++++---- src/raddbg/raddbg_views.h | 4 + 5 files changed, 125 insertions(+), 20 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index fbda345d..9dad2728 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[296] = +RD_VocabInfo rd_vocab_info_table[297] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -300,6 +300,7 @@ RD_VocabInfo rd_vocab_info_table[296] = {str8_lit_comp("push_lister"), str8_lit_comp(""), str8_lit_comp("Push Lister"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("complete_lister"), str8_lit_comp(""), str8_lit_comp("Complete Lister"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("cancel_lister"), str8_lit_comp(""), str8_lit_comp("Cancel Lister"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("update_lister"), str8_lit_comp(""), str8_lit_comp("Update Lister"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("toggle_dev_menu"), str8_lit_comp(""), str8_lit_comp("Toggle Developer Menu"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("log_marker"), str8_lit_comp(""), str8_lit_comp("Log Marker"), str8_lit_comp(""), RD_IconKind_Null}, }; @@ -364,7 +365,7 @@ Rng1U64 rd_reg_slot_range_table[40] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[214] = +RD_CmdKindInfo rd_cmd_kind_info_table[215] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -578,6 +579,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[214] = { str8_lit_comp("push_lister"), str8_lit_comp("Pushes a new lister onto the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("complete_lister"), str8_lit_comp("Completes a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("cancel_lister"), str8_lit_comp("Cancels a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("update_lister"), str8_lit_comp("Updates a query input."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_dev_menu"), str8_lit_comp("Opens and closes the developer menu."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, }; diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 3261a8da..6a70cc3f 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -265,6 +265,7 @@ RD_CmdKind_PickFileOrFolder, RD_CmdKind_PushQuery, RD_CmdKind_CompleteQuery, RD_CmdKind_CancelQuery, +RD_CmdKind_UpdateQuery, RD_CmdKind_ToggleDevMenu, RD_CmdKind_LogMarker, RD_CmdKind_COUNT, @@ -632,7 +633,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[296]; +extern RD_VocabInfo rd_vocab_info_table[297]; extern RD_NameSchemaInfo rd_name_schema_info_table[12]; extern Rng1U64 rd_reg_slot_range_table[40]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 58e3e47c..f3058905 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -613,6 +613,7 @@ RD_CmdTable: // | | | | {PushQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "push_lister" "Push Lister" "Pushes a new lister onto the lister stack." "" "" } {CompleteQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "complete_lister" "Complete Lister" "Completes a lister, and pops it off the lister stack." "" "" } {CancelQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "cancel_lister" "Cancel Lister" "Cancels a lister, and pops it off the lister stack." "" "" } + {UpdateQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "update_lister" "Update Lister" "Updates a query input." "" "" } //- rjf: developer commands {ToggleDevMenu 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "toggle_dev_menu" "Toggle Developer Menu" "Opens and closes the developer menu." "" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index d3071173..8401e40a 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3759,6 +3759,7 @@ rd_view_ui(Rng2F32 rect) { is_first_frame = 1; ewv->initialized = 1; + ewv->filter_arena = rd_push_view_arena(); ewv->text_edit_arena = rd_push_view_arena(); } @@ -3774,6 +3775,19 @@ rd_view_ui(Rng2F32 rect) Vec4F32 pop_background_rgba = {0}; UI_TagF("pop") pop_background_rgba = ui_color_from_name(str8_lit("background")); + ////////////////////////////// + //- rjf: whenever the filter changes, we want to reset the cursor/mark state + // + if(!str8_match(filter, ewv->last_filter, 0)) + { + MemoryZeroStruct(&ewv->cursor); + MemoryZeroStruct(&ewv->mark); + MemoryZeroStruct(&ewv->next_cursor); + MemoryZeroStruct(&ewv->next_mark); + arena_clear(ewv->filter_arena); + ewv->last_filter = push_str8_copy(ewv->filter_arena, filter); + } + ////////////////////////////// //- rjf: decide if root should be implicit // @@ -3816,19 +3830,6 @@ rd_view_ui(Rng2F32 rect) } } - ////////////////////////////// - //- rjf: consume query-completion events, if this view is being used as a query - // -#if 0 - if(vs->query_is_selected && - ui_is_focus_active() && - ui_slot_press(UI_EventActionSlot_Accept)) - { - // TODO(rjf): // TODO(rjf): // TODO(rjf): // TODO(rjf): // TODO(rjf): - // TODO(rjf): // TODO(rjf): // TODO(rjf): // TODO(rjf): // TODO(rjf): - } -#endif - ////////////////////////////// //- rjf: consume events & perform navigations/edits - calculate state // @@ -4026,6 +4027,75 @@ rd_view_ui(Rng2F32 rect) } B32 taken = 0; + ////////////////////////////// + //- rjf: consume query-completion events, if this view is being used as a query + // + { + RD_Cfg *lister = rd_cfg_child_from_string(view, str8_lit("lister")); + if(lister != &rd_nil_cfg && + evt->kind == UI_EventKind_Press && + evt->slot == UI_EventActionSlot_Accept && + selection_tbl.min.y == selection_tbl.max.y) + { + RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query")); + RD_Cfg *cmd = rd_cfg_child_from_string(query, str8_lit("cmd")); + String8 cmd_name = cmd->first->string; + + // rjf: if we have no selection, just pick the first row + EV_Row *row = 0; + if(selection_tbl.min.y == 0 && selection_tbl.max.y == 0) + { + row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, 1); + } + + // rjf: if we do have a selection, compute that row + else + { + row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, selection_tbl.min.y); + } + + // rjf: use row to complete query + if(row != 0) + { + taken = 1; + E_Eval eval = e_eval_from_expr(scratch.arena, row->expr); + switch(eval.space.kind) + { + default: + { + String8 symbol_name = d_symbol_name_from_process_vaddr(scratch.arena, ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), eval.value.u64, 0, 0); + rd_cmd(RD_CmdKind_CompleteQuery, .string = symbol_name); + }break; + case E_SpaceKind_File: + case E_SpaceKind_FileSystem: + { + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + String8 file = rd_file_path_from_eval(scratch.arena, eval); + if(str8_match(type->name, str8_lit("folder"), 0)) + { + String8 new_input_string = push_str8f(scratch.arena, "%S/", file); + rd_cmd(RD_CmdKind_UpdateQuery, .string = new_input_string); + } + else + { + rd_cmd(RD_CmdKind_CompleteQuery, .file_path = file); + } + }break; + case RD_EvalSpaceKind_MetaCfg: + { + RD_Cfg *cfg = rd_cfg_from_eval_space(eval.space); + rd_cmd(RD_CmdKind_CompleteQuery, .cfg = cfg->id); + }break; + case RD_EvalSpaceKind_MetaUnattachedProcess: + { + U64 pid = eval.value.u128.u64[0]; + rd_cmd(RD_CmdKind_CompleteQuery, .pid = pid); + }break; + } + } + } + } + ////////////////////////// //- rjf: begin editing on some operations // @@ -5376,8 +5446,16 @@ rd_view_ui(Rng2F32 rect) ui_kill_action(); } + // rjf: this watch window is being queried? -> move curosr & accept + RD_Cfg *lister = rd_cfg_child_from_string(view, str8_lit("lister")); + if(lister != &rd_nil_cfg) + { + ewv->next_cursor = ewv->next_mark = cell_pt; + rd_cmd(RD_CmdKind_Accept); + } + // rjf: has a command name? -> push command - if(cell_info.cmd_name.size != 0) + else if(cell_info.cmd_name.size != 0) { CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(row_info->eval.space); RD_Cfg *cfg = rd_cfg_from_eval_space(row_info->eval.space); @@ -5396,6 +5474,7 @@ rd_view_ui(Rng2F32 rect) // rjf: can edit? -> begin editing else if(!(sig.f & UI_SignalFlag_KeyboardPressed) && cell_info.flags & RD_WatchCellFlag_CanEdit) { + ewv->next_cursor = ewv->next_mark = cell_pt; rd_cmd(RD_CmdKind_Edit); } @@ -5698,7 +5777,14 @@ rd_view_ui(Rng2F32 rect) } if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) { - rd_cmd(RD_CmdKind_CompleteQuery); + String8 cmd_name = rd_view_query_cmd(); + String8 input = rd_view_query_input(); + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + RD_RegsScope() + { + rd_regs_fill_slot_from_string(cmd_kind_info->query.slot, input); + rd_cmd(RD_CmdKind_CompleteQuery); + } } } @@ -15840,6 +15926,8 @@ Z(getting_started) if(dst_tab == &rd_nil_cfg && dst_panel == panel_w_auto && view_w_auto != &rd_nil_cfg) { dst_tab = view_w_auto; + RD_ViewState *vs = rd_view_state_from_cfg(dst_tab); + vs->last_frame_index_built = 0; RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(dst_tab, str8_lit("expression")); rd_cfg_new_replace(expr, rd_eval_string_from_file_path(scratch.arena, file_path)); } @@ -15985,11 +16073,9 @@ Z(getting_started) case RD_CmdKind_CompleteQuery: { String8 cmd_name = rd_view_query_cmd(); - String8 input = rd_view_query_input(); RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); RD_RegsScope() { - rd_regs_fill_slot_from_string(cmd_kind_info->query.slot, input); rd_push_cmd(cmd_name, rd_regs()); } if(cmd_kind_info->query.flags & RD_QueryFlag_Floating) @@ -16017,6 +16103,17 @@ Z(getting_started) ws->query_cmd_name = str8_zero(); } }break; + case RD_CmdKind_UpdateQuery: + { + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); + RD_Cfg *input = rd_cfg_child_from_string_or_alloc(query, str8_lit("input")); + rd_cfg_new_replace(input, rd_regs()->string); + RD_ViewState *vs = rd_view_state_from_cfg(view); + vs->query_cursor = vs->query_mark = txt_pt(1, rd_regs()->string.size+1); + vs->query_string_size = Min(sizeof(vs->query_buffer), rd_regs()->string.size); + MemoryCopy(vs->query_buffer, rd_regs()->string.str, vs->query_string_size); + }break; //- rjf: developer commands case RD_CmdKind_ToggleDevMenu: diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 5bc84acd..8f4b7570 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -190,6 +190,10 @@ struct RD_WatchViewState { B32 initialized; + // rjf: filter history + Arena *filter_arena; + String8 last_filter; + // rjf; table cursor state RD_WatchPt cursor; RD_WatchPt mark;