From bb85f6f6923b78503d44750f1de0c38c463449e2 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 7 Jul 2026 20:09:18 -0700 Subject: [PATCH] text patches: checkpoint --- project.4coder | 2 +- src/base/base_memory_map.c | 36 +- src/base/base_memory_map.h | 1 + src/dbg_engine/dbg_engine_user.c | 2 +- src/dbg_engine/dbg_engine_user.h | 3 +- src/raddbg/generated/raddbg.meta.c | 14 +- src/raddbg/generated/raddbg.meta.h | 14 +- src/raddbg/raddbg.mdesk | 8 +- src/raddbg/raddbg_core.c | 143 +++--- src/raddbg/raddbg_core.h | 5 +- src/raddbg/raddbg_views.c | 428 +++++++++--------- src/raddbg/raddbg_views.h | 4 +- src/raddbg/raddbg_widgets.c | 258 +++++------ src/raddbg/raddbg_widgets.h | 12 +- src/text/text.c | 59 +-- src/text/text.h | 7 +- src/ui/ui_basic_widgets.c | 36 +- src/ui/ui_basic_widgets.h | 4 +- src/ui/ui_core.c | 74 ++- src/ui/ui_core.h | 10 +- .../window_manager/win32_window_manager.c | 6 +- src/window_manager/window_manager.c | 1 + 22 files changed, 562 insertions(+), 565 deletions(-) diff --git a/project.4coder b/project.4coder index 6d11dd66..0b10da9c 100644 --- a/project.4coder +++ b/project.4coder @@ -49,7 +49,7 @@ commands = // .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg debug telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f1 = { .win = "raddbg_stable --ipc kill_all && build radbin", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, - .f1 = { .win = "raddbg_stable --ipc kill_all && build ryan_scratch && pushd build && ryan_scratch && popd", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: [raddbg wsl] // .f1 = { .win = "wsl ./build.sh raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/base/base_memory_map.c b/src/base/base_memory_map.c index 23e37ea7..e774ca81 100644 --- a/src/base/base_memory_map.c +++ b/src/base/base_memory_map.c @@ -18,19 +18,39 @@ memory_map_read(MemoryMap *map, Rng1U64 range, void *dst) { U64 dst_vaddr = range.min; { - for(MemoryMapRangeNode *n = map->first_range; n != 0; n = n->next) + for(;;) { - if(contains_1u64(n->v.vaddr_range, dst_vaddr)) + U64 start_dst_vaddr = dst_vaddr; + B32 found = 0; + for(MemoryMapRangeNode *n = map->first_range; n != 0; n = n->next) { - U64 src_off = dst_vaddr - n->v.vaddr_range.min; - U64 num_bytes_possible = n->v.vaddr_range.max - dst_vaddr; - U64 num_bytes_needed = range.max - dst_vaddr; - U64 num_bytes_to_read = Min(num_bytes_needed, num_bytes_possible); - MemoryCopy((U8 *)dst + (dst_vaddr - range.min), (U8 *)n->v.base + src_off, num_bytes_to_read); - dst_vaddr += num_bytes_to_read; + if(contains_1u64(n->v.vaddr_range, dst_vaddr)) + { + U64 src_off = dst_vaddr - n->v.vaddr_range.min; + U64 num_bytes_possible = n->v.vaddr_range.max - dst_vaddr; + U64 num_bytes_needed = range.max - dst_vaddr; + U64 num_bytes_to_read = Min(num_bytes_needed, num_bytes_possible); + MemoryCopy((U8 *)dst + (dst_vaddr - range.min), (U8 *)n->v.base + src_off, num_bytes_to_read); + dst_vaddr += num_bytes_to_read; + found = 1; + } + } + if(!found || start_dst_vaddr == dst_vaddr) + { + break; } } } U64 bytes_read = (dst_vaddr - range.min); return bytes_read; } + +internal String8 +memory_map_data_from_range(Arena *arena, MemoryMap *map, Rng1U64 range) +{ + String8 result = {0}; + result.size = dim_1u64(range); + result.str = push_array(arena, U8, result.size); + memory_map_read(map, range, result.str); + return result; +} diff --git a/src/base/base_memory_map.h b/src/base/base_memory_map.h index 40a5e4fd..b33f2802 100644 --- a/src/base/base_memory_map.h +++ b/src/base/base_memory_map.h @@ -34,5 +34,6 @@ struct MemoryMap internal void memory_map_push(Arena *arena, MemoryMap *map, Rng1U64 vaddr_range, void *data); internal U64 memory_map_read(MemoryMap *map, Rng1U64 range, void *dst); #define memory_map_read_struct(map, vaddr, ptr) memory_map_read((map), r1u64((vaddr), (vaddr)+sizeof(*(ptr))), (ptr)) +internal String8 memory_map_data_from_range(Arena *arena, MemoryMap *map, Rng1U64 range); #endif // BASE_MEMORY_MAP_H diff --git a/src/dbg_engine/dbg_engine_user.c b/src/dbg_engine/dbg_engine_user.c index bafedc75..9a923aa1 100644 --- a/src/dbg_engine/dbg_engine_user.c +++ b/src/dbg_engine/dbg_engine_user.c @@ -2004,7 +2004,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P if(params->file_path.size != 0) { run_extra_bps.v[0].file_path = params->file_path; - run_extra_bps.v[0].pt = params->cursor; + run_extra_bps.v[0].pt = txt_pt((S64)params->line_num, (S64)params->column_num); } else if(params->vaddr != 0) { diff --git a/src/dbg_engine/dbg_engine_user.h b/src/dbg_engine/dbg_engine_user.h index 2a81e8a8..eb63a750 100644 --- a/src/dbg_engine/dbg_engine_user.h +++ b/src/dbg_engine/dbg_engine_user.h @@ -65,7 +65,8 @@ struct D_CmdParams D_Handle entity; String8 string; String8 file_path; - TxtPt cursor; + U64 line_num; + U64 column_num; U64 vaddr; B32 prefer_disasm; U32 pid; diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index b8bcd0cd..adfc729f 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -477,7 +477,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[39] = {str8_lit_comp("thread"), 0, str8_lit_comp("x:{'label':code_string, 'id':u64, @no_expand 'active':bool, 'call_stack':set}")}, }; -String8 rd_reg_slot_code_name_table[52] = +String8 rd_reg_slot_code_name_table[54] = { {0}, str8_lit_comp("machine"), @@ -499,6 +499,8 @@ str8_lit_comp("inline_depth"), str8_lit_comp("file_path"), str8_lit_comp("cursor"), str8_lit_comp("mark"), +str8_lit_comp("line_num"), +str8_lit_comp("column_num"), str8_lit_comp("text_key"), str8_lit_comp("lang_kind"), str8_lit_comp("lines"), @@ -533,7 +535,7 @@ str8_lit_comp("cmd_name"), str8_lit_comp("wm_event"), }; -Rng1U64 rd_reg_slot_range_table[52] = +Rng1U64 rd_reg_slot_range_table[54] = { {0}, {OffsetOf(RD_Regs, machine), OffsetOf(RD_Regs, machine) + sizeof(D_Handle)}, @@ -553,8 +555,10 @@ Rng1U64 rd_reg_slot_range_table[52] = {OffsetOf(RD_Regs, unwind_count), OffsetOf(RD_Regs, unwind_count) + sizeof(U64)}, {OffsetOf(RD_Regs, inline_depth), OffsetOf(RD_Regs, inline_depth) + sizeof(U64)}, {OffsetOf(RD_Regs, file_path), OffsetOf(RD_Regs, file_path) + sizeof(String8)}, -{OffsetOf(RD_Regs, cursor), OffsetOf(RD_Regs, cursor) + sizeof(TxtPt)}, -{OffsetOf(RD_Regs, mark), OffsetOf(RD_Regs, mark) + sizeof(TxtPt)}, +{OffsetOf(RD_Regs, cursor), OffsetOf(RD_Regs, cursor) + sizeof(U64)}, +{OffsetOf(RD_Regs, mark), OffsetOf(RD_Regs, mark) + sizeof(U64)}, +{OffsetOf(RD_Regs, line_num), OffsetOf(RD_Regs, line_num) + sizeof(U64)}, +{OffsetOf(RD_Regs, column_num), OffsetOf(RD_Regs, column_num) + sizeof(U64)}, {OffsetOf(RD_Regs, text_key), OffsetOf(RD_Regs, text_key) + sizeof(C_Key)}, {OffsetOf(RD_Regs, lang_kind), OffsetOf(RD_Regs, lang_kind) + sizeof(TXT_LangKind)}, {OffsetOf(RD_Regs, lines), OffsetOf(RD_Regs, lines) + sizeof(D_LineList)}, @@ -755,7 +759,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[256] = { str8_lit_comp("insert_text"), str8_lit_comp("Inserts the text that was used to cause this command."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(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("move_next"), str8_lit_comp("Moves the cursor or selection to the next element."), 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("move_prev"), str8_lit_comp("Moves the cursor or selection to the previous element."), 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("goto_line"), str8_lit_comp("Jumps to a line number in the current code file."), 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*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cursor, str8_lit_comp("")}}, +{ str8_lit_comp("goto_line"), str8_lit_comp("Jumps to a line number in the current code file."), 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*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_LineNum, str8_lit_comp("")}}, { str8_lit_comp("goto_address"), str8_lit_comp("Jumps to an address in the current memory or disassembly view."), 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*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp("")}}, { str8_lit_comp("center_cursor"), str8_lit_comp("Snaps the current code view to center the cursor."), 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("contain_cursor"), str8_lit_comp("Snaps the current code view to contain the cursor."), 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("")}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 92db5712..0fb38188 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -28,6 +28,8 @@ RD_RegSlot_InlineDepth, RD_RegSlot_FilePath, RD_RegSlot_Cursor, RD_RegSlot_Mark, +RD_RegSlot_LineNum, +RD_RegSlot_ColumnNum, RD_RegSlot_TextKey, RD_RegSlot_LangKind, RD_RegSlot_Lines, @@ -478,8 +480,10 @@ E_Space eval_space; U64 unwind_count; U64 inline_depth; String8 file_path; -TxtPt cursor; -TxtPt mark; +U64 cursor; +U64 mark; +U64 line_num; +U64 column_num; C_Key text_key; TXT_LangKind lang_kind; D_LineList lines; @@ -581,6 +585,8 @@ Z(getting_started)\ .file_path = rd_regs()->file_path,\ .cursor = rd_regs()->cursor,\ .mark = rd_regs()->mark,\ +.line_num = rd_regs()->line_num,\ +.column_num = rd_regs()->column_num,\ .text_key = rd_regs()->text_key,\ .lang_kind = rd_regs()->lang_kind,\ .lines = rd_regs()->lines,\ @@ -619,8 +625,8 @@ extern String8 rd_tab_fast_path_view_name_table[25]; extern String8 rd_tab_fast_path_query_name_table[25]; extern RD_VocabInfo rd_vocab_info_table[368]; extern RD_NameSchemaInfo rd_name_schema_info_table[39]; -extern String8 rd_reg_slot_code_name_table[52]; -extern Rng1U64 rd_reg_slot_range_table[52]; +extern String8 rd_reg_slot_code_name_table[54]; +extern Rng1U64 rd_reg_slot_range_table[54]; extern String8 rd_binding_version_remap_old_name_table[9]; extern String8 rd_binding_version_remap_new_name_table[9]; extern String8 rd_icon_kind_text_table[75]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index e5e11731..6aea21f3 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -870,8 +870,10 @@ RD_RegTable: // rjf: code / address location info {String8 file_path FilePath } - {TxtPt cursor Cursor } - {TxtPt mark Mark } + {U64 cursor Cursor } + {U64 mark Mark } + {U64 line_num LineNum } + {U64 column_num ColumnNum } {C_Key text_key TextKey } {TXT_LangKind lang_kind LangKind } {D_LineList lines Lines } @@ -1131,7 +1133,7 @@ RD_CmdTable: // | | | {MovePrev 1 1 "" Null 0 0 0 0 0 0 0 Null "move_prev" "Move Previous" "Moves the cursor or selection to the previous element." "" "" } //- rjf: code navigation - {GoToLine 1 1 "" Cursor 0 0 0 0 1 0 1 Null "goto_line" "Go To Line" "Jumps to a line number in the current code file." "" "" } + {GoToLine 1 1 "" LineNum 0 0 0 0 1 0 1 Null "goto_line" "Go To Line" "Jumps to a line number in the current code file." "" "" } {GoToAddress 1 1 "" Vaddr 0 0 0 0 1 0 1 Null "goto_address" "Go To Address" "Jumps to an address in the current memory or disassembly view." "" "" } {CenterCursor 1 1 "" Null 0 0 0 0 0 0 0 Null "center_cursor" "Center Cursor" "Snaps the current code view to center the cursor." "" "" } {ContainCursor 1 1 "" Null 0 0 0 0 0 0 0 Null "contain_cursor" "Contain Cursor" "Snaps the current code view to contain the cursor." "" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 87cc8d0d..ba4c7a30 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1671,13 +1671,6 @@ rd_view_ui(Rng2F32 rect) vs->query_string_size = Min(sizeof(vs->query_buffer), current_input.size); MemoryCopy(vs->query_buffer, current_input.str, vs->query_string_size); - //- rjf: clamp cursor - if(vs->query_cursor.column == 0) - { - vs->query_mark = txt_pt(1, 1); - vs->query_cursor = txt_pt(1, vs->query_string_size+1); - } - //- rjf: determine dimensions F32 search_row_height_target = ui_top_px_height(); F32 search_row_height = search_row_open_t*search_row_height_target; @@ -2622,8 +2615,8 @@ rd_view_ui(Rng2F32 rect) RD_WatchViewTextEditState *edit_state = push_array(ewv->text_edit_arena, RD_WatchViewTextEditState, 1); SLLStackPush_N(ewv->text_edit_state_slots[slot_idx], edit_state, pt_hash_next); edit_state->pt = pt; - edit_state->cursor = txt_pt(1, string.size+1); - edit_state->mark = txt_pt(1, 1); + edit_state->cursor = string.size; + edit_state->mark = 0; edit_state->input_size = string.size; MemoryCopy(edit_state->input_buffer, string.str, string.size); edit_state->initial_size = string.size; @@ -2748,11 +2741,11 @@ rd_view_ui(Rng2F32 rect) CFG_Node *window = cfg_node_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); RD_AutocompCursorInfo *autocomp_cursor_info = &ws->autocomp_cursor_info; - String8 new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(autocomp_cursor_info->replaced_range.min+1, autocomp_cursor_info->replaced_range.max+1), autocomplete_string); + String8 new_string = ui_push_string_replace_range(scratch.arena, string, autocomp_cursor_info->replaced_range, autocomplete_string); new_string.size = Min(sizeof(edit_state->input_buffer), new_string.size); MemoryCopy(edit_state->input_buffer, new_string.str, new_string.size); edit_state->input_size = new_string.size; - edit_state->cursor = edit_state->mark = txt_pt(1, 1+autocomp_cursor_info->replaced_range.min+autocomplete_string.size); + edit_state->cursor = edit_state->mark = autocomp_cursor_info->replaced_range.min+autocomplete_string.size; string = str8(edit_state->input_buffer, edit_state->input_size); op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); } @@ -2765,9 +2758,9 @@ rd_view_ui(Rng2F32 rect) // rjf: obtain edited string String8 new_string = string; - if(!txt_pt_match(op.range.min, op.range.max) || op.replace.size != 0) + if(op.range.min != op.range.max || op.replace.size != 0) { - new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(op.range.min.column, op.range.max.column), op.replace); + new_string = ui_push_string_replace_range(scratch.arena, string, op.range, op.replace); } // rjf: commit to edit state @@ -4235,7 +4228,7 @@ rd_view_ui(Rng2F32 rect) } if(ui_is_focus_active() && selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y && - txt_pt_match(cell_edit_state->cursor, cell_edit_state->mark)) + cell_edit_state->cursor == cell_edit_state->mark) { String8 input = str8(cell_edit_state->input_buffer, cell_edit_state->input_size); rd_set_autocomp_regs(cell->eval, .ui_key = line_edit_key, .string = input, .cursor = cell_edit_state->cursor); @@ -4548,7 +4541,11 @@ rd_view_ui(Rng2F32 rect) { String8 file_path = lines.first->v.file_path; TxtPt pt = lines.first->v.pt; - rd_cmd(RD_CmdKind_FindCodeLocation, .file_path = file_path, .cursor = pt, .vaddr = vaddr, + rd_cmd(RD_CmdKind_FindCodeLocation, + .file_path = file_path, + .line_num = (U64)pt.line, + .column_num = (U64)pt.column, + .vaddr = vaddr, .process = process->handle, .module = module->handle, .dbgi_key = dbgi_key); @@ -4562,7 +4559,11 @@ rd_view_ui(Rng2F32 rect) RD_Location loc = rd_location_from_cfg(cfg); if(loc.file_path.size != 0) { - rd_cmd(RD_CmdKind_FindCodeLocation, .vaddr = 0, .file_path = loc.file_path, .cursor = loc.pt); + rd_cmd(RD_CmdKind_FindCodeLocation, + .vaddr = 0, + .file_path = loc.file_path, + .line_num = (U64)loc.pt.line, + .column_num = (U64)loc.pt.column); } else if(loc.expr.size != 0) { @@ -4594,7 +4595,7 @@ rd_view_ui(Rng2F32 rect) // rjf: is file eval? -> switch to file else if(cell_info.file_path.size != 0) { - rd_cmd(RD_CmdKind_FindCodeLocation, .cfg = 0, .file_path = cell_info.file_path, .cursor = txt_pt(0, 0)); + rd_cmd(RD_CmdKind_FindCodeLocation, .cfg = 0, .file_path = cell_info.file_path, .line_num = 0, .column_num = 0); } } @@ -5943,8 +5944,10 @@ rd_window_frame(void) #undef Handle ui_labelf("file_path: \"%S\"", regs->file_path); ui_labelf("expr: \"%S\"", regs->expr); - ui_labelf("cursor: (L:%I64d, C:%I64d)", regs->cursor.line, regs->cursor.column); - ui_labelf("mark: (L:%I64d, C:%I64d)", regs->mark.line, regs->mark.column); + ui_labelf("cursor: %I64u", regs->cursor); + ui_labelf("mark: %I64u", regs->mark); + ui_labelf("line_num: %I64u", regs->line_num); + ui_labelf("column_num: %I64u", regs->column_num); ui_labelf("unwind_count: %I64u", regs->unwind_count); ui_labelf("inline_depth: %I64u", regs->inline_depth); ui_labelf("text_key: [0x%I64x / 0x%I64x:0x%I64x]", regs->text_key.root.u64[0], regs->text_key.id.u128[0].u64[0], regs->text_key.id.u128[0].u64[1]); @@ -9597,7 +9600,7 @@ rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs) U64 cursor_arg_idx = 0; if(expr_based_replace) { - U64 cursor_off = (U64)(regs->cursor.column-1); + U64 cursor_off = regs->cursor; E_Parse parse = e_parse_from_string(regs->string); //- rjf: cursor offset -> cursor containing node @@ -10478,20 +10481,21 @@ rd_regs_fill_slot_from_string(RD_RegSlot slot, String8 query_expr, String8 strin case RD_RegSlot_FilePath: { String8TxtPtPair pair = str8_txt_pt_pair_from_string(string); - rd_regs()->string = push_str8_copy(rd_frame_arena(), string); + rd_regs()->string = str8_copy(rd_frame_arena(), string); if(pair.pt.line != 0) { - rd_regs()->file_path = push_str8_copy(rd_frame_arena(), pair.string); - rd_regs()->cursor = pair.pt; + rd_regs()->file_path = str8_copy(rd_frame_arena(), pair.string); + rd_regs()->line_num = (U64)pair.pt.line; + rd_regs()->column_num = (U64)pair.pt.column; } }break; case RD_RegSlot_Expr: { - rd_regs()->expr = push_str8_copy(rd_frame_arena(), string); + rd_regs()->expr = str8_copy(rd_frame_arena(), string); }break; case RD_RegSlot_CmdName: { - rd_regs()->cmd_name = push_str8_copy(rd_frame_arena(), string); + rd_regs()->cmd_name = str8_copy(rd_frame_arena(), string); }break; //- rjf: ctrl entities @@ -10563,13 +10567,12 @@ rd_regs_fill_slot_from_string(RD_RegSlot slot, String8 query_expr, String8 strin }break; //- rjf: line numbers - case RD_RegSlot_Cursor: + case RD_RegSlot_LineNum: { E_Eval eval = e_value_eval_from_eval(e_eval_from_string(string)); if(eval.msgs.max_kind == E_MsgKind_Null) { - rd_regs()->cursor.column = 1; - rd_regs()->cursor.line = (S64)eval.value.u64; + rd_regs()->line_num = eval.value.u64; } else { @@ -11168,7 +11171,9 @@ rd_frame(void) rd_state->hover_regs_slot = RD_RegSlot_Null; } B32 allow_text_hotkeys = !rd_state->text_edit_mode; + B32 allow_text_multiline_hotkeys = !rd_state->text_edit_mode_multiline; rd_state->text_edit_mode = 0; + rd_state->text_edit_mode_multiline = 0; if(rd_state->frame_depth == 1) { arena_clear(rd_state->cmd_output_arena); @@ -11688,7 +11693,7 @@ rd_frame(void) if(key_map_nodes.first != 0) { U32 hit_char = wm_codepoint_from_modifiers_and_key(event->modifiers, event->key); - if(hit_char == 0 || allow_text_hotkeys) + if((allow_text_hotkeys || hit_char == 0 || (hit_char == '\n' && allow_text_multiline_hotkeys))) { String8 cmd_name = key_map_nodes.first->v->name; for(U64 idx = 0; idx < ArrayCount(rd_binding_version_remap_old_name_table); idx += 1) @@ -11699,11 +11704,8 @@ rd_frame(void) } } rd_cmd(RD_CmdKind_RunCommand, .cmd_name = cmd_name); - if(allow_text_hotkeys) - { - wm_text(&events, event->window, hit_char); - next = event->next; - } + wm_text(&events, event->window, hit_char); + next = event->next; take = 1; if(event->modifiers & WM_Modifier_Alt) { @@ -11719,7 +11721,7 @@ rd_frame(void) } //- rjf: try text events - if(!take && event->kind == WM_EventKind_Text) + if(!take && event->kind == WM_EventKind_Text && (event->character != '\n' || !allow_text_multiline_hotkeys)) { String32 insertion32 = str32(&event->character, 1); String8 insertion8 = str8_from_32(scratch.arena, insertion32); @@ -13028,7 +13030,8 @@ rd_frame(void) params.entity = rd_regs()->ctrl_entity; params.string = rd_regs()->string; params.file_path = rd_regs()->file_path; - params.cursor = rd_regs()->cursor; + params.line_num = rd_regs()->line_num; + params.column_num = rd_regs()->column_num; params.vaddr = rd_regs()->vaddr; params.prefer_disasm = rd_regs()->prefer_disasm; params.pid = rd_regs()->pid; @@ -14655,7 +14658,7 @@ rd_frame(void) case RD_CmdKind_OpenSourceFileFromDebugInfo: { String8 path = rd_regs()->file_path; - rd_cmd(RD_CmdKind_FindCodeLocation, .file_path = path, .cursor = txt_pt(0, 0), .vaddr = 0, .force_focus = 1, .prefer_new_tab = 1); + rd_cmd(RD_CmdKind_FindCodeLocation, .file_path = path, .line_num = 0, .vaddr = 0, .force_focus = 1, .prefer_new_tab = 1); }break; case RD_CmdKind_SwitchToPartnerFile: { @@ -14682,7 +14685,7 @@ rd_frame(void) FileProperties candidate_props = properties_from_file_path(candidate_path); if(candidate_props.modified != 0) { - rd_cmd(RD_CmdKind_FindCodeLocation, .file_path = candidate_path, .cursor = txt_pt(0, 0), .vaddr = 0, .prefer_new_tab = 1); + rd_cmd(RD_CmdKind_FindCodeLocation, .file_path = candidate_path, .line_num = 0, .vaddr = 0, .prefer_new_tab = 1); break; } } @@ -14718,7 +14721,8 @@ rd_frame(void) { rd_cmd(RD_CmdKind_FindCodeLocation, .file_path = rd_regs()->lines.first->v.file_path, - .cursor = rd_regs()->lines.first->v.pt, + .line_num = (U64)rd_regs()->lines.first->v.pt.line, + .column_num= (U64)rd_regs()->lines.first->v.pt.column, .vaddr = 0, .process = d_handle_zero(), .prefer_disasm = 0); @@ -15020,7 +15024,8 @@ rd_frame(void) { rd_cmd(RD_CmdKind_FindCodeLocation, .file_path = line.file_path, - .cursor = line.pt, + .line_num = (U64)line.pt.line, + .column_num = (U64)line.pt.column, .process = process->handle, .voff = rip_voff, .vaddr = rip_vaddr, @@ -15168,7 +15173,8 @@ rd_frame(void) } rd_cmd(RD_CmdKind_FindCodeLocation, .file_path = lines.first->v.file_path, - .cursor = lines.first->v.pt, + .line_num = (U64)lines.first->v.pt.line, + .column_num= (U64)lines.first->v.pt.column, .process = process->handle, .module = module->handle, .vaddr = module->vaddr_range.min + lines.first->v.voff_range.min); @@ -15178,7 +15184,7 @@ rd_frame(void) // rjf: name resolved to a file path if(name_resolved && file_path.size != 0) { - rd_cmd(RD_CmdKind_FindCodeLocation, .file_path = file_path, .cursor = txt_pt(1, 1), .vaddr = 0); + rd_cmd(RD_CmdKind_FindCodeLocation, .file_path = file_path, .line_num = 0, .vaddr = 0); } } }break; @@ -15230,7 +15236,8 @@ rd_frame(void) //- rjf: grab things to find. path * point, process * address, etc. String8 file_path = {0}; - TxtPt point = {0}; + U64 line_num = 0; + U64 column_num = 0; D_Entity *thread = &d_entity_nil; D_Entity *process = &d_entity_nil; U64 vaddr = 0; @@ -15238,7 +15245,8 @@ rd_frame(void) B32 prefer_new_tab = 0; { file_path = rd_mapped_from_file_path(scratch.arena, rd_regs()->file_path); - point = rd_regs()->cursor; + line_num = rd_regs()->line_num; + column_num = rd_regs()->column_num; thread = d_entity_from_handle(rd_regs()->thread); process = d_entity_from_handle(rd_regs()->process); vaddr = rd_regs()->vaddr; @@ -15267,7 +15275,7 @@ rd_frame(void) // try to map the src coordinates to a vaddr via line info if(vaddr == 0 && file_path.size != 0) { - D_LineList lines = d_lines_from_file_path_line_num(scratch.arena, file_path, point.line, max_U64); + D_LineList lines = d_lines_from_file_path_line_num(scratch.arena, file_path, (S64)line_num, max_U64); for(D_LineNode *n = lines.first; n != 0; n = n->next) { D_EntityList modules = d_modules_from_dbgi_key(scratch.arena, n->v.dbgi_key); @@ -15774,9 +15782,9 @@ rd_frame(void) rd_cmd(RD_CmdKind_FocusPanel); } rd_cmd(RD_CmdKind_FocusTab); - if(point.line != 0) + if(line_num != 0) { - rd_cmd(RD_CmdKind_GoToLine, .cursor = point); + rd_cmd(RD_CmdKind_GoToLine, .line_num = line_num); } rd_cmd(cursor_snap_kind); } @@ -16042,12 +16050,12 @@ rd_frame(void) { if(!vs->query_is_open && 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); + vs->query_cursor = input->first->string.size; + vs->query_mark = 0; } else { - vs->query_cursor = txt_pt(1, 1+input->first->string.size); + vs->query_cursor = input->first->string.size; vs->query_mark = vs->query_cursor; } if(!str8_match(current_query_cmd_name, cmd_name, 0)) @@ -16119,8 +16127,8 @@ rd_frame(void) CFG_Node *input = cfg_node_child_from_string_or_alloc(rd_state->cfg, query, str8_lit("input")); cfg_node_new_replace(rd_state->cfg, 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); + vs->query_cursor = vs->query_mark = vs->query_string_size; MemoryCopy(vs->query_buffer, rd_regs()->string.str, vs->query_string_size); }break; @@ -16227,17 +16235,18 @@ rd_frame(void) // rjf: attach new location info { String8 file_path = rd_regs()->file_path; - TxtPt pt = rd_regs()->cursor; + U64 line_num = rd_regs()->line_num; + U64 column_num = rd_regs()->column_num; String8 expr_string = rd_regs()->expr; U64 vaddr = rd_regs()->vaddr; if(expr_string.size == 0 && vaddr != 0) { expr_string = push_str8f(scratch.arena, "0x%I64x", vaddr); } - if(file_path.size != 0 && pt.line != 0) + if(file_path.size != 0 && line_num != 0) { CFG_Node *src_loc = cfg_node_new(rd_state->cfg, cfg, str8_lit("source_location")); - cfg_node_newf(rd_state->cfg, src_loc, "%S:%I64d:%I64d", file_path, pt.line, pt.column); + cfg_node_newf(rd_state->cfg, src_loc, "%S:%I64u:%I64u", file_path, line_num, column_num); } else if(expr_string.size != 0) { @@ -16259,12 +16268,13 @@ rd_frame(void) case RD_CmdKind_ToggleBreakpoint: { String8 file_path = rd_regs()->file_path; - TxtPt pt = rd_regs()->cursor; + U64 line_num = rd_regs()->line_num; + U64 column_num = rd_regs()->column_num; U64 vaddr = rd_regs()->vaddr; String8 expr = rd_regs()->expr; if(expr.size == 0 && vaddr != 0) { - expr = push_str8f(scratch.arena, "0x%I64x", vaddr); + expr = str8f(scratch.arena, "0x%I64x", vaddr); } if(file_path.size != 0 || expr.size != 0) { @@ -16276,7 +16286,7 @@ rd_frame(void) CFG_Node *bp = n->v; CFG_Node *cnd = cfg_node_child_from_string(bp, str8_lit("condition")); RD_Location loc = rd_location_from_cfg(bp); - B32 loc_matches_file_pt = (file_path.size != 0 && path_match_normalized(loc.file_path, file_path) && loc.pt.line == pt.line); + B32 loc_matches_file_pt = (file_path.size != 0 && path_match_normalized(loc.file_path, file_path) && loc.pt.line == line_num); B32 loc_matches_expr = (expr.size != 0 && str8_match(expr, loc.expr, 0)); if((loc_matches_file_pt || loc_matches_expr) && cnd->first->string.size == 0) { @@ -16341,7 +16351,8 @@ rd_frame(void) case RD_CmdKind_ToggleWatchPin: { String8 file_path = rd_regs()->file_path; - TxtPt pt = rd_regs()->cursor; + U64 line_num = rd_regs()->line_num; + U64 column_num = rd_regs()->column_num; String8 expr_string = rd_regs()->expr; U64 vaddr = rd_regs()->vaddr; B32 removed_already_existing = 0; @@ -16353,7 +16364,7 @@ rd_frame(void) CFG_Node *wp = n->v; CFG_Node *expr = cfg_node_child_from_string(wp, str8_lit("expression")); RD_Location loc = rd_location_from_cfg(wp); - B32 loc_matches_file_pt = (file_path.size != 0 && path_match_normalized(loc.file_path, file_path) && loc.pt.line == pt.line); + B32 loc_matches_file_pt = (file_path.size != 0 && path_match_normalized(loc.file_path, file_path) && loc.pt.line == (S64)line_num); B32 loc_matches_expr = (expr_string.size != 0 && str8_match(expr_string, loc.expr, 0)); if((loc_matches_file_pt || loc_matches_expr) && str8_match(expr->first->string, expr_string, 0)) { @@ -16579,21 +16590,11 @@ rd_frame(void) RD_Regs *regs = rd_regs(); C_Key text_key = regs->text_key; TXT_LangKind lang_kind = regs->lang_kind; - TxtRng range = txt_rng(regs->cursor, regs->mark); + Rng1U64 range = r1u64(regs->cursor, regs->mark); U128 hash = {0}; TXT_TextInfo info = txt_text_info_from_key_lang(access, text_key, lang_kind, &hash); String8 data = c_data_from_hash(access, hash); - TXT_PatchList patches = {0}; - Rng1U64 expr_off_range = {0}; - if(range.min.column != range.max.column) - { - expr_off_range = r1u64(txt_off_from_pt(&info, &patches, range.min), txt_off_from_pt(&info, &patches, range.max)); - } - else - { - expr_off_range = txt_expr_off_range_from_info_data_pt(&info, data, range.min); - } - String8 expr = str8_substr(data, expr_off_range); + String8 expr = str8_substr(data, range); rd_cmd((kind == RD_CmdKind_GoToNameAtCursor ? RD_CmdKind_GoToName : kind == RD_CmdKind_ToggleWatchExpressionAtCursor ? RD_CmdKind_ToggleWatchExpression : RD_CmdKind_GoToName), diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index c473ee8f..5d314d7e 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -152,8 +152,8 @@ struct RD_ViewState // rjf: query state B32 query_is_open; - TxtPt query_cursor; - TxtPt query_mark; + U64 query_cursor; + U64 query_mark; U8 query_buffer[KB(1)]; U64 query_string_size; @@ -496,6 +496,7 @@ struct RD_State // rjf: text editing mode state B32 text_edit_mode; + B32 text_edit_mode_multiline; // rjf: contextual hover info RD_Regs *hover_regs; diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index dd212d48..8c975327 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -48,6 +48,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla D_Entity *thread = d_entity_from_handle(rd_regs()->thread); D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process); B32 do_line_numbers = rd_setting_b32_from_name(str8_lit("show_line_numbers")); + B32 text_is_ready = (text_info->lines_count != 0); ////////////////////////////// //- rjf: unpack information about the viewed source file, if any @@ -66,7 +67,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla default: break; case RD_CmdKind_GoToLine: { - cv->goto_line_num = cmd->regs->cursor.line; + cv->goto_line_num = cmd->regs->line_num; }break; case RD_CmdKind_CenterCursor: { @@ -121,14 +122,17 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla } ////////////////////////////// - //- rjf: do keyboard interaction + //- rjf: do keyboard interaction, compute patched text state // + TXT_Patched text_patched = txt_patched_from_info_data_patches(scratch.arena, text_info, text_data, &cv->patches); B32 snap[Axis2_COUNT] = {0}; UI_Focus(UI_FocusKind_On) if(ui_is_focus_active()) { + rd_state->text_edit_mode = 1; + rd_state->text_edit_mode_multiline = 1; U64 line_count_per_page = ClampBot(num_possible_visible_lines, 10) - 10; - TxtPt *cursor = &rd_regs()->cursor; - TxtPt *mark = &rd_regs()->mark; + U64 *cursor = &rd_regs()->cursor; + U64 *mark = &rd_regs()->mark; S64 *preferred_column = &cv->preferred_column; B32 change = 0; for(UI_Event *evt = 0; ui_next_event(&evt);) @@ -138,96 +142,108 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla continue; } B32 taken = 0; - String8 line = txt_string_from_info_data_line_num(text_info, text_data, cursor->line); - UI_TxtOp single_line_op = ui_single_line_txt_op_from_event(scratch.arena, evt, line, *cursor, *mark); + U64 line_num = txt_line_num_from_off(&text_patched.line_map, *cursor); + Rng1U64 line_range = txt_range_from_line_num(&text_patched.line_map, line_num); + String8 line = {0}; + line.size = dim_1u64(line_range); + line.str = push_array(scratch.arena, U8, line.size); + memory_map_read(&text_patched.memory_map, line_range, line.str); + + //- rjf: try to treat event as single-line operation; map into multi-line space + U64 line_cursor = *cursor - line_range.min; + U64 line_mark = *mark - line_range.min; + UI_TxtOp single_line_op = ui_single_line_txt_op_from_event(scratch.arena, evt, line, line_cursor, line_mark); + single_line_op.range = shift_1u64(single_line_op.range, line_range.min); + single_line_op.cursor += line_range.min; + single_line_op.mark += line_range.min; //- rjf: invalid single-line op or endpoint units => try multiline if(evt->delta_unit == UI_EventDeltaUnit_Whole || single_line_op.flags & UI_TxtOpFlag_Invalid) { - U64 line_count = text_info->lines_count; - String8 prev_line = txt_string_from_info_data_line_num(text_info, text_data, cursor->line-1); - String8 next_line = txt_string_from_info_data_line_num(text_info, text_data, cursor->line+1); + U64 line_count = text_patched.line_map.total_line_count; Vec2S32 delta = evt->delta_2s32; //- rjf: wrap lines right - if(evt->delta_unit != UI_EventDeltaUnit_Whole && delta.x > 0 && cursor->column == line.size+1 && cursor->line+1 <= line_count) + if(evt->delta_unit != UI_EventDeltaUnit_Whole && delta.x > 0 && *cursor == line_range.max+1 && line_num+1 <= line_count) { - cursor->line += 1; - cursor->column = 1; + Rng1U64 next_line_range = txt_range_from_line_num(&text_patched.line_map, line_num+1); + *cursor = next_line_range.min; *preferred_column = 1; change = 1; taken = 1; } //- rjf: wrap lines left - if(evt->delta_unit != UI_EventDeltaUnit_Whole && delta.x < 0 && cursor->column == 1 && cursor->line-1 >= 1) + if(evt->delta_unit != UI_EventDeltaUnit_Whole && delta.x < 0 && *cursor == line_range.min && line_num-1 >= 1) { - cursor->line -= 1; - cursor->column = prev_line.size+1; - *preferred_column = prev_line.size+1; + Rng1U64 prev_line_range = txt_range_from_line_num(&text_patched.line_map, line_num-1); + *cursor = prev_line_range.max; + *preferred_column = (S64)dim_1u64(prev_line_range)+1; change = 1; taken = 1; } //- rjf: movement down (plain) - if(evt->delta_unit == UI_EventDeltaUnit_Char && delta.y > 0 && cursor->line+1 <= line_count) + if(evt->delta_unit == UI_EventDeltaUnit_Char && delta.y > 0 && line_num+1 <= line_count) { - cursor->line += 1; - cursor->column = Min(*preferred_column, next_line.size+1); + Rng1U64 next_line_range = txt_range_from_line_num(&text_patched.line_map, line_num+1); + *cursor = next_line_range.min + *preferred_column; + *cursor = clamp_1u64(next_line_range, *cursor); change = 1; taken = 1; } //- rjf: movement up (plain) - if(evt->delta_unit == UI_EventDeltaUnit_Char && delta.y < 0 && cursor->line-1 >= 1) + if(evt->delta_unit == UI_EventDeltaUnit_Char && delta.y < 0 && line_num > 1) { - cursor->line -= 1; - cursor->column = Min(*preferred_column, prev_line.size+1); + Rng1U64 prev_line_range = txt_range_from_line_num(&text_patched.line_map, line_num-1); + *cursor = prev_line_range.min + *preferred_column; + *cursor = clamp_1u64(prev_line_range, *cursor); change = 1; taken = 1; } //- rjf: movement down (chunk) - if(evt->delta_unit == UI_EventDeltaUnit_Word && delta.y > 0 && cursor->line+1 <= line_count) + if(evt->delta_unit == UI_EventDeltaUnit_Word && delta.y > 0 && line_num+1 <= line_count) { - for(S64 line_num = cursor->line+1; line_num <= line_count; line_num += 1) + for(U64 scan_line_num = line_num+1; scan_line_num <= line_count; scan_line_num += 1) { - String8 line = txt_string_from_info_data_line_num(text_info, text_data, line_num); - U64 line_size = line.size; - if(line_size == 0) + Temp scratch = scratch_begin(&arena, 1); + Rng1U64 line_range = txt_range_from_line_num(&text_patched.line_map, scan_line_num); + String8 line = memory_map_data_from_range(scratch.arena, &text_patched.memory_map, line_range); + String8 line_without_whitespace = str8_skip_chop_whitespace(line); + if(line_without_whitespace.size == 0) { - cursor->line = line_num; - cursor->column = 1; - break; + *cursor = line_range.min + (U64)(line_without_whitespace.str - line.str); } - else if(line_num == line_count) + else if(scan_line_num == line_count) { - cursor->line = line_num; - cursor->column = line_size+1; + *cursor = text_patched.size; } + scratch_end(scratch); } change = 1; taken = 1; } //- rjf: movement up (chunk) - if(evt->delta_unit == UI_EventDeltaUnit_Word && delta.y < 0 && cursor->line-1 >= 1) + if(evt->delta_unit == UI_EventDeltaUnit_Word && delta.y < 0 && line_num > 1) { - for(S64 line_num = cursor->line-1; line_num > 0; line_num -= 1) + for(U64 scan_line_num = line_num-1; scan_line_num > 0; scan_line_num -= 1) { - String8 line = txt_string_from_info_data_line_num(text_info, text_data, line_num); - U64 line_size = line.size; - if(line_size == 0) + Temp scratch = scratch_begin(&arena, 1); + Rng1U64 line_range = txt_range_from_line_num(&text_patched.line_map, scan_line_num); + String8 line = memory_map_data_from_range(scratch.arena, &text_patched.memory_map, line_range); + String8 line_without_whitespace = str8_skip_chop_whitespace(line); + if(line_without_whitespace.size == 0) { - cursor->line = line_num; - cursor->column = 1; - break; + *cursor = line_range.min + (U64)(line_without_whitespace.str - line.str); } - else if(line_num == 1) + else if(scan_line_num == 1) { - cursor->line = line_num; - cursor->column = 1; + *cursor = 0; } + scratch_end(scratch); } change = 1; taken = 1; @@ -236,9 +252,11 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla //- rjf: movement down (page) if(evt->delta_unit == UI_EventDeltaUnit_Page && delta.y > 0) { - cursor->line += line_count_per_page; - cursor->column = 1; - cursor->line = Clamp(1, cursor->line, line_count); + U64 advance = line_count_per_page; + U64 next_line = line_num + advance; + U64 next_line_clamped = Clamp(1, next_line, text_patched.line_map.total_line_count); + Rng1U64 next_line_range = txt_range_from_line_num(&text_patched.line_map, next_line_clamped); + *cursor = next_line_range.min; change = 1; taken = 1; } @@ -246,9 +264,15 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla //- rjf: movement up (page) if(evt->delta_unit == UI_EventDeltaUnit_Page && delta.y < 0) { - cursor->line -= line_count_per_page; - cursor->column = 1; - cursor->line = Clamp(1, cursor->line, line_count); + S64 advance = -line_count_per_page; + if(line_num < line_count_per_page) + { + advance = -(line_num - 1); + } + U64 next_line = (U64)((S64)line_num + line_count_per_page); + U64 next_line_clamped = Clamp(1, next_line, text_patched.line_map.total_line_count); + Rng1U64 next_line_range = txt_range_from_line_num(&text_patched.line_map, next_line_clamped); + *cursor = next_line_range.min; change = 1; taken = 1; } @@ -256,7 +280,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla //- rjf: movement to endpoint (+) if(evt->delta_unit == UI_EventDeltaUnit_Whole && (delta.y > 0 || delta.x > 0)) { - *cursor = txt_pt(line_count, text_info->lines_count ? dim_1u64(text_info->lines_ranges[text_info->lines_count-1])+1 : 1); + *cursor = txt_range_from_line_num(&text_patched.line_map, text_patched.line_map.total_line_count).max; change = 1; taken = 1; } @@ -264,7 +288,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla //- rjf: movement to endpoint (-) if(evt->delta_unit == UI_EventDeltaUnit_Whole && (delta.y < 0 || delta.x < 0)) { - *cursor = txt_pt(1, 1); + *cursor = 0; change = 1; taken = 1; } @@ -279,17 +303,16 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla //- rjf: valid single-line op => do single-line op else { -#if 0 - if(single_line_op.replace.size != 0) + if(single_line_op.range.min != single_line_op.range.max || single_line_op.replace.size != 0) { - Rng1U64 range = r1u64(txt_off_from_pt(text_info, &cv->patches, *cursor), - txt_off_from_pt(text_info, &cv->patches, *mark)); - txt_patch_list_push_new(cv->patch_arena, &cv->patches, range, single_line_op.replace); + txt_patch_list_push_new(cv->patch_arena, &cv->patches, single_line_op.range, single_line_op.replace); + text_patched = txt_patched_from_info_data_patches(scratch.arena, text_info, text_data, &cv->patches); } -#endif *cursor = single_line_op.cursor; *mark = single_line_op.mark; - *preferred_column = cursor->column; + U64 line_num = txt_line_num_from_off(&text_patched.line_map, *cursor); + Rng1U64 line_range = txt_range_from_line_num(&text_patched.line_map, line_num); + *preferred_column = (*cursor - line_range.min); change = 1; taken = 1; } @@ -297,7 +320,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla //- rjf: copy if(evt->flags & UI_EventFlag_Copy) { - String8 text = txt_string_from_info_data_txt_rng(text_info, text_data, &cv->patches, txt_rng(*cursor, *mark)); + String8 text = memory_map_data_from_range(scratch.arena, &text_patched.memory_map, r1u64(*cursor, *mark)); wm_set_clipboard_text(text); taken = 1; } @@ -310,11 +333,6 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla } } - ////////////////////////////// - //- rjf: compute current patched text state - // - TXT_Patched text_patched = txt_patched_from_info_data_patches(scratch.arena, text_info, text_data, &cv->patches); - ////////////////////////////// //- rjf: determine visible line range / count // @@ -324,12 +342,12 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla scroll_pos.y.idx + 1 + num_possible_visible_lines); U64 visible_line_count = 0; { - visible_line_num_range.min = Clamp(1, visible_line_num_range.min, (S64)text_info->lines_count); - visible_line_num_range.max = Clamp(1, visible_line_num_range.max, (S64)text_info->lines_count); + visible_line_num_range.min = Clamp(1, visible_line_num_range.min, (S64)text_patched.line_map.total_line_count); + visible_line_num_range.max = Clamp(1, visible_line_num_range.max, (S64)text_patched.line_map.total_line_count); visible_line_num_range.min = Max(1, visible_line_num_range.min); visible_line_num_range.max = Max(1, visible_line_num_range.max); - target_visible_line_num_range.min = Clamp(1, target_visible_line_num_range.min, (S64)text_info->lines_count); - target_visible_line_num_range.max = Clamp(1, target_visible_line_num_range.max, (S64)text_info->lines_count); + target_visible_line_num_range.min = Clamp(1, target_visible_line_num_range.min, (S64)text_patched.line_map.total_line_count); + target_visible_line_num_range.max = Clamp(1, target_visible_line_num_range.max, (S64)text_patched.line_map.total_line_count); target_visible_line_num_range.min = Max(1, target_visible_line_num_range.min); target_visible_line_num_range.max = Max(1, target_visible_line_num_range.max); visible_line_count = (U64)dim_1s64(visible_line_num_range)+1; @@ -345,7 +363,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla line_size_x = ClampBot(line_size_x, (S64)big_glyph_advance*120); line_size_x = ClampBot(line_size_x, (S64)code_area_dim.x); scroll_idx_rng[Axis2_X] = r1s64(0, line_size_x-(S64)code_area_dim.x); - scroll_idx_rng[Axis2_Y] = r1s64(0, (S64)text_info->lines_count-1); + scroll_idx_rng[Axis2_Y] = r1s64(0, (S64)text_patched.line_map.total_line_count-1); } ////////////////////////////// @@ -368,22 +386,28 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla ////////////////////////////// //- rjf: selection on single line, no query? -> set search text // - if(rd_regs()->cursor.line == rd_regs()->mark.line) { - CFG_Node *view = cfg_node_from_id(rd_regs()->view); - RD_ViewState *vs = rd_view_state_from_cfg(view); - if(!vs->query_is_open) + U64 cursor = rd_regs()->cursor; + U64 mark = rd_regs()->mark; + U64 cursor_line_num = txt_line_num_from_off(&text_patched.line_map, cursor); + Rng1U64 cursor_line_range = txt_range_from_line_num(&text_patched.line_map, cursor_line_num); + if(cursor_line_range.min <= mark && mark <= cursor_line_range.max) { - CFG_Node *query = cfg_node_child_from_string_or_alloc(rd_state->cfg, view, str8_lit("query")); - CFG_Node *input = cfg_node_child_from_string_or_alloc(rd_state->cfg, query, str8_lit("input")); - String8 text = txt_string_from_info_data_txt_rng(text_info, text_data, &cv->patches, txt_rng(rd_regs()->cursor, rd_regs()->mark)); - if(text.size < 256) + CFG_Node *view = cfg_node_from_id(rd_regs()->view); + RD_ViewState *vs = rd_view_state_from_cfg(view); + if(!vs->query_is_open) { - cfg_node_new_replace(rd_state->cfg, input, text); - } - else - { - cfg_node_new_replace(rd_state->cfg, input, str8_zero()); + CFG_Node *query = cfg_node_child_from_string_or_alloc(rd_state->cfg, view, str8_lit("query")); + CFG_Node *input = cfg_node_child_from_string_or_alloc(rd_state->cfg, query, str8_lit("input")); + String8 text = memory_map_data_from_range(scratch.arena, &text_patched.memory_map, r1u64(cursor, mark)); + if(text.size < 256) + { + cfg_node_new_replace(rd_state->cfg, input, text); + } + else + { + cfg_node_new_replace(rd_state->cfg, input, str8_zero()); + } } } } @@ -436,12 +460,18 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla S64 line_num = visible_line_num_range.min; U64 line_idx = visible_line_num_range.min-1; for(U64 visible_line_idx = 0; - visible_line_idx < visible_line_count && line_idx < text_info->lines_count; + visible_line_idx < visible_line_count && line_idx < text_patched.line_map.total_line_count; visible_line_idx += 1, line_idx += 1, line_num += 1) { - code_slice_params.line_text[visible_line_idx] = txt_string_from_info_data_line_num(text_info, text_data, line_num); - code_slice_params.line_ranges[visible_line_idx] = text_info->lines_ranges[line_idx]; - code_slice_params.line_tokens[visible_line_idx] = slice.line_tokens[visible_line_idx]; + Rng1U64 line_range = txt_range_from_line_num(&text_patched.line_map, line_num); + String8 line_text = {0}; + line_text.size = dim_1u64(line_range); + line_text.str = push_array(scratch.arena, U8, line_text.size); + memory_map_read(&text_patched.memory_map, line_range, line_text.str); + code_slice_params.line_text[visible_line_idx] = line_text; + code_slice_params.line_ranges[visible_line_idx] = line_range; + // TODO(rjf): tokens + // code_slice_params.line_tokens[visible_line_idx] = slice.line_tokens[visible_line_idx]; } } @@ -683,111 +713,75 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla //- rjf: do searching operations // { + U64 search_chunk_size = KB(4); + //- rjf: find text (forward) if(cv->find_text_fwd.size != 0) { - B32 found = 0; - B32 first = 1; - S64 line_num_start = rd_regs()->cursor.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) + String8 needle = cv->find_text_fwd; + B32 done = 0; + for(U64 off = rd_regs()->cursor+1; !done && off < text_patched.size; off += search_chunk_size) { - // rjf: gather line info - String8 line_string = str8_substr(text_data, text_info->lines_ranges[line_num-1]); - U64 search_start = 0; - if(rd_regs()->cursor.line == line_num && first) + Temp scratch = scratch_begin(&arena, 1); + String8 data = memory_map_data_from_range(scratch.arena, &text_patched.memory_map, r1u64(off, off+search_chunk_size)); + U64 needle_pos = str8_find_needle(data, 0, needle, StringMatchFlag_CaseInsensitive); + if(needle_pos < data.size) { - search_start = rd_regs()->cursor.column; - } - - // rjf: search string - U64 needle_pos = str8_find_needle(line_string, search_start, cv->find_text_fwd, StringMatchFlag_CaseInsensitive); - if(needle_pos < line_string.size) - { - 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; - } - - // rjf: break if circled back around to cursor - else if(line_num == line_num_start && !first) - { - break; - } - - // rjf: increment - line_num += 1; - if(line_num > line_num_last) - { - line_num = 1; + done = 1; + rd_regs()->mark = needle_pos; + rd_regs()->cursor = rd_regs()->mark + needle.size; } + scratch_end(scratch); } - cv->center_cursor = found; - if(found == 0) + if(!done) { - log_user_errorf("Could not find `%S`", cv->find_text_fwd); + log_user_errorf("Could not find `%S`", needle); } + cv->center_cursor = done; } //- rjf: find text (backward) - if(cv->find_text_bwd.size != 0) + if(cv->find_text_bwd.size != 0 && rd_regs()->cursor > 0) { - B32 found = 0; - B32 first = 1; - 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) + String8 needle = cv->find_text_bwd; + B32 done = 0; + for(U64 off = rd_regs()->cursor-1, next_off = 0; !done; off = next_off) { - // rjf: gather line info - String8 line_string = str8_substr(text_data, text_info->lines_ranges[line_num-1]); - if(rng.min.line == line_num && first) + U64 advance = Min(search_chunk_size, off); + next_off = off - advance; + Temp scratch = scratch_begin(&arena, 1); + String8 data = memory_map_data_from_range(scratch.arena, &text_patched.memory_map, r1u64(off, off+search_chunk_size)); + U64 needle_pos = 0; { - line_string = str8_prefix(line_string, rng.min.column-1); - } - - // rjf: search string - U64 next_needle_pos = line_string.size; - for(U64 needle_pos = 0; needle_pos < line_string.size;) - { - needle_pos = str8_find_needle(line_string, needle_pos, cv->find_text_bwd, StringMatchFlag_CaseInsensitive); - if(needle_pos < line_string.size) + U64 start_search_pos = 0; + for(;;) { - next_needle_pos = needle_pos; - needle_pos += 1; + U64 next_needle_pos = str8_find_needle(data, start_search_pos, needle, StringMatchFlag_CaseInsensitive); + if(next_needle_pos < data.size) + { + needle_pos = next_needle_pos; + } + else + { + needle_pos = data.size; + break; + } + start_search_pos = next_needle_pos+1; } } - if(next_needle_pos < line_string.size) + if(needle_pos < data.size) { - 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; - } - - // rjf: break if circled back around to cursor line - else if(line_num == line_num_start && !first) - { - break; - } - - // rjf: increment - line_num -= 1; - if(line_num == 0) - { - line_num = line_num_last; + done = 1; + rd_regs()->mark = needle_pos; + rd_regs()->cursor = rd_regs()->mark + needle.size; } + scratch_end(scratch); } - cv->center_cursor = found; - if(found == 0) + if(!done) { - log_user_errorf("Could not find `%S`", cv->find_text_bwd); + log_user_errorf("Could not find `%S`", needle); } + cv->center_cursor = done; } MemoryZeroStruct(&cv->find_text_fwd); @@ -798,12 +792,13 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla ////////////////////////////// //- rjf: do goto line // - if(cv->goto_line_num != 0 && text_info->lines_count != 0) + if(cv->goto_line_num != 0 && text_is_ready) { S64 line_num = cv->goto_line_num; cv->goto_line_num = 0; - line_num = Clamp(1, line_num, text_info->lines_count); - rd_regs()->cursor = rd_regs()->mark = txt_pt(line_num, 1); + line_num = Clamp(1, line_num, text_patched.line_map.total_line_count); + Rng1U64 range = txt_range_from_line_num(&text_patched.line_map, line_num); + rd_regs()->cursor = rd_regs()->mark = range.min; cv->center_cursor = !cv->force_contain_only && (!cv->contain_cursor || (line_num < target_visible_line_num_range.min+4 || target_visible_line_num_range.max-4 < line_num)); } @@ -846,27 +841,28 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla if(ui_pressed(sig.base) && sig.base.event_flags & WM_Modifier_Ctrl) { ui_kill_action(); - rd_cmd(RD_CmdKind_GoToName, .string = txt_string_from_info_data_txt_rng(text_info, text_data, &cv->patches, sig.mouse_expr_rng)); + rd_cmd(RD_CmdKind_GoToName, .string = memory_map_data_from_range(scratch.arena, &text_patched.memory_map, sig.mouse_expr_rng)); } //- rjf: watch expr at mouse if(cv->watch_expr_at_mouse) { cv->watch_expr_at_mouse = 0; - rd_cmd(RD_CmdKind_ToggleWatchExpression, .string = txt_string_from_info_data_txt_rng(text_info, text_data, &cv->patches, sig.mouse_expr_rng)); + rd_cmd(RD_CmdKind_ToggleWatchExpression, .string = memory_map_data_from_range(scratch.arena, &text_patched.memory_map, sig.mouse_expr_rng)); } } ////////////////////////////// //- rjf: apply post-build view snapping rules // - if(text_info->lines_count != 0) + if(text_is_ready) { - TxtPt cursor = rd_regs()->cursor; - B32 cursor_in_range = (1 <= cursor.line && cursor.line <= text_info->lines_count); + U64 cursor = rd_regs()->cursor; + U64 cursor_line_num = txt_line_num_from_off(&text_patched.line_map, cursor); + B32 cursor_in_range = (1 <= cursor_line_num && cursor_line_num <= text_patched.line_map.total_line_count); // rjf: contain => snap - if(cv->contain_cursor && text_info->lines_count != 0) + if(cv->contain_cursor) { cv->contain_cursor = 0; snap[Axis2_X] = 1; @@ -874,13 +870,14 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla } // rjf: center cursor - if(cv->center_cursor && text_info->lines_count != 0) + if(cv->center_cursor) { cv->center_cursor = 0; if(cursor_in_range) { - String8 cursor_line = str8_substr(text_data, text_info->lines_ranges[cursor.line-1]); - F32 cursor_advance = fnt_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, cursor.column-1)).x; + Rng1U64 cursor_line_range = txt_range_from_line_num(&text_patched.line_map, cursor_line_num); + String8 cursor_line = memory_map_data_from_range(scratch.arena, &text_patched.memory_map, cursor_line_range); + F32 cursor_advance = fnt_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, cursor-cursor_line_range.min)).x; // rjf: scroll x { @@ -892,7 +889,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla // rjf: scroll y { - S64 new_idx = (cursor.line-1) - num_possible_visible_lines/2 + 2; + S64 new_idx = ((S64)cursor_line_num-1) - num_possible_visible_lines/2 + 2; new_idx = Clamp(scroll_idx_rng[Axis2_Y].min, new_idx, scroll_idx_rng[Axis2_Y].max); ui_scroll_pt_target_idx(&scroll_pos.y, new_idx); snap[Axis2_Y] = 0; @@ -903,8 +900,9 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla // rjf: snap in X if(snap[Axis2_X] && cursor_in_range) { - String8 cursor_line = str8_substr(text_data, text_info->lines_ranges[cursor.line-1]); - S64 cursor_off = (S64)(fnt_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, cursor.column-1)).x + priority_margin_width_px + catchall_margin_width_px + line_num_width_px); + Rng1U64 cursor_line_range = txt_range_from_line_num(&text_patched.line_map, cursor_line_num); + String8 cursor_line = memory_map_data_from_range(scratch.arena, &text_patched.memory_map, cursor_line_range); + S64 cursor_off = (S64)(fnt_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, cursor-cursor_line_range.min)).x + priority_margin_width_px + catchall_margin_width_px + line_num_width_px); Rng1S64 visible_pixel_range = { scroll_pos.x.idx, @@ -925,13 +923,13 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla // rjf: snap in Y if(snap[Axis2_Y]) { - Rng1S64 cursor_visibility_range = r1s64(cursor.line-4, cursor.line+4); + Rng1S64 cursor_visibility_range = r1s64((S64)cursor_line_num-4, (S64)cursor_line_num+4); cursor_visibility_range.min = ClampBot(0, cursor_visibility_range.min); cursor_visibility_range.max = ClampBot(0, cursor_visibility_range.max); S64 min_delta = Min(0, cursor_visibility_range.min-(target_visible_line_num_range.min)); S64 max_delta = Max(0, cursor_visibility_range.max-(target_visible_line_num_range.min+num_possible_visible_lines)); S64 new_idx = scroll_pos.y.idx+min_delta+max_delta; - new_idx = Clamp(0, new_idx, (S64)text_info->lines_count-1); + new_idx = Clamp(0, new_idx, (S64)text_patched.line_map.total_line_count-1); ui_scroll_pt_target_idx(&scroll_pos.y, new_idx); } } @@ -973,7 +971,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla ////////////////////////////// //- rjf: top-level container interaction (scrolling) // - if(text_info->lines_count != 0) + if(text_is_ready) { UI_Signal sig = ui_signal_from_box(container_box); if(sig.scroll.x != 0) @@ -2263,14 +2261,8 @@ RD_VIEW_UI_FUNCTION_DEF(text) rd_regs()->file_path = rd_file_path_from_eval(rd_frame_arena(), eval); rd_regs()->vaddr = 0; rd_regs()->prefer_disasm = 0; - rd_regs()->cursor.line = rd_view_setting_value_from_name(str8_lit("cursor_line")).s64; - rd_regs()->cursor.column = rd_view_setting_value_from_name(str8_lit("cursor_column")).s64; - rd_regs()->mark.line = rd_view_setting_value_from_name(str8_lit("mark_line")).s64; - rd_regs()->mark.column = rd_view_setting_value_from_name(str8_lit("mark_column")).s64; - if(rd_regs()->cursor.line == 0) { rd_regs()->cursor.line = 1; } - if(rd_regs()->cursor.column == 0) { rd_regs()->cursor.column = 1; } - if(rd_regs()->mark.line == 0) { rd_regs()->mark.line = 1; } - if(rd_regs()->mark.column == 0) { rd_regs()->mark.column = 1; } + rd_regs()->cursor = rd_view_setting_value_from_name(s("cursor")).u64; + rd_regs()->mark = rd_view_setting_value_from_name(s("mark")).u64; String8List overrides = rd_possible_overrides_from_file_path(scratch.arena, rd_regs()->file_path); Rng1U64 range = rd_space_range_from_eval(eval); rd_regs()->text_key = rd_key_from_eval_space_range(eval.space, range, 1); @@ -2404,6 +2396,12 @@ RD_VIEW_UI_FUNCTION_DEF(text) rd_code_view_build(scratch.arena, cv, flags, code_area_rect, hash, data, &info, 0, r1u64(0, 0), di_key_zero()); } + ////////////////////////////// + //- rjf: produced patched text info, unpack cursor info in patched text + // + TXT_Patched patched = txt_patched_from_info_data_patches(scratch.arena, &info, data, &cv->patches); + U64 cursor_line_num = txt_line_num_from_off(&patched.line_map, rd_regs()->cursor); + ////////////////////////////// //- rjf: unpack cursor info // @@ -2411,7 +2409,7 @@ RD_VIEW_UI_FUNCTION_DEF(text) { D_Entity *module = d_entity_from_handle(rd_regs()->module); DI_Key dbgi_key = d_dbgi_key_from_module(module); - rd_regs()->lines = d_lines_from_dbgi_key_file_path_line_num(rd_frame_arena(), dbgi_key, rd_regs()->file_path, rd_regs()->cursor.line, 8); + rd_regs()->lines = d_lines_from_dbgi_key_file_path_line_num(rd_frame_arena(), dbgi_key, rd_regs()->file_path, (S64)cursor_line_num, 8); } ////////////////////////////// @@ -2521,7 +2519,8 @@ RD_VIEW_UI_FUNCTION_DEF(text) ui_label(rd_regs()->file_path); ui_spacer(ui_em(1.5f, 1)); } - ui_labelf("Line: %I64d, Column: %I64d", rd_regs()->cursor.line, rd_regs()->cursor.column); + Rng1U64 cursor_line_range = txt_range_from_line_num(&patched.line_map, cursor_line_num); + ui_labelf("Line: %I64d, Column: %I64d", cursor_line_num, 1 + rd_regs()->cursor - cursor_line_range.min); ui_spacer(ui_pct(1, 0)); ui_labelf("(read only)"); ui_labelf("%s", @@ -2535,10 +2534,8 @@ RD_VIEW_UI_FUNCTION_DEF(text) ////////////////////////////// //- rjf: store params // - rd_store_view_param_s64(str8_lit("cursor_line"), rd_regs()->cursor.line); - rd_store_view_param_s64(str8_lit("cursor_column"), rd_regs()->cursor.column); - rd_store_view_param_s64(str8_lit("mark_line"), rd_regs()->mark.line); - rd_store_view_param_s64(str8_lit("mark_column"), rd_regs()->mark.column); + rd_store_view_param_u64(s("cursor"), rd_regs()->cursor); + rd_store_view_param_u64(s("mark"), rd_regs()->mark); access_close(access); scratch_end(scratch); @@ -2551,8 +2548,8 @@ typedef struct RD_DisasmViewState RD_DisasmViewState; struct RD_DisasmViewState { B32 initialized; - TxtPt cursor; - TxtPt mark; + U64 cursor; + U64 mark; D_Handle temp_look_process; U64 temp_look_vaddr; U64 temp_look_run_gen; @@ -2574,8 +2571,8 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) if(dv->initialized == 0) { dv->initialized = 1; - dv->cursor = txt_pt(1, 1); - dv->mark = txt_pt(1, 1); + dv->cursor = 0; + dv->mark = 0; rd_code_view_init(&dv->cv); } RD_CodeViewState *cv = &dv->cv; @@ -2747,13 +2744,19 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) rd_code_view_build(scratch.arena, cv, RD_CodeViewBuildFlag_All, code_area_rect, dasm_text_hash, dasm_text_data, &dasm_text_info, &dasm_info.lines, range, dbgi_key); } + ////////////////////////////// + //- rjf: produced patched text info, unpack cursor info in patched text + // + TXT_Patched patched = txt_patched_from_info_data_patches(scratch.arena, &dasm_text_info, dasm_text_data, &cv->patches); + U64 cursor_line_num = txt_line_num_from_off(&patched.line_map, rd_regs()->cursor); + ////////////////////////////// //- rjf: unpack cursor info / fill regs // rd_regs()->prefer_disasm = 1; if(!is_loading && has_disasm) { - U64 off = dasm_line_array_code_off_from_idx(&dasm_info.lines, rd_regs()->cursor.line-1); + U64 off = dasm_line_array_code_off_from_idx(&dasm_info.lines, cursor_line_num-1); rd_regs()->vaddr = range.min+off; rd_regs()->vaddr_range = r1u64(range.min+off, range.min+off); rd_regs()->voff_range = d_voff_range_from_vaddr_range(dasm_module, rd_regs()->vaddr_range); @@ -2773,13 +2776,14 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) UI_TagF("weak") RD_Font(RD_FontSlot_Code) { - U64 cursor_vaddr = (1 <= rd_regs()->cursor.line && rd_regs()->cursor.line <= dasm_info.lines.count) ? (range.min+dasm_info.lines.v[rd_regs()->cursor.line-1].code_off) : 0; + U64 cursor_vaddr = (1 <= cursor_line_num && cursor_line_num <= dasm_info.lines.count) ? (range.min+dasm_info.lines.v[cursor_line_num-1].code_off) : 0; if(dasm_module != &d_entity_nil) { ui_labelf("%S", dasm_module->string); ui_spacer(ui_em(1.5f, 1)); } - ui_labelf("Address: 0x%I64x, Line: %I64d, Column: %I64d", cursor_vaddr, rd_regs()->cursor.line, rd_regs()->cursor.column); + Rng1U64 cursor_line_range = txt_range_from_line_num(&patched.line_map, cursor_line_num); + ui_labelf("Address: 0x%I64x, Line: %I64d, Column: %I64d", cursor_vaddr, cursor_line_num, 1 + rd_regs()->cursor - cursor_line_range.min); ui_spacer(ui_pct(1, 0)); ui_labelf("(read only)"); ui_labelf("bin"); @@ -2813,8 +2817,8 @@ struct RD_MemoryViewState B32 snap_scroll; B32 cell_value_edit_in_progress; U8 cell_value_edit_first_digit; - TxtPt addrbar_cursor; - TxtPt addrbar_mark; + U64 addrbar_cursor; + U64 addrbar_mark; U8 addrbar_buffer[1024]; U64 addrbar_string_size; B32 addrbar_is_focused; @@ -4587,8 +4591,8 @@ RD_VIEW_UI_FUNCTION_DEF(memory) mv->addrbar_is_focused = 1; mv->addrbar_string_size = Min(sizeof(mv->addrbar_buffer), cursor_addr->first->string.size); MemoryCopy(mv->addrbar_buffer, cursor_addr->first->string.str, mv->addrbar_string_size); - mv->addrbar_cursor = txt_pt(1, mv->addrbar_string_size+1); - mv->addrbar_mark = txt_pt(1, 1); + mv->addrbar_cursor = mv->addrbar_string_size+1; + mv->addrbar_mark = 0; } if(commit_addrbar) { diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 7e5b22ab..1bae6b7d 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -163,8 +163,8 @@ struct RD_WatchViewTextEditState { RD_WatchViewTextEditState *pt_hash_next; RD_WatchPt pt; - TxtPt cursor; - TxtPt mark; + U64 cursor; + U64 mark; U8 input_buffer[1024]; U64 input_size; U8 initial_buffer[1024]; diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index b4d7c3a0..f99d3151 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1291,7 +1291,7 @@ internal UI_BOX_CUSTOM_DRAW(rd_bp_box_draw_extensions) } internal RD_CodeSliceSignal -rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *preferred_column, String8 string) +rd_code_slice(RD_CodeSliceParams *params, U64 *cursor, U64 *mark, S64 *preferred_column, String8 string) { RD_CodeSliceSignal result = {0}; ProfBeginFunction(); @@ -1887,9 +1887,9 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { rd_cmd(RD_CmdKind_AddBreakpoint, .file_path = params->line_vaddrs[line_idx] ? str8_zero() : rd_regs()->file_path, - .cursor = params->line_vaddrs[line_idx] ? txt_pt(0, 0) : txt_pt(line_num, 1), + .line_num = params->line_vaddrs[line_idx] ? 0 : line_num, .vaddr = params->line_vaddrs[line_idx], - .expr = s("")); + .expr = s("")); } } } @@ -1901,7 +1901,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe if(params->flags & RD_CodeSliceFlag_LineNums) UI_Parent(top_container_box) ProfScope("build line numbers") UI_Focus(UI_FocusKind_Off) UI_TagF("floating") { - TxtRng select_rng = txt_rng(*cursor, *mark); + Rng1U64 select_rng = r1u64(*cursor, *mark); ui_set_next_fixed_x(floor_f32(params->margin_float_off_px + params->priority_margin_width_px + params->catchall_margin_width_px)); ui_set_next_pref_width(ui_px(params->line_num_width_px, 1.f)); ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); @@ -1917,7 +1917,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe line_num <= params->line_num_range.max; line_num += 1, line_idx += 1) { - B32 line_is_selected = (select_rng.min.line <= line_num && line_num <= select_rng.max.line); + Rng1U64 line_range = params->line_ranges[line_idx]; + B32 line_is_selected = (dim_1u64(intersect_1u64(select_rng, line_range)) != 0) || (line_range.min <= *cursor && *cursor <= line_range.max); Vec4F32 bg_color = v4f32(0, 0, 0, 0); // rjf: line info on this line -> adjust bg color to visualize @@ -1974,63 +1975,55 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ////////////////////////////// //- rjf: mouse -> text coordinates // - TxtPt mouse_pt = {0}; + U64 mouse_off = 0; + U64 mouse_y_line_idx = 0; ProfScope("mouse -> text coordinates") { Vec2F32 mouse = ui_mouse(); // rjf: mouse y => index - U64 mouse_y_line_idx = (U64)((mouse.y - text_container_box->rect.y0) / params->line_height_px); + mouse_y_line_idx = (U64)((mouse.y - text_container_box->rect.y0) / params->line_height_px); // rjf: index => line num S64 line_num = (params->line_num_range.min + mouse_y_line_idx); + Rng1U64 line_range = (params->line_num_range.min <= line_num && line_num <= params->line_num_range.max) ? (params->line_ranges[mouse_y_line_idx]) : r1u64(0, 0); String8 line_string = (params->line_num_range.min <= line_num && line_num <= params->line_num_range.max) ? (params->line_text[mouse_y_line_idx]) : str8_zero(); - // rjf: mouse x * string => column - S64 column = fnt_char_pos_from_tag_size_string_p(params->font, params->font_size, 0, params->tab_size, line_string, mouse.x-text_container_box->rect.x0-params->line_num_width_px-line_num_padding_px)+1; + // rjf: mouse x * string => line offset + U64 mouse_line_off = fnt_char_pos_from_tag_size_string_p(params->font, params->font_size, 0, params->tab_size, line_string, mouse.x-text_container_box->rect.x0-params->line_num_width_px-line_num_padding_px); - // rjf: bundle - mouse_pt = txt_pt(line_num, column); + // rjf: compute + mouse_off = line_range.min + mouse_line_off; // rjf: clamp { - U64 last_line_size = params->line_text[dim_1s64(params->line_num_range)].size; - TxtRng legal_pt_rng = txt_rng(txt_pt(params->line_num_range.min, 1), - txt_pt(params->line_num_range.max, last_line_size+1)); - if(txt_pt_less_than(mouse_pt, legal_pt_rng.min)) - { - mouse_pt = legal_pt_rng.min; - } - if(txt_pt_less_than(legal_pt_rng.max, mouse_pt)) - { - mouse_pt = legal_pt_rng.max; - } + Rng1U64 legal_range = r1u64(params->line_ranges[0].min, params->line_ranges[dim_1s64(params->line_num_range)].max); + mouse_off = clamp_1u64(legal_range, mouse_off); } - result.mouse_pt = mouse_pt; + result.mouse_off = mouse_off; } ////////////////////////////// //- rjf: mouse point -> mouse token range, mouse line range // - TxtRng mouse_token_rng = txt_rng(mouse_pt, mouse_pt); - TxtRng mouse_line_rng = txt_rng(mouse_pt, mouse_pt); - if(contains_1s64(params->line_num_range, mouse_pt.line)) + Rng1U64 mouse_token_rng = r1u64(mouse_off, mouse_off); + Rng1U64 mouse_line_rng = r1u64(mouse_off, mouse_off); + if(mouse_y_line_idx < (U64)dim_1s64(params->line_num_range)) { - TXT_TokenArray *line_tokens = ¶ms->line_tokens[mouse_pt.line-params->line_num_range.min]; - Rng1U64 line_range = params->line_ranges[mouse_pt.line-params->line_num_range.min]; - U64 mouse_pt_off = (mouse_pt.column-1) + line_range.min; + TXT_TokenArray *line_tokens = ¶ms->line_tokens[mouse_y_line_idx]; + Rng1U64 line_range = params->line_ranges[mouse_y_line_idx]; for(U64 line_token_idx = 0; line_token_idx < line_tokens->count; line_token_idx += 1) { TXT_Token *line_token = &line_tokens->v[line_token_idx]; - if(contains_1u64(line_token->range, mouse_pt_off)) + if(contains_1u64(line_token->range, mouse_off)) { Rng1U64 line_token_range_clamped = intersect_1u64(line_token->range, line_range); - mouse_token_rng = txt_rng(txt_pt(mouse_pt.line, 1+line_token_range_clamped.min-line_range.min), txt_pt(mouse_pt.line, 1+line_token_range_clamped.max-line_range.min)); + mouse_token_rng = r1u64(line_token_range_clamped.min-line_range.min, line_token_range_clamped.max-line_range.min); break; } } - mouse_line_rng = txt_rng(txt_pt(mouse_pt.line, 1), txt_pt(mouse_pt.line, 1+(line_range.max-line_range.min))); + mouse_line_rng = r1u64(0, dim_1u64(line_range)); } ////////////////////////////// @@ -2042,7 +2035,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe UI_Signal text_container_sig = ui_signal_from_box(text_container_box); { //- rjf: determine mouse drag range - TxtRng mouse_drag_rng = txt_rng(mouse_pt, mouse_pt); + Rng1U64 mouse_drag_rng = r1u64(mouse_off, mouse_off); if(text_container_sig.f & UI_SignalFlag_LeftTripleDragging) { mouse_drag_rng = mouse_line_rng; @@ -2055,24 +2048,12 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe //- rjf: clicking/dragging over the text container if(!ctrlified && ui_dragging(text_container_sig)) { - if(mouse_pt.line == 0) - { - mouse_pt.column = 1; - if(ui_mouse().y <= top_container_box->rect.y0) - { - mouse_pt.line = params->line_num_range.min - 2; - } - else if(ui_mouse().y >= top_container_box->rect.y1) - { - mouse_pt.line = params->line_num_range.max + 2; - } - } if(ui_pressed(text_container_sig)) { *cursor = mouse_drag_rng.max; *mark = mouse_drag_rng.min; } - if(txt_pt_less_than(mouse_pt, *mark)) + if(mouse_off < *mark) { *cursor = mouse_drag_rng.min; } @@ -2080,7 +2061,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { *cursor = mouse_drag_rng.max; } - *preferred_column = cursor->column; + *preferred_column = *cursor - mouse_line_rng.min; } //- rjf: dragging will invalidate the search string, so we don't want to draw it while dragging/releasing @@ -2092,25 +2073,25 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe //- rjf: right-click => code context menu if(ui_right_clicked(text_container_sig)) { - if(txt_pt_match(*cursor, *mark)) + if(*cursor == *mark) { - *cursor = *mark = mouse_pt; + *cursor = *mark = mouse_off; } U64 vaddr = 0; D_LineList lines = {0}; - if(params->line_num_range.min <= cursor->line && cursor->line < params->line_num_range.max) + if(mouse_y_line_idx < (U64)dim_1s64(params->line_num_range)) { - vaddr = params->line_vaddrs[cursor->line - params->line_num_range.min]; - lines = params->line_infos[cursor->line - params->line_num_range.min]; + vaddr = params->line_vaddrs[mouse_y_line_idx]; + lines = params->line_infos[mouse_y_line_idx]; } String8 commands_expr; if(vaddr != 0) { - commands_expr = txt_pt_match(*cursor, *mark) ? s("query:disasm_pt_commands") : s("query:disasm_range_commands"); + commands_expr = (*cursor == *mark) ? s("query:disasm_pt_commands") : s("query:disasm_range_commands"); } else { - commands_expr = txt_pt_match(*cursor, *mark) ? s("query:text_pt_commands") : s("query:text_range_commands"); + commands_expr = (*cursor == *mark) ? s("query:text_pt_commands") : s("query:text_range_commands"); } rd_cmd(RD_CmdKind_FocusPanel); rd_cmd(RD_CmdKind_PushQuery, @@ -2127,40 +2108,38 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe } //- rjf: drop target is dropped -> process - if(drop_can_hit_lines && ui_key_match(ui_drop_hot_key(), drop_site_key) && rd_drag_drop()) + if(drop_can_hit_lines && ui_key_match(ui_drop_hot_key(), drop_site_key) && rd_drag_drop() && + mouse_y_line_idx < (U64)dim_1s64(params->line_num_range)) { if(rd_state->drag_drop_regs_slot == RD_RegSlot_Expr) { - S64 line_num = mouse_pt.line; - U64 line_idx = line_num - params->line_num_range.min; - U64 line_vaddr = params->line_vaddrs[line_idx]; + U64 line_num = (U64)params->line_num_range.min + mouse_y_line_idx; + U64 line_vaddr = params->line_vaddrs[mouse_y_line_idx]; rd_cmd(RD_CmdKind_AddWatchPin, .expr = rd_state->drag_drop_regs->expr, .file_path = line_vaddr == 0 ? rd_regs()->file_path : str8_zero(), - .cursor = line_vaddr == 0 ? txt_pt(line_num, 1) : txt_pt(0, 0), + .line_num = line_vaddr == 0 ? line_num : 0, .vaddr = line_vaddr); } if(rd_state->drag_drop_regs_slot == RD_RegSlot_Cfg && drop_cfg != &cfg_nil_node) { - S64 line_num = mouse_pt.line; - U64 line_idx = line_num - params->line_num_range.min; - U64 line_vaddr = params->line_vaddrs[line_idx]; + U64 line_num = (U64)params->line_num_range.min + mouse_y_line_idx; + U64 line_vaddr = params->line_vaddrs[mouse_y_line_idx]; rd_cmd(RD_CmdKind_RelocateCfg, .cfg = drop_cfg->id, .file_path = line_vaddr == 0 ? rd_regs()->file_path : str8_zero(), - .cursor = line_vaddr == 0 ? txt_pt(line_num, 1) : txt_pt(0, 0), + .line_num = line_vaddr == 0 ? line_num : 0, .vaddr = line_vaddr); } if(drop_thread != &d_entity_nil) { - S64 line_num = mouse_pt.line; - U64 line_idx = line_num - params->line_num_range.min; - U64 line_vaddr = params->line_vaddrs[line_idx]; + U64 line_num = (U64)params->line_num_range.min + mouse_y_line_idx; + U64 line_vaddr = params->line_vaddrs[mouse_y_line_idx]; D_Entity *thread = drop_thread; U64 new_rip_vaddr = line_vaddr; - if(params->line_vaddrs[line_idx] == 0) + if(params->line_vaddrs[mouse_y_line_idx] == 0) { - D_LineList *lines = ¶ms->line_infos[line_idx]; + D_LineList *lines = ¶ms->line_infos[mouse_y_line_idx]; for(D_LineNode *n = lines->first; n != 0; n = n->next) { D_EntityList modules = d_modules_from_dbgi_key(scratch.arena, n->v.dbgi_key); @@ -2186,7 +2165,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe TXT_ScopeNode *cursor_scope_node = &txt_scope_node_nil; if(params->text_info != 0) { - cursor_scope_node = txt_scope_node_from_info_pt(params->text_info, params->patches, rd_regs()->cursor); + cursor_scope_node = txt_scope_node_from_info_off(params->text_info, *cursor); } ////////////////////////////// @@ -2623,40 +2602,37 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ////////////////////////////// //- rjf: mouse -> expression range info // - TxtRng mouse_expr_rng = {0}; + Rng1U64 mouse_expr_rng = {0}; Vec2F32 mouse_expr_baseline_pos = {0}; String8 mouse_expr = {0}; B32 mouse_expr_is_explicit = 0; - if(ui_hovering(text_container_sig) && contains_1s64(params->line_num_range, mouse_pt.line)) ProfScope("mouse -> expression range") + if(ui_hovering(text_container_sig) && mouse_y_line_idx < (U64)dim_1s64(params->line_num_range)) { - TxtRng selected_rng = txt_rng(*cursor, *mark); - if(!txt_pt_match(*cursor, *mark) && cursor->line == mark->line && - ((txt_pt_less_than(selected_rng.min, mouse_pt) || txt_pt_match(selected_rng.min, mouse_pt)) && - txt_pt_less_than(mouse_pt, selected_rng.max))) + Rng1U64 selected_rng = r1u64(*cursor, *mark); + if(*cursor != *mark && contains_1u64(selected_rng, mouse_off)) { - U64 line_slice_idx = mouse_pt.line-params->line_num_range.min; - String8 line_text = params->line_text[line_slice_idx]; - F32 expr_hoff_px = params->line_num_width_px + fnt_dim_from_tag_size_string(params->font, params->font_size, 0, params->tab_size, str8_prefix(line_text, selected_rng.min.column-1)).x; - result.mouse_expr_rng = mouse_expr_rng = selected_rng; + String8 line_text = params->line_text[mouse_y_line_idx]; + Rng1U64 line_range = params->line_ranges[mouse_y_line_idx]; + Rng1U64 selected_in_line_range = intersect_1u64(line_range, selected_rng); + F32 expr_hoff_px = params->line_num_width_px + fnt_dim_from_tag_size_string(params->font, params->font_size, 0, params->tab_size, str8_prefix(line_text, selected_in_line_range.min)).x; + result.mouse_expr_rng = mouse_expr_rng = selected_in_line_range; mouse_expr_baseline_pos = v2f32(text_container_box->rect.x0+expr_hoff_px, - text_container_box->rect.y0+line_slice_idx*params->line_height_px + params->line_height_px*0.85f); - mouse_expr = str8_substr(line_text, r1u64(selected_rng.min.column-1, selected_rng.max.column-1)); + text_container_box->rect.y0+mouse_y_line_idx*params->line_height_px + params->line_height_px*0.85f); + mouse_expr = str8_substr(line_text, selected_in_line_range); mouse_expr_is_explicit = 1; } else { - U64 line_slice_idx = mouse_pt.line-params->line_num_range.min; - String8 line_text = params->line_text[line_slice_idx]; - TXT_TokenArray line_tokens = params->line_tokens[line_slice_idx]; - Rng1U64 line_range = params->line_ranges[line_slice_idx]; - U64 mouse_pt_off = line_range.min + (mouse_pt.column-1); - Rng1U64 expr_off_rng = txt_expr_off_range_from_line_off_range_string_tokens(mouse_pt_off, line_range, line_text, &line_tokens); + String8 line_text = params->line_text[mouse_y_line_idx]; + TXT_TokenArray line_tokens = params->line_tokens[mouse_y_line_idx]; + Rng1U64 line_range = params->line_ranges[mouse_y_line_idx]; + Rng1U64 expr_off_rng = txt_expr_off_range_from_line_off_range_string_tokens(mouse_off, line_range, line_text, &line_tokens); if(expr_off_rng.max != expr_off_rng.min) { F32 expr_hoff_px = params->line_num_width_px + fnt_dim_from_tag_size_string(params->font, params->font_size, 0, params->tab_size, str8_prefix(line_text, expr_off_rng.min-line_range.min)).x; - result.mouse_expr_rng = mouse_expr_rng = txt_rng(txt_pt(mouse_pt.line, 1+(expr_off_rng.min-line_range.min)), txt_pt(mouse_pt.line, 1+(expr_off_rng.max-line_range.min))); + result.mouse_expr_rng = mouse_expr_rng = r1u64(expr_off_rng.min - line_range.min, expr_off_rng.max - line_range.min); mouse_expr_baseline_pos = v2f32(text_container_box->rect.x0+expr_hoff_px, - text_container_box->rect.y0+line_slice_idx*params->line_height_px + params->line_height_px*0.85f); + text_container_box->rect.y0+mouse_y_line_idx*params->line_height_px + params->line_height_px*0.85f); mouse_expr = str8_substr(line_text, r1u64(expr_off_rng.min-line_range.min, expr_off_rng.max-line_range.min)); } } @@ -2665,11 +2641,10 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ////////////////////////////// //- rjf: mouse -> set global frontend hovered line info // - if(ui_hovering(text_container_sig) && contains_1s64(params->line_num_range, mouse_pt.line) && (ui_mouse().x - text_container_box->rect.x0 < params->line_num_width_px + line_num_padding_px)) + if(ui_hovering(text_container_sig) && mouse_y_line_idx < (U64)dim_1s64(params->line_num_range) && (ui_mouse().x - text_container_box->rect.x0 < params->line_num_width_px + line_num_padding_px)) { - U64 line_slice_idx = mouse_pt.line-params->line_num_range.min; - D_LineList *lines = ¶ms->line_infos[line_slice_idx]; - if(lines->first != 0 && (params->line_vaddrs[line_slice_idx] != 0 || lines->first->v.pt.line == mouse_pt.line)) + D_LineList *lines = ¶ms->line_infos[mouse_y_line_idx]; + if(lines->first != 0 && (params->line_vaddrs[mouse_y_line_idx] != 0 || lines->first->v.pt.line == params->line_num_range.min + mouse_y_line_idx)) { RD_RegsScope(.process = selected_thread_process->handle, .vaddr_range = d_vaddr_range_from_voff_range(selected_thread_module, lines->first->v.voff_range), @@ -2693,10 +2668,9 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe if(eval.msgs.max_kind == E_MsgKind_Null && (eval_implicit_hover || mouse_expr_is_explicit)) { U64 line_vaddr = 0; - if(contains_1s64(params->line_num_range, mouse_pt.line)) + if(mouse_y_line_idx < (U64)dim_1s64(params->line_num_range)) { - U64 line_idx = mouse_pt.line-params->line_num_range.min; - line_vaddr = params->line_vaddrs[line_idx]; + line_vaddr = params->line_vaddrs[mouse_y_line_idx]; } rd_set_hover_eval(mouse_expr_baseline_pos, mouse_expr); } @@ -2713,9 +2687,9 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe Vec4F32 color = drop_color; color.w *= 0.2f; Rng2F32 drop_line_rect = r2f32p(top_container_box->rect.x0, - top_container_box->rect.y0 + (mouse_pt.line - params->line_num_range.min) * params->line_height_px, + top_container_box->rect.y0 + mouse_y_line_idx*params->line_height_px, top_container_box->rect.x1, - top_container_box->rect.y0 + (mouse_pt.line - params->line_num_range.min + 1) * params->line_height_px); + top_container_box->rect.y0 + (mouse_y_line_idx+1)*params->line_height_px); R_Rect2DInst *inst = dr_rect(drop_line_rect, color, 0, 0, 1.f); inst->colors[Corner_10] = inst->colors[Corner_11] = v4f32(color.x, color.y, color.z, 0); } @@ -2729,7 +2703,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe struct TxtRngColorPairNode { TxtRngColorPairNode *next; - TxtRng rng; + Rng1U64 range; Vec4F32 color; }; TxtRngColorPairNode *first_txt_rng_color_pair = 0; @@ -2738,16 +2712,16 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: push initial for cursor/mark { TxtRngColorPairNode *n = push_array(scratch.arena, TxtRngColorPairNode, 1); - n->rng = txt_rng(*cursor, *mark); + n->range = r1u64(*cursor, *mark); n->color = ui_color_from_name(s("selection")); SLLQueuePush(first_txt_rng_color_pair, last_txt_rng_color_pair, n); } // rjf: push for ctrlified mouse expr - if(ctrlified && !txt_pt_match(result.mouse_expr_rng.max, result.mouse_expr_rng.min)) UI_Tag(s("pop")) + if(ctrlified && result.mouse_expr_rng.max != result.mouse_expr_rng.min) UI_Tag(s("pop")) { TxtRngColorPairNode *n = push_array(scratch.arena, TxtRngColorPairNode, 1); - n->rng = result.mouse_expr_rng; + n->range = result.mouse_expr_rng; n->color = ui_color_from_name(s("background")); n->color.w *= 0.2f; SLLQueuePush(first_txt_rng_color_pair, last_txt_rng_color_pair, n); @@ -2840,33 +2814,22 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: extra rendering for list(text_range*color) { - U64 prev_line_size = (line_idx > 0) ? params->line_text[line_idx-1].size : 0; - U64 next_line_size = (line_idx+1 < dim_1s64(params->line_num_range)) ? params->line_text[line_idx+1].size : 0; + Rng1U64 prev_line_range = (line_idx > 0) ? params->line_ranges[line_idx-1] : r1u64(0, 0); + Rng1U64 next_line_range = (line_idx+1 < dim_1s64(params->line_num_range)) ? params->line_ranges[line_idx+1] : r1u64(0, 0); for(TxtRngColorPairNode *n = first_txt_rng_color_pair; n != 0; n = n->next) { - TxtRng select_range = n->rng; - TxtRng line_range = txt_rng(txt_pt(line_num, 1), txt_pt(line_num, line_string.size+1)); - TxtRng select_range_in_line = txt_rng_intersect(select_range, line_range); - if(!txt_pt_match(select_range_in_line.min, select_range_in_line.max) && - txt_pt_less_than(select_range_in_line.min, select_range_in_line.max)) + Rng1U64 select_range = n->range; + Rng1U64 select_range_in_line = intersect_1u64(select_range, line_range); + if(select_range_in_line.min < select_range_in_line.max) { - TxtRng prev_line_range = txt_rng(txt_pt(line_num-1, 1), txt_pt(line_num-1, prev_line_size+1)); - TxtRng next_line_range = txt_rng(txt_pt(line_num+1, 1), txt_pt(line_num+1, next_line_size+1)); - TxtRng select_range_in_prev_line = txt_rng_intersect(prev_line_range, select_range); - TxtRng select_range_in_next_line = txt_rng_intersect(next_line_range, select_range); - B32 prev_line_good = (!txt_pt_match(select_range_in_prev_line.min, select_range_in_prev_line.max) && - txt_pt_less_than(select_range_in_prev_line.min, select_range_in_prev_line.max)); - B32 next_line_good = (!txt_pt_match(select_range_in_next_line.min, select_range_in_next_line.max) && - txt_pt_less_than(select_range_in_next_line.min, select_range_in_next_line.max)); - Rng1S64 select_column_range_in_line = - { - (select_range.min.line == line_num) ? select_range.min.column : 1, - (select_range.max.line == line_num) ? select_range.max.column : (S64)(line_string.size+1), - }; + Rng1U64 select_range_in_prev_line = intersect_1u64(prev_line_range, select_range); + Rng1U64 select_range_in_next_line = intersect_1u64(next_line_range, select_range); + B32 prev_line_good = (select_range_in_prev_line.min < select_range_in_prev_line.max); + B32 next_line_good = (select_range_in_next_line.min < select_range_in_next_line.max); Rng1F32 select_column_pixel_off_range = { - fnt_dim_from_tag_size_string(line_box->font, line_box->font_size, 0, params->tab_size, str8_prefix(line_string, select_column_range_in_line.min-1)).x, - fnt_dim_from_tag_size_string(line_box->font, line_box->font_size, 0, params->tab_size, str8_prefix(line_string, select_column_range_in_line.max-1)).x, + fnt_dim_from_tag_size_string(line_box->font, line_box->font_size, 0, params->tab_size, str8_prefix(line_string, select_range_in_line.min - line_range.min)).x, + fnt_dim_from_tag_size_string(line_box->font, line_box->font_size, 0, params->tab_size, str8_prefix(line_string, select_range_in_line.max - line_range.min)).x, }; Rng2F32 select_rect = { @@ -2882,19 +2845,21 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe } F32 rounded_radius = params->font_size*0.4f; R_Rect2DInst *inst = dr_rect(select_rect, color, rounded_radius, 0, 1); - inst->corner_radii[Corner_00] = !prev_line_good || select_range_in_prev_line.min.column > select_range_in_line.min.column ? rounded_radius : 0.f; - inst->corner_radii[Corner_10] = (!prev_line_good || select_range_in_line.max.column > select_range_in_prev_line.max.column || select_range_in_line.max.column < select_range_in_prev_line.min.column) ? rounded_radius : 0.f; - inst->corner_radii[Corner_01] = (!next_line_good || select_range_in_next_line.min.column > select_range_in_line.min.column || select_range_in_next_line.max.column < select_range_in_line.min.column) ? rounded_radius : 0.f; - inst->corner_radii[Corner_11] = !next_line_good || select_range_in_line.max.column > select_range_in_next_line.max.column ? rounded_radius : 0.f; + Rng1U64 prev_line_selection_off_range = r1u64(select_range_in_prev_line.min - prev_line_range.min, select_range_in_prev_line.max - prev_line_range.min); + Rng1U64 next_line_selection_off_range = r1u64(select_range_in_next_line.min - next_line_range.min, select_range_in_next_line.max - next_line_range.min); + Rng1U64 crnt_line_selection_off_range = r1u64(select_range_in_line.min - line_range.min, select_range_in_line.max - line_range.min); + inst->corner_radii[Corner_00] = !prev_line_good || prev_line_selection_off_range.min > crnt_line_selection_off_range.min ? rounded_radius : 0.f; + inst->corner_radii[Corner_10] = (!prev_line_good || crnt_line_selection_off_range.max > prev_line_selection_off_range.max || crnt_line_selection_off_range.max < prev_line_selection_off_range.min) ? rounded_radius : 0.f; + inst->corner_radii[Corner_01] = (!next_line_good || next_line_selection_off_range.min > crnt_line_selection_off_range.min || next_line_selection_off_range.max < crnt_line_selection_off_range.min) ? rounded_radius : 0.f; + inst->corner_radii[Corner_11] = !next_line_good || crnt_line_selection_off_range.max > next_line_selection_off_range.max ? rounded_radius : 0.f; } } } // rjf: extra rendering for cursor position - if(cursor->line == line_num) + if(line_range.min <= *cursor && *cursor <= line_range.max) { - S64 column = cursor->column; - Vec2F32 advance = fnt_dim_from_tag_size_string(line_box->font, line_box->font_size, 0, params->tab_size, str8_prefix(line_string, column-1)); + Vec2F32 advance = fnt_dim_from_tag_size_string(line_box->font, line_box->font_size, 0, params->tab_size, str8_prefix(line_string, *cursor - line_range.min)); F32 cursor_y = line_box->rect.y0-params->font_size*0.125f; F32 cursor_y__animated = ui_anim(ui_key_from_stringf(text_container_box->key, "cursor_y_px"), cursor_y); F32 cursor_off_pixels = advance.x; @@ -2986,7 +2951,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe } internal RD_CodeSliceSignal -rd_code_slicef(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *preferred_column, char *fmt, ...) +rd_code_slicef(RD_CodeSliceParams *params, U64 *cursor, U64 *mark, S64 *preferred_column, char *fmt, ...) { Temp scratch = scratch_begin(0, 0); va_list args; @@ -3883,8 +3848,8 @@ rd_cell(RD_CellParams *params, String8 string) { ui_kill_action(); } - params->cursor[0] = txt_pt(1, edit_string.size+1); - params->mark[0] = txt_pt(1, 1); + params->cursor[0] = edit_string.size; + params->mark[0] = 0; focus_started = 1; } } @@ -3928,20 +3893,20 @@ rd_cell(RD_CellParams *params, String8 string) CFG_Node *window = cfg_node_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); RD_AutocompCursorInfo *autocomp_cursor_info = &ws->autocomp_cursor_info; - String8 new_string = ui_push_string_replace_range(scratch.arena, edit_string, r1s64(autocomp_cursor_info->replaced_range.min+1, autocomp_cursor_info->replaced_range.max+1), autocomplete_hint_string); + String8 new_string = ui_push_string_replace_range(scratch.arena, edit_string, autocomp_cursor_info->replaced_range, autocomplete_hint_string); new_string.size = Min(params->edit_buffer_size, new_string.size); MemoryCopy(params->edit_buffer, new_string.str, new_string.size); params->edit_string_size_out[0] = new_string.size; - params->cursor[0] = params->mark[0] = txt_pt(1, 1+autocomp_cursor_info->replaced_range.min+autocomplete_hint_string.size); + params->cursor[0] = params->mark[0] = autocomp_cursor_info->replaced_range.min+autocomplete_hint_string.size; edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); op = ui_single_line_txt_op_from_event(scratch.arena, evt, edit_string, params->cursor[0], params->mark[0]); MemoryZeroStruct(&autocomplete_hint_string); } // rjf: perform replace range - if(!txt_pt_match(op.range.min, op.range.max) || op.replace.size != 0) + if(op.range.min != op.range.max || op.replace.size != 0) { - String8 new_string = ui_push_string_replace_range(scratch.arena, edit_string, r1s64(op.range.min.column, op.range.max.column), op.replace); + String8 new_string = ui_push_string_replace_range(scratch.arena, edit_string, op.range, op.replace); new_string.size = Min(params->edit_buffer_size, new_string.size); MemoryCopy(params->edit_buffer, new_string.str, new_string.size); params->edit_string_size_out[0] = new_string.size; @@ -4026,9 +3991,9 @@ rd_cell(RD_CellParams *params, String8 string) CFG_Node *window = cfg_node_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); RD_AutocompCursorInfo *autocomp_cursor_info = &ws->autocomp_cursor_info; - String8 autocomplete_append_string = str8_skip(autocomplete_hint_string, params->cursor->column-1 - autocomp_cursor_info->replaced_range.min); + String8 autocomplete_append_string = str8_skip(autocomplete_hint_string, params->cursor[0] - autocomp_cursor_info->replaced_range.min); U64 off = 0; - U64 cursor_off = params->cursor->column-1; + U64 cursor_off = params->cursor[0]; DR_FStrNode *prev_n = 0; for(DR_FStrNode *n = edit_string_fstrs.first; n != 0; n = n->next) { @@ -4095,7 +4060,7 @@ rd_cell(RD_CellParams *params, String8 string) ////////////////////////////// //- rjf: build scrolled contents // - TxtPt mouse_pt = {0}; + U64 mouse_off = {0}; F32 cursor_off = 0; if(scrollable_box != &ui_nil_box) UI_Parent(scrollable_box) { @@ -4132,9 +4097,8 @@ rd_cell(RD_CellParams *params, String8 string) { font = rd_font_from_slot(RD_FontSlot_Code); } - U64 mouse_pt_off = fnt_char_pos_from_tag_size_string_p(font, font_size, 0, ui_top_tab_size(), edit_string, text2mouse.x); - mouse_pt = txt_pt(1, 1+mouse_pt_off); - cursor_off = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, params->cursor->column-1)).x; + mouse_off = fnt_char_pos_from_tag_size_string_p(font, font_size, 0, ui_top_tab_size(), edit_string, text2mouse.x); + cursor_off = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, params->cursor[0])).x; } } @@ -4145,13 +4109,13 @@ rd_cell(RD_CellParams *params, String8 string) { if(ui_pressed(sig)) { - params->mark[0] = mouse_pt; + params->mark[0] = mouse_off; } - params->cursor[0] = mouse_pt; + params->cursor[0] = mouse_off; } if(!is_focus_active && is_focus_active_disabled && ui_pressed(sig)) { - params->cursor[0] = params->mark[0] = mouse_pt; + params->cursor[0] = params->mark[0] = mouse_off; } ////////////////////////////// diff --git a/src/raddbg/raddbg_widgets.h b/src/raddbg/raddbg_widgets.h index 62d29b55..be3d5497 100644 --- a/src/raddbg/raddbg_widgets.h +++ b/src/raddbg/raddbg_widgets.h @@ -72,8 +72,8 @@ struct RD_CellParams B32 *revert_out; //- rjf: text editing r/w info - TxtPt *cursor; - TxtPt *mark; + U64 *cursor; + U64 *mark; U8 *edit_buffer; U64 edit_buffer_size; U64 *edit_string_size_out; @@ -128,8 +128,8 @@ typedef struct RD_CodeSliceSignal RD_CodeSliceSignal; struct RD_CodeSliceSignal { UI_Signal base; - TxtPt mouse_pt; - TxtRng mouse_expr_rng; + U64 mouse_off; + Rng1U64 mouse_expr_rng; }; //////////////////////////////// @@ -172,8 +172,8 @@ internal UI_Signal rd_icon_buttonf(RD_IconKind kind, FuzzyMatchRangeList *matche internal UI_BOX_CUSTOM_DRAW(rd_code_slice_text_draw_extensions); internal UI_BOX_CUSTOM_DRAW(rd_thread_box_draw_extensions); internal UI_BOX_CUSTOM_DRAW(rd_bp_box_draw_extensions); -internal RD_CodeSliceSignal rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *preferred_column, String8 string); -internal RD_CodeSliceSignal rd_code_slicef(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *preferred_column, char *fmt, ...); +internal RD_CodeSliceSignal rd_code_slice(RD_CodeSliceParams *params, U64 *cursor, U64 *mark, S64 *preferred_column, String8 string); +internal RD_CodeSliceSignal rd_code_slicef(RD_CodeSliceParams *params, U64 *cursor, U64 *mark, S64 *preferred_column, char *fmt, ...); internal B32 rd_do_txt_controls(TXT_TextInfo *info, String8 data, TXT_PatchList *patches, U64 line_count_per_page, TxtPt *cursor, TxtPt *mark, S64 *preferred_column); diff --git a/src/text/text.c b/src/text/text.c index 1043d970..896fe3c5 100644 --- a/src/text/text.c +++ b/src/text/text.c @@ -2329,14 +2329,14 @@ txt_patched_range_from_base_range(TXT_PatchList *patches, Rng1U64 base_range) } internal void -txt_line_map_push(Arena *arena, TXT_LineMap *map, Rng1U64 idx_range, Rng1U64 *ranges, S64 delta) +txt_line_map_push(Arena *arena, TXT_LineMap *map, Rng1U64 num_range, Rng1U64 *ranges, S64 delta) { TXT_LineMapRangeNode *n = push_array(arena, TXT_LineMapRangeNode, 1); - n->idx_range = idx_range; + n->num_range = num_range; n->ranges = ranges; n->delta = delta; SLLQueuePush(map->first_range, map->last_range, n); - map->total_line_count += dim_1u64(idx_range); + map->total_line_count += dim_1u64(num_range); } internal U64 @@ -2345,13 +2345,13 @@ txt_line_num_from_off(TXT_LineMap *map, U64 off) U64 result = 0; for(TXT_LineMapRangeNode *n = map->first_range; n != 0; n = n->next) { - for EachInRange(idx, n->idx_range) + for EachInRange(num, n->num_range) { - Rng1U64 line_range = n->ranges[idx-n->idx_range.min]; + Rng1U64 line_range = n->ranges[num-n->num_range.min]; Rng1U64 line_range_shifted = r1u64(line_range.min + n->delta, line_range.max + n->delta); if(line_range_shifted.min <= off && off <= line_range_shifted.max) { - result = idx+1; + result = num; goto break_all; } } @@ -2361,14 +2361,14 @@ txt_line_num_from_off(TXT_LineMap *map, U64 off) } internal Rng1U64 -txt_range_from_line_idx(TXT_LineMap *map, U64 idx) +txt_range_from_line_num(TXT_LineMap *map, U64 num) { Rng1U64 result = {0}; for(TXT_LineMapRangeNode *n = map->first_range; n != 0; n = n->next) { - if(contains_1u64(n->idx_range, idx)) + if(contains_1u64(n->num_range, num)) { - result = n->ranges[idx - n->idx_range.min]; + result = n->ranges[num - n->num_range.min]; result.min = (U64)((S64)result.min + n->delta); result.max = (U64)((S64)result.max + n->delta); } @@ -2386,7 +2386,7 @@ txt_patched_from_info_data_patches(Arena *arena, TXT_TextInfo *info, String8 dat U64 last_size = data.size; TXT_LineMap last_line_map = {0}; memory_map_push(scratch.arena, &last_memory_map, r1u64(0, data.size), data.str); - txt_line_map_push(scratch.arena, &last_line_map, r1u64(0, info->lines_count), info->lines_ranges, 0); + txt_line_map_push(scratch.arena, &last_line_map, r1u64(1, info->lines_count+1), info->lines_ranges, 0); // rjf: apply the patches in order, each being able to slice/dice the previous memory map for EachNode(n, TXT_PatchNode, patches->first) @@ -2405,7 +2405,7 @@ txt_patched_from_info_data_patches(Arena *arena, TXT_TextInfo *info, String8 dat replace_line_num_range.max = txt_line_num_from_off(&last_line_map, n->v.range.max); } - // rjf: compute portion of lines before/after this replace-range + // rjf: compute ranges of (unchanged) lines before/after this replace-range Rng1U64 pre_replace_line_num_range = r1u64(1, replace_line_num_range.min); Rng1U64 post_replace_line_num_range = r1u64(replace_line_num_range.max+1, last_line_map.total_line_count+1); @@ -2433,10 +2433,7 @@ txt_patched_from_info_data_patches(Arena *arena, TXT_TextInfo *info, String8 dat last_line_start_off = idx+1; } } - if(last_line_start_off < n->v.replace.size) - { - rng1u64_list_push(scratch.arena, &replace_line_ranges, r1u64(last_line_start_off, n->v.replace.size)); - } + rng1u64_list_push(scratch.arena, &replace_line_ranges, r1u64(last_line_start_off, n->v.replace.size)); } // rjf: push all portions of pre-replace / post-replace ranges in previous memory map @@ -2469,56 +2466,62 @@ txt_patched_from_info_data_patches(Arena *arena, TXT_TextInfo *info, String8 dat { for EachNode(map_n, TXT_LineMapRangeNode, last_line_map.first_range) { - Rng1U64 num_range = shift_1u64(map_n->idx_range, 1); + Rng1U64 num_range = map_n->num_range; Rng1U64 range_x_pre = intersect_1u64(pre_replace_line_num_range, num_range); Rng1U64 range_x_post = intersect_1u64(post_replace_line_num_range, num_range); if(range_x_pre.max > range_x_pre.min) { - txt_line_map_push(scratch.arena, &next_line_map, r1u64(range_x_pre.min-1, range_x_pre.max-1), map_n->ranges + (range_x_pre.min - num_range.min), map_n->delta); + txt_line_map_push(scratch.arena, &next_line_map, r1u64(range_x_pre.min, range_x_pre.max), map_n->ranges + (range_x_pre.min - num_range.min), map_n->delta); } if(range_x_post.max > range_x_post.min) { Rng1U64 range_x_post_shifted = range_x_post; range_x_post_shifted.min = (U64)((S64)range_x_post_shifted.min + line_delta); range_x_post_shifted.max = (U64)((S64)range_x_post_shifted.max + line_delta); - txt_line_map_push(scratch.arena, &next_line_map, r1u64(range_x_post_shifted.min-1, range_x_post_shifted.max-1), map_n->ranges + (range_x_post.min - num_range.min), map_n->delta + size_delta); + txt_line_map_push(scratch.arena, &next_line_map, r1u64(range_x_post_shifted.min, range_x_post_shifted.max), map_n->ranges + (range_x_post.min - num_range.min), map_n->delta + size_delta); } } } // rjf: compute affected line ranges - U64 affected_line_count = dim_1u64(replace_line_num_range)+1; + U64 affected_line_count = replace_line_ranges.count; Rng1U64 *affected_line_ranges = push_array(arena, Rng1U64, affected_line_count); { Rng1U64Node *replace_line_range_n = replace_line_ranges.first; for EachIndex(affected_line_idx, affected_line_count) { - Rng1U64 replace_line_range = replace_line_range_n->v; - Rng1U64 affected_line_range = r1u64(replace_line_range.min + n->v.range.min, replace_line_range.max + n->v.range.min); + Rng1U64 affected_line_range = {0}; + if(replace_line_range_n != 0) + { + Rng1U64 replace_line_range = replace_line_range_n->v; + affected_line_range = r1u64(replace_line_range.min + n->v.range.min, replace_line_range.max + n->v.range.min); + replace_line_range_n = replace_line_range_n->next; + } // rjf: the first line in the range -> take min from original line map if(affected_line_idx == 0) { - Rng1U64 og_line_range = txt_range_from_line_idx(&last_line_map, replace_line_num_range.min + affected_line_idx - 1); + Rng1U64 og_line_range = txt_range_from_line_num(&last_line_map, replace_line_num_range.min + affected_line_idx); affected_line_range.min = og_line_range.min; } // rjf: the last line in the range -> take max from original line map, shift if(affected_line_idx == affected_line_count-1) { - Rng1U64 og_line_range = txt_range_from_line_idx(&last_line_map, replace_line_num_range.min + affected_line_idx - 1); - affected_line_range.max = og_line_range.max + size_delta; + Rng1U64 og_line_range = txt_range_from_line_num(&last_line_map, replace_line_num_range.min + affected_line_idx); + if(dim_1u64(og_line_range) != 0) + { + affected_line_range.max += dim_1u64(og_line_range); + } } // rjf: commit affected_line_ranges[affected_line_idx] = affected_line_range; - - replace_line_range_n = replace_line_range_n->next; } } // rjf: push affected line ranges - txt_line_map_push(scratch.arena, &next_line_map, r1u64(replace_line_num_range.min-1, (replace_line_num_range.max+1) - 1), affected_line_ranges, 0); + txt_line_map_push(scratch.arena, &next_line_map, r1u64(replace_line_num_range.min, replace_line_num_range.min + affected_line_count), affected_line_ranges, 0); // rjf: advance to the next memory map last_memory_map = next_memory_map; @@ -2536,7 +2539,7 @@ txt_patched_from_info_data_patches(Arena *arena, TXT_TextInfo *info, String8 dat result.size = last_size; for EachNode(n, TXT_LineMapRangeNode, last_line_map.first_range) { - txt_line_map_push(arena, &result.line_map, n->idx_range, n->ranges, n->delta); + txt_line_map_push(arena, &result.line_map, n->num_range, n->ranges, n->delta); } } diff --git a/src/text/text.h b/src/text/text.h index efe94ad4..d8279b3d 100644 --- a/src/text/text.h +++ b/src/text/text.h @@ -196,7 +196,7 @@ typedef struct TXT_LineMapRangeNode TXT_LineMapRangeNode; struct TXT_LineMapRangeNode { TXT_LineMapRangeNode *next; - Rng1U64 idx_range; + Rng1U64 num_range; Rng1U64 *ranges; S64 delta; }; @@ -291,12 +291,11 @@ internal TXT_TokenArray txt_token_array_from_string__disasm_x64_intel(Arena *are internal U64 txt_patched_off_from_base_off(TXT_PatchList *patches, U64 base_off); internal Rng1U64 txt_patched_range_from_base_range(TXT_PatchList *patches, Rng1U64 base_range); -internal void txt_line_map_push(Arena *arena, TXT_LineMap *map, Rng1U64 idx_range, Rng1U64 *ranges, S64 delta); +internal void txt_line_map_push(Arena *arena, TXT_LineMap *map, Rng1U64 num_range, Rng1U64 *ranges, S64 delta); internal U64 txt_line_num_from_off(TXT_LineMap *map, U64 off); -internal Rng1U64 txt_range_from_line_idx(TXT_LineMap *map, U64 idx); +internal Rng1U64 txt_range_from_line_num(TXT_LineMap *map, U64 num); internal TXT_Patched txt_patched_from_info_data_patches(Arena *arena, TXT_TextInfo *info, String8 data, TXT_PatchList *patches); - //~ TODO(rjf): old unpatched text viz code: internal U64 txt_off_from_pt(TXT_TextInfo *info, TXT_PatchList *patches, TxtPt pt); diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index dffd3c34..9098bfbb 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -129,8 +129,8 @@ typedef struct UI_LineEditDrawData UI_LineEditDrawData; struct UI_LineEditDrawData { String8 edited_string; - TxtPt cursor; - TxtPt mark; + U64 cursor; + U64 mark; B32 trail; }; @@ -148,11 +148,11 @@ internal UI_BOX_CUSTOM_DRAW(ui_line_edit_draw) trail_color.w *= 0.25f; Vec2F32 text_position = ui_box_text_position(box); String8 edited_string = draw_data->edited_string; - TxtPt cursor = draw_data->cursor; - TxtPt mark = draw_data->mark; - F32 cursor_pixel_off = fnt_dim_from_tag_size_string(font, font_size, 0, tab_size, str8_prefix(edited_string, cursor.column-1)).x; + U64 cursor = draw_data->cursor; + U64 mark = draw_data->mark; + F32 cursor_pixel_off = fnt_dim_from_tag_size_string(font, font_size, 0, tab_size, str8_prefix(edited_string, cursor)).x; F32 cursor_pixel_off__animated = ui_anim(ui_key_from_stringf(box->key, "cursor_off_px"), cursor_pixel_off); - F32 mark_pixel_off = fnt_dim_from_tag_size_string(font, font_size, 0, tab_size, str8_prefix(edited_string, mark.column-1)).x; + F32 mark_pixel_off = fnt_dim_from_tag_size_string(font, font_size, 0, tab_size, str8_prefix(edited_string, mark)).x; F32 cursor_thickness = ClampBot(1.f, floor_f32(font_size/10.f)); Rng2F32 cursor_rect = { @@ -196,7 +196,7 @@ internal UI_BOX_CUSTOM_DRAW(ui_line_edit_draw) } internal UI_Signal -ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, U64 *edit_string_size_out, String8 pre_edit_value, String8 string) +ui_line_edit(U64 *cursor, U64 *mark, U8 *edit_buffer, U64 edit_buffer_size, U64 *edit_string_size_out, String8 pre_edit_value, String8 string) { //- rjf: make key UI_Key key = ui_key_from_string(ui_active_seed_key(), string); @@ -241,9 +241,9 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, edit_string, *cursor, *mark); // rjf: perform replace range - if(!txt_pt_match(op.range.min, op.range.max) || op.replace.size != 0) + if(op.range.min != op.range.max || op.replace.size != 0) { - String8 new_string = ui_push_string_replace_range(scratch.arena, edit_string, r1s64(op.range.min.column, op.range.max.column), op.replace); + String8 new_string = ui_push_string_replace_range(scratch.arena, edit_string, op.range, op.replace); new_string.size = Min(edit_buffer_size, new_string.size); MemoryCopy(edit_buffer, new_string.str, new_string.size); edit_string_size_out[0] = new_string.size; @@ -269,7 +269,7 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, } //- rjf: build contents - TxtPt mouse_pt = {0}; + U64 mouse_off = {0}; F32 cursor_off = 0; UI_Parent(box) { @@ -289,14 +289,14 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, ui_set_next_pref_width(ui_px(total_text_width+ui_top_font_size()*5, 1.f)); UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); UI_LineEditDrawData *draw_data = push_array(ui_build_arena(), UI_LineEditDrawData, 1); - draw_data->edited_string = push_str8_copy(ui_build_arena(), edit_string); + draw_data->edited_string = str8_copy(ui_build_arena(), edit_string); draw_data->cursor = *cursor; draw_data->mark = *mark; draw_data->trail = 1; ui_box_equip_display_string(editstr_box, edit_string); ui_box_equip_custom_draw(editstr_box, ui_line_edit_draw, draw_data); - mouse_pt = txt_pt(1, 1+ui_box_char_pos_from_xy(editstr_box, ui_mouse())); - cursor_off = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, cursor->column-1)).x; + mouse_off = ui_box_char_pos_from_xy(editstr_box, ui_mouse()); + cursor_off = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, *cursor)).x; } } @@ -310,8 +310,8 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, edit_string_size_out[0] = edit_string.size; ui_set_auto_focus_active_key(key); ui_kill_action(); - *cursor = txt_pt(1, edit_string.size+1); - *mark = txt_pt(1, 1); + *cursor = edit_string.size; + *mark = 0; } if(is_focus_active && sig.f&UI_SignalFlag_KeyboardPressed) { @@ -322,9 +322,9 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, { if(ui_pressed(sig)) { - *mark = mouse_pt; + *mark = mouse_off; } - *cursor = mouse_pt; + *cursor = mouse_off; } //- rjf: focus cursor @@ -349,7 +349,7 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, } internal UI_Signal -ui_line_editf(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, U64 *edit_string_size_out, String8 pre_edit_value, char *fmt, ...) +ui_line_editf(U64 *cursor, U64 *mark, U8 *edit_buffer, U64 edit_buffer_size, U64 *edit_string_size_out, String8 pre_edit_value, char *fmt, ...) { Temp scratch = scratch_begin(0, 0); va_list args; diff --git a/src/ui/ui_basic_widgets.h b/src/ui/ui_basic_widgets.h index a2ca4159..526bb738 100644 --- a/src/ui/ui_basic_widgets.h +++ b/src/ui/ui_basic_widgets.h @@ -77,8 +77,8 @@ internal UI_Signal ui_button(String8 string); internal UI_Signal ui_buttonf(char *fmt, ...); internal UI_Signal ui_hover_label(String8 string); internal UI_Signal ui_hover_labelf(char *fmt, ...); -internal UI_Signal ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, U64 *edit_string_size_out, String8 pre_edit_value, String8 string); -internal UI_Signal ui_line_editf(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, U64 *edit_string_size_out, String8 pre_edit_value, char *fmt, ...); +internal UI_Signal ui_line_edit(U64 *cursor, U64 *mark, U8 *edit_buffer, U64 edit_buffer_size, U64 *edit_string_size_out, String8 pre_edit_value, String8 string); +internal UI_Signal ui_line_editf(U64 *cursor, U64 *mark, U8 *edit_buffer, U64 edit_buffer_size, U64 *edit_string_size_out, String8 pre_edit_value, char *fmt, ...); //////////////////////////////// //~ rjf: Images diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 34aa9a66..77642562 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -142,11 +142,11 @@ ui_scanned_column_from_column(String8 string, S64 start_column, Side side) } internal UI_TxtOp -ui_single_line_txt_op_from_event(Arena *arena, UI_Event *event, String8 string, TxtPt cursor, TxtPt mark) +ui_single_line_txt_op_from_event(Arena *arena, UI_Event *event, String8 string, U64 cursor, U64 mark) { - TxtPt next_cursor = cursor; - TxtPt next_mark = mark; - TxtRng range = {0}; + U64 next_cursor = cursor; + U64 next_mark = mark; + Rng1U64 range = {0}; String8 replace = {0}; String8 copy = {0}; UI_TxtOpFlags flags = 0; @@ -164,85 +164,78 @@ ui_single_line_txt_op_from_event(Arena *arena, UI_Event *event, String8 string, }break; case UI_EventDeltaUnit_Word: { - delta.x = (S32)ui_scanned_column_from_column(string, cursor.column, delta.x > 0 ? Side_Max : Side_Min) - cursor.column; + delta.x = (S32)(ui_scanned_column_from_column(string, (S64)cursor+1, delta.x > 0 ? Side_Max : Side_Min)-1 - (S64)cursor); }break; case UI_EventDeltaUnit_Line: case UI_EventDeltaUnit_Whole: case UI_EventDeltaUnit_Page: { - S64 first_nonwhitespace_column = 1; + U64 first_nonwhitespace_off = 0; for(U64 idx = 0; idx < string.size; idx += 1) { if(!char_is_space(string.str[idx])) { - first_nonwhitespace_column = (S64)idx + 1; + first_nonwhitespace_off = idx; break; } } - S64 home_dest_column = (cursor.column == first_nonwhitespace_column) ? 1 : first_nonwhitespace_column; - delta.x = (delta.x > 0) ? ((S64)string.size+1 - cursor.column) : (home_dest_column - cursor.column); + U64 home_dest_off = (cursor == first_nonwhitespace_off) ? 0 : first_nonwhitespace_off; + delta.x = (delta.x > 0) ? ((S64)string.size - (S64)cursor) : ((S64)home_dest_off - (S64)cursor); }break; } //- rjf: zero delta - if(!txt_pt_match(cursor, mark) && event->flags & UI_EventFlag_ZeroDeltaOnSelect) + if(cursor != mark && event->flags & UI_EventFlag_ZeroDeltaOnSelect) { delta = v2s32(0, 0); } //- rjf: form next cursor - if(txt_pt_match(cursor, mark) || !(event->flags & UI_EventFlag_ZeroDeltaOnSelect)) + if(cursor == mark || !(event->flags & UI_EventFlag_ZeroDeltaOnSelect)) { - next_cursor.column += delta.x; + next_cursor += delta.x; } //- rjf: cap at line if(event->flags & UI_EventFlag_CapAtLine) { - next_cursor.column = Clamp(1, next_cursor.column, (S64)(string.size+1)); + next_cursor = Clamp(0, next_cursor, string.size); } //- rjf: in some cases, we want to pick a selection side based on the delta - if(!txt_pt_match(cursor, mark) && event->flags & UI_EventFlag_PickSelectSide) + if(cursor != mark && event->flags & UI_EventFlag_PickSelectSide) { if(original_delta.x < 0 || original_delta.y < 0) { - next_cursor = next_mark = txt_pt_min(cursor, mark); + next_cursor = next_mark = Min(cursor, mark); } else if(original_delta.x > 0 || original_delta.y > 0) { - next_cursor = next_mark = txt_pt_max(cursor, mark); + next_cursor = next_mark = Max(cursor, mark); } } //- rjf: copying if(event->flags & UI_EventFlag_Copy) { - if(cursor.line == mark.line) - { - copy = str8_substr(string, r1u64(cursor.column-1, mark.column-1)); - flags |= UI_TxtOpFlag_Copy; - } - else - { - flags |= UI_TxtOpFlag_Invalid; - } + copy = str8_substr(string, r1u64(cursor, mark)); + flags |= UI_TxtOpFlag_Copy; } //- rjf: pasting if(event->flags & UI_EventFlag_Paste) { - range = txt_rng(cursor, mark); + range = r1u64(cursor, mark); replace = wm_get_clipboard_text(arena); - next_cursor = next_mark = txt_pt(cursor.line, cursor.column+replace.size); + next_cursor = next_mark = cursor + replace.size; } //- rjf: deletion if(event->flags & UI_EventFlag_Delete) { - TxtPt new_pos = txt_pt_min(next_cursor, next_mark); - range = txt_rng(next_cursor, next_mark); - replace = str8_lit(""); + U64 new_pos = Min(next_cursor, next_mark); + range = r1u64(next_cursor, next_mark); + replace = s(""); next_cursor = next_mark = new_pos; } @@ -255,19 +248,19 @@ ui_single_line_txt_op_from_event(Arena *arena, UI_Event *event, String8 string, //- rjf: insertion if(event->string.size != 0) { - range = txt_rng(cursor, mark); - replace = push_str8_copy(arena, event->string); - next_cursor = next_mark = txt_pt(range.min.line, range.min.column + event->string.size); + range = r1u64(cursor, mark); + replace = str8_copy(arena, event->string); + next_cursor = next_mark = range.min + event->string.size; } //- rjf: determine if this event should be taken, based on bounds of cursor { - if(next_cursor.column > string.size+replace.size+1 || 1 > next_cursor.column || event->delta_2s32.y != 0) + if(next_cursor > string.size+replace.size || event->delta_2s32.y != 0) { flags |= UI_TxtOpFlag_Invalid; } - next_cursor.column = Clamp(1, next_cursor.column, string.size+replace.size+1); - next_mark.column = Clamp(1, next_mark.column, string.size+replace.size+1); + next_cursor = Clamp(0, next_cursor, string.size+replace.size); + next_mark = Clamp(0, next_mark, string.size+replace.size); } //- rjf: build+fill @@ -284,15 +277,8 @@ ui_single_line_txt_op_from_event(Arena *arena, UI_Event *event, String8 string, } internal String8 -ui_push_string_replace_range(Arena *arena, String8 string, Rng1S64 col_range, String8 replace) +ui_push_string_replace_range(Arena *arena, String8 string, Rng1U64 range, String8 replace) { - //- rjf: convert to offset range - Rng1U64 range = - { - (U64)(col_range.min-1), - (U64)(col_range.max-1), - }; - //- rjf: clamp range if(range.min > string.size) { diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 445e3741..c7dcde6d 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -184,9 +184,9 @@ struct UI_TxtOp UI_TxtOpFlags flags; String8 replace; String8 copy; - TxtRng range; - TxtPt cursor; - TxtPt mark; + Rng1U64 range; + U64 cursor; + U64 mark; }; //////////////////////////////// @@ -776,8 +776,8 @@ internal void ui_eat_event_node(UI_EventList *list, UI_EventNode *node); internal B32 ui_char_is_scan_boundary(U8 c); internal S64 ui_scanned_column_from_column(String8 string, S64 start_column, Side side); -internal UI_TxtOp ui_single_line_txt_op_from_event(Arena *arena, UI_Event *event, String8 string, TxtPt cursor, TxtPt mark); -internal String8 ui_push_string_replace_range(Arena *arena, String8 string, Rng1S64 range, String8 replace); +internal UI_TxtOp ui_single_line_txt_op_from_event(Arena *arena, UI_Event *event, String8 string, U64 cursor, U64 mark); +internal String8 ui_push_string_replace_range(Arena *arena, String8 string, Rng1U64 range, String8 replace); //////////////////////////////// //~ rjf: Size Type Functions diff --git a/src/win32/window_manager/win32_window_manager.c b/src/win32/window_manager/win32_window_manager.c index bb155677..235a02f3 100644 --- a/src/win32/window_manager/win32_window_manager.c +++ b/src/win32/window_manager/win32_window_manager.c @@ -506,13 +506,17 @@ w32_wm_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_CHAR: { U32 character = wParam; - if(character >= 32 && character != 127) + if(character >= 10 && character != 127) { WM_Event *event = w32_wm_push_event(WM_EventKind_Text, window); if(lParam & bit29) { event->modifiers |= WM_Modifier_Alt; } + if(character == '\r') + { + character = '\n'; + } event->character = character; } }break; diff --git a/src/window_manager/window_manager.c b/src/window_manager/window_manager.c index c5dc11cb..c6008c13 100644 --- a/src/window_manager/window_manager.c +++ b/src/window_manager/window_manager.c @@ -91,6 +91,7 @@ wm_codepoint_from_modifiers_and_key(WM_Modifiers modifiers, WM_Key key) // rjf: special-case map local_persist read_only struct {U32 character; WM_Key key; WM_Modifiers modifiers;} map[] = { + {'\n', WM_Key_Return, 0}, {'!', WM_Key_1, WM_Modifier_Shift}, {'@', WM_Key_2, WM_Modifier_Shift}, {'#', WM_Key_3, WM_Modifier_Shift},