Optimizing auto-indent scanning logic

master
Allen Webster 2020-01-11 16:27:34 -08:00
parent f1dd78f32a
commit 8e390db03c
3 changed files with 58 additions and 40 deletions

View File

@ -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

View File

@ -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

View File

@ -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 },