/////////////////////////////////////////////////////////////////////////// // 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); }