From a70da837fa92b0214ad9a042f68e8101abf59c6f Mon Sep 17 00:00:00 2001 From: Patrick Cleaveliln Date: Fri, 25 Jul 2025 06:05:41 +0000 Subject: [PATCH] don't reparse buffer on every keystroke --- src/core/core.odin | 2 +- src/core/file_buffer.odin | 25 ++++++++++++------- src/main.odin | 2 ++ src/panels/file_buffer.odin | 4 +-- src/panels/grep.odin | 12 ++++++--- todo.md | 50 +++++++++++++++++++++---------------- 6 files changed, 59 insertions(+), 36 deletions(-) diff --git a/src/core/core.odin b/src/core/core.odin index ebb9401..15f9fe1 100644 --- a/src/core/core.odin +++ b/src/core/core.odin @@ -188,7 +188,7 @@ yank_selection :: proc(state: ^State, buffer: ^FileBuffer) { } paste_register :: proc(state: ^State, register: Register, buffer: ^FileBuffer) { - insert_content(buffer, register.data) + insert_content(buffer, register.data, reparse_buffer = true) move_cursor_left(buffer) } diff --git a/src/core/file_buffer.odin b/src/core/file_buffer.odin index e5adfc0..5d807b2 100644 --- a/src/core/file_buffer.odin +++ b/src/core/file_buffer.odin @@ -982,7 +982,7 @@ scroll_file_buffer :: proc(buffer: ^FileBuffer, dir: ScrollDir, cursor: Maybe(^C } } -insert_content :: proc(buffer: ^FileBuffer, to_be_inserted: []u8) { +insert_content :: proc(buffer: ^FileBuffer, to_be_inserted: []u8, reparse_buffer: bool = false) { if len(to_be_inserted) == 0 { return; } @@ -995,10 +995,12 @@ insert_content :: proc(buffer: ^FileBuffer, to_be_inserted: []u8) { update_file_buffer_index_from_cursor(buffer); move_cursor_right(buffer, false, amt = len(to_be_inserted)); - ts.parse_buffer(&buffer.tree, tree_sitter_file_buffer_input(buffer)) + if reparse_buffer { + ts.parse_buffer(&buffer.tree, tree_sitter_file_buffer_input(buffer)) + } } -delete_content_from_buffer_cursor :: proc(buffer: ^FileBuffer, amount: int) { +delete_content_from_buffer_cursor :: proc(buffer: ^FileBuffer, amount: int, reparse_buffer: bool = false) { buffer.flags += { .UnsavedChanges } // Calculate proper line/col values @@ -1010,10 +1012,12 @@ delete_content_from_buffer_cursor :: proc(buffer: ^FileBuffer, amount: int) { buffer.history.cursor.line = it.cursor.line buffer.history.cursor.col = it.cursor.col - ts.parse_buffer(&buffer.tree, tree_sitter_file_buffer_input(buffer)) + if reparse_buffer { + ts.parse_buffer(&buffer.tree, tree_sitter_file_buffer_input(buffer)) + } } -delete_content_from_selection :: proc(buffer: ^FileBuffer, selection: ^Selection) { +delete_content_from_selection :: proc(buffer: ^FileBuffer, selection: ^Selection, reparse_buffer: bool = false) { buffer.flags += { .UnsavedChanges } selection^ = swap_selections(selection^) @@ -1028,7 +1032,9 @@ delete_content_from_selection :: proc(buffer: ^FileBuffer, selection: ^Selection move_cursor_left(buffer) } - ts.parse_buffer(&buffer.tree, tree_sitter_file_buffer_input(buffer)) + if reparse_buffer { + ts.parse_buffer(&buffer.tree, tree_sitter_file_buffer_input(buffer)) + } } delete_content :: proc{delete_content_from_buffer_cursor, delete_content_from_selection}; @@ -1043,10 +1049,11 @@ get_buffer_indent :: proc(buffer: ^FileBuffer, cursor: Maybe(Cursor) = nil) -> i ptr_cursor := &cursor.? move_cursor_start_of_line(buffer, ptr_cursor) - move_cursor_forward_end_of_word(buffer, ptr_cursor) - move_cursor_backward_start_of_word(buffer, ptr_cursor) - return cursor.?.col + it := new_file_buffer_iter_with_cursor(buffer, ptr_cursor^); + iterate_file_buffer_until(&it, until_non_whitespace) + + return it.cursor.col } buffer_to_string :: proc(buffer: ^FileBuffer, allocator := context.allocator) -> string { diff --git a/src/main.odin b/src/main.odin index f316571..a7cffb3 100644 --- a/src/main.odin +++ b/src/main.odin @@ -431,6 +431,8 @@ main :: proc() { core.move_cursor_left(buffer) sdl2.StopTextInput(); + + ts.parse_buffer(&buffer.tree, core.tree_sitter_file_buffer_input(buffer)) } case .TAB: { // TODO: change this to insert a tab character diff --git a/src/panels/file_buffer.odin b/src/panels/file_buffer.odin index 761d1eb..785b0d7 100644 --- a/src/panels/file_buffer.odin +++ b/src/panels/file_buffer.odin @@ -200,7 +200,7 @@ file_buffer_delete_actions :: proc(input_map: ^core.InputActions) { core.move_cursor_start_of_line(buffer, cursor = &sel_cur.start); core.move_cursor_end_of_line(buffer, cursor = &sel_cur.end, stop_at_end = false); - core.delete_content_from_selection(buffer, sel_cur) + core.delete_content_from_selection(buffer, sel_cur, reparse_buffer = true) buffer.selection = nil; core.reset_input_map(state) @@ -451,7 +451,7 @@ file_buffer_visual_actions :: proc(input_map: ^core.InputActions) { if state.yank_register.whole_line { core.insert_content(buffer, []u8{'\n'}); core.paste_register(state, state.yank_register, buffer) - core.insert_content(buffer, []u8{'\n'}); + core.insert_content(buffer, []u8{'\n'}, reparse_buffer = true); } else { core.paste_register(state, state.yank_register, buffer) } diff --git a/src/panels/grep.odin b/src/panels/grep.odin index 65e52a7..c9d8dd6 100644 --- a/src/panels/grep.odin +++ b/src/panels/grep.odin @@ -183,7 +183,7 @@ make_grep_panel :: proc() -> core.Panel { max_results := container_height / 16 for result, i in panel_state.query_results { - if i > max_results { + if i >= max_results { break } @@ -204,8 +204,14 @@ make_grep_panel :: proc() -> core.Panel { style.background_color = .Background2 } - ui.open_element(s, result.file_path[len(state.directory):], {}, style) - ui.close_element(s) + if len(result.file_path) > 0 { + ui.open_element(s, result.file_path[len(state.directory):], {}, style) + ui.close_element(s) + } else { + style.background_color = .BrightRed + ui.open_element(s, "BAD FILE DIRECTORY", {}, style) + ui.close_element(s) + } } } } diff --git a/todo.md b/todo.md index 942578b..cbac4bc 100644 --- a/todo.md +++ b/todo.md @@ -1,12 +1,13 @@ # Bugs - Fix jumping forward a word jumping past consecutive brackets -- Odd scrolling behavior on small screen heights -- Scrolling past end/beginning of results panics +- Scrolling past end/beginning of grep results panics +- "change selection" not pushing snapshot +- Don't allow panel navigation in grep panel # Visual QOL - Split grep search results into a table to avoid funky unaligned text -# Planned Features +# TODO - [ ] Jump List - [x] Use grouped lifetimes exclusively for memory allocation/freeing - [ ] Highlight which panel is currently active @@ -16,7 +17,6 @@ - [ ] Finish writing tests for all current user actions - Vim-like Macro replays - [ ] Simple File Search (vim /) -- [ ] Auto-indent - Modify input system to allow for keybinds that take input - Vim's f and F movement commands - Vim's r command @@ -29,26 +29,34 @@ - [ ] In-line errors - [ ] Go-to Definition/ - [ ] Find references -- Re-implement lost features from Plugins - - [ ] Integrate tree-sitter - - [x] Syntax Highlighting - - [ ] Auto Setup Parsers - - [ ] Download parser - - [ ] Compile/"Install" - - [ ] Auto-indent? - - [ ] Bootleg Telescope - - [ ] Grepping Files - - [x] Query across project - - [x] Open file in new buffer - - [x] Open file in new buffer at found location - - [ ] Preview file with context - - [x] Show Context - - [ ] Properly show lines numbers - - [ ] Don't overlap result list with file preview - - [ ] Open Buffer Search +- [ ] Integrate tree-sitter + - [x] Syntax Highlighting + - [ ] Auto Setup Parsers + - [ ] Download parser + - [ ] Compile/"Install" + - [ ] Auto-indent + - [x] Infer indent with similar lines + - [x] Infer indent with C-style scopes (languages using '{') + - [ ] Infer indent inside multi-line function calls (again C-style) + - [ ] Somehow use tree-sitter to be language agnostic (not sure this is even possible with TS) +- [ ] Bootleg Telescope + - [ ] Grepping Files + - [x] Query across project + - [x] Open file in new buffer + - [x] Open file in new buffer at found location + - [ ] Preview file with context + - [x] Show Context + - [ ] Properly show lines numbers + - [ ] Don't overlap result list with file preview + - [ ] Open Buffer Search + - [ ] Workspace file search - Re-write the UI (again) - [x] New UI - [ ] Styling + - [x] Background colors + - [x] Borders + Border Color + - [ ] Rounded corners? + - [ ] Gradients? - Undo/Redo - [x] Basic/Naive Undo/Redo - [ ] Interface for undo-able actions