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
2019-10-25 06:17:54 +00:00
global Project current_project = { } ;
2020-03-11 23:22:37 +00:00
global Arena current_project_arena = { } ;
2018-05-09 05:22:33 +00:00
///////////////////////////////
2019-10-25 06:17:54 +00:00
function Project_File_Pattern_Array
2019-06-01 23:33:31 +00:00
get_pattern_array_from_string_array ( Arena * arena , String_Const_u8_Array list ) {
2018-11-20 08:18:54 +00:00
Project_File_Pattern_Array array = { } ;
2019-06-01 23:33:31 +00:00
array . count = list . count ;
array . patterns = push_array ( arena , Project_File_Pattern , list . count ) ;
for ( i32 i = 0 ; i < list . count ; + + i ) {
2019-06-18 22:56:09 +00:00
String_Const_u8 str = push_u8_stringf ( arena , " *.%.*s " , string_expand ( list . strings [ i ] ) ) ;
2019-06-01 23:33:31 +00:00
array . patterns [ i ] . absolutes = string_split_wildcards ( arena , str ) ;
2018-05-08 07:14:23 +00:00
}
2018-05-09 05:22:33 +00:00
return ( array ) ;
}
///////////////////////////////
2019-10-25 06:17:54 +00:00
function void
2019-06-01 23:33:31 +00:00
close_all_files_with_extension ( Application_Links * app , String_Const_u8_Array extension_array ) {
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 ) ;
2019-06-02 03:07:57 +00:00
String_Const_u8 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 ) {
2019-06-01 23:33:31 +00:00
String_Const_u8 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
}
2019-10-25 06:17:54 +00:00
function b32
2019-06-01 23:33:31 +00:00
match_in_pattern_array ( String_Const_u8 string , Project_File_Pattern_Array array ) {
2019-02-26 23:08:42 +00:00
b32 found_match = false ;
2018-05-26 07:49:37 +00:00
Project_File_Pattern * pattern = array . patterns ;
2019-02-26 23:08:42 +00:00
for ( i32 i = 0 ; i < array . count ; + + i , + + pattern ) {
2019-06-01 23:33:31 +00:00
if ( string_wildcard_match ( pattern - > absolutes , string , StringMatch_Exact ) ) {
2018-05-26 07:49:37 +00:00
found_match = true ;
break ;
}
}
return ( found_match ) ;
}
2019-10-25 06:17:54 +00:00
function void
open_files_pattern_match__recursive ( Application_Links * app , String_Const_u8 path ,
Project_File_Pattern_Array whitelist ,
Project_File_Pattern_Array blacklist ,
u32 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 ) {
2019-08-04 00:49:40 +00:00
String_Const_u8 file_name = ( * * info ) . file_name ;
2019-06-01 23:33:31 +00:00
2019-08-04 00:49:40 +00:00
if ( HasFlag ( ( * * info ) . attributes . flags , FileAttribute_IsDirectory ) ) {
if ( ( flags & OpenAllFilesFlag_Recursive ) = = 0 ) continue ;
if ( match_in_pattern_array ( file_name , blacklist ) ) continue ;
2018-05-26 07:49:37 +00:00
2019-06-18 22:56:09 +00:00
String_Const_u8 new_path = push_u8_stringf ( scratch , " %.*s%.*s/ " ,
2019-06-01 23:33:31 +00:00
string_expand ( path ) ,
string_expand ( file_name ) ) ;
2019-12-18 00:19:03 +00:00
open_files_pattern_match__recursive ( app , new_path , whitelist , blacklist , flags ) ;
2018-05-09 05:22:33 +00:00
}
else {
2019-06-01 23:33:31 +00:00
if ( ! match_in_pattern_array ( file_name , whitelist ) ) {
2018-05-26 07:49:37 +00:00
continue ;
2018-05-09 05:22:33 +00:00
}
2019-06-01 23:33:31 +00:00
if ( match_in_pattern_array ( file_name , blacklist ) ) {
2018-05-26 07:49:37 +00:00
continue ;
2018-05-09 05:22:33 +00:00
}
2018-05-26 07:49:37 +00:00
2019-06-18 22:56:09 +00:00
String_Const_u8 full_path = push_u8_stringf ( scratch , " %.*s%.*s " ,
2019-06-01 23:33:31 +00:00
string_expand ( path ) ,
string_expand ( file_name ) ) ;
2019-10-26 20:48:50 +00:00
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 Project_File_Pattern_Array
2019-06-01 23:33:31 +00:00
get_standard_blacklist ( Arena * arena ) {
String_Const_u8 dot = string_u8_litexpr ( " .* " ) ;
String_Const_u8_Array black_array = { } ;
black_array . strings = & dot ;
2018-05-26 07:49:37 +00:00
black_array . count = 1 ;
2019-06-01 23:33:31 +00:00
return ( get_pattern_array_from_string_array ( arena , black_array ) ) ;
2018-05-26 07:49:37 +00:00
}
2019-10-25 06:17:54 +00:00
function void
2019-11-07 05:58:08 +00:00
open_files_pattern_match ( Application_Links * app , String_Const_u8 dir , Project_File_Pattern_Array whitelist , Project_File_Pattern_Array blacklist , u32 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 ) ;
String_Const_u8 directory = dir ;
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
}
2019-10-25 06:17:54 +00:00
open_files_pattern_match__recursive ( app , directory , whitelist , blacklist , flags ) ;
2018-05-26 07:49:37 +00:00
}
2019-10-25 06:17:54 +00:00
function void
open_files_with_extension ( Application_Links * app , String_Const_u8 dir , String_Const_u8_Array array , u32 flags ) {
2019-06-01 23:33:31 +00:00
Scratch_Block scratch ( app ) ;
Project_File_Pattern_Array whitelist = get_pattern_array_from_string_array ( scratch , array ) ;
2018-05-26 07:49:37 +00:00
Project_File_Pattern_Array blacklist = get_standard_blacklist ( scratch ) ;
2019-10-25 06:17:54 +00:00
open_files_pattern_match ( app , dir , whitelist , blacklist , flags ) ;
2018-05-09 05:22:33 +00:00
}
2019-10-25 06:17:54 +00:00
function void
2019-06-01 23:33:31 +00:00
open_all_files_in_hot_with_extension ( Application_Links * app , String_Const_u8_Array array , u32 flags ) {
Scratch_Block scratch ( app ) ;
String_Const_u8 hot = push_hot_directory ( app , scratch ) ;
String_Const_u8 directory = hot ;
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
}
2019-10-25 06:17:54 +00:00
open_files_with_extension ( app , hot , array , flags ) ;
2018-05-09 05:22:33 +00:00
}
///////////////////////////////
2018-05-08 07:14:23 +00:00
2019-06-01 23:33:31 +00:00
# if OS_WINDOWS
2018-05-26 07:49:37 +00:00
# define PlatformName "win"
2019-06-01 23:33:31 +00:00
# elif OS_LINUX
2018-05-26 07:49:37 +00:00
# define PlatformName "linux"
2019-06-01 23:33:31 +00:00
# elif OS_MAC
2018-05-26 07:49:37 +00:00
# define PlatformName "mac"
# else
# error no project configuration names for this platform
# endif
2019-10-25 06:17:54 +00:00
function void
2019-06-01 23:33:31 +00:00
parse_project__extract_pattern_array ( Arena * arena , Config * parsed , char * root_variable_name , Project_File_Pattern_Array * array_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 ) ;
2018-05-26 07:49:37 +00:00
2018-05-30 20:27:47 +00:00
array_out - > patterns = push_array ( arena , Project_File_Pattern , list . count ) ;
array_out - > count = list . count ;
2018-05-26 07:49:37 +00:00
2019-02-26 23:08:42 +00:00
i32 i = 0 ;
2018-05-30 20:27:47 +00:00
for ( Config_Get_Result_Node * node = list . first ;
node ! = 0 ;
node = node - > next , i + = 1 ) {
2019-07-13 00:43:17 +00:00
String_Const_u8 str = push_string_copy ( arena , node - > result . string ) ;
2019-06-01 23:33:31 +00:00
array_out - > patterns [ i ] . absolutes = string_split_wildcards ( arena , str ) ;
2018-05-26 07:49:37 +00:00
}
}
}
2019-10-25 06:17:54 +00:00
function Project_OS_Match_Level
2019-06-01 23:33:31 +00:00
parse_project__version_1__os_match ( String_Const_u8 str , String_Const_u8 this_os_str ) {
if ( string_match ( str , this_os_str ) ) {
2018-06-16 20:57:32 +00:00
return ( ProjectOSMatchLevel_ActiveMatch ) ;
}
2019-06-01 23:33:31 +00:00
else if ( string_match ( str , string_u8_litexpr ( " all " ) ) ) {
2018-06-16 20:57:32 +00:00
return ( ProjectOSMatchLevel_ActiveMatch ) ;
}
2019-06-01 23:33:31 +00:00
else if ( string_match ( str , string_u8_litexpr ( " default " ) ) ) {
2018-06-16 20:57:32 +00:00
return ( ProjectOSMatchLevel_PassiveMatch ) ;
}
return ( ProjectOSMatchLevel_NoMatch ) ;
}
2019-10-25 06:17:54 +00:00
function Project *
2019-11-07 05:58:08 +00:00
parse_project__config_data__version_1 ( Application_Links * app , Arena * arena , String_Const_u8 root_dir , Config * parsed ) {
2019-06-01 23:33:31 +00:00
Project * project = push_array_zero ( arena , Project , 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
{
2019-06-01 23:33:31 +00:00
String_Const_u8 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
parse_project__extract_pattern_array ( arena , parsed , " patterns " , & project - > pattern_array ) ;
// blacklist_patterns
parse_project__extract_pattern_array ( arena , parsed , " blacklist_patterns " , & project - > blacklist_pattern_array ) ;
// 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 ) ) {
2019-06-01 23:33:31 +00:00
String_Const_u8 str = { } ;
2018-05-26 07:49:37 +00:00
if ( config_compound_string_member ( parsed , paths_option , " os " , 1 , & str ) ) {
2019-06-01 23:33:31 +00:00
Project_OS_Match_Level r = parse_project__version_1__os_match ( str , string_u8_litexpr ( PlatformName ) ) ;
2018-06-16 20:57:32 +00:00
if ( r = = ProjectOSMatchLevel_ActiveMatch ) {
found_match = true ;
best_paths = paths ;
break ;
}
else if ( r = = ProjectOSMatchLevel_PassiveMatch ) {
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
2018-06-16 20:57:32 +00:00
project - > load_path_array . paths = push_array ( arena , Project_File_Load_Path , list . count ) ;
project - > load_path_array . count = list . count ;
Project_File_Load_Path * dst = project - > load_path_array . paths ;
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
2019-06-01 23:33:31 +00:00
String_Const_u8 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
2018-05-30 20:27:47 +00:00
project - > command_array . commands = push_array ( arena , Project_Command , list . count ) ;
project - > command_array . count = list . count ;
2018-05-26 07:49:37 +00:00
Project_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 ;
String_Const_u8 cmd_str = { } ;
String_Const_u8 out = { } ;
2019-02-26 23:08:42 +00:00
b32 footer_panel = false ;
b32 save_dirty_files = true ;
b32 cursor_at_end = false ;
2019-06-01 23:33:31 +00:00
String_Const_u8 name = { } ;
2018-05-30 20:27:47 +00:00
if ( ! config_compound_string_member ( parsed , src , " name " , 0 , & name ) ) {
can_emit_command = false ;
2018-06-02 04:06:13 +00:00
config_add_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 ;
2018-06-02 04:06:13 +00:00
config_add_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
2019-06-01 23:33:31 +00:00
String_Const_u8 cmd = { } ;
2018-05-30 20:27:47 +00:00
if ( config_compound_string_member ( parsed , cmd_option , " cmd " , 0 , & cmd ) ) {
2019-06-01 23:33:31 +00:00
String_Const_u8 str = { } ;
2018-05-30 20:27:47 +00:00
if ( config_compound_string_member ( parsed , cmd_option , " os " , 1 , & str ) ) {
2019-06-01 23:33:31 +00:00
Project_OS_Match_Level r = parse_project__version_1__os_match ( str , string_u8_litexpr ( PlatformName ) ) ;
2018-06-16 20:57:32 +00:00
if ( r = = ProjectOSMatchLevel_ActiveMatch ) {
can_emit_command = true ;
cmd_str = cmd ;
break ;
}
else if ( r = = ProjectOSMatchLevel_PassiveMatch ) {
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 ) {
config_add_error ( arena , parsed , cmd_pos , " no usable command strings found in cmd " ) ;
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 ) {
2019-06-01 23:33:31 +00:00
String_Const_u8 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 ;
2018-05-26 07:49:37 +00:00
Project_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 Project *
2019-11-07 05:58:08 +00:00
parse_project__config_data ( Application_Links * app , Arena * arena , String_Const_u8 file_dir , Config * parsed ) {
2019-02-26 23:08:42 +00:00
i32 version = 0 ;
2018-05-26 07:49:37 +00:00
if ( parsed - > version ! = 0 ) {
version = * parsed - > version ;
}
2019-11-07 05:58:08 +00:00
Project * result = 0 ;
2018-05-26 07:49:37 +00:00
switch ( version ) {
case 1 :
{
2019-11-07 05:58:08 +00:00
result = parse_project__config_data__version_1 ( app , arena , file_dir , parsed ) ;
2018-05-26 07:49:37 +00:00
} break ;
}
2019-11-07 05:58:08 +00:00
return ( result ) ;
2018-05-26 07:49:37 +00:00
}
2019-10-25 06:17:54 +00:00
function Project_Parse_Result
2019-11-07 05:58:08 +00:00
parse_project__data ( Application_Links * app , Arena * arena , String_Const_u8 file_name , Data raw_data , String_Const_u8 file_dir ) {
2019-06-01 23:33:31 +00:00
String_Const_u8 data = SCu8 ( raw_data ) ;
2018-11-20 08:18:54 +00:00
Project_Parse_Result result = { } ;
2019-10-25 06:17:54 +00:00
Token_Array array = token_array_from_text ( app , arena , data ) ;
2018-05-26 07:49:37 +00:00
if ( array . tokens ! = 0 ) {
2019-10-25 06:17:54 +00:00
result . parsed = config_parse ( app , arena , file_name , data , array ) ;
2018-05-26 07:49:37 +00:00
if ( result . parsed ! = 0 ) {
2019-10-25 06:17:54 +00:00
result . project = parse_project__config_data ( app , arena , file_dir ,
result . parsed ) ;
2018-05-26 07:49:37 +00:00
}
}
return ( result ) ;
2018-05-19 22:05:31 +00:00
}
2019-10-25 06:17:54 +00:00
function Project_Parse_Result
2019-06-01 23:33:31 +00:00
parse_project__nearest_file ( Application_Links * app , Arena * arena ) {
2018-11-20 08:18:54 +00:00
Project_Parse_Result result = { } ;
2018-05-19 22:05:31 +00:00
2019-06-01 23:33:31 +00:00
Temp_Memory restore_point = begin_temp ( arena ) ;
2019-06-20 04:45:58 +00:00
String_Const_u8 project_path = push_hot_directory ( app , arena ) ;
2019-06-01 23:33:31 +00:00
if ( project_path . size = = 0 ) {
print_message ( app , string_u8_litexpr ( " The hot directory is empty, cannot search for a project. \n " ) ) ;
}
else {
File_Name_Data dump = dump_file_search_up_path ( app , arena , project_path , string_u8_litexpr ( " project.4coder " ) ) ;
if ( dump . data . data ! = 0 ) {
String_Const_u8 project_root = string_remove_last_folder ( dump . file_name ) ;
2019-10-25 06:17:54 +00:00
result = parse_project__data ( app , arena , dump . file_name , dump . data ,
project_root ) ;
2017-06-20 20:37:45 +00:00
}
2018-05-19 22:05:31 +00:00
else {
2019-06-01 23:33:31 +00:00
List_String_Const_u8 list = { } ;
string_list_push ( arena , & list , string_u8_litexpr ( " Did not find project.4coder. " ) ) ;
if ( current_project . loaded ) {
string_list_push ( arena , & list , string_u8_litexpr ( " Continuing with: " ) ) ;
if ( current_project . name . size > 0 ) {
string_list_push ( arena , & list , current_project . name ) ;
2018-05-19 22:05:31 +00:00
}
else {
2019-06-01 23:33:31 +00:00
string_list_push ( arena , & list , current_project . dir ) ;
2018-05-19 22:05:31 +00:00
}
}
2019-06-01 23:33:31 +00:00
else {
string_list_push ( arena , & list , string_u8_litexpr ( " Continuing without a project. " ) ) ;
}
string_list_push ( arena , & list , string_u8_litexpr ( " \n " ) ) ;
String_Const_u8 message = string_list_flatten ( arena , list ) ;
print_message ( app , message ) ;
end_temp ( restore_point ) ;
2017-01-29 00:03:23 +00:00
}
2017-03-27 22:36:42 +00:00
}
2018-05-19 22:05:31 +00:00
2018-05-26 07:49:37 +00:00
return ( result ) ;
2018-05-19 22:05:31 +00:00
}
2019-10-25 06:17:54 +00:00
function void
2019-06-01 23:33:31 +00:00
project_deep_copy__pattern_array ( Arena * arena , Project_File_Pattern_Array * src_array , Project_File_Pattern_Array * dst_array ) {
2019-02-26 23:08:42 +00:00
i32 pattern_count = src_array - > count ;
2018-05-26 07:49:37 +00:00
dst_array - > patterns = push_array ( arena , Project_File_Pattern , pattern_count ) ;
dst_array - > count = pattern_count ;
Project_File_Pattern * dst = dst_array - > patterns ;
Project_File_Pattern * src = src_array - > patterns ;
2019-02-26 23:08:42 +00:00
for ( i32 i = 0 ; i < pattern_count ; + + i , + + dst , + + src ) {
2019-06-01 23:33:31 +00:00
for ( Node_String_Const_u8 * node = src - > absolutes . first ;
node ! = 0 ;
node = node - > next ) {
2020-02-08 02:22:14 +00:00
String_Const_u8 string = push_string_copy ( arena , node - > string ) ;
string_list_push ( arena , & dst - > absolutes , string ) ;
2018-05-26 07:49:37 +00:00
}
}
}
2019-10-25 06:17:54 +00:00
function Project
2019-06-01 23:33:31 +00:00
project_deep_copy__inner ( Arena * arena , Project * project ) {
2018-11-20 08:18:54 +00:00
Project 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 ) ;
2019-06-01 23:33:31 +00:00
project_deep_copy__pattern_array ( arena , & project - > pattern_array , & result . pattern_array ) ;
project_deep_copy__pattern_array ( arena , & project - > blacklist_pattern_array , & result . blacklist_pattern_array ) ;
2018-05-26 07:49:37 +00:00
{
2019-02-26 23:08:42 +00:00
i32 path_count = project - > load_path_array . count ;
2018-05-26 07:49:37 +00:00
result . load_path_array . paths = push_array ( arena , Project_File_Load_Path , path_count ) ;
result . load_path_array . count = path_count ;
Project_File_Load_Path * dst = result . load_path_array . paths ;
Project_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 ;
2019-06-01 23:33:31 +00:00
result . command_array . commands = push_array_zero ( arena , Project_Command , command_count ) ;
2018-05-26 07:49:37 +00:00
result . command_array . count = command_count ;
Project_Command * dst = result . command_array . commands ;
Project_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 ) ;
}
2019-10-25 06:17:54 +00:00
function Project
2019-06-01 23:33:31 +00:00
project_deep_copy ( Arena * arena , Project * project ) {
Temp_Memory restore_point = begin_temp ( arena ) ;
2018-05-26 07:49:37 +00:00
Project result = project_deep_copy__inner ( arena , project ) ;
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 ) ;
}
2019-10-25 06:17:54 +00:00
function void
2019-06-01 23:33:31 +00:00
config_feedback_file_pattern_array ( Arena * arena , List_String_Const_u8 * list , char * name , Project_File_Pattern_Array * array ) {
string_list_pushf ( arena , list , " %s = { \n " , name ) ;
2018-05-28 05:30:31 +00:00
Project_File_Pattern * pattern = array - > patterns ;
2019-02-26 23:08:42 +00:00
for ( i32 i = 0 ; i < array - > count ; + + i , + + pattern ) {
2019-06-01 23:33:31 +00:00
string_list_push_u8_lit ( arena , list , " \" " ) ;
b32 is_first = true ;
for ( Node_String_Const_u8 * node = pattern - > absolutes . first ;
node ! = 0 ;
node = node - > next ) {
if ( is_first ) {
string_list_push ( arena , list , node - > string ) ;
is_first = false ;
}
else {
string_list_pushf ( arena , list , " *%.*s " , string_expand ( node - > string ) ) ;
2018-05-28 05:30:31 +00:00
}
}
2019-06-01 23:33:31 +00:00
string_list_push_u8_lit ( arena , list , " \" , \n " ) ;
2018-05-28 05:30:31 +00:00
}
2019-06-01 23:33:31 +00:00
string_list_push_u8_lit ( arena , list , " }; \n " ) ;
2018-05-28 05:30:31 +00:00
}
2019-10-25 06:17:54 +00:00
function void
2019-06-01 23:33:31 +00:00
config_feedback_file_load_path_array ( Arena * arena , List_String_Const_u8 * list , char * name , Project_File_Load_Path_Array * array ) {
string_list_pushf ( arena , list , " %s = { \n " , name ) ;
2018-05-28 05:30:31 +00:00
Project_File_Load_Path * path = array - > paths ;
2019-02-26 23:08:42 +00:00
for ( i32 i = 0 ; i < array - > count ; + + i , + + path ) {
2019-06-01 23:33:31 +00:00
string_list_pushf ( arena , list , " { .path = \" %.*s \" , .recursive = %s, .relative = %s, }, \n " ,
string_expand ( path - > path ) , ( char * ) ( path - > recursive ? " true " : " false " ) , ( char * ) ( path - > relative ? " true " : " false " ) ) ;
2018-05-28 05:30:31 +00:00
}
2019-06-01 23:33:31 +00:00
string_list_push_u8_lit ( arena , list , " }; \n " ) ;
2018-05-28 05:30:31 +00:00
}
2019-10-25 06:17:54 +00:00
function void
2019-06-01 23:33:31 +00:00
config_feedback_command_array ( Arena * arena , List_String_Const_u8 * list , char * name , Project_Command_Array * array ) {
string_list_pushf ( arena , list , " %s = { \n " , name ) ;
2018-05-28 05:30:31 +00:00
Project_Command * command = array - > commands ;
2019-02-26 23:08:42 +00:00
for ( i32 i = 0 ; i < array - > count ; + + i , + + command ) {
2019-06-01 23:33:31 +00:00
string_list_pushf ( arena , list ,
" { .name = \" %.*s \" , .cmd = \" %.*s \" , .out = \" %.*s \" , "
" .footer_panel = %s, .save_dirty_files = %s, .cursor_at_end = %s, }, \n " ,
string_expand ( command - > name ) , string_expand ( command - > cmd ) , string_expand ( command - > out ) ,
( char * ) ( command - > footer_panel ? " true " : " false " ) ,
( char * ) ( command - > save_dirty_files ? " true " : " false " ) ,
( char * ) ( command - > cursor_at_end ? " true " : " false " ) ) ;
2018-05-28 05:30:31 +00:00
}
2019-06-01 23:33:31 +00:00
string_list_push_u8_lit ( arena , list , " }; \n " ) ;
2018-05-28 05:30:31 +00:00
}
2019-10-25 06:17:54 +00:00
function void
2019-06-01 23:33:31 +00:00
set_current_project ( Application_Links * app , Project * project , Config * parsed ) {
2019-02-26 23:08:42 +00:00
b32 print_feedback = false ;
2019-06-01 23:33:31 +00:00
Scratch_Block scratch ( app ) ;
2018-05-26 07:49:37 +00:00
if ( parsed ! = 0 & & project ! = 0 ) {
2020-03-11 23:22:37 +00:00
if ( current_project_arena . base_allocator = = 0 ) {
current_project_arena = make_arena_system ( ) ;
2018-05-26 07:49:37 +00:00
}
// Copy project to current_project
2020-03-11 23:22:37 +00:00
linalloc_clear ( & current_project_arena ) ;
Project new_project = project_deep_copy ( & current_project_arena , project ) ;
2018-05-26 07:49:37 +00:00
if ( new_project . loaded ) {
current_project = new_project ;
2018-05-28 05:30:31 +00:00
print_feedback = true ;
2018-05-26 07:49:37 +00:00
2020-11-24 06:27:33 +00:00
// NOTE(allen): Set the normal search list's project slot
def_search_project_path = current_project . dir ;
2018-05-26 07:49:37 +00:00
// Open all project files
2019-02-26 23:08:42 +00:00
for ( i32 i = 0 ; i < current_project . load_path_array . count ; + + i ) {
2018-05-26 07:49:37 +00:00
Project_File_Load_Path * load_path = & current_project . load_path_array . paths [ i ] ;
2019-02-26 23:08:42 +00:00
u32 flags = 0 ;
2018-05-26 07:49:37 +00:00
if ( load_path - > recursive ) {
flags | = OpenAllFilesFlag_Recursive ;
}
2019-06-01 23:33:31 +00:00
Temp_Memory temp = begin_temp ( scratch ) ;
String_Const_u8 path_str = load_path - > path ;
String_Const_u8 file_dir = path_str ;
2018-05-26 07:49:37 +00:00
if ( load_path - > relative ) {
2019-06-01 23:33:31 +00:00
String_Const_u8 project_dir = current_project . dir ;
List_String_Const_u8 file_dir_list = { } ;
string_list_push ( scratch , & file_dir_list , project_dir ) ;
string_list_push_overlap ( scratch , & file_dir_list , ' / ' , path_str ) ;
string_list_push_overlap ( scratch , & file_dir_list , ' / ' , SCu8 ( ) ) ;
file_dir = string_list_flatten ( scratch , file_dir_list , StringFill_NullTerminate ) ;
2018-05-26 07:49:37 +00:00
}
Project_File_Pattern_Array whitelist = current_project . pattern_array ;
Project_File_Pattern_Array blacklist = current_project . blacklist_pattern_array ;
2019-10-25 06:17:54 +00:00
open_files_pattern_match ( app , file_dir , whitelist , blacklist , flags ) ;
2019-06-01 23:33:31 +00:00
end_temp ( temp ) ;
2018-05-26 07:49:37 +00:00
}
// Set window title
if ( project - > name . size > 0 ) {
2019-06-01 23:33:31 +00:00
Temp_Memory temp = begin_temp ( scratch ) ;
2019-06-18 22:56:09 +00:00
String_Const_u8 builder = push_u8_stringf ( scratch , " 4coder project: %.*s " ,
2019-06-01 23:33:31 +00:00
string_expand ( project - > name ) ) ;
set_window_title ( app , builder ) ;
end_temp ( temp ) ;
2018-05-26 07:49:37 +00:00
}
}
else {
# define M "Failed to initialize new project; need more memory dedicated to the project system.\n"
2019-06-01 23:33:31 +00:00
print_message ( app , string_u8_litexpr ( M ) ) ;
2018-05-26 07:49:37 +00:00
# undef M
}
}
else if ( parsed ! = 0 ) {
2018-05-28 05:30:31 +00:00
print_feedback = true ;
2018-05-26 07:49:37 +00:00
}
2018-05-28 05:30:31 +00:00
if ( print_feedback ) {
2019-06-01 23:33:31 +00:00
Temp_Memory temp = begin_temp ( scratch ) ;
2018-05-28 05:30:31 +00:00
// Errors
2019-10-25 06:17:54 +00:00
String_Const_u8 error_text = config_stringize_errors ( app , scratch , parsed ) ;
2020-05-01 14:38:57 +00:00
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 " ) ) ;
}
2018-05-28 05:30:31 +00:00
// Values
if ( project = = 0 ) {
2019-06-01 23:33:31 +00:00
print_message ( app , string_u8_litexpr ( " Could not instantiate project \n " ) ) ;
2018-05-28 05:30:31 +00:00
}
else {
2020-05-01 14:38:57 +00:00
print_message ( app , string_u8_litexpr ( " New project contents: \n " ) ) ;
2019-06-01 23:33:31 +00:00
Temp_Memory temp2 = begin_temp ( scratch ) ;
List_String_Const_u8 list = { } ;
2018-05-28 05:30:31 +00:00
2019-06-01 23:33:31 +00:00
config_feedback_string ( scratch , & list , " 'root_directory' " , project - > dir ) ;
config_feedback_string ( scratch , & list , " project_name " , project - > name ) ;
2018-05-28 05:30:31 +00:00
2019-06-01 23:33:31 +00:00
config_feedback_file_pattern_array ( scratch , & list , " patterns " , & project - > pattern_array ) ;
config_feedback_file_pattern_array ( scratch , & list , " blacklist_patterns " , & project - > blacklist_pattern_array ) ;
config_feedback_file_load_path_array ( scratch , & list , " load_paths " , & project - > load_path_array ) ;
config_feedback_command_array ( scratch , & list , " command_list " , & project - > command_array ) ;
string_list_push_u8_lit ( scratch , & list , " \n " ) ;
String_Const_u8 message = string_list_flatten ( scratch , list ) ;
print_message ( app , message ) ;
end_temp ( temp2 ) ;
2018-05-28 05:30:31 +00:00
}
2019-06-01 23:33:31 +00:00
end_temp ( temp ) ;
2018-05-26 07:49:37 +00:00
}
2018-05-19 22:05:31 +00:00
}
2019-10-25 06:17:54 +00:00
function void
set_current_project_from_data ( Application_Links * app , String_Const_u8 file_name ,
Data data , String_Const_u8 file_dir ) {
2020-03-11 23:22:37 +00:00
Scratch_Block scratch ( app ) ;
Project_Parse_Result project_parse = parse_project__data ( app , scratch , file_name , data , file_dir ) ;
2019-06-01 23:33:31 +00:00
set_current_project ( app , project_parse . project , project_parse . parsed ) ;
2018-05-19 22:05:31 +00:00
}
2019-10-25 06:17:54 +00:00
function void
2019-06-01 23:33:31 +00:00
set_current_project_from_nearest_project_file ( Application_Links * app ) {
2020-03-11 23:22:37 +00:00
Scratch_Block scratch ( app ) ;
2018-05-26 07:49:37 +00:00
Project_Parse_Result project_parse = parse_project__nearest_file ( app , scratch ) ;
2019-06-01 23:33:31 +00:00
set_current_project ( app , project_parse . project , project_parse . parsed ) ;
2017-03-27 22:36:42 +00:00
}
2019-10-25 06:17:54 +00:00
function void
2018-06-16 20:57:32 +00:00
exec_project_command ( Application_Links * app , Project_Command * command ) {
if ( command - > cmd . size > 0 ) {
2019-02-26 23:08:42 +00:00
b32 footer_panel = command - > footer_panel ;
b32 save_dirty_files = command - > save_dirty_files ;
b32 cursor_at_end = command - > cursor_at_end ;
2018-05-08 07:14:23 +00:00
2018-05-26 07:49:37 +00:00
if ( save_dirty_files ) {
2018-05-08 07:14:23 +00:00
save_all_dirty_buffers ( app ) ;
}
2019-04-06 19:40:36 +00:00
View_ID view = 0 ;
2018-11-20 08:18:54 +00:00
Buffer_Identifier buffer_id = { } ;
2019-03-17 23:11:37 +00:00
u32 flags = CLI_OverlapWithConflict | CLI_SendEndSignal ;
2018-06-02 00:29:36 +00:00
if ( cursor_at_end ) {
flags | = CLI_CursorAtEnd ;
}
2018-05-08 07:14:23 +00:00
2019-02-26 23:08:42 +00:00
b32 set_fancy_font = false ;
2018-06-16 20:57:32 +00:00
if ( command - > out . size > 0 ) {
2019-06-01 23:33:31 +00:00
buffer_id = buffer_identifier ( command - > out ) ;
2018-05-08 07:14:23 +00:00
2018-05-26 07:49:37 +00:00
if ( footer_panel ) {
2018-05-09 05:22:33 +00:00
view = get_or_open_build_panel ( app ) ;
2019-06-01 23:33:31 +00:00
if ( string_match ( command - > out , string_u8_litexpr ( " *compilation* " ) ) ) {
2018-05-08 07:14:23 +00:00
set_fancy_font = true ;
}
}
else {
2019-04-15 19:43:58 +00:00
Buffer_ID buffer = buffer_identifier_to_id ( app , buffer_id ) ;
view = get_first_view_with_buffer ( app , buffer ) ;
if ( view = = 0 ) {
2019-10-18 02:54:02 +00:00
view = get_active_view ( app , Access_Always ) ;
2019-04-15 19:43:58 +00:00
}
2018-05-08 07:14:23 +00:00
}
2019-06-01 23:33:31 +00:00
block_zero_struct ( & prev_location ) ;
2019-08-16 02:54:06 +00:00
lock_jump_buffer ( app , command - > out ) ;
2018-05-08 07:14:23 +00:00
}
else {
// TODO(allen): fix the exec_system_command call so it can take a null buffer_id.
2019-06-01 23:33:31 +00:00
buffer_id = buffer_identifier ( string_u8_litexpr ( " *dump* " ) ) ;
2018-05-08 07:14:23 +00:00
}
2019-06-01 23:33:31 +00:00
String_Const_u8 dir = current_project . dir ;
String_Const_u8 cmd = command - > cmd ;
exec_system_command ( app , view , buffer_id , dir , cmd , flags ) ;
2018-05-08 07:14:23 +00:00
if ( set_fancy_font ) {
set_fancy_compilation_buffer_font ( app ) ;
}
}
}
2019-10-25 06:17:54 +00:00
function void
2019-02-26 23:08:42 +00:00
exec_project_command_by_index ( Application_Links * app , i32 command_index ) {
2018-09-17 18:47:06 +00:00
if ( ! current_project . loaded ) {
return ;
}
if ( command_index < 0 | | command_index > = current_project . command_array . count ) {
return ;
}
Project_Command * command = & current_project . command_array . commands [ command_index ] ;
exec_project_command ( app , command ) ;
}
2019-10-25 06:17:54 +00:00
function void
2019-02-26 23:08:42 +00:00
exec_project_fkey_command ( Application_Links * app , i32 fkey_index ) {
2018-06-16 20:57:32 +00:00
if ( ! current_project . loaded ) {
return ;
}
2019-02-26 23:08:42 +00:00
i32 command_index = current_project . fkey_commands [ fkey_index ] ;
2018-06-16 20:57:32 +00:00
if ( command_index < 0 | | command_index > = current_project . command_array . count ) {
return ;
}
2018-09-17 18:47:06 +00:00
Project_Command * command = & current_project . command_array . commands [ command_index ] ;
exec_project_command ( app , command ) ;
2018-06-16 20:57:32 +00:00
}
2019-10-25 06:17:54 +00:00
function void
2019-06-01 23:33:31 +00:00
exec_project_command_by_name ( Application_Links * app , String_Const_u8 name ) {
2018-06-16 20:57:32 +00:00
if ( ! current_project . loaded ) {
return ;
}
Project_Command * command = current_project . command_array . commands ;
2019-02-26 23:08:42 +00:00
for ( i32 i = 0 ; i < current_project . command_array . count ; + + i , + + command ) {
2019-06-01 23:33:31 +00:00
if ( string_match ( command - > name , name ) ) {
2018-06-16 20:57:32 +00:00
exec_project_command ( app , command ) ;
break ;
}
}
}
2019-10-25 06:17:54 +00:00
function void
2018-06-16 20:57:32 +00:00
exec_project_command_by_name ( Application_Links * app , char * name ) {
2019-06-01 23:33:31 +00:00
exec_project_command_by_name ( app , SCu8 ( name ) ) ;
2018-06-16 20:57:32 +00:00
}
2018-05-09 07:10:07 +00:00
////////////////////////////////
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. " )
{
2019-06-01 23:33:31 +00:00
close_all_files_with_extension ( app , global_config . code_exts ) ;
2018-05-09 07:10:07 +00:00
}
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. " )
{
2019-06-01 23:33:31 +00:00
open_all_files_in_hot_with_extension ( app , global_config . code_exts , 0 ) ;
2018-05-09 07:10:07 +00:00
}
CUSTOM_COMMAND_SIG ( open_all_code_recursive )
CUSTOM_DOC ( " Works as open_all_code but also runs in all subdirectories. " )
{
2019-06-01 23:33:31 +00:00
open_all_files_in_hot_with_extension ( app , global_config . code_exts , OpenAllFilesFlag_Recursive ) ;
2018-05-09 07:10:07 +00:00
}
2018-05-08 07:14:23 +00:00
///////////////////////////////
2017-11-15 23:57:21 +00:00
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. " )
{
2019-10-22 07:15:49 +00:00
ProfileScope ( app , " load project " ) ;
2018-05-09 05:22:33 +00:00
save_all_dirty_buffers ( app ) ;
2019-06-01 23:33:31 +00:00
set_current_project_from_nearest_project_file ( app ) ;
2017-11-21 18:25:19 +00:00
}
2017-11-15 23:57:21 +00:00
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. " )
{
2019-10-22 07:15:49 +00:00
ProfileScope ( app , " project fkey command " ) ;
2019-10-14 22:57:47 +00:00
User_Input input = get_current_input ( app ) ;
2019-02-26 23:08:42 +00:00
b32 got_ind = false ;
i32 ind = 0 ;
2019-10-10 18:21:47 +00:00
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 ) {
exec_project_fkey_command ( app , ind ) ;
}
2017-01-29 00:03:23 +00:00
}
}
2017-11-15 23:57:21 +00:00
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. " )
{
2017-06-20 20:37:45 +00:00
if ( current_project . loaded ) {
2019-06-01 23:33:31 +00:00
set_hot_directory ( app , current_project . dir ) ;
2017-06-20 20:37:45 +00:00
}
}
2017-11-09 18:30:24 +00:00
///////////////////////////////
2019-10-25 06:17:54 +00:00
function Project_Setup_Status
2019-06-01 23:33:31 +00:00
project_is_setup ( Application_Links * app , String_Const_u8 script_path , String_Const_u8 script_file ) {
2018-11-20 08:18:54 +00:00
Project_Setup_Status result = { } ;
2019-06-01 23:33:31 +00:00
{
Scratch_Block scratch ( app ) ;
2019-06-18 22:56:09 +00:00
String_Const_u8 bat_path = push_u8_stringf ( scratch , " %.*s/%.*s.bat " ,
2019-06-01 23:33:31 +00:00
string_expand ( script_path ) ,
string_expand ( script_file ) ) ;
result . bat_exists = file_exists ( app , bat_path ) ;
}
{
Scratch_Block scratch ( app ) ;
2019-06-18 22:56:09 +00:00
String_Const_u8 sh_path = push_u8_stringf ( scratch , " %.*s/%.*s.sh " ,
2019-06-01 23:33:31 +00:00
string_expand ( script_path ) ,
string_expand ( script_file ) ) ;
result . sh_exists = file_exists ( app , sh_path ) ;
}
{
Scratch_Block scratch ( app ) ;
2019-06-18 22:56:09 +00:00
String_Const_u8 project_path = push_u8_stringf ( scratch , " %.*s/project.4coder " ,
2019-06-01 23:33:31 +00:00
string_expand ( script_path ) ) ;
result . sh_exists = file_exists ( app , project_path ) ;
}
result . everything_exists = ( result . bat_exists & & result . sh_exists & & result . project_exists ) ;
2017-11-09 18:30:24 +00:00
return ( result ) ;
}
2019-10-25 06:17:54 +00:00
function Project_Key_Strings
2018-06-02 00:29:36 +00:00
project_key_strings_query_user ( Application_Links * app ,
2019-02-26 23:08:42 +00:00
b32 get_script_file , b32 get_code_file ,
2019-06-01 23:33:31 +00:00
u8 * script_file_space , i32 script_file_cap ,
u8 * code_file_space , i32 code_file_cap ,
u8 * output_dir_space , i32 output_dir_cap ,
u8 * binary_file_space , i32 binary_file_cap ) {
2018-11-20 08:18:54 +00:00
Project_Key_Strings keys = { } ;
2017-11-09 18:30:24 +00:00
2019-10-13 20:17:22 +00:00
Query_Bar_Group bar_group ( app ) ;
2018-11-20 08:18:54 +00:00
Query_Bar script_file_bar = { } ;
Query_Bar code_file_bar = { } ;
Query_Bar output_dir_bar = { } ;
Query_Bar binary_file_bar = { } ;
2018-06-02 00:29:36 +00:00
if ( get_script_file ) {
2019-06-01 23:33:31 +00:00
script_file_bar . prompt = string_u8_litexpr ( " Script Name: " ) ;
2019-12-18 03:38:08 +00:00
script_file_bar . string = SCu8 ( script_file_space , ( u64 ) 0 ) ;
2019-06-01 23:33:31 +00:00
script_file_bar . string_capacity = script_file_cap ;
2018-06-02 00:29:36 +00:00
if ( ! query_user_string ( app , & script_file_bar ) ) return ( keys ) ;
if ( script_file_bar . string . size = = 0 ) return ( keys ) ;
}
if ( get_code_file ) {
2019-06-01 23:33:31 +00:00
code_file_bar . prompt = string_u8_litexpr ( " Build Target: " ) ;
2019-12-18 03:38:08 +00:00
code_file_bar . string = SCu8 ( code_file_space , ( u64 ) 0 ) ;
2019-06-01 23:33:31 +00:00
code_file_bar . string_capacity = code_file_cap ;
2018-06-02 00:29:36 +00:00
if ( ! query_user_string ( app , & code_file_bar ) ) return ( keys ) ;
if ( code_file_bar . string . size = = 0 ) return ( keys ) ;
}
2019-06-01 23:33:31 +00:00
output_dir_bar . prompt = string_u8_litexpr ( " Output Directory: " ) ;
2019-12-18 03:38:08 +00:00
output_dir_bar . string = SCu8 ( output_dir_space , ( u64 ) 0 ) ;
2019-06-01 23:33:31 +00:00
output_dir_bar . string_capacity = output_dir_cap ;
2018-06-02 00:29:36 +00:00
if ( ! query_user_string ( app , & output_dir_bar ) ) return ( keys ) ;
2019-06-01 23:33:31 +00:00
if ( output_dir_bar . string . size = = 0 & & output_dir_cap > 0 ) {
output_dir_bar . string . str [ 0 ] = ' . ' ;
output_dir_bar . string . size = 1 ;
2018-06-02 00:29:36 +00:00
}
2019-06-01 23:33:31 +00:00
binary_file_bar . prompt = string_u8_litexpr ( " Binary Output: " ) ;
2019-12-18 03:38:08 +00:00
binary_file_bar . string = SCu8 ( binary_file_space , ( u64 ) 0 ) ;
2019-06-01 23:33:31 +00:00
binary_file_bar . string_capacity = binary_file_cap ;
2018-06-02 00:29:36 +00:00
if ( ! query_user_string ( app , & binary_file_bar ) ) return ( keys ) ;
if ( binary_file_bar . string . size = = 0 ) return ( keys ) ;
keys . success = true ;
keys . script_file = script_file_bar . string ;
keys . code_file = code_file_bar . string ;
keys . output_dir = output_dir_bar . string ;
keys . binary_file = binary_file_bar . string ;
return ( keys ) ;
}
2019-10-25 06:17:54 +00:00
function b32
2019-06-01 23:33:31 +00:00
project_generate_bat_script ( Arena * scratch , String_Const_u8 opts , String_Const_u8 compiler ,
String_Const_u8 script_path , String_Const_u8 script_file ,
String_Const_u8 code_file , String_Const_u8 output_dir , String_Const_u8 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
2019-07-13 00:43:17 +00:00
String_Const_u8 cf = push_string_copy ( scratch , code_file ) ;
String_Const_u8 od = push_string_copy ( scratch , output_dir ) ;
String_Const_u8 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
2019-06-18 22:56:09 +00:00
String_Const_u8 file_name = push_u8_stringf ( scratch , " %.*s/%.*s.bat " ,
2019-06-01 23:33:31 +00:00
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
2019-06-01 23:33:31 +00:00
project_generate_sh_script ( Arena * scratch , String_Const_u8 opts , String_Const_u8 compiler ,
String_Const_u8 script_path , String_Const_u8 script_file ,
String_Const_u8 code_file , String_Const_u8 output_dir , String_Const_u8 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
2019-06-01 23:33:31 +00:00
String_Const_u8 cf = code_file ;
String_Const_u8 od = output_dir ;
String_Const_u8 bf = binary_file ;
2018-06-02 00:29:36 +00:00
2019-06-18 22:56:09 +00:00
String_Const_u8 file_name = push_u8_stringf ( scratch , " %.*s/%.*s.sh " ,
2019-06-01 23:33:31 +00:00
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
2019-06-01 23:33:31 +00:00
project_generate_project_4coder_file ( Arena * scratch , String_Const_u8 script_path , String_Const_u8 script_file , String_Const_u8 output_dir , String_Const_u8 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
2019-06-01 23:33:31 +00:00
String_Const_u8 od = output_dir ;
String_Const_u8 bf = binary_file ;
2018-06-02 00:29:36 +00:00
2019-06-01 23:33:31 +00:00
String_Const_u8 od_win = string_replace ( scratch , od ,
string_u8_litexpr ( " / " ) , string_u8_litexpr ( " \\ " ) ) ;
String_Const_u8 bf_win = string_replace ( scratch , bf ,
string_u8_litexpr ( " / " ) , string_u8_litexpr ( " \\ " ) ) ;
2018-06-02 00:29:36 +00:00
2019-06-18 22:56:09 +00:00
String_Const_u8 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
2019-06-01 23:33:31 +00:00
project_setup_scripts__generic ( Application_Links * app , b32 do_project_file , b32 do_bat_script , b32 do_sh_script ) {
2019-10-01 02:06:21 +00:00
Scratch_Block scratch ( app ) ;
2019-06-01 23:33:31 +00:00
String_Const_u8 script_path = push_hot_directory ( app , scratch ) ;
2018-06-02 00:29:36 +00:00
2019-02-26 23:08:42 +00:00
b32 needs_to_do_work = false ;
2018-11-20 08:18:54 +00:00
Project_Setup_Status status = { } ;
2018-06-02 00:29:36 +00:00
if ( do_project_file ) {
2019-06-01 23:33:31 +00:00
status = project_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
2019-06-01 23:33:31 +00:00
u8 script_file_space [ 1024 ] ;
u8 code_file_space [ 1024 ] ;
u8 output_dir_space [ 1024 ] ;
u8 binary_file_space [ 1024 ] ;
2017-11-09 18:30:24 +00:00
2019-02-26 23:08:42 +00:00
b32 get_script_file = ! do_project_file ;
b32 get_code_file =
2018-06-02 00:29:36 +00:00
( do_bat_script & & ! status . bat_exists ) | |
( do_sh_script & & ! status . sh_exists ) ;
2017-11-09 18:30:24 +00:00
2019-06-01 23:33:31 +00:00
Project_Key_Strings keys = { } ;
keys = project_key_strings_query_user ( app , get_script_file , get_code_file ,
script_file_space , sizeof ( script_file_space ) ,
code_file_space , sizeof ( code_file_space ) ,
output_dir_space , sizeof ( output_dir_space ) ,
binary_file_space , sizeof ( binary_file_space ) ) ;
2017-11-09 18:30:24 +00:00
2018-06-02 00:29:36 +00:00
if ( ! keys . success ) {
return ;
}
2017-11-09 18:30:24 +00:00
2018-06-02 00:29:36 +00:00
if ( do_project_file ) {
2019-06-01 23:33:31 +00:00
keys . 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 ) {
2019-06-01 23:33:31 +00:00
status = project_is_setup ( app , script_path , keys . 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 ) {
if ( ! project_generate_bat_script ( scratch ,
global_config . default_flags_bat ,
global_config . default_compiler_bat ,
script_path , keys . script_file ,
keys . code_file , keys . output_dir , keys . 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 ) {
if ( ! project_generate_sh_script ( scratch ,
global_config . default_flags_sh ,
global_config . default_compiler_sh ,
script_path , keys . script_file ,
keys . code_file , keys . output_dir , keys . 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 ) {
2019-06-01 23:33:31 +00:00
if ( ! project_generate_project_4coder_file ( scratch ,
script_path ,
keys . script_file ,
keys . output_dir ,
keys . binary_file ) ) {
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
}
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. " )
{
2019-06-01 23:33:31 +00:00
project_setup_scripts__generic ( app , true , true , true ) ;
2017-11-21 18:25:19 +00:00
load_project ( app ) ;
2017-11-09 18:30:24 +00:00
}
2018-06-02 00:29:36 +00:00
CUSTOM_COMMAND_SIG ( setup_build_bat )
CUSTOM_DOC ( " Queries the user for several configuration options and initializes a new build batch script. " )
{
2019-06-01 23:33:31 +00:00
project_setup_scripts__generic ( app , false , true , false ) ;
2018-06-02 00:29:36 +00:00
}
CUSTOM_COMMAND_SIG ( setup_build_sh )
CUSTOM_DOC ( " Queries the user for several configuration options and initializes a new build shell script. " )
{
2019-06-01 23:33:31 +00:00
project_setup_scripts__generic ( app , false , false , true ) ;
2018-06-02 00:29:36 +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. " )
{
2019-06-01 23:33:31 +00:00
project_setup_scripts__generic ( app , false , true , true ) ;
2018-06-02 00:29:36 +00:00
}
2018-09-17 18:47:06 +00:00
///////////////////////////////
2019-10-25 23:33:50 +00:00
function Project_Command_Lister_Result
2020-03-11 23:22:37 +00:00
get_project_command_from_user ( Application_Links * app , Project * project , String_Const_u8 query ) {
2019-10-25 23:33:50 +00:00
Project_Command_Lister_Result result = { } ;
if ( project ! = 0 ) {
Scratch_Block scratch ( app ) ;
2020-02-29 23:38:38 +00:00
Lister_Block lister ( app , scratch ) ;
2019-10-25 23:33:50 +00:00
lister_set_query ( lister , query ) ;
2020-02-29 23:38:38 +00:00
lister_set_default_handlers ( lister ) ;
2019-10-25 23:33:50 +00:00
Project_Command * proj_cmd = project - > command_array . commands ;
i32 count = project - > command_array . count ;
for ( i32 i = 0 ; i < count ; i + = 1 , proj_cmd + = 1 ) {
lister_add_item ( lister , proj_cmd - > name , proj_cmd - > cmd , IntAsPtr ( i ) , 0 ) ;
}
Lister_Result l_result = run_lister ( app , lister ) ;
if ( ! l_result . canceled ) {
result . success = true ;
result . index = ( i32 ) PtrAsInt ( l_result . user_data ) ;
}
}
return ( result ) ;
}
function Project_Command_Lister_Result
get_project_command_from_user ( Application_Links * app , Project * project , char * query ) {
return ( get_project_command_from_user ( app , project , SCu8 ( query ) ) ) ;
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. " )
{
2019-06-01 23:33:31 +00:00
if ( current_project . loaded ) {
2019-10-25 23:33:50 +00:00
Project_Command_Lister_Result proj_cmd =
get_project_command_from_user ( app , & current_project , " Command: " ) ;
if ( proj_cmd . success ) {
exec_project_command_by_index ( app , proj_cmd . index ) ;
2019-06-01 23:33:31 +00:00
}
2018-09-17 18:47:06 +00:00
}
}
2017-01-29 00:03:23 +00:00
// BOTTOM