Skip to content

Instantly share code, notes, and snippets.

@aolo2
Created Aug 12, 2021
Embed
What would you like to do?
4coder code index usability patch: function prototypes as separate note kind & full function signature in lister
//////////////////////////////////////
// 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