From 8e390db03c1594dfb6d7bc991e0c6a4b930734d2 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sat, 11 Jan 2020 16:27:34 -0800 Subject: [PATCH] Optimizing auto-indent scanning logic --- custom/4coder_auto_indent.cpp | 82 ++++++++++++++++------------- custom/4coder_auto_indent.h | 8 +++ custom/generated/command_metadata.h | 8 +-- 3 files changed, 58 insertions(+), 40 deletions(-) diff --git a/custom/4coder_auto_indent.cpp b/custom/4coder_auto_indent.cpp index b672edd4..e34efdb1 100644 --- a/custom/4coder_auto_indent.cpp +++ b/custom/4coder_auto_indent.cpp @@ -147,6 +147,17 @@ indent__unfinished_statement(Token *token, Nest *current_nest){ return(result); } +function void +line_indent_cache_update(Application_Links *app, Buffer_ID buffer, i32 tab_width, Indent_Line_Cache *line_cache){ + if (line_cache->line_number_for_cached_indent != line_cache->where_token_starts){ + ProfileScope(app, "get indent info"); + line_cache->line_number_for_cached_indent = line_cache->where_token_starts; + line_cache->start_pos = get_line_start_pos(app, buffer, line_cache->where_token_starts); + Range_i64 range = Ii64(line_cache->start_pos, line_cache->one_past_last_pos); + line_cache->indent_info = get_indent_info_range(app, buffer, range, tab_width); + } +} + internal i64* get_indentation_array(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 lines, Indent_Flag flags, i32 tab_width, i32 indent_width){ ProfileScope(app, "get indentation array"); @@ -176,30 +187,16 @@ get_indentation_array(Application_Links *app, Arena *arena, Buffer_ID buffer, Ra i64 actual_indent = 0; b32 in_unfinished_statement = false; - i64 line_where_token_starts = 0; - i64 line_start_pos = 0; - i64 line_one_past_last_pos = 0; - Indent_Info line_indent_info = {}; + Indent_Line_Cache line_cache = {}; for (;;){ Token *token = token_it_read(&token_it); - if (line_where_token_starts == 0 || - token->pos >= line_one_past_last_pos){ - - { - line_where_token_starts = get_line_number_from_pos(app, buffer, token->pos); - } - { - line_start_pos = get_line_start_pos(app, buffer, line_where_token_starts); - } - { - line_one_past_last_pos = get_line_end_pos(app, buffer, line_where_token_starts); - } - { - Range_i64 range = Ii64(line_start_pos, line_one_past_last_pos); - line_indent_info = get_indent_info_range(app, buffer, range, tab_width); - } + if (line_cache.where_token_starts == 0 || + token->pos >= line_cache.one_past_last_pos){ + ProfileScope(app, "get line number"); + line_cache.where_token_starts = get_line_number_from_pos(app, buffer, token->pos); + line_cache.one_past_last_pos = get_line_end_pos(app, buffer, line_cache.where_token_starts); } i64 current_indent = 0; @@ -251,7 +248,8 @@ get_indentation_array(Application_Links *app, Arena *arena, Buffer_ID buffer, Ra Nest *new_nest = indent__new_nest(arena, &nest_alloc); sll_stack_push(nest, new_nest); nest->kind = TokenBaseKind_ParentheticalOpen; - nest->indent = (token->pos - line_indent_info.first_char_pos) + 1; + line_indent_cache_update(app, buffer, tab_width, &line_cache); + nest->indent = (token->pos - line_cache.indent_info.first_char_pos) + 1; following_indent = nest->indent; shift_by_actual_indent = true; }break; @@ -282,25 +280,37 @@ if (line_it == lines.end){goto finished;} \ actual_indent = N; ) i64 line_it = line_last_indented; - for (;line_it < line_where_token_starts;){ - line_it += 1; - if (line_it == line_where_token_starts){ - EMIT(this_indent); - } - else{ - EMIT(last_indent); + if (lines.first <= line_cache.where_token_starts){ + for (;line_it < line_cache.where_token_starts;){ + line_it += 1; + if (line_it == line_cache.where_token_starts){ + EMIT(this_indent); + } + else{ + EMIT(last_indent); + } } } + else{ + actual_indent = this_indent; + line_it = line_cache.where_token_starts; + } - i64 line_where_token_starts_shift = this_indent - line_indent_info.indent_pos; i64 line_where_token_ends = get_line_number_from_pos(app, buffer, token->pos + token->size); - for (;line_it < line_where_token_ends;){ - line_it += 1; - i64 line_it_start_pos = get_line_start_pos(app, buffer, line_it); - Indent_Info line_it_indent_info = get_indent_info_line_number_and_start(app, buffer, line_it, line_it_start_pos, tab_width); - i64 new_indent = line_it_indent_info.indent_pos + line_where_token_starts_shift; - new_indent = clamp_bot(0, new_indent); - EMIT(new_indent); + if (lines.first <= line_where_token_ends){ + line_indent_cache_update(app, buffer, tab_width, &line_cache); + i64 line_where_token_starts_shift = this_indent - line_cache.indent_info.indent_pos; + for (;line_it < line_where_token_ends;){ + line_it += 1; + i64 line_it_start_pos = get_line_start_pos(app, buffer, line_it); + Indent_Info line_it_indent_info = get_indent_info_line_number_and_start(app, buffer, line_it, line_it_start_pos, tab_width); + i64 new_indent = line_it_indent_info.indent_pos + line_where_token_starts_shift; + new_indent = clamp_bot(0, new_indent); + EMIT(new_indent); + } + } + else{ + line_it = line_where_token_ends; } #undef EMIT diff --git a/custom/4coder_auto_indent.h b/custom/4coder_auto_indent.h index 214cc8b8..79e2fa05 100644 --- a/custom/4coder_auto_indent.h +++ b/custom/4coder_auto_indent.h @@ -24,6 +24,14 @@ struct Nest_Alloc{ Nest *free_nest; }; +struct Indent_Line_Cache{ + i64 where_token_starts; + i64 line_number_for_cached_indent; + i64 start_pos; + i64 one_past_last_pos; + Indent_Info indent_info; +}; + #endif // BOTTOM diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index 7064e503..cc473ae3 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -252,9 +252,9 @@ i32 line_number; }; static Command_Metadata fcoder_metacmd_table[229] = { { PROC_LINKS(allow_mouse, 0), false, "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 409 }, -{ PROC_LINKS(auto_indent_line_at_cursor, 0), false, "auto_indent_line_at_cursor", 26, "Auto-indents the line on which the cursor sits.", 47, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 397 }, -{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 407 }, -{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 388 }, +{ PROC_LINKS(auto_indent_line_at_cursor, 0), false, "auto_indent_line_at_cursor", 26, "Auto-indents the line on which the cursor sits.", 47, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 407 }, +{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 417 }, +{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 398 }, { PROC_LINKS(backspace_alpha_numeric_boundary, 0), false, "backspace_alpha_numeric_boundary", 32, "Delete characters between the cursor position and the first alphanumeric boundary to the left.", 94, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 154 }, { PROC_LINKS(backspace_char, 0), false, "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 96 }, { PROC_LINKS(basic_change_active_panel, 0), false, "basic_change_active_panel", 25, "Change the currently active panel, moving to the panel with the next highest view_id. Will not skipe the build panel if it is open.", 132, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 611 }, @@ -475,7 +475,7 @@ static Command_Metadata fcoder_metacmd_table[229] = { { PROC_LINKS(write_hack, 0), false, "write_hack", 10, "At the cursor, insert a '// HACK' comment, includes user name if it was specified in config.4coder.", 99, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 82 }, { PROC_LINKS(write_note, 0), false, "write_note", 10, "At the cursor, insert a '// NOTE' comment, includes user name if it was specified in config.4coder.", 99, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 88 }, { PROC_LINKS(write_space, 0), false, "write_space", 11, "Inserts a space.", 16, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 67 }, -{ PROC_LINKS(write_text_and_auto_indent, 0), false, "write_text_and_auto_indent", 26, "Inserts text and auto-indents the line on which the cursor sits if any of the text contains 'layout punctuation' such as ;:{}()[]# and new lines.", 145, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 417 }, +{ PROC_LINKS(write_text_and_auto_indent, 0), false, "write_text_and_auto_indent", 26, "Inserts text and auto-indents the line on which the cursor sits if any of the text contains 'layout punctuation' such as ;:{}()[]# and new lines.", 145, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 427 }, { PROC_LINKS(write_text_input, 0), false, "write_text_input", 16, "Inserts whatever text was used to trigger this command.", 55, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 59 }, { PROC_LINKS(write_todo, 0), false, "write_todo", 10, "At the cursor, insert a '// TODO' comment, includes user name if it was specified in config.4coder.", 99, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 76 }, { PROC_LINKS(write_underscore, 0), false, "write_underscore", 16, "Inserts an underscore.", 22, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 73 },