diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 661c49af..e318b97e 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -819,12 +819,20 @@ e_append_strings_from_expr(Arena *arena, E_Expr *expr, String8List *out) op_info->sep, op_info->post, }; - U64 idx = 0; - for(E_Expr *child = expr->first;; child = child->next, idx += 1) + U64 sep_idx = 0; + for(E_Expr *child = expr->first;; child = child->next) { - if(seps[idx].size != 0) + if(seps[sep_idx].size != 0) { - str8_list_push(arena, out, seps[idx]); + if(sep_idx == 1 && child == &e_expr_nil) + { + sep_idx += 1; + } + str8_list_push(arena, out, seps[sep_idx]); + if(sep_idx == 0) + { + sep_idx += 1; + } } if(child == &e_expr_nil) { diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 8b9c90d1..1130807d 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1443,6 +1443,8 @@ rd_cfg_newf(RD_Cfg *parent, char *fmt, ...) internal RD_Cfg * rd_cfg_new_replace(RD_Cfg *parent, String8 string) { + Temp scratch = scratch_begin(0, 0); + string = push_str8_copy(scratch.arena, string); for(RD_Cfg *child = parent->first->next, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) { next = child->next; @@ -1454,6 +1456,7 @@ rd_cfg_new_replace(RD_Cfg *parent, String8 string) } RD_Cfg *child = parent->first; rd_cfg_equip_string(child, string); + scratch_end(scratch); return child; } @@ -3354,7 +3357,7 @@ rd_view_ui(Rng2F32 rect) RD_Cfg *input_root = rd_cfg_child_from_string(query_root, str8_lit("input")); RD_Cfg *cmd_root = rd_cfg_child_from_string(query_root, str8_lit("cmd")); String8 current_input = input_root->first->string; - B32 search_row_is_open = (vs->query_is_selected || current_input.size != 0); + B32 search_row_is_open = (vs->query_is_selected); F32 search_row_open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "search_row_open_%p", view), (F32)!!search_row_is_open, .initial = (F32)!!search_row_is_open); if(search_row_open_t > 0.001f) { @@ -3412,11 +3415,14 @@ rd_view_ui(Rng2F32 rect) params.edit_buffer_size = sizeof(vs->query_buffer); params.pre_edit_value = current_input; } - UI_Signal sig = rd_line_editf(¶ms, "###search"); - if(ui_pressed(sig)) + UI_Transparency(1-search_row_open_t) { - vs->query_is_selected = 1; - rd_cmd(RD_CmdKind_FocusPanel); + UI_Signal sig = rd_line_editf(¶ms, "###search"); + if(ui_pressed(sig)) + { + vs->query_is_selected = 1; + rd_cmd(RD_CmdKind_FocusPanel); + } } } @@ -5389,7 +5395,7 @@ rd_view_ui(Rng2F32 rect) } } - // rjf: can't edit, but has cfg location info? -> find + // rjf: can't edit, but has cfg? -> find or select else if(cell_info.eval.space.kind == RD_EvalSpaceKind_MetaCfg) { RD_Cfg *cfg = rd_cfg_from_eval_space(cell_info.eval.space); @@ -5403,6 +5409,24 @@ rd_view_ui(Rng2F32 rect) U64 value = e_value_from_string(loc.expr).u64; rd_cmd(RD_CmdKind_FindCodeLocation, .vaddr = value); } + else if(str8_match(cfg->string, str8_lit("target"), 0) && sig.event_flags & OS_Modifier_Ctrl) + { + rd_cmd(RD_CmdKind_EnableCfg, .cfg = cfg->id); + } + else if(str8_match(cfg->string, str8_lit("target"), 0)) + { + rd_cmd(RD_CmdKind_SelectCfg, .cfg = cfg->id); + } + } + + // rjf: can't edit, but has thread? -> select + else if(cell_info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) + { + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(cell_info.eval.space); + if(entity->kind == CTRL_EntityKind_Thread) + { + rd_cmd(RD_CmdKind_SelectThread, .thread = entity->handle); + } } } @@ -11515,23 +11539,6 @@ rd_set_autocomp_lister_query_(RD_Regs *regs) ws->autocomp_lister_last_frame_idx = rd_state->frame_index; } -//////////////////////////////// -//~ rjf: Search Strings - -internal void -rd_set_search_string(String8 string) -{ - arena_clear(rd_state->string_search_arena); - rd_state->string_search_string = push_str8_copy(rd_state->string_search_arena, string); -} - -internal String8 -rd_push_search_string(Arena *arena) -{ - String8 result = push_str8_copy(arena, rd_state->string_search_string); - return result; -} - //////////////////////////////// //~ rjf: Colors, Fonts, Config @@ -12244,7 +12251,6 @@ rd_init(CmdLine *cmdln) rd_state->popup_arena = arena_alloc(); rd_state->ctx_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("top_level_ctx_menu")); rd_state->drop_completion_key = ui_key_from_string(ui_key_zero(), str8_lit("drop_completion_ctx_menu")); - rd_state->string_search_arena = arena_alloc(); rd_state->bind_change_arena = arena_alloc(); rd_state->drag_drop_arena = arena_alloc(); rd_state->drag_drop_regs = push_array(rd_state->drag_drop_arena, RD_Regs, 1); @@ -14059,25 +14065,6 @@ rd_frame(void) } }break; - //- rjf: code navigation - case RD_CmdKind_Search: - case RD_CmdKind_SearchBackwards: - case RD_CmdKind_FindTextForward: - case RD_CmdKind_FindTextBackward: - { - rd_set_search_string(rd_regs()->string); - }break; - - //- rjf: find next and find prev - case RD_CmdKind_FindNext: - { - rd_cmd(RD_CmdKind_Search, .string = rd_push_search_string(scratch.arena)); - }break; - case RD_CmdKind_FindPrev: - { - rd_cmd(RD_CmdKind_SearchBackwards, .string = rd_push_search_string(scratch.arena)); - }break; - //- rjf: font sizes case RD_CmdKind_IncUIFontScale: { @@ -15854,6 +15841,7 @@ Z(getting_started) RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); // rjf: floating queries -> set up window to build immediate-mode top-level query + RD_Cfg *view = &rd_nil_cfg; if(cmd_kind_info->query.flags & RD_QueryFlag_Floating) { RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); @@ -15865,31 +15853,54 @@ Z(getting_started) ws->query_cmd_name = push_str8_copy(ws->query_arena, cmd_name); ws->query_regs = rd_regs_copy(ws->query_arena, rd_regs()); } + RD_Cfg *window_query = rd_immediate_cfg_from_keyf("window_query_%p", window); + view = rd_cfg_child_from_string_or_alloc(window_query, str8_lit("watch")); } // rjf: non-floating -> embed in tab parameter else { - 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 *cmd = rd_cfg_child_from_string_or_alloc(query, str8_lit("cmd")); - RD_Cfg *input = rd_cfg_child_from_string_or_alloc(query, str8_lit("input")); - String8 current_query_cmd_name = cmd->first->string; - RD_ViewState *vs = rd_view_state_from_cfg(view); - if(!str8_match(current_query_cmd_name, cmd_name, 0)) - { - rd_cfg_new_replace(cmd, cmd_name); - if(!vs->query_is_selected) - { - vs->query_cursor = txt_pt(1, 1+input->first->string.size); - vs->query_mark = txt_pt(1, 1); - } - vs->query_is_selected = 1; - } - else - { - vs->query_is_selected ^= 1; - } + view = rd_cfg_from_id(rd_regs()->view); + } + + // rjf: unpack view's query info + RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); + RD_Cfg *cmd = rd_cfg_child_from_string_or_alloc(query, str8_lit("cmd")); + RD_Cfg *input = rd_cfg_child_from_string_or_alloc(query, str8_lit("input")); + + // rjf: choose initial input string + String8 initial_input = {0}; + if(cmd_kind_info->query.slot == RD_RegSlot_FilePath) + { + initial_input = rd_state->current_path; + } + else if(cmd_kind_info->query.flags & RD_QueryFlag_KeepOldInput) + { + initial_input = input->first->string; + } + + // rjf: build query state + rd_cfg_new_replace(input, initial_input); + rd_cfg_new_replace(cmd, cmd_name); + String8 current_query_cmd_name = cmd->first->string; + RD_ViewState *vs = rd_view_state_from_cfg(view); + if(!vs->query_is_selected && cmd_kind_info->query.flags & RD_QueryFlag_SelectOldInput) + { + vs->query_cursor = txt_pt(1, 1+input->first->string.size); + vs->query_mark = txt_pt(1, 1); + } + else + { + vs->query_cursor = txt_pt(1, 1+input->first->string.size); + vs->query_mark = vs->query_cursor; + } + if(!str8_match(current_query_cmd_name, cmd_name, 0)) + { + vs->query_is_selected = 1; + } + else + { + vs->query_is_selected ^= 1; } }break; case RD_CmdKind_CompleteQuery: @@ -15914,7 +15925,6 @@ Z(getting_started) RD_ViewState *vs = rd_view_state_from_cfg(view); vs->query_is_selected = 0; vs->query_string_size = 0; - rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("query"))); } }break; case RD_CmdKind_CancelQuery: diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 33fc8eaa..2bd8628f 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -792,10 +792,6 @@ struct RD_State // rjf: text editing mode state B32 text_edit_mode; - // rjf: string search state - Arena *string_search_arena; - String8 string_search_string; - // rjf: contextual hover info RD_Regs *hover_regs; RD_RegSlot hover_regs_slot; @@ -1146,12 +1142,6 @@ internal void rd_set_autocomp_lister_query_(RD_ListerParams *params); internal void rd_set_autocomp_lister_query_(RD_Regs *regs); #define rd_set_autocomp_lister_query(...) rd_set_autocomp_lister_query_(&(RD_Regs){rd_regs_lit_init_top __VA_ARGS__}) -//////////////////////////////// -//~ rjf: Search Strings - -internal void rd_set_search_string(String8 string); -internal String8 rd_push_search_string(Arena *arena); - //////////////////////////////// //~ rjf: Colors, Fonts, Config diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 4b07362c..56d5ae16 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -83,6 +83,18 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla arena_clear(cv->find_text_arena); cv->find_text_bwd = push_str8_copy(cv->find_text_arena, cmd->regs->string); }break; + case RD_CmdKind_FindNext: + { + String8 string = rd_view_query_input(); + arena_clear(cv->find_text_arena); + cv->find_text_fwd = push_str8_copy(cv->find_text_arena, string); + }break; + case RD_CmdKind_FindPrev: + { + String8 string = rd_view_query_input(); + arena_clear(cv->find_text_arena); + cv->find_text_bwd = push_str8_copy(cv->find_text_arena, string); + }break; case RD_CmdKind_ToggleWatchExpressionAtMouse: { cv->watch_expr_at_mouse = 1; @@ -136,6 +148,29 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla } TXT_LineTokensSlice slice = txt_line_tokens_slice_from_info_data_line_range(scratch.arena, text_info, text_data, visible_line_num_range); + ////////////////////////////// + //- rjf: selection on single line, no query? -> set search text + // + if(rd_regs()->cursor.line == rd_regs()->mark.line) + { + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_ViewState *vs = rd_view_state_from_cfg(view); + if(!vs->query_is_selected) + { + 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")); + String8 text = txt_string_from_info_data_txt_rng(text_info, text_data, txt_rng(rd_regs()->cursor, rd_regs()->mark)); + if(text.size < 256) + { + rd_cfg_new_replace(input, text); + } + else + { + rd_cfg_new_replace(input, str8_zero()); + } + } + } + ////////////////////////////// //- rjf: get active search query // @@ -428,9 +463,10 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla U64 needle_pos = str8_find_needle(line_string, search_start, cv->find_text_fwd, StringMatchFlag_CaseInsensitive); if(needle_pos < line_string.size) { - rd_regs()->cursor.line = line_num; - rd_regs()->cursor.column = needle_pos+1; - rd_regs()->mark = rd_regs()->cursor; + rd_regs()->mark.line = line_num; + rd_regs()->mark.column = needle_pos+1; + rd_regs()->cursor = rd_regs()->mark; + rd_regs()->cursor.column += cv->find_text_fwd.size; found = 1; break; } @@ -460,15 +496,16 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla { B32 found = 0; B32 first = 1; - S64 line_num_start = rd_regs()->cursor.line; + TxtRng rng = txt_rng(rd_regs()->cursor, rd_regs()->mark); + S64 line_num_start = rng.min.line; S64 line_num_last = (S64)text_info->lines_count; for(S64 line_num = line_num_start; 1 <= line_num && line_num <= line_num_last; first = 0) { // rjf: gather line info String8 line_string = str8_substr(text_data, text_info->lines_ranges[line_num-1]); - if(rd_regs()->cursor.line == line_num && first) + if(rng.min.line == line_num && first) { - line_string = str8_prefix(line_string, rd_regs()->cursor.column-1); + line_string = str8_prefix(line_string, rng.min.column-1); } // rjf: search string @@ -484,9 +521,10 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla } if(next_needle_pos < line_string.size) { - rd_regs()->cursor.line = line_num; - rd_regs()->cursor.column = next_needle_pos+1; - rd_regs()->mark = rd_regs()->cursor; + rd_regs()->mark.line = line_num; + rd_regs()->mark.column = next_needle_pos+1; + rd_regs()->cursor = rd_regs()->mark; + rd_regs()->cursor.column += cv->find_text_bwd.size; found = 1; break; } @@ -588,13 +626,6 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla cv->watch_expr_at_mouse = 0; rd_cmd(RD_CmdKind_ToggleWatchExpression, .string = txt_string_from_info_data_txt_rng(text_info, text_data, sig.mouse_expr_rng)); } - - //- rjf: selected text on single line, no query? -> set search text - if(!txt_pt_match(rd_regs()->cursor, rd_regs()->mark) && rd_regs()->cursor.line == rd_regs()->mark.line && search_query.size == 0) - { - String8 text = txt_string_from_info_data_txt_rng(text_info, text_data, txt_rng(rd_regs()->cursor, rd_regs()->mark)); - rd_set_search_string(text); - } } ////////////////////////////// diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index b2c11429..253dcd91 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1960,6 +1960,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ////////////////////////////// //- rjf: interact with margin box & text box // + B32 search_query_invalidated = 0; UI_Signal priority_margin_container_sig = ui_signal_from_box(priority_margin_container_box); UI_Signal catchall_margin_container_sig = ui_signal_from_box(catchall_margin_container_box); UI_Signal text_container_sig = ui_signal_from_box(text_container_box); @@ -2010,6 +2011,12 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe *preferred_column = cursor->column; } + //- rjf: dragging will invalidate the search string, so we don't want to draw it while dragging/releasing + if(ui_dragging(text_container_sig) || ui_released(text_container_sig)) + { + search_query_invalidated = 1; + } + //- rjf: right-click => code context menu if(ui_right_clicked(text_container_sig)) { @@ -2371,7 +2378,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_box_equip_display_fstrs(line_box, &line_fstrs); // rjf: extra rendering for strings that are currently being searched for - if(params->search_query.size != 0) + if(!search_query_invalidated && params->search_query.size != 0) { for(U64 needle_pos = 0; needle_pos < line_string.size;) { @@ -2392,13 +2399,6 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe line_box->rect.y1, }; Vec4F32 color = pop_color; - if(cursor->line == line_num && needle_pos+1 <= cursor->column && cursor->column < needle_pos+params->search_query.size+1) - { - color.x += (1.f - color.x) * 0.5f; - color.y += (1.f - color.y) * 0.5f; - color.z += (1.f - color.z) * 0.5f; - color.w += (1.f - color.w) * 0.5f; - } if(!is_focused) { color.w *= 0.5f;