Rough version of virtual whitespace up and running

This commit is contained in:
Allen Webster 2019-10-31 20:46:53 -07:00
parent 46241c4450
commit 09acacd3cf
14 changed files with 570 additions and 178 deletions

View File

@ -264,9 +264,7 @@ models_init(void){
} }
internal void internal void
app_load_vtables(API_VTable_system *vtable_system, app_load_vtables(API_VTable_system *vtable_system, API_VTable_font *vtable_font, API_VTable_graphics *vtable_graphics){
API_VTable_font *vtable_font,
API_VTable_graphics *vtable_graphics){
system_api_read_vtable(vtable_system); system_api_read_vtable(vtable_system);
font_api_read_vtable(vtable_font); font_api_read_vtable(vtable_font);
graphics_api_read_vtable(vtable_graphics); graphics_api_read_vtable(vtable_graphics);

View File

@ -656,7 +656,7 @@ buffer_set_layout(Application_Links *app, Buffer_ID buffer_id, Layout_Function *
} }
api(custom) function b32 api(custom) function b32
file_clear_layout_cache(Application_Links *app, Buffer_ID buffer_id){ buffer_clear_layout_cache(Application_Links *app, Buffer_ID buffer_id){
Models *models = (Models*)app->cmd_context; Models *models = (Models*)app->cmd_context;
Editing_File *file = imp_get_file(models, buffer_id); Editing_File *file = imp_get_file(models, buffer_id);
b32 result = false; b32 result = false;
@ -2844,7 +2844,7 @@ text_layout_get_buffer(Application_Links *app, Text_Layout_ID text_layout_id){
return(result); return(result);
} }
api(custom) function Interval_i64 api(custom) function Range_i64
text_layout_get_visible_range(Application_Links *app, Text_Layout_ID text_layout_id){ text_layout_get_visible_range(Application_Links *app, Text_Layout_ID text_layout_id){
Models *models = (Models*)app->cmd_context; Models *models = (Models*)app->cmd_context;
Range_i64 result = {}; Range_i64 result = {};
@ -2943,8 +2943,10 @@ text_layout_character_on_screen(Application_Links *app, Text_Layout_ID layout_id
for (i32 i = 0; i < count; i += 1, item_ptr += 1){ for (i32 i = 0; i < count; i += 1, item_ptr += 1){
i64 index = item_ptr->index; i64 index = item_ptr->index;
if (index == pos){ if (index == pos){
if (!HasFlag(item_ptr->flags, LayoutItemFlag_Ghost_Character)){
result = rect_union(result, item_ptr->rect); result = rect_union(result, item_ptr->rect);
} }
}
else if (index > pos){ else if (index > pos){
break; break;
} }

View File

@ -875,6 +875,9 @@ buffer_layout_nearest_pos_to_xy(Layout_Item_List list, Vec2_f32 p){
i64 count = block->count; i64 count = block->count;
Layout_Item *item = block->items; Layout_Item *item = block->items;
for (i32 i = 0; i < count; i += 1, item += 1){ for (i32 i = 0; i < count; i += 1, item += 1){
if (HasFlag(item->flags, LayoutItemFlag_Ghost_Character)){
continue;
}
// NOTE(allen): This only works if we build layouts in y-sorted order. // NOTE(allen): This only works if we build layouts in y-sorted order.
if (p.y < item->rect.y0){ if (p.y < item->rect.y0){
goto double_break; goto double_break;
@ -901,6 +904,7 @@ buffer_layout_nearest_pos_to_xy(Layout_Item_List list, Vec2_f32 p){
double_break:; double_break:;
} }
else{ else{
if (p.x == max_f32){ if (p.x == max_f32){
Layout_Item *prev_item = 0; Layout_Item *prev_item = 0;
for (Layout_Item_Block *block = list.first; for (Layout_Item_Block *block = list.first;
@ -909,6 +913,9 @@ buffer_layout_nearest_pos_to_xy(Layout_Item_List list, Vec2_f32 p){
i64 count = block->count; i64 count = block->count;
Layout_Item *item = block->items; Layout_Item *item = block->items;
for (i32 i = 0; i < count; i += 1, item += 1){ for (i32 i = 0; i < count; i += 1, item += 1){
if (HasFlag(item->flags, LayoutItemFlag_Ghost_Character)){
continue;
}
if (p.y < item->rect.y0){ if (p.y < item->rect.y0){
goto double_break_2; goto double_break_2;
} }
@ -918,6 +925,7 @@ buffer_layout_nearest_pos_to_xy(Layout_Item_List list, Vec2_f32 p){
} }
} }
} }
double_break_2:; double_break_2:;
if (prev_item != 0){ if (prev_item != 0){
closest_match = prev_item->index; closest_match = prev_item->index;
@ -934,6 +942,9 @@ buffer_layout_nearest_pos_to_xy(Layout_Item_List list, Vec2_f32 p){
i64 count = block->count; i64 count = block->count;
Layout_Item *item = block->items; Layout_Item *item = block->items;
for (i32 i = 0; i < count; i += 1, item += 1){ for (i32 i = 0; i < count; i += 1, item += 1){
if (HasFlag(item->flags, LayoutItemFlag_Ghost_Character)){
continue;
}
// NOTE(allen): This only works if we build layouts in y-sorted order. // NOTE(allen): This only works if we build layouts in y-sorted order.
if (p.y < item->rect.y0){ if (p.y < item->rect.y0){
goto double_break_3; goto double_break_3;
@ -945,6 +956,7 @@ buffer_layout_nearest_pos_to_xy(Layout_Item_List list, Vec2_f32 p){
goto double_break_3; goto double_break_3;
} }
} }
double_break_3:; double_break_3:;
if (closest_item != 0){ if (closest_item != 0){
closest_match = closest_item->index; closest_match = closest_item->index;
@ -953,6 +965,7 @@ buffer_layout_nearest_pos_to_xy(Layout_Item_List list, Vec2_f32 p){
closest_match = list.manifested_index_range.min; closest_match = list.manifested_index_range.min;
} }
} }
} }
} }
return(closest_match); return(closest_match);
@ -980,6 +993,9 @@ buffer_layout_get_pos_at_character(Layout_Item_List list, i64 character){
i64 prev_index = -1; i64 prev_index = -1;
Layout_Item *item = node->items; Layout_Item *item = node->items;
for (i64 i = 0; i < count; i += 1, item += 1){ for (i64 i = 0; i < count; i += 1, item += 1){
if (HasFlag(item->flags, LayoutItemFlag_Ghost_Character)){
continue;
}
if (prev_index != item->index){ if (prev_index != item->index){
prev_index = item->index; prev_index = item->index;
if (relative_character_counter == relative_character){ if (relative_character_counter == relative_character){
@ -1007,6 +1023,9 @@ buffer_layout_get_first_with_index(Layout_Item_List list, i64 index){
i64 count = block->count; i64 count = block->count;
Layout_Item *item = block->items; Layout_Item *item = block->items;
for (i32 i = 0; i < count; i += 1, item += 1){ for (i32 i = 0; i < count; i += 1, item += 1){
if (HasFlag(item->flags, LayoutItemFlag_Ghost_Character)){
continue;
}
if (item->index > index){ if (item->index > index){
result = prev; result = prev;
goto done; goto done;

View File

@ -72,7 +72,6 @@ code_index_unlock(void){
function void function void
code_index_set_file(Buffer_ID buffer, Arena arena, Code_Index_File *index){ code_index_set_file(Buffer_ID buffer, Arena arena, Code_Index_File *index){
Code_Index_File_Storage *storage = 0; Code_Index_File_Storage *storage = 0;
Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file,
buffer); buffer);
if (lookup.found_match){ if (lookup.found_match){
@ -92,8 +91,7 @@ code_index_set_file(Buffer_ID buffer, Arena arena, Code_Index_File *index){
function void function void
code_index_erase_file(Buffer_ID buffer){ code_index_erase_file(Buffer_ID buffer){
Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer);
buffer);
if (lookup.found_match){ if (lookup.found_match){
u64 val = 0; u64 val = 0;
table_read(&global_code_index.buffer_to_index_file, lookup, &val); table_read(&global_code_index.buffer_to_index_file, lookup, &val);
@ -107,12 +105,12 @@ code_index_erase_file(Buffer_ID buffer){
function Code_Index_File* function Code_Index_File*
code_index_get_file(Buffer_ID buffer){ code_index_get_file(Buffer_ID buffer){
Code_Index_File *result = 0; Code_Index_File *result = 0;
Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer);
buffer);
if (lookup.found_match){ if (lookup.found_match){
u64 val = 0; u64 val = 0;
table_read(&global_code_index.buffer_to_index_file, lookup, &val); table_read(&global_code_index.buffer_to_index_file, lookup, &val);
result = (Code_Index_File*)IntAsPtr(val); Code_Index_File_Storage *storage = (Code_Index_File_Storage*)IntAsPtr(val);
result = storage->file;
} }
return(result); return(result);
} }
@ -124,7 +122,7 @@ code_index_get_nest(Code_Index_Nest_Ptr_Array *array, i64 pos){
Code_Index_Nest **nest_ptrs = array->ptrs; Code_Index_Nest **nest_ptrs = array->ptrs;
for (i32 i = 0; i < count; i += 1){ for (i32 i = 0; i < count; i += 1){
Code_Index_Nest *nest = nest_ptrs[i]; Code_Index_Nest *nest = nest_ptrs[i];
if (nest->open.max <= pos && pos < nest->close.min){ if (nest->open.max <= pos && pos <= nest->close.min){
Code_Index_Nest *sub_nest = Code_Index_Nest *sub_nest =
code_index_get_nest(&nest->nest_array, pos); code_index_get_nest(&nest->nest_array, pos);
if (sub_nest != 0){ if (sub_nest != 0){
@ -149,6 +147,39 @@ 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 void
index_shift(i64 *ptr, Range_i64 old_range, umem 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);
}
}
function void
code_index_shift(Code_Index_Nest_Ptr_Array *array,
Range_i64 old_range, umem 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, umem new_size){
code_index_shift(&file->nest_array, old_range, new_size);
}
//////////////////////////////// ////////////////////////////////
function void function void
@ -164,8 +195,6 @@ generic_parse_skip_soft_tokens(Code_Index_File *index, Generic_Parse_State *stat
for (;token != 0 && !state->finished;){ for (;token != 0 && !state->finished;){
if (token->kind == TokenBaseKind_Comment){ if (token->kind == TokenBaseKind_Comment){
state->handle_comment(state->app, state->arena, index, token, state->contents); state->handle_comment(state->app, state->arena, index, token, state->contents);
token_it_inc_non_whitespace(&state->it);
token = token_it_read(&state->it);
} }
else if (token->kind == TokenBaseKind_Whitespace){ else if (token->kind == TokenBaseKind_Whitespace){
Range_i64 range = Ii64(token); Range_i64 range = Ii64(token);
@ -188,7 +217,8 @@ generic_parse_skip_soft_tokens(Code_Index_File *index, Generic_Parse_State *stat
} }
function void function void
generic_parse_init(Application_Links *app, Arena *arena, String_Const_u8 contents, Token_Array *tokens, 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){ Generic_Parse_Comment_Function *handle_comment, Generic_Parse_State *state){
state->app = app; state->app = app;
state->arena = arena; state->arena = arena;
@ -199,7 +229,7 @@ generic_parse_init(Application_Links *app, Arena *arena, String_Const_u8 content
} }
function Code_Index_Nest* function Code_Index_Nest*
generic_parse_parenthical(Code_Index_File *index, Generic_Parse_State *state, generic_parse_paren(Code_Index_File *index, Generic_Parse_State *state,
i64 indentation); i64 indentation);
function Code_Index_Nest* function Code_Index_Nest*
@ -209,6 +239,7 @@ generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state,
Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1);
result->kind = CodeIndexNest_Scope; result->kind = CodeIndexNest_Scope;
result->open = Ii64(token); result->open = Ii64(token);
result->close = Ii64(max_i64);
result->file = index; result->file = index;
result->interior_indentation = indentation + 4; result->interior_indentation = indentation + 4;
@ -229,7 +260,7 @@ generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state,
code_index_push_nest(&result->nest_list, nest); code_index_push_nest(&result->nest_list, nest);
} }
else if (token->kind == TokenBaseKind_ParentheticalOpen){ else if (token->kind == TokenBaseKind_ParentheticalOpen){
Code_Index_Nest *nest = generic_parse_parenthical(index, state, Code_Index_Nest *nest = generic_parse_paren(index, state,
indentation); indentation);
nest->parent = result; nest->parent = result;
code_index_push_nest(&result->nest_list, nest); code_index_push_nest(&result->nest_list, nest);
@ -245,19 +276,19 @@ generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state,
} }
} }
result->nest_array = result->nest_array = code_index_nest_ptr_array_from_list(state->arena, &result->nest_list);
code_index_nest_ptr_array_from_list(state->arena, &result->nest_list);
return(result); return(result);
} }
function Code_Index_Nest* function Code_Index_Nest*
generic_parse_parenthical(Code_Index_File *index, Generic_Parse_State *state, generic_parse_paren(Code_Index_File *index, Generic_Parse_State *state,
i64 indentation){ i64 indentation){
Token *token = token_it_read(&state->it); Token *token = token_it_read(&state->it);
Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1);
result->kind = CodeIndexNest_Paren; result->kind = CodeIndexNest_Paren;
result->open = Ii64(token); result->open = Ii64(token);
result->close = Ii64(max_i64);
result->file = index; result->file = index;
i64 manifested_characters_on_line = 0; i64 manifested_characters_on_line = 0;
@ -292,8 +323,7 @@ generic_parse_parenthical(Code_Index_File *index, Generic_Parse_State *state,
code_index_push_nest(&result->nest_list, nest); code_index_push_nest(&result->nest_list, nest);
} }
else if (token->kind == TokenBaseKind_ParentheticalOpen){ else if (token->kind == TokenBaseKind_ParentheticalOpen){
Code_Index_Nest *nest = generic_parse_parenthical(index, state, Code_Index_Nest *nest = generic_parse_paren(index, state, indentation);
indentation);
nest->parent = result; nest->parent = result;
code_index_push_nest(&result->nest_list, nest); code_index_push_nest(&result->nest_list, nest);
} }
@ -303,13 +333,15 @@ generic_parse_parenthical(Code_Index_File *index, Generic_Parse_State *state,
generic_parse_inc(state); generic_parse_inc(state);
break; break;
} }
else if (token->kind == TokenBaseKind_ScopeClose){
break;
}
else{ else{
generic_parse_inc(state); generic_parse_inc(state);
} }
} }
result->nest_array = result->nest_array = code_index_nest_ptr_array_from_list(state->arena, &result->nest_list);
code_index_nest_ptr_array_from_list(state->arena, &result->nest_list);
return(result); return(result);
} }
@ -335,7 +367,7 @@ generic_parse_full_input_breaks(Code_Index_File *index, Generic_Parse_State *sta
code_index_push_nest(&index->nest_list, nest); code_index_push_nest(&index->nest_list, nest);
} }
else if (token->kind == TokenBaseKind_ParentheticalOpen){ else if (token->kind == TokenBaseKind_ParentheticalOpen){
Code_Index_Nest *nest = generic_parse_parenthical(index, state, indentation); Code_Index_Nest *nest = generic_parse_paren(index, state, indentation);
code_index_push_nest(&index->nest_list, nest); code_index_push_nest(&index->nest_list, nest);
} }
else{ else{
@ -353,8 +385,7 @@ generic_parse_full_input_breaks(Code_Index_File *index, Generic_Parse_State *sta
} }
if (result){ if (result){
index->nest_array = index->nest_array = code_index_nest_ptr_array_from_list(state->arena, &index->nest_list);
code_index_nest_ptr_array_from_list(state->arena, &index->nest_list);
} }
return(result); return(result);
@ -374,6 +405,210 @@ generic_parse_init(Application_Links *app, Arena *arena, String_Const_u8 content
generic_parse_init(app, arena, contents, tokens, default_comment_index, state); generic_parse_init(app, arena, contents, tokens, default_comment_index, state);
} }
////////////////////////////////
function i64
layout_index_indent(Code_Index_File *file, i64 pos){
i64 indent = 0;
Code_Index_Nest *nest = code_index_get_nest(file, pos);
if (nest != 0){
if (pos == nest->close.min){
indent = nest->close_indentation;
}
else{
indent = nest->interior_indentation;
}
}
return(indent);
}
function f32
layout_index_x_shift(Code_Index_File *file, i64 pos, f32 space_advance){
i64 indent = layout_index_indent(file, pos);
return(((f32)indent)*space_advance);
}
function Layout_Item_List
layout_index_unwrapped__inner(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width, Code_Index_File *file){
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);
f32 wrap_align_x = width - metrics.normal_advance;
if (text.size == 0){
lr_tb_write_blank(&pos_vars, 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;
if (!character_is_whitespace(*ptr)){
goto consuming_non_whitespace;
}
skipping_leading_whitespace:
for (;ptr < end_ptr; ptr += 1){
if (!character_is_whitespace(*ptr)){
word_ptr = ptr;
goto consuming_non_whitespace;
}
if (*ptr == '\n'){
goto consuming_normal_whitespace;
}
}
if (ptr == end_ptr){
goto finish;
}
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, (umem)(word_end - ptr));
if (consume.codepoint != max_u32){
total_advance += lr_tb_advance(&pos_vars, consume.codepoint);
}
else{
total_advance += lr_tb_advance_byte(&pos_vars);
}
ptr += consume.inc;
}
if (lr_tb_crosses_width(&pos_vars, total_advance)){
i64 index = layout_index_from_ptr(word.str, text.str, range.first);
lr_tb_align_rightward(&pos_vars, wrap_align_x);
lr_tb_write_ghost(&pos_vars, arena, &list, index, '\\');
lr_tb_next_line(&pos_vars);
f32 shift = layout_index_x_shift(file, index, metrics.space_advance);
lr_tb_advance_x_without_item(&pos_vars, shift);
}
}
else{
i64 index = layout_index_from_ptr(word.str, text.str, range.first);
f32 shift = layout_index_x_shift(file, index, metrics.space_advance);
lr_tb_advance_x_without_item(&pos_vars, shift);
}
ptr = word.str;
for (;ptr < word_end;){
Character_Consume_Result consume =
utf8_consume(ptr, (umem)(word_end - ptr));
i64 index = layout_index_from_ptr(ptr, text.str, range.first);
if (consume.codepoint != max_u32){
lr_tb_write(&pos_vars, arena, &list, index, consume.codepoint);
}
else{
lr_tb_write_byte(&pos_vars, arena, &list, index, *ptr);
}
ptr += consume.inc;
}
first_of_the_line = false;
}
consuming_normal_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){
default:
{
newline_layout_consume_default(&newline_vars);
lr_tb_write(&pos_vars, arena, &list, index, *ptr);
first_of_the_line = false;
}break;
case '\r':
{
newline_layout_consume_CR(&newline_vars, index);
}break;
case '\n':
{
if (first_of_the_line){
f32 shift = layout_index_x_shift(file, index,
metrics.space_advance);
lr_tb_advance_x_without_item(&pos_vars, shift);
}
u64 newline_index = newline_layout_consume_LF(&newline_vars, index);
lr_tb_write_blank(&pos_vars, arena, &list, newline_index);
lr_tb_next_line(&pos_vars);
first_of_the_line = true;
ptr += 1;
goto skipping_leading_whitespace;
}break;
}
}
finish:
if (newline_layout_consume_finish(&newline_vars)){
i64 index = layout_index_from_ptr(ptr, text.str, range.first);
if (first_of_the_line){
f32 shift = layout_index_x_shift(file, index,
metrics.space_advance);
lr_tb_advance_x_without_item(&pos_vars, shift);
}
lr_tb_write_blank(&pos_vars, arena, &list, index);
}
}
layout_item_list_finish(&list, -pos_vars.line_to_text_shift);
return(list);
}
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){
Layout_Item_List result = {};
code_index_lock();
Code_Index_File *file = code_index_get_file(buffer);
if (file != 0){
result = layout_index_unwrapped__inner(app, arena, buffer, range, face, width, file);
}
code_index_unlock();
if (file == 0){
result = layout_virt_indent_literal_unwrapped(app, arena, buffer, range, face, width);
}
return(result);
}
// BOTTOM // BOTTOM

View File

@ -460,6 +460,7 @@ default_4coder_initialize(Application_Links *app, String_Const_u8_Array file_nam
buffer_map_id = managed_id_declare(app, SCu8("DEFAULT.buffer_map_id" )); buffer_map_id = managed_id_declare(app, SCu8("DEFAULT.buffer_map_id" ));
buffer_eol_setting = managed_id_declare(app, SCu8("DEFAULT.buffer_eol_setting")); buffer_eol_setting = managed_id_declare(app, SCu8("DEFAULT.buffer_eol_setting"));
buffer_lex_task = managed_id_declare(app, SCu8("DEFAULT.buffer_lex_task")); buffer_lex_task = managed_id_declare(app, SCu8("DEFAULT.buffer_lex_task"));
buffer_parse_task = managed_id_declare(app, SCu8("DEFAULT.buffer_parse_task"));
sticky_jump_marker_handle = managed_id_declare(app, SCu8("DEFAULT.sticky_jump_marker_handle")); sticky_jump_marker_handle = managed_id_declare(app, SCu8("DEFAULT.sticky_jump_marker_handle"));
attachment_tokens = managed_id_declare(app, SCu8("DEFAULT.tokens")); attachment_tokens = managed_id_declare(app, SCu8("DEFAULT.tokens"));

View File

@ -46,6 +46,7 @@ global Managed_ID view_word_complete_menu = 0;
global Managed_ID buffer_map_id = 0; global Managed_ID buffer_map_id = 0;
global Managed_ID buffer_eol_setting = 0; global Managed_ID buffer_eol_setting = 0;
global Managed_ID buffer_lex_task = 0; global Managed_ID buffer_lex_task = 0;
global Managed_ID buffer_parse_task = 0;
global Managed_ID sticky_jump_marker_handle = 0; global Managed_ID sticky_jump_marker_handle = 0;

View File

@ -53,7 +53,6 @@ CUSTOM_DOC("Default command for responding to a try-exit event")
} }
} }
CUSTOM_COMMAND_SIG(default_view_input_handler) CUSTOM_COMMAND_SIG(default_view_input_handler)
CUSTOM_DOC("Input consumption loop for default view behavior") CUSTOM_DOC("Input consumption loop for default view behavior")
{ {
@ -281,6 +280,48 @@ default_buffer_region(Application_Links *app, View_ID view_id, Rect_f32 region){
return(region); return(region);
} }
function void
recursive_nest_highlight(Application_Links *app, Text_Layout_ID layout_id, Range_i64 range,
Code_Index_Nest_Ptr_Array *array, i32 counter){
Code_Index_Nest **ptr = array->ptrs;
Code_Index_Nest **ptr_end = ptr + array->count;
for (;ptr < ptr_end; ptr += 1){
Code_Index_Nest *nest = *ptr;
if (!nest->is_closed){
break;
}
if (range.first <= nest->close.max){
break;
}
}
FColor t_colors[] = {
fcolor_id(Stag_Text_Cycle_1), fcolor_id(Stag_Text_Cycle_2),
fcolor_id(Stag_Text_Cycle_3), fcolor_id(Stag_Text_Cycle_4),
};
FColor t_color = t_colors[counter%ArrayCount(t_colors)];
for (;ptr < ptr_end; ptr += 1){
Code_Index_Nest *nest = *ptr;
if (range.max <= nest->open.min){
break;
}
paint_text_color(app, layout_id, nest->open, t_color);
if (nest->is_closed){
paint_text_color(app, layout_id, nest->close, t_color);
}
recursive_nest_highlight(app, layout_id, range, &nest->nest_array, counter + 1);
}
}
function void
recursive_nest_highlight(Application_Links *app, Text_Layout_ID layout_id, Range_i64 range,
Code_Index_File *file){
recursive_nest_highlight(app, layout_id, range, &file->nest_array, 0);
}
function void function void
default_render_buffer(Application_Links *app, View_ID view_id, Face_ID face_id, default_render_buffer(Application_Links *app, View_ID view_id, Face_ID face_id,
Buffer_ID buffer, Text_Layout_ID text_layout_id, Buffer_ID buffer, Text_Layout_ID text_layout_id,
@ -581,6 +622,45 @@ BUFFER_NAME_RESOLVER_SIG(default_buffer_name_resolution){
} }
} }
function void
parse_async__inner(Async_Context *actx, Buffer_ID buffer_id,
String_Const_u8 contents, Token_Array *tokens, i32 limit_factor){
Application_Links *app = actx->app;
ProfileBlock(app, "async parse");
Arena arena = make_arena_system(KB(16));
Code_Index_File *index = push_array_zero(&arena, Code_Index_File, 1);
index->buffer = buffer_id;
Generic_Parse_State state = {};
generic_parse_init(app, &arena, contents, tokens, &state);
b32 canceled = false;
for (;;){
if (generic_parse_full_input_breaks(index, &state, limit_factor)){
break;
}
if (async_check_canceled(actx)){
canceled = true;
break;
}
}
if (!canceled){
Thread_Context *tctx = get_thread_context(app);
system_acquire_global_frame_mutex(tctx);
code_index_lock();
code_index_set_file(buffer_id, arena, index);
code_index_unlock();
buffer_clear_layout_cache(app, buffer_id);
system_release_global_frame_mutex(tctx);
}
else{
linalloc_clear(&arena);
}
}
function void function void
do_full_lex_and_parse_async__inner(Async_Context *actx, Buffer_ID buffer_id){ do_full_lex_and_parse_async__inner(Async_Context *actx, Buffer_ID buffer_id){
Application_Links *app = actx->app; Application_Links *app = actx->app;
@ -600,10 +680,8 @@ do_full_lex_and_parse_async__inner(Async_Context *actx, Buffer_ID buffer_id){
Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens, Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens,
Token_Array); Token_Array);
base_free(allocator, tokens_ptr->tokens); base_free(allocator, tokens_ptr->tokens);
block_zero_struct(tokens_ptr);
} }
code_index_lock();
code_index_erase_file(buffer_id);
code_index_unlock();
contents = push_whole_buffer(app, scratch, buffer_id); contents = push_whole_buffer(app, scratch, buffer_id);
system_release_global_frame_mutex(tctx); system_release_global_frame_mutex(tctx);
@ -650,32 +728,7 @@ do_full_lex_and_parse_async__inner(Async_Context *actx, Buffer_ID buffer_id){
} }
if (tokens.count > 0){ if (tokens.count > 0){
ProfileBlock(app, "async parse"); parse_async__inner(actx, buffer_id, contents, &tokens, limit_factor);
Arena arena = make_arena_system(KB(16));
Code_Index_File *index = push_array_zero(&arena, Code_Index_File, 1);
index->buffer = buffer_id;
Generic_Parse_State state = {};
generic_parse_init(app, &arena, contents, &tokens, &state);
for (;;){
if (generic_parse_full_input_breaks(index, &state, limit_factor)){
break;
}
if (async_check_canceled(actx)){
canceled = true;
break;
}
}
if (!canceled){
code_index_lock();
code_index_set_file(buffer_id, arena, index);
code_index_unlock();
}
else{
linalloc_clear(&arena);
}
} }
} }
@ -687,6 +740,49 @@ do_full_lex_and_parse_async(Async_Context *actx, Data data){
} }
} }
function void
do_parse_async__inner(Async_Context *actx, Buffer_ID buffer_id){
Application_Links *app = actx->app;
ProfileScope(app, "async lex");
Thread_Context *tctx = get_thread_context(app);
Scratch_Block scratch(tctx);
String_Const_u8 contents = {};
Token_Array tokens = {};
{
ProfileBlock(app, "async parse contents (before mutex)");
system_acquire_global_frame_mutex(tctx);
ProfileBlock(app, "async parse contents (after mutex)");
Managed_Scope scope = buffer_get_managed_scope(app, buffer_id);
if (scope != 0){
Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens,
Token_Array);
tokens.count = tokens_ptr->count;
tokens.tokens = push_array_write(scratch, Token, tokens.count, tokens_ptr->tokens);
if (tokens.count > 0){
contents = push_whole_buffer(app, scratch, buffer_id);
}
}
system_release_global_frame_mutex(tctx);
}
i32 limit_factor = 10000;
if (tokens.count > 0){
parse_async__inner(actx, buffer_id, contents, &tokens, limit_factor);
}
}
function void
do_parse_async(Async_Context *actx, Data data){
if (data.size == sizeof(Buffer_ID)){
Buffer_ID buffer = *(Buffer_ID*)data.data;
do_parse_async__inner(actx, buffer);
}
}
BUFFER_HOOK_SIG(default_begin_buffer){ BUFFER_HOOK_SIG(default_begin_buffer){
ProfileScope(app, "begin buffer"); ProfileScope(app, "begin buffer");
@ -774,6 +870,7 @@ BUFFER_HOOK_SIG(default_begin_buffer){
buffer_map_id = managed_id_declare(app, SCu8("DEFAULT.buffer_map_id")); buffer_map_id = managed_id_declare(app, SCu8("DEFAULT.buffer_map_id"));
buffer_eol_setting = managed_id_declare(app, SCu8("DEFAULT.buffer_eol_setting")); buffer_eol_setting = managed_id_declare(app, SCu8("DEFAULT.buffer_eol_setting"));
buffer_lex_task = managed_id_declare(app, SCu8("DEFAULT.buffer_lex_task")); buffer_lex_task = managed_id_declare(app, SCu8("DEFAULT.buffer_lex_task"));
buffer_parse_task = managed_id_declare(app, SCu8("DEFAULT.buffer_parse_task"));
} }
Command_Map_ID map_id = (treat_as_code)?(default_code_map):(mapid_file); Command_Map_ID map_id = (treat_as_code)?(default_code_map):(mapid_file);
@ -810,7 +907,13 @@ BUFFER_HOOK_SIG(default_begin_buffer){
if (wrap_lines){ if (wrap_lines){
if (use_virtual_whitespace){ if (use_virtual_whitespace){
buffer_set_layout(app, buffer_id, layout_virt_indent_unwrapped); if (use_lexer){
buffer_set_layout(app, buffer_id, layout_virt_indent_index_unwrapped);
//buffer_set_layout(app, buffer_id, layout_virt_indent_literal_unwrapped);
}
else{
buffer_set_layout(app, buffer_id, layout_virt_indent_literal_unwrapped);
}
} }
else{ else{
buffer_set_layout(app, buffer_id, layout_wrap_whitespace); buffer_set_layout(app, buffer_id, layout_wrap_whitespace);
@ -818,7 +921,13 @@ BUFFER_HOOK_SIG(default_begin_buffer){
} }
else{ else{
if (use_virtual_whitespace){ if (use_virtual_whitespace){
buffer_set_layout(app, buffer_id, layout_virt_indent_unwrapped); if (use_lexer){
buffer_set_layout(app, buffer_id, layout_virt_indent_index_unwrapped);
//buffer_set_layout(app, buffer_id, layout_virt_indent_literal_unwrapped);
}
else{
buffer_set_layout(app, buffer_id, layout_virt_indent_literal_unwrapped);
}
} }
else{ else{
buffer_set_layout(app, buffer_id, layout_unwrapped); buffer_set_layout(app, buffer_id, layout_unwrapped);
@ -865,7 +974,17 @@ BUFFER_EDIT_RANGE_SIG(default_buffer_edit_range){
// buffer_id, new_range, original_size // buffer_id, new_range, original_size
ProfileScope(app, "default edit range"); ProfileScope(app, "default edit range");
Interval_i64 old_range = Ii64(new_range.first, new_range.first + original_size); Range_i64 old_range = Ii64(new_range.first, new_range.first + original_size);
{
code_index_lock();
Code_Index_File *file = code_index_get_file(buffer_id);
if (file != 0){
code_index_shift(file, old_range, range_size(new_range));
}
code_index_unlock();
}
i64 insert_size = range_size(new_range); i64 insert_size = range_size(new_range);
i64 text_shift = replace_range_shift(old_range, insert_size); i64 text_shift = replace_range_shift(old_range, insert_size);
@ -873,20 +992,25 @@ BUFFER_EDIT_RANGE_SIG(default_buffer_edit_range){
Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); Managed_Scope scope = buffer_get_managed_scope(app, buffer_id);
Async_Task *lex_task_ptr = scope_attachment(app, scope, buffer_lex_task, Async_Task); Async_Task *lex_task_ptr = scope_attachment(app, scope, buffer_lex_task, Async_Task);
Async_Task *parse_task_ptr = scope_attachment(app, scope, buffer_parse_task, Async_Task);
Base_Allocator *allocator = managed_scope_allocator(app, scope);
b32 do_full_relex = false;
if (async_task_is_running_or_pending(&global_async_system, *lex_task_ptr)){ if (async_task_is_running_or_pending(&global_async_system, *lex_task_ptr)){
async_task_cancel(&global_async_system, *lex_task_ptr); async_task_cancel(&global_async_system, *lex_task_ptr);
*lex_task_ptr = async_task_no_dep(&global_async_system, do_full_relex = true;
do_full_lex_and_parse_async, *lex_task_ptr = 0;
make_data_struct(&buffer_id));
} }
else{ if (async_task_is_running_or_pending(&global_async_system, *parse_task_ptr)){
async_task_cancel(&global_async_system, *parse_task_ptr);
*parse_task_ptr = 0;
}
Token_Array *ptr = scope_attachment(app, scope, attachment_tokens, Token_Array); Token_Array *ptr = scope_attachment(app, scope, attachment_tokens, Token_Array);
if (ptr != 0 && ptr->tokens != 0){ if (ptr != 0 && ptr->tokens != 0){
ProfileBlockNamed(app, "attempt resync", profile_attempt_resync); ProfileBlockNamed(app, "attempt resync", profile_attempt_resync);
Base_Allocator *allocator = managed_scope_allocator(app, scope);
b32 do_full_relex = false;
i64 token_index_first = token_relex_first(ptr, old_range.first, 1); i64 token_index_first = token_relex_first(ptr, old_range.first, 1);
i64 token_index_resync_guess = i64 token_index_resync_guess =
token_relex_resync(ptr, old_range.one_past_last, 16); token_relex_resync(ptr, old_range.one_past_last, 16);
@ -915,7 +1039,10 @@ BUFFER_EDIT_RANGE_SIG(default_buffer_edit_range){
ProfileCloseNow(profile_attempt_resync); ProfileCloseNow(profile_attempt_resync);
if (relex.successful_resync){ if (!relex.successful_resync){
do_full_relex = true;
}
else{
ProfileBlock(app, "apply resync"); ProfileBlock(app, "apply resync");
i64 token_index_resync = relex.first_resync_index; i64 token_index_resync = relex.first_resync_index;
@ -946,19 +1073,17 @@ BUFFER_EDIT_RANGE_SIG(default_buffer_edit_range){
ptr->tokens = new_tokens; ptr->tokens = new_tokens;
ptr->count = new_tokens_count; ptr->count = new_tokens_count;
ptr->max = new_tokens_count; ptr->max = new_tokens_count;
*parse_task_ptr = async_task_no_dep(&global_async_system, do_parse_async,
make_data_struct(&buffer_id));
} }
else{
do_full_relex = true;
} }
} }
if (do_full_relex){ if (do_full_relex){
*lex_task_ptr = async_task_no_dep(&global_async_system, *lex_task_ptr = async_task_no_dep(&global_async_system, do_full_lex_and_parse_async,
do_full_lex_and_parse_async,
make_data_struct(&buffer_id)); make_data_struct(&buffer_id));
} }
}
}
// no meaning for return // no meaning for return
return(0); return(0);
@ -970,6 +1095,10 @@ BUFFER_HOOK_SIG(default_end_buffer){
if (lex_task_ptr != 0){ if (lex_task_ptr != 0){
async_task_cancel(&global_async_system, *lex_task_ptr); async_task_cancel(&global_async_system, *lex_task_ptr);
} }
Async_Task *lex_parse_ptr = scope_attachment(app, scope, buffer_parse_task, Async_Task);
if (lex_parse_ptr != 0){
async_task_cancel(&global_async_system, *lex_parse_ptr);
}
code_index_lock(); code_index_lock();
code_index_erase_file(buffer_id); code_index_erase_file(buffer_id);
code_index_unlock(); code_index_unlock();

View File

@ -28,12 +28,12 @@
#include "4coder_profile.h" #include "4coder_profile.h"
#include "4coder_async_tasks.h" #include "4coder_async_tasks.h"
#include "4coder_token.h" #include "4coder_token.h"
#include "4coder_code_index.h"
#include "generated/lexer_cpp.h" #include "generated/lexer_cpp.h"
#include "4coder_string_match.h" #include "4coder_string_match.h"
#include "4coder_helper.h" #include "4coder_helper.h"
#include "4coder_delta_rule.h" #include "4coder_delta_rule.h"
#include "4coder_layout_rule.h" #include "4coder_layout_rule.h"
#include "4coder_code_index.h"
#include "4coder_draw.h" #include "4coder_draw.h"
#include "4coder_insertion.h" #include "4coder_insertion.h"
#include "4coder_lister_base.h" #include "4coder_lister_base.h"
@ -72,13 +72,13 @@
#include "4coder_buffer_seek_constructors.cpp" #include "4coder_buffer_seek_constructors.cpp"
#include "4coder_token.cpp" #include "4coder_token.cpp"
#include "4coder_code_index.cpp"
#include "generated/lexer_cpp.cpp" #include "generated/lexer_cpp.cpp"
#include "4coder_command_map.cpp" #include "4coder_command_map.cpp"
#include "4coder_default_framework_variables.cpp" #include "4coder_default_framework_variables.cpp"
#include "4coder_helper.cpp" #include "4coder_helper.cpp"
#include "4coder_delta_rule.cpp" #include "4coder_delta_rule.cpp"
#include "4coder_layout_rule.cpp" #include "4coder_layout_rule.cpp"
#include "4coder_code_index.cpp"
#include "4coder_fancy.cpp" #include "4coder_fancy.cpp"
#include "4coder_draw.cpp" #include "4coder_draw.cpp"
#include "4coder_font_helper.cpp" #include "4coder_font_helper.cpp"

View File

@ -24,8 +24,7 @@ layout_item_list_finish(Layout_Item_List *list, f32 bottom_padding){
} }
function void function void
layout_write(Arena *arena, Layout_Item_List *list, layout_write(Arena *arena, Layout_Item_List *list, i64 index, u32 codepoint, Layout_Item_Flag flags, Rect_f32 rect){
i64 index, u32 codepoint, Layout_Item_Flag flags, Rect_f32 rect){
Temp_Memory restore_point = begin_temp(arena); Temp_Memory restore_point = begin_temp(arena);
Layout_Item *item = push_array(arena, Layout_Item, 1); Layout_Item *item = push_array(arena, Layout_Item, 1);
@ -140,37 +139,45 @@ lr_tb_advance(LefRig_TopBot_Layout_Vars *vars, u32 codepoint){
} }
function void function void
lr_tb_write_with_advance(LefRig_TopBot_Layout_Vars *vars, f32 advance, lr_tb_write_with_advance_with_flags(LefRig_TopBot_Layout_Vars *vars, f32 advance, Arena *arena, Layout_Item_List *list, i64 index, u32 codepoint, Layout_Item_Flag flags){
Arena *arena, Layout_Item_List *list, i64 index, u32 codepoint){
if (codepoint == '\t'){ if (codepoint == '\t'){
codepoint = ' '; codepoint = ' ';
} }
vars->p.x = f32_ceil32(vars->p.x); vars->p.x = f32_ceil32(vars->p.x);
f32 next_x = vars->p.x + advance; f32 next_x = vars->p.x + advance;
layout_write(arena, list, index, codepoint, 0, layout_write(arena, list, index, codepoint, flags,
Rf32(vars->p, V2f32(next_x, vars->text_y))); Rf32(vars->p, V2f32(next_x, vars->text_y)));
vars->p.x = next_x; vars->p.x = next_x;
} }
function void function void
lr_tb_write(LefRig_TopBot_Layout_Vars *vars, lr_tb_write_with_advance(LefRig_TopBot_Layout_Vars *vars, f32 advance, Arena *arena, Layout_Item_List *list, i64 index, u32 codepoint){
Arena *arena, Layout_Item_List *list, i64 index, u32 codepoint){ lr_tb_write_with_advance_with_flags(vars, advance, arena, list, index, codepoint, 0);
}
function void
lr_tb_write(LefRig_TopBot_Layout_Vars *vars, Arena *arena, Layout_Item_List *list, i64 index, u32 codepoint){
f32 advance = lr_tb_advance(vars, codepoint); f32 advance = lr_tb_advance(vars, codepoint);
lr_tb_write_with_advance(vars, advance, arena, list, index, codepoint); lr_tb_write_with_advance(vars, advance, arena, list, index, codepoint);
} }
function void
lr_tb_write_ghost(LefRig_TopBot_Layout_Vars *vars, Arena *arena, Layout_Item_List *list, i64 index, u32 codepoint){
f32 advance = lr_tb_advance(vars, codepoint);
lr_tb_write_with_advance_with_flags(vars, advance, arena, list, index, codepoint, LayoutItemFlag_Ghost_Character);
}
function f32 function f32
lr_tb_advance_byte(LefRig_TopBot_Layout_Vars *vars){ lr_tb_advance_byte(LefRig_TopBot_Layout_Vars *vars){
return(vars->metrics->byte_advance); return(vars->metrics->byte_advance);
} }
function void function void
lr_tb_write_byte_with_advance(LefRig_TopBot_Layout_Vars *vars, f32 advance, lr_tb_write_byte_with_advance(LefRig_TopBot_Layout_Vars *vars, f32 advance, Arena *arena, Layout_Item_List *list, i64 index, u8 byte){
Arena *arena, Layout_Item_List *list, i64 index, u8 byte){
Face_Metrics *metrics = vars->metrics; Face_Metrics *metrics = vars->metrics;
f32 final_next_x = vars->p.x + advance; f32 final_next_x = vars->p.x + advance;
u32 lo = ((u32)byte)&0xF; u32 lo = ((u32)byte )&0xF;
u32 hi = ((u32)byte >> 4)&0xF; u32 hi = ((u32)byte >> 4)&0xF;
Vec2_f32 p = vars->p; Vec2_f32 p = vars->p;
@ -178,15 +185,17 @@ lr_tb_write_byte_with_advance(LefRig_TopBot_Layout_Vars *vars, f32 advance,
f32 next_x = p.x + metrics->byte_sub_advances[0]; f32 next_x = p.x + metrics->byte_sub_advances[0];
f32 text_y = vars->text_y; f32 text_y = vars->text_y;
layout_write(arena, list, index, '\\', 0, Layout_Item_Flag flags = LayoutItemFlag_Special_Character;
layout_write(arena, list, index, '\\', flags,
Rf32(p, V2f32(next_x, text_y))); Rf32(p, V2f32(next_x, text_y)));
p.x = next_x; p.x = next_x;
next_x += metrics->byte_sub_advances[1]; next_x += metrics->byte_sub_advances[1];
layout_write(arena, list, index, integer_symbols[hi], 0, layout_write(arena, list, index, integer_symbols[hi], flags,
Rf32(p, V2f32(next_x, text_y))); Rf32(p, V2f32(next_x, text_y)));
p.x = next_x; p.x = next_x;
next_x += metrics->byte_sub_advances[2]; next_x += metrics->byte_sub_advances[2];
layout_write(arena, list, index, integer_symbols[lo], 0, layout_write(arena, list, index, integer_symbols[lo], flags,
Rf32(p, V2f32(next_x, text_y))); Rf32(p, V2f32(next_x, text_y)));
vars->p.x = final_next_x; vars->p.x = final_next_x;
@ -234,6 +243,11 @@ 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);
}
//////////////////////////////// ////////////////////////////////
function Layout_Item_List function Layout_Item_List
@ -517,7 +531,7 @@ layout_wrap_whitespace(Application_Links *app, Arena *arena, Buffer_ID buffer,
if (!first_of_the_line){ if (!first_of_the_line){
f32 total_advance = 0.f; f32 total_advance = 0.f;
ptr = word.str; ptr = word.str;
for (; ptr < word_end;){ for (;ptr < word_end;){
Character_Consume_Result consume = Character_Consume_Result consume =
utf8_consume(ptr, (umem)(word_end - ptr)); utf8_consume(ptr, (umem)(word_end - ptr));
if (consume.codepoint != max_u32){ if (consume.codepoint != max_u32){
@ -536,7 +550,7 @@ layout_wrap_whitespace(Application_Links *app, Arena *arena, Buffer_ID buffer,
ptr = word.str; ptr = word.str;
for (; ptr < word_end;){ for (;ptr < word_end;){
Character_Consume_Result consume = Character_Consume_Result consume =
utf8_consume(ptr, (umem)(word_end - ptr)); utf8_consume(ptr, (umem)(word_end - ptr));
i64 index = layout_index_from_ptr(ptr, text.str, range.first); i64 index = layout_index_from_ptr(ptr, text.str, range.first);
@ -602,7 +616,7 @@ layout_wrap_whitespace(Application_Links *app, Arena *arena, Buffer_ID buffer,
} }
function Layout_Item_List function Layout_Item_List
layout_virt_indent_unwrapped(Application_Links *app, Arena *arena, layout_virt_indent_literal_unwrapped(Application_Links *app, Arena *arena,
Buffer_ID buffer, Range_i64 range, Face_ID face, Buffer_ID buffer, Range_i64 range, Face_ID face,
f32 width){ f32 width){
Scratch_Block scratch(app); Scratch_Block scratch(app);

View File

@ -582,32 +582,25 @@ struct Buffer_Name_Conflict_Entry{
}; };
typedef void Buffer_Name_Resolver_Function(Application_Links *app, Buffer_Name_Conflict_Entry *conflicts, i32 conflict_count); typedef void Buffer_Name_Resolver_Function(Application_Links *app, Buffer_Name_Conflict_Entry *conflicts, i32 conflict_count);
#define BUFFER_NAME_RESOLVER_SIG(n) \ #define BUFFER_NAME_RESOLVER_SIG(n) void n(Application_Links *app, Buffer_Name_Conflict_Entry *conflicts, i32 conflict_count)
void n(Application_Links *app, Buffer_Name_Conflict_Entry *conflicts, \
i32 conflict_count)
typedef i32 Buffer_Hook_Function(Application_Links *app, Buffer_ID buffer_id); typedef i32 Buffer_Hook_Function(Application_Links *app, Buffer_ID buffer_id);
#define BUFFER_HOOK_SIG(name) i32 name(Application_Links *app, Buffer_ID buffer_id) #define BUFFER_HOOK_SIG(name) i32 name(Application_Links *app, Buffer_ID buffer_id)
typedef i32 Buffer_Edit_Range_Function(Application_Links *app, Buffer_ID buffer_id, typedef i32 Buffer_Edit_Range_Function(Application_Links *app, Buffer_ID buffer_id,
Range_i64 new_range, umem original_size); Range_i64 new_range, umem original_size);
#define BUFFER_EDIT_RANGE_SIG(name) \ #define BUFFER_EDIT_RANGE_SIG(name) i32 name(Application_Links *app, Buffer_ID buffer_id, Interval_i64 new_range, umem original_size)
i32 name(Application_Links *app, Buffer_ID buffer_id, \
Interval_i64 new_range, umem original_size)
typedef Vec2_f32 Delta_Rule_Function(Vec2_f32 pending, b32 is_new_target, f32 dt, void *data); typedef Vec2_f32 Delta_Rule_Function(Vec2_f32 pending, b32 is_new_target, f32 dt, void *data);
#define DELTA_RULE_SIG(name) \ #define DELTA_RULE_SIG(name) Vec2_f32 name(Vec2_f32 pending, b32 is_new_target, f32 dt, void *data)
Vec2_f32 name(Vec2_f32 pending, b32 is_new_target, f32 dt, void *data)
typedef Rect_f32 Buffer_Region_Function(Application_Links *app, View_ID view_id, Rect_f32 region); typedef Rect_f32 Buffer_Region_Function(Application_Links *app, View_ID view_id, Rect_f32 region);
typedef void New_Clipboard_Contents_Function(Application_Links *app, String_Const_u8 contents); typedef void New_Clipboard_Contents_Function(Application_Links *app, String_Const_u8 contents);
#define NEW_CLIPBOARD_CONTENTS_SIG(name) \ #define NEW_CLIPBOARD_CONTENTS_SIG(name) void name(Application_Links *app, String_Const_u8 contents)
void name(Application_Links *app, String_Const_u8 contents)
typedef void Render_Caller_Function(Application_Links *app, Frame_Info frame_info, View_ID view); typedef void Render_Caller_Function(Application_Links *app, Frame_Info frame_info, View_ID view);
#define RENDER_CALLER_SIG(name) \ #define RENDER_CALLER_SIG(name) void name(Application_Links *app, Frame_Info frame_info, View_ID view)
void name(Application_Links *app, Frame_Info frame_info, View_ID view)
typedef u32 Layout_Item_Flag; typedef u32 Layout_Item_Flag;
enum{ enum{

View File

@ -236,7 +236,7 @@ i32 source_name_len;
i32 line_number; i32 line_number;
}; };
static Command_Metadata fcoder_metacmd_table[214] = { static Command_Metadata fcoder_metacmd_table[214] = {
{ PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 57 }, { PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 56 },
{ PROC_LINKS(profile_enable, 0), false, "profile_enable", 14, "Allow 4coder's self profiler to gather new profiling information.", 65, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 207 }, { PROC_LINKS(profile_enable, 0), false, "profile_enable", 14, "Allow 4coder's self profiler to gather new profiling information.", 65, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 207 },
{ PROC_LINKS(profile_disable, 0), false, "profile_disable", 15, "Prevent 4coder's self profiler from gathering new profiling information.", 72, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 214 }, { PROC_LINKS(profile_disable, 0), false, "profile_disable", 15, "Prevent 4coder's self profiler from gathering new profiling information.", 72, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 214 },
{ PROC_LINKS(profile_clear, 0), false, "profile_clear", 13, "Clear all profiling information from 4coder's self profiler.", 60, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 221 }, { PROC_LINKS(profile_clear, 0), false, "profile_clear", 13, "Clear all profiling information from 4coder's self profiler.", 60, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 221 },

View File

@ -43,7 +43,7 @@ vtable->push_buffer_file_name = push_buffer_file_name;
vtable->buffer_get_dirty_state = buffer_get_dirty_state; vtable->buffer_get_dirty_state = buffer_get_dirty_state;
vtable->buffer_set_dirty_state = buffer_set_dirty_state; vtable->buffer_set_dirty_state = buffer_set_dirty_state;
vtable->buffer_set_layout = buffer_set_layout; vtable->buffer_set_layout = buffer_set_layout;
vtable->file_clear_layout_cache = file_clear_layout_cache; vtable->buffer_clear_layout_cache = buffer_clear_layout_cache;
vtable->buffer_get_layout = buffer_get_layout; vtable->buffer_get_layout = buffer_get_layout;
vtable->buffer_get_setting = buffer_get_setting; vtable->buffer_get_setting = buffer_get_setting;
vtable->buffer_set_setting = buffer_set_setting; vtable->buffer_set_setting = buffer_set_setting;
@ -223,7 +223,7 @@ push_buffer_file_name = vtable->push_buffer_file_name;
buffer_get_dirty_state = vtable->buffer_get_dirty_state; buffer_get_dirty_state = vtable->buffer_get_dirty_state;
buffer_set_dirty_state = vtable->buffer_set_dirty_state; buffer_set_dirty_state = vtable->buffer_set_dirty_state;
buffer_set_layout = vtable->buffer_set_layout; buffer_set_layout = vtable->buffer_set_layout;
file_clear_layout_cache = vtable->file_clear_layout_cache; buffer_clear_layout_cache = vtable->buffer_clear_layout_cache;
buffer_get_layout = vtable->buffer_get_layout; buffer_get_layout = vtable->buffer_get_layout;
buffer_get_setting = vtable->buffer_get_setting; buffer_get_setting = vtable->buffer_get_setting;
buffer_set_setting = vtable->buffer_set_setting; buffer_set_setting = vtable->buffer_set_setting;

View File

@ -41,7 +41,7 @@
#define custom_buffer_get_dirty_state_sig() Dirty_State custom_buffer_get_dirty_state(Application_Links* app, Buffer_ID buffer_id) #define custom_buffer_get_dirty_state_sig() Dirty_State custom_buffer_get_dirty_state(Application_Links* app, Buffer_ID buffer_id)
#define custom_buffer_set_dirty_state_sig() b32 custom_buffer_set_dirty_state(Application_Links* app, Buffer_ID buffer_id, Dirty_State dirty_state) #define custom_buffer_set_dirty_state_sig() b32 custom_buffer_set_dirty_state(Application_Links* app, Buffer_ID buffer_id, Dirty_State dirty_state)
#define custom_buffer_set_layout_sig() b32 custom_buffer_set_layout(Application_Links* app, Buffer_ID buffer_id, Layout_Function* layout_func) #define custom_buffer_set_layout_sig() b32 custom_buffer_set_layout(Application_Links* app, Buffer_ID buffer_id, Layout_Function* layout_func)
#define custom_file_clear_layout_cache_sig() b32 custom_file_clear_layout_cache(Application_Links* app, Buffer_ID buffer) #define custom_buffer_clear_layout_cache_sig() b32 custom_buffer_clear_layout_cache(Application_Links* app, Buffer_ID buffer_id)
#define custom_buffer_get_layout_sig() Layout_Function* custom_buffer_get_layout(Application_Links* app, Buffer_ID buffer_id) #define custom_buffer_get_layout_sig() Layout_Function* custom_buffer_get_layout(Application_Links* app, Buffer_ID buffer_id)
#define custom_buffer_get_setting_sig() b32 custom_buffer_get_setting(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64* value_out) #define custom_buffer_get_setting_sig() b32 custom_buffer_get_setting(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64* value_out)
#define custom_buffer_set_setting_sig() b32 custom_buffer_set_setting(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64 value) #define custom_buffer_set_setting_sig() b32 custom_buffer_set_setting(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64 value)
@ -164,7 +164,7 @@
#define custom_text_layout_create_sig() Text_Layout_ID custom_text_layout_create(Application_Links* app, Buffer_ID buffer_id, Rect_f32 rect, Buffer_Point buffer_point) #define custom_text_layout_create_sig() Text_Layout_ID custom_text_layout_create(Application_Links* app, Buffer_ID buffer_id, Rect_f32 rect, Buffer_Point buffer_point)
#define custom_text_layout_region_sig() Rect_f32 custom_text_layout_region(Application_Links* app, Text_Layout_ID text_layout_id) #define custom_text_layout_region_sig() Rect_f32 custom_text_layout_region(Application_Links* app, Text_Layout_ID text_layout_id)
#define custom_text_layout_get_buffer_sig() Buffer_ID custom_text_layout_get_buffer(Application_Links* app, Text_Layout_ID text_layout_id) #define custom_text_layout_get_buffer_sig() Buffer_ID custom_text_layout_get_buffer(Application_Links* app, Text_Layout_ID text_layout_id)
#define custom_text_layout_get_visible_range_sig() Interval_i64 custom_text_layout_get_visible_range(Application_Links* app, Text_Layout_ID text_layout_id) #define custom_text_layout_get_visible_range_sig() Range_i64 custom_text_layout_get_visible_range(Application_Links* app, Text_Layout_ID text_layout_id)
#define custom_text_layout_line_on_screen_sig() Range_f32 custom_text_layout_line_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 line_number) #define custom_text_layout_line_on_screen_sig() Range_f32 custom_text_layout_line_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 line_number)
#define custom_text_layout_character_on_screen_sig() Rect_f32 custom_text_layout_character_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 pos) #define custom_text_layout_character_on_screen_sig() Rect_f32 custom_text_layout_character_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 pos)
#define custom_paint_text_color_sig() void custom_paint_text_color(Application_Links* app, Text_Layout_ID layout_id, Interval_i64 range, FColor color) #define custom_paint_text_color_sig() void custom_paint_text_color(Application_Links* app, Text_Layout_ID layout_id, Interval_i64 range, FColor color)
@ -217,7 +217,7 @@ typedef String_Const_u8 custom_push_buffer_file_name_type(Application_Links* app
typedef Dirty_State custom_buffer_get_dirty_state_type(Application_Links* app, Buffer_ID buffer_id); typedef Dirty_State custom_buffer_get_dirty_state_type(Application_Links* app, Buffer_ID buffer_id);
typedef b32 custom_buffer_set_dirty_state_type(Application_Links* app, Buffer_ID buffer_id, Dirty_State dirty_state); typedef b32 custom_buffer_set_dirty_state_type(Application_Links* app, Buffer_ID buffer_id, Dirty_State dirty_state);
typedef b32 custom_buffer_set_layout_type(Application_Links* app, Buffer_ID buffer_id, Layout_Function* layout_func); typedef b32 custom_buffer_set_layout_type(Application_Links* app, Buffer_ID buffer_id, Layout_Function* layout_func);
typedef b32 custom_file_clear_layout_cache_type(Application_Links* app, Buffer_ID buffer); typedef b32 custom_buffer_clear_layout_cache_type(Application_Links* app, Buffer_ID buffer_id);
typedef Layout_Function* custom_buffer_get_layout_type(Application_Links* app, Buffer_ID buffer_id); typedef Layout_Function* custom_buffer_get_layout_type(Application_Links* app, Buffer_ID buffer_id);
typedef b32 custom_buffer_get_setting_type(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64* value_out); typedef b32 custom_buffer_get_setting_type(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64* value_out);
typedef b32 custom_buffer_set_setting_type(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64 value); typedef b32 custom_buffer_set_setting_type(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64 value);
@ -340,7 +340,7 @@ typedef Rect_f32 custom_draw_set_clip_type(Application_Links* app, Rect_f32 new_
typedef Text_Layout_ID custom_text_layout_create_type(Application_Links* app, Buffer_ID buffer_id, Rect_f32 rect, Buffer_Point buffer_point); typedef Text_Layout_ID custom_text_layout_create_type(Application_Links* app, Buffer_ID buffer_id, Rect_f32 rect, Buffer_Point buffer_point);
typedef Rect_f32 custom_text_layout_region_type(Application_Links* app, Text_Layout_ID text_layout_id); typedef Rect_f32 custom_text_layout_region_type(Application_Links* app, Text_Layout_ID text_layout_id);
typedef Buffer_ID custom_text_layout_get_buffer_type(Application_Links* app, Text_Layout_ID text_layout_id); typedef Buffer_ID custom_text_layout_get_buffer_type(Application_Links* app, Text_Layout_ID text_layout_id);
typedef Interval_i64 custom_text_layout_get_visible_range_type(Application_Links* app, Text_Layout_ID text_layout_id); typedef Range_i64 custom_text_layout_get_visible_range_type(Application_Links* app, Text_Layout_ID text_layout_id);
typedef Range_f32 custom_text_layout_line_on_screen_type(Application_Links* app, Text_Layout_ID layout_id, i64 line_number); typedef Range_f32 custom_text_layout_line_on_screen_type(Application_Links* app, Text_Layout_ID layout_id, i64 line_number);
typedef Rect_f32 custom_text_layout_character_on_screen_type(Application_Links* app, Text_Layout_ID layout_id, i64 pos); typedef Rect_f32 custom_text_layout_character_on_screen_type(Application_Links* app, Text_Layout_ID layout_id, i64 pos);
typedef void custom_paint_text_color_type(Application_Links* app, Text_Layout_ID layout_id, Interval_i64 range, FColor color); typedef void custom_paint_text_color_type(Application_Links* app, Text_Layout_ID layout_id, Interval_i64 range, FColor color);
@ -394,7 +394,7 @@ custom_push_buffer_file_name_type *push_buffer_file_name;
custom_buffer_get_dirty_state_type *buffer_get_dirty_state; custom_buffer_get_dirty_state_type *buffer_get_dirty_state;
custom_buffer_set_dirty_state_type *buffer_set_dirty_state; custom_buffer_set_dirty_state_type *buffer_set_dirty_state;
custom_buffer_set_layout_type *buffer_set_layout; custom_buffer_set_layout_type *buffer_set_layout;
custom_file_clear_layout_cache_type *file_clear_layout_cache; custom_buffer_clear_layout_cache_type *buffer_clear_layout_cache;
custom_buffer_get_layout_type *buffer_get_layout; custom_buffer_get_layout_type *buffer_get_layout;
custom_buffer_get_setting_type *buffer_get_setting; custom_buffer_get_setting_type *buffer_get_setting;
custom_buffer_set_setting_type *buffer_set_setting; custom_buffer_set_setting_type *buffer_set_setting;
@ -572,7 +572,7 @@ internal String_Const_u8 push_buffer_file_name(Application_Links* app, Arena* ar
internal Dirty_State buffer_get_dirty_state(Application_Links* app, Buffer_ID buffer_id); internal Dirty_State buffer_get_dirty_state(Application_Links* app, Buffer_ID buffer_id);
internal b32 buffer_set_dirty_state(Application_Links* app, Buffer_ID buffer_id, Dirty_State dirty_state); internal b32 buffer_set_dirty_state(Application_Links* app, Buffer_ID buffer_id, Dirty_State dirty_state);
internal b32 buffer_set_layout(Application_Links* app, Buffer_ID buffer_id, Layout_Function* layout_func); internal b32 buffer_set_layout(Application_Links* app, Buffer_ID buffer_id, Layout_Function* layout_func);
internal b32 file_clear_layout_cache(Application_Links* app, Buffer_ID buffer); internal b32 buffer_clear_layout_cache(Application_Links* app, Buffer_ID buffer_id);
internal Layout_Function* buffer_get_layout(Application_Links* app, Buffer_ID buffer_id); internal Layout_Function* buffer_get_layout(Application_Links* app, Buffer_ID buffer_id);
internal b32 buffer_get_setting(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64* value_out); internal b32 buffer_get_setting(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64* value_out);
internal b32 buffer_set_setting(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64 value); internal b32 buffer_set_setting(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64 value);
@ -695,7 +695,7 @@ internal Rect_f32 draw_set_clip(Application_Links* app, Rect_f32 new_clip);
internal Text_Layout_ID text_layout_create(Application_Links* app, Buffer_ID buffer_id, Rect_f32 rect, Buffer_Point buffer_point); internal Text_Layout_ID text_layout_create(Application_Links* app, Buffer_ID buffer_id, Rect_f32 rect, Buffer_Point buffer_point);
internal Rect_f32 text_layout_region(Application_Links* app, Text_Layout_ID text_layout_id); internal Rect_f32 text_layout_region(Application_Links* app, Text_Layout_ID text_layout_id);
internal Buffer_ID text_layout_get_buffer(Application_Links* app, Text_Layout_ID text_layout_id); internal Buffer_ID text_layout_get_buffer(Application_Links* app, Text_Layout_ID text_layout_id);
internal Interval_i64 text_layout_get_visible_range(Application_Links* app, Text_Layout_ID text_layout_id); internal Range_i64 text_layout_get_visible_range(Application_Links* app, Text_Layout_ID text_layout_id);
internal Range_f32 text_layout_line_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 line_number); internal Range_f32 text_layout_line_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 line_number);
internal Rect_f32 text_layout_character_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 pos); internal Rect_f32 text_layout_character_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 pos);
internal void paint_text_color(Application_Links* app, Text_Layout_ID layout_id, Interval_i64 range, FColor color); internal void paint_text_color(Application_Links* app, Text_Layout_ID layout_id, Interval_i64 range, FColor color);
@ -750,7 +750,7 @@ global custom_push_buffer_file_name_type *push_buffer_file_name = 0;
global custom_buffer_get_dirty_state_type *buffer_get_dirty_state = 0; global custom_buffer_get_dirty_state_type *buffer_get_dirty_state = 0;
global custom_buffer_set_dirty_state_type *buffer_set_dirty_state = 0; global custom_buffer_set_dirty_state_type *buffer_set_dirty_state = 0;
global custom_buffer_set_layout_type *buffer_set_layout = 0; global custom_buffer_set_layout_type *buffer_set_layout = 0;
global custom_file_clear_layout_cache_type *file_clear_layout_cache = 0; global custom_buffer_clear_layout_cache_type *buffer_clear_layout_cache = 0;
global custom_buffer_get_layout_type *buffer_get_layout = 0; global custom_buffer_get_layout_type *buffer_get_layout = 0;
global custom_buffer_get_setting_type *buffer_get_setting = 0; global custom_buffer_get_setting_type *buffer_get_setting = 0;
global custom_buffer_set_setting_type *buffer_set_setting = 0; global custom_buffer_set_setting_type *buffer_set_setting = 0;

View File

@ -41,7 +41,7 @@ api(custom) function String_Const_u8 push_buffer_file_name(Application_Links* ap
api(custom) function Dirty_State buffer_get_dirty_state(Application_Links* app, Buffer_ID buffer_id); api(custom) function Dirty_State buffer_get_dirty_state(Application_Links* app, Buffer_ID buffer_id);
api(custom) function b32 buffer_set_dirty_state(Application_Links* app, Buffer_ID buffer_id, Dirty_State dirty_state); api(custom) function b32 buffer_set_dirty_state(Application_Links* app, Buffer_ID buffer_id, Dirty_State dirty_state);
api(custom) function b32 buffer_set_layout(Application_Links* app, Buffer_ID buffer_id, Layout_Function* layout_func); api(custom) function b32 buffer_set_layout(Application_Links* app, Buffer_ID buffer_id, Layout_Function* layout_func);
api(custom) function b32 file_clear_layout_cache(Application_Links* app, Buffer_ID buffer); api(custom) function b32 buffer_clear_layout_cache(Application_Links* app, Buffer_ID buffer_id);
api(custom) function Layout_Function* buffer_get_layout(Application_Links* app, Buffer_ID buffer_id); api(custom) function Layout_Function* buffer_get_layout(Application_Links* app, Buffer_ID buffer_id);
api(custom) function b32 buffer_get_setting(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64* value_out); api(custom) function b32 buffer_get_setting(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64* value_out);
api(custom) function b32 buffer_set_setting(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64 value); api(custom) function b32 buffer_set_setting(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64 value);
@ -164,7 +164,7 @@ api(custom) function Rect_f32 draw_set_clip(Application_Links* app, Rect_f32 new
api(custom) function Text_Layout_ID text_layout_create(Application_Links* app, Buffer_ID buffer_id, Rect_f32 rect, Buffer_Point buffer_point); api(custom) function Text_Layout_ID text_layout_create(Application_Links* app, Buffer_ID buffer_id, Rect_f32 rect, Buffer_Point buffer_point);
api(custom) function Rect_f32 text_layout_region(Application_Links* app, Text_Layout_ID text_layout_id); api(custom) function Rect_f32 text_layout_region(Application_Links* app, Text_Layout_ID text_layout_id);
api(custom) function Buffer_ID text_layout_get_buffer(Application_Links* app, Text_Layout_ID text_layout_id); api(custom) function Buffer_ID text_layout_get_buffer(Application_Links* app, Text_Layout_ID text_layout_id);
api(custom) function Interval_i64 text_layout_get_visible_range(Application_Links* app, Text_Layout_ID text_layout_id); api(custom) function Range_i64 text_layout_get_visible_range(Application_Links* app, Text_Layout_ID text_layout_id);
api(custom) function Range_f32 text_layout_line_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 line_number); api(custom) function Range_f32 text_layout_line_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 line_number);
api(custom) function Rect_f32 text_layout_character_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 pos); api(custom) function Rect_f32 text_layout_character_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 pos);
api(custom) function void paint_text_color(Application_Links* app, Text_Layout_ID layout_id, Interval_i64 range, FColor color); api(custom) function void paint_text_color(Application_Links* app, Text_Layout_ID layout_id, Interval_i64 range, FColor color);