diff --git a/code/custom/4coder_tree_sitter.cpp b/code/custom/4coder_tree_sitter.cpp index f6deca6d..d050acb6 100644 --- a/code/custom/4coder_tree_sitter.cpp +++ b/code/custom/4coder_tree_sitter.cpp @@ -269,14 +269,7 @@ tree_sitter_parse_async__inner(Async_Context* actx, Buffer_ID buffer_id) tree_data->tree = new_tree; system_mutex_acquire(tree_data->tree_mutex); - // TODO(PS): Just put the code index update call here - // NOTE(jack): This feels kinda hacky, this is here to trigger - // the code index update tick. The buffer is also makred by the - // async lexer so we will update the index too frequently. We - // should probably change the lexer to not mark as modified. - // TODO(jack): Should we instead trigger another async task here to - // update the code index once this is done? - buffer_mark_as_modified(buffer_id); + tree_sitter_code_index_update_single_buffer(app, buffer_id); // Force a frame refresh by requesting another frame animate_in_n_milliseconds(app, 0); @@ -329,137 +322,140 @@ code_index_new_note(Code_Index_File* index, Arena* arena, Code_Index_Note_Kind k } function void -tree_sitter_code_index_update_tick(Application_Links* app) +tree_sitter_code_index_update_single_buffer(Application_Links* app, Buffer_ID buffer_id) { Scratch_Block scratch(app); + Arena arena = make_arena_system(KB(16)); + Code_Index_File* index = push_array_zero(&arena, Code_Index_File, 1); + index->buffer = buffer_id; + + String_Const_u8 buffer_contents = push_whole_buffer(app, scratch, buffer_id); + + Tree_Sitter_Language_Definition* lang = tree_sitter_language_for_buffer(app, buffer_id); + if (!lang) return; + + TSQuery* ts_query = lang->queries.ptr[Tree_Sitter_Language_Query_Tags]; + Tree_Sitter_Query_Cursor query = tree_sitter_query_init( + app, buffer_id, ts_query + ); + + Code_Index_Nest_Stack* nest_stack_first = 0; + Code_Index_Nest_Stack* nest_stack_last = 0; + + Code_Index_Note* last_note = 0; + u32 last_note_match_id = max_u32; + + TSQueryMatch query_match; + u32 capture_index; + while (tree_sitter_query_continue(&query, &query_match, &capture_index)) + { + TSQueryCapture type_capture = query_match.captures[capture_index]; + TSNode type_node = type_capture.node; + Range_i64 type_range = tree_sitter_node_to_range(type_node); + + u32 length; + const char* tmp = ts_query_capture_name_for_id(query.query, type_capture.index, &length); + String_Const_u8 capture_name = SCu8((char*)tmp, length); + + if (string_match(capture_name, SCu8("scope_begin"))) + { + Code_Index_Nest* nest = push_array_zero(&arena, Code_Index_Nest, 1); + nest->kind = CodeIndexNest_Scope; + nest->open = type_range; + nest->close = Ii64(max_i64); + nest->file = index; + if (nest_stack_last != 0) + { + nest->parent = nest_stack_last->nest; + code_index_push_nest(&nest->parent->nest_list, nest); + } + + Code_Index_Nest_Stack* stack = push_array_zero(scratch, Code_Index_Nest_Stack, 1); + stack->nest = nest; + stack->prev = nest_stack_last; + stack->match_id = query_match.id; + if (nest_stack_last != 0) nest_stack_last->next = stack; + else nest_stack_first = stack; + nest_stack_last = stack; + } + else if (string_match(capture_name, SCu8("scope_end"))) + { + Assert(nest_stack_last != 0); + Assert(nest_stack_last->match_id == query_match.id); + + Code_Index_Nest* nest = nest_stack_last->nest; + nest->close = type_range; + nest->is_closed = true; + nest->nest_array = code_index_nest_ptr_array_from_list(&arena, &nest->nest_list); + if (nest->parent == 0) code_index_push_nest(&index->nest_list, nest); + + nest_stack_last = nest_stack_last->prev; + if (nest_stack_last != 0) nest_stack_last->next = 0; + } + else if (string_match(capture_name, SCu8("definition.class"))) + { + last_note = code_index_new_note(index, &arena, CodeIndexNote_Type, type_range, nest_stack_last); + last_note_match_id = query_match.id; + } + else if (string_match(capture_name, SCu8("definition.function"))) + { + last_note = code_index_new_note(index, &arena, CodeIndexNote_Function, type_range, nest_stack_last); + last_note_match_id = query_match.id; + } + else if (string_match(capture_name, SCu8("definition.method"))) + { + last_note = code_index_new_note(index, &arena, CodeIndexNote_Function, type_range, nest_stack_last);; + last_note_match_id = query_match.id; + } + else if (string_match(capture_name, SCu8("definition.type"))) + { + last_note = code_index_new_note(index, &arena, CodeIndexNote_Type, type_range, nest_stack_last); + last_note_match_id = query_match.id; + } + else if (string_match(capture_name, SCu8("name"))) + { + if (last_note != 0 && last_note_match_id == query_match.id) + { + last_note->pos = Ii64_size(type_range.start, type_range.end - type_range.start); + } + } + } + + while (nest_stack_last != 0) + { + Code_Index_Nest* nest = nest_stack_last->nest; + if (nest->parent != 0) code_index_push_nest(&nest->parent->nest_list, nest); + else code_index_push_nest(&index->nest_list, nest); + nest->nest_array = code_index_nest_ptr_array_from_list(&arena, &nest->nest_list); + nest_stack_last = nest_stack_last->prev; + } + + for (Code_Index_Note* note = index->note_list.first; note != 0 && note->next != note; note = note->next) + { + note->text = push_string_copy(&arena, string_substring(buffer_contents, note->pos)); + } + + // Finish the Index + index->nest_array = code_index_nest_ptr_array_from_list(&arena, &index->nest_list); + index->note_array = code_index_note_ptr_array_from_list(&arena, &index->note_list); + + code_index_lock(); + code_index_set_file(buffer_id, arena, index); + code_index_unlock(); + buffer_clear_layout_cache(app, buffer_id); + + tree_sitter_query_end(&query); +} + +function void +tree_sitter_code_index_update_tick(Application_Links* app) +{ for (Buffer_Modified_Node* modified_node = global_buffer_modified_set.first; modified_node != 0; modified_node = modified_node->next ){ - Temp_Memory_Block temp(scratch); - - Buffer_ID buffer_id = modified_node->buffer; - Arena arena = make_arena_system(KB(16)); - Code_Index_File* index = push_array_zero(&arena, Code_Index_File, 1); - index->buffer = buffer_id; - - String_Const_u8 buffer_contents = push_whole_buffer(app, scratch, buffer_id); - - Tree_Sitter_Language_Definition* lang = tree_sitter_language_for_buffer(app, buffer_id); - if (!lang) continue; - - TSQuery* ts_query = lang->queries.ptr[Tree_Sitter_Language_Query_Tags]; - Tree_Sitter_Query_Cursor query = tree_sitter_query_init( - app, buffer_id, ts_query - ); - - Code_Index_Nest_Stack* nest_stack_first = 0; - Code_Index_Nest_Stack* nest_stack_last = 0; - - Code_Index_Note* last_note = 0; - u32 last_note_match_id = max_u32; - - TSQueryMatch query_match; - u32 capture_index; - while (tree_sitter_query_continue(&query, &query_match, &capture_index)) - { - TSQueryCapture type_capture = query_match.captures[capture_index]; - TSNode type_node = type_capture.node; - Range_i64 type_range = tree_sitter_node_to_range(type_node); - - u32 length; - const char* tmp = ts_query_capture_name_for_id(query.query, type_capture.index, &length); - String_Const_u8 capture_name = SCu8((char*)tmp, length); - - if (string_match(capture_name, SCu8("scope_begin"))) - { - Code_Index_Nest* nest = push_array_zero(&arena, Code_Index_Nest, 1); - nest->kind = CodeIndexNest_Scope; - nest->open = type_range; - nest->close = Ii64(max_i64); - nest->file = index; - if (nest_stack_last != 0) - { - nest->parent = nest_stack_last->nest; - code_index_push_nest(&nest->parent->nest_list, nest); - } - - Code_Index_Nest_Stack* stack = push_array_zero(scratch, Code_Index_Nest_Stack, 1); - stack->nest = nest; - stack->prev = nest_stack_last; - stack->match_id = query_match.id; - if (nest_stack_last != 0) nest_stack_last->next = stack; - else nest_stack_first = stack; - nest_stack_last = stack; - } - else if (string_match(capture_name, SCu8("scope_end"))) - { - Assert(nest_stack_last != 0); - Assert(nest_stack_last->match_id == query_match.id); - - Code_Index_Nest* nest = nest_stack_last->nest; - nest->close = type_range; - nest->is_closed = true; - nest->nest_array = code_index_nest_ptr_array_from_list(&arena, &nest->nest_list); - if (nest->parent == 0) code_index_push_nest(&index->nest_list, nest); - - nest_stack_last = nest_stack_last->prev; - if (nest_stack_last != 0) nest_stack_last->next = 0; - } - else if (string_match(capture_name, SCu8("definition.class"))) - { - last_note = code_index_new_note(index, &arena, CodeIndexNote_Type, type_range, nest_stack_last); - last_note_match_id = query_match.id; - } - else if (string_match(capture_name, SCu8("definition.function"))) - { - last_note = code_index_new_note(index, &arena, CodeIndexNote_Function, type_range, nest_stack_last); - last_note_match_id = query_match.id; - } - else if (string_match(capture_name, SCu8("definition.method"))) - { - last_note = code_index_new_note(index, &arena, CodeIndexNote_Function, type_range, nest_stack_last);; - last_note_match_id = query_match.id; - } - else if (string_match(capture_name, SCu8("definition.type"))) - { - last_note = code_index_new_note(index, &arena, CodeIndexNote_Type, type_range, nest_stack_last); - last_note_match_id = query_match.id; - } - else if (string_match(capture_name, SCu8("name"))) - { - if (last_note != 0 && last_note_match_id == query_match.id) - { - last_note->pos = Ii64_size(type_range.start, type_range.end - type_range.start); - } - } - } - - while (nest_stack_last != 0) - { - Code_Index_Nest* nest = nest_stack_last->nest; - if (nest->parent != 0) code_index_push_nest(&nest->parent->nest_list, nest); - else code_index_push_nest(&index->nest_list, nest); - nest->nest_array = code_index_nest_ptr_array_from_list(&arena, &nest->nest_list); - nest_stack_last = nest_stack_last->prev; - } - - for (Code_Index_Note* note = index->note_list.first; note != 0 && note->next != note; note = note->next) - { - note->text = push_string_copy(&arena, string_substring(buffer_contents, note->pos)); - } - - // Finish the Index - index->nest_array = code_index_nest_ptr_array_from_list(&arena, &index->nest_list); - index->note_array = code_index_note_ptr_array_from_list(&arena, &index->note_list); - - code_index_lock(); - code_index_set_file(buffer_id, arena, index); - code_index_unlock(); - buffer_clear_layout_cache(app, buffer_id); - - tree_sitter_query_end(&query); + tree_sitter_code_index_update_single_buffer(app, modified_node->buffer); } buffer_modified_set_clear(); diff --git a/code/custom/4coder_tree_sitter.h b/code/custom/4coder_tree_sitter.h index 1b977c52..9611a85f 100644 --- a/code/custom/4coder_tree_sitter.h +++ b/code/custom/4coder_tree_sitter.h @@ -68,6 +68,7 @@ function void tree_sitter_register_language(String_Const_u8 ext, TSLanguage* lan b8 use_tree_sitter_code_indexing = true; b8 use_tree_sitter_token_coloring = true; +function void tree_sitter_code_index_update_single_buffer(Application_Links *app, Buffer_ID buffer_id); function void tree_sitter_code_index_update_tick(Application_Links *app); #endif //FCODER_TREE_SITTER_H