2017-01-29 00:03:23 +00:00
/*
2017-11-09 18:30:24 +00:00
4 coder_project_commands . cpp - commands for loading and using a project .
2017-01-29 00:03:23 +00:00
*/
2018-05-08 07:14:23 +00:00
// TOP
2017-01-29 00:03:23 +00:00
2021-01-09 05:20:39 +00:00
////////////////////////////////
// NOTE(allen): File Pattern Operators
2021-01-09 07:06:55 +00:00
function Prj_Pattern_List
2021-01-09 05:20:39 +00:00
prj_pattern_list_from_extension_array ( Arena * arena , String8Array list ) {
2021-01-09 07:06:55 +00:00
Prj_Pattern_List result = { } ;
2020-12-05 20:32:56 +00:00
for ( i32 i = 0 ;
i < list . count ;
+ + i ) {
2021-01-09 07:06:55 +00:00
Prj_Pattern_Node * node = push_array ( arena , Prj_Pattern_Node , 1 ) ;
2021-01-01 23:33:03 +00:00
sll_queue_push ( result . first , result . last , node ) ;
result . count + = 1 ;
2021-01-09 05:20:39 +00:00
String8 str = push_stringf ( arena , " *.%.*s " , string_expand ( list . vals [ i ] ) ) ;
2021-01-01 23:33:03 +00:00
node - > pattern . absolutes = string_split_wildcards ( arena , str ) ;
2018-05-08 07:14:23 +00:00
}
2021-01-01 23:33:03 +00:00
return ( result ) ;
}
2021-01-09 07:06:55 +00:00
function Prj_Pattern_List
2021-01-01 23:33:03 +00:00
prj_pattern_list_from_var ( Arena * arena , Variable_Handle var ) {
2021-01-09 07:06:55 +00:00
Prj_Pattern_List result = { } ;
2021-01-01 23:33:03 +00:00
for ( Vars_Children ( child_var , var ) ) {
2021-01-09 07:06:55 +00:00
Prj_Pattern_Node * node = push_array ( arena , Prj_Pattern_Node , 1 ) ;
2021-01-01 23:33:03 +00:00
sll_queue_push ( result . first , result . last , node ) ;
result . count + = 1 ;
2021-01-09 05:20:39 +00:00
String8 str = vars_string_from_var ( arena , child_var ) ;
2021-01-01 23:33:03 +00:00
node - > pattern . absolutes = string_split_wildcards ( arena , str ) ;
}
return ( result ) ;
2018-05-09 05:22:33 +00:00
}
2021-01-09 07:06:55 +00:00
function Prj_Pattern_List
2021-01-07 08:41:04 +00:00
prj_get_standard_blacklist ( Arena * arena ) {
2021-01-09 05:20:39 +00:00
String8 dot = string_u8_litexpr ( " .* " ) ;
String8Array black_array = { } ;
2021-01-07 08:41:04 +00:00
black_array . strings = & dot ;
black_array . count = 1 ;
return ( prj_pattern_list_from_extension_array ( arena , black_array ) ) ;
}
function b32
2021-01-09 07:06:55 +00:00
prj_match_in_pattern_list ( String8 string , Prj_Pattern_List list ) {
2021-01-07 08:41:04 +00:00
b32 found_match = false ;
2021-01-09 07:06:55 +00:00
for ( Prj_Pattern_Node * node = list . first ;
2021-01-07 08:41:04 +00:00
node ! = 0 ;
node = node - > next ) {
if ( string_wildcard_match ( node - > pattern . absolutes , string , StringMatch_Exact ) ) {
found_match = true ;
break ;
}
}
return ( found_match ) ;
}
2018-05-09 05:22:33 +00:00
2019-10-25 06:17:54 +00:00
function void
2021-01-09 05:20:39 +00:00
prj_close_files_with_ext ( Application_Links * app , String8Array extension_array ) {
2019-06-01 23:33:31 +00:00
Scratch_Block scratch ( app ) ;
2017-01-29 00:03:23 +00:00
2019-06-01 23:33:31 +00:00
i32 buffers_to_close_max = Thousand ( 100 ) ;
Buffer_ID * buffers_to_close = push_array ( scratch , Buffer_ID , buffers_to_close_max ) ;
2018-05-09 05:22:33 +00:00
2019-04-05 02:03:36 +00:00
b32 do_repeat = false ;
2018-05-09 05:22:33 +00:00
do {
2019-06-01 23:33:31 +00:00
i32 buffers_to_close_count = 0 ;
2019-04-05 02:03:36 +00:00
do_repeat = false ;
2018-05-09 05:22:33 +00:00
2019-10-18 02:54:02 +00:00
for ( Buffer_ID buffer = get_buffer_next ( app , 0 , Access_Always ) ;
2019-04-05 02:03:36 +00:00
buffer ! = 0 ;
2019-10-18 02:54:02 +00:00
buffer = get_buffer_next ( app , buffer , Access_Always ) ) {
2019-04-05 02:03:36 +00:00
b32 is_match = true ;
2018-05-09 05:22:33 +00:00
if ( extension_array . count > 0 ) {
2019-06-01 23:33:31 +00:00
Temp_Memory name_temp = begin_temp ( scratch ) ;
2021-01-09 05:20:39 +00:00
String8 file_name = push_buffer_file_name ( app , scratch , buffer ) ;
2019-04-05 02:03:36 +00:00
is_match = false ;
if ( file_name . size > 0 ) {
2021-01-09 05:20:39 +00:00
String8 extension = string_file_extension ( file_name ) ;
2019-02-26 23:08:42 +00:00
for ( i32 i = 0 ; i < extension_array . count ; + + i ) {
2019-06-01 23:33:31 +00:00
if ( string_match ( extension , extension_array . strings [ i ] ) ) {
2019-04-05 02:03:36 +00:00
is_match = true ;
2018-05-09 05:22:33 +00:00
break ;
}
}
}
2019-06-01 23:33:31 +00:00
end_temp ( name_temp ) ;
2018-05-09 05:22:33 +00:00
}
if ( is_match ) {
if ( buffers_to_close_count > = buffers_to_close_max ) {
2019-04-05 02:03:36 +00:00
do_repeat = true ;
2018-05-09 05:22:33 +00:00
break ;
}
2019-04-05 02:03:36 +00:00
buffers_to_close [ buffers_to_close_count + + ] = buffer ;
2018-05-09 05:22:33 +00:00
}
2017-01-29 00:03:23 +00:00
}
2019-02-26 23:08:42 +00:00
for ( i32 i = 0 ; i < buffers_to_close_count ; + + i ) {
2019-06-19 02:31:59 +00:00
buffer_kill ( app , buffers_to_close [ i ] , BufferKill_AlwaysKill ) ;
2017-01-29 00:03:23 +00:00
}
2018-05-09 05:22:33 +00:00
} while ( do_repeat ) ;
2017-01-29 00:03:23 +00:00
}
2021-01-07 08:41:04 +00:00
function void
2021-01-09 07:06:55 +00:00
prj_open_files_pattern_filter__rec ( Application_Links * app , String8 path , Prj_Pattern_List whitelist , Prj_Pattern_List blacklist , Prj_Open_File_Flags flags ) {
2019-06-01 23:33:31 +00:00
Scratch_Block scratch ( app ) ;
2019-10-25 06:17:54 +00:00
2019-10-26 20:48:50 +00:00
ProfileScopeNamed ( app , " get file list " , profile_get_file_list ) ;
2019-10-08 01:42:23 +00:00
File_List list = system_get_file_list ( scratch , path ) ;
2019-10-26 20:48:50 +00:00
ProfileCloseNow ( profile_get_file_list ) ;
2018-05-09 05:22:33 +00:00
2019-08-04 00:49:40 +00:00
File_Info * * info = list . infos ;
2019-02-26 23:08:42 +00:00
for ( u32 i = 0 ; i < list . count ; + + i , + + info ) {
2021-01-09 05:20:39 +00:00
String8 file_name = ( * * info ) . file_name ;
2019-08-04 00:49:40 +00:00
if ( HasFlag ( ( * * info ) . attributes . flags , FileAttribute_IsDirectory ) ) {
2021-01-09 05:20:39 +00:00
if ( ( flags & PrjOpenFileFlag_Recursive ) = = 0 ) {
2021-01-01 23:33:03 +00:00
continue ;
}
2021-01-07 08:41:04 +00:00
if ( prj_match_in_pattern_list ( file_name , blacklist ) ) {
2021-01-01 23:33:03 +00:00
continue ;
}
2021-01-09 05:20:39 +00:00
String8 new_path = push_u8_stringf ( scratch , " %.*s%.*s/ " , string_expand ( path ) , string_expand ( file_name ) ) ;
2021-01-07 08:41:04 +00:00
prj_open_files_pattern_filter__rec ( app , new_path , whitelist , blacklist , flags ) ;
2018-05-09 05:22:33 +00:00
}
else {
2021-01-07 08:41:04 +00:00
if ( ! prj_match_in_pattern_list ( file_name , whitelist ) ) {
2018-05-26 07:49:37 +00:00
continue ;
2018-05-09 05:22:33 +00:00
}
2021-01-07 08:41:04 +00:00
if ( prj_match_in_pattern_list ( file_name , blacklist ) ) {
2018-05-26 07:49:37 +00:00
continue ;
2018-05-09 05:22:33 +00:00
}
2021-01-09 05:20:39 +00:00
String8 full_path = push_u8_stringf ( scratch , " %.*s%.*s " , string_expand ( path ) , string_expand ( file_name ) ) ;
2019-06-19 02:31:59 +00:00
create_buffer ( app , full_path , 0 ) ;
2017-01-29 00:03:23 +00:00
}
}
}
2019-10-25 06:17:54 +00:00
function void
2021-01-09 07:06:55 +00:00
prj_open_files_pattern_filter ( Application_Links * app , String8 dir , Prj_Pattern_List whitelist , Prj_Pattern_List blacklist , Prj_Open_File_Flags flags ) {
2019-10-22 07:15:49 +00:00
ProfileScope ( app , " open all files in directory pattern " ) ;
2019-06-01 23:33:31 +00:00
Scratch_Block scratch ( app ) ;
2021-01-09 05:20:39 +00:00
String8 directory = dir ;
2019-06-01 23:33:31 +00:00
if ( ! character_is_slash ( string_get_character ( directory , directory . size - 1 ) ) ) {
2019-06-18 22:56:09 +00:00
directory = push_u8_stringf ( scratch , " %.*s/ " , string_expand ( dir ) ) ;
2018-05-30 07:58:22 +00:00
}
2021-01-07 08:41:04 +00:00
prj_open_files_pattern_filter__rec ( app , directory , whitelist , blacklist , flags ) ;
2018-05-09 05:22:33 +00:00
}
2019-10-25 06:17:54 +00:00
function void
2021-01-09 05:20:39 +00:00
prj_open_all_files_with_ext_in_hot ( Application_Links * app , String8Array array , Prj_Open_File_Flags flags ) {
2019-06-01 23:33:31 +00:00
Scratch_Block scratch ( app ) ;
2021-01-09 05:20:39 +00:00
String8 hot = push_hot_directory ( app , scratch ) ;
String8 directory = hot ;
2019-06-01 23:33:31 +00:00
if ( ! character_is_slash ( string_get_character ( hot , hot . size - 1 ) ) ) {
2019-06-18 22:56:09 +00:00
directory = push_u8_stringf ( scratch , " %.*s/ " , string_expand ( hot ) ) ;
2018-05-30 07:58:22 +00:00
}
2021-01-09 07:06:55 +00:00
Prj_Pattern_List whitelist = prj_pattern_list_from_extension_array ( scratch , array ) ;
Prj_Pattern_List blacklist = prj_get_standard_blacklist ( scratch ) ;
2021-01-09 05:20:39 +00:00
prj_open_files_pattern_filter ( app , hot , whitelist , blacklist , flags ) ;
2018-05-09 05:22:33 +00:00
}
2021-01-09 05:20:39 +00:00
////////////////////////////////
// NOTE(allen): Project Parse
2018-05-08 07:14:23 +00:00
2019-10-25 06:17:54 +00:00
function void
2021-01-09 07:06:55 +00:00
prj_parse_pattern_list ( Arena * arena , Config * parsed , char * root_variable_name , Prj_Pattern_List * list_out ) {
2018-05-26 07:49:37 +00:00
Config_Compound * compound = 0 ;
if ( config_compound_var ( parsed , root_variable_name , 0 , & compound ) ) {
2018-05-30 20:27:47 +00:00
Config_Get_Result_List list = typed_string_array_reference_list ( arena , parsed , compound ) ;
2021-01-01 23:33:03 +00:00
for ( Config_Get_Result_Node * cfg_node = list . first ;
cfg_node ! = 0 ;
cfg_node = cfg_node - > next ) {
2021-01-09 07:06:55 +00:00
Prj_Pattern_Node * node = push_array ( arena , Prj_Pattern_Node , 1 ) ;
2021-01-01 23:33:03 +00:00
sll_queue_push ( list_out - > first , list_out - > last , node ) ;
list_out - > count + = 1 ;
2021-01-09 05:20:39 +00:00
String8 str = push_string_copy ( arena , cfg_node - > result . string ) ;
2021-01-01 23:33:03 +00:00
node - > pattern . absolutes = string_split_wildcards ( arena , str ) ;
2018-05-26 07:49:37 +00:00
}
}
}
2021-01-09 06:58:05 +00:00
function Prj_OS_Match_Level
2021-01-09 05:20:39 +00:00
prj_parse_v1_os_match ( String8 str , String8 this_os_str ) {
2021-01-09 06:58:05 +00:00
Prj_OS_Match_Level result = PrjOSMatchLevel_NoMatch ;
2019-06-01 23:33:31 +00:00
if ( string_match ( str , this_os_str ) ) {
2021-01-09 06:58:05 +00:00
result = PrjOSMatchLevel_ActiveMatch ;
2018-06-16 20:57:32 +00:00
}
2019-06-01 23:33:31 +00:00
else if ( string_match ( str , string_u8_litexpr ( " all " ) ) ) {
2021-01-09 06:58:05 +00:00
result = PrjOSMatchLevel_ActiveMatch ;
2018-06-16 20:57:32 +00:00
}
2019-06-01 23:33:31 +00:00
else if ( string_match ( str , string_u8_litexpr ( " default " ) ) ) {
2021-01-09 06:58:05 +00:00
result = PrjOSMatchLevel_PassiveMatch ;
2018-06-16 20:57:32 +00:00
}
2021-01-07 08:41:04 +00:00
return ( result ) ;
2018-06-16 20:57:32 +00:00
}
2021-01-09 06:58:05 +00:00
function Prj *
2021-01-09 05:20:39 +00:00
prj_parse_from_v1_config_data ( Application_Links * app , Arena * arena , String8 root_dir , Config * parsed ) {
2021-01-09 06:58:05 +00:00
Prj * project = push_array_zero ( arena , Prj , 1 ) ;
2018-05-26 07:49:37 +00:00
// Set new project directory
2019-07-13 00:43:17 +00:00
project - > dir = push_string_copy ( arena , root_dir ) ;
2018-05-26 07:49:37 +00:00
// project_name
{
2021-01-09 05:20:39 +00:00
String8 str = { } ;
2018-05-26 07:49:37 +00:00
if ( config_string_var ( parsed , " project_name " , 0 , & str ) ) {
2019-07-13 00:43:17 +00:00
project - > name = push_string_copy ( arena , str ) ;
2018-05-26 07:49:37 +00:00
}
2018-06-02 23:02:14 +00:00
else {
2019-06-01 23:33:31 +00:00
project - > name = SCu8 ( " " ) ;
2018-06-02 23:02:14 +00:00
}
2018-05-26 07:49:37 +00:00
}
// patterns
2021-01-07 08:41:04 +00:00
prj_parse_pattern_list ( arena , parsed , " patterns " , & project - > pattern_list ) ;
2018-05-26 07:49:37 +00:00
// blacklist_patterns
2021-01-07 08:41:04 +00:00
prj_parse_pattern_list ( arena , parsed , " blacklist_patterns " , & project - > blacklist_pattern_list ) ;
2018-05-26 07:49:37 +00:00
// load_paths
{
Config_Compound * compound = 0 ;
if ( config_compound_var ( parsed , " load_paths " , 0 , & compound ) ) {
2019-02-26 23:08:42 +00:00
b32 found_match = false ;
2018-06-16 20:57:32 +00:00
Config_Compound * best_paths = 0 ;
2019-02-26 23:08:42 +00:00
for ( i32 i = 0 ; ; + + i ) {
2018-05-30 20:27:47 +00:00
Config_Iteration_Step_Result result = typed_array_iteration_step ( parsed , compound , ConfigRValueType_Compound , i ) ;
if ( result . step = = Iteration_Skip ) {
2018-05-26 07:49:37 +00:00
continue ;
}
2018-05-30 20:27:47 +00:00
else if ( result . step = = Iteration_Quit ) {
2018-05-26 07:49:37 +00:00
break ;
}
2018-05-30 20:27:47 +00:00
Config_Compound * paths_option = result . get . compound ;
2018-05-26 07:49:37 +00:00
Config_Compound * paths = 0 ;
if ( config_compound_compound_member ( parsed , paths_option , " paths " , 0 , & paths ) ) {
2021-01-09 05:20:39 +00:00
String8 str = { } ;
2018-05-26 07:49:37 +00:00
if ( config_compound_string_member ( parsed , paths_option , " os " , 1 , & str ) ) {
2021-01-09 06:58:05 +00:00
Prj_OS_Match_Level r = prj_parse_v1_os_match ( str , string_u8_litexpr ( OS_NAME ) ) ;
if ( r = = PrjOSMatchLevel_ActiveMatch ) {
2018-06-16 20:57:32 +00:00
found_match = true ;
best_paths = paths ;
break ;
}
2021-01-09 06:58:05 +00:00
else if ( r = = PrjOSMatchLevel_PassiveMatch ) {
2018-06-16 20:57:32 +00:00
if ( ! found_match ) {
found_match = true ;
best_paths = paths ;
}
2018-05-26 07:49:37 +00:00
}
}
}
2018-06-16 20:57:32 +00:00
}
if ( found_match ) {
Config_Get_Result_List list = typed_compound_array_reference_list ( arena , parsed , best_paths ) ;
2018-05-26 07:49:37 +00:00
2021-01-09 06:58:05 +00:00
project - > load_path_array . paths = push_array ( arena , Prj_File_Load_Path , list . count ) ;
2018-06-16 20:57:32 +00:00
project - > load_path_array . count = list . count ;
2021-01-09 06:58:05 +00:00
Prj_File_Load_Path * dst = project - > load_path_array . paths ;
2018-06-16 20:57:32 +00:00
for ( Config_Get_Result_Node * node = list . first ;
node ! = 0 ;
node = node - > next , + + dst ) {
Config_Compound * src = node - > result . compound ;
2019-09-27 23:56:05 +00:00
block_zero_struct ( dst ) ;
2018-06-16 20:57:32 +00:00
dst - > recursive = true ;
dst - > relative = true ;
2018-05-26 07:49:37 +00:00
2021-01-09 05:20:39 +00:00
String8 str = { } ;
2018-06-16 20:57:32 +00:00
if ( config_compound_string_member ( parsed , src , " path " , 0 , & str ) ) {
2019-07-13 00:43:17 +00:00
dst - > path = push_string_copy ( arena , str ) ;
2018-05-21 06:12:08 +00:00
}
2018-06-16 20:57:32 +00:00
config_compound_bool_member ( parsed , src , " recursive " , 1 , & dst - > recursive ) ;
config_compound_bool_member ( parsed , src , " relative " , 2 , & dst - > relative ) ;
2018-05-26 07:49:37 +00:00
}
}
}
}
// command_list
{
Config_Compound * compound = 0 ;
if ( config_compound_var ( parsed , " command_list " , 0 , & compound ) ) {
2018-05-30 20:27:47 +00:00
Config_Get_Result_List list = typed_compound_array_reference_list ( arena , parsed , compound ) ;
2018-05-26 07:49:37 +00:00
2021-01-09 06:58:05 +00:00
project - > command_array . commands = push_array ( arena , Prj_Command , list . count ) ;
2018-05-30 20:27:47 +00:00
project - > command_array . count = list . count ;
2018-05-26 07:49:37 +00:00
2021-01-09 06:58:05 +00:00
Prj_Command * dst = project - > command_array . commands ;
2018-05-30 20:27:47 +00:00
for ( Config_Get_Result_Node * node = list . first ;
node ! = 0 ;
node = node - > next , + + dst ) {
2019-06-01 23:33:31 +00:00
u8 * pos = node - > result . pos ;
2018-05-30 20:27:47 +00:00
Config_Compound * src = node - > result . compound ;
2019-06-01 23:33:31 +00:00
block_zero_struct ( dst ) ;
2018-05-26 07:49:37 +00:00
2019-02-26 23:08:42 +00:00
b32 can_emit_command = true ;
2018-05-30 20:27:47 +00:00
2018-11-20 08:18:54 +00:00
Config_Get_Result cmd_result = { } ;
2018-06-02 04:06:13 +00:00
Config_Compound * cmd_set = 0 ;
2019-06-01 23:33:31 +00:00
u8 * cmd_pos = 0 ;
2021-01-09 05:20:39 +00:00
String8 cmd_str = { } ;
String8 out = { } ;
2019-02-26 23:08:42 +00:00
b32 footer_panel = false ;
b32 save_dirty_files = true ;
b32 cursor_at_end = false ;
2021-01-09 05:20:39 +00:00
String8 name = { } ;
2018-05-30 20:27:47 +00:00
if ( ! config_compound_string_member ( parsed , src , " name " , 0 , & name ) ) {
can_emit_command = false ;
2020-11-25 00:58:29 +00:00
def_config_push_error ( arena , parsed , pos , " a command must have a string type name member " ) ;
2018-05-30 20:27:47 +00:00
goto finish_command ;
}
2020-05-01 14:38:57 +00:00
cmd_result = config_compound_member ( parsed , src , string_u8_litexpr ( " cmd " ) , 1 ) ;
if ( cmd_result . success & & cmd_result . type = = ConfigRValueType_Compound ) {
2018-06-02 04:06:13 +00:00
cmd_set = cmd_result . compound ;
cmd_pos = cmd_result . pos ;
}
else {
2018-05-30 20:27:47 +00:00
can_emit_command = false ;
2020-11-25 00:58:29 +00:00
def_config_push_error ( arena , parsed , pos , " a command must have an array type cmd member " ) ;
2018-05-30 20:27:47 +00:00
goto finish_command ;
}
can_emit_command = false ;
2019-02-26 23:08:42 +00:00
for ( i32 j = 0 ; ; + + j ) {
2018-05-30 20:27:47 +00:00
Config_Iteration_Step_Result result = typed_array_iteration_step ( parsed , cmd_set , ConfigRValueType_Compound , j ) ;
if ( result . step = = Iteration_Skip ) {
continue ;
2018-05-21 06:12:08 +00:00
}
2018-05-30 20:27:47 +00:00
else if ( result . step = = Iteration_Quit ) {
break ;
2018-05-21 06:12:08 +00:00
}
2018-05-30 20:27:47 +00:00
Config_Compound * cmd_option = result . get . compound ;
2018-05-21 06:12:08 +00:00
2021-01-09 05:20:39 +00:00
String8 cmd = { } ;
2018-05-30 20:27:47 +00:00
if ( config_compound_string_member ( parsed , cmd_option , " cmd " , 0 , & cmd ) ) {
2021-01-09 05:20:39 +00:00
String8 str = { } ;
2018-05-30 20:27:47 +00:00
if ( config_compound_string_member ( parsed , cmd_option , " os " , 1 , & str ) ) {
2021-01-09 06:58:05 +00:00
Prj_OS_Match_Level r = prj_parse_v1_os_match ( str , string_u8_litexpr ( OS_NAME ) ) ;
if ( r = = PrjOSMatchLevel_ActiveMatch ) {
2018-06-16 20:57:32 +00:00
can_emit_command = true ;
cmd_str = cmd ;
break ;
}
2021-01-09 06:58:05 +00:00
else if ( r = = PrjOSMatchLevel_PassiveMatch ) {
2018-06-16 20:57:32 +00:00
if ( ! can_emit_command ) {
can_emit_command = true ;
cmd_str = cmd ;
}
2018-05-26 07:49:37 +00:00
}
}
}
2018-05-30 20:27:47 +00:00
}
2018-06-02 04:06:13 +00:00
if ( ! can_emit_command ) {
2020-11-25 00:58:29 +00:00
def_config_push_error ( arena , parsed , cmd_pos , " no usable command strings found in cmd " ) ;
2018-06-02 04:06:13 +00:00
goto finish_command ;
2018-05-26 07:49:37 +00:00
}
2018-05-30 20:27:47 +00:00
2018-06-02 04:06:13 +00:00
config_compound_string_member ( parsed , src , " out " , 2 , & out ) ;
config_compound_bool_member ( parsed , src , " footer_panel " , 3 , & footer_panel ) ;
config_compound_bool_member ( parsed , src , " save_dirty_files " , 4 ,
& save_dirty_files ) ;
config_compound_bool_member ( parsed , src , " cursor_at_end " , 5 ,
& cursor_at_end ) ;
2019-07-13 00:43:17 +00:00
dst - > name = push_string_copy ( arena , name ) ;
dst - > cmd = push_string_copy ( arena , cmd_str ) ;
dst - > out = push_string_copy ( arena , out ) ;
2018-06-02 04:06:13 +00:00
dst - > footer_panel = footer_panel ;
dst - > save_dirty_files = save_dirty_files ;
dst - > cursor_at_end = cursor_at_end ;
2018-05-30 20:27:47 +00:00
finish_command : ;
2018-05-26 07:49:37 +00:00
}
}
}
// fkey_command
{
2019-02-26 23:08:42 +00:00
for ( i32 i = 1 ; i < = 16 ; + + i ) {
2021-01-09 05:20:39 +00:00
String8 name = { } ;
2019-02-26 23:08:42 +00:00
i32 index = - 1 ;
2018-05-26 07:49:37 +00:00
if ( config_string_var ( parsed , " fkey_command " , i , & name ) ) {
2019-02-26 23:08:42 +00:00
i32 count = project - > command_array . count ;
2021-01-09 06:58:05 +00:00
Prj_Command * command_ptr = project - > command_array . commands ;
2019-02-26 23:08:42 +00:00
for ( i32 j = 0 ; j < count ; + + j , + + command_ptr ) {
2019-06-01 23:33:31 +00:00
if ( string_match ( command_ptr - > name , name ) ) {
2018-05-26 07:49:37 +00:00
index = j ;
break ;
2018-05-21 06:12:08 +00:00
}
}
2017-11-15 00:06:00 +00:00
}
2018-05-26 07:49:37 +00:00
project - > fkey_commands [ i - 1 ] = index ;
2017-06-20 20:37:45 +00:00
}
2018-05-19 22:05:31 +00:00
}
2018-05-26 07:49:37 +00:00
project - > loaded = true ;
return ( project ) ;
}
2019-10-25 06:17:54 +00:00
function void
2021-01-09 07:06:55 +00:00
project_deep_copy__pattern_list ( Arena * arena , Prj_Pattern_List * src_list , Prj_Pattern_List * dst_list ) {
for ( Prj_Pattern_Node * src_node = src_list - > first ;
2021-01-01 23:33:03 +00:00
src_node ! = 0 ;
src_node = src_node - > next ) {
2021-01-09 07:06:55 +00:00
Prj_Pattern_Node * dst_node = push_array ( arena , Prj_Pattern_Node , 1 ) ;
2021-01-01 23:33:03 +00:00
sll_queue_push ( dst_list - > first , dst_list - > last , dst_node ) ;
dst_list - > count + = 1 ;
2021-01-09 05:20:39 +00:00
for ( String8Node * node = src_node - > pattern . absolutes . first ;
2019-06-01 23:33:31 +00:00
node ! = 0 ;
node = node - > next ) {
2021-01-09 05:20:39 +00:00
String8 string = push_string_copy ( arena , node - > string ) ;
2021-01-01 23:33:03 +00:00
string_list_push ( arena , & dst_node - > pattern . absolutes , string ) ;
2018-05-26 07:49:37 +00:00
}
}
}
2021-01-09 06:58:05 +00:00
function Prj
project_deep_copy__inner ( Arena * arena , Prj * project ) {
Prj result = { } ;
2019-07-13 00:43:17 +00:00
result . dir = push_string_copy ( arena , project - > dir ) ;
result . name = push_string_copy ( arena , project - > name ) ;
2021-01-01 23:33:03 +00:00
project_deep_copy__pattern_list ( arena , & project - > pattern_list , & result . pattern_list ) ;
project_deep_copy__pattern_list ( arena , & project - > blacklist_pattern_list , & result . blacklist_pattern_list ) ;
2018-05-26 07:49:37 +00:00
{
2019-02-26 23:08:42 +00:00
i32 path_count = project - > load_path_array . count ;
2021-01-09 06:58:05 +00:00
result . load_path_array . paths = push_array ( arena , Prj_File_Load_Path , path_count ) ;
2018-05-26 07:49:37 +00:00
result . load_path_array . count = path_count ;
2021-01-09 06:58:05 +00:00
Prj_File_Load_Path * dst = result . load_path_array . paths ;
Prj_File_Load_Path * src = project - > load_path_array . paths ;
2019-02-26 23:08:42 +00:00
for ( i32 i = 0 ; i < path_count ; + + i , + + dst , + + src ) {
2019-07-13 00:43:17 +00:00
dst - > path = push_string_copy ( arena , src - > path ) ;
2018-05-26 07:49:37 +00:00
dst - > recursive = src - > recursive ;
dst - > relative = src - > relative ;
}
}
{
2019-02-26 23:08:42 +00:00
i32 command_count = project - > command_array . count ;
2021-01-09 06:58:05 +00:00
result . command_array . commands = push_array_zero ( arena , Prj_Command , command_count ) ;
2018-05-26 07:49:37 +00:00
result . command_array . count = command_count ;
2021-01-09 06:58:05 +00:00
Prj_Command * dst = result . command_array . commands ;
Prj_Command * src = project - > command_array . commands ;
2019-02-26 23:08:42 +00:00
for ( i32 i = 0 ; i < command_count ; + + i , + + dst , + + src ) {
2018-05-26 07:49:37 +00:00
if ( src - > name . str ! = 0 ) {
2019-07-13 00:43:17 +00:00
dst - > name = push_string_copy ( arena , src - > name ) ;
2018-05-26 07:49:37 +00:00
}
if ( src - > cmd . str ! = 0 ) {
2019-07-13 00:43:17 +00:00
dst - > cmd = push_string_copy ( arena , src - > cmd ) ;
2018-05-26 07:49:37 +00:00
}
if ( src - > out . str ! = 0 ) {
2019-07-13 00:43:17 +00:00
dst - > out = push_string_copy ( arena , src - > out ) ;
2018-05-26 07:49:37 +00:00
}
dst - > footer_panel = src - > footer_panel ;
dst - > save_dirty_files = src - > save_dirty_files ;
2018-06-02 00:29:36 +00:00
dst - > cursor_at_end = src - > cursor_at_end ;
2018-05-26 07:49:37 +00:00
}
}
2019-09-27 23:56:05 +00:00
block_copy_array ( result . fkey_commands , project - > fkey_commands ) ;
2018-05-26 07:49:37 +00:00
result . loaded = true ;
return ( result ) ;
}
2021-01-09 06:58:05 +00:00
function Prj
project_deep_copy ( Arena * arena , Prj * project ) {
2019-06-01 23:33:31 +00:00
Temp_Memory restore_point = begin_temp ( arena ) ;
2021-01-09 06:58:05 +00:00
Prj result = project_deep_copy__inner ( arena , project ) ;
2018-05-26 07:49:37 +00:00
if ( ! result . loaded ) {
2019-06-01 23:33:31 +00:00
end_temp ( restore_point ) ;
block_zero_struct ( & result ) ;
2018-05-26 07:49:37 +00:00
}
return ( result ) ;
}
2020-11-25 08:41:30 +00:00
// NOTE(allen): string list join ("flatten") doesn't really work... :(
2021-01-09 05:20:39 +00:00
function String8
prj_join_pattern_string ( Arena * arena , String8List list ) {
String8 pattern_string = { } ;
2020-11-25 08:41:30 +00:00
pattern_string . size = list . total_size + list . node_count - 1 ;
pattern_string . str = push_array ( arena , u8 , pattern_string . size + 1 ) ;
u8 * ptr = pattern_string . str ;
2021-01-09 05:20:39 +00:00
String8Node * node = list . first ;
2020-11-25 08:41:30 +00:00
if ( node ! = 0 ) {
for ( ; ; ) {
block_copy ( ptr , node - > string . str , node - > string . size ) ;
ptr + = node - > string . size ;
node = node - > next ;
if ( node = = 0 ) {
break ;
}
* ptr = ' * ' ;
ptr + = 1 ;
}
}
pattern_string . str [ pattern_string . size ] = 0 ;
return ( pattern_string ) ;
}
2021-01-09 05:20:39 +00:00
function String8
prj_sanitize_string ( Arena * arena , String8 string ) {
String8 result = { } ;
2020-12-06 00:54:33 +00:00
if ( string . size > 0 ) {
result . size = string . size ;
result . str = push_array ( arena , u8 , result . size + 2 ) ;
u8 * in = string . str ;
u8 * out = result . str ;
if ( character_is_base10 ( * in ) ) {
* out = ' _ ' ;
out + = 1 ;
result . size + = 1 ;
}
for ( u64 i = 0 ; i < string . size ; i + = 1 , in + = 1 , out + = 1 ) {
u8 c = * in ;
if ( ! character_is_alpha_numeric ( c ) ) {
c = ' _ ' ;
}
* out = c ;
}
result . str [ result . size ] = 0 ;
}
return ( result ) ;
}
2020-12-05 20:32:56 +00:00
function Variable_Handle
2021-01-09 06:58:05 +00:00
prj_version_1_to_version_2 ( Application_Links * app , Config * parsed , Prj * project ) {
2020-12-05 20:32:56 +00:00
Scratch_Block scratch ( app ) ;
String_ID project_id = vars_save_string_lit ( " prj_config " ) ;
2020-12-31 00:55:11 +00:00
String_ID version_id = vars_save_string ( str8_lit ( " version " ) ) ;
String_ID project_name_id = vars_save_string ( str8_lit ( " project_name " ) ) ;
String_ID patterns_id = vars_save_string ( str8_lit ( " patterns " ) ) ;
String_ID blacklist_patterns_id = vars_save_string ( str8_lit ( " blacklist_patterns " ) ) ;
2020-12-05 20:32:56 +00:00
2020-12-31 00:55:11 +00:00
String_ID load_paths_id = vars_save_string ( str8_lit ( " load_paths " ) ) ;
String_ID path_id = vars_save_string ( str8_lit ( " path " ) ) ;
String_ID recursive_id = vars_save_string ( str8_lit ( " recursive " ) ) ;
String_ID relative_id = vars_save_string ( str8_lit ( " relative " ) ) ;
String_ID true_id = vars_save_string ( str8_lit ( " true " ) ) ;
String_ID false_id = vars_save_string ( str8_lit ( " false " ) ) ;
2021-01-06 05:00:37 +00:00
String_ID commands_id = vars_save_string ( str8_lit ( " commands " ) ) ;
2020-12-05 20:32:56 +00:00
2020-12-31 00:55:11 +00:00
String_ID out_id = vars_save_string ( str8_lit ( " out " ) ) ;
String_ID footer_panel_id = vars_save_string ( str8_lit ( " footer_panel " ) ) ;
String_ID save_dirty_files_id = vars_save_string ( str8_lit ( " save_dirty_files " ) ) ;
String_ID cursor_at_end_id = vars_save_string ( str8_lit ( " cursor_at_end " ) ) ;
2020-12-05 20:32:56 +00:00
2020-12-31 00:55:11 +00:00
String_ID fkey_command_id = vars_save_string ( str8_lit ( " fkey_command " ) ) ;
2020-12-05 20:32:56 +00:00
2020-12-31 00:55:11 +00:00
String_ID os_id = vars_save_string ( str8_lit ( OS_NAME ) ) ; ;
2020-12-05 20:32:56 +00:00
Variable_Handle proj_var = vars_new_variable ( vars_get_root ( ) , project_id , vars_save_string ( parsed - > file_name ) ) ;
if ( parsed - > version ! = 0 ) {
2021-01-09 05:20:39 +00:00
String8 version_str = push_stringf ( scratch , " %d " , * parsed - > version ) ;
2020-12-05 20:32:56 +00:00
vars_new_variable ( proj_var , version_id , vars_save_string ( version_str ) ) ;
}
vars_new_variable ( proj_var , project_name_id , vars_save_string ( project - > name ) ) ;
2021-01-06 05:00:37 +00:00
// NOTE(allen): Load Pattern
2020-12-05 20:32:56 +00:00
struct PatternVars {
String_ID id ;
2021-01-09 07:06:55 +00:00
Prj_Pattern_List list ;
2020-12-05 20:32:56 +00:00
} ;
PatternVars pattern_vars [ ] = {
2021-01-01 23:33:03 +00:00
{ patterns_id , project - > pattern_list } ,
{ blacklist_patterns_id , project - > blacklist_pattern_list } ,
2020-12-05 20:32:56 +00:00
} ;
PatternVars * pattern_var = pattern_vars ;
PatternVars * opl = pattern_vars + ArrayCount ( pattern_vars ) ;
for ( ; pattern_var < opl ; pattern_var + = 1 ) {
Variable_Handle patterns = vars_new_variable ( proj_var , pattern_var - > id ) ;
2021-01-01 23:33:03 +00:00
i32 i = 0 ;
2021-01-09 07:06:55 +00:00
for ( Prj_Pattern_Node * node = pattern_var - > list . first ;
2021-01-01 23:33:03 +00:00
node ! = 0 ;
node = node - > next , i + = 1 ) {
2021-01-09 05:20:39 +00:00
String8 pattern_string = prj_join_pattern_string ( scratch , node - > pattern . absolutes ) ;
2020-12-05 20:32:56 +00:00
String_ID key = vars_save_string ( push_stringf ( scratch , " %d " , i ) ) ;
String_ID pattern_id = vars_save_string ( pattern_string ) ;
vars_new_variable ( patterns , key , pattern_id ) ;
}
}
2021-01-06 05:00:37 +00:00
// NOTE(allen): Load Paths
2020-12-05 20:32:56 +00:00
{
Variable_Handle load_paths = vars_new_variable ( proj_var , load_paths_id ) ;
Variable_Handle os_var = vars_new_variable ( load_paths , os_id ) ;
i32 count = project - > load_path_array . count ;
2021-01-09 06:58:05 +00:00
Prj_File_Load_Path * load_path = project - > load_path_array . paths ;
2020-12-05 20:32:56 +00:00
for ( i32 i = 0 ; i < count ; i + = 1 , load_path + = 1 ) {
String_ID key = vars_save_string ( push_stringf ( scratch , " %d " , i ) ) ;
Variable_Handle path_var = vars_new_variable ( os_var , key ) ;
vars_new_variable ( path_var , path_id , vars_save_string ( load_path - > path ) ) ;
vars_new_variable ( path_var , recursive_id , load_path - > recursive ? true_id : false_id ) ;
vars_new_variable ( path_var , relative_id , load_path - > recursive ? true_id : false_id ) ;
}
}
2021-01-06 05:00:37 +00:00
// NOTE(allen): Commands
2020-12-05 20:32:56 +00:00
{
2021-01-06 05:00:37 +00:00
Variable_Handle cmd_list_var = vars_new_variable ( proj_var , commands_id ) ;
2020-12-05 20:32:56 +00:00
i32 count = project - > command_array . count ;
2021-01-09 06:58:05 +00:00
Prj_Command * cmd = project - > command_array . commands ;
2020-12-05 20:32:56 +00:00
for ( i32 i = 0 ; i < count ; i + = 1 , cmd + = 1 ) {
2021-01-09 05:20:39 +00:00
String8 cmd_name = prj_sanitize_string ( scratch , cmd - > name ) ;
2021-01-06 05:00:37 +00:00
Variable_Handle cmd_var = vars_new_variable ( cmd_list_var , vars_save_string ( cmd_name ) ) ;
2020-12-05 20:32:56 +00:00
vars_new_variable ( cmd_var , os_id , vars_save_string ( cmd - > cmd ) ) ;
vars_new_variable ( cmd_var , out_id , vars_save_string ( cmd - > out ) ) ;
vars_new_variable ( cmd_var , footer_panel_id , cmd - > footer_panel ? true_id : false_id ) ;
vars_new_variable ( cmd_var , save_dirty_files_id , cmd - > save_dirty_files ? true_id : false_id ) ;
vars_new_variable ( cmd_var , cursor_at_end_id , cmd - > cursor_at_end ? true_id : false_id ) ;
}
}
2021-01-06 05:00:37 +00:00
// NOTE(allen): FKey Commands
2020-12-05 20:32:56 +00:00
{
Variable_Handle fkeys_var = vars_new_variable ( proj_var , fkey_command_id ) ;
for ( i32 i = 0 ; i < 16 ; i + = 1 ) {
i32 cmd_index = project - > fkey_commands [ i ] ;
if ( 0 < = cmd_index & & cmd_index < project - > command_array . count ) {
2021-01-09 06:58:05 +00:00
Prj_Command * cmd = project - > command_array . commands + cmd_index ;
2020-12-05 20:32:56 +00:00
if ( cmd - > name . size > 0 ) {
2021-01-09 05:20:39 +00:00
String8 cmd_name = prj_sanitize_string ( scratch , cmd - > name ) ;
2020-12-05 20:32:56 +00:00
String_ID key = vars_save_string ( push_stringf ( scratch , " %d " , i ) ) ;
2020-12-06 00:54:33 +00:00
String_ID val = vars_save_string ( cmd_name ) ;
2020-12-05 20:32:56 +00:00
vars_new_variable ( fkeys_var , key , val ) ;
}
}
}
}
2020-12-06 00:54:33 +00:00
2021-01-06 05:00:37 +00:00
return ( proj_var ) ;
2020-12-05 20:32:56 +00:00
}
2021-01-09 05:20:39 +00:00
////////////////////////////////
// NOTE(allen): Project Files
2020-12-05 20:32:56 +00:00
2021-01-09 06:58:05 +00:00
function Prj_Setup_Status
2021-01-09 05:20:39 +00:00
prj_file_is_setup ( Application_Links * app , String8 script_path , String8 script_file ) {
2021-01-09 06:58:05 +00:00
Prj_Setup_Status result = { } ;
2021-01-09 05:20:39 +00:00
{
Scratch_Block scratch ( app ) ;
String8 bat_path = push_u8_stringf ( scratch , " %.*s/%.*s.bat " ,
string_expand ( script_path ) ,
string_expand ( script_file ) ) ;
result . bat_exists = file_exists ( app , bat_path ) ;
2018-05-08 07:14:23 +00:00
}
2021-01-09 05:20:39 +00:00
{
Scratch_Block scratch ( app ) ;
String8 sh_path = push_u8_stringf ( scratch , " %.*s/%.*s.sh " ,
string_expand ( script_path ) ,
string_expand ( script_file ) ) ;
result . sh_exists = file_exists ( app , sh_path ) ;
}
{
Scratch_Block scratch ( app ) ;
String8 project_path = push_u8_stringf ( scratch , " %.*s/project.4coder " ,
string_expand ( script_path ) ) ;
result . sh_exists = file_exists ( app , project_path ) ;
}
result . everything_exists = ( result . bat_exists & & result . sh_exists & & result . project_exists ) ;
return ( result ) ;
2018-05-08 07:14:23 +00:00
}
2021-01-09 05:20:39 +00:00
function b32
prj_generate_bat ( Arena * scratch , String8 opts , String8 compiler , String8 script_path , String8 script_file ,
String8 code_file , String8 output_dir , String8 binary_file ) {
b32 success = false ;
2021-01-01 23:33:03 +00:00
2021-01-09 05:20:39 +00:00
Temp_Memory temp = begin_temp ( scratch ) ;
2021-01-01 23:33:03 +00:00
2021-01-09 05:20:39 +00:00
String8 cf = push_string_copy ( scratch , code_file ) ;
String8 od = push_string_copy ( scratch , output_dir ) ;
String8 bf = push_string_copy ( scratch , binary_file ) ;
2018-06-02 00:29:36 +00:00
2019-06-01 23:33:31 +00:00
cf = string_mod_replace_character ( cf , ' / ' , ' \\ ' ) ;
od = string_mod_replace_character ( od , ' / ' , ' \\ ' ) ;
bf = string_mod_replace_character ( bf , ' / ' , ' \\ ' ) ;
2018-06-02 00:29:36 +00:00
2021-01-09 05:20:39 +00:00
String8 file_name = push_u8_stringf ( scratch , " %.*s/%.*s.bat " ,
string_expand ( script_path ) ,
string_expand ( script_file ) ) ;
2018-06-02 00:29:36 +00:00
2019-06-01 23:33:31 +00:00
FILE * bat_script = fopen ( ( char * ) file_name . str , " wb " ) ;
2018-06-02 00:29:36 +00:00
if ( bat_script ! = 0 ) {
fprintf ( bat_script , " @echo off \n \n " ) ;
2019-06-01 23:33:31 +00:00
fprintf ( bat_script , " set opts=%.*s \n " , ( i32 ) opts . size , opts . str ) ;
2018-06-02 00:29:36 +00:00
fprintf ( bat_script , " set code=%%cd%% \n " ) ;
2019-06-01 23:33:31 +00:00
fprintf ( bat_script , " pushd %.*s \n " , ( i32 ) od . size , od . str ) ;
2018-06-02 00:29:36 +00:00
fprintf ( bat_script , " %.*s %%opts%% %%code%% \\ %.*s -Fe%.*s \n " ,
2019-06-01 23:33:31 +00:00
( i32 ) compiler . size , compiler . str , ( i32 ) cf . size , cf . str , ( i32 ) bf . size , bf . str ) ;
2018-06-02 00:29:36 +00:00
fprintf ( bat_script , " popd \n " ) ;
fclose ( bat_script ) ;
success = true ;
}
2019-06-01 23:33:31 +00:00
end_temp ( temp ) ;
2018-06-02 00:29:36 +00:00
return ( success ) ;
}
2019-10-25 06:17:54 +00:00
function b32
2021-01-09 05:20:39 +00:00
prj_generate_sh ( Arena * scratch , String8 opts , String8 compiler , String8 script_path , String8 script_file , String8 code_file , String8 output_dir , String8 binary_file ) {
2019-02-26 23:08:42 +00:00
b32 success = false ;
2018-06-02 00:29:36 +00:00
2019-06-01 23:33:31 +00:00
Temp_Memory temp = begin_temp ( scratch ) ;
2018-06-02 00:29:36 +00:00
2021-01-09 05:20:39 +00:00
String8 cf = code_file ;
String8 od = output_dir ;
String8 bf = binary_file ;
2018-06-02 00:29:36 +00:00
2021-01-09 05:20:39 +00:00
String8 file_name = push_u8_stringf ( scratch , " %.*s/%.*s.sh " ,
string_expand ( script_path ) ,
string_expand ( script_file ) ) ;
2018-06-02 00:29:36 +00:00
2019-06-01 23:33:31 +00:00
FILE * sh_script = fopen ( ( char * ) file_name . str , " wb " ) ;
2018-06-02 00:29:36 +00:00
if ( sh_script ! = 0 ) {
fprintf ( sh_script , " #!/bin/bash \n \n " ) ;
fprintf ( sh_script , " code= \" $PWD \" \n " ) ;
2019-06-01 23:33:31 +00:00
fprintf ( sh_script , " opts=%.*s \n " , string_expand ( opts ) ) ;
fprintf ( sh_script , " cd %.*s > /dev/null \n " , string_expand ( od ) ) ;
fprintf ( sh_script , " %.*s $opts $code/%.*s -o %.*s \n " , string_expand ( compiler ) , string_expand ( cf ) , string_expand ( bf ) ) ;
2018-06-02 00:29:36 +00:00
fprintf ( sh_script , " cd $code > /dev/null \n " ) ;
fclose ( sh_script ) ;
success = true ;
}
2019-06-01 23:33:31 +00:00
end_temp ( temp ) ;
2018-06-02 00:29:36 +00:00
return ( success ) ;
}
2019-10-25 06:17:54 +00:00
function b32
2021-01-09 05:20:39 +00:00
prj_generate_project ( Arena * scratch , String8 script_path , String8 script_file , String8 output_dir , String8 binary_file ) {
2019-02-26 23:08:42 +00:00
b32 success = false ;
2018-06-02 00:29:36 +00:00
2019-06-01 23:33:31 +00:00
Temp_Memory temp = begin_temp ( scratch ) ;
2018-06-02 00:29:36 +00:00
2021-01-09 05:20:39 +00:00
String8 od = output_dir ;
String8 bf = binary_file ;
2018-06-02 00:29:36 +00:00
2021-01-09 05:20:39 +00:00
String8 od_win = string_replace ( scratch , od ,
string_u8_litexpr ( " / " ) , string_u8_litexpr ( " \\ " ) ) ;
String8 bf_win = string_replace ( scratch , bf ,
string_u8_litexpr ( " / " ) , string_u8_litexpr ( " \\ " ) ) ;
2018-06-02 00:29:36 +00:00
2021-01-09 05:20:39 +00:00
String8 file_name = push_u8_stringf ( scratch , " %.*s/project.4coder " , string_expand ( script_path ) ) ;
2018-06-02 00:29:36 +00:00
2019-06-01 23:33:31 +00:00
FILE * out = fopen ( ( char * ) file_name . str , " wb " ) ;
2018-06-02 00:29:36 +00:00
if ( out ! = 0 ) {
fprintf ( out , " version(1); \n " ) ;
2019-06-01 23:33:31 +00:00
fprintf ( out , " project_name = \" %.*s \" ; \n " , string_expand ( binary_file ) ) ;
2018-06-02 00:29:36 +00:00
fprintf ( out , " patterns = { \n " ) ;
fprintf ( out , " \" *.c \" , \n " ) ;
fprintf ( out , " \" *.cpp \" , \n " ) ;
fprintf ( out , " \" *.h \" , \n " ) ;
fprintf ( out , " \" *.m \" , \n " ) ;
fprintf ( out , " \" *.bat \" , \n " ) ;
fprintf ( out , " \" *.sh \" , \n " ) ;
fprintf ( out , " \" *.4coder \" , \n " ) ;
fprintf ( out , " }; \n " ) ;
2018-06-02 23:02:14 +00:00
fprintf ( out , " blacklist_patterns = { \n " ) ;
2018-06-02 00:29:36 +00:00
fprintf ( out , " \" .* \" , \n " ) ;
fprintf ( out , " }; \n " ) ;
fprintf ( out , " load_paths_base = { \n " ) ;
2018-06-02 23:02:14 +00:00
fprintf ( out , " { \" . \" , .relative = true, .recursive = true, }, \n " ) ;
2018-06-02 00:29:36 +00:00
fprintf ( out , " }; \n " ) ;
fprintf ( out , " load_paths = { \n " ) ;
fprintf ( out , " { load_paths_base, .os = \" win \" , }, \n " ) ;
fprintf ( out , " { load_paths_base, .os = \" linux \" , }, \n " ) ;
fprintf ( out , " { load_paths_base, .os = \" mac \" , }, \n " ) ;
fprintf ( out , " }; \n " ) ;
fprintf ( out , " \n " ) ;
fprintf ( out , " command_list = { \n " ) ;
fprintf ( out , " { .name = \" build \" , \n " ) ;
fprintf ( out , " .out = \" *compilation* \" , .footer_panel = true, .save_dirty_files = true, \n " ) ;
2019-06-01 23:33:31 +00:00
fprintf ( out , " .cmd = { { \" %.*s.bat \" , .os = \" win \" }, \n " , string_expand ( script_file ) ) ;
fprintf ( out , " { \" ./%.*s.sh \" , .os = \" linux \" }, \n " , string_expand ( script_file ) ) ;
fprintf ( out , " { \" ./%.*s.sh \" , .os = \" mac \" }, }, }, \n " , string_expand ( script_file ) ) ;
2018-06-02 00:29:36 +00:00
fprintf ( out , " { .name = \" run \" , \n " ) ;
fprintf ( out , " .out = \" *run* \" , .footer_panel = false, .save_dirty_files = false, \n " ) ;
2019-06-01 23:33:31 +00:00
fprintf ( out , " .cmd = { { \" %.*s \\ \\ %.*s \" , .os = \" win \" }, \n " , string_expand ( od_win ) , string_expand ( bf_win ) ) ;
fprintf ( out , " { \" %.*s/%.*s \" , .os = \" linux \" }, \n " , string_expand ( od ) , string_expand ( bf ) ) ;
fprintf ( out , " { \" %.*s/%.*s \" , .os = \" mac \" }, }, }, \n " , string_expand ( od ) , string_expand ( bf ) ) ;
2018-06-02 00:29:36 +00:00
fprintf ( out , " }; \n " ) ;
fprintf ( out , " fkey_command[1] = \" build \" ; \n " ) ;
fprintf ( out , " fkey_command[2] = \" run \" ; \n " ) ;
fclose ( out ) ;
success = true ;
}
2019-06-01 23:33:31 +00:00
end_temp ( temp ) ;
2018-06-02 00:29:36 +00:00
return ( success ) ;
}
2019-10-25 06:17:54 +00:00
function void
2021-01-09 06:58:05 +00:00
prj_setup_scripts ( Application_Links * app , Prj_Setup_Script_Flags flags ) {
2019-10-01 02:06:21 +00:00
Scratch_Block scratch ( app ) ;
2021-01-09 05:20:39 +00:00
String8 script_path = push_hot_directory ( app , scratch ) ;
2018-06-02 00:29:36 +00:00
2021-01-09 06:58:05 +00:00
b32 do_project_file = ( flags & PrjSetupScriptFlag_Project ) ;
b32 do_bat_script = ( flags & PrjSetupScriptFlag_Bat ) ;
b32 do_sh_script = ( flags & PrjSetupScriptFlag_Sh ) ;
2019-02-26 23:08:42 +00:00
b32 needs_to_do_work = false ;
2021-01-09 06:58:05 +00:00
Prj_Setup_Status status = { } ;
2018-06-02 00:29:36 +00:00
if ( do_project_file ) {
2021-01-09 05:20:39 +00:00
status = prj_file_is_setup ( app , script_path , string_u8_litexpr ( " build " ) ) ;
2018-06-02 00:29:36 +00:00
needs_to_do_work =
! status . project_exists | |
( do_bat_script & & ! status . bat_exists ) | |
( do_sh_script & & ! status . sh_exists ) ;
}
else {
needs_to_do_work = true ;
}
if ( needs_to_do_work ) {
// Query the User for Key File Names
2017-11-09 18:30:24 +00:00
2021-01-09 06:58:05 +00:00
b32 finished_queries = false ;
local_const i32 text_field_cap = 1024 ;
String8 script_file = { } ;
String8 code_file = { } ;
String8 output_dir = { } ;
String8 binary_file = { } ;
2017-11-09 18:30:24 +00:00
2021-01-09 06:58:05 +00:00
{
Query_Bar_Group bar_group ( app ) ;
Query_Bar script_file_bar = { } ;
Query_Bar code_file_bar = { } ;
Query_Bar output_dir_bar = { } ;
Query_Bar binary_file_bar = { } ;
b32 get_script_file = ! do_project_file ;
b32 get_code_file = ( ( do_bat_script & & ! status . bat_exists ) | | ( do_sh_script & & ! status . sh_exists ) ) ;
if ( get_script_file ) {
script_file_bar . prompt = string_u8_litexpr ( " Script Name: " ) ;
script_file_bar . string . str = push_array ( scratch , u8 , text_field_cap ) ;
script_file_bar . string_capacity = text_field_cap ;
if ( ! query_user_string ( app , & script_file_bar ) | |
script_file_bar . string . size = = 0 ) {
goto fail_out ;
}
}
if ( get_code_file ) {
code_file_bar . prompt = string_u8_litexpr ( " Build Target: " ) ;
code_file_bar . string . str = push_array ( scratch , u8 , text_field_cap ) ;
code_file_bar . string_capacity = text_field_cap ;
if ( ! query_user_string ( app , & code_file_bar ) | |
code_file_bar . string . size = = 0 ) {
goto fail_out ;
}
}
output_dir_bar . prompt = string_u8_litexpr ( " Output Directory: " ) ;
output_dir_bar . string . str = push_array ( scratch , u8 , text_field_cap ) ;
output_dir_bar . string_capacity = text_field_cap ;
if ( ! query_user_string ( app , & output_dir_bar ) ) {
goto fail_out ;
}
if ( output_dir_bar . string . size = = 0 ) {
output_dir_bar . string . str [ 0 ] = ' . ' ;
output_dir_bar . string . size = 1 ;
}
binary_file_bar . prompt = string_u8_litexpr ( " Binary Output: " ) ;
binary_file_bar . string . str = push_array ( scratch , u8 , text_field_cap ) ;
binary_file_bar . string_capacity = text_field_cap ;
if ( ! query_user_string ( app , & binary_file_bar ) | |
binary_file_bar . string . size = = 0 ) {
goto fail_out ;
}
finished_queries = true ;
script_file = script_file_bar . string ;
code_file = code_file_bar . string ;
output_dir = output_dir_bar . string ;
binary_file = binary_file_bar . string ;
fail_out : ;
}
2017-11-09 18:30:24 +00:00
2021-01-09 06:58:05 +00:00
if ( ! finished_queries ) {
2018-06-02 00:29:36 +00:00
return ;
}
2017-11-09 18:30:24 +00:00
2018-06-02 00:29:36 +00:00
if ( do_project_file ) {
2021-01-09 06:58:05 +00:00
script_file = string_u8_litexpr ( " build " ) ;
2018-06-02 00:29:36 +00:00
}
2017-11-09 18:30:24 +00:00
2018-06-02 00:29:36 +00:00
if ( ! do_project_file ) {
2021-01-09 06:58:05 +00:00
status = prj_file_is_setup ( app , script_path , script_file ) ;
2018-06-02 00:29:36 +00:00
}
2017-11-09 18:30:24 +00:00
// Generate Scripts
2018-06-02 00:29:36 +00:00
if ( do_bat_script ) {
if ( ! status . bat_exists ) {
2021-01-09 05:20:39 +00:00
String8 default_flags_bat = def_get_config_string ( scratch , vars_save_string_lit ( " default_flags_bat " ) ) ;
String8 default_compiler_bat = def_get_config_string ( scratch , vars_save_string_lit ( " default_compiler_bat " ) ) ;
2020-11-26 03:20:36 +00:00
2021-01-09 06:58:05 +00:00
if ( ! prj_generate_bat ( scratch , default_flags_bat , default_compiler_bat , script_path ,
script_file , code_file , output_dir , binary_file ) ) {
2019-06-01 23:33:31 +00:00
print_message ( app , string_u8_litexpr ( " could not create build.bat for new project \n " ) ) ;
2018-06-02 00:29:36 +00:00
}
2017-11-09 18:30:24 +00:00
}
else {
2019-06-01 23:33:31 +00:00
print_message ( app , string_u8_litexpr ( " the batch script already exists, no changes made to it \n " ) ) ;
2017-11-09 18:30:24 +00:00
}
}
2018-06-02 00:29:36 +00:00
if ( do_sh_script ) {
if ( ! status . bat_exists ) {
2021-01-09 05:20:39 +00:00
String8 default_flags_sh = def_get_config_string ( scratch , vars_save_string_lit ( " default_flags_sh " ) ) ;
String8 default_compiler_sh = def_get_config_string ( scratch , vars_save_string_lit ( " default_compiler_sh " ) ) ;
if ( ! prj_generate_sh ( scratch , default_flags_sh , default_compiler_sh ,
2021-01-09 06:58:05 +00:00
script_path , script_file , code_file , output_dir , binary_file ) ) {
2019-06-01 23:33:31 +00:00
print_message ( app , string_u8_litexpr ( " could not create build.sh for new project \n " ) ) ;
2018-06-02 00:29:36 +00:00
}
2017-11-09 18:30:24 +00:00
}
else {
2019-06-01 23:33:31 +00:00
print_message ( app , string_u8_litexpr ( " the shell script already exists, no changes made to it \n " ) ) ;
2017-11-09 18:30:24 +00:00
}
}
2018-06-02 00:29:36 +00:00
if ( do_project_file ) {
if ( ! status . project_exists ) {
2021-01-09 06:58:05 +00:00
if ( ! prj_generate_project ( scratch , script_path , script_file , output_dir , binary_file ) ) {
2019-06-01 23:33:31 +00:00
print_message ( app , string_u8_litexpr ( " could not create project.4coder for new project \n " ) ) ;
2018-06-02 00:29:36 +00:00
}
2017-11-09 18:30:24 +00:00
}
else {
2019-06-01 23:33:31 +00:00
print_message ( app , string_u8_litexpr ( " project.4coder already exists, no changes made to it \n " ) ) ;
2017-11-09 18:30:24 +00:00
}
}
}
else {
2018-06-02 00:29:36 +00:00
if ( do_project_file ) {
2019-06-01 23:33:31 +00:00
print_message ( app , string_u8_litexpr ( " project already setup, no changes made \n " ) ) ;
2018-06-02 00:29:36 +00:00
}
2017-11-09 18:30:24 +00:00
}
2018-06-02 00:29:36 +00:00
}
2021-01-09 05:20:39 +00:00
////////////////////////////////
// NOTE(allen): Project Operations
function void
prj_exec_command ( Application_Links * app , Variable_Handle cmd_var ) {
Scratch_Block scratch ( app ) ;
String_ID os_id = vars_save_string_lit ( OS_NAME ) ;
String8 cmd = vars_string_from_var ( scratch , vars_read_key ( cmd_var , os_id ) ) ;
if ( cmd . size > 0 ) {
String_ID out_id = vars_save_string_lit ( " out " ) ;
String_ID footer_panel_id = vars_save_string_lit ( " footer_panel " ) ;
String_ID save_dirty_files_id = vars_save_string_lit ( " save_dirty_files " ) ;
String_ID cursor_at_end_id = vars_save_string_lit ( " cursor_at_end " ) ;
b32 save_dirty_files = vars_b32_from_var ( vars_read_key ( cmd_var , save_dirty_files_id ) ) ;
if ( save_dirty_files ) {
save_all_dirty_buffers ( app ) ;
}
u32 flags = CLI_OverlapWithConflict | CLI_SendEndSignal ;
b32 cursor_at_end = vars_b32_from_var ( vars_read_key ( cmd_var , cursor_at_end_id ) ) ;
if ( cursor_at_end ) {
flags | = CLI_CursorAtEnd ;
}
View_ID view = 0 ;
Buffer_Identifier buffer_id = { } ;
b32 set_fancy_font = false ;
String8 out = vars_string_from_var ( scratch , vars_read_key ( cmd_var , out_id ) ) ;
if ( out . size > 0 ) {
buffer_id = buffer_identifier ( out ) ;
b32 footer_panel = vars_b32_from_var ( vars_read_key ( cmd_var , footer_panel_id ) ) ;
if ( footer_panel ) {
view = get_or_open_build_panel ( app ) ;
if ( string_match ( out , string_u8_litexpr ( " *compilation* " ) ) ) {
set_fancy_font = true ;
}
}
else {
Buffer_ID buffer = buffer_identifier_to_id ( app , buffer_id ) ;
view = get_first_view_with_buffer ( app , buffer ) ;
if ( view = = 0 ) {
view = get_active_view ( app , Access_Always ) ;
}
}
block_zero_struct ( & prev_location ) ;
lock_jump_buffer ( app , out ) ;
}
else {
// TODO(allen): fix the exec_system_command call so it can take a null buffer_id.
buffer_id = buffer_identifier ( string_u8_litexpr ( " *dump* " ) ) ;
}
Variable_Handle command_list_var = vars_parent ( cmd_var ) ;
Variable_Handle prj_var = vars_parent ( command_list_var ) ;
String8 prj_dir = prj_path_from_project ( scratch , prj_var ) ;
exec_system_command ( app , view , buffer_id , prj_dir , cmd , flags ) ;
if ( set_fancy_font ) {
set_fancy_compilation_buffer_font ( app ) ;
}
}
2017-11-09 18:30:24 +00:00
}
2021-01-09 05:20:39 +00:00
function Variable_Handle
prj_command_from_name ( Application_Links * app , String8 cmd_name ) {
Scratch_Block scratch ( app ) ;
// TODO(allen): fallback for multiple stages of reading
Variable_Handle cmd_list = def_get_config_var ( vars_save_string_lit ( " commands " ) ) ;
Variable_Handle cmd = vars_read_key ( cmd_list , vars_save_string ( cmd_name ) ) ;
return ( cmd ) ;
2018-06-02 00:29:36 +00:00
}
2021-01-09 05:20:39 +00:00
function void
prj_exec_command_name ( Application_Links * app , String8 cmd_name ) {
Scratch_Block scratch ( app ) ;
Variable_Handle cmd = prj_command_from_name ( app , cmd_name ) ;
prj_exec_command ( app , cmd ) ;
2018-06-02 00:29:36 +00:00
}
2021-01-09 05:20:39 +00:00
function void
prj_exec_command_fkey_index ( Application_Links * app , i32 fkey_index ) {
// TODO(allen): ideally if one fkey_command is missing this index the fallback
// can be continued.
Variable_Handle fkeys = def_get_config_var ( vars_save_string_lit ( " fkey_command " ) ) ;
// TODO(allen): Ideally I could just pass fkey_index right to vars_read_key
// in a case like this.
Scratch_Block scratch ( app ) ;
String8 fkey_index_str = push_stringf ( scratch , " %d " , fkey_index ) ;
String_ID fkey_index_id = vars_save_string ( fkey_index_str ) ;
Variable_Handle cmd_name_var = vars_read_key ( fkeys , fkey_index_id ) ;
String8 cmd_name = vars_string_from_var ( scratch , cmd_name_var ) ;
prj_exec_command_name ( app , cmd_name ) ;
2018-06-02 00:29:36 +00:00
}
2021-01-09 05:20:39 +00:00
function String8
prj_path_from_project ( Arena * arena , Variable_Handle project ) {
String8 project_full_path = vars_string_from_var ( arena , project ) ;
String8 project_dir = string_remove_last_folder ( project_full_path ) ;
return ( project_dir ) ;
}
2018-09-17 18:47:06 +00:00
2021-01-06 05:00:37 +00:00
function Variable_Handle
2021-01-09 05:20:39 +00:00
prj_cmd_from_user ( Application_Links * app , Variable_Handle prj_var , String8 query ) {
2021-01-06 05:00:37 +00:00
Scratch_Block scratch ( app ) ;
Lister_Block lister ( app , scratch ) ;
lister_set_query ( lister , query ) ;
lister_set_default_handlers ( lister ) ;
Variable_Handle cmd_list_var = vars_read_key ( prj_var , vars_save_string_lit ( " commands " ) ) ;
String_ID os_id = vars_save_string_lit ( OS_NAME ) ;
for ( Variable_Handle cmd = vars_first_child ( cmd_list_var ) ;
! vars_is_nil ( cmd ) ;
cmd = vars_next_sibling ( cmd ) ) {
Variable_Handle os_cmd = vars_read_key ( cmd , os_id ) ;
if ( ! vars_is_nil ( os_cmd ) ) {
2021-01-09 05:20:39 +00:00
String8 cmd_name = vars_key_from_var ( scratch , cmd ) ;
String8 os_cmd_str = vars_string_from_var ( scratch , os_cmd ) ;
2021-01-06 05:00:37 +00:00
lister_add_item ( lister , cmd_name , os_cmd_str , cmd . ptr , 0 ) ;
}
}
Variable_Handle result = vars_get_nil ( ) ;
Lister_Result l_result = run_lister ( app , lister ) ;
if ( ! l_result . canceled ) {
if ( l_result . user_data ! = 0 ) {
result . ptr = ( Variable * ) l_result . user_data ;
}
}
return ( result ) ;
}
2021-01-09 05:20:39 +00:00
////////////////////////////////
// NOTE(allen): Commands
CUSTOM_COMMAND_SIG ( close_all_code )
CUSTOM_DOC ( " Closes any buffer with a filename ending with an extension configured to be recognized as a code file type. " )
{
Scratch_Block scratch ( app ) ;
String8 treat_as_code = def_get_config_string ( scratch , vars_save_string_lit ( " treat_as_code " ) ) ;
String8Array extensions = parse_extension_line_to_extension_list ( app , scratch , treat_as_code ) ;
prj_close_files_with_ext ( app , extensions ) ;
}
CUSTOM_COMMAND_SIG ( open_all_code )
CUSTOM_DOC ( " Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config. " )
{
Scratch_Block scratch ( app ) ;
String8 treat_as_code = def_get_config_string ( scratch , vars_save_string_lit ( " treat_as_code " ) ) ;
String8Array extensions = parse_extension_line_to_extension_list ( app , scratch , treat_as_code ) ;
prj_open_all_files_with_ext_in_hot ( app , extensions , 0 ) ;
}
CUSTOM_COMMAND_SIG ( open_all_code_recursive )
CUSTOM_DOC ( " Works as open_all_code but also runs in all subdirectories. " )
{
Scratch_Block scratch ( app ) ;
String8 treat_as_code = def_get_config_string ( scratch , vars_save_string_lit ( " treat_as_code " ) ) ;
String8Array extensions = parse_extension_line_to_extension_list ( app , scratch , treat_as_code ) ;
prj_open_all_files_with_ext_in_hot ( app , extensions , PrjOpenFileFlag_Recursive ) ;
}
CUSTOM_COMMAND_SIG ( load_project )
CUSTOM_DOC ( " Looks for a project.4coder file in the current directory and tries to load it. Looks in parent directories until a project file is found or there are no more parents. " )
{
ProfileScope ( app , " load project " ) ;
save_all_dirty_buffers ( app ) ;
Scratch_Block scratch ( app ) ;
// NOTE(allen): Load the project file from the hot directory
String8 project_path = push_hot_directory ( app , scratch ) ;
File_Name_Data dump = dump_file_search_up_path ( app , scratch , project_path , string_u8_litexpr ( " project.4coder " ) ) ;
String8 project_root = string_remove_last_folder ( dump . file_name ) ;
if ( dump . data . str = = 0 ) {
print_message ( app , string_u8_litexpr ( " Did not find project.4coder. \n " ) ) ;
}
// NOTE(allen): Parse config data out of project file
Config * config_parse = 0 ;
Variable_Handle proj_var = vars_get_nil ( ) ;
if ( dump . data . str ! = 0 ) {
Token_Array array = token_array_from_text ( app , scratch , dump . data ) ;
if ( array . tokens ! = 0 ) {
config_parse = def_config_parse ( app , scratch , dump . file_name , dump . data , array ) ;
if ( config_parse ! = 0 ) {
i32 version = 0 ;
if ( config_parse - > version ! = 0 ) {
version = * config_parse - > version ;
}
switch ( version ) {
case 0 :
case 1 :
{
2021-01-09 06:58:05 +00:00
Prj * project = prj_parse_from_v1_config_data ( app , scratch , project_root , config_parse ) ;
2021-01-09 05:20:39 +00:00
proj_var = prj_version_1_to_version_2 ( app , config_parse , project ) ;
} break ;
default :
{
proj_var = def_fill_var_from_config ( app , vars_get_root ( ) , vars_save_string_lit ( " prj_config " ) , config_parse ) ;
} break ;
}
}
}
}
// NOTE(allen): Print Project
if ( ! vars_is_nil ( proj_var ) ) {
vars_print ( app , proj_var ) ;
print_message ( app , string_u8_litexpr ( " \n " ) ) ;
}
// NOTE(allen): Print Errors
if ( config_parse ! = 0 ) {
String8 error_text = config_stringize_errors ( app , scratch , config_parse ) ;
if ( error_text . size > 0 ) {
print_message ( app , string_u8_litexpr ( " Project errors: \n " ) ) ;
print_message ( app , error_text ) ;
print_message ( app , string_u8_litexpr ( " \n " ) ) ;
}
}
// NOTE(allen): Open All Project Files
Variable_Handle load_paths_var = vars_read_key ( proj_var , vars_save_string_lit ( " load_paths " ) ) ;
Variable_Handle load_paths_os_var = vars_read_key ( load_paths_var , vars_save_string_lit ( OS_NAME ) ) ;
String_ID path_id = vars_save_string_lit ( " path " ) ;
String_ID recursive_id = vars_save_string_lit ( " recursive " ) ;
String_ID relative_id = vars_save_string_lit ( " relative " ) ;
Variable_Handle whitelist_var = vars_read_key ( proj_var , vars_save_string_lit ( " patterns " ) ) ;
Variable_Handle blacklist_var = vars_read_key ( proj_var , vars_save_string_lit ( " blacklist_patterns " ) ) ;
2021-01-09 07:06:55 +00:00
Prj_Pattern_List whitelist = prj_pattern_list_from_var ( scratch , whitelist_var ) ;
Prj_Pattern_List blacklist = prj_pattern_list_from_var ( scratch , blacklist_var ) ;
2021-01-09 05:20:39 +00:00
for ( Variable_Handle load_path_var = vars_first_child ( load_paths_os_var ) ;
! vars_is_nil ( load_path_var ) ;
load_path_var = vars_next_sibling ( load_path_var ) ) {
Variable_Handle path_var = vars_read_key ( load_path_var , path_id ) ;
Variable_Handle recursive_var = vars_read_key ( load_path_var , recursive_id ) ;
Variable_Handle relative_var = vars_read_key ( load_path_var , relative_id ) ;
2019-10-25 23:33:50 +00:00
2021-01-09 05:20:39 +00:00
String8 path = vars_string_from_var ( scratch , path_var ) ;
b32 recursive = vars_b32_from_var ( recursive_var ) ;
b32 relative = vars_b32_from_var ( relative_var ) ;
u32 flags = 0 ;
if ( recursive ) {
flags | = PrjOpenFileFlag_Recursive ;
2019-10-25 23:33:50 +00:00
}
2021-01-09 05:20:39 +00:00
String8 file_dir = path ;
if ( relative ) {
String8 prj_dir = prj_path_from_project ( scratch , proj_var ) ;
String8List file_dir_list = { } ;
string_list_push ( scratch , & file_dir_list , prj_dir ) ;
string_list_push_overlap ( scratch , & file_dir_list , ' / ' , path ) ;
string_list_push_overlap ( scratch , & file_dir_list , ' / ' , SCu8 ( ) ) ;
file_dir = string_list_flatten ( scratch , file_dir_list , StringFill_NullTerminate ) ;
2019-10-25 23:33:50 +00:00
}
2021-01-09 05:20:39 +00:00
prj_open_files_pattern_filter ( app , file_dir , whitelist , blacklist , flags ) ;
2019-10-25 23:33:50 +00:00
}
2021-01-09 05:20:39 +00:00
// NOTE(allen): Set Window Title
Variable_Handle proj_name_var = vars_read_key ( proj_var , vars_save_string_lit ( " project_name " ) ) ;
String_ID proj_name_id = vars_key_id_from_var ( proj_var ) ;
if ( proj_name_id ! = 0 ) {
String8 proj_name = vars_read_string ( scratch , proj_name_id ) ;
String8 title = push_u8_stringf ( scratch , " 4coder project: %.*s " , string_expand ( proj_name ) ) ;
set_window_title ( app , title ) ;
}
}
CUSTOM_COMMAND_SIG ( project_fkey_command )
CUSTOM_DOC ( " Run an 'fkey command' configured in a project.4coder file. Determines the index of the 'fkey command' by which function key or numeric key was pressed to trigger the command. " )
{
ProfileScope ( app , " project fkey command " ) ;
User_Input input = get_current_input ( app ) ;
b32 got_ind = false ;
i32 ind = 0 ;
if ( input . event . kind = = InputEventKind_KeyStroke ) {
if ( KeyCode_F1 < = input . event . key . code & & input . event . key . code < = KeyCode_F16 ) {
ind = ( input . event . key . code - KeyCode_F1 ) ;
got_ind = true ;
}
else if ( KeyCode_1 < = input . event . key . code & & input . event . key . code < = KeyCode_9 ) {
ind = ( input . event . key . code - ' 1 ' ) ;
got_ind = true ;
}
else if ( input . event . key . code = = KeyCode_0 ) {
ind = 9 ;
got_ind = true ;
}
if ( got_ind ) {
prj_exec_command_fkey_index ( app , ind ) ;
}
}
}
CUSTOM_COMMAND_SIG ( project_go_to_root_directory )
CUSTOM_DOC ( " Changes 4coder's hot directory to the root directory of the currently loaded project. With no loaded project nothing hapepns. " )
{
Scratch_Block scratch ( app ) ;
Variable_Handle prj_var = vars_read_key ( vars_get_root ( ) , vars_save_string_lit ( " prj_config " ) ) ;
String8 prj_dir = prj_path_from_project ( scratch , prj_var ) ;
if ( prj_dir . size > 0 ) {
set_hot_directory ( app , prj_dir ) ;
}
}
CUSTOM_COMMAND_SIG ( setup_new_project )
CUSTOM_DOC ( " Queries the user for several configuration options and initializes a new 4coder project with build scripts for every OS. " )
{
2021-01-09 06:58:05 +00:00
prj_setup_scripts ( app , PrjSetupScriptFlag_Project | PrjSetupScriptFlag_Bat | PrjSetupScriptFlag_Sh ) ;
2021-01-09 05:20:39 +00:00
load_project ( app ) ;
}
CUSTOM_COMMAND_SIG ( setup_build_bat )
CUSTOM_DOC ( " Queries the user for several configuration options and initializes a new build batch script. " )
{
2021-01-09 06:58:05 +00:00
prj_setup_scripts ( app , PrjSetupScriptFlag_Bat ) ;
2021-01-09 05:20:39 +00:00
}
CUSTOM_COMMAND_SIG ( setup_build_sh )
CUSTOM_DOC ( " Queries the user for several configuration options and initializes a new build shell script. " )
{
2021-01-09 06:58:05 +00:00
prj_setup_scripts ( app , PrjSetupScriptFlag_Sh ) ;
2021-01-09 05:20:39 +00:00
}
CUSTOM_COMMAND_SIG ( setup_build_bat_and_sh )
CUSTOM_DOC ( " Queries the user for several configuration options and initializes a new build batch script. " )
{
2021-01-09 06:58:05 +00:00
prj_setup_scripts ( app , PrjSetupScriptFlag_Bat | PrjSetupScriptFlag_Sh ) ;
2019-10-25 23:33:50 +00:00
}
2018-09-17 18:47:06 +00:00
CUSTOM_COMMAND_SIG ( project_command_lister )
CUSTOM_DOC ( " Open a lister of all commands in the currently loaded project. " )
{
2021-01-06 05:00:37 +00:00
Variable_Handle prj_var = vars_read_key ( vars_get_root ( ) , vars_save_string_lit ( " prj_config " ) ) ;
Variable_Handle prj_cmd = prj_cmd_from_user ( app , prj_var , string_u8_litexpr ( " Command: " ) ) ;
if ( ! vars_is_nil ( prj_cmd ) ) {
prj_exec_command ( app , prj_cmd ) ;
2018-09-17 18:47:06 +00:00
}
}
2017-01-29 00:03:23 +00:00
// BOTTOM