4coder code index usability patch: function prototypes as separate note kind & full function signature in lister
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
////////////////////////////////////// | |
// 4coder_code_index.h | |
////////////////////////////////////// | |
/* There are new fields in these two enums/structures */ | |
typedef i64 Code_Index_Note_Kind; | |
enum{ | |
CodeIndexNote_Type, | |
CodeIndexNote_Function, | |
CodeIndexNote_Macro, | |
CodeIndexNote_4coderCommand, | |
CodeIndexNote_FunctionPrototype, /* <---- this is new */ | |
}; | |
struct Code_Index_Note{ | |
Code_Index_Note *next; | |
Code_Index_Note_Kind note_kind; | |
Range_i64 pos; | |
String_Const_u8 text; | |
struct Code_Index_File *file; | |
Code_Index_Nest *parent; | |
Code_Index_Note *prev_in_hash; | |
Code_Index_Note *next_in_hash; | |
String_Const_u8 verbose_text; /* <---- this is new */ | |
}; | |
////////////////////////////////////// | |
// 4coder_code_index.cpp | |
////////////////////////////////////// | |
/* modified index_new_note accepts "verbose_range" */ | |
function Code_Index_Note* | |
index_new_note(Code_Index_File *index, Generic_Parse_State *state, Range_i64 range, Code_Index_Note_Kind kind, Code_Index_Nest *parent, Range_i64 verbose_range){ | |
Code_Index_Note *result = push_array(state->arena, Code_Index_Note, 1); | |
sll_queue_push(index->note_list.first, index->note_list.last, result); | |
index->note_list.count += 1; | |
result->note_kind = kind; | |
result->pos = range; | |
result->text = push_string_copy(state->arena, string_substring(state->contents, range)); | |
/******** New from here *******/ | |
if (verbose_range.end - verbose_range.start) { | |
result->verbose_text = push_string_copy(state->arena, string_substring(state->contents, verbose_range)); | |
/* normalize whitespaces */ | |
String_Const_u8 normalized_text = push_string_copy(state->arena, result->verbose_text); | |
u32 norm_size = 0; | |
bool last_char_was_space = false; | |
for (u32 i = 0; i < result->verbose_text.size; ++i) { | |
u8 c = result->verbose_text.str[i]; | |
if (c == '\n' || c == '\t' || c == '\r' || c == ' ') { | |
if (!last_char_was_space) normalized_text.str[norm_size++] = ' '; | |
last_char_was_space = true; | |
continue; | |
} | |
normalized_text.str[norm_size++] = c; | |
last_char_was_space = false; | |
} | |
normalized_text.size = norm_size; | |
result->verbose_text = normalized_text; | |
} else { | |
result->verbose_text = result->text; | |
} | |
/******** To here *******/ | |
result->file = index; | |
result->parent = parent; | |
return(result); | |
} | |
/* modified cpp_parse function passes the verbose_range to index_new_note as well as switches on the closing token */ | |
function void | |
cpp_parse_function(Code_Index_File *index, Generic_Parse_State *state, Code_Index_Nest *parent){ | |
Token *token = token_it_read(&state->it); | |
generic_parse_inc(state); | |
generic_parse_skip_soft_tokens(index, state); | |
if (state->finished){ | |
return; | |
} | |
Token *peek = token_it_read(&state->it); | |
Token *reset_point = peek; | |
if (peek != 0 && peek->sub_kind == TokenCppKind_ParenOp){ | |
b32 at_paren_close = false; | |
i32 paren_nest_level = 0; | |
for (; peek != 0;){ | |
generic_parse_inc(state); | |
generic_parse_skip_soft_tokens(index, state); | |
peek = token_it_read(&state->it); | |
if (peek == 0 || state->finished){ | |
break; | |
} | |
if (peek->kind == TokenBaseKind_ParentheticalOpen){ | |
paren_nest_level += 1; | |
} | |
else if (peek->kind == TokenBaseKind_ParentheticalClose){ | |
if (paren_nest_level > 0){ | |
paren_nest_level -= 1; | |
} | |
else{ | |
at_paren_close = true; | |
break; | |
} | |
} | |
} | |
if (at_paren_close){ | |
/******** Only changes are here *******/ | |
i64 definition_start = token->pos; | |
i64 definition_end = peek->pos + peek->size; | |
generic_parse_inc(state); | |
generic_parse_skip_soft_tokens(index, state); | |
peek = token_it_read(&state->it); | |
if (peek) { | |
if (peek->kind == TokenBaseKind_ScopeOpen) { | |
index_new_note(index, state, Ii64(token), CodeIndexNote_Function, parent, Ii64(definition_start, definition_end)); | |
} else if (peek->kind == TokenBaseKind_StatementClose) { | |
index_new_note(index, state, Ii64(token), CodeIndexNote_FunctionPrototype, parent, Ii64(definition_start, definition_end)); | |
} | |
} | |
} | |
} | |
state->it = token_iterator(state->it.user_id, state->it.tokens, state->it.count, reset_point); | |
} | |
////////////////////////////////////// | |
// 4coder_code_index_listers.cpp | |
////////////////////////////////////// | |
CUSTOM_UI_COMMAND_SIG(jump_to_definition) | |
CUSTOM_DOC("List all definitions in the code index and jump to one chosen by the user.") | |
{ | |
char *query = "Definition:"; | |
Scratch_Block scratch(app); | |
Lister_Block lister(app, scratch); | |
lister_set_query(lister, query); | |
lister_set_default_handlers(lister); | |
code_index_lock(); | |
for (Buffer_ID buffer = get_buffer_next(app, 0, Access_Always); | |
buffer != 0; | |
buffer = get_buffer_next(app, buffer, Access_Always)){ | |
Code_Index_File *file = code_index_get_file(buffer); | |
if (file != 0){ | |
for (i32 i = 0; i < file->note_array.count; i += 1){ | |
Code_Index_Note *note = file->note_array.ptrs[i]; | |
Tiny_Jump *jump = push_array(scratch, Tiny_Jump, 1); | |
jump->buffer = buffer; | |
jump->pos = note->pos.first; | |
String_Const_u8 sort = {}; | |
switch (note->note_kind){ | |
case CodeIndexNote_Type: | |
{ | |
sort = string_u8_litexpr("type"); | |
}break; | |
case CodeIndexNote_Function: | |
{ | |
sort = string_u8_litexpr("function"); | |
}break; | |
case CodeIndexNote_Macro: | |
{ | |
sort = string_u8_litexpr("macro"); | |
}break; | |
case CodeIndexNote_FunctionPrototype: /* <------- new case here */ | |
{ | |
sort = string_u8_litexpr("prototype"); | |
}break; | |
} | |
lister_add_item(lister, note->verbose_text, sort, jump, 0); /* <------- verbose_text here */ | |
} | |
} | |
} | |
code_index_unlock(); | |
Lister_Result l_result = run_lister(app, lister); | |
Tiny_Jump result = {}; | |
if (!l_result.canceled && l_result.user_data != 0){ | |
block_copy_struct(&result, (Tiny_Jump*)l_result.user_data); | |
} | |
if (result.buffer != 0){ | |
View_ID view = get_this_ctx_view(app, Access_Always); | |
point_stack_push_view_cursor(app, view); | |
jump_to_location(app, view, result.buffer, result.pos); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment