4coder/code/custom/4coder_custom_hooks.cpp

193 lines
7.2 KiB
C++

///////////////////////////////////////////////////////////////////////////
// Begin Buffer
///////////////////////////////////////////////////////////////////////////
struct File_Language_Result
{
File_Language_Kind kind;
bool treat_as_code;
};
function File_Language_Result
identify_file_language(Application_Links* app, Buffer_ID buffer_id)
{
Scratch_Block scratch(app);
File_Language_Result result;
block_zero_struct(&result);
String_Const_u8 file_name = push_buffer_file_name(app, scratch, buffer_id);
if (file_name.size <= 0) return result;
String_Const_u8 file_extension = string_file_extension(file_name);
result.kind = File_Language_Text;
String_Const_u8 treat_as_code_string = def_get_config_string(scratch, vars_save_string_lit("treat_as_code"));
String_Const_u8_Array extensions_to_treat_as_code = parse_extension_line_to_extension_list(app, scratch, treat_as_code_string);
for (i32 i = 0; i < extensions_to_treat_as_code.count; ++i)
{
if (string_match(file_extension, extensions_to_treat_as_code.strings[i]))
{
result.treat_as_code = true;
result.kind = File_Language_Unknown;
if (string_match(file_extension, string_u8_litexpr("md")))
{
print_message(app, SCu8("Language Detected as Markdown\n"));
result.kind = File_Language_Markdown;
}
else if (string_match(file_extension, string_u8_litexpr("c")))
{
print_message(app, SCu8("Language Detected as C\n"));
result.kind = File_Language_CPP;
}
else if (string_match(file_extension, string_u8_litexpr("cpp")) ||
string_match(file_extension, string_u8_litexpr("h")) ||
string_match(file_extension, string_u8_litexpr("hpp")) ||
string_match(file_extension, string_u8_litexpr("cc"))
){
print_message(app, SCu8("Language Detected as Cpp\n"));
result.kind = File_Language_CPP;
}
else if (string_match(file_extension, string_u8_litexpr("m"))){
print_message(app, SCu8("Language Detected as ObjectiveC\n"));
result.kind = File_Language_ObjectiveC;
}
else if (string_match(file_extension, string_u8_litexpr("hlsl"))){
print_message(app, SCu8("Language Detected as HLSL\n"));
result.kind = File_Language_HLSL;
}
else if (string_match(file_extension, string_u8_litexpr("glsl"))){
print_message(app, SCu8("Language Detected as GLSL\n"));
result.kind = File_Language_GLSL;
}
else if (string_match(file_extension, string_u8_litexpr("jai"))){
print_message(app, SCu8("Language Detected as Jai\n"));
result.kind = File_Language_Jai;
}
else if (string_match(file_extension, string_u8_litexpr("cs"))){
print_message(app, SCu8("Language Detected as C#\n"));
result.kind = File_Language_CSharp;
}
else if (string_match(file_extension, string_u8_litexpr("swift"))){
print_message(app, SCu8("Language Detected as Swift\n"));
result.kind = File_Language_Swift;
}
else if (string_match(file_extension, string_u8_litexpr("go"))){
print_message(app, SCu8("Language Detected as Go\n"));
result.kind = File_Language_Go;
}
else if (string_match(file_extension, string_u8_litexpr("rs"))){
print_message(app, SCu8("Language Detected as Rust\n"));
result.kind = File_Language_Rust;
}
else if (string_match(file_extension, string_u8_litexpr("js"))){
print_message(app, SCu8("Language Detected as Javascript\n"));
result.kind = File_Language_Javascript;
}
else if (string_match(file_extension, string_u8_litexpr("ts"))){
print_message(app, SCu8("Language Detected as Typescript\n"));
result.kind = File_Language_Typescript;
}
else if (string_match(file_extension, string_u8_litexpr("json"))){
print_message(app, SCu8("Language Detected as JSON\n"));
result.kind = File_Language_JSON;
}
else if (string_match(file_extension, string_u8_litexpr("odin"))){
print_message(app, SCu8("Language Detected as Odin\n"));
result.kind = File_Language_Odin;
}
else if (string_match(file_extension, string_u8_litexpr("zig"))){
print_message(app, SCu8("Language Detected as Zig\n"));
result.kind = File_Language_Zig;
}
if (result.kind != File_Language_Unknown) break;
}
}
return result;
}
BUFFER_HOOK_SIG(custom_begin_buffer){
ProfileScope(app, "begin buffer");
Scratch_Block scratch(app);
File_Language_Result lang = identify_file_language(app, buffer_id);
bool begin_parse_task = false;
if (lang.treat_as_code) begin_parse_task = tree_sitter_begin_buffer(app, buffer_id, lang.kind);
String_ID file_map_id = vars_save_string_lit("keys_file");
String_ID code_map_id = vars_save_string_lit("keys_code");
Command_Map_ID map_id = (lang.treat_as_code)?(code_map_id):(file_map_id);
Managed_Scope scope = buffer_get_managed_scope(app, buffer_id);
Command_Map_ID *map_id_ptr = scope_attachment(app, scope, buffer_map_id, Command_Map_ID);
*map_id_ptr = map_id;
Line_Ending_Kind setting = guess_line_ending_kind_from_buffer(app, buffer_id);
Line_Ending_Kind *eol_setting = scope_attachment(app, scope, buffer_eol_setting, Line_Ending_Kind);
*eol_setting = setting;
// NOTE(allen): Decide buffer settings
b32 wrap_lines = true;
b32 use_lexer = false;
if (lang.treat_as_code){
wrap_lines = def_get_config_b32(vars_save_string_lit("enable_code_wrapping"));
// TODO(PS): @Remove - consider removing the lexer for now? later, replace in favor of tree-sitter
use_lexer = true;
}
if (begin_parse_task)
{
Async_Task* parse_task = scope_attachment(app, scope, buffer_tree_sitter_parse_task_id, Async_Task);
*parse_task = async_task_no_dep(&global_async_system, tree_sitter_parse_async, make_data_struct(&buffer_id));
}
String_Const_u8 buffer_name = push_buffer_base_name(app, scratch, buffer_id);
if (buffer_name.size > 0 && buffer_name.str[0] == '*' && buffer_name.str[buffer_name.size - 1] == '*'){
wrap_lines = def_get_config_b32(vars_save_string_lit("enable_output_wrapping"));
}
if (use_lexer){
ProfileBlock(app, "begin buffer kick off lexer");
Async_Task *lex_task_ptr = scope_attachment(app, scope, buffer_lex_task, Async_Task);
*lex_task_ptr = async_task_no_dep(&global_async_system, do_full_lex_async, make_data_struct(&buffer_id));
}
{
b32 *wrap_lines_ptr = scope_attachment(app, scope, buffer_wrap_lines, b32);
*wrap_lines_ptr = wrap_lines;
}
if (use_lexer){
buffer_set_layout(app, buffer_id, layout_virt_indent_index_generic);
}
else{
if (lang.treat_as_code){
buffer_set_layout(app, buffer_id, layout_virt_indent_literal_generic);
}
else{
buffer_set_layout(app, buffer_id, layout_generic);
}
}
// no meaning for return
return(0);
}
///////////////////////////////////////////////////////////////////////////
// End Buffer
///////////////////////////////////////////////////////////////////////////
BUFFER_HOOK_SIG(custom_end_buffer){
Marker_List *list = get_marker_list_for_buffer(buffer_id);
if (list != 0) delete_marker_list(list);
tree_sitter_end_buffer(app, buffer_id);
default_end_buffer(app, buffer_id);
return(0);
}