From d8e1f2f7d4286b71425c5e104e436cec162596c0 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Mon, 31 May 2021 16:08:54 -0700 Subject: [PATCH] [indent] fix inside paretheses bug --- custom/4coder_auto_indent.cpp | 815 ++++++++++++++-------------- custom/generated/command_metadata.h | 8 +- 2 files changed, 412 insertions(+), 411 deletions(-) diff --git a/custom/4coder_auto_indent.cpp b/custom/4coder_auto_indent.cpp index f960ff25..a2b17025 100644 --- a/custom/4coder_auto_indent.cpp +++ b/custom/4coder_auto_indent.cpp @@ -6,403 +6,404 @@ internal Batch_Edit* make_batch_from_indentations(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 lines, i64 *indentations, Indent_Flag flags, i32 tab_width){ -i64 *shifted_indentations = indentations - lines.first; - -Batch_Edit *batch_first = 0; -Batch_Edit *batch_last = 0; - -for (i64 line_number = lines.first; - line_number <= lines.max; - ++line_number){ -i64 line_start_pos = get_line_start_pos(app, buffer, line_number); -Indent_Info indent_info = get_indent_info_line_number_and_start(app, buffer, line_number, line_start_pos, tab_width); - -i64 correct_indentation = shifted_indentations[line_number]; -if (indent_info.is_blank && HasFlag(flags, Indent_ClearLine)){ -correct_indentation = 0; -} -if (correct_indentation <= -1){ -correct_indentation = indent_info.indent_pos; -} - -if (correct_indentation != indent_info.indent_pos){ -u64 str_size = 0; -u8 *str = 0; -if (HasFlag(flags, Indent_UseTab)){ -i64 tab_count = correct_indentation/tab_width; -i64 indent = tab_count*tab_width; -i64 space_count = correct_indentation - indent; -str_size = tab_count + space_count; -str = push_array(arena, u8, str_size); -block_fill_u8(str, tab_count, '\t'); -block_fill_u8(str + tab_count, space_count, ' '); -} -else{ -str_size = correct_indentation; -str = push_array(arena, u8, str_size); -block_fill_u8(str, str_size, ' '); -} - -Batch_Edit *batch = push_array(arena, Batch_Edit, 1); -sll_queue_push(batch_first, batch_last, batch); -batch->edit.text = SCu8(str, str_size); -batch->edit.range = Ii64(line_start_pos, indent_info.first_char_pos); -} -} - -return(batch_first); + i64 *shifted_indentations = indentations - lines.first; + + Batch_Edit *batch_first = 0; + Batch_Edit *batch_last = 0; + + for (i64 line_number = lines.first; + line_number <= lines.max; + ++line_number){ + i64 line_start_pos = get_line_start_pos(app, buffer, line_number); + Indent_Info indent_info = get_indent_info_line_number_and_start(app, buffer, line_number, line_start_pos, tab_width); + + i64 correct_indentation = shifted_indentations[line_number]; + if (indent_info.is_blank && HasFlag(flags, Indent_ClearLine)){ + correct_indentation = 0; + } + if (correct_indentation <= -1){ + correct_indentation = indent_info.indent_pos; + } + + if (correct_indentation != indent_info.indent_pos){ + u64 str_size = 0; + u8 *str = 0; + if (HasFlag(flags, Indent_UseTab)){ + i64 tab_count = correct_indentation/tab_width; + i64 indent = tab_count*tab_width; + i64 space_count = correct_indentation - indent; + str_size = tab_count + space_count; + str = push_array(arena, u8, str_size); + block_fill_u8(str, tab_count, '\t'); + block_fill_u8(str + tab_count, space_count, ' '); + } + else{ + str_size = correct_indentation; + str = push_array(arena, u8, str_size); + block_fill_u8(str, str_size, ' '); + } + + Batch_Edit *batch = push_array(arena, Batch_Edit, 1); + sll_queue_push(batch_first, batch_last, batch); + batch->edit.text = SCu8(str, str_size); + batch->edit.range = Ii64(line_start_pos, indent_info.first_char_pos); + } + } + + return(batch_first); } internal void set_line_indents(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 lines, i64 *indentations, Indent_Flag flags, i32 tab_width){ -Batch_Edit *batch = make_batch_from_indentations(app, arena, buffer, lines, indentations, flags, tab_width); -if (batch != 0){ -buffer_batch_edit(app, buffer, batch); -} + Batch_Edit *batch = make_batch_from_indentations(app, arena, buffer, lines, indentations, flags, tab_width); + if (batch != 0){ + buffer_batch_edit(app, buffer, batch); + } } internal Token* find_anchor_token(Application_Links *app, Buffer_ID buffer, Token_Array *tokens, i64 invalid_line){ -ProfileScope(app, "find anchor token"); -Token *result = 0; - -if (tokens != 0 && tokens->tokens != 0){ -result = tokens->tokens; -i64 invalid_pos = get_line_start_pos(app, buffer, invalid_line); -i32 scope_counter = 0; -i32 paren_counter = 0; -Token *token = tokens->tokens; -for (;;token += 1){ -if (token->pos + token->size > invalid_pos){ -break; -} -if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){ -if (scope_counter == 0 && paren_counter == 0){ -result = token; -} -switch (token->kind){ -case TokenBaseKind_ScopeOpen: -{ -scope_counter += 1; -}break; -case TokenBaseKind_ScopeClose: -{ -paren_counter = 0; -if (scope_counter > 0){ -scope_counter -= 1; -} -}break; -case TokenBaseKind_ParentheticalOpen: -{ -paren_counter += 1; -}break; -case TokenBaseKind_ParentheticalClose: -{ -if (paren_counter > 0){ -paren_counter -= 1; -} -}break; -} -} -} -} - -return(result); + ProfileScope(app, "find anchor token"); + Token *result = 0; + + if (tokens != 0 && tokens->tokens != 0){ + result = tokens->tokens; + i64 invalid_pos = get_line_start_pos(app, buffer, invalid_line); + i32 scope_counter = 0; + i32 paren_counter = 0; + Token *token = tokens->tokens; + for (;;token += 1){ + if (token->pos + token->size > invalid_pos){ + break; + } + if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){ + if (scope_counter == 0 && paren_counter == 0){ + result = token; + } + switch (token->kind){ + case TokenBaseKind_ScopeOpen: + { + scope_counter += 1; + }break; + case TokenBaseKind_ScopeClose: + { + paren_counter = 0; + if (scope_counter > 0){ + scope_counter -= 1; + } + }break; + case TokenBaseKind_ParentheticalOpen: + { + paren_counter += 1; + }break; + case TokenBaseKind_ParentheticalClose: + { + if (paren_counter > 0){ + paren_counter -= 1; + } + }break; + } + } + } + } + + return(result); } internal Nest* indent__new_nest(Arena *arena, Nest_Alloc *alloc){ -Nest *new_nest = alloc->free_nest; -if (new_nest == 0){ -new_nest = push_array(arena, Nest, 1); -} -else{ -sll_stack_pop(alloc->free_nest); -} -return(new_nest); + Nest *new_nest = alloc->free_nest; + if (new_nest == 0){ + new_nest = push_array(arena, Nest, 1); + } + else{ + sll_stack_pop(alloc->free_nest); + } + return(new_nest); } internal void indent__free_nest(Nest_Alloc *alloc, Nest *nest){ -sll_stack_push(alloc->free_nest, nest); + sll_stack_push(alloc->free_nest, nest); } internal b32 indent__unfinished_statement(Token *token, Nest *current_nest){ -b32 result = false; -if (current_nest != 0 && current_nest->kind == TokenBaseKind_ScopeOpen){ -result = true; -switch (token->kind){ -case TokenBaseKind_ScopeOpen: -case TokenBaseKind_ScopeClose: -case TokenBaseKind_StatementClose: -{ -result = false; -}break; -} -if (HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){ -result = false; -} -} -return(result); + b32 result = false; + if (current_nest != 0 && current_nest->kind == TokenBaseKind_ScopeOpen){ + result = true; + switch (token->kind){ + case TokenBaseKind_ScopeOpen: + case TokenBaseKind_ScopeClose: + case TokenBaseKind_StatementClose: + { + result = false; + }break; + } + if (HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){ + result = false; + } + } + 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); -} + 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"); -i64 count = lines.max - lines.min + 1; -i64 *indentations = push_array(arena, i64, count); -i64 *shifted_indentations = indentations - lines.first; -block_fill_u64(indentations, sizeof(*indentations)*count, (u64)(-1)); - + ProfileScope(app, "get indentation array"); + i64 count = lines.max - lines.min + 1; + i64 *indentations = push_array(arena, i64, count); + i64 *shifted_indentations = indentations - lines.first; + block_fill_u64(indentations, sizeof(*indentations)*count, (u64)(-1)); + #if 0 -Managed_Scope scope = buffer_get_managed_scope(app, buffer); -Token_Array *tokens = scope_attachment(app, scope, attachment_tokens, Token_Array); + Managed_Scope scope = buffer_get_managed_scope(app, buffer); + Token_Array *tokens = scope_attachment(app, scope, attachment_tokens, Token_Array); #endif - -Token_Array token_array = get_token_array_from_buffer(app, buffer); -Token_Array *tokens = &token_array; - -i64 anchor_line = clamp_bot(1, lines.first - 1); -Token *anchor_token = find_anchor_token(app, buffer, tokens, anchor_line); -if (anchor_token != 0 && - anchor_token >= tokens->tokens && - anchor_token < tokens->tokens + tokens->count){ -i64 line = get_line_number_from_pos(app, buffer, anchor_token->pos); -line = clamp_top(line, lines.first); - -Token_Iterator_Array token_it = token_iterator(0, tokens, anchor_token); - -Scratch_Block scratch(app, arena); -Nest *nest = 0; -Nest_Alloc nest_alloc = {}; - -i64 line_last_indented = line - 1; -i64 last_indent = 0; -i64 actual_indent = 0; -b32 in_unfinished_statement = false; - -Indent_Line_Cache line_cache = {}; - -for (;;){ -Token *token = token_it_read(&token_it); - -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; -if (nest != 0){ -current_indent = nest->indent; -} -i64 this_indent = current_indent; -i64 following_indent = current_indent; - -b32 shift_by_actual_indent = false; -b32 ignore_unfinished_statement = false; -if (HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){ -this_indent = 0; -} -else{ -switch (token->kind){ -case TokenBaseKind_ScopeOpen: -{ -Nest *new_nest = indent__new_nest(arena, &nest_alloc); -sll_stack_push(nest, new_nest); -nest->kind = TokenBaseKind_ScopeOpen; -nest->indent = current_indent + indent_width; -following_indent = nest->indent; -ignore_unfinished_statement = true; -}break; - -case TokenBaseKind_ScopeClose: -{ -for (;nest != 0 && nest->kind != TokenBaseKind_ScopeOpen;){ -Nest *n = nest; -sll_stack_pop(nest); -indent__free_nest(&nest_alloc, n); -} -if (nest != 0 && nest->kind == TokenBaseKind_ScopeOpen){ -Nest *n = nest; -sll_stack_pop(nest); -indent__free_nest(&nest_alloc, n); -} -this_indent = 0; -if (nest != 0){ -this_indent = nest->indent; -} -following_indent = this_indent; -ignore_unfinished_statement = true; -}break; - -case TokenBaseKind_ParentheticalOpen: -{ -Nest *new_nest = indent__new_nest(arena, &nest_alloc); -sll_stack_push(nest, new_nest); -nest->kind = TokenBaseKind_ParentheticalOpen; -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; - -case TokenBaseKind_ParentheticalClose: -{ -if (nest != 0 && nest->kind == TokenBaseKind_ParentheticalOpen){ -Nest *n = nest; -sll_stack_pop(nest); -indent__free_nest(&nest_alloc, n); -} -following_indent = 0; -if (nest != 0){ -following_indent = nest->indent; -} -//ignore_unfinished_statement = true; -}break; -} - -if (token->sub_kind == TokenCppKind_BlockComment || - token->sub_kind == TokenCppKind_LiteralStringRaw){ -ignore_unfinished_statement = true; -} - -if (in_unfinished_statement && !ignore_unfinished_statement){ -this_indent += indent_width; -} -} - + + Token_Array token_array = get_token_array_from_buffer(app, buffer); + Token_Array *tokens = &token_array; + + i64 anchor_line = clamp_bot(1, lines.first - 1); + Token *anchor_token = find_anchor_token(app, buffer, tokens, anchor_line); + if (anchor_token != 0 && + anchor_token >= tokens->tokens && + anchor_token < tokens->tokens + tokens->count){ + i64 line = get_line_number_from_pos(app, buffer, anchor_token->pos); + line = clamp_top(line, lines.first); + + Token_Iterator_Array token_it = token_iterator(0, tokens, anchor_token); + + Scratch_Block scratch(app, arena); + Nest *nest = 0; + Nest_Alloc nest_alloc = {}; + + i64 line_last_indented = line - 1; + i64 last_indent = 0; + i64 actual_indent = 0; + b32 in_unfinished_statement = false; + + Indent_Line_Cache line_cache = {}; + + for (;;){ + Token *token = token_it_read(&token_it); + + 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; + if (nest != 0){ + current_indent = nest->indent; + } + i64 this_indent = current_indent; + i64 following_indent = current_indent; + + b32 shift_by_actual_indent = false; + b32 ignore_unfinished_statement = false; + if (HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){ + this_indent = 0; + } + else{ + switch (token->kind){ + case TokenBaseKind_ScopeOpen: + { + Nest *new_nest = indent__new_nest(arena, &nest_alloc); + sll_stack_push(nest, new_nest); + nest->kind = TokenBaseKind_ScopeOpen; + nest->indent = current_indent + indent_width; + following_indent = nest->indent; + ignore_unfinished_statement = true; + }break; + + case TokenBaseKind_ScopeClose: + { + for (;nest != 0 && nest->kind != TokenBaseKind_ScopeOpen;){ + Nest *n = nest; + sll_stack_pop(nest); + indent__free_nest(&nest_alloc, n); + } + if (nest != 0 && nest->kind == TokenBaseKind_ScopeOpen){ + Nest *n = nest; + sll_stack_pop(nest); + indent__free_nest(&nest_alloc, n); + } + this_indent = 0; + if (nest != 0){ + this_indent = nest->indent; + } + following_indent = this_indent; + ignore_unfinished_statement = true; + }break; + + case TokenBaseKind_ParentheticalOpen: + { + Nest *new_nest = indent__new_nest(arena, &nest_alloc); + sll_stack_push(nest, new_nest); + nest->kind = TokenBaseKind_ParentheticalOpen; + 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; + ignore_unfinished_statement = true; + }break; + + case TokenBaseKind_ParentheticalClose: + { + if (nest != 0 && nest->kind == TokenBaseKind_ParentheticalOpen){ + Nest *n = nest; + sll_stack_pop(nest); + indent__free_nest(&nest_alloc, n); + } + following_indent = 0; + if (nest != 0){ + following_indent = nest->indent; + } + //ignore_unfinished_statement = true; + }break; + } + + if (token->sub_kind == TokenCppKind_BlockComment || + token->sub_kind == TokenCppKind_LiteralStringRaw){ + ignore_unfinished_statement = true; + } + + if (in_unfinished_statement && !ignore_unfinished_statement){ + this_indent += indent_width; + } + } + #define EMIT(N) \ Stmnt(if (lines.first <= line_it){shifted_indentations[line_it]=N;} \ if (line_it == lines.end){goto finished;} \ actual_indent = N; ) - -i64 line_it = line_last_indented; -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_ends = get_line_number_from_pos(app, buffer, token->pos + token->size); -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; -} + + i64 line_it = line_last_indented; + 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_ends = get_line_number_from_pos(app, buffer, token->pos + token->size); + 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 - -if (shift_by_actual_indent){ -nest->indent += actual_indent; -following_indent += actual_indent; -} - -if (token->kind != TokenBaseKind_Comment){ -in_unfinished_statement = indent__unfinished_statement(token, nest); -if (in_unfinished_statement){ -following_indent += indent_width; -} -} - -last_indent = following_indent; -line_last_indented = line_it; - -if (!token_it_inc_non_whitespace(&token_it)){ -break; -} -} -} - -finished:; -return(indentations); + + if (shift_by_actual_indent){ + nest->indent += actual_indent; + following_indent += actual_indent; + } + + if (token->kind != TokenBaseKind_Comment){ + in_unfinished_statement = indent__unfinished_statement(token, nest); + if (in_unfinished_statement){ + following_indent += indent_width; + } + } + + last_indent = following_indent; + line_last_indented = line_it; + + if (!token_it_inc_non_whitespace(&token_it)){ + break; + } + } + } + + finished:; + return(indentations); } internal b32 auto_indent_buffer(Application_Links *app, Buffer_ID buffer, Range_i64 pos, Indent_Flag flags, i32 tab_width, i32 indent_width){ -ProfileScope(app, "auto indent buffer"); -Token_Array token_array = get_token_array_from_buffer(app, buffer); -Token_Array *tokens = &token_array; - -b32 result = false; -if (tokens->tokens != 0){ -result = true; - -Scratch_Block scratch(app); -Range_i64 line_numbers = {}; -if (HasFlag(flags, Indent_FullTokens)){ -i32 safety_counter = 0; -for (;;){ -Range_i64 expanded = enclose_tokens(app, buffer, pos); -expanded = enclose_whole_lines(app, buffer, expanded); -if (expanded == pos){ -break; -} -pos = expanded; -safety_counter += 1; -if (safety_counter == 20){ -pos = buffer_range(app, buffer); -break; -} -} -} -line_numbers = get_line_range_from_pos_range(app, buffer, pos); - -i64 *indentations = get_indentation_array(app, scratch, buffer, line_numbers, flags, tab_width, indent_width); -set_line_indents(app, scratch, buffer, line_numbers, indentations, flags, tab_width); -} - -return(result); + ProfileScope(app, "auto indent buffer"); + Token_Array token_array = get_token_array_from_buffer(app, buffer); + Token_Array *tokens = &token_array; + + b32 result = false; + if (tokens->tokens != 0){ + result = true; + + Scratch_Block scratch(app); + Range_i64 line_numbers = {}; + if (HasFlag(flags, Indent_FullTokens)){ + i32 safety_counter = 0; + for (;;){ + Range_i64 expanded = enclose_tokens(app, buffer, pos); + expanded = enclose_whole_lines(app, buffer, expanded); + if (expanded == pos){ + break; + } + pos = expanded; + safety_counter += 1; + if (safety_counter == 20){ + pos = buffer_range(app, buffer); + break; + } + } + } + line_numbers = get_line_range_from_pos_range(app, buffer, pos); + + i64 *indentations = get_indentation_array(app, scratch, buffer, line_numbers, flags, tab_width, indent_width); + set_line_indents(app, scratch, buffer, line_numbers, indentations, flags, tab_width); + } + + return(result); } function void auto_indent_buffer(Application_Links *app, Buffer_ID buffer, Range_i64 pos, Indent_Flag flags){ -i32 indent_width = (i32)def_get_config_u64(app, vars_save_string_lit("indent_width")); -i32 tab_width = (i32)def_get_config_u64(app, vars_save_string_lit("default_tab_width")); -tab_width = clamp_bot(1, tab_width); -AddFlag(flags, Indent_FullTokens); -b32 indent_with_tabs = def_get_config_b32(vars_save_string_lit("indent_with_tabs")); -if (indent_with_tabs){ -AddFlag(flags, Indent_UseTab); -} -auto_indent_buffer(app, buffer, pos, flags, indent_width, tab_width); + i32 indent_width = (i32)def_get_config_u64(app, vars_save_string_lit("indent_width")); + i32 tab_width = (i32)def_get_config_u64(app, vars_save_string_lit("default_tab_width")); + tab_width = clamp_bot(1, tab_width); + AddFlag(flags, Indent_FullTokens); + b32 indent_with_tabs = def_get_config_b32(vars_save_string_lit("indent_with_tabs")); + if (indent_with_tabs){ + AddFlag(flags, Indent_UseTab); + } + auto_indent_buffer(app, buffer, pos, flags, indent_width, tab_width); } function void auto_indent_buffer(Application_Links *app, Buffer_ID buffer, Range_i64 pos){ -auto_indent_buffer(app, buffer, pos, 0); + auto_indent_buffer(app, buffer, pos, 0); } //////////////////////////////// @@ -410,78 +411,78 @@ auto_indent_buffer(app, buffer, pos, 0); CUSTOM_COMMAND_SIG(auto_indent_whole_file) CUSTOM_DOC("Audo-indents the entire current buffer.") { -View_ID view = get_active_view(app, Access_ReadWriteVisible); -Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible); -i64 buffer_size = buffer_get_size(app, buffer); -auto_indent_buffer(app, buffer, Ii64(0, buffer_size)); + View_ID view = get_active_view(app, Access_ReadWriteVisible); + Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible); + i64 buffer_size = buffer_get_size(app, buffer); + auto_indent_buffer(app, buffer, Ii64(0, buffer_size)); } CUSTOM_COMMAND_SIG(auto_indent_line_at_cursor) CUSTOM_DOC("Auto-indents the line on which the cursor sits.") { -View_ID view = get_active_view(app, Access_ReadWriteVisible); -Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible); -i64 pos = view_get_cursor_pos(app, view); -auto_indent_buffer(app, buffer, Ii64(pos)); -move_past_lead_whitespace(app, view, buffer); + View_ID view = get_active_view(app, Access_ReadWriteVisible); + Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible); + i64 pos = view_get_cursor_pos(app, view); + auto_indent_buffer(app, buffer, Ii64(pos)); + move_past_lead_whitespace(app, view, buffer); } CUSTOM_COMMAND_SIG(auto_indent_range) CUSTOM_DOC("Auto-indents the range between the cursor and the mark.") { -View_ID view = get_active_view(app, Access_ReadWriteVisible); -Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible); -Range_i64 range = get_view_range(app, view); -auto_indent_buffer(app, buffer, range); -move_past_lead_whitespace(app, view, buffer); + View_ID view = get_active_view(app, Access_ReadWriteVisible); + Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible); + Range_i64 range = get_view_range(app, view); + auto_indent_buffer(app, buffer, range); + move_past_lead_whitespace(app, view, buffer); } CUSTOM_COMMAND_SIG(write_text_and_auto_indent) CUSTOM_DOC("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.") { -ProfileScope(app, "write and auto indent"); -User_Input in = get_current_input(app); -String_Const_u8 insert = to_writable(&in); -if (insert.str != 0 && insert.size > 0){ -b32 do_auto_indent = false; -for (u64 i = 0; !do_auto_indent && i < insert.size; i += 1){ -switch (insert.str[i]){ -case ';': case ':': -case '{': case '}': -case '(': case ')': -case '[': case ']': -case '#': -case '\n': case '\t': -{ -do_auto_indent = true; -}break; -} -} -if (do_auto_indent){ -View_ID view = get_active_view(app, Access_ReadWriteVisible); -Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible); - -Range_i64 pos = {}; -if (view_has_highlighted_range(app, view)){ -pos = get_view_range(app, view); -} -else{ -pos.min = pos.max = view_get_cursor_pos(app, view); -} - -write_text_input(app); - -i64 end_pos = view_get_cursor_pos(app, view); -pos.min = Min(pos.min, end_pos); -pos.max = Max(pos.max, end_pos); - -auto_indent_buffer(app, buffer, pos, 0); -move_past_lead_whitespace(app, view, buffer); -} -else{ -write_text_input(app); -} -} + ProfileScope(app, "write and auto indent"); + User_Input in = get_current_input(app); + String_Const_u8 insert = to_writable(&in); + if (insert.str != 0 && insert.size > 0){ + b32 do_auto_indent = false; + for (u64 i = 0; !do_auto_indent && i < insert.size; i += 1){ + switch (insert.str[i]){ + case ';': case ':': + case '{': case '}': + case '(': case ')': + case '[': case ']': + case '#': + case '\n': case '\t': + { + do_auto_indent = true; + }break; + } + } + if (do_auto_indent){ + View_ID view = get_active_view(app, Access_ReadWriteVisible); + Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible); + + Range_i64 pos = {}; + if (view_has_highlighted_range(app, view)){ + pos = get_view_range(app, view); + } + else{ + pos.min = pos.max = view_get_cursor_pos(app, view); + } + + write_text_input(app); + + i64 end_pos = view_get_cursor_pos(app, view); + pos.min = Min(pos.min, end_pos); + pos.max = Max(pos.max, end_pos); + + auto_indent_buffer(app, buffer, pos, 0); + move_past_lead_whitespace(app, view, buffer); + } + else{ + write_text_input(app); + } + } } // BOTTOM diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index 60ed5c25..353a86e2 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -291,9 +291,9 @@ i32 line_number; }; static Command_Metadata fcoder_metacmd_table[268] = { { 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, 481 }, -{ 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, 419 }, -{ 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, 429 }, -{ 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, 410 }, +{ 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, 420 }, +{ 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, 430 }, +{ 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, 411 }, { 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, 668 }, @@ -553,7 +553,7 @@ static Command_Metadata fcoder_metacmd_table[268] = { { 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, 439 }, +{ 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, 440 }, { 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 },