Parse delimiters before creating the nests tree
This commit is contained in:
parent
ee082e42d1
commit
1dfc106e8c
|
@ -6,6 +6,15 @@
|
|||
|
||||
global Code_Index global_code_index = {};
|
||||
|
||||
function bool
|
||||
delims_are_open_close_pair(Code_Index_Scope_Delim_Kind a, Code_Index_Scope_Delim_Kind b)
|
||||
{
|
||||
if (a == CodeIndexScopeDelim_ScopeOpen) return b == CodeIndexScopeDelim_ScopeClose;
|
||||
if (a == CodeIndexScopeDelim_ParenOpen) return b == CodeIndexScopeDelim_ParenClose;
|
||||
if (a == CodeIndexScopeDelim_BracketOpen) return b == CodeIndexScopeDelim_BracketClose;
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
// NOTE(allen): Lookups
|
||||
|
||||
|
@ -196,19 +205,26 @@ code_index_erase_file(Buffer_ID buffer){
|
|||
}
|
||||
}
|
||||
|
||||
function Code_Index_File*
|
||||
code_index_get_file(Buffer_ID buffer){
|
||||
Code_Index_File *result = 0;
|
||||
function Code_Index_File_Storage*
|
||||
code_index_get_file_storage(Buffer_ID buffer){
|
||||
Code_Index_File_Storage *result = 0;
|
||||
Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer);
|
||||
if (lookup.found_match){
|
||||
u64 val = 0;
|
||||
table_read(&global_code_index.buffer_to_index_file, lookup, &val);
|
||||
Code_Index_File_Storage *storage = (Code_Index_File_Storage*)IntAsPtr(val);
|
||||
result = storage->file;
|
||||
result = (Code_Index_File_Storage*)IntAsPtr(val);
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
function Code_Index_File*
|
||||
code_index_get_file(Buffer_ID buffer){
|
||||
Code_Index_File *result = 0;
|
||||
Code_Index_File_Storage *storage = code_index_get_file_storage(buffer);
|
||||
if (storage) result = storage->file;
|
||||
return result;
|
||||
}
|
||||
|
||||
function void
|
||||
index_shift(i64 *ptr, Range_i64 old_range, u64 new_size){
|
||||
i64 i = *ptr;
|
||||
|
|
|
@ -7,6 +7,35 @@
|
|||
#if !defined(FCODER_CODE_INDEX_H)
|
||||
#define FCODER_CODE_INDEX_H
|
||||
|
||||
typedef i32 Code_Index_Scope_Delim_Kind;
|
||||
enum {
|
||||
CodeIndexScopeDelim_ScopeOpen,
|
||||
CodeIndexScopeDelim_ScopeClose,
|
||||
CodeIndexScopeDelim_ParenOpen,
|
||||
CodeIndexScopeDelim_ParenClose,
|
||||
CodeIndexScopeDelim_BracketOpen,
|
||||
CodeIndexScopeDelim_BracketClose
|
||||
};
|
||||
|
||||
struct Code_Index_Scope_Delim {
|
||||
Code_Index_Scope_Delim_Kind kind;
|
||||
i32 depth;
|
||||
Range_i64 pos;
|
||||
|
||||
Code_Index_Scope_Delim* next;
|
||||
Code_Index_Scope_Delim* prev;
|
||||
};
|
||||
|
||||
struct Code_Index_Scope_Delim_List {
|
||||
Code_Index_Scope_Delim* first;
|
||||
Code_Index_Scope_Delim* last;
|
||||
};
|
||||
|
||||
struct Code_Index_Scope_Delim_Ptr_Array {
|
||||
Code_Index_Scope_Delim** ptrs;
|
||||
i32 count;
|
||||
};
|
||||
|
||||
struct Code_Index_Nest_List{
|
||||
struct Code_Index_Nest *first;
|
||||
struct Code_Index_Nest *last;
|
||||
|
@ -29,7 +58,10 @@ enum{
|
|||
struct Code_Index_Nest{
|
||||
Code_Index_Nest *next;
|
||||
|
||||
// TODO(PS): kind and delim are redundant, I don't want to break virtual indentation just yet
|
||||
// so Im leaving them both here.
|
||||
Code_Index_Nest_Kind kind;
|
||||
Code_Index_Scope_Delim_Kind delim;
|
||||
b32 is_closed;
|
||||
Range_i64 open;
|
||||
Range_i64 close;
|
||||
|
@ -73,6 +105,8 @@ struct Code_Index_Note_Ptr_Array{
|
|||
};
|
||||
|
||||
struct Code_Index_File{
|
||||
Code_Index_Scope_Delim_List scope_delim_list;
|
||||
Code_Index_Scope_Delim_Ptr_Array scope_delim_array;
|
||||
Code_Index_Nest_List nest_list;
|
||||
Code_Index_Nest_Ptr_Array nest_array;
|
||||
Code_Index_Note_List note_list;
|
||||
|
|
|
@ -410,40 +410,31 @@ tree_sitter_code_index_update_process_query_match(
|
|||
const char* tmp = ts_query_capture_name_for_id(state->query.query, type_capture.index, &length);
|
||||
String_Const_u8 capture_name = SCu8((char*)tmp, length);
|
||||
|
||||
if (string_match(capture_name, SCu8("scope_begin")))
|
||||
if (string_match(capture_name, SCu8("scope_begin")) || string_match(capture_name, SCu8("scope_end")))
|
||||
{
|
||||
Code_Index_Nest* nest = push_array_zero(&state->index_arena, Code_Index_Nest, 1);
|
||||
nest->kind = CodeIndexNest_Scope;
|
||||
nest->open = type_range;
|
||||
nest->close = Ii64(max_i64);
|
||||
nest->file = state->index;
|
||||
if (state->nest_stack_last != 0)
|
||||
Code_Index_Scope_Delim_Kind kind;
|
||||
String_Const_u8 delim_char = string_substring(state->buffer_contents, type_range);
|
||||
bool skip = false;
|
||||
if (delim_char.str[0] == '{') kind = CodeIndexScopeDelim_ScopeOpen;
|
||||
else if (delim_char.str[0] == '}') kind = CodeIndexScopeDelim_ScopeClose;
|
||||
else if (delim_char.str[0] == '(') kind = CodeIndexScopeDelim_ParenOpen;
|
||||
else if (delim_char.str[0] == ')') kind = CodeIndexScopeDelim_ParenClose;
|
||||
else if (delim_char.str[0] == '[') kind = CodeIndexScopeDelim_BracketOpen;
|
||||
else if (delim_char.str[0] == ']') kind = CodeIndexScopeDelim_BracketClose;
|
||||
else skip = true;
|
||||
|
||||
if (!skip)
|
||||
{
|
||||
nest->parent = state->nest_stack_last->nest;
|
||||
code_index_push_nest(&nest->parent->nest_list, nest);
|
||||
Code_Index_Scope_Delim* delim = push_array_zero(&state->index_arena, Code_Index_Scope_Delim, 1);
|
||||
delim->pos = type_range;
|
||||
delim->kind = kind;
|
||||
|
||||
Code_Index_Scope_Delim_List* list = &state->index->scope_delim_list;
|
||||
if (!list->first) list->first = delim;
|
||||
if (list->last) list->last->next = delim;
|
||||
delim->prev = list->last;
|
||||
list->last = delim;
|
||||
}
|
||||
|
||||
Code_Index_Nest_Stack* stack = push_array_zero(scratch, Code_Index_Nest_Stack, 1);
|
||||
stack->nest = nest;
|
||||
stack->prev = state->nest_stack_last;
|
||||
stack->match_id = query_match.id;
|
||||
if (state->nest_stack_last != 0) state->nest_stack_last->next = stack;
|
||||
else state->nest_stack_first = stack;
|
||||
state->nest_stack_last = stack;
|
||||
}
|
||||
else if (string_match(capture_name, SCu8("scope_end")))
|
||||
{
|
||||
Assert(state->nest_stack_last != 0);
|
||||
Assert(state->nest_stack_last->match_id == query_match.id);
|
||||
|
||||
Code_Index_Nest* nest = state->nest_stack_last->nest;
|
||||
nest->close = type_range;
|
||||
nest->is_closed = true;
|
||||
nest->nest_array = code_index_nest_ptr_array_from_list(&state->index_arena, &nest->nest_list);
|
||||
if (nest->parent == 0) code_index_push_nest(&state->index->nest_list, nest);
|
||||
|
||||
state->nest_stack_last = state->nest_stack_last->prev;
|
||||
if (state->nest_stack_last != 0) state->nest_stack_last->next = 0;
|
||||
}
|
||||
else if (string_match(capture_name, SCu8("definition.class")))
|
||||
{
|
||||
|
@ -477,16 +468,89 @@ tree_sitter_code_index_update_process_query_match(
|
|||
function void
|
||||
tree_sitter_code_index_update_complete(
|
||||
Application_Links* app,
|
||||
Tree_Sitter_Code_Index_Update_State* state
|
||||
Tree_Sitter_Code_Index_Update_State* state,
|
||||
Arena* scratch
|
||||
){
|
||||
tree_sitter_query_end(&state->query);
|
||||
if (state->ok)
|
||||
{
|
||||
Code_Index_Nest* free_nests = state->index->nest_list.first;
|
||||
state->index->nest_list.first = 0;
|
||||
state->index->nest_list.last = 0;
|
||||
|
||||
Code_Index_Scope_Delim* delim_at = state->index->scope_delim_list.first;
|
||||
while (delim_at != 0)
|
||||
{
|
||||
bool is_open = (
|
||||
delim_at->kind == CodeIndexScopeDelim_ScopeOpen ||
|
||||
delim_at->kind == CodeIndexScopeDelim_ParenOpen ||
|
||||
delim_at->kind == CodeIndexScopeDelim_BracketOpen
|
||||
);
|
||||
if (is_open)
|
||||
{
|
||||
if (!free_nests)
|
||||
{
|
||||
int count = 32;
|
||||
free_nests = push_array_zero(&state->index_arena, Code_Index_Nest, count);
|
||||
for (int i = 0; i < count-2; i++)
|
||||
{
|
||||
free_nests[i].next = &free_nests[i+1];
|
||||
}
|
||||
}
|
||||
|
||||
Code_Index_Nest* nest = free_nests;
|
||||
if (nest->nest_list.first)
|
||||
{
|
||||
nest->nest_list.last->next = free_nests;
|
||||
free_nests = nest->nest_list.first;
|
||||
}
|
||||
else
|
||||
{
|
||||
free_nests = nest->next;
|
||||
}
|
||||
|
||||
nest->kind = CodeIndexNest_Scope;
|
||||
nest->delim = delim_at->kind;
|
||||
nest->open = delim_at->pos;
|
||||
nest->close = Ii64(max_i64);
|
||||
nest->file = state->index;
|
||||
if (state->nest_stack_last != 0)
|
||||
{
|
||||
nest->parent = state->nest_stack_last->nest;
|
||||
code_index_push_nest(&nest->parent->nest_list, nest);
|
||||
}
|
||||
else
|
||||
{
|
||||
code_index_push_nest(&state->index->nest_list, nest);
|
||||
}
|
||||
|
||||
Code_Index_Nest_Stack* stack = push_array_zero(scratch, Code_Index_Nest_Stack, 1);
|
||||
stack->nest = nest;
|
||||
stack->prev = state->nest_stack_last;
|
||||
if (state->nest_stack_last != 0) state->nest_stack_last->next = stack;
|
||||
else state->nest_stack_first = stack;
|
||||
state->nest_stack_last = stack;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state->nest_stack_last != 0 && delims_are_open_close_pair(state->nest_stack_last->nest->delim, delim_at->kind))
|
||||
{
|
||||
Code_Index_Nest* nest = state->nest_stack_last->nest;
|
||||
nest->close = delim_at->pos;
|
||||
nest->is_closed = true;
|
||||
nest->nest_array = code_index_nest_ptr_array_from_list(&state->index_arena, &nest->nest_list);
|
||||
|
||||
state->nest_stack_last = state->nest_stack_last->prev;
|
||||
if (state->nest_stack_last != 0) state->nest_stack_last->next = 0;
|
||||
}
|
||||
}
|
||||
|
||||
delim_at = delim_at->next;
|
||||
}
|
||||
|
||||
while (state->nest_stack_last != 0)
|
||||
{
|
||||
Code_Index_Nest* nest = state->nest_stack_last->nest;
|
||||
if (nest->parent != 0) code_index_push_nest(&nest->parent->nest_list, nest);
|
||||
else code_index_push_nest(&state->index->nest_list, nest);
|
||||
nest->nest_array = code_index_nest_ptr_array_from_list(&state->index_arena, &nest->nest_list);
|
||||
state->nest_stack_last = state->nest_stack_last->prev;
|
||||
}
|
||||
|
@ -500,7 +564,6 @@ tree_sitter_code_index_update_complete(
|
|||
state->index->nest_array = code_index_nest_ptr_array_from_list(&state->index_arena, &state->index->nest_list);
|
||||
state->index->note_array = code_index_note_ptr_array_from_list(&state->index_arena, &state->index->note_list);
|
||||
|
||||
|
||||
code_index_lock();
|
||||
code_index_set_file(state->buffer_id, state->index_arena, state->index);
|
||||
code_index_unlock();
|
||||
|
@ -513,36 +576,6 @@ tree_sitter_code_index_update_complete(
|
|||
}
|
||||
}
|
||||
|
||||
function Tree_Sitter_Code_Index_Update_State
|
||||
tree_sitter_code_index_update_full_file_async(Async_Context* actx, Buffer_ID buffer_id)
|
||||
{
|
||||
Application_Links* app = actx->app;
|
||||
Scratch_Block scratch(app);
|
||||
|
||||
acquire_global_frame_mutex(app);
|
||||
Tree_Sitter_Code_Index_Update_State state = tree_sitter_code_index_update_state_create(
|
||||
app,
|
||||
buffer_id,
|
||||
scratch
|
||||
);
|
||||
release_global_frame_mutex(app);
|
||||
|
||||
TSQueryMatch query_match;
|
||||
u32 capture_index;
|
||||
while (state.ok && tree_sitter_query_continue(&state.query, &query_match, &capture_index))
|
||||
{
|
||||
tree_sitter_code_index_update_process_query_match(&state, query_match, capture_index, scratch);
|
||||
if (async_check_canceled(actx))
|
||||
{
|
||||
state.ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tree_sitter_code_index_update_complete(app, &state);
|
||||
return state;
|
||||
}
|
||||
|
||||
function Tree_Sitter_Code_Index_Update_State
|
||||
tree_sitter_code_index_update_full_file(Application_Links* app, Buffer_ID buffer_id)
|
||||
{
|
||||
|
@ -566,7 +599,7 @@ tree_sitter_code_index_update_full_file(Application_Links* app, Buffer_ID buffer
|
|||
);
|
||||
}
|
||||
|
||||
tree_sitter_code_index_update_complete(app, &state);
|
||||
tree_sitter_code_index_update_complete(app, &state, scratch);
|
||||
return state;
|
||||
}
|
||||
|
||||
|
@ -575,9 +608,72 @@ tree_sitter_code_index_update_async(Async_Context* actx, String_Const_u8 data)
|
|||
{
|
||||
if (data.size != sizeof(Buffer_ID)) return;
|
||||
Buffer_ID buffer_id = *(Buffer_ID*)data.str;
|
||||
tree_sitter_code_index_update_full_file_async(actx, buffer_id);
|
||||
Application_Links* app = actx->app;
|
||||
Scratch_Block scratch(app);
|
||||
|
||||
acquire_global_frame_mutex(app);
|
||||
Tree_Sitter_Code_Index_Update_State state = tree_sitter_code_index_update_state_create(
|
||||
app,
|
||||
buffer_id,
|
||||
scratch
|
||||
);
|
||||
release_global_frame_mutex(app);
|
||||
|
||||
TSQueryMatch query_match;
|
||||
u32 capture_index;
|
||||
while (state.ok && tree_sitter_query_continue(&state.query, &query_match, &capture_index))
|
||||
{
|
||||
tree_sitter_code_index_update_process_query_match(&state, query_match, capture_index, scratch);
|
||||
if (async_check_canceled(actx))
|
||||
{
|
||||
state.ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tree_sitter_code_index_update_complete(app, &state, scratch);
|
||||
}
|
||||
|
||||
/*
|
||||
function void
|
||||
tree_sitter_code_index_update_incremental(Application_Links* app, Buffer_ID buffer_id)
|
||||
{
|
||||
// TODO(PS): @Collapse with tree_sitter_code_index_update_state_create
|
||||
Tree_Sitter_Code_Index_Update_State state = {};
|
||||
state.ok = false;
|
||||
state.buffer_id = buffer_id;
|
||||
state.language = tree_sitter_language_for_buffer(app, state.buffer_id);
|
||||
if (!state.language) return state;
|
||||
|
||||
Code_Index_File_Storage* storage = code_index_get_file_storage(state.buffer_id);
|
||||
state.index_arena = storage->arena;
|
||||
state.index = storage->file;
|
||||
state.buffer_contents = push_whole_buffer(app, scratch, state.buffer_id);
|
||||
state.query = tree_sitter_query_init(
|
||||
app, state.buffer_id, state.language->queries.ptr[Tree_Sitter_Language_Query_Tags]
|
||||
);
|
||||
state.nest_stack_first = 0;
|
||||
state.nest_stack_last = 0;
|
||||
state.last_note = 0;
|
||||
state.last_note_match_id = max_u32;
|
||||
state.ok = true;
|
||||
|
||||
TSQueryMatch query_match;
|
||||
u32 capture_index;
|
||||
while (state.ok && tree_sitter_query_continue(&state.query, &query_match, &capture_index))
|
||||
{
|
||||
tree_sitter_code_index_update_process_query_match(
|
||||
&state,
|
||||
query_match,
|
||||
capture_index,
|
||||
scratch
|
||||
);
|
||||
}
|
||||
|
||||
tree_sitter_code_index_update_complete(app, &state, scratch);
|
||||
}
|
||||
*/
|
||||
|
||||
function void
|
||||
tree_sitter_code_index_update_tick(Application_Links* app)
|
||||
{
|
||||
|
@ -591,7 +687,11 @@ tree_sitter_code_index_update_tick(Application_Links* app)
|
|||
Buffer_Tree_Sitter_Data* tree_data = scope_attachment(app, buffer_scope, buffer_tree_sitter_data_id, Buffer_Tree_Sitter_Data);
|
||||
if (!tree_data || !tree_data->tree) continue;
|
||||
|
||||
#if 1
|
||||
tree_sitter_code_index_update_full_file(app, buffer_id);
|
||||
#else
|
||||
tree_sitter_code_index_update_incremental(app, buffer_id);
|
||||
#endif
|
||||
}
|
||||
buffer_modified_set_clear();
|
||||
}
|
||||
|
@ -658,6 +758,19 @@ draw_tree_sitter_node_colors(Application_Links* app, Text_Layout_ID text_layout_
|
|||
if (!lang) return;
|
||||
TSQuery* query = lang->queries.ptr[Tree_Sitter_Language_Query_Highlights];
|
||||
|
||||
Managed_ID color_id = managed_id_get(app, SCu8("colors"), SCu8("defcolor_str_constant"));
|
||||
Code_Index_File* file = code_index_get_file(buffer_id);
|
||||
if (file != 0)
|
||||
{
|
||||
Code_Index_Scope_Delim* delim = file->scope_delim_list.first;
|
||||
while (delim != 0)
|
||||
{
|
||||
paint_text_color_fcolor(app, text_layout_id, delim->pos, fcolor_id(color_id));
|
||||
if (delim->next == delim) break;
|
||||
delim = delim->next;
|
||||
}
|
||||
}
|
||||
|
||||
Range_i64 visible_range = text_layout_get_visible_range(app, text_layout_id);
|
||||
Managed_Scope buffer_scope = buffer_get_managed_scope(app, buffer_id);
|
||||
Buffer_Tree_Sitter_Data* tree_data = scope_attachment(app, buffer_scope, buffer_tree_sitter_data_id, Buffer_Tree_Sitter_Data);
|
||||
|
|
|
@ -21,9 +21,16 @@ String_Const_u8 TS_CPP_TAGS_QUERY_SCM = string_u8_litexpr(R"DONE(
|
|||
|
||||
(class_specifier name: (type_identifier) @name) @definition.class
|
||||
|
||||
(_ "{" @scope_begin "}" @scope_end )
|
||||
(_ "(" @scope_begin ")" @scope_end )
|
||||
(_ "[" @scope_begin "]" @scope_end )
|
||||
"{" @scope_begin
|
||||
"(" @scope_begin
|
||||
"[" @scope_begin
|
||||
"}" @scope_end
|
||||
")" @scope_end
|
||||
"]" @scope_end
|
||||
|
||||
; (_ "{" @scope_begin "}" @scope_end )
|
||||
; (_ "(" @scope_begin ")" @scope_end )
|
||||
; (_ "[" @scope_begin "]" @scope_end )
|
||||
|
||||
)DONE");
|
||||
|
||||
|
|
Loading…
Reference in New Issue