diff --git a/custom/4coder_auto_indent.cpp b/custom/4coder_auto_indent.cpp index 3f0a3cf8..f960ff25 100644 --- a/custom/4coder_auto_indent.cpp +++ b/custom/4coder_auto_indent.cpp @@ -6,402 +6,403 @@ 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; +}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 = global_config.indent_width; - i32 tab_width = global_config.default_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); } //////////////////////////////// @@ -409,78 +410,78 @@ auto_indent_buffer(Application_Links *app, Buffer_ID buffer, Range_i64 pos){ 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/4coder_code_index.cpp b/custom/4coder_code_index.cpp index 2576a117..ace1bdd1 100644 --- a/custom/4coder_code_index.cpp +++ b/custom/4coder_code_index.cpp @@ -13,50 +13,50 @@ global Code_Index global_code_index = {}; // Looks like the only one I ever actually use is the file one, not the array one. function Code_Index_Nest* code_index_get_nest_(Code_Index_Nest_Ptr_Array *array, i64 pos){ - Code_Index_Nest *result = 0; - i32 count = array->count; - Code_Index_Nest **nest_ptrs = array->ptrs; - for (i32 i = 0; i < count; i += 1){ - Code_Index_Nest *nest = nest_ptrs[i]; - if (nest->open.max <= pos && pos <= nest->close.min){ - Code_Index_Nest *sub_nest = code_index_get_nest_(&nest->nest_array, pos); - if (sub_nest != 0){ - result = sub_nest; - } - else{ - result = nest; - } - break; - } - } - return(result); +Code_Index_Nest *result = 0; +i32 count = array->count; +Code_Index_Nest **nest_ptrs = array->ptrs; +for (i32 i = 0; i < count; i += 1){ +Code_Index_Nest *nest = nest_ptrs[i]; +if (nest->open.max <= pos && pos <= nest->close.min){ +Code_Index_Nest *sub_nest = code_index_get_nest_(&nest->nest_array, pos); +if (sub_nest != 0){ +result = sub_nest; +} +else{ +result = nest; +} +break; +} +} +return(result); } function Code_Index_Nest* code_index_get_nest(Code_Index_File *file, i64 pos){ - return(code_index_get_nest_(&file->nest_array, pos)); +return(code_index_get_nest_(&file->nest_array, pos)); } function Code_Index_Note_List* code_index__list_from_string(String_Const_u8 string){ - u64 hash = table_hash_u8(string.str, string.size); - Code_Index_Note_List *result = &global_code_index.name_hash[hash % ArrayCount(global_code_index.name_hash)]; - return(result); +u64 hash = table_hash_u8(string.str, string.size); +Code_Index_Note_List *result = &global_code_index.name_hash[hash % ArrayCount(global_code_index.name_hash)]; +return(result); } function Code_Index_Note* code_index_note_from_string(String_Const_u8 string){ - Code_Index_Note_List *list = code_index__list_from_string(string); - Code_Index_Note *result = 0; - for (Code_Index_Note *node = list->first; - node != 0; - node = node->next_in_hash){ - if (string_match(string, node->text)){ - result = node; - break; - } - } - return(result); +Code_Index_Note_List *list = code_index__list_from_string(string); +Code_Index_Note *result = 0; +for (Code_Index_Note *node = list->first; + node != 0; + node = node->next_in_hash){ +if (string_match(string, node->text)){ +result = node; +break; +} +} +return(result); } @@ -65,181 +65,181 @@ code_index_note_from_string(String_Const_u8 string){ function void code_index_init(void){ - global_code_index.mutex = system_mutex_make(); - global_code_index.node_arena = make_arena_system(KB(4)); - global_code_index.buffer_to_index_file = make_table_u64_u64(global_code_index.node_arena.base_allocator, 500); +global_code_index.mutex = system_mutex_make(); +global_code_index.node_arena = make_arena_system(KB(4)); +global_code_index.buffer_to_index_file = make_table_u64_u64(global_code_index.node_arena.base_allocator, 500); } function Code_Index_File_Storage* code_index__alloc_storage(void){ - Code_Index_File_Storage *result = global_code_index.free_storage; - if (result == 0){ - result = push_array_zero(&global_code_index.node_arena, Code_Index_File_Storage, 1); - } - else{ - sll_stack_pop(global_code_index.free_storage); - } - zdll_push_back(global_code_index.storage_first, global_code_index.storage_last, result); - global_code_index.storage_count += 1; - return(result); +Code_Index_File_Storage *result = global_code_index.free_storage; +if (result == 0){ +result = push_array_zero(&global_code_index.node_arena, Code_Index_File_Storage, 1); +} +else{ +sll_stack_pop(global_code_index.free_storage); +} +zdll_push_back(global_code_index.storage_first, global_code_index.storage_last, result); +global_code_index.storage_count += 1; +return(result); } function void code_index__free_storage(Code_Index_File_Storage *storage){ - zdll_remove(global_code_index.storage_first, global_code_index.storage_last, storage); - global_code_index.storage_count -= 1; - sll_stack_push(global_code_index.free_storage, storage); +zdll_remove(global_code_index.storage_first, global_code_index.storage_last, storage); +global_code_index.storage_count -= 1; +sll_stack_push(global_code_index.free_storage, storage); } function void code_index_push_nest(Code_Index_Nest_List *list, Code_Index_Nest *nest){ - sll_queue_push(list->first, list->last, nest); - list->count += 1; +sll_queue_push(list->first, list->last, nest); +list->count += 1; } function Code_Index_Nest_Ptr_Array code_index_nest_ptr_array_from_list(Arena *arena, Code_Index_Nest_List *list){ - Code_Index_Nest_Ptr_Array array = {}; - array.ptrs = push_array_zero(arena, Code_Index_Nest*, list->count); - array.count = list->count; - i32 counter = 0; - for (Code_Index_Nest *node = list->first; - node != 0; - node = node->next){ - array.ptrs[counter] = node; - counter += 1; - } - return(array); +Code_Index_Nest_Ptr_Array array = {}; +array.ptrs = push_array_zero(arena, Code_Index_Nest*, list->count); +array.count = list->count; +i32 counter = 0; +for (Code_Index_Nest *node = list->first; + node != 0; + node = node->next){ +array.ptrs[counter] = node; +counter += 1; +} +return(array); } function Code_Index_Note_Ptr_Array code_index_note_ptr_array_from_list(Arena *arena, Code_Index_Note_List *list){ - Code_Index_Note_Ptr_Array array = {}; - array.ptrs = push_array_zero(arena, Code_Index_Note*, list->count); - array.count = list->count; - i32 counter = 0; - for (Code_Index_Note *node = list->first; - node != 0; - node = node->next){ - array.ptrs[counter] = node; - counter += 1; - } - return(array); +Code_Index_Note_Ptr_Array array = {}; +array.ptrs = push_array_zero(arena, Code_Index_Note*, list->count); +array.count = list->count; +i32 counter = 0; +for (Code_Index_Note *node = list->first; + node != 0; + node = node->next){ +array.ptrs[counter] = node; +counter += 1; +} +return(array); } function void code_index_lock(void){ - system_mutex_acquire(global_code_index.mutex); +system_mutex_acquire(global_code_index.mutex); } function void code_index_unlock(void){ - system_mutex_release(global_code_index.mutex); +system_mutex_release(global_code_index.mutex); } function void code_index__hash_file(Code_Index_File *file){ - for (Code_Index_Note *node = file->note_list.first; - node != 0; - node = node->next){ - Code_Index_Note_List *list = code_index__list_from_string(node->text); - zdll_push_back_NP_(list->first, list->last, node, next_in_hash, prev_in_hash); - list->count += 1; - } +for (Code_Index_Note *node = file->note_list.first; + node != 0; + node = node->next){ +Code_Index_Note_List *list = code_index__list_from_string(node->text); +zdll_push_back_NP_(list->first, list->last, node, next_in_hash, prev_in_hash); +list->count += 1; +} } function void code_index__clear_file(Code_Index_File *file){ - for (Code_Index_Note *node = file->note_list.first; - node != 0; - node = node->next){ - Code_Index_Note_List *list = code_index__list_from_string(node->text); - zdll_remove_NP_(list->first, list->last, node, next_in_hash, prev_in_hash); - list->count -= 1; - } +for (Code_Index_Note *node = file->note_list.first; + node != 0; + node = node->next){ +Code_Index_Note_List *list = code_index__list_from_string(node->text); +zdll_remove_NP_(list->first, list->last, node, next_in_hash, prev_in_hash); +list->count -= 1; +} } function void code_index_set_file(Buffer_ID buffer, Arena arena, Code_Index_File *index){ - Code_Index_File_Storage *storage = 0; - Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer); - if (lookup.found_match){ - u64 val = 0; - table_read(&global_code_index.buffer_to_index_file, lookup, &val); - storage = (Code_Index_File_Storage*)IntAsPtr(val); - code_index__clear_file(storage->file); - linalloc_clear(&storage->arena); - } - else{ - storage = code_index__alloc_storage(); - table_insert(&global_code_index.buffer_to_index_file, buffer, (u64)PtrAsInt(storage)); - } - storage->arena = arena; - storage->file = index; - - code_index__hash_file(index); +Code_Index_File_Storage *storage = 0; +Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer); +if (lookup.found_match){ +u64 val = 0; +table_read(&global_code_index.buffer_to_index_file, lookup, &val); +storage = (Code_Index_File_Storage*)IntAsPtr(val); +code_index__clear_file(storage->file); +linalloc_clear(&storage->arena); +} +else{ +storage = code_index__alloc_storage(); +table_insert(&global_code_index.buffer_to_index_file, buffer, (u64)PtrAsInt(storage)); +} +storage->arena = arena; +storage->file = index; + +code_index__hash_file(index); } function void code_index_erase_file(Buffer_ID buffer){ - Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer); - if (lookup.found_match){ - u64 val = 0; - table_read(&global_code_index.buffer_to_index_file, lookup, &val); - Code_Index_File_Storage *storage = (Code_Index_File_Storage*)IntAsPtr(val); - - code_index__clear_file(storage->file); - - linalloc_clear(&storage->arena); - table_erase(&global_code_index.buffer_to_index_file, lookup); - code_index__free_storage(storage); - } +Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer); +if (lookup.found_match){ +u64 val = 0; +table_read(&global_code_index.buffer_to_index_file, lookup, &val); +Code_Index_File_Storage *storage = (Code_Index_File_Storage*)IntAsPtr(val); + +code_index__clear_file(storage->file); + +linalloc_clear(&storage->arena); +table_erase(&global_code_index.buffer_to_index_file, lookup); +code_index__free_storage(storage); +} } function Code_Index_File* code_index_get_file(Buffer_ID buffer){ - Code_Index_File *result = 0; - Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer); - if (lookup.found_match){ - u64 val = 0; - table_read(&global_code_index.buffer_to_index_file, lookup, &val); - Code_Index_File_Storage *storage = (Code_Index_File_Storage*)IntAsPtr(val); - result = storage->file; - } - return(result); +Code_Index_File *result = 0; +Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer); +if (lookup.found_match){ +u64 val = 0; +table_read(&global_code_index.buffer_to_index_file, lookup, &val); +Code_Index_File_Storage *storage = (Code_Index_File_Storage*)IntAsPtr(val); +result = storage->file; +} +return(result); } function void index_shift(i64 *ptr, Range_i64 old_range, u64 new_size){ - i64 i = *ptr; - if (old_range.min <= i && i < old_range.max){ - *ptr = old_range.first; - } - else if (old_range.max <= i){ - *ptr = i + new_size - (old_range.max - old_range.min); - } +i64 i = *ptr; +if (old_range.min <= i && i < old_range.max){ +*ptr = old_range.first; +} +else if (old_range.max <= i){ +*ptr = i + new_size - (old_range.max - old_range.min); +} } function void code_index_shift(Code_Index_Nest_Ptr_Array *array, Range_i64 old_range, u64 new_size){ - i32 count = array->count; - Code_Index_Nest **nest_ptr = array->ptrs; - for (i32 i = 0; i < count; i += 1, nest_ptr += 1){ - Code_Index_Nest *nest = *nest_ptr; - index_shift(&nest->open.min, old_range, new_size); - index_shift(&nest->open.max, old_range, new_size); - if (nest->is_closed){ - index_shift(&nest->close.min, old_range, new_size); - index_shift(&nest->close.max, old_range, new_size); - } - code_index_shift(&nest->nest_array, old_range, new_size); - } +i32 count = array->count; +Code_Index_Nest **nest_ptr = array->ptrs; +for (i32 i = 0; i < count; i += 1, nest_ptr += 1){ +Code_Index_Nest *nest = *nest_ptr; +index_shift(&nest->open.min, old_range, new_size); +index_shift(&nest->open.max, old_range, new_size); +if (nest->is_closed){ +index_shift(&nest->close.min, old_range, new_size); +index_shift(&nest->close.max, old_range, new_size); +} +code_index_shift(&nest->nest_array, old_range, new_size); +} } function void code_index_shift(Code_Index_File *file, Range_i64 old_range, u64 new_size){ - code_index_shift(&file->nest_array, old_range, new_size); +code_index_shift(&file->nest_array, old_range, new_size); } @@ -248,49 +248,49 @@ code_index_shift(Code_Index_File *file, Range_i64 old_range, u64 new_size){ function void generic_parse_inc(Generic_Parse_State *state){ - if (!token_it_inc_all(&state->it)){ - state->finished = true; - } +if (!token_it_inc_all(&state->it)){ +state->finished = true; +} } function void generic_parse_skip_soft_tokens(Code_Index_File *index, Generic_Parse_State *state){ - Token *token = token_it_read(&state->it); - for (;token != 0 && !state->finished;){ - if (state->in_preprocessor && !HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){ - break; - } - if (token->kind == TokenBaseKind_Comment){ - state->handle_comment(state->app, state->arena, index, token, state->contents); - } - else if (token->kind == TokenBaseKind_Whitespace){ - Range_i64 range = Ii64(token); - u8 *ptr = state->contents.str + range.one_past_last - 1; - for (i64 i = range.one_past_last - 1; - i >= range.first; - i -= 1, ptr -= 1){ - if (*ptr == '\n'){ - state->prev_line_start = ptr + 1; - break; - } - } - } - else{ - break; - } - generic_parse_inc(state); - token = token_it_read(&state->it); - } +Token *token = token_it_read(&state->it); +for (;token != 0 && !state->finished;){ +if (state->in_preprocessor && !HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){ +break; +} +if (token->kind == TokenBaseKind_Comment){ +state->handle_comment(state->app, state->arena, index, token, state->contents); +} +else if (token->kind == TokenBaseKind_Whitespace){ +Range_i64 range = Ii64(token); +u8 *ptr = state->contents.str + range.one_past_last - 1; +for (i64 i = range.one_past_last - 1; + i >= range.first; + i -= 1, ptr -= 1){ +if (*ptr == '\n'){ +state->prev_line_start = ptr + 1; +break; +} +} +} +else{ +break; +} +generic_parse_inc(state); +token = token_it_read(&state->it); +} } function void generic_parse_init(Application_Links *app, Arena *arena, String_Const_u8 contents, Token_Array *tokens, Generic_Parse_Comment_Function *handle_comment, Generic_Parse_State *state){ - state->app = app; - state->arena = arena; - state->contents = contents; - state->it = token_iterator(0, tokens); - state->handle_comment = handle_comment; - state->prev_line_start = contents.str; +state->app = app; +state->arena = arena; +state->contents = contents; +state->it = token_iterator(0, tokens); +state->handle_comment = handle_comment; +state->prev_line_start = contents.str; } //////////////////////////////// @@ -329,126 +329,126 @@ function: >"(" ["(" ")" | * - ("(" | ")")] ")" ("{" | ";") function Code_Index_Note* index_new_note(Code_Index_File *index, Generic_Parse_State *state, Range_i64 range, Code_Index_Note_Kind kind, Code_Index_Nest *parent){ - Code_Index_Note *result = push_array(state->arena, Code_Index_Note, 1); - sll_queue_push(index->note_list.first, index->note_list.last, result); - index->note_list.count += 1; - result->note_kind = kind; - result->pos = range; - result->text = push_string_copy(state->arena, string_substring(state->contents, range)); - result->file = index; - result->parent = parent; - return(result); +Code_Index_Note *result = push_array(state->arena, Code_Index_Note, 1); +sll_queue_push(index->note_list.first, index->note_list.last, result); +index->note_list.count += 1; +result->note_kind = kind; +result->pos = range; +result->text = push_string_copy(state->arena, string_substring(state->contents, range)); +result->file = index; +result->parent = parent; +return(result); } function void cpp_parse_type_structure(Code_Index_File *index, Generic_Parse_State *state, Code_Index_Nest *parent){ - generic_parse_inc(state); - generic_parse_skip_soft_tokens(index, state); - if (state->finished){ - return; - } - Token *token = token_it_read(&state->it); - if (token != 0 && token->kind == TokenBaseKind_Identifier){ - generic_parse_inc(state); - generic_parse_skip_soft_tokens(index, state); - Token *peek = token_it_read(&state->it); - if (peek != 0 && peek->kind == TokenBaseKind_StatementClose || - peek->kind == TokenBaseKind_ScopeOpen){ - index_new_note(index, state, Ii64(token), CodeIndexNote_Type, parent); - } - } +generic_parse_inc(state); +generic_parse_skip_soft_tokens(index, state); +if (state->finished){ +return; +} +Token *token = token_it_read(&state->it); +if (token != 0 && token->kind == TokenBaseKind_Identifier){ +generic_parse_inc(state); +generic_parse_skip_soft_tokens(index, state); +Token *peek = token_it_read(&state->it); +if (peek != 0 && peek->kind == TokenBaseKind_StatementClose || + peek->kind == TokenBaseKind_ScopeOpen){ +index_new_note(index, state, Ii64(token), CodeIndexNote_Type, parent); +} +} } function void cpp_parse_type_def(Code_Index_File *index, Generic_Parse_State *state, Code_Index_Nest *parent){ - generic_parse_inc(state); - generic_parse_skip_soft_tokens(index, state); - for (;;){ - b32 did_advance = false; - Token *token = token_it_read(&state->it); - if (token == 0 || state->finished){ - break; - } - if (token->kind == TokenBaseKind_Identifier){ - generic_parse_inc(state); - generic_parse_skip_soft_tokens(index, state); - did_advance = true; - Token *peek = token_it_read(&state->it); - if (peek != 0 && peek->kind == TokenBaseKind_StatementClose || - peek->kind == TokenBaseKind_ParentheticalOpen){ - index_new_note(index, state, Ii64(token), CodeIndexNote_Type, parent); - break; - } - } - else if (token->kind == TokenBaseKind_StatementClose || - token->kind == TokenBaseKind_ScopeOpen || - token->kind == TokenBaseKind_ScopeClose || - token->kind == TokenBaseKind_ScopeOpen || - token->kind == TokenBaseKind_ScopeClose){ - break; - } - else if (token->kind == TokenBaseKind_Keyword){ - String_Const_u8 lexeme = string_substring(state->contents, Ii64(token)); - if (string_match(lexeme, string_u8_litexpr("struct")) || - string_match(lexeme, string_u8_litexpr("union")) || - string_match(lexeme, string_u8_litexpr("enum"))){ - break; - } - } - if (!did_advance){ - generic_parse_inc(state); - generic_parse_skip_soft_tokens(index, state); - } - } +generic_parse_inc(state); +generic_parse_skip_soft_tokens(index, state); +for (;;){ +b32 did_advance = false; +Token *token = token_it_read(&state->it); +if (token == 0 || state->finished){ +break; +} +if (token->kind == TokenBaseKind_Identifier){ +generic_parse_inc(state); +generic_parse_skip_soft_tokens(index, state); +did_advance = true; +Token *peek = token_it_read(&state->it); +if (peek != 0 && peek->kind == TokenBaseKind_StatementClose || + peek->kind == TokenBaseKind_ParentheticalOpen){ +index_new_note(index, state, Ii64(token), CodeIndexNote_Type, parent); +break; +} +} +else if (token->kind == TokenBaseKind_StatementClose || + token->kind == TokenBaseKind_ScopeOpen || + token->kind == TokenBaseKind_ScopeClose || + token->kind == TokenBaseKind_ScopeOpen || + token->kind == TokenBaseKind_ScopeClose){ +break; +} +else if (token->kind == TokenBaseKind_Keyword){ +String_Const_u8 lexeme = string_substring(state->contents, Ii64(token)); +if (string_match(lexeme, string_u8_litexpr("struct")) || + string_match(lexeme, string_u8_litexpr("union")) || + string_match(lexeme, string_u8_litexpr("enum"))){ +break; +} +} +if (!did_advance){ +generic_parse_inc(state); +generic_parse_skip_soft_tokens(index, state); +} +} } function void cpp_parse_function(Code_Index_File *index, Generic_Parse_State *state, Code_Index_Nest *parent){ - Token *token = token_it_read(&state->it); - generic_parse_inc(state); - generic_parse_skip_soft_tokens(index, state); - if (state->finished){ - return; - } - Token *peek = token_it_read(&state->it); - Token *reset_point = peek; - if (peek != 0 && peek->sub_kind == TokenCppKind_ParenOp){ - b32 at_paren_close = false; - i32 paren_nest_level = 0; - for (; peek != 0;){ - generic_parse_inc(state); - generic_parse_skip_soft_tokens(index, state); - peek = token_it_read(&state->it); - if (peek == 0 || state->finished){ - break; - } - - if (peek->kind == TokenBaseKind_ParentheticalOpen){ - paren_nest_level += 1; - } - else if (peek->kind == TokenBaseKind_ParentheticalClose){ - if (paren_nest_level > 0){ - paren_nest_level -= 1; - } - else{ - at_paren_close = true; - break; - } - } - } - - if (at_paren_close){ - generic_parse_inc(state); - generic_parse_skip_soft_tokens(index, state); - peek = token_it_read(&state->it); - if (peek != 0 && - peek->kind == TokenBaseKind_ScopeOpen || - peek->kind == TokenBaseKind_StatementClose){ - index_new_note(index, state, Ii64(token), CodeIndexNote_Function, parent); - } - } - } - state->it = token_iterator(state->it.user_id, state->it.tokens, state->it.count, reset_point); +Token *token = token_it_read(&state->it); +generic_parse_inc(state); +generic_parse_skip_soft_tokens(index, state); +if (state->finished){ +return; +} +Token *peek = token_it_read(&state->it); +Token *reset_point = peek; +if (peek != 0 && peek->sub_kind == TokenCppKind_ParenOp){ +b32 at_paren_close = false; +i32 paren_nest_level = 0; +for (; peek != 0;){ +generic_parse_inc(state); +generic_parse_skip_soft_tokens(index, state); +peek = token_it_read(&state->it); +if (peek == 0 || state->finished){ +break; +} + +if (peek->kind == TokenBaseKind_ParentheticalOpen){ +paren_nest_level += 1; +} +else if (peek->kind == TokenBaseKind_ParentheticalClose){ +if (paren_nest_level > 0){ +paren_nest_level -= 1; +} +else{ +at_paren_close = true; +break; +} +} +} + +if (at_paren_close){ +generic_parse_inc(state); +generic_parse_skip_soft_tokens(index, state); +peek = token_it_read(&state->it); +if (peek != 0 && + peek->kind == TokenBaseKind_ScopeOpen || + peek->kind == TokenBaseKind_StatementClose){ +index_new_note(index, state, Ii64(token), CodeIndexNote_Function, parent); +} +} +} +state->it = token_iterator(state->it.user_id, state->it.tokens, state->it.count, reset_point); } function Code_Index_Nest* @@ -465,350 +465,350 @@ generic_parse_paren(Code_Index_File *index, Generic_Parse_State *state); function Code_Index_Nest* generic_parse_statement(Code_Index_File *index, Generic_Parse_State *state){ - Token *token = token_it_read(&state->it); - Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); - result->kind = CodeIndexNest_Statement; - result->open = Ii64(token->pos); - result->close = Ii64(max_i64); - result->file = index; - - state->in_statement = true; - - for (;;){ - generic_parse_skip_soft_tokens(index, state); - token = token_it_read(&state->it); - if (token == 0 || state->finished){ - break; - } - - if (state->in_preprocessor){ - if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || - token->kind == TokenBaseKind_Preprocessor){ - result->is_closed = true; - result->close = Ii64(token->pos); - break; - } - } - else{ - if (token->kind == TokenBaseKind_Preprocessor){ - result->is_closed = true; - result->close = Ii64(token->pos); - break; - } - } - - if (token->kind == TokenBaseKind_ScopeOpen || - token->kind == TokenBaseKind_ScopeClose || - token->kind == TokenBaseKind_ParentheticalOpen){ - result->is_closed = true; - result->close = Ii64(token->pos); - break; - } - - if (token->kind == TokenBaseKind_StatementClose){ - result->is_closed = true; - result->close = Ii64(token); - generic_parse_inc(state); - break; - } - - generic_parse_inc(state); - } - - state->in_statement = false; - - return(result); +Token *token = token_it_read(&state->it); +Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); +result->kind = CodeIndexNest_Statement; +result->open = Ii64(token->pos); +result->close = Ii64(max_i64); +result->file = index; + +state->in_statement = true; + +for (;;){ +generic_parse_skip_soft_tokens(index, state); +token = token_it_read(&state->it); +if (token == 0 || state->finished){ +break; +} + +if (state->in_preprocessor){ +if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || + token->kind == TokenBaseKind_Preprocessor){ +result->is_closed = true; +result->close = Ii64(token->pos); +break; +} +} +else{ +if (token->kind == TokenBaseKind_Preprocessor){ +result->is_closed = true; +result->close = Ii64(token->pos); +break; +} +} + +if (token->kind == TokenBaseKind_ScopeOpen || + token->kind == TokenBaseKind_ScopeClose || + token->kind == TokenBaseKind_ParentheticalOpen){ +result->is_closed = true; +result->close = Ii64(token->pos); +break; +} + +if (token->kind == TokenBaseKind_StatementClose){ +result->is_closed = true; +result->close = Ii64(token); +generic_parse_inc(state); +break; +} + +generic_parse_inc(state); +} + +state->in_statement = false; + +return(result); } function Code_Index_Nest* generic_parse_preprocessor(Code_Index_File *index, Generic_Parse_State *state){ - Token *token = token_it_read(&state->it); - Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); - result->kind = CodeIndexNest_Preprocessor; - result->open = Ii64(token->pos); - result->close = Ii64(max_i64); - result->file = index; - - state->in_preprocessor = true; - - b32 potential_macro = false; - if (state->do_cpp_parse){ - if (token->sub_kind == TokenCppKind_PPDefine){ - potential_macro = true; - } - } - - generic_parse_inc(state); - for (;;){ - generic_parse_skip_soft_tokens(index, state); - token = token_it_read(&state->it); - if (token == 0 || state->finished){ - break; - } - - if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || - token->kind == TokenBaseKind_Preprocessor){ - result->is_closed = true; - result->close = Ii64(token->pos); - break; - } - - if (state->do_cpp_parse && potential_macro){ - if (token->sub_kind == TokenCppKind_Identifier){ - index_new_note(index, state, Ii64(token), CodeIndexNote_Macro, result); - } - potential_macro = false; - } - - if (token->kind == TokenBaseKind_ScopeOpen){ - Code_Index_Nest *nest = generic_parse_scope(index, state); - nest->parent = result; - code_index_push_nest(&result->nest_list, nest); - continue; - } - - if (token->kind == TokenBaseKind_ParentheticalOpen){ - Code_Index_Nest *nest = generic_parse_paren(index, state); - nest->parent = result; - code_index_push_nest(&result->nest_list, nest); - continue; - } - - generic_parse_inc(state); - } - - result->nest_array = code_index_nest_ptr_array_from_list(state->arena, &result->nest_list); - - state->in_preprocessor = false; - - return(result); +Token *token = token_it_read(&state->it); +Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); +result->kind = CodeIndexNest_Preprocessor; +result->open = Ii64(token->pos); +result->close = Ii64(max_i64); +result->file = index; + +state->in_preprocessor = true; + +b32 potential_macro = false; +if (state->do_cpp_parse){ +if (token->sub_kind == TokenCppKind_PPDefine){ +potential_macro = true; +} +} + +generic_parse_inc(state); +for (;;){ +generic_parse_skip_soft_tokens(index, state); +token = token_it_read(&state->it); +if (token == 0 || state->finished){ +break; +} + +if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || + token->kind == TokenBaseKind_Preprocessor){ +result->is_closed = true; +result->close = Ii64(token->pos); +break; +} + +if (state->do_cpp_parse && potential_macro){ +if (token->sub_kind == TokenCppKind_Identifier){ +index_new_note(index, state, Ii64(token), CodeIndexNote_Macro, result); +} +potential_macro = false; +} + +if (token->kind == TokenBaseKind_ScopeOpen){ +Code_Index_Nest *nest = generic_parse_scope(index, state); +nest->parent = result; +code_index_push_nest(&result->nest_list, nest); +continue; +} + +if (token->kind == TokenBaseKind_ParentheticalOpen){ +Code_Index_Nest *nest = generic_parse_paren(index, state); +nest->parent = result; +code_index_push_nest(&result->nest_list, nest); +continue; +} + +generic_parse_inc(state); +} + +result->nest_array = code_index_nest_ptr_array_from_list(state->arena, &result->nest_list); + +state->in_preprocessor = false; + +return(result); } function Code_Index_Nest* generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state){ - Token *token = token_it_read(&state->it); - Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); - result->kind = CodeIndexNest_Scope; - result->open = Ii64(token); - result->close = Ii64(max_i64); - result->file = index; - - state->scope_counter += 1; - - generic_parse_inc(state); - for (;;){ - generic_parse_skip_soft_tokens(index, state); - token = token_it_read(&state->it); - if (token == 0 || state->finished){ - break; - } - - if (state->in_preprocessor){ - if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || - token->kind == TokenBaseKind_Preprocessor){ - break; - } - } - else{ - if (token->kind == TokenBaseKind_Preprocessor){ - Code_Index_Nest *nest = generic_parse_preprocessor(index, state); - code_index_push_nest(&index->nest_list, nest); - continue; - } - } - - if (token->kind == TokenBaseKind_ScopeClose){ - result->is_closed = true; - result->close = Ii64(token); - generic_parse_inc(state); - break; - } - - if (token->kind == TokenBaseKind_ScopeOpen){ - Code_Index_Nest *nest = generic_parse_scope(index, state); - nest->parent = result; - code_index_push_nest(&result->nest_list, nest); - continue; - } - - if (token->kind == TokenBaseKind_ParentheticalClose){ - generic_parse_inc(state); - continue; - } - - if (token->kind == TokenBaseKind_ParentheticalOpen){ - Code_Index_Nest *nest = generic_parse_paren(index, state); - nest->parent = result; - code_index_push_nest(&result->nest_list, nest); - - // NOTE(allen): after a parenthetical group we consider ourselves immediately - // transitioning into a statement - nest = generic_parse_statement(index, state); - nest->parent = result; - code_index_push_nest(&result->nest_list, nest); - - continue; - } - - { - Code_Index_Nest *nest = generic_parse_statement(index, state); - nest->parent = result; - code_index_push_nest(&result->nest_list, nest); - } - } - - result->nest_array = code_index_nest_ptr_array_from_list(state->arena, &result->nest_list); - - state->scope_counter -= 1; - - return(result); +Token *token = token_it_read(&state->it); +Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); +result->kind = CodeIndexNest_Scope; +result->open = Ii64(token); +result->close = Ii64(max_i64); +result->file = index; + +state->scope_counter += 1; + +generic_parse_inc(state); +for (;;){ +generic_parse_skip_soft_tokens(index, state); +token = token_it_read(&state->it); +if (token == 0 || state->finished){ +break; +} + +if (state->in_preprocessor){ +if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || + token->kind == TokenBaseKind_Preprocessor){ +break; +} +} +else{ +if (token->kind == TokenBaseKind_Preprocessor){ +Code_Index_Nest *nest = generic_parse_preprocessor(index, state); +code_index_push_nest(&index->nest_list, nest); +continue; +} +} + +if (token->kind == TokenBaseKind_ScopeClose){ +result->is_closed = true; +result->close = Ii64(token); +generic_parse_inc(state); +break; +} + +if (token->kind == TokenBaseKind_ScopeOpen){ +Code_Index_Nest *nest = generic_parse_scope(index, state); +nest->parent = result; +code_index_push_nest(&result->nest_list, nest); +continue; +} + +if (token->kind == TokenBaseKind_ParentheticalClose){ +generic_parse_inc(state); +continue; +} + +if (token->kind == TokenBaseKind_ParentheticalOpen){ +Code_Index_Nest *nest = generic_parse_paren(index, state); +nest->parent = result; +code_index_push_nest(&result->nest_list, nest); + +// NOTE(allen): after a parenthetical group we consider ourselves immediately +// transitioning into a statement +nest = generic_parse_statement(index, state); +nest->parent = result; +code_index_push_nest(&result->nest_list, nest); + +continue; +} + +{ +Code_Index_Nest *nest = generic_parse_statement(index, state); +nest->parent = result; +code_index_push_nest(&result->nest_list, nest); +} +} + +result->nest_array = code_index_nest_ptr_array_from_list(state->arena, &result->nest_list); + +state->scope_counter -= 1; + +return(result); } function Code_Index_Nest* generic_parse_paren(Code_Index_File *index, Generic_Parse_State *state){ - Token *token = token_it_read(&state->it); - Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); - result->kind = CodeIndexNest_Paren; - result->open = Ii64(token); - result->close = Ii64(max_i64); - result->file = index; - - i64 manifested_characters_on_line = 0; - { - u8 *ptr = state->prev_line_start; - u8 *end_ptr = state->contents.str + token->pos; - // NOTE(allen): Initial whitespace - for (;ptr < end_ptr; ptr += 1){ - if (!character_is_whitespace(*ptr)){ - break; - } - } - // NOTE(allen): Manifested characters - manifested_characters_on_line = (i64)(end_ptr - ptr) + token->size; - } - - state->paren_counter += 1; - - generic_parse_inc(state); - for (;;){ - generic_parse_skip_soft_tokens(index, state); - token = token_it_read(&state->it); - if (token == 0 || state->finished){ - break; - } - - if (state->in_preprocessor){ - if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || - token->kind == TokenBaseKind_Preprocessor){ - break; - } - } - else{ - if (token->kind == TokenBaseKind_Preprocessor){ - Code_Index_Nest *nest = generic_parse_preprocessor(index, state); - code_index_push_nest(&index->nest_list, nest); - continue; - } - } - - if (token->kind == TokenBaseKind_ParentheticalClose){ - result->is_closed = true; - result->close = Ii64(token); - generic_parse_inc(state); - break; - } - - if (token->kind == TokenBaseKind_ScopeClose){ - break; - } - - if (token->kind == TokenBaseKind_ScopeOpen){ - Code_Index_Nest *nest = generic_parse_scope(index, state); - nest->parent = result; - code_index_push_nest(&result->nest_list, nest); - continue; - } - - if (token->kind == TokenBaseKind_ParentheticalOpen){ - Code_Index_Nest *nest = generic_parse_paren(index, state); - nest->parent = result; - code_index_push_nest(&result->nest_list, nest); - continue; - } - - generic_parse_inc(state); - } - - result->nest_array = code_index_nest_ptr_array_from_list(state->arena, &result->nest_list); - - state->paren_counter -= 1; - - return(result); +Token *token = token_it_read(&state->it); +Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); +result->kind = CodeIndexNest_Paren; +result->open = Ii64(token); +result->close = Ii64(max_i64); +result->file = index; + +i64 manifested_characters_on_line = 0; +{ +u8 *ptr = state->prev_line_start; +u8 *end_ptr = state->contents.str + token->pos; +// NOTE(allen): Initial whitespace +for (;ptr < end_ptr; ptr += 1){ +if (!character_is_whitespace(*ptr)){ +break; +} +} +// NOTE(allen): Manifested characters +manifested_characters_on_line = (i64)(end_ptr - ptr) + token->size; +} + +state->paren_counter += 1; + +generic_parse_inc(state); +for (;;){ +generic_parse_skip_soft_tokens(index, state); +token = token_it_read(&state->it); +if (token == 0 || state->finished){ +break; +} + +if (state->in_preprocessor){ +if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || + token->kind == TokenBaseKind_Preprocessor){ +break; +} +} +else{ +if (token->kind == TokenBaseKind_Preprocessor){ +Code_Index_Nest *nest = generic_parse_preprocessor(index, state); +code_index_push_nest(&index->nest_list, nest); +continue; +} +} + +if (token->kind == TokenBaseKind_ParentheticalClose){ +result->is_closed = true; +result->close = Ii64(token); +generic_parse_inc(state); +break; +} + +if (token->kind == TokenBaseKind_ScopeClose){ +break; +} + +if (token->kind == TokenBaseKind_ScopeOpen){ +Code_Index_Nest *nest = generic_parse_scope(index, state); +nest->parent = result; +code_index_push_nest(&result->nest_list, nest); +continue; +} + +if (token->kind == TokenBaseKind_ParentheticalOpen){ +Code_Index_Nest *nest = generic_parse_paren(index, state); +nest->parent = result; +code_index_push_nest(&result->nest_list, nest); +continue; +} + +generic_parse_inc(state); +} + +result->nest_array = code_index_nest_ptr_array_from_list(state->arena, &result->nest_list); + +state->paren_counter -= 1; + +return(result); } function b32 generic_parse_full_input_breaks(Code_Index_File *index, Generic_Parse_State *state, i32 limit){ - b32 result = false; - - i64 first_index = token_it_index(&state->it); - i64 one_past_last_index = first_index + limit; - for (;;){ - generic_parse_skip_soft_tokens(index, state); - Token *token = token_it_read(&state->it); - - if (token == 0 || state->finished){ - result = true; - break; - } - - if (token->kind == TokenBaseKind_Preprocessor){ - Code_Index_Nest *nest = generic_parse_preprocessor(index, state); - code_index_push_nest(&index->nest_list, nest); - } - else if (token->kind == TokenBaseKind_ScopeOpen){ - Code_Index_Nest *nest = generic_parse_scope(index, state); - code_index_push_nest(&index->nest_list, nest); - } - else if (token->kind == TokenBaseKind_ParentheticalOpen){ - Code_Index_Nest *nest = generic_parse_paren(index, state); - code_index_push_nest(&index->nest_list, nest); - } - else if (state->do_cpp_parse){ - if (token->sub_kind == TokenCppKind_Struct || - token->sub_kind == TokenCppKind_Union || - token->sub_kind == TokenCppKind_Enum){ - cpp_parse_type_structure(index, state, 0); - } - else if (token->sub_kind == TokenCppKind_Typedef){ - cpp_parse_type_def(index, state, 0); - } - else if (token->sub_kind == TokenCppKind_Identifier){ - cpp_parse_function(index, state, 0); - } - else{ - generic_parse_inc(state); - } - } - else{ - generic_parse_inc(state); - } - - i64 index = token_it_index(&state->it); - if (index >= one_past_last_index){ - token = token_it_read(&state->it); - if (token == 0){ - result = true; - } - break; - } - } - - if (result){ - index->nest_array = code_index_nest_ptr_array_from_list(state->arena, &index->nest_list); - index->note_array = code_index_note_ptr_array_from_list(state->arena, &index->note_list); - } - - return(result); +b32 result = false; + +i64 first_index = token_it_index(&state->it); +i64 one_past_last_index = first_index + limit; +for (;;){ +generic_parse_skip_soft_tokens(index, state); +Token *token = token_it_read(&state->it); + +if (token == 0 || state->finished){ +result = true; +break; +} + +if (token->kind == TokenBaseKind_Preprocessor){ +Code_Index_Nest *nest = generic_parse_preprocessor(index, state); +code_index_push_nest(&index->nest_list, nest); +} +else if (token->kind == TokenBaseKind_ScopeOpen){ +Code_Index_Nest *nest = generic_parse_scope(index, state); +code_index_push_nest(&index->nest_list, nest); +} +else if (token->kind == TokenBaseKind_ParentheticalOpen){ +Code_Index_Nest *nest = generic_parse_paren(index, state); +code_index_push_nest(&index->nest_list, nest); +} +else if (state->do_cpp_parse){ +if (token->sub_kind == TokenCppKind_Struct || + token->sub_kind == TokenCppKind_Union || + token->sub_kind == TokenCppKind_Enum){ +cpp_parse_type_structure(index, state, 0); +} +else if (token->sub_kind == TokenCppKind_Typedef){ +cpp_parse_type_def(index, state, 0); +} +else if (token->sub_kind == TokenCppKind_Identifier){ +cpp_parse_function(index, state, 0); +} +else{ +generic_parse_inc(state); +} +} +else{ +generic_parse_inc(state); +} + +i64 index = token_it_index(&state->it); +if (index >= one_past_last_index){ +token = token_it_read(&state->it); +if (token == 0){ +result = true; +} +break; +} +} + +if (result){ +index->nest_array = code_index_nest_ptr_array_from_list(state->arena, &index->nest_list); +index->note_array = code_index_note_ptr_array_from_list(state->arena, &index->note_list); +} + +return(result); } @@ -817,12 +817,12 @@ generic_parse_full_input_breaks(Code_Index_File *index, Generic_Parse_State *sta function void default_comment_index(Application_Links *app, Arena *arena, Code_Index_File *index, Token *token, String_Const_u8 contents){ - + } function void generic_parse_init(Application_Links *app, Arena *arena, String_Const_u8 contents, Token_Array *tokens, Generic_Parse_State *state){ - generic_parse_init(app, arena, contents, tokens, default_comment_index, state); +generic_parse_init(app, arena, contents, tokens, default_comment_index, state); } @@ -831,413 +831,416 @@ generic_parse_init(Application_Links *app, Arena *arena, String_Const_u8 content function Token_Pair layout_token_pair(Token_Array *tokens, i64 pos){ - Token_Pair result = {}; - Token_Iterator_Array it = token_iterator_pos(0, tokens, pos); - Token *b = token_it_read(&it); - if (b != 0){ - if (b->kind == TokenBaseKind_Whitespace){ - token_it_inc_non_whitespace(&it); - b = token_it_read(&it); - } - } - token_it_dec_non_whitespace(&it); - Token *a = token_it_read(&it); - if (a != 0){ - result.a = *a; - } - if (b != 0){ - result.b = *b; - } - return(result); +Token_Pair result = {}; +Token_Iterator_Array it = token_iterator_pos(0, tokens, pos); +Token *b = token_it_read(&it); +if (b != 0){ +if (b->kind == TokenBaseKind_Whitespace){ +token_it_inc_non_whitespace(&it); +b = token_it_read(&it); +} +} +token_it_dec_non_whitespace(&it); +Token *a = token_it_read(&it); +if (a != 0){ +result.a = *a; +} +if (b != 0){ +result.b = *b; +} +return(result); } function f32 layout_index_x_shift(Application_Links *app, Layout_Reflex *reflex, Code_Index_Nest *nest, i64 pos, f32 regular_indent, b32 *unresolved_dependence){ - f32 result = 0.f; - if (nest != 0){ - switch (nest->kind){ - case CodeIndexNest_Scope: - case CodeIndexNest_Preprocessor: - { - result = layout_index_x_shift(app, reflex, nest->parent, pos, regular_indent, unresolved_dependence); - if (nest->open.min < pos && nest->open.max <= pos && - (!nest->is_closed || pos < nest->close.min)){ - result += regular_indent; - } - }break; - - case CodeIndexNest_Statement: - { - result = layout_index_x_shift(app, reflex, nest->parent, pos, regular_indent, unresolved_dependence); - if (nest->open.min < pos && nest->open.max <= pos && - (!nest->is_closed || pos < nest->close.min)){ - result += regular_indent; - } - }break; - - case CodeIndexNest_Paren: - { - Rect_f32 box = layout_reflex_get_rect(app, reflex, nest->open.max - 1, unresolved_dependence); - result = box.x1; - }break; - } - } - return(result); +f32 result = 0.f; +if (nest != 0){ +switch (nest->kind){ +case CodeIndexNest_Scope: +case CodeIndexNest_Preprocessor: +{ +result = layout_index_x_shift(app, reflex, nest->parent, pos, regular_indent, unresolved_dependence); +if (nest->open.min < pos && nest->open.max <= pos && + (!nest->is_closed || pos < nest->close.min)){ +result += regular_indent; +} +}break; + +case CodeIndexNest_Statement: +{ +result = layout_index_x_shift(app, reflex, nest->parent, pos, regular_indent, unresolved_dependence); +if (nest->open.min < pos && nest->open.max <= pos && + (!nest->is_closed || pos < nest->close.min)){ +result += regular_indent; +} +}break; + +case CodeIndexNest_Paren: +{ +Rect_f32 box = layout_reflex_get_rect(app, reflex, nest->open.max - 1, unresolved_dependence); +result = box.x1; +}break; +} +} +return(result); } function f32 layout_index_x_shift(Application_Links *app, Layout_Reflex *reflex, Code_Index_Nest *nest, i64 pos, f32 regular_indent){ - b32 ignore; - return(layout_index_x_shift(app, reflex, nest, pos, regular_indent, &ignore)); +b32 ignore; +return(layout_index_x_shift(app, reflex, nest, pos, regular_indent, &ignore)); } function f32 layout_index_x_shift(Application_Links *app, Layout_Reflex *reflex, Code_Index_File *file, i64 pos, f32 regular_indent, b32 *unresolved_dependence){ - f32 indent = 0; - Code_Index_Nest *nest = code_index_get_nest(file, pos); - if (nest != 0){ - indent = layout_index_x_shift(app, reflex, nest, pos, regular_indent, unresolved_dependence); - } - return(indent); +f32 indent = 0; +Code_Index_Nest *nest = code_index_get_nest(file, pos); +if (nest != 0){ +indent = layout_index_x_shift(app, reflex, nest, pos, regular_indent, unresolved_dependence); +} +return(indent); } function f32 layout_index_x_shift(Application_Links *app, Layout_Reflex *reflex, Code_Index_File *file, i64 pos, f32 regular_indent){ - b32 ignore; - return(layout_index_x_shift(app, reflex, file, pos, regular_indent, &ignore)); +b32 ignore; +return(layout_index_x_shift(app, reflex, file, pos, regular_indent, &ignore)); } function void layout_index__emit_chunk(LefRig_TopBot_Layout_Vars *pos_vars, Face_ID face, Arena *arena, u8 *text_str, i64 range_first, u8 *ptr, u8 *end, Layout_Item_List *list){ - for (;ptr < end;){ - Character_Consume_Result consume = utf8_consume(ptr, (u64)(end - ptr)); - if (consume.codepoint != '\r'){ - i64 index = layout_index_from_ptr(ptr, text_str, range_first); - if (consume.codepoint != max_u32){ - lr_tb_write(pos_vars, face, arena, list, index, consume.codepoint); - } - else{ - lr_tb_write_byte(pos_vars, face, arena, list, index, *ptr); - } - } - ptr += consume.inc; - } +for (;ptr < end;){ +Character_Consume_Result consume = utf8_consume(ptr, (u64)(end - ptr)); +if (consume.codepoint != '\r'){ +i64 index = layout_index_from_ptr(ptr, text_str, range_first); +if (consume.codepoint != max_u32){ +lr_tb_write(pos_vars, face, arena, list, index, consume.codepoint); +} +else{ +lr_tb_write_byte(pos_vars, face, arena, list, index, *ptr); +} +} +ptr += consume.inc; +} } function i32 layout_token_score_wrap_token(Token_Pair *pair, Token_Cpp_Kind kind){ - i32 result = 0; - if (pair->a.sub_kind != kind && pair->b.sub_kind == kind){ - result -= 1; - } - else if (pair->a.sub_kind == kind && pair->b.sub_kind != kind){ - result += 1; - } - return(result); +i32 result = 0; +if (pair->a.sub_kind != kind && pair->b.sub_kind == kind){ +result -= 1; +} +else if (pair->a.sub_kind == kind && pair->b.sub_kind != kind){ +result += 1; +} +return(result); } function Layout_Item_List layout_index__inner(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width, Code_Index_File *file, Layout_Wrap_Kind kind){ - Scratch_Block scratch(app, arena); - - Token_Array tokens = get_token_array_from_buffer(app, buffer); - Token_Array *tokens_ptr = &tokens; - - Layout_Item_List list = get_empty_item_list(range); - String_Const_u8 text = push_buffer_range(app, scratch, buffer, range); - - Face_Advance_Map advance_map = get_face_advance_map(app, face); - Face_Metrics metrics = get_face_metrics(app, face); - LefRig_TopBot_Layout_Vars pos_vars = get_lr_tb_layout_vars(&advance_map, &metrics, width); - - f32 regular_indent = metrics.space_advance*global_config.virtual_whitespace_regular_indent; - f32 wrap_align_x = width - metrics.normal_advance; - - Layout_Reflex reflex = get_layout_reflex(&list, buffer, width, face); - - if (text.size == 0){ - lr_tb_write_blank(&pos_vars, face, arena, &list, range.start); - } - else{ - b32 first_of_the_line = true; - Newline_Layout_Vars newline_vars = get_newline_layout_vars(); - - u8 *ptr = text.str; - u8 *end_ptr = ptr + text.size; - u8 *word_ptr = ptr; - - u8 *pending_wrap_ptr = ptr; - f32 pending_wrap_x = 0.f; - i32 pending_wrap_paren_nest_count = 0; - i32 pending_wrap_token_score = 0; - f32 pending_wrap_accumulated_w = 0.f; - - start: - if (ptr == end_ptr){ - i64 index = layout_index_from_ptr(ptr, text.str, range.first); - f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); - lr_tb_advance_x_without_item(&pos_vars, shift); - goto finish; - } - - if (!character_is_whitespace(*ptr)){ - i64 index = layout_index_from_ptr(ptr, text.str, range.first); - f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); - lr_tb_advance_x_without_item(&pos_vars, shift); - goto consuming_non_whitespace; - } - - { - for (;ptr < end_ptr; ptr += 1){ - if (!character_is_whitespace(*ptr)){ - pending_wrap_ptr = ptr; - word_ptr = ptr; - i64 index = layout_index_from_ptr(ptr, text.str, range.first); - f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); - lr_tb_advance_x_without_item(&pos_vars, shift); - goto consuming_non_whitespace; - } - if (*ptr == '\r'){ - i64 index = layout_index_from_ptr(ptr, text.str, range.first); - newline_layout_consume_CR(&newline_vars, index); - } - else if (*ptr == '\n'){ - pending_wrap_ptr = ptr; - i64 index = layout_index_from_ptr(ptr, text.str, range.first); - f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); - lr_tb_advance_x_without_item(&pos_vars, shift); - goto consuming_normal_whitespace; - } - } - - if (ptr == end_ptr){ - pending_wrap_ptr = ptr; - i64 index = layout_index_from_ptr(ptr - 1, text.str, range.first); - f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); - lr_tb_advance_x_without_item(&pos_vars, shift); - goto finish; - } - } - - consuming_non_whitespace: - { - for (;ptr <= end_ptr; ptr += 1){ - if (ptr == end_ptr || character_is_whitespace(*ptr)){ - break; - } - } - - // NOTE(allen): measure this word - newline_layout_consume_default(&newline_vars); - String_Const_u8 word = SCu8(word_ptr, ptr); - u8 *word_end = ptr; - { - f32 word_advance = 0.f; - ptr = word.str; - for (;ptr < word_end;){ - Character_Consume_Result consume = utf8_consume(ptr, (u64)(word_end - ptr)); - if (consume.codepoint != max_u32){ - word_advance += lr_tb_advance(&pos_vars, face, consume.codepoint); - } - else{ - word_advance += lr_tb_advance_byte(&pos_vars); - } - ptr += consume.inc; - } - pending_wrap_accumulated_w += word_advance; - } - - if (!first_of_the_line && (kind == Layout_Wrapped) && lr_tb_crosses_width(&pos_vars, pending_wrap_accumulated_w)){ - i64 index = layout_index_from_ptr(pending_wrap_ptr, text.str, range.first); - lr_tb_align_rightward(&pos_vars, wrap_align_x); - lr_tb_write_ghost(&pos_vars, face, arena, &list, index, '\\'); - - lr_tb_next_line(&pos_vars); +Scratch_Block scratch(app, arena); + +Token_Array tokens = get_token_array_from_buffer(app, buffer); +Token_Array *tokens_ptr = &tokens; + +Layout_Item_List list = get_empty_item_list(range); +String_Const_u8 text = push_buffer_range(app, scratch, buffer, range); + +Face_Advance_Map advance_map = get_face_advance_map(app, face); +Face_Metrics metrics = get_face_metrics(app, face); +f32 tab_width = (f32)def_get_config_u64(app, vars_save_string_lit("default_tab_width")); +tab_width = clamp_bot(1, tab_width); +LefRig_TopBot_Layout_Vars pos_vars = get_lr_tb_layout_vars(&advance_map, &metrics, tab_width, width); + +u64 vw_indent = def_get_config_u64(app, vars_save_string_lit("virtual_whitespace_regular_indent")); +f32 regular_indent = metrics.space_advance*vw_indent; +f32 wrap_align_x = width - metrics.normal_advance; + +Layout_Reflex reflex = get_layout_reflex(&list, buffer, width, face); + +if (text.size == 0){ +lr_tb_write_blank(&pos_vars, face, arena, &list, range.start); +} +else{ +b32 first_of_the_line = true; +Newline_Layout_Vars newline_vars = get_newline_layout_vars(); + +u8 *ptr = text.str; +u8 *end_ptr = ptr + text.size; +u8 *word_ptr = ptr; + +u8 *pending_wrap_ptr = ptr; +f32 pending_wrap_x = 0.f; +i32 pending_wrap_paren_nest_count = 0; +i32 pending_wrap_token_score = 0; +f32 pending_wrap_accumulated_w = 0.f; + +start: +if (ptr == end_ptr){ +i64 index = layout_index_from_ptr(ptr, text.str, range.first); +f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); +lr_tb_advance_x_without_item(&pos_vars, shift); +goto finish; +} + +if (!character_is_whitespace(*ptr)){ +i64 index = layout_index_from_ptr(ptr, text.str, range.first); +f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); +lr_tb_advance_x_without_item(&pos_vars, shift); +goto consuming_non_whitespace; +} + +{ +for (;ptr < end_ptr; ptr += 1){ +if (!character_is_whitespace(*ptr)){ +pending_wrap_ptr = ptr; +word_ptr = ptr; +i64 index = layout_index_from_ptr(ptr, text.str, range.first); +f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); +lr_tb_advance_x_without_item(&pos_vars, shift); +goto consuming_non_whitespace; +} +if (*ptr == '\r'){ +i64 index = layout_index_from_ptr(ptr, text.str, range.first); +newline_layout_consume_CR(&newline_vars, index); +} +else if (*ptr == '\n'){ +pending_wrap_ptr = ptr; +i64 index = layout_index_from_ptr(ptr, text.str, range.first); +f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); +lr_tb_advance_x_without_item(&pos_vars, shift); +goto consuming_normal_whitespace; +} +} + +if (ptr == end_ptr){ +pending_wrap_ptr = ptr; +i64 index = layout_index_from_ptr(ptr - 1, text.str, range.first); +f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); +lr_tb_advance_x_without_item(&pos_vars, shift); +goto finish; +} +} + +consuming_non_whitespace: +{ +for (;ptr <= end_ptr; ptr += 1){ +if (ptr == end_ptr || character_is_whitespace(*ptr)){ +break; +} +} + +// NOTE(allen): measure this word +newline_layout_consume_default(&newline_vars); +String_Const_u8 word = SCu8(word_ptr, ptr); +u8 *word_end = ptr; +{ +f32 word_advance = 0.f; +ptr = word.str; +for (;ptr < word_end;){ +Character_Consume_Result consume = utf8_consume(ptr, (u64)(word_end - ptr)); +if (consume.codepoint != max_u32){ +word_advance += lr_tb_advance(&pos_vars, face, consume.codepoint); +} +else{ +word_advance += lr_tb_advance_byte(&pos_vars); +} +ptr += consume.inc; +} +pending_wrap_accumulated_w += word_advance; +} + +if (!first_of_the_line && (kind == Layout_Wrapped) && lr_tb_crosses_width(&pos_vars, pending_wrap_accumulated_w)){ +i64 index = layout_index_from_ptr(pending_wrap_ptr, text.str, range.first); +lr_tb_align_rightward(&pos_vars, wrap_align_x); +lr_tb_write_ghost(&pos_vars, face, arena, &list, index, '\\'); + +lr_tb_next_line(&pos_vars); #if 0 - f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); - lr_tb_advance_x_without_item(&pos_vars, shift); +f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); +lr_tb_advance_x_without_item(&pos_vars, shift); #endif - - ptr = pending_wrap_ptr; - pending_wrap_accumulated_w = 0.f; - first_of_the_line = true; - goto start; - } - } - - consuming_normal_whitespace: - for (; ptr < end_ptr; ptr += 1){ - if (!character_is_whitespace(*ptr)){ - u8 *new_wrap_ptr = ptr; - - i64 index = layout_index_from_ptr(new_wrap_ptr, text.str, range.first); - Code_Index_Nest *new_wrap_nest = code_index_get_nest(file, index); - b32 invalid_wrap_x = false; - f32 new_wrap_x = layout_index_x_shift(app, &reflex, new_wrap_nest, index, regular_indent, &invalid_wrap_x); - if (invalid_wrap_x){ - new_wrap_x = max_f32; - } - - i32 new_wrap_paren_nest_count = 0; - for (Code_Index_Nest *nest = new_wrap_nest; - nest != 0; - nest = nest->parent){ - if (nest->kind == CodeIndexNest_Paren){ - new_wrap_paren_nest_count += 1; - } - } - - Token_Pair new_wrap_token_pair = layout_token_pair(tokens_ptr, index); - - // TODO(allen): pull out the token scoring part and make it replacable for other - // language's token based wrap scoring needs. - i32 token_score = 0; - if (new_wrap_token_pair.a.kind == TokenBaseKind_Keyword){ - if (new_wrap_token_pair.b.kind == TokenBaseKind_ParentheticalOpen || - new_wrap_token_pair.b.kind == TokenBaseKind_Keyword){ - token_score -= 2; - } - } - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Eq); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_PlusEq); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_MinusEq); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_StarEq); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_DivEq); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_ModEq); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_LeftLeftEq); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_RightRightEq); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Comma); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_AndAnd); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_OrOr); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Ternary); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Colon); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Semicolon); - - i32 new_wrap_token_score = token_score; - - b32 new_wrap_ptr_is_better = false; - if (first_of_the_line){ - new_wrap_ptr_is_better = true; - } - else{ - if (new_wrap_token_score > pending_wrap_token_score){ - new_wrap_ptr_is_better = true; - } - else if (new_wrap_token_score == pending_wrap_token_score){ - f32 new_score = new_wrap_paren_nest_count*10.f + new_wrap_x; - f32 old_score = pending_wrap_paren_nest_count*10.f + pending_wrap_x + metrics.normal_advance*4.f + pending_wrap_accumulated_w*0.5f; - - if (new_score < old_score){ - new_wrap_ptr_is_better = true; - } - } - } - - if (new_wrap_ptr_is_better){ - layout_index__emit_chunk(&pos_vars, face, arena, text.str, range.first, pending_wrap_ptr, new_wrap_ptr, &list); - first_of_the_line = false; - - pending_wrap_ptr = new_wrap_ptr; - pending_wrap_paren_nest_count = new_wrap_paren_nest_count; - pending_wrap_x = layout_index_x_shift(app, &reflex, new_wrap_nest, index, regular_indent); - pending_wrap_paren_nest_count = new_wrap_paren_nest_count; - pending_wrap_token_score = new_wrap_token_score; - pending_wrap_accumulated_w = 0.f; - } - - word_ptr = ptr; - goto consuming_non_whitespace; - } - - i64 index = layout_index_from_ptr(ptr, text.str, range.first); - switch (*ptr){ - default: - { - newline_layout_consume_default(&newline_vars); - pending_wrap_accumulated_w += lr_tb_advance(&pos_vars, face, *ptr); - }break; - - case '\r': - { - newline_layout_consume_CR(&newline_vars, index); - }break; - - case '\n': - { - layout_index__emit_chunk(&pos_vars, face, arena, text.str, range.first, pending_wrap_ptr, ptr, &list); - pending_wrap_ptr = ptr + 1; - pending_wrap_accumulated_w = 0.f; - - u64 newline_index = newline_layout_consume_LF(&newline_vars, index); - lr_tb_write_blank(&pos_vars, face, arena, &list, newline_index); - lr_tb_next_line(&pos_vars); - first_of_the_line = true; - ptr += 1; - goto start; - }break; - } - } - - finish: - if (newline_layout_consume_finish(&newline_vars)){ - layout_index__emit_chunk(&pos_vars, face, arena, text.str, range.first, pending_wrap_ptr, ptr, &list); - i64 index = layout_index_from_ptr(ptr, text.str, range.first); - lr_tb_write_blank(&pos_vars, face, arena, &list, index); - } - } - - layout_item_list_finish(&list, -pos_vars.line_to_text_shift); - - return(list); + +ptr = pending_wrap_ptr; +pending_wrap_accumulated_w = 0.f; +first_of_the_line = true; +goto start; +} +} + +consuming_normal_whitespace: +for (; ptr < end_ptr; ptr += 1){ +if (!character_is_whitespace(*ptr)){ +u8 *new_wrap_ptr = ptr; + +i64 index = layout_index_from_ptr(new_wrap_ptr, text.str, range.first); +Code_Index_Nest *new_wrap_nest = code_index_get_nest(file, index); +b32 invalid_wrap_x = false; +f32 new_wrap_x = layout_index_x_shift(app, &reflex, new_wrap_nest, index, regular_indent, &invalid_wrap_x); +if (invalid_wrap_x){ +new_wrap_x = max_f32; +} + +i32 new_wrap_paren_nest_count = 0; +for (Code_Index_Nest *nest = new_wrap_nest; + nest != 0; + nest = nest->parent){ +if (nest->kind == CodeIndexNest_Paren){ +new_wrap_paren_nest_count += 1; +} +} + +Token_Pair new_wrap_token_pair = layout_token_pair(tokens_ptr, index); + +// TODO(allen): pull out the token scoring part and make it replacable for other +// language's token based wrap scoring needs. +i32 token_score = 0; +if (new_wrap_token_pair.a.kind == TokenBaseKind_Keyword){ +if (new_wrap_token_pair.b.kind == TokenBaseKind_ParentheticalOpen || + new_wrap_token_pair.b.kind == TokenBaseKind_Keyword){ +token_score -= 2; +} +} +token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Eq); +token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_PlusEq); +token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_MinusEq); +token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_StarEq); +token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_DivEq); +token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_ModEq); +token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_LeftLeftEq); +token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_RightRightEq); +token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Comma); +token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_AndAnd); +token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_OrOr); +token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Ternary); +token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Colon); +token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Semicolon); + +i32 new_wrap_token_score = token_score; + +b32 new_wrap_ptr_is_better = false; +if (first_of_the_line){ +new_wrap_ptr_is_better = true; +} +else{ +if (new_wrap_token_score > pending_wrap_token_score){ +new_wrap_ptr_is_better = true; +} +else if (new_wrap_token_score == pending_wrap_token_score){ +f32 new_score = new_wrap_paren_nest_count*10.f + new_wrap_x; +f32 old_score = pending_wrap_paren_nest_count*10.f + pending_wrap_x + metrics.normal_advance*4.f + pending_wrap_accumulated_w*0.5f; + +if (new_score < old_score){ +new_wrap_ptr_is_better = true; +} +} +} + +if (new_wrap_ptr_is_better){ +layout_index__emit_chunk(&pos_vars, face, arena, text.str, range.first, pending_wrap_ptr, new_wrap_ptr, &list); +first_of_the_line = false; + +pending_wrap_ptr = new_wrap_ptr; +pending_wrap_paren_nest_count = new_wrap_paren_nest_count; +pending_wrap_x = layout_index_x_shift(app, &reflex, new_wrap_nest, index, regular_indent); +pending_wrap_paren_nest_count = new_wrap_paren_nest_count; +pending_wrap_token_score = new_wrap_token_score; +pending_wrap_accumulated_w = 0.f; +} + +word_ptr = ptr; +goto consuming_non_whitespace; +} + +i64 index = layout_index_from_ptr(ptr, text.str, range.first); +switch (*ptr){ +default: +{ +newline_layout_consume_default(&newline_vars); +pending_wrap_accumulated_w += lr_tb_advance(&pos_vars, face, *ptr); +}break; + +case '\r': +{ +newline_layout_consume_CR(&newline_vars, index); +}break; + +case '\n': +{ +layout_index__emit_chunk(&pos_vars, face, arena, text.str, range.first, pending_wrap_ptr, ptr, &list); +pending_wrap_ptr = ptr + 1; +pending_wrap_accumulated_w = 0.f; + +u64 newline_index = newline_layout_consume_LF(&newline_vars, index); +lr_tb_write_blank(&pos_vars, face, arena, &list, newline_index); +lr_tb_next_line(&pos_vars); +first_of_the_line = true; +ptr += 1; +goto start; +}break; +} +} + +finish: +if (newline_layout_consume_finish(&newline_vars)){ +layout_index__emit_chunk(&pos_vars, face, arena, text.str, range.first, pending_wrap_ptr, ptr, &list); +i64 index = layout_index_from_ptr(ptr, text.str, range.first); +lr_tb_write_blank(&pos_vars, face, arena, &list, index); +} +} + +layout_item_list_finish(&list, -pos_vars.line_to_text_shift); + +return(list); } function Layout_Item_List layout_virt_indent_index(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width, Layout_Wrap_Kind kind){ - Layout_Item_List result = {}; - - b32 enable_virtual_whitespace = def_get_config_b32(vars_save_string_lit("enable_virtual_whitespace")); - if (enable_virtual_whitespace){ - code_index_lock(); - Code_Index_File *file = code_index_get_file(buffer); - if (file != 0){ - result = layout_index__inner(app, arena, buffer, range, face, width, file, kind); - } - code_index_unlock(); - if (file == 0){ - result = layout_virt_indent_literal(app, arena, buffer, range, face, width, kind); - } - } - else{ - result = layout_basic(app, arena, buffer, range, face, width, kind); - } - - return(result); +Layout_Item_List result = {}; + +b32 enable_virtual_whitespace = def_get_config_b32(vars_save_string_lit("enable_virtual_whitespace")); +if (enable_virtual_whitespace){ +code_index_lock(); +Code_Index_File *file = code_index_get_file(buffer); +if (file != 0){ +result = layout_index__inner(app, arena, buffer, range, face, width, file, kind); +} +code_index_unlock(); +if (file == 0){ +result = layout_virt_indent_literal(app, arena, buffer, range, face, width, kind); +} +} +else{ +result = layout_basic(app, arena, buffer, range, face, width, kind); +} + +return(result); } function Layout_Item_List layout_virt_indent_index_unwrapped(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width){ - return(layout_virt_indent_index(app, arena, buffer, range, face, width, Layout_Unwrapped)); +return(layout_virt_indent_index(app, arena, buffer, range, face, width, Layout_Unwrapped)); } function Layout_Item_List layout_virt_indent_index_wrapped(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width){ - return(layout_virt_indent_index(app, arena, buffer, range, face, width, Layout_Wrapped)); +return(layout_virt_indent_index(app, arena, buffer, range, face, width, Layout_Wrapped)); } function Layout_Item_List layout_virt_indent_index_generic(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width){ - Managed_Scope scope = buffer_get_managed_scope(app, buffer); - b32 *wrap_lines_ptr = scope_attachment(app, scope, buffer_wrap_lines, b32); - b32 wrap_lines = (wrap_lines_ptr != 0 && *wrap_lines_ptr); - return(layout_virt_indent_index(app, arena, buffer, range, face, width, wrap_lines?Layout_Wrapped:Layout_Unwrapped)); +Managed_Scope scope = buffer_get_managed_scope(app, buffer); +b32 *wrap_lines_ptr = scope_attachment(app, scope, buffer_wrap_lines, b32); +b32 wrap_lines = (wrap_lines_ptr != 0 && *wrap_lines_ptr); +return(layout_virt_indent_index(app, arena, buffer, range, face, width, wrap_lines?Layout_Wrapped:Layout_Unwrapped)); } CUSTOM_COMMAND_SIG(toggle_virtual_whitespace) CUSTOM_DOC("Toggles virtual whitespace for all files.") { - String_ID key = vars_save_string_lit("enable_virtual_whitespace"); - b32 enable_virtual_whitespace = def_get_config_b32(key); - def_set_config_b32(key, !enable_virtual_whitespace); +String_ID key = vars_save_string_lit("enable_virtual_whitespace"); +b32 enable_virtual_whitespace = def_get_config_b32(key); +def_set_config_b32(key, !enable_virtual_whitespace); } // BOTTOM diff --git a/custom/4coder_config.cpp b/custom/4coder_config.cpp index 35052f1c..20a30a2f 100644 --- a/custom/4coder_config.cpp +++ b/custom/4coder_config.cpp @@ -806,7 +806,35 @@ def_get_config_string(Arena *arena, String_ID key){ function void def_set_config_string(String_ID key, String_Const_u8 val){ - def_set_config_var(key, vars_save_string(val) ); + def_set_config_var(key, vars_save_string(val)); +} + +function u64 +def_get_config_u64(Application_Links *app, String_ID key){ + Scratch_Block scratch(app); + Variable_Handle var = def_get_config_var(key); + String_ID val = vars_string_id_from_var(var); + String_Const_u8 string = vars_read_string(scratch, val); + u64 result = 0; + if (string_match(string_prefix(string, 2), string_u8_litinit("0x"))){ + String_Const_u8 string_hex = string_skip(string, 2); + if (string_is_integer(string_hex, 0x10)){ + result = string_to_integer(string_hex, 0x10); + } + } + else{ + if (string_is_integer(string, 10)){ + result = string_to_integer(string, 10); + } + } + return(result); +} + +function void +def_set_config_u64(Application_Links *app, String_ID key, u64 val){ + Scratch_Block scratch(app); + String_Const_u8 val_string = push_stringf(scratch, "%llu", val); + def_set_config_var(key, vars_save_string(val_string)); } @@ -1341,16 +1369,9 @@ config_init_default(Config_Data *config){ config->mark_thickness = 2.f; config->lister_roundness = .20f; - config->virtual_whitespace_regular_indent = 4; - - config->indent_width = 4; - config->default_tab_width = 4; - config->default_font_size = 16; } -//parse_extension_line_to_extension_list - function Config* config_parse__data(Application_Links *app, Arena *arena, String_Const_u8 file_name, String_Const_u8 data, Config_Data *config){ @@ -1375,11 +1396,6 @@ config_parse__data(Application_Links *app, Arena *arena, String_Const_u8 file_na } } - config_int_var(parsed, "virtual_whitespace_regular_indent", 0, &config->virtual_whitespace_regular_indent); - - config_int_var(parsed, "indent_width", 0, &config->indent_width); - config_int_var(parsed, "default_tab_width", 0, &config->default_tab_width); - config_int_var(parsed, "default_font_size", 0, &config->default_font_size); } diff --git a/custom/4coder_config.h b/custom/4coder_config.h index 3a008e62..38785d04 100644 --- a/custom/4coder_config.h +++ b/custom/4coder_config.h @@ -182,11 +182,6 @@ struct Config_Data{ f32 mark_thickness; f32 lister_roundness; - i32 virtual_whitespace_regular_indent; - - i32 indent_width; - i32 default_tab_width; - i32 default_font_size; }; @@ -248,6 +243,9 @@ function void def_set_config_b32(String_ID key, b32 val); function String_Const_u8 def_get_config_string(Arena *arena, String_ID key); function void def_set_config_string(String_ID key, String_Const_u8 val); +function u64 def_get_config_u64(Application_Links *app, String_ID key); +function void def_set_config_u64(Application_Links *app, String_ID key, u64 val); + #endif // BOTTOM diff --git a/custom/4coder_helper.cpp b/custom/4coder_helper.cpp index 941efb92..9b66b845 100644 --- a/custom/4coder_helper.cpp +++ b/custom/4coder_helper.cpp @@ -2514,22 +2514,22 @@ exec_system_command(Application_Links *app, View_ID view, Buffer_Identifier buff //////////////////////////////// +#if 0 function f32 -font_get_glyph_advance(Face_Advance_Map *map, Face_Metrics *metrics, u32 codepoint){ - return(font_get_glyph_advance(map, metrics, codepoint, (f32)global_config.default_tab_width)); +font_get_glyph_advance(Face_Advance_Map *map, Face_Metrics *metrics, u32 codepoint, f32 tab_width){ + return(font_get_glyph_advance(map, metrics, codepoint, tab_width)); } function f32 font_get_max_glyph_advance_range(Face_Advance_Map *map, Face_Metrics *metrics, - u32 codepoint_first, u32 codepoint_last){ - return(font_get_max_glyph_advance_range(map, metrics, codepoint_first, codepoint_last, - (f32)global_config.default_tab_width)); + u32 codepoint_first, u32 codepoint_last, f32 tab_width){ + return(font_get_max_glyph_advance_range(map, metrics, codepoint_first, codepoint_last, tab_width)); } function f32 font_get_average_glyph_advance_range(Face_Advance_Map *map, Face_Metrics *metrics, - u32 codepoint_first, u32 codepoint_last){ - return(font_get_average_glyph_advance_range(map, metrics, codepoint_first, codepoint_last, - (f32)global_config.default_tab_width)); + u32 codepoint_first, u32 codepoint_last, f32 tab_width){ + return(font_get_average_glyph_advance_range(map, metrics, codepoint_first, codepoint_last, tab_width)); } +#endif //////////////////////////////// // NOTE(allen): Layout Invalidate diff --git a/custom/4coder_layout_rule.cpp b/custom/4coder_layout_rule.cpp index d83e3836..4d7afaf2 100644 --- a/custom/4coder_layout_rule.cpp +++ b/custom/4coder_layout_rule.cpp @@ -6,738 +6,747 @@ function Layout_Reflex get_layout_reflex(Layout_Item_List *list, Buffer_ID buffer, f32 width, Face_ID face){ - Layout_Reflex reflex = {}; - reflex.list = list; - reflex.buffer = buffer; - reflex.width = width; - reflex.face = face; - return(reflex); +Layout_Reflex reflex = {}; +reflex.list = list; +reflex.buffer = buffer; +reflex.width = width; +reflex.face = face; +return(reflex); } function Rect_f32 layout_reflex_get_rect(Application_Links *app, Layout_Reflex *reflex, i64 pos, b32 *unresolved_dependence){ - Rect_f32 rect = {}; - pos = clamp_bot(0, pos); - if (range_contains(reflex->list->input_index_range, pos)){ - if (range_contains(reflex->list->manifested_index_range, pos)){ - rect = layout_box_of_pos(*reflex->list, pos); - *unresolved_dependence = false; - } - else{ - *unresolved_dependence = true; - } - } - else{ - Buffer_Cursor cursor = buffer_compute_cursor(app, reflex->buffer, seek_pos(pos)); - rect = buffer_relative_box_of_pos(app, reflex->buffer, reflex->width, reflex->face, cursor.line, cursor.pos); - *unresolved_dependence = false; - } - return(rect); +Rect_f32 rect = {}; +pos = clamp_bot(0, pos); +if (range_contains(reflex->list->input_index_range, pos)){ +if (range_contains(reflex->list->manifested_index_range, pos)){ +rect = layout_box_of_pos(*reflex->list, pos); +*unresolved_dependence = false; +} +else{ +*unresolved_dependence = true; +} +} +else{ +Buffer_Cursor cursor = buffer_compute_cursor(app, reflex->buffer, seek_pos(pos)); +rect = buffer_relative_box_of_pos(app, reflex->buffer, reflex->width, reflex->face, cursor.line, cursor.pos); +*unresolved_dependence = false; +} +return(rect); } //////////////////////////////// function i64 layout_index_from_ptr(u8 *ptr, u8 *string_base, i64 index_base){ - return((i64)(ptr - string_base) + index_base); +return((i64)(ptr - string_base) + index_base); } function Layout_Item_List get_empty_item_list(Range_i64 input_range){ - Layout_Item_List list = {}; - list.input_index_range = input_range; - list.manifested_index_range = Ii64_neg_inf; - return(list); +Layout_Item_List list = {}; +list.input_index_range = input_range; +list.manifested_index_range = Ii64_neg_inf; +return(list); } function void layout_item_list_finish(Layout_Item_List *list, f32 bottom_padding){ - list->bottom_padding = bottom_padding; - list->height += bottom_padding; +list->bottom_padding = bottom_padding; +list->height += bottom_padding; } function void layout_write(Arena *arena, Layout_Item_List *list, Face_ID face, i64 index, u32 codepoint, Layout_Item_Flag flags, Rect_f32 rect, f32 padded_y1){ - Temp_Memory restore_point = begin_temp(arena); - Layout_Item *item = push_array(arena, Layout_Item, 1); - Layout_Item_Block *block = list->last; - if (block != 0){ - if (block->face != face){ - block = 0; - } - else if (block->items + block->item_count == item){ - block->item_count += 1; - } - else{ - block = 0; - } - } - if (block == 0){ - end_temp(restore_point); - block = push_array(arena, Layout_Item_Block, 1); - item = push_array(arena, Layout_Item, 1); - sll_queue_push(list->first, list->last, block); - list->node_count += 1; - block->items = item; - block->item_count = 1; - block->face = face; - } - - list->item_count += 1; - list->manifested_index_range.min = Min(list->manifested_index_range.min, index); - list->manifested_index_range.max = Max(list->manifested_index_range.max, index); - - if (!HasFlag(flags, LayoutItemFlag_Ghost_Character)){ - block->character_count += 1; - list->character_count += 1; - } - - item->index = index; - item->codepoint = codepoint; - item->flags = flags; - item->rect = rect; - item->padded_y1 = padded_y1; - list->height = Max(list->height, rect.y1); +Temp_Memory restore_point = begin_temp(arena); +Layout_Item *item = push_array(arena, Layout_Item, 1); +Layout_Item_Block *block = list->last; +if (block != 0){ +if (block->face != face){ +block = 0; +} +else if (block->items + block->item_count == item){ +block->item_count += 1; +} +else{ +block = 0; +} +} +if (block == 0){ +end_temp(restore_point); +block = push_array(arena, Layout_Item_Block, 1); +item = push_array(arena, Layout_Item, 1); +sll_queue_push(list->first, list->last, block); +list->node_count += 1; +block->items = item; +block->item_count = 1; +block->face = face; +} + +list->item_count += 1; +list->manifested_index_range.min = Min(list->manifested_index_range.min, index); +list->manifested_index_range.max = Max(list->manifested_index_range.max, index); + +if (!HasFlag(flags, LayoutItemFlag_Ghost_Character)){ +block->character_count += 1; +list->character_count += 1; +} + +item->index = index; +item->codepoint = codepoint; +item->flags = flags; +item->rect = rect; +item->padded_y1 = padded_y1; +list->height = Max(list->height, rect.y1); } //// function Newline_Layout_Vars get_newline_layout_vars(void){ - Newline_Layout_Vars result = {}; - result.newline_character_index = -1; - return(result); +Newline_Layout_Vars result = {}; +result.newline_character_index = -1; +return(result); } function void newline_layout_consume_CR(Newline_Layout_Vars *vars, i64 index){ - if (!vars->consuming_newline_characters){ - vars->consuming_newline_characters = true; - vars->newline_character_index = index; - } - vars->prev_did_emit_newline = false; +if (!vars->consuming_newline_characters){ +vars->consuming_newline_characters = true; +vars->newline_character_index = index; +} +vars->prev_did_emit_newline = false; } function i64 newline_layout_consume_LF(Newline_Layout_Vars *vars, i64 index){ - if (!vars->consuming_newline_characters){ - vars->newline_character_index = index; - } - vars->prev_did_emit_newline = true; - vars->consuming_newline_characters = false; - return(vars->newline_character_index); +if (!vars->consuming_newline_characters){ +vars->newline_character_index = index; +} +vars->prev_did_emit_newline = true; +vars->consuming_newline_characters = false; +return(vars->newline_character_index); } function void newline_layout_consume_default(Newline_Layout_Vars *vars){ - vars->consuming_newline_characters = false; - vars->prev_did_emit_newline = false; +vars->consuming_newline_characters = false; +vars->prev_did_emit_newline = false; } function b32 newline_layout_consume_finish(Newline_Layout_Vars *vars){ - return((!vars->prev_did_emit_newline)); +return((!vars->prev_did_emit_newline)); } //// function LefRig_TopBot_Layout_Vars -get_lr_tb_layout_vars(Face_Advance_Map *advance_map, Face_Metrics *metrics, f32 width){ - f32 text_height = metrics->text_height; - f32 line_height = metrics->line_height; - - LefRig_TopBot_Layout_Vars result = {}; - result.advance_map = advance_map; - result.metrics = metrics; - result.line_to_text_shift = text_height - line_height; - - result.blank_dim = V2f32(metrics->space_advance, text_height); - - result.line_y = line_height; - result.text_y = text_height; - result.width = width; - return(result); +get_lr_tb_layout_vars(Face_Advance_Map *advance_map, Face_Metrics *metrics, f32 tab_width, f32 width){ +f32 text_height = metrics->text_height; +f32 line_height = metrics->line_height; + +LefRig_TopBot_Layout_Vars result = {}; +result.advance_map = advance_map; +result.metrics = metrics; +result.tab_width = tab_width; +result.line_to_text_shift = text_height - line_height; + +result.blank_dim = V2f32(metrics->space_advance, text_height); + +result.line_y = line_height; +result.text_y = text_height; +result.width = width; +return(result); } function b32 lr_tb_crosses_width(LefRig_TopBot_Layout_Vars *vars, f32 advance, f32 width){ - return(vars->p.x + advance > width); +return(vars->p.x + advance > width); } function b32 lr_tb_crosses_width(LefRig_TopBot_Layout_Vars *vars, f32 advance){ - return(vars->p.x + advance > vars->width); +return(vars->p.x + advance > vars->width); } function f32 lr_tb_advance(LefRig_TopBot_Layout_Vars *vars, Face_ID face, u32 codepoint){ - return(font_get_glyph_advance(vars->advance_map, vars->metrics, codepoint)); +return(font_get_glyph_advance(vars->advance_map, vars->metrics, codepoint, vars->tab_width)); } function void lr_tb_write_with_advance_with_flags(LefRig_TopBot_Layout_Vars *vars, Face_ID face, f32 advance, Arena *arena, Layout_Item_List *list, i64 index, u32 codepoint, Layout_Item_Flag flags){ - if (codepoint == '\t'){ - codepoint = ' '; - } - vars->p.x = f32_ceil32(vars->p.x); - f32 next_x = vars->p.x + advance; - layout_write(arena, list, face, index, codepoint, flags, Rf32(vars->p, V2f32(next_x, vars->text_y)), vars->line_y); - vars->p.x = next_x; +if (codepoint == '\t'){ +codepoint = ' '; +} +vars->p.x = f32_ceil32(vars->p.x); +f32 next_x = vars->p.x + advance; +layout_write(arena, list, face, index, codepoint, flags, Rf32(vars->p, V2f32(next_x, vars->text_y)), vars->line_y); +vars->p.x = next_x; } function void lr_tb_write_with_advance(LefRig_TopBot_Layout_Vars *vars, Face_ID face, f32 advance, Arena *arena, Layout_Item_List *list, i64 index, u32 codepoint){ - lr_tb_write_with_advance_with_flags(vars, face, advance, arena, list, index, codepoint, 0); +lr_tb_write_with_advance_with_flags(vars, face, advance, arena, list, index, codepoint, 0); } function void lr_tb_write(LefRig_TopBot_Layout_Vars *vars, Face_ID face, Arena *arena, Layout_Item_List *list, i64 index, u32 codepoint){ - f32 advance = lr_tb_advance(vars, face, codepoint); - lr_tb_write_with_advance(vars, face, advance, arena, list, index, codepoint); +f32 advance = lr_tb_advance(vars, face, codepoint); +lr_tb_write_with_advance(vars, face, advance, arena, list, index, codepoint); } function void lr_tb_write_ghost(LefRig_TopBot_Layout_Vars *vars, Face_ID face, Arena *arena, Layout_Item_List *list, i64 index, u32 codepoint){ - f32 advance = lr_tb_advance(vars, face, codepoint); - lr_tb_write_with_advance_with_flags(vars, face, advance, arena, list, index, codepoint, LayoutItemFlag_Ghost_Character); +f32 advance = lr_tb_advance(vars, face, codepoint); +lr_tb_write_with_advance_with_flags(vars, face, advance, arena, list, index, codepoint, LayoutItemFlag_Ghost_Character); } function f32 lr_tb_advance_byte(LefRig_TopBot_Layout_Vars *vars){ - return(vars->metrics->byte_advance); +return(vars->metrics->byte_advance); } function void lr_tb_write_byte_with_advance(LefRig_TopBot_Layout_Vars *vars, Face_ID face, f32 advance, Arena *arena, Layout_Item_List *list, i64 index, u8 byte){ - Face_Metrics *metrics = vars->metrics; - - f32 final_next_x = vars->p.x + advance; - u32 lo = ((u32)byte )&0xF; - u32 hi = ((u32)byte >> 4)&0xF; - - Vec2_f32 p = vars->p; - p.x = f32_ceil32(p.x); - f32 next_x = p.x + metrics->byte_sub_advances[0]; - f32 text_y = vars->text_y; - - Layout_Item_Flag flags = LayoutItemFlag_Special_Character; - layout_write(arena, list, face, index, '\\', flags, Rf32(p, V2f32(next_x, text_y)), vars->line_y); - p.x = next_x; - - flags = LayoutItemFlag_Ghost_Character; - next_x += metrics->byte_sub_advances[1]; - layout_write(arena, list, face, index, integer_symbols[hi], flags, Rf32(p, V2f32(next_x, text_y)), vars->line_y); - p.x = next_x; - next_x += metrics->byte_sub_advances[2]; - layout_write(arena, list, face, index, integer_symbols[lo], flags, Rf32(p, V2f32(next_x, text_y)), vars->line_y); - - vars->p.x = final_next_x; +Face_Metrics *metrics = vars->metrics; + +f32 final_next_x = vars->p.x + advance; +u32 lo = ((u32)byte )&0xF; +u32 hi = ((u32)byte >> 4)&0xF; + +Vec2_f32 p = vars->p; +p.x = f32_ceil32(p.x); +f32 next_x = p.x + metrics->byte_sub_advances[0]; +f32 text_y = vars->text_y; + +Layout_Item_Flag flags = LayoutItemFlag_Special_Character; +layout_write(arena, list, face, index, '\\', flags, Rf32(p, V2f32(next_x, text_y)), vars->line_y); +p.x = next_x; + +flags = LayoutItemFlag_Ghost_Character; +next_x += metrics->byte_sub_advances[1]; +layout_write(arena, list, face, index, integer_symbols[hi], flags, Rf32(p, V2f32(next_x, text_y)), vars->line_y); +p.x = next_x; +next_x += metrics->byte_sub_advances[2]; +layout_write(arena, list, face, index, integer_symbols[lo], flags, Rf32(p, V2f32(next_x, text_y)), vars->line_y); + +vars->p.x = final_next_x; } function void lr_tb_write_byte(LefRig_TopBot_Layout_Vars *vars, Face_ID face, Arena *arena, Layout_Item_List *list, i64 index, u8 byte){ - lr_tb_write_byte_with_advance(vars, face, vars->metrics->byte_advance, - arena, list, index, byte); +lr_tb_write_byte_with_advance(vars, face, vars->metrics->byte_advance, + arena, list, index, byte); } function void lr_tb_write_blank_dim(LefRig_TopBot_Layout_Vars *vars, Face_ID face, Vec2_f32 dim, Arena *arena, Layout_Item_List *list, i64 index){ - layout_write(arena, list, face, index, ' ', 0, Rf32_xy_wh(vars->p, dim), vars->line_y); - vars->p.x += dim.x; +layout_write(arena, list, face, index, ' ', 0, Rf32_xy_wh(vars->p, dim), vars->line_y); +vars->p.x += dim.x; } function void lr_tb_write_blank(LefRig_TopBot_Layout_Vars *vars, Face_ID face, Arena *arena, Layout_Item_List *list, i64 index){ - lr_tb_write_blank_dim(vars, face, vars->blank_dim, arena, list, index); +lr_tb_write_blank_dim(vars, face, vars->blank_dim, arena, list, index); } function void lr_tb_next_line(LefRig_TopBot_Layout_Vars *vars){ - vars->p.x = 0.f; - vars->p.y = vars->line_y; - vars->line_y += vars->metrics->line_height; - vars->text_y = vars->line_y + vars->line_to_text_shift; +vars->p.x = 0.f; +vars->p.y = vars->line_y; +vars->line_y += vars->metrics->line_height; +vars->text_y = vars->line_y + vars->line_to_text_shift; } function void lr_tb_next_line_padded(LefRig_TopBot_Layout_Vars *vars, f32 top, f32 bot){ - vars->p.x = 0.f; - vars->p.y = vars->line_y + top; - vars->line_y += top + vars->metrics->line_height; - vars->text_y = vars->line_y + vars->line_to_text_shift; - vars->line_y += bot; +vars->p.x = 0.f; +vars->p.y = vars->line_y + top; +vars->line_y += top + vars->metrics->line_height; +vars->text_y = vars->line_y + vars->line_to_text_shift; +vars->line_y += bot; } function void lr_tb_advance_x_without_item(LefRig_TopBot_Layout_Vars *vars, f32 advance){ - vars->p.x += advance; +vars->p.x += advance; } function void lr_tb_align_rightward(LefRig_TopBot_Layout_Vars *vars, f32 align_x){ - vars->p.x = clamp_bot(align_x, vars->p.x); +vars->p.x = clamp_bot(align_x, vars->p.x); } //////////////////////////////// function Layout_Item_List layout_unwrapped_small_blank_lines(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width){ - Layout_Item_List list = get_empty_item_list(range); - - Scratch_Block scratch(app); - String_Const_u8 text = push_buffer_range(app, scratch, buffer, range); - - Face_Advance_Map advance_map = get_face_advance_map(app, face); - Face_Metrics metrics = get_face_metrics(app, face); - LefRig_TopBot_Layout_Vars pos_vars = get_lr_tb_layout_vars(&advance_map, &metrics, width); - - pos_vars.blank_dim = V2f32(metrics.space_advance, metrics.text_height*0.5f); - - if (text.size == 0){ - lr_tb_write_blank(&pos_vars, face, arena, &list, range.start); - } - else{ - Newline_Layout_Vars newline_vars = get_newline_layout_vars(); - - b32 all_whitespace = true; - for (u64 i = 0; i < text.size; i += 1){ - if (!character_is_whitespace(text.str[i])){ - all_whitespace = false; - break; - } - } - - if (!all_whitespace){ - pos_vars.blank_dim.y = metrics.text_height; - } - - u8 *ptr = text.str; - u8 *end_ptr = ptr + text.size; - for (;ptr < end_ptr;){ - Character_Consume_Result consume = utf8_consume(ptr, (u64)(end_ptr - ptr)); - - i64 index = layout_index_from_ptr(ptr, text.str, range.first); - switch (consume.codepoint){ - case '\t': - { - newline_layout_consume_default(&newline_vars); - Vec2_f32 dim = pos_vars.blank_dim; - dim.x = lr_tb_advance(&pos_vars, face, '\t'); - lr_tb_write_blank_dim(&pos_vars, face, dim, arena, &list, index); - }break; - - case ' ': - case '\f': - case '\v': - { - newline_layout_consume_default(&newline_vars); - lr_tb_write_blank(&pos_vars, face, arena, &list, index); - }break; - - default: - { - newline_layout_consume_default(&newline_vars); - lr_tb_write(&pos_vars, face, arena, &list, index, consume.codepoint); - }break; - - case '\r': - { - newline_layout_consume_CR(&newline_vars, index); - }break; - - case '\n': - { - i64 newline_index = newline_layout_consume_LF(&newline_vars, index); - lr_tb_write_blank(&pos_vars, face, arena, &list, newline_index); - lr_tb_next_line(&pos_vars); - }break; - - case max_u32: - { - newline_layout_consume_default(&newline_vars); - lr_tb_write_byte(&pos_vars, face, arena, &list, index, *ptr); - }break; - } - - ptr += consume.inc; - } - - if (newline_layout_consume_finish(&newline_vars)){ - i64 index = layout_index_from_ptr(ptr, text.str, range.first); - lr_tb_write_blank(&pos_vars, face, arena, &list, index); - } - } - - layout_item_list_finish(&list, -pos_vars.line_to_text_shift); - - return(list); +Layout_Item_List list = get_empty_item_list(range); + +Scratch_Block scratch(app); +String_Const_u8 text = push_buffer_range(app, scratch, buffer, range); + +Face_Advance_Map advance_map = get_face_advance_map(app, face); +Face_Metrics metrics = get_face_metrics(app, face); +f32 tab_width = (f32)def_get_config_u64(app, vars_save_string_lit("default_tab_width")); +tab_width = clamp_bot(1, tab_width); +LefRig_TopBot_Layout_Vars pos_vars = get_lr_tb_layout_vars(&advance_map, &metrics, tab_width, width); + +pos_vars.blank_dim = V2f32(metrics.space_advance, metrics.text_height*0.5f); + +if (text.size == 0){ +lr_tb_write_blank(&pos_vars, face, arena, &list, range.start); +} +else{ +Newline_Layout_Vars newline_vars = get_newline_layout_vars(); + +b32 all_whitespace = true; +for (u64 i = 0; i < text.size; i += 1){ +if (!character_is_whitespace(text.str[i])){ +all_whitespace = false; +break; +} +} + +if (!all_whitespace){ +pos_vars.blank_dim.y = metrics.text_height; +} + +u8 *ptr = text.str; +u8 *end_ptr = ptr + text.size; +for (;ptr < end_ptr;){ +Character_Consume_Result consume = utf8_consume(ptr, (u64)(end_ptr - ptr)); + +i64 index = layout_index_from_ptr(ptr, text.str, range.first); +switch (consume.codepoint){ +case '\t': +{ +newline_layout_consume_default(&newline_vars); +Vec2_f32 dim = pos_vars.blank_dim; +dim.x = lr_tb_advance(&pos_vars, face, '\t'); +lr_tb_write_blank_dim(&pos_vars, face, dim, arena, &list, index); +}break; + +case ' ': +case '\f': +case '\v': +{ +newline_layout_consume_default(&newline_vars); +lr_tb_write_blank(&pos_vars, face, arena, &list, index); +}break; + +default: +{ +newline_layout_consume_default(&newline_vars); +lr_tb_write(&pos_vars, face, arena, &list, index, consume.codepoint); +}break; + +case '\r': +{ +newline_layout_consume_CR(&newline_vars, index); +}break; + +case '\n': +{ +i64 newline_index = newline_layout_consume_LF(&newline_vars, index); +lr_tb_write_blank(&pos_vars, face, arena, &list, newline_index); +lr_tb_next_line(&pos_vars); +}break; + +case max_u32: +{ +newline_layout_consume_default(&newline_vars); +lr_tb_write_byte(&pos_vars, face, arena, &list, index, *ptr); +}break; +} + +ptr += consume.inc; +} + +if (newline_layout_consume_finish(&newline_vars)){ +i64 index = layout_index_from_ptr(ptr, text.str, range.first); +lr_tb_write_blank(&pos_vars, face, arena, &list, index); +} +} + +layout_item_list_finish(&list, -pos_vars.line_to_text_shift); + +return(list); } function Layout_Item_List layout_wrap_anywhere(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width){ - Scratch_Block scratch(app); - - Layout_Item_List list = get_empty_item_list(range); - - String_Const_u8 text = push_buffer_range(app, scratch, buffer, range); - - Face_Advance_Map advance_map = get_face_advance_map(app, face); - Face_Metrics metrics = get_face_metrics(app, face); - LefRig_TopBot_Layout_Vars pos_vars = get_lr_tb_layout_vars(&advance_map, &metrics, width); - - if (text.size == 0){ - lr_tb_write_blank(&pos_vars, face, arena, &list, range.first); - } - else{ - b32 first_of_the_line = true; - Newline_Layout_Vars newline_vars = get_newline_layout_vars(); - - u8 *ptr = text.str; - u8 *end_ptr = ptr + text.size; - for (;ptr < end_ptr;){ - Character_Consume_Result consume = utf8_consume(ptr, (u64)(end_ptr - ptr)); - i64 index = layout_index_from_ptr(ptr, text.str, range.first); - switch (consume.codepoint){ - default: - { - newline_layout_consume_default(&newline_vars); - f32 advance = lr_tb_advance(&pos_vars, face, consume.codepoint); - if (!first_of_the_line && lr_tb_crosses_width(&pos_vars, advance)){ - lr_tb_next_line(&pos_vars); - } - lr_tb_write_with_advance(&pos_vars, face, advance, arena, &list, index, consume.codepoint); - first_of_the_line = false; - }break; - - case '\r': - { - newline_layout_consume_CR(&newline_vars, index); - }break; - - case '\n': - { - i64 newline_index = newline_layout_consume_LF(&newline_vars, index); - lr_tb_write_blank(&pos_vars, face, arena, &list, newline_index); - lr_tb_next_line(&pos_vars); - first_of_the_line = true; - }break; - - case max_u32: - { - newline_layout_consume_default(&newline_vars); - f32 advance = lr_tb_advance_byte(&pos_vars); - if (!first_of_the_line && lr_tb_crosses_width(&pos_vars, advance)){ - lr_tb_next_line(&pos_vars); - } - lr_tb_write_byte_with_advance(&pos_vars, face, advance, arena, &list, index, *ptr); - first_of_the_line = false; - }break; - } - ptr += consume.inc; - } - - if (newline_layout_consume_finish(&newline_vars)){ - i64 index = layout_index_from_ptr(ptr, text.str, range.first); - lr_tb_write_blank(&pos_vars, face, arena, &list, index); - } - } - - layout_item_list_finish(&list, -pos_vars.line_to_text_shift); - - return(list); +Scratch_Block scratch(app); + +Layout_Item_List list = get_empty_item_list(range); + +String_Const_u8 text = push_buffer_range(app, scratch, buffer, range); + +Face_Advance_Map advance_map = get_face_advance_map(app, face); +Face_Metrics metrics = get_face_metrics(app, face); +f32 tab_width = (f32)def_get_config_u64(app, vars_save_string_lit("default_tab_width")); +tab_width = clamp_bot(1, tab_width); +LefRig_TopBot_Layout_Vars pos_vars = get_lr_tb_layout_vars(&advance_map, &metrics, tab_width, width); + +if (text.size == 0){ +lr_tb_write_blank(&pos_vars, face, arena, &list, range.first); +} +else{ +b32 first_of_the_line = true; +Newline_Layout_Vars newline_vars = get_newline_layout_vars(); + +u8 *ptr = text.str; +u8 *end_ptr = ptr + text.size; +for (;ptr < end_ptr;){ +Character_Consume_Result consume = utf8_consume(ptr, (u64)(end_ptr - ptr)); +i64 index = layout_index_from_ptr(ptr, text.str, range.first); +switch (consume.codepoint){ +default: +{ +newline_layout_consume_default(&newline_vars); +f32 advance = lr_tb_advance(&pos_vars, face, consume.codepoint); +if (!first_of_the_line && lr_tb_crosses_width(&pos_vars, advance)){ +lr_tb_next_line(&pos_vars); +} +lr_tb_write_with_advance(&pos_vars, face, advance, arena, &list, index, consume.codepoint); +first_of_the_line = false; +}break; + +case '\r': +{ +newline_layout_consume_CR(&newline_vars, index); +}break; + +case '\n': +{ +i64 newline_index = newline_layout_consume_LF(&newline_vars, index); +lr_tb_write_blank(&pos_vars, face, arena, &list, newline_index); +lr_tb_next_line(&pos_vars); +first_of_the_line = true; +}break; + +case max_u32: +{ +newline_layout_consume_default(&newline_vars); +f32 advance = lr_tb_advance_byte(&pos_vars); +if (!first_of_the_line && lr_tb_crosses_width(&pos_vars, advance)){ +lr_tb_next_line(&pos_vars); +} +lr_tb_write_byte_with_advance(&pos_vars, face, advance, arena, &list, index, *ptr); +first_of_the_line = false; +}break; +} +ptr += consume.inc; +} + +if (newline_layout_consume_finish(&newline_vars)){ +i64 index = layout_index_from_ptr(ptr, text.str, range.first); +lr_tb_write_blank(&pos_vars, face, arena, &list, index); +} +} + +layout_item_list_finish(&list, -pos_vars.line_to_text_shift); + +return(list); } function Layout_Item_List layout_unwrapped__inner(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width, Layout_Virtual_Indent virt_indent){ - Layout_Item_List list = get_empty_item_list(range); - - Scratch_Block scratch(app); - String_Const_u8 text = push_buffer_range(app, scratch, buffer, range); - - Face_Advance_Map advance_map = get_face_advance_map(app, face); - Face_Metrics metrics = get_face_metrics(app, face); - LefRig_TopBot_Layout_Vars pos_vars = get_lr_tb_layout_vars(&advance_map, &metrics, width); - - if (text.size == 0){ - lr_tb_write_blank(&pos_vars, face, arena, &list, range.first); - } - else{ - b32 skipping_leading_whitespace = (virt_indent == LayoutVirtualIndent_On); - Newline_Layout_Vars newline_vars = get_newline_layout_vars(); - - u8 *ptr = text.str; - u8 *end_ptr = ptr + text.size; - for (;ptr < end_ptr;){ - Character_Consume_Result consume = utf8_consume(ptr, (u64)(end_ptr - ptr)); - - i64 index = layout_index_from_ptr(ptr, text.str, range.first); - switch (consume.codepoint){ - case '\t': - case ' ': - { - newline_layout_consume_default(&newline_vars); - f32 advance = lr_tb_advance(&pos_vars, face, consume.codepoint); - if (!skipping_leading_whitespace){ - lr_tb_write_with_advance(&pos_vars, face, advance, arena, &list, index, consume.codepoint); - } - else{ - lr_tb_advance_x_without_item(&pos_vars, advance); - } - }break; - - default: - { - newline_layout_consume_default(&newline_vars); - lr_tb_write(&pos_vars, face, arena, &list, index, consume.codepoint); - }break; - - case '\r': - { - newline_layout_consume_CR(&newline_vars, index); - }break; - - case '\n': - { - i64 newline_index = newline_layout_consume_LF(&newline_vars, index); - lr_tb_write_blank(&pos_vars, face, arena, &list, newline_index); - lr_tb_next_line(&pos_vars); - }break; - - case max_u32: - { - newline_layout_consume_default(&newline_vars); - lr_tb_write_byte(&pos_vars, face, arena, &list, index, *ptr); - }break; - } - - ptr += consume.inc; - } - - if (newline_layout_consume_finish(&newline_vars)){ - i64 index = layout_index_from_ptr(ptr, text.str, range.first); - lr_tb_write_blank(&pos_vars, face, arena, &list, index); - } - } - - layout_item_list_finish(&list, -pos_vars.line_to_text_shift); - - return(list); +Layout_Item_List list = get_empty_item_list(range); + +Scratch_Block scratch(app); +String_Const_u8 text = push_buffer_range(app, scratch, buffer, range); + +Face_Advance_Map advance_map = get_face_advance_map(app, face); +Face_Metrics metrics = get_face_metrics(app, face); +f32 tab_width = (f32)def_get_config_u64(app, vars_save_string_lit("default_tab_width")); +tab_width = clamp_bot(1, tab_width); +LefRig_TopBot_Layout_Vars pos_vars = get_lr_tb_layout_vars(&advance_map, &metrics, tab_width, width); + +if (text.size == 0){ +lr_tb_write_blank(&pos_vars, face, arena, &list, range.first); +} +else{ +b32 skipping_leading_whitespace = (virt_indent == LayoutVirtualIndent_On); +Newline_Layout_Vars newline_vars = get_newline_layout_vars(); + +u8 *ptr = text.str; +u8 *end_ptr = ptr + text.size; +for (;ptr < end_ptr;){ +Character_Consume_Result consume = utf8_consume(ptr, (u64)(end_ptr - ptr)); + +i64 index = layout_index_from_ptr(ptr, text.str, range.first); +switch (consume.codepoint){ +case '\t': +case ' ': +{ +newline_layout_consume_default(&newline_vars); +f32 advance = lr_tb_advance(&pos_vars, face, consume.codepoint); +if (!skipping_leading_whitespace){ +lr_tb_write_with_advance(&pos_vars, face, advance, arena, &list, index, consume.codepoint); +} +else{ +lr_tb_advance_x_without_item(&pos_vars, advance); +} +}break; + +default: +{ +newline_layout_consume_default(&newline_vars); +lr_tb_write(&pos_vars, face, arena, &list, index, consume.codepoint); +}break; + +case '\r': +{ +newline_layout_consume_CR(&newline_vars, index); +}break; + +case '\n': +{ +i64 newline_index = newline_layout_consume_LF(&newline_vars, index); +lr_tb_write_blank(&pos_vars, face, arena, &list, newline_index); +lr_tb_next_line(&pos_vars); +}break; + +case max_u32: +{ +newline_layout_consume_default(&newline_vars); +lr_tb_write_byte(&pos_vars, face, arena, &list, index, *ptr); +}break; +} + +ptr += consume.inc; +} + +if (newline_layout_consume_finish(&newline_vars)){ +i64 index = layout_index_from_ptr(ptr, text.str, range.first); +lr_tb_write_blank(&pos_vars, face, arena, &list, index); +} +} + +layout_item_list_finish(&list, -pos_vars.line_to_text_shift); + +return(list); } function Layout_Item_List layout_wrap_whitespace__inner(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width, Layout_Virtual_Indent virt_indent){ - Scratch_Block scratch(app); - - Layout_Item_List list = get_empty_item_list(range); - - String_Const_u8 text = push_buffer_range(app, scratch, buffer, range); - - Face_Advance_Map advance_map = get_face_advance_map(app, face); - Face_Metrics metrics = get_face_metrics(app, face); - LefRig_TopBot_Layout_Vars pos_vars = get_lr_tb_layout_vars(&advance_map, &metrics, width); - - if (text.size == 0){ - lr_tb_write_blank(&pos_vars, face, arena, &list, range.first); - } - else{ - b32 skipping_leading_whitespace = false; - b32 first_of_the_line = true; - Newline_Layout_Vars newline_vars = get_newline_layout_vars(); - - u8 *ptr = text.str; - u8 *end_ptr = ptr + text.size; - u8 *word_ptr = ptr; - - if (character_is_whitespace(*ptr)){ - skipping_leading_whitespace = (virt_indent == LayoutVirtualIndent_On); - goto consuming_whitespace; - } - - consuming_non_whitespace: - for (;ptr <= end_ptr; ptr += 1){ - if (ptr == end_ptr || character_is_whitespace(*ptr)){ - break; - } - } - - { - newline_layout_consume_default(&newline_vars); - - String_Const_u8 word = SCu8(word_ptr, ptr); - u8 *word_end = ptr; - - if (!first_of_the_line){ - f32 total_advance = 0.f; - ptr = word.str; - for (;ptr < word_end;){ - Character_Consume_Result consume = - utf8_consume(ptr, (u64)(word_end - ptr)); - if (consume.codepoint != max_u32){ - total_advance += lr_tb_advance(&pos_vars, face, consume.codepoint); - } - else{ - total_advance += lr_tb_advance_byte(&pos_vars); - } - ptr += consume.inc; - } - - if (lr_tb_crosses_width(&pos_vars, total_advance)){ - lr_tb_next_line(&pos_vars); - } - } - - ptr = word.str; - - for (;ptr < word_end;){ - Character_Consume_Result consume = - utf8_consume(ptr, (u64)(word_end - ptr)); - i64 index = layout_index_from_ptr(ptr, text.str, range.first); - - if (consume.codepoint != max_u32){ - lr_tb_write(&pos_vars, face, arena, &list, index, consume.codepoint); - } - else{ - lr_tb_write_byte(&pos_vars, face, arena, &list, index, *ptr); - } - - ptr += consume.inc; - } - - first_of_the_line = false; - } - - consuming_whitespace: - for (; ptr < end_ptr; ptr += 1){ - if (!character_is_whitespace(*ptr)){ - word_ptr = ptr; - goto consuming_non_whitespace; - } - - i64 index = layout_index_from_ptr(ptr, text.str, range.first); - switch (*ptr){ - case '\t': - case ' ': - { - newline_layout_consume_default(&newline_vars); - f32 advance = lr_tb_advance(&pos_vars, face, *ptr); - if (!skipping_leading_whitespace){ - if (!first_of_the_line && lr_tb_crosses_width(&pos_vars, advance)){ - lr_tb_next_line(&pos_vars); - } - lr_tb_write_with_advance(&pos_vars, face, advance, arena, &list, index, *ptr); - first_of_the_line = false; - } - else{ - lr_tb_advance_x_without_item(&pos_vars, advance); - } - }break; - - default: - { - newline_layout_consume_default(&newline_vars); - f32 advance = lr_tb_advance(&pos_vars, face, *ptr); - if (!first_of_the_line && lr_tb_crosses_width(&pos_vars, advance)){ - lr_tb_next_line(&pos_vars); - } - lr_tb_write_with_advance(&pos_vars, face, advance, arena, &list, index, *ptr); - first_of_the_line = false; - }break; - - case '\r': - { - newline_layout_consume_CR(&newline_vars, index); - }break; - - case '\n': - { - u64 newline_index = newline_layout_consume_LF(&newline_vars, index); - lr_tb_write_blank(&pos_vars, face, arena, &list, newline_index); - lr_tb_next_line(&pos_vars); - first_of_the_line = true; - }break; - } - } - - if (newline_layout_consume_finish(&newline_vars)){ - i64 index = layout_index_from_ptr(ptr, text.str, range.first); - lr_tb_write_blank(&pos_vars, face, arena, &list, index); - } - } - - layout_item_list_finish(&list, -pos_vars.line_to_text_shift); - - return(list); +Scratch_Block scratch(app); + +Layout_Item_List list = get_empty_item_list(range); + +String_Const_u8 text = push_buffer_range(app, scratch, buffer, range); + +Face_Advance_Map advance_map = get_face_advance_map(app, face); +Face_Metrics metrics = get_face_metrics(app, face); +f32 tab_width = (f32)def_get_config_u64(app, vars_save_string_lit("default_tab_width")); +tab_width = clamp_bot(1, tab_width); +LefRig_TopBot_Layout_Vars pos_vars = get_lr_tb_layout_vars(&advance_map, &metrics, tab_width, width); + +if (text.size == 0){ +lr_tb_write_blank(&pos_vars, face, arena, &list, range.first); +} +else{ +b32 skipping_leading_whitespace = false; +b32 first_of_the_line = true; +Newline_Layout_Vars newline_vars = get_newline_layout_vars(); + +u8 *ptr = text.str; +u8 *end_ptr = ptr + text.size; +u8 *word_ptr = ptr; + +if (character_is_whitespace(*ptr)){ +skipping_leading_whitespace = (virt_indent == LayoutVirtualIndent_On); +goto consuming_whitespace; +} + +consuming_non_whitespace: +for (;ptr <= end_ptr; ptr += 1){ +if (ptr == end_ptr || character_is_whitespace(*ptr)){ +break; +} +} + +{ +newline_layout_consume_default(&newline_vars); + +String_Const_u8 word = SCu8(word_ptr, ptr); +u8 *word_end = ptr; + +if (!first_of_the_line){ +f32 total_advance = 0.f; +ptr = word.str; +for (;ptr < word_end;){ +Character_Consume_Result consume = +utf8_consume(ptr, (u64)(word_end - ptr)); +if (consume.codepoint != max_u32){ +total_advance += lr_tb_advance(&pos_vars, face, consume.codepoint); +} +else{ +total_advance += lr_tb_advance_byte(&pos_vars); +} +ptr += consume.inc; +} + +if (lr_tb_crosses_width(&pos_vars, total_advance)){ +lr_tb_next_line(&pos_vars); +} +} + +ptr = word.str; + +for (;ptr < word_end;){ +Character_Consume_Result consume = +utf8_consume(ptr, (u64)(word_end - ptr)); +i64 index = layout_index_from_ptr(ptr, text.str, range.first); + +if (consume.codepoint != max_u32){ +lr_tb_write(&pos_vars, face, arena, &list, index, consume.codepoint); +} +else{ +lr_tb_write_byte(&pos_vars, face, arena, &list, index, *ptr); +} + +ptr += consume.inc; +} + +first_of_the_line = false; +} + +consuming_whitespace: +for (; ptr < end_ptr; ptr += 1){ +if (!character_is_whitespace(*ptr)){ +word_ptr = ptr; +goto consuming_non_whitespace; +} + +i64 index = layout_index_from_ptr(ptr, text.str, range.first); +switch (*ptr){ +case '\t': +case ' ': +{ +newline_layout_consume_default(&newline_vars); +f32 advance = lr_tb_advance(&pos_vars, face, *ptr); +if (!skipping_leading_whitespace){ +if (!first_of_the_line && lr_tb_crosses_width(&pos_vars, advance)){ +lr_tb_next_line(&pos_vars); +} +lr_tb_write_with_advance(&pos_vars, face, advance, arena, &list, index, *ptr); +first_of_the_line = false; +} +else{ +lr_tb_advance_x_without_item(&pos_vars, advance); +} +}break; + +default: +{ +newline_layout_consume_default(&newline_vars); +f32 advance = lr_tb_advance(&pos_vars, face, *ptr); +if (!first_of_the_line && lr_tb_crosses_width(&pos_vars, advance)){ +lr_tb_next_line(&pos_vars); +} +lr_tb_write_with_advance(&pos_vars, face, advance, arena, &list, index, *ptr); +first_of_the_line = false; +}break; + +case '\r': +{ +newline_layout_consume_CR(&newline_vars, index); +}break; + +case '\n': +{ +u64 newline_index = newline_layout_consume_LF(&newline_vars, index); +lr_tb_write_blank(&pos_vars, face, arena, &list, newline_index); +lr_tb_next_line(&pos_vars); +first_of_the_line = true; +}break; +} +} + +if (newline_layout_consume_finish(&newline_vars)){ +i64 index = layout_index_from_ptr(ptr, text.str, range.first); +lr_tb_write_blank(&pos_vars, face, arena, &list, index); +} +} + +layout_item_list_finish(&list, -pos_vars.line_to_text_shift); + +return(list); } function Layout_Item_List layout_unwrapped(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width){ - return(layout_unwrapped__inner(app, arena, buffer, range, face, width, LayoutVirtualIndent_Off)); +return(layout_unwrapped__inner(app, arena, buffer, range, face, width, LayoutVirtualIndent_Off)); } function Layout_Item_List layout_wrap_whitespace(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width){ - return(layout_wrap_whitespace__inner(app, arena, buffer, range, face, width, LayoutVirtualIndent_Off)); +return(layout_wrap_whitespace__inner(app, arena, buffer, range, face, width, LayoutVirtualIndent_Off)); } function Layout_Item_List layout_basic(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width, Layout_Wrap_Kind kind){ - Layout_Item_List result = {}; - switch (kind){ - case Layout_Unwrapped: - { - result = layout_unwrapped(app, arena, buffer, range, face, width); - }break; - case Layout_Wrapped: - { - result = layout_wrap_whitespace(app, arena, buffer, range, face, width); - }break; - } - return(result); +Layout_Item_List result = {}; +switch (kind){ +case Layout_Unwrapped: +{ +result = layout_unwrapped(app, arena, buffer, range, face, width); +}break; +case Layout_Wrapped: +{ +result = layout_wrap_whitespace(app, arena, buffer, range, face, width); +}break; +} +return(result); } function Layout_Item_List layout_generic(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width){ - Managed_Scope scope = buffer_get_managed_scope(app, buffer); - b32 *wrap_lines_ptr = scope_attachment(app, scope, buffer_wrap_lines, b32); - b32 wrap_lines = (wrap_lines_ptr != 0 && *wrap_lines_ptr); - return(layout_basic(app, arena, buffer, range, face, width, wrap_lines?Layout_Wrapped:Layout_Unwrapped)); +Managed_Scope scope = buffer_get_managed_scope(app, buffer); +b32 *wrap_lines_ptr = scope_attachment(app, scope, buffer_wrap_lines, b32); +b32 wrap_lines = (wrap_lines_ptr != 0 && *wrap_lines_ptr); +return(layout_basic(app, arena, buffer, range, face, width, wrap_lines?Layout_Wrapped:Layout_Unwrapped)); } function Layout_Item_List layout_virt_indent_literal_unwrapped(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width){ - return(layout_unwrapped__inner(app, arena, buffer, range, face, width, LayoutVirtualIndent_On)); +return(layout_unwrapped__inner(app, arena, buffer, range, face, width, LayoutVirtualIndent_On)); } function Layout_Item_List layout_virt_indent_literal_wrapped(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width){ - return(layout_wrap_whitespace__inner(app, arena, buffer, range, face, width, LayoutVirtualIndent_On)); +return(layout_wrap_whitespace__inner(app, arena, buffer, range, face, width, LayoutVirtualIndent_On)); } function Layout_Item_List layout_virt_indent_literal(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width, Layout_Wrap_Kind kind){ - Layout_Item_List result = {}; - switch (kind){ - case Layout_Unwrapped: - { - result = layout_virt_indent_literal_unwrapped(app, arena, buffer, range, face, width); - }break; - case Layout_Wrapped: - { - result = layout_virt_indent_literal_wrapped(app, arena, buffer, range, face, width); - }break; - } - return(result); +Layout_Item_List result = {}; +switch (kind){ +case Layout_Unwrapped: +{ +result = layout_virt_indent_literal_unwrapped(app, arena, buffer, range, face, width); +}break; +case Layout_Wrapped: +{ +result = layout_virt_indent_literal_wrapped(app, arena, buffer, range, face, width); +}break; +} +return(result); } function Layout_Item_List layout_virt_indent_literal_generic(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width){ - Managed_Scope scope = buffer_get_managed_scope(app, buffer); - b32 *wrap_lines_ptr = scope_attachment(app, scope, buffer_wrap_lines, b32); - b32 wrap_lines = (wrap_lines_ptr != 0 && *wrap_lines_ptr); - return(layout_virt_indent_literal(app, arena, buffer, range, face, width, wrap_lines?Layout_Wrapped:Layout_Unwrapped)); +Managed_Scope scope = buffer_get_managed_scope(app, buffer); +b32 *wrap_lines_ptr = scope_attachment(app, scope, buffer_wrap_lines, b32); +b32 wrap_lines = (wrap_lines_ptr != 0 && *wrap_lines_ptr); +return(layout_virt_indent_literal(app, arena, buffer, range, face, width, wrap_lines?Layout_Wrapped:Layout_Unwrapped)); } // BOTTOM diff --git a/custom/4coder_layout_rule.h b/custom/4coder_layout_rule.h index 702e1783..b0d771d1 100644 --- a/custom/4coder_layout_rule.h +++ b/custom/4coder_layout_rule.h @@ -16,6 +16,7 @@ struct Newline_Layout_Vars{ struct LefRig_TopBot_Layout_Vars{ Face_Advance_Map *advance_map; Face_Metrics *metrics; + f32 tab_width; f32 line_to_text_shift; Vec2_f32 blank_dim; diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index ff40adc7..aa7f7746 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -273,9 +273,9 @@ i32 line_number; }; static Command_Metadata fcoder_metacmd_table[250] = { { 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, 418 }, -{ 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, 428 }, -{ 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, 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, 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(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, 666 }, @@ -372,7 +372,7 @@ static Command_Metadata fcoder_metacmd_table[250] = { { PROC_LINKS(list_all_substring_locations, 0), false, "list_all_substring_locations", 28, "Queries the user for a string and lists all case-sensitive substring matches found in all open buffers.", 103, "W:\\4ed\\code\\custom\\4coder_search.cpp", 36, 174 }, { PROC_LINKS(list_all_substring_locations_case_insensitive, 0), false, "list_all_substring_locations_case_insensitive", 45, "Queries the user for a string and lists all case-insensitive substring matches found in all open buffers.", 105, "W:\\4ed\\code\\custom\\4coder_search.cpp", 36, 186 }, { PROC_LINKS(load_project, 0), false, "load_project", 12, "Looks for a project.4coder file in the current directory and tries to load it. Looks in parent directories until a project file is found or there are no more parents.", 167, "W:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 972 }, -{ PROC_LINKS(load_theme_current_buffer, 0), false, "load_theme_current_buffer", 25, "Parse the current buffer as a theme file and add the theme to the theme list. If the buffer has a .4coder postfix in it's name, it is removed when the name is saved.", 165, "W:\\4ed\\code\\custom\\4coder_config.cpp", 36, 1609 }, +{ PROC_LINKS(load_theme_current_buffer, 0), false, "load_theme_current_buffer", 25, "Parse the current buffer as a theme file and add the theme to the theme list. If the buffer has a .4coder postfix in it's name, it is removed when the name is saved.", 165, "W:\\4ed\\code\\custom\\4coder_config.cpp", 36, 1625 }, { PROC_LINKS(load_themes_default_folder, 0), false, "load_themes_default_folder", 26, "Loads all the theme files in the default theme folder.", 54, "W:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 535 }, { PROC_LINKS(load_themes_hot_directory, 0), false, "load_themes_hot_directory", 25, "Loads all the theme files in the current hot directory.", 55, "W:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 547 }, { PROC_LINKS(make_directory_query, 0), false, "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1495 }, @@ -503,7 +503,7 @@ static Command_Metadata fcoder_metacmd_table[250] = { { PROC_LINKS(toggle_mouse, 0), false, "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "W:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 487 }, { PROC_LINKS(toggle_paren_matching_helper, 0), false, "toggle_paren_matching_helper", 28, "In code files matching parentheses pairs are colored with distinguishing colors.", 80, "W:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 521 }, { PROC_LINKS(toggle_show_whitespace, 0), false, "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 816 }, -{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles virtual whitespace for all files.", 41, "W:\\4ed\\code\\custom\\4coder_code_index.cpp", 40, 1235 }, +{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles virtual whitespace for all files.", 41, "W:\\4ed\\code\\custom\\4coder_code_index.cpp", 40, 1238 }, { PROC_LINKS(tutorial_maximize, 0), false, "tutorial_maximize", 17, "Expand the tutorial window", 26, "W:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 20 }, { PROC_LINKS(tutorial_minimize, 0), false, "tutorial_minimize", 17, "Shrink the tutorial window", 26, "W:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 34 }, { PROC_LINKS(uncomment_line, 0), false, "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "W:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 137 }, @@ -517,7 +517,7 @@ static Command_Metadata fcoder_metacmd_table[250] = { { 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, 438 }, +{ 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_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 },