From 4640349de8c25c66715183093223e78f71c877cf Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sat, 28 Sep 2019 19:13:46 -0700 Subject: [PATCH] Basics of relex are now in place --- 4coder_API/4coder_types.h | 3 - 4coder_base_types.cpp | 11 +++ 4coder_default_hooks.cpp | 104 ++++++++++++++++++------ 4coder_experiments.cpp | 6 +- 4coder_helper.cpp | 9 -- 4coder_table.cpp | 150 ++++++++++++++++++---------------- 4coder_token.cpp | 167 +++++++++++++++++++++++++++++++------- 4coder_token.h | 5 ++ 4ed.cpp | 68 ---------------- 4ed_app_models.h | 1 - 4ed_edit.cpp | 17 ++-- 4ed_file.cpp | 4 - 4ed_file.h | 2 - 4ed_working_set.cpp | 33 -------- 4ed_working_set.h | 12 --- 15 files changed, 330 insertions(+), 262 deletions(-) diff --git a/4coder_API/4coder_types.h b/4coder_API/4coder_types.h index 2b969e35..a47761eb 100644 --- a/4coder_API/4coder_types.h +++ b/4coder_API/4coder_types.h @@ -548,9 +548,6 @@ TYPEDEF_FUNC i32 File_Edit_Range_Function(struct Application_Links *app, Buffer_ Interval_i64 range, String_Const_u8 text); #define FILE_EDIT_RANGE_SIG(name) i32 name(struct Application_Links *app, Buffer_ID buffer_id, Interval_i64 range, String_Const_u8 text) -TYPEDEF_FUNC i32 File_Edit_Finished_Function(struct Application_Links *app, Buffer_ID *buffer_ids, i32 buffer_id_count); -#define FILE_EDIT_FINISHED_SIG(name) i32 name(struct Application_Links *app, Buffer_ID *buffer_ids, i32 buffer_id_count) - TYPEDEF_FUNC i32 File_Externally_Modified_Function(struct Application_Links *app, Buffer_ID buffer_id); #define FILE_EXTERNALLY_MODIFIED_SIG(name) i32 name(struct Application_Links *app, Buffer_ID buffer_id) diff --git a/4coder_base_types.cpp b/4coder_base_types.cpp index 30a5f046..a1812949 100644 --- a/4coder_base_types.cpp +++ b/4coder_base_types.cpp @@ -291,6 +291,17 @@ block_fill_u64(void *a, umem size, u64 val){ #define block_match_struct(a,b) block_match((a), (b), sizeof(*(a))) #define block_match_array(a,b) block_match((a), (b), sizeof(a)) +internal void +block_copy_array_shift__inner(void *dst, void *src, umem it_size, Interval_i64 range, i64 shift){ + u8 *dptr = (u8*)dst; + u8 *sptr = (u8*)src; + dptr += it_size*(range.first + shift); + sptr += it_size*range.first; + block_copy(dptr, sptr, it_size*(range.one_past_last - range.first)); +} + +#define block_copy_array_shift(d,s,r,h) block_copy_array_shift__inner((d),(s),sizeof(*(d)),(r),(h)) + //////////////////////////////// internal f32 diff --git a/4coder_default_hooks.cpp b/4coder_default_hooks.cpp index 13ced961..1796717b 100644 --- a/4coder_default_hooks.cpp +++ b/4coder_default_hooks.cpp @@ -1027,6 +1027,24 @@ BUFFER_NAME_RESOLVER_SIG(default_buffer_name_resolution){ } } +internal void +do_full_lex(Application_Links *app, Buffer_ID buffer_id){ + Scratch_Block scratch(app); + String_Const_u8 contents = push_whole_buffer(app, scratch, buffer_id); + Token_List list = lex_full_input_cpp(scratch, contents); + + Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); + Base_Allocator *allocator = managed_scope_allocator(app, scope); + Token_Array tokens = {}; + tokens.tokens = base_array(allocator, Token, list.total_count); + tokens.count = list.total_count; + tokens.max = list.total_count; + token_fill_memory_from_list(tokens.tokens, &list); + + Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens, Token_Array); + block_copy_struct(tokens_ptr, &tokens); +} + BUFFER_HOOK_SIG(default_file_settings){ b32 treat_as_code = false; b32 lex_without_strings = false; @@ -1144,18 +1162,7 @@ BUFFER_HOOK_SIG(default_file_settings){ } if (use_lexer){ - Temp_Memory temp = begin_temp(scratch); - String_Const_u8 contents = push_whole_buffer(app, scratch, buffer_id); - Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); - Base_Allocator *allocator = managed_scope_allocator(app, scope); - Arena alloc_arena = make_arena(allocator); - Token_List list = lex_full_input_cpp(&alloc_arena, contents); - Token_Array tokens = token_array_from_list(&alloc_arena, &list); - - Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens, Token_Array); - block_copy_struct(tokens_ptr, &tokens); - - end_temp(temp); + do_full_lex(app, buffer_id); } #if 0 @@ -1176,8 +1183,8 @@ BUFFER_HOOK_SIG(default_file_settings){ } BUFFER_HOOK_SIG(default_new_file){ - // no meaning for return // buffer_id + // no meaning for return return(0); } @@ -1186,7 +1193,7 @@ BUFFER_HOOK_SIG(default_file_save){ if (global_config.automatically_indent_text_on_save && buffer_get_setting(app, buffer_id, BufferSetting_VirtualWhitespace, &is_virtual)){ if (is_virtual){ - i32 buffer_size = (i32)buffer_get_size(app, buffer_id); + i64 buffer_size = buffer_get_size(app, buffer_id); buffer_auto_indent(app, buffer_id, 0, buffer_size, DEF_TAB_WIDTH, DEFAULT_INDENT_FLAGS | AutoIndent_FullTokens); } } @@ -1195,23 +1202,73 @@ BUFFER_HOOK_SIG(default_file_save){ } FILE_EDIT_RANGE_SIG(default_file_edit_range){ - // no meaning for return // buffer_id, range, text - return(0); -} - -FILE_EDIT_FINISHED_SIG(default_file_edit_finished){ -#if 0 - for (i32 i = 0; i < buffer_id_count; i += 1){ - // buffer_ids[i] + + Interval_i64 replace_range = Ii64(range.first, range.first + text.size); + i64 insert_size = range_size(range); + i64 text_shift = replace_range_shift(replace_range, insert_size); + + Scratch_Block scratch(app); + + Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); + Token_Array *ptr = scope_attachment(app, scope, attachment_tokens, Token_Array); + if (ptr != 0 && ptr->tokens != 0){ + i64 token_index_first = token_relex_first(ptr, range.first, 1); + i64 token_index_resync_guess = token_relex_resync(ptr, range.one_past_last, 16); + + Token *token_first = ptr->tokens + token_index_first; + Token *token_resync = ptr->tokens + token_index_resync_guess; + + Interval_i64 relex_range = Ii64(token_first->pos, token_resync->pos + token_resync->size); + String_Const_u8 partial_text = push_buffer_range(app, scratch, buffer_id, relex_range); + + Token_List relex_list = lex_full_input_cpp(scratch, partial_text); + if (relex_range.one_past_last < buffer_get_size(app, buffer_id)){ + token_drop_eof(&relex_list); + } + + Token_Relex relex = token_relex(relex_list, token_first->pos - text_shift, + ptr->tokens, token_index_first, token_index_resync_guess); + + Base_Allocator *allocator = managed_scope_allocator(app, scope); + + if (relex.successful_resync){ + i64 token_index_resync = relex.first_resync_index; + + Interval_i64 head = Ii64(0, token_index_first); + Interval_i64 tail = Ii64(token_index_resync, ptr->count); + i64 tail_shift = relex_list.total_count - (token_index_resync - token_index_first); + + i64 new_tokens_count = ptr->count + tail_shift; + Token *new_tokens = base_array(allocator, Token, new_tokens_count); + + Token *old_tokens = ptr->tokens; + block_copy_array_shift(new_tokens, old_tokens, head, 0); + for (i64 i = tail.first; i < tail.one_past_last; i += 1){ + old_tokens[i].pos += text_shift; + } + block_copy_array_shift(new_tokens, ptr->tokens, tail, tail_shift); + token_fill_memory_from_list(new_tokens + head.one_past_last, &relex_list); + + base_free(allocator, ptr->tokens); + + ptr->tokens = new_tokens; + ptr->count = new_tokens_count; + ptr->max = new_tokens_count; + } + else{ + scratch.restore(); + base_free(allocator, ptr->tokens); + do_full_lex(app, buffer_id); + } } -#endif // no meaning for return return(0); } FILE_EXTERNALLY_MODIFIED_SIG(default_file_externally_modified){ + // buffer_id Scratch_Block scratch(app); String_Const_u8 name = push_buffer_unique_name(app, scratch, buffer_id); String_Const_u8 str = push_u8_stringf(scratch, "Modified externally: %s\n", name.str); @@ -1331,7 +1388,6 @@ set_all_default_hooks(Bind_Helper *context){ set_new_file_hook(context, default_new_file); set_save_file_hook(context, default_file_save); set_file_edit_range_hook(context, default_file_edit_range); - set_file_edit_finished_hook(context, default_file_edit_finished); set_file_externally_modified_hook(context, default_file_externally_modified); set_end_file_hook(context, end_file_close_jump_list); diff --git a/4coder_experiments.cpp b/4coder_experiments.cpp index 9472fb21..5958112b 100644 --- a/4coder_experiments.cpp +++ b/4coder_experiments.cpp @@ -196,12 +196,14 @@ get_bindings(void *data, i32 size){ set_open_file_hook(context, default_file_settings); set_new_file_hook(context, default_new_file); set_save_file_hook(context, default_file_save); + set_file_edit_range_hook(context, default_file_edit_range); + set_file_externally_modified_hook(context, default_file_externally_modified); + set_end_file_hook(context, end_file_close_jump_list); - set_input_filter(context, default_suppress_mouse_filter); set_command_caller(context, default_command_caller); set_render_caller(context, default_render_caller); - + set_input_filter(context, default_suppress_mouse_filter); set_scroll_rule(context, smooth_scroll_rule); set_buffer_name_resolver(context, default_buffer_name_resolution); set_modify_color_table_hook(context, default_modify_color_table); diff --git a/4coder_helper.cpp b/4coder_helper.cpp index 0ff63e6f..d231fd43 100644 --- a/4coder_helper.cpp +++ b/4coder_helper.cpp @@ -219,15 +219,6 @@ set_file_edit_range_hook(Bind_Helper *helper, File_Edit_Range_Function *func){ write_unit(helper, unit); } -internal void -set_file_edit_finished_hook(Bind_Helper *helper, File_Edit_Finished_Function *func){ - Binding_Unit unit = {}; - unit.type = unit_hook; - unit.hook.hook_id = special_hook_file_edit_finished; - unit.hook.func = (void*)func; - write_unit(helper, unit); -} - internal void set_file_externally_modified_hook(Bind_Helper *helper, File_Externally_Modified_Function *func){ Binding_Unit unit = {}; diff --git a/4coder_table.cpp b/4coder_table.cpp index 82173b5a..747e811e 100644 --- a/4coder_table.cpp +++ b/4coder_table.cpp @@ -134,22 +134,24 @@ table_rehash(Table_u64_u64 *dst, Table_u64_u64 *src){ internal b32 table_insert(Table_u64_u64 *table, u64 key, u64 val){ b32 result = false; - Table_Lookup lookup = table_lookup(table, key); - if (!lookup.found_match){ - if ((table->dirty_count + 1)*8 >= table->slot_count*7){ - i32 new_slot_count = table->slot_count; - if (table->used_count*2 >= table->slot_count){ - new_slot_count = table->slot_count*4; + if (key != table_empty_key && key != table_erased_key){ + Table_Lookup lookup = table_lookup(table, key); + if (!lookup.found_match){ + if ((table->dirty_count + 1)*8 >= table->slot_count*7){ + i32 new_slot_count = table->slot_count; + if (table->used_count*2 >= table->slot_count){ + new_slot_count = table->slot_count*4; + } + Table_u64_u64 new_table = make_table_u64_u64(table->allocator, new_slot_count); + table_rehash(&new_table, table); + table_free(table); + *table = new_table; + lookup = table_lookup(table, key); + Assert(lookup.found_empty_slot); } - Table_u64_u64 new_table = make_table_u64_u64(table->allocator, new_slot_count); - table_rehash(&new_table, table); - table_free(table); - *table = new_table; - lookup = table_lookup(table, key); - Assert(lookup.found_empty_slot); + table_insert__inner(table, lookup, val); + result = true; } - table_insert__inner(table, lookup, val); - result = true; } return(result); } @@ -288,22 +290,24 @@ table_rehash(Table_u32_u16 *dst, Table_u32_u16 *src){ internal b32 table_insert(Table_u32_u16 *table, u32 key, u16 val){ b32 result = false; - Table_Lookup lookup = table_lookup(table, key); - if (!lookup.found_match){ - if ((table->dirty_count + 1)*8 >= table->slot_count*7){ - i32 new_slot_count = table->slot_count; - if (table->used_count*2 >= table->slot_count){ - new_slot_count = table->slot_count*4; + if (key != table_empty_u32_key && key != table_erased_u32_key){ + Table_Lookup lookup = table_lookup(table, key); + if (!lookup.found_match){ + if ((table->dirty_count + 1)*8 >= table->slot_count*7){ + i32 new_slot_count = table->slot_count; + if (table->used_count*2 >= table->slot_count){ + new_slot_count = table->slot_count*4; + } + Table_u32_u16 new_table = make_table_u32_u16(table->allocator, new_slot_count); + table_rehash(&new_table, table); + table_free(table); + *table = new_table; + lookup = table_lookup(table, key); + Assert(lookup.found_empty_slot); } - Table_u32_u16 new_table = make_table_u32_u16(table->allocator, new_slot_count); - table_rehash(&new_table, table); - table_free(table); - *table = new_table; - lookup = table_lookup(table, key); - Assert(lookup.found_empty_slot); + table_insert__inner(table, lookup, key, val); + result = true; } - table_insert__inner(table, lookup, key, val); - result = true; } return(result); } @@ -453,22 +457,24 @@ table_rehash(Table_Data_u64 *dst, Table_Data_u64 *src){ internal b32 table_insert(Table_Data_u64 *table, Data key, u64 val){ b32 result = false; - Table_Lookup lookup = table_lookup(table, key); - if (!lookup.found_match){ - if ((table->dirty_count + 1)*8 >= table->slot_count*7){ - i32 new_slot_count = table->slot_count; - if (table->used_count*2 >= table->slot_count){ - new_slot_count = table->slot_count*4; + if (key.data != 0){ + Table_Lookup lookup = table_lookup(table, key); + if (!lookup.found_match){ + if ((table->dirty_count + 1)*8 >= table->slot_count*7){ + i32 new_slot_count = table->slot_count; + if (table->used_count*2 >= table->slot_count){ + new_slot_count = table->slot_count*4; + } + Table_Data_u64 new_table = make_table_Data_u64(table->allocator, new_slot_count); + table_rehash(&new_table, table); + table_free(table); + *table = new_table; + lookup = table_lookup(table, key); + Assert(lookup.found_empty_slot); } - Table_Data_u64 new_table = make_table_Data_u64(table->allocator, new_slot_count); - table_rehash(&new_table, table); - table_free(table); - *table = new_table; - lookup = table_lookup(table, key); - Assert(lookup.found_empty_slot); + table_insert__inner(table, lookup, key, val); + result = true; } - table_insert__inner(table, lookup, key, val); - result = true; } return(result); } @@ -612,22 +618,24 @@ table_rehash(Table_u64_Data *dst, Table_u64_Data *src){ internal b32 table_insert(Table_u64_Data *table, u64 key, Data val){ b32 result = false; - Table_Lookup lookup = table_lookup(table, key); - if (!lookup.found_match){ - if ((table->dirty_count + 1)*8 >= table->slot_count*7){ - i32 new_slot_count = table->slot_count; - if (table->used_count*2 >= table->slot_count){ - new_slot_count = table->slot_count*4; + if (key != table_empty_key && table_erased_key){ + Table_Lookup lookup = table_lookup(table, key); + if (!lookup.found_match){ + if ((table->dirty_count + 1)*8 >= table->slot_count*7){ + i32 new_slot_count = table->slot_count; + if (table->used_count*2 >= table->slot_count){ + new_slot_count = table->slot_count*4; + } + Table_u64_Data new_table = make_table_u64_Data(table->allocator, new_slot_count); + table_rehash(&new_table, table); + table_free(table); + *table = new_table; + lookup = table_lookup(table, key); + Assert(lookup.found_empty_slot); } - Table_u64_Data new_table = make_table_u64_Data(table->allocator, new_slot_count); - table_rehash(&new_table, table); - table_free(table); - *table = new_table; - lookup = table_lookup(table, key); - Assert(lookup.found_empty_slot); + table_insert__inner(table, lookup, val); + result = true; } - table_insert__inner(table, lookup, val); - result = true; } return(result); } @@ -772,22 +780,24 @@ table_rehash(Table_Data_Data *dst, Table_Data_Data *src){ internal b32 table_insert(Table_Data_Data *table, Data key, Data val){ b32 result = false; - Table_Lookup lookup = table_lookup(table, key); - if (!lookup.found_match){ - if ((table->dirty_count + 1)*8 >= table->slot_count*7){ - i32 new_slot_count = table->slot_count; - if (table->used_count*2 >= table->slot_count){ - new_slot_count = table->slot_count*4; + if (key.data != 0){ + Table_Lookup lookup = table_lookup(table, key); + if (!lookup.found_match){ + if ((table->dirty_count + 1)*8 >= table->slot_count*7){ + i32 new_slot_count = table->slot_count; + if (table->used_count*2 >= table->slot_count){ + new_slot_count = table->slot_count*4; + } + Table_Data_Data new_table = make_table_Data_Data(table->allocator, new_slot_count); + table_rehash(&new_table, table); + table_free(table); + *table = new_table; + lookup = table_lookup(table, key); + Assert(lookup.found_empty_slot); } - Table_Data_Data new_table = make_table_Data_Data(table->allocator, new_slot_count); - table_rehash(&new_table, table); - table_free(table); - *table = new_table; - lookup = table_lookup(table, key); - Assert(lookup.found_empty_slot); + table_insert__inner(table, lookup, key, val); + result = true; } - table_insert__inner(table, lookup, key, val); - result = true; } return(result); } diff --git a/4coder_token.cpp b/4coder_token.cpp index c467a268..e7748fb8 100644 --- a/4coder_token.cpp +++ b/4coder_token.cpp @@ -23,18 +23,35 @@ token_list_push(Arena *arena, Token_List *list, Token *token){ list->total_count += 1; } +internal void +token_fill_memory_from_list(Token *dst, Token_List *list){ + Token *ptr = dst; + for (Token_Block *node = list->first; + node != 0; + node = node->next){ + block_copy_dynamic_array(ptr, node->tokens, node->count); + ptr += node->count; + } +} + +internal Token_Array +token_array_from_list_always_copy(Arena *arena, Token_List *list){ + Token_Array array = {}; + if (list->node_count >= 1){ + array.tokens = push_array(arena, Token, list->total_count); + token_fill_memory_from_list(array.tokens, list); + array.count = list->total_count; + array.max = array.count; + } + return(array); +} + internal Token_Array token_array_from_list(Arena *arena, Token_List *list){ Token_Array array = {}; if (list->node_count > 1){ array.tokens = push_array(arena, Token, list->total_count); - Token *ptr = array.tokens; - for (Token_Block *node = list->first; - node != 0; - node = node->next){ - block_copy_dynamic_array(ptr, node->tokens, node->count); - ptr += node->count; - } + token_fill_memory_from_list(array.tokens, list); array.count = list->total_count; array.max = array.count; } @@ -49,27 +66,29 @@ token_array_from_list(Arena *arena, Token_List *list){ internal i64 token_index_from_pos(Token *tokens, i64 count, i64 pos){ i64 result = 0; - if (pos >= tokens[count - 1].pos){ - result = count - 1; - } - else if (pos < 0){ - result = 0; - } - else{ - i64 first = 0; - i64 one_past_last = count; - for (;;){ - i64 index = (first + one_past_last) >> 1; - i64 index_pos = tokens[index].pos; - if (index_pos > pos){ - one_past_last = index; - } - else if (index_pos + tokens[index].size <= pos){ - first = index + 1; - } - else{ - result = index; - break; + if (count > 0){ + if (pos >= tokens[count - 1].pos){ + result = count - 1; + } + else if (pos <= tokens[0].pos){ + result = 0; + } + else{ + i64 first = 0; + i64 one_past_last = count; + for (;;){ + i64 index = (first + one_past_last) >> 1; + i64 index_pos = tokens[index].pos; + if (index_pos > p){ + one_past_last = index; + } + else if (index_pos + tokens[index].size <= pos){ + first = index + 1; + } + else{ + result = index; + break; + } } } } @@ -562,5 +581,97 @@ token_it_dec(Token_Iterator *it){ return(0); } +//////////////////////////////// + +internal void +token_drop_eof(Token_List *list){ + if (list->last != 0){ + Token_Block *block = list->last; + if (block->tokens[block->count - 1].kind == TokenBaseKind_EOF){ + list->total_count -= 1; + block->count -= 1; + if (block->count == 0){ + zdll_remove(list->first, list->last, block); + list->node_count -= 1; + } + } + } +} + +//////////////////////////////// + +internal i64 +token_relex_first(Token_Array *tokens, i64 edit_range_first, i64 backup_repeats){ + Token_Iterator_Array it = token_iterator_pos(0, tokens, edit_range_first); + b32 good_status = true; + for (i64 i = 0; i < backup_repeats && good_status; i += 1){ + good_status = token_it_dec(&it); + } + if (good_status){ + for (;;){ + Token *token = token_it_read(&it); + if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){ + break; + } + if (!token_it_dec(&it)){ + break; + } + } + } + return(token_it_index(&it)); +} + +internal i64 +token_relex_resync(Token_Array *tokens, i64 edit_range_first, i64 look_ahead_repeats){ + Token_Iterator_Array it = token_iterator_pos(0, tokens, edit_range_first); + b32 good_status = true; + for (i64 i = 0; i < look_ahead_repeats && good_status; i += 1){ + good_status = token_it_inc(&it); + } + if (good_status){ + for (;;){ + Token *token = token_it_read(&it); + if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){ + break; + } + if (!token_it_inc(&it)){ + break; + } + } + } + return(token_it_index(&it)); +} + +internal Token_Relex +token_relex(Token_List relex_list, i64 new_pos_to_old_pos_shift, Token *tokens, i64 relex_first, i64 relex_last){ + Token_Relex relex = {}; + if (relex_list.total_count > 0){ + Token_Array relexed_tokens = {tokens + relex_first, relex_last - relex_first + 1}; + Token_Iterator_List it = token_iterator_index(0, &relex_list, relex_list.total_count - 1); + for (;;){ + Token *token = token_it_read(&it); + i64 new_pos_rebased = token->pos + new_pos_to_old_pos_shift; + i64 old_token_index = token_index_from_pos(&relexed_tokens, new_pos_rebased); + Token *old_token = relexed_tokens.tokens + old_token_index; + if (new_pos_rebased == old_token->pos && + token->size == old_token->size && + token->kind == old_token->kind && + token->sub_kind == old_token->sub_kind && + token->flags == old_token->flags && + token->sub_flags == old_token->sub_flags){ + relex.successful_resync = true; + relex.first_resync_index = relex_first + old_token_index; + } + else{ + break; + } + if (!token_it_dec_all(&it)){ + break; + } + } + } + return(relex); +} + // BOTTOM diff --git a/4coder_token.h b/4coder_token.h index 13b656db..7613621f 100644 --- a/4coder_token.h +++ b/4coder_token.h @@ -81,6 +81,11 @@ struct Token_List{ i64 total_count; }; +struct Token_Relex{ + b32 successful_resync; + i64 first_resync_index; +}; + struct Token_Iterator_Array{ u64 user_id; Token *ptr; diff --git a/4ed.cpp b/4ed.cpp index 82f61aed..5a007727 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -173,7 +173,6 @@ interpret_binding_buffer(Models *models, void *buffer, i32 size){ models->hook_save_file = 0; models->hook_end_file = 0; models->hook_file_edit_range = 0; - models->hook_file_edit_finished = 0; models->command_caller = 0; models->render_caller = 0; models->input_filter = 0; @@ -379,11 +378,6 @@ interpret_binding_buffer(Models *models, void *buffer, i32 size){ models->hook_file_edit_range = (File_Edit_Range_Function*)unit->hook.func; }break; - case special_hook_file_edit_finished: - { - models->hook_file_edit_finished = (File_Edit_Finished_Function*)unit->hook.func; - }break; - case special_hook_file_externally_modified: { models->hook_file_externally_modified = (File_Externally_Modified_Function*)unit->hook.func; @@ -1346,68 +1340,6 @@ App_Step_Sig(app_step){ } } - // NOTE(allen): hook for files marked "edit finished" - { - File_Edit_Finished_Function *hook_file_edit_finished = models->hook_file_edit_finished; - if (hook_file_edit_finished != 0){ - Working_Set *working_set = &models->working_set; - if (working_set->edit_finished_count > 0){ - Assert(working_set->edit_finished_sentinel.next != 0); - b32 trigger_hook = false; - - u32 elapse_time = models->edit_finished_hook_repeat_speed; - if (elapse_time != 0){ - trigger_hook = true; - } - else if (working_set->time_of_next_edit_finished_signal == 0){ - u32 trigger_window_length = 0; - if (elapse_time > 5){ - trigger_window_length = elapse_time - 5; - } - u64 trigger_time = system->now_time() + (u64)trigger_window_length*1000LLU; - working_set->time_of_next_edit_finished_signal = trigger_time; - system->wake_up_timer_set(working_set->edit_finished_timer, elapse_time); - } - else if (system->now_time() >= working_set->time_of_next_edit_finished_signal){ - trigger_hook = true; - } - if (trigger_hook){ - Arena *scratch = &models->mem.arena; - Temp_Memory temp = begin_temp(scratch); - Node *first = working_set->edit_finished_sentinel.next; - Node *one_past_last = &working_set->edit_finished_sentinel; - - i32 max_id_count = working_set->edit_finished_count; - Editing_File **file_ptrs = push_array(scratch, Editing_File*, max_id_count); - Buffer_ID *ids = push_array(scratch, Buffer_ID, max_id_count); - i32 id_count = 0; - for (Node *node = first; - node != one_past_last; - node = node->next){ - Editing_File *file_ptr = CastFromMember(Editing_File, edit_finished_mark_node, node); - file_ptrs[id_count] = file_ptr; - ids[id_count] = file_ptr->id; - id_count += 1; - } - - working_set->do_not_mark_edits = true; - hook_file_edit_finished(&models->app_links, ids, id_count); - working_set->do_not_mark_edits = false; - - for (i32 i = 0; i < id_count; i += 1){ - file_ptrs[i]->edit_finished_marked = false; - } - - dll_init_sentinel(&working_set->edit_finished_sentinel); - working_set->edit_finished_count = 0; - working_set->time_of_next_edit_finished_signal = 0; - - end_temp(temp); - } - } - } - } - // NOTE(allen): if the exit signal has been sent, run the exit hook. if (input->trying_to_kill){ models->keep_playing = false; diff --git a/4ed_app_models.h b/4ed_app_models.h index 65a39fca..f3da21b3 100644 --- a/4ed_app_models.h +++ b/4ed_app_models.h @@ -63,7 +63,6 @@ struct Models{ Buffer_Hook_Function *hook_save_file; Buffer_Hook_Function *hook_end_file; File_Edit_Range_Function *hook_file_edit_range; - File_Edit_Finished_Function *hook_file_edit_finished; File_Externally_Modified_Function *hook_file_externally_modified; Command_Caller_Hook_Function *command_caller; Render_Caller_Function *render_caller; diff --git a/4ed_edit.cpp b/4ed_edit.cpp index 709a15bb..9ddf64a1 100644 --- a/4ed_edit.cpp +++ b/4ed_edit.cpp @@ -13,7 +13,6 @@ internal void edit_pre_state_change(Models *models, Editing_File *file){ System_Functions *system = models->system; file_add_dirty_flag(file, DirtyState_UnsavedChanges); - file_unmark_edit_finished(&models->working_set, file); } internal void @@ -191,10 +190,10 @@ edit_single(Models *models, Editing_File *file, Interval_i64 range, String_Const Assert(edit.range.one_past_last <= buffer_size(buffer)); Arena *scratch = &models->mem.arena; + Temp_Memory temp = begin_temp(scratch); // NOTE(allen): history update if (!behaviors.do_not_post_to_history){ - // TODO(allen): if the edit number counter is not updated, maybe auto-merge edits? Wouldn't that just work? history_dump_records_after_index(&file->state.history, file->state.current_record_index); history_record_edit(&models->global_history, &file->state.history, buffer, edit); file->state.current_record_index = history_get_record_count(&file->state.history); @@ -203,9 +202,10 @@ edit_single(Models *models, Editing_File *file, Interval_i64 range, String_Const // NOTE(allen): fixing stuff beforewards???? edit_pre_state_change(models, file); - // NOTE(allen): edit range hook + // NOTE(allen): save the original text for the edit range hook. + String_Const_u8 original_text = {}; if (models->hook_file_edit_range != 0){ - models->hook_file_edit_range(&models->app_links, file->id, edit.range, edit.text); + original_text = buffer_stringify(scratch, &file->state.buffer, edit.range); } // NOTE(allen): expand spec, compute shift @@ -227,8 +227,13 @@ edit_single(Models *models, Editing_File *file, Interval_i64 range, String_Const // NOTE(allen): cursor fixing edit_fix_markers(models, file, edit); - // NOTE(allen): mark edit finished - file_mark_edit_finished(&models->working_set, file); + // NOTE(allen): edit range hook + if (models->hook_file_edit_range != 0){ + Interval_i64 new_range = Ii64(edit.range.first, edit.range.first + edit.text.size); + models->hook_file_edit_range(&models->app_links, file->id, new_range, original_text); + } + + end_temp(temp); } internal void diff --git a/4ed_file.cpp b/4ed_file.cpp index 89e71c12..30c7ff71 100644 --- a/4ed_file.cpp +++ b/4ed_file.cpp @@ -233,8 +233,6 @@ file_create_from_string(Models *models, Editing_File *file, String_Const_u8 val, file->lifetime_object = lifetime_alloc_object(&models->lifetime_allocator, DynamicWorkspace_Buffer, file); history_init(&models->app_links, &file->state.history); - file_mark_edit_finished(&models->working_set, file); - file->state.cached_layouts_arena = make_arena(allocator); file->state.line_layout_table = make_table_Data_u64(allocator, 500); @@ -272,8 +270,6 @@ file_free(System_Functions *system, Lifetime_Allocator *lifetime_allocator, Work linalloc_clear(&file->state.cached_layouts_arena); table_free(&file->state.line_layout_table); - - file_unmark_edit_finished(working_set, file); } //////////////////////////////// diff --git a/4ed_file.h b/4ed_file.h index 3141728c..b9441d41 100644 --- a/4ed_file.h +++ b/4ed_file.h @@ -83,8 +83,6 @@ struct Editing_File{ }; Node touch_node; Node external_mod_node; - Node edit_finished_mark_node; - b32 edit_finished_marked; b32 is_loading; Buffer_ID id; Editing_File_Settings settings; diff --git a/4ed_working_set.cpp b/4ed_working_set.cpp index 7bcf9057..5afb517c 100644 --- a/4ed_working_set.cpp +++ b/4ed_working_set.cpp @@ -125,9 +125,6 @@ working_set_init(Models *models, Working_Set *working_set){ dll_init_sentinel(&working_set->active_file_sentinel); dll_init_sentinel(&working_set->touch_order_sentinel); - dll_init_sentinel(&working_set->edit_finished_sentinel); - working_set->edit_finished_timer = system->wake_up_timer_create(); - local_const i32 slot_count = 128; Base_Allocator *allocator = get_base_allocator_system(system); working_set->id_to_ptr_table = make_table_u64_u64(allocator, slot_count); @@ -502,36 +499,6 @@ file_get_next(Working_Set *working_set, Editing_File *file){ return(file); } -internal void -file_mark_edit_finished(Working_Set *working_set, Editing_File *file){ - // TODO(allen): do(propogate do_not_mark_edits down the edit pipeline to here) - // This current method only works for synchronous calls, asynchronous calls - // will get the wrong do_not_mark_edits value. - if (!working_set->do_not_mark_edits){ - if (!file->edit_finished_marked){ - file->edit_finished_marked = true; - dll_insert_back(&working_set->edit_finished_sentinel, - &file->edit_finished_mark_node); - working_set->edit_finished_count += 1; - } - } -} - -internal b32 -file_unmark_edit_finished(Working_Set *working_set, Editing_File *file){ - b32 result = false; - if (!working_set->do_not_mark_edits){ - if (file->edit_finished_marked){ - file->edit_finished_marked = false; - dll_remove(&file->edit_finished_mark_node); - working_set->edit_finished_count -= 1; - block_zero_struct(&file->edit_finished_mark_node); - result = true; - } - } - return(result); -} - //////////////////////////////// internal Editing_File* diff --git a/4ed_working_set.h b/4ed_working_set.h index 159ee02f..3e213b2d 100644 --- a/4ed_working_set.h +++ b/4ed_working_set.h @@ -26,12 +26,6 @@ struct Working_Set{ Node touch_order_sentinel; i32 active_file_count; - Node edit_finished_sentinel; - i32 edit_finished_count; - u64 time_of_next_edit_finished_signal; - Plat_Handle edit_finished_timer; - b32 do_not_mark_edits; - Table_u64_u64 id_to_ptr_table; Table_Data_u64 canon_table; Table_Data_u64 name_table; @@ -51,12 +45,6 @@ struct Working_Set{ i32 clipboard_rolling; }; -internal void -file_mark_edit_finished(Working_Set *working_set, Editing_File *file); - -internal b32 -file_unmark_edit_finished(Working_Set *working_set, Editing_File *file); - #endif // BOTTOM