Upgraded new project commands, cursor at bottom of output option

This commit is contained in:
Allen Webster 2018-06-01 17:29:36 -07:00
parent 91384ca559
commit 7699b37767
8 changed files with 488 additions and 250 deletions

View File

@ -1,7 +1,7 @@
#define command_id(c) (fcoder_metacmd_ID_##c)
#define command_metadata(c) (&fcoder_metacmd_table[command_id(c)])
#define command_metadata_by_id(id) (&fcoder_metacmd_table[id])
#define command_one_past_last_id 193
#define command_one_past_last_id 196
#if defined(CUSTOM_COMMAND_SIG)
#define PROC_LINKS(x,y) x
#else
@ -173,6 +173,9 @@ CUSTOM_COMMAND_SIG(set_bindings_choose);
CUSTOM_COMMAND_SIG(set_bindings_default);
CUSTOM_COMMAND_SIG(set_bindings_mac_default);
CUSTOM_COMMAND_SIG(set_mark);
CUSTOM_COMMAND_SIG(setup_build_bat);
CUSTOM_COMMAND_SIG(setup_build_bat_and_sh);
CUSTOM_COMMAND_SIG(setup_build_sh);
CUSTOM_COMMAND_SIG(setup_new_project);
CUSTOM_COMMAND_SIG(show_filebar);
CUSTOM_COMMAND_SIG(show_scrollbar);
@ -212,7 +215,7 @@ char *source_name;
int32_t source_name_len;
int32_t line_number;
};
static Command_Metadata fcoder_metacmd_table[193] = {
static Command_Metadata fcoder_metacmd_table[196] = {
{ PROC_LINKS(allow_mouse, 0), "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "C:\\work\\4ed\\code\\4coder_default_framework.cpp", 49, 199 },
{ PROC_LINKS(auto_tab_line_at_cursor, 0), "auto_tab_line_at_cursor", 23, "Auto-indents the line on which the cursor sits.", 47, "C:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 722 },
{ PROC_LINKS(auto_tab_range, 0), "auto_tab_range", 14, "Auto-indents the range between the cursor and the mark.", 55, "C:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 733 },
@ -229,7 +232,7 @@ static Command_Metadata fcoder_metacmd_table[193] = {
{ PROC_LINKS(clean_all_lines, 0), "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 368 },
{ PROC_LINKS(click_set_cursor, 0), "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 174 },
{ PROC_LINKS(click_set_mark, 0), "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 187 },
{ PROC_LINKS(close_all_code, 0), "close_all_code", 14, "Closes any buffer with a filename ending with an extension configured to be recognized as a code file type.", 107, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 974 },
{ PROC_LINKS(close_all_code, 0), "close_all_code", 14, "Closes any buffer with a filename ending with an extension configured to be recognized as a code file type.", 107, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 986 },
{ PROC_LINKS(close_build_panel, 0), "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "C:\\work\\4ed\\code\\4coder_build_commands.cpp", 46, 205 },
{ PROC_LINKS(close_panel, 0), "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 441 },
{ PROC_LINKS(copy, 0), "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "C:\\work\\4ed\\code\\4coder_clipboard.cpp", 41, 26 },
@ -295,7 +298,7 @@ static Command_Metadata fcoder_metacmd_table[193] = {
{ PROC_LINKS(list_all_locations_of_type_definition_of_identifier, 0), "list_all_locations_of_type_definition_of_identifier", 51, "Reads a token or word under the cursor and lists all locations of strings that appear to define a type whose name matches it.", 125, "C:\\work\\4ed\\code\\4coder_search.cpp", 38, 800 },
{ PROC_LINKS(list_all_substring_locations, 0), "list_all_substring_locations", 28, "Queries the user for a string and lists all case-sensitive substring matches found in all open buffers.", 103, "C:\\work\\4ed\\code\\4coder_search.cpp", 38, 747 },
{ PROC_LINKS(list_all_substring_locations_case_insensitive, 0), "list_all_substring_locations_case_insensitive", 45, "Queries the user for a string and lists all case-insensitive substring matches found in all open buffers.", 105, "C:\\work\\4ed\\code\\4coder_search.cpp", 38, 759 },
{ PROC_LINKS(load_project, 0), "load_project", 12, "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.", 167, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 997 },
{ PROC_LINKS(load_project, 0), "load_project", 12, "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.", 167, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 1009 },
{ PROC_LINKS(make_directory_query, 0), "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1101 },
{ PROC_LINKS(miblo_decrement_basic, 0), "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "C:\\work\\4ed\\code\\4coder_miblo_numbers.cpp", 45, 110 },
{ PROC_LINKS(miblo_decrement_time_stamp, 0), "miblo_decrement_time_stamp", 26, "Decrement a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss", 81, "C:\\work\\4ed\\code\\4coder_miblo_numbers.cpp", 45, 383 },
@ -317,8 +320,8 @@ static Command_Metadata fcoder_metacmd_table[193] = {
{ PROC_LINKS(newline_or_goto_position_same_panel_direct, 0), "newline_or_goto_position_same_panel_direct", 42, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "C:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 116 },
{ PROC_LINKS(newline_or_goto_position_same_panel_sticky, 0), "newline_or_goto_position_same_panel_sticky", 42, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "C:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 571 },
{ PROC_LINKS(newline_or_goto_position_sticky, 0), "newline_or_goto_position_sticky", 31, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "C:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 556 },
{ PROC_LINKS(open_all_code, 0), "open_all_code", 13, "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.", 164, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 981 },
{ PROC_LINKS(open_all_code_recursive, 0), "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 988 },
{ PROC_LINKS(open_all_code, 0), "open_all_code", 13, "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.", 164, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 993 },
{ PROC_LINKS(open_all_code_recursive, 0), "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 1000 },
{ PROC_LINKS(open_color_tweaker, 0), "open_color_tweaker", 18, "Opens the 4coder colors and fonts selector menu.", 48, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1457 },
{ PROC_LINKS(open_file_in_quotes, 0), "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1320 },
{ PROC_LINKS(open_in_other, 0), "open_in_other", 13, "Switches to the next active panel and begins an open file dialogue.", 67, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1465 },
@ -335,8 +338,8 @@ static Command_Metadata fcoder_metacmd_table[193] = {
{ PROC_LINKS(paste_next, 0), "paste_next", 10, "If the previous command was paste or paste_next, replaces the paste range with the next text down on the clipboard, otherwise operates as the paste command.", 156, "C:\\work\\4ed\\code\\4coder_clipboard.cpp", 41, 84 },
{ PROC_LINKS(paste_next_and_indent, 0), "paste_next_and_indent", 21, "Paste the next item on the clipboard and run auto-indent on the newly pasted text.", 82, "C:\\work\\4ed\\code\\4coder_clipboard.cpp", 41, 135 },
{ PROC_LINKS(place_in_scope, 0), "place_in_scope", 14, "Wraps the code contained in the range between cursor and mark with a new curly brace scope.", 91, "C:\\work\\4ed\\code\\4coder_scope_commands.cpp", 46, 481 },
{ PROC_LINKS(project_fkey_command, 0), "project_fkey_command", 20, "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.", 175, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 1004 },
{ PROC_LINKS(project_go_to_root_directory, 0), "project_go_to_root_directory", 28, "Changes 4coder's hot directory to the root directory of the currently loaded project. With no loaded project nothing hapepns.", 125, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 1029 },
{ PROC_LINKS(project_fkey_command, 0), "project_fkey_command", 20, "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.", 175, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 1016 },
{ PROC_LINKS(project_go_to_root_directory, 0), "project_go_to_root_directory", 28, "Changes 4coder's hot directory to the root directory of the currently loaded project. With no loaded project nothing hapepns.", 125, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 1041 },
{ PROC_LINKS(query_replace, 0), "query_replace", 13, "Queries the user for two strings, and incrementally replaces every occurence of the first string with the second string.", 120, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 893 },
{ PROC_LINKS(query_replace_identifier, 0), "query_replace_identifier", 24, "Queries the user for a string, and incrementally replace every occurence of the word or token found at the cursor with the specified string.", 140, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 913 },
{ PROC_LINKS(query_replace_selection, 0), "query_replace_selection", 23, "Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string.", 141, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 931 },
@ -378,7 +381,10 @@ static Command_Metadata fcoder_metacmd_table[193] = {
{ PROC_LINKS(set_bindings_default, 0), "set_bindings_default", 20, "Remap keybindings using the 'default' mapping rule.", 51, "C:\\work\\4ed\\code\\4coder_remapping_commands.cpp", 50, 61 },
{ PROC_LINKS(set_bindings_mac_default, 0), "set_bindings_mac_default", 24, "Remap keybindings using the 'mac-default' mapping rule.", 55, "C:\\work\\4ed\\code\\4coder_remapping_commands.cpp", 50, 75 },
{ PROC_LINKS(set_mark, 0), "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 86 },
{ PROC_LINKS(setup_new_project, 0), "setup_new_project", 17, "Queries the user for several configuration options and initializes a new 4coder project with build scripts for every OS.", 120, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 1077 },
{ PROC_LINKS(setup_build_bat, 0), "setup_build_bat", 15, "Queries the user for several configuration options and initializes a new build batch script.", 92, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 1426 },
{ PROC_LINKS(setup_build_bat_and_sh, 0), "setup_build_bat_and_sh", 22, "Queries the user for several configuration options and initializes a new build batch script.", 92, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 1438 },
{ PROC_LINKS(setup_build_sh, 0), "setup_build_sh", 14, "Queries the user for several configuration options and initializes a new build shell script.", 92, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 1432 },
{ PROC_LINKS(setup_new_project, 0), "setup_new_project", 17, "Queries the user for several configuration options and initializes a new 4coder project with build scripts for every OS.", 120, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 1419 },
{ PROC_LINKS(show_filebar, 0), "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 464 },
{ PROC_LINKS(show_scrollbar, 0), "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 450 },
{ PROC_LINKS(snipe_token_or_word, 0), "snipe_token_or_word", 19, "Delete a single, whole token on or to the left of the cursor and post it to the clipboard.", 90, "C:\\work\\4ed\\code\\4coder_seek.cpp", 36, 1259 },
@ -572,31 +578,34 @@ static int32_t fcoder_metacmd_ID_set_bindings_choose = 161;
static int32_t fcoder_metacmd_ID_set_bindings_default = 162;
static int32_t fcoder_metacmd_ID_set_bindings_mac_default = 163;
static int32_t fcoder_metacmd_ID_set_mark = 164;
static int32_t fcoder_metacmd_ID_setup_new_project = 165;
static int32_t fcoder_metacmd_ID_show_filebar = 166;
static int32_t fcoder_metacmd_ID_show_scrollbar = 167;
static int32_t fcoder_metacmd_ID_snipe_token_or_word = 168;
static int32_t fcoder_metacmd_ID_snipe_token_or_word_right = 169;
static int32_t fcoder_metacmd_ID_suppress_mouse = 170;
static int32_t fcoder_metacmd_ID_swap_buffers_between_panels = 171;
static int32_t fcoder_metacmd_ID_to_lowercase = 172;
static int32_t fcoder_metacmd_ID_to_uppercase = 173;
static int32_t fcoder_metacmd_ID_toggle_filebar = 174;
static int32_t fcoder_metacmd_ID_toggle_fullscreen = 175;
static int32_t fcoder_metacmd_ID_toggle_line_wrap = 176;
static int32_t fcoder_metacmd_ID_toggle_mouse = 177;
static int32_t fcoder_metacmd_ID_toggle_show_whitespace = 178;
static int32_t fcoder_metacmd_ID_toggle_virtual_whitespace = 179;
static int32_t fcoder_metacmd_ID_undo = 180;
static int32_t fcoder_metacmd_ID_view_buffer_other_panel = 181;
static int32_t fcoder_metacmd_ID_word_complete = 182;
static int32_t fcoder_metacmd_ID_write_and_auto_tab = 183;
static int32_t fcoder_metacmd_ID_write_block = 184;
static int32_t fcoder_metacmd_ID_write_character = 185;
static int32_t fcoder_metacmd_ID_write_explicit_enum_flags = 186;
static int32_t fcoder_metacmd_ID_write_explicit_enum_values = 187;
static int32_t fcoder_metacmd_ID_write_hack = 188;
static int32_t fcoder_metacmd_ID_write_note = 189;
static int32_t fcoder_metacmd_ID_write_todo = 190;
static int32_t fcoder_metacmd_ID_write_underscore = 191;
static int32_t fcoder_metacmd_ID_write_zero_struct = 192;
static int32_t fcoder_metacmd_ID_setup_build_bat = 165;
static int32_t fcoder_metacmd_ID_setup_build_bat_and_sh = 166;
static int32_t fcoder_metacmd_ID_setup_build_sh = 167;
static int32_t fcoder_metacmd_ID_setup_new_project = 168;
static int32_t fcoder_metacmd_ID_show_filebar = 169;
static int32_t fcoder_metacmd_ID_show_scrollbar = 170;
static int32_t fcoder_metacmd_ID_snipe_token_or_word = 171;
static int32_t fcoder_metacmd_ID_snipe_token_or_word_right = 172;
static int32_t fcoder_metacmd_ID_suppress_mouse = 173;
static int32_t fcoder_metacmd_ID_swap_buffers_between_panels = 174;
static int32_t fcoder_metacmd_ID_to_lowercase = 175;
static int32_t fcoder_metacmd_ID_to_uppercase = 176;
static int32_t fcoder_metacmd_ID_toggle_filebar = 177;
static int32_t fcoder_metacmd_ID_toggle_fullscreen = 178;
static int32_t fcoder_metacmd_ID_toggle_line_wrap = 179;
static int32_t fcoder_metacmd_ID_toggle_mouse = 180;
static int32_t fcoder_metacmd_ID_toggle_show_whitespace = 181;
static int32_t fcoder_metacmd_ID_toggle_virtual_whitespace = 182;
static int32_t fcoder_metacmd_ID_undo = 183;
static int32_t fcoder_metacmd_ID_view_buffer_other_panel = 184;
static int32_t fcoder_metacmd_ID_word_complete = 185;
static int32_t fcoder_metacmd_ID_write_and_auto_tab = 186;
static int32_t fcoder_metacmd_ID_write_block = 187;
static int32_t fcoder_metacmd_ID_write_character = 188;
static int32_t fcoder_metacmd_ID_write_explicit_enum_flags = 189;
static int32_t fcoder_metacmd_ID_write_explicit_enum_values = 190;
static int32_t fcoder_metacmd_ID_write_hack = 191;
static int32_t fcoder_metacmd_ID_write_note = 192;
static int32_t fcoder_metacmd_ID_write_todo = 193;
static int32_t fcoder_metacmd_ID_write_underscore = 194;
static int32_t fcoder_metacmd_ID_write_zero_struct = 195;

View File

@ -1130,6 +1130,21 @@ lexer_keywords_default_init(Partition *arena, Cpp_Keyword_Table *kw_out, Cpp_Key
////////////////////////////////
static String
get_hot_directory(Application_Links *app, Partition *arena){
Temp_Memory temp = begin_temp_memory(arena);
int32_t space_cap = partition_remaining(arena);
char *space = push_array(arena, char, space_cap);
String hot_dir = make_string_cap(space, 0, space_cap);
hot_dir.size = directory_get_hot(app, hot_dir.str, hot_dir.memory_size);
end_temp_memory(temp);
push_array(arena, char, hot_dir.size);
hot_dir.memory_size = hot_dir.size;
return(hot_dir);
}
////////////////////////////////
static String
dump_file_handle(Partition *arena, FILE *file){
String str = {0};

View File

@ -44,6 +44,15 @@ CUSTOM_DOC("Execute a 'long form' command.")
else if (match(bar.string, make_lit_string("new project"))){
setup_new_project(app);
}
else if (match(bar.string, make_lit_string("new bat"))){
setup_build_bat(app);
}
else if (match(bar.string, make_lit_string("new sh"))){
setup_build_sh(app);
}
else if (match(bar.string, make_lit_string("new scripts"))){
setup_build_bat_and_sh(app);
}
else if (match(bar.string, make_lit_string("delete file"))){
delete_file_query(app);
}

View File

@ -416,12 +416,13 @@ parse_project__config_data__version_1(Partition *arena, String root_dir, Config
bool32 can_emit_command = true;
String name = {0};
Config_Compound *cmd_set = 0;
String name = {0};
String cmd_str = {0};
String out = {0};
bool32 footer_panel = false;
bool32 save_dirty_files = true;
String cmd_str = {0};
bool32 cursor_at_end = false;
if (!config_compound_string_member(parsed, src, "name", 0, &name)){
can_emit_command = false;
@ -468,12 +469,15 @@ parse_project__config_data__version_1(Partition *arena, String root_dir, Config
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);
dst->name = push_string_copy(arena, name);
dst->cmd = push_string_copy(arena, cmd_str);
dst->out = push_string_copy(arena, out);
dst->footer_panel = footer_panel;
dst->save_dirty_files = save_dirty_files;
dst->cursor_at_end = cursor_at_end;
}
finish_command:;
@ -691,6 +695,7 @@ project_deep_copy__inner(Partition *arena, Project *project){
}
dst->footer_panel = src->footer_panel;
dst->save_dirty_files = src->save_dirty_files;
dst->cursor_at_end = src->cursor_at_end;
}
}
@ -775,6 +780,9 @@ config_feedback_command_array(String *space, char *name, Project_Command_Array *
append(space, ".save_dirty_files = ");
append(space, command->save_dirty_files?"true":"false");
append(space, ", ");
append(space, ".cursor_at_end = ");
append(space, command->cursor_at_end?"true":"false");
append(space, ", ");
append(space, "},\n");
}
append(space, "};\n");
@ -927,6 +935,7 @@ exec_project_fkey_command(Application_Links *app, int32_t fkey_index){
if (fkey->cmd.size > 0){
bool32 footer_panel = fkey->footer_panel;
bool32 save_dirty_files = fkey->save_dirty_files;
bool32 cursor_at_end = fkey->cursor_at_end;
if (save_dirty_files){
save_all_dirty_buffers(app);
@ -936,6 +945,9 @@ exec_project_fkey_command(Application_Links *app, int32_t fkey_index){
View_Summary *view_ptr = 0;
Buffer_Identifier buffer_id = {0};
uint32_t flags = CLI_OverlapWithConflict;
if (cursor_at_end){
flags |= CLI_CursorAtEnd;
}
bool32 set_fancy_font = false;
if (fkey->out.size > 0){
@ -1038,29 +1050,26 @@ CUSTOM_DOC("Changes 4coder's hot directory to the root directory of the currentl
///////////////////////////////
static Project_Setup_Status
project_is_setup(Application_Links *app, char *dir, int32_t dir_len, int32_t dir_capacity){
project_is_setup(Application_Links *app, Partition *scratch, String script_path, String script_file){
Project_Setup_Status result = {0};
Temp_Memory temp = begin_temp_memory(&global_part);
Temp_Memory temp = begin_temp_memory(scratch);
static int32_t needed_extra_space = 15;
char *space = push_array(&global_part, char, script_path.size + needed_extra_space);
String str = make_string_cap(space, 0, script_path.size + needed_extra_space);
copy(&str, script_path);
String str = {0};
if (dir_capacity >= dir_len + needed_extra_space){
str = make_string_cap(dir, dir_len, dir_capacity);
}
else{
char *space = push_array(&global_part, char, dir_len + needed_extra_space);
str = make_string_cap(space, 0, dir_len + needed_extra_space);
copy(&str, make_string(dir, dir_len));
}
str.size = dir_len;
append(&str, "/build.bat");
int32_t dir_len = str.size;
append(&str, "/");
append(&str, script_file);
append(&str, ".bat");
result.bat_exists = file_exists(app, str.str, str.size);
str.size = dir_len;
append(&str, "/build.sh");
append(&str, "/");
append(&str, script_file);
append(&str, ".sh");
result.sh_exists = file_exists(app, str.str, str.size);
str.size = dir_len;
@ -1074,175 +1083,363 @@ project_is_setup(Application_Links *app, char *dir, int32_t dir_len, int32_t dir
return(result);
}
static Project_Key_Strings
project_key_strings_query_user(Application_Links *app,
bool32 get_script_file, bool32 get_code_file,
char *script_file_space, int32_t script_file_cap,
char *code_file_space, int32_t code_file_cap,
char *output_dir_space, int32_t output_dir_cap,
char *binary_file_space, int32_t binary_file_cap){
Project_Key_Strings keys = {0};
Query_Bar script_file_bar = {0};
Query_Bar code_file_bar = {0};
Query_Bar output_dir_bar = {0};
Query_Bar binary_file_bar = {0};
if (get_script_file){
script_file_bar.prompt = make_lit_string("Script Name: ");
script_file_bar.string = make_string_cap(script_file_space, 0, script_file_cap);
if (!query_user_string(app, &script_file_bar)) return(keys);
if (script_file_bar.string.size == 0) return(keys);
}
if (get_code_file){
code_file_bar.prompt = make_lit_string("Build Target: ");
code_file_bar.string = make_string_cap(code_file_space, 0, code_file_cap);
if (!query_user_string(app, &code_file_bar)) return(keys);
if (code_file_bar.string.size == 0) return(keys);
}
output_dir_bar.prompt = make_lit_string("Output Directory: ");
output_dir_bar.string = make_string_cap(output_dir_space, 0, output_dir_cap);
if (!query_user_string(app, &output_dir_bar)) return(keys);
if (output_dir_bar.string.size == 0){
copy(&output_dir_bar.string, ".");
}
binary_file_bar.prompt = make_lit_string("Binary Output: ");
binary_file_bar.string = make_string_cap(binary_file_space, 0, binary_file_cap);
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);
}
static bool32
project_generate_bat_script(Partition *scratch, String opts, String compiler,
String script_path, String script_file,
String code_file, String output_dir, String binary_file){
bool32 success = false;
Temp_Memory temp = begin_temp_memory(scratch);
String cf = push_string_copy(scratch, code_file);
String od = push_string_copy(scratch, output_dir);
String bf = push_string_copy(scratch, binary_file);
replace_char(&cf, '/', '\\');
replace_char(&od, '/', '\\');
replace_char(&bf, '/', '\\');
int32_t space_cap = partition_remaining(scratch);
char *space = push_array(scratch, char, space_cap);
String file_name = make_string_cap(space, 0, space_cap);
append(&file_name, script_path);
append(&file_name, "/");
append(&file_name, script_file);
append(&file_name, ".bat");
terminate_with_null(&file_name);
FILE *bat_script = fopen(file_name.str, "wb");
if (bat_script != 0){
fprintf(bat_script, "@echo off\n\n");
fprintf(bat_script, "set opts=%.*s\n", opts.size, opts.str);
fprintf(bat_script, "set code=%%cd%%\n");
fprintf(bat_script, "pushd %.*s\n", od.size, od.str);
fprintf(bat_script, "%.*s %%opts%% %%code%%\\%.*s -Fe%.*s\n",
compiler.size, compiler.str, cf.size, cf.str, bf.size, bf.str);
fprintf(bat_script, "popd\n");
fclose(bat_script);
success = true;
}
end_temp_memory(temp);
return(success);
}
static bool32
project_generate_sh_script(Partition *scratch, String opts, String compiler,
String script_path, String script_file,
String code_file, String output_dir, String binary_file){
bool32 success = false;
Temp_Memory temp = begin_temp_memory(scratch);
String cf = code_file;
String od = output_dir;
String bf = binary_file;
int32_t space_cap = partition_remaining(scratch);
char *space = push_array(scratch, char, space_cap);
String file_name = make_string_cap(space, 0, space_cap);
append(&file_name, script_path);
append(&file_name, "/");
append(&file_name, script_file);
append(&file_name, ".sh");
terminate_with_null(&file_name);
FILE *sh_script = fopen(file_name.str, "wb");
if (sh_script != 0){
fprintf(sh_script, "#!/bin/bash\n\n");
fprintf(sh_script, "code=\"$PWD\"\n");
fprintf(sh_script, "opts=%.*s\n", opts.size, opts.str);
fprintf(sh_script, "cd %.*s > /dev/null\n", od.size, od.str);
fprintf(sh_script, "%.*s $opts $code/%.*s -o %.*s\n",
compiler.size, compiler.str, cf.size, cf.str, bf.size, bf.str);
fprintf(sh_script, "cd $code > /dev/null\n");
fclose(sh_script);
success = true;
}
end_temp_memory(temp);
return(success);
}
static bool32
project_generate_project_4coder_file(Partition *scratch,
String script_path, String script_file,
String output_dir, String binary_file){
bool32 success = false;
Temp_Memory temp = begin_temp_memory(scratch);
String od = output_dir;
String bf = binary_file;
String od_win = push_string(scratch, od.size*2);
String bf_win = push_string(scratch, bf.size*2);
append(&od_win, od);
append(&bf_win, bf);
replace_str(&od_win, "/", "\\\\");
replace_str(&bf_win, "/", "\\\\");
int32_t space_cap = partition_remaining(scratch);
char *space = push_array(scratch, char, space_cap);
String file_name = make_string_cap(space, 0, space_cap);
append(&file_name, script_path);
append(&file_name, "/project.4coder");
terminate_with_null(&file_name);
FILE *out = fopen(file_name.str, "wb");
if (out != 0){
fprintf(out, "version(1);\n");
fprintf(out, "project_name = \"%.*s\";\n", binary_file.size, binary_file.str);
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");
fprintf(out, "patterns = {\n");
fprintf(out, "\".*\",\n");
fprintf(out, "};\n");
fprintf(out, "load_paths_base = {\n");
fprintf(out, " { \".\", .relative = true, .recursive = true, },");
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");
fprintf(out, " .cmd = { { \"%.*s.bat\", .os = \"win\" },\n",
script_file.size, script_file.str);
fprintf(out, " { \"%.*s.sh\" , .os = \"linux\" },\n",
script_file.size, script_file.str);
fprintf(out, " { \"%.*s.sh\" , .os = \"mac\" }, }, },\n",
script_file.size, script_file.str);
fprintf(out, " { .name = \"run\",\n");
fprintf(out, " .out = \"*run*\", .footer_panel = false, .save_dirty_files = false,\n");
fprintf(out, " .cmd = { { \"%.*s\\\\%.*s\", .os = \"win\" },\n",
od_win.size, od_win.str, bf_win.size, bf_win.str);
fprintf(out, " { \"%.*s/%.*s\" , .os = \"linux\" },\n",
od.size, od.str, bf.size, bf.str);
fprintf(out, " { \"%.*s/%.*s\" , .os = \"mac\" }, }, },\n",
od.size, od.str, bf.size, bf.str);
fprintf(out, "};\n");
fprintf(out, "fkey_command[1] = \"build\";\n");
fprintf(out, "fkey_command[2] = \"run\";\n");
fclose(out);
success = true;
}
end_temp_memory(temp);
return(success);
}
static void
project_setup_scripts__generic(Application_Links *app, Partition *scratch,
bool32 do_project_file,
bool32 do_bat_script,
bool32 do_sh_script){
Temp_Memory temp = begin_temp_memory(scratch);
String script_path = get_hot_directory(app, scratch);
bool32 needs_to_do_work = false;
Project_Setup_Status status = {0};
if (do_project_file){
status = project_is_setup(app, scratch, script_path, make_lit_string("build"));
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
char script_file_space[1024];
char code_file_space [1024];
char output_dir_space [1024];
char binary_file_space[1024];
bool32 get_script_file = !do_project_file;
bool32 get_code_file =
(do_bat_script && !status.bat_exists) ||
(do_sh_script && !status.sh_exists);
Project_Key_Strings 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));
if (!keys.success){
return;
}
if (do_project_file){
keys.script_file = make_lit_string("build");
}
if (!do_project_file){
status = project_is_setup(app, scratch, script_path, keys.script_file);
}
// Generate Scripts
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)){
print_message(app, literal("could not create build.bat for new project\n"));
}
}
else{
print_message(app, literal("the batch script already exists, no changes made to it\n"));
}
}
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)){
print_message(app, literal("could not create build.sh for new project\n"));
}
}
else{
print_message(app, literal("the shell script already exists, no changes made to it\n"));
}
}
if (do_project_file){
if (!status.project_exists){
if (!project_generate_project_4coder_file(scratch, script_path, keys.script_file,
keys.output_dir, keys.binary_file)){
print_message(app, literal("could not create project.4coder for new project\n"));
}
}
else{
print_message(app, literal("project.4coder already exists, no changes made to it\n"));
}
}
}
else{
if (do_project_file){
print_message(app, literal("project already setup, no changes made\n"));
}
}
end_temp_memory(temp);
}
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.")
{
char space[4096];
String str = make_fixed_width_string(space);
str.size = directory_get_hot(app, str.str, str.memory_size);
int32_t dir_size = str.size;
Project_Setup_Status status = project_is_setup(app, str.str, dir_size, str.memory_size);
if (!status.everything_exists){
// Query the User for Key File Names
Query_Bar code_file_bar = {0};
Query_Bar output_dir_bar = {0};
Query_Bar binary_file_bar = {0};
char code_file_space[1024];
char output_dir_space[1024];
char binary_file_space[1024];
if (!status.bat_exists || !status.sh_exists){
code_file_bar.prompt = make_lit_string("Build Target: ");
code_file_bar.string = make_fixed_width_string(code_file_space);
if (!query_user_string(app, &code_file_bar)) return;
if (code_file_bar.string.size == 0) return;
}
output_dir_bar.prompt = make_lit_string("Output Directory: ");
output_dir_bar.string = make_fixed_width_string(output_dir_space);
if (!query_user_string(app, &output_dir_bar)) return;
if (output_dir_bar.string.size == 0){
copy(&output_dir_bar.string, ".");
}
binary_file_bar.prompt = make_lit_string("Binary Output: ");
binary_file_bar.string = make_fixed_width_string(binary_file_space);
if (!query_user_string(app, &binary_file_bar)) return;
if (binary_file_bar.string.size == 0) return;
String code_file = code_file_bar.string;
String output_dir = output_dir_bar.string;
String binary_file = binary_file_bar.string;
// Generate Scripts
if (!status.bat_exists){
replace_char(&code_file, '/', '\\');
replace_char(&output_dir, '/', '\\');
replace_char(&binary_file, '/', '\\');
str.size = dir_size;
append(&str, "/build.bat");
terminate_with_null(&str);
FILE *bat_script = fopen(str.str, "wb");
if (bat_script != 0){
fprintf(bat_script, "@echo off\n\n");
fprintf(bat_script, "set opts=%.*s\n",
global_config.default_flags_bat.size,
global_config.default_flags_bat.str);
fprintf(bat_script, "set code=%%cd%%\n");
fprintf(bat_script, "pushd %.*s\n",
output_dir.size, output_dir.str);
fprintf(bat_script, "%.*s %%opts%% %%code%%\\%.*s -Fe%.*s\n",
global_config.default_compiler_bat.size,
global_config.default_compiler_bat.str,
code_file.size, code_file.str,
binary_file.size, binary_file.str);
fprintf(bat_script, "popd\n");
fclose(bat_script);
}
else{
print_message(app, literal("could not create build.bat for new project\n"));
}
replace_char(&code_file, '\\', '/');
replace_char(&output_dir, '\\', '/');
replace_char(&binary_file, '\\', '/');
}
else{
print_message(app, literal("build.bat already exists, no changes made to it\n"));
}
if (!status.sh_exists){
str.size = dir_size;
append(&str, "/build.sh");
terminate_with_null(&str);
FILE *sh_script = fopen(str.str, "wb");
if (sh_script != 0){
fprintf(sh_script, "#!/bin/bash\n\n");
fprintf(sh_script, "code=\"$PWD\"\n");
fprintf(sh_script, "opts=%.*s\n",
global_config.default_flags_sh.size,
global_config.default_flags_sh.str);
fprintf(sh_script, "cd %.*s > /dev/null\n",
output_dir.size, output_dir.str);
fprintf(sh_script, "%.*s $opts $code/%.*s -o %.*s\n",
global_config.default_compiler_sh.size,
global_config.default_compiler_sh.str,
code_file.size, code_file.str,
binary_file.size, binary_file.str);
fprintf(sh_script, "cd $code > /dev/null\n");
fclose(sh_script);
}
else{
print_message(app, literal("could not create build.sh for new project\n"));
}
}
else{
print_message(app, literal("build.sh already exists, no changes made to it\n"));
}
if (!status.project_exists){
str.size = dir_size;
append(&str, "/project.4coder");
terminate_with_null(&str);
FILE *project_script = fopen(str.str, "wb");
if (project_script != 0){
fprintf(project_script, "extensions = \".c.cpp.h.m.bat.sh.4coder\";\n");
fprintf(project_script, "open_recursively = true;\n\n");
replace_str(&code_file, "/", "\\\\");
replace_str(&output_dir, "/", "\\\\");
replace_str(&binary_file, "/", "\\\\");
fprintf(project_script,
"fkey_command_win[1] = {\"build.bat\", \"*compilation*\", true , true };\n");
fprintf(project_script,
"fkey_command_win[2] = {\"%.*s\\\\%.*s\", \"*run*\", false , true };\n",
output_dir.size, output_dir.str,
binary_file.size, binary_file.str);
replace_str(&code_file, "\\\\", "/");
replace_str(&output_dir, "\\\\", "/");
replace_str(&binary_file, "\\\\", "/");
fprintf(project_script, "fkey_command_linux[1] = {\"./build.sh\", \"*compilation*\", true , true };\n");
fprintf(project_script,
"fkey_command_linux[2] = {\"%.*s/%.*s\", \"*run*\", false , true };\n",
output_dir.size, output_dir.str,
binary_file.size, binary_file.str);
fprintf(project_script, "fkey_command_mac[1] = {\"./build.sh\", \"*compilation*\", true , true };\n");
fprintf(project_script,
"fkey_command_mac[2] = {\"%.*s/%.*s\", \"*run*\", false , true };\n",
output_dir.size, output_dir.str,
binary_file.size, binary_file.str);
fclose(project_script);
}
else{
print_message(app, literal("could not create project.4coder for new project\n"));
}
}
else{
print_message(app, literal("project.4coder already exists, no changes made to it\n"));
}
}
else{
print_message(app, literal("project already setup, no changes made\n"));
}
project_setup_scripts__generic(app, &global_part, true, true, true);
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.")
{
project_setup_scripts__generic(app, &global_part, false, true, false);
}
CUSTOM_COMMAND_SIG(setup_build_sh)
CUSTOM_DOC("Queries the user for several configuration options and initializes a new build shell script.")
{
project_setup_scripts__generic(app, &global_part, false, false, true);
}
CUSTOM_COMMAND_SIG(setup_build_bat_and_sh)
CUSTOM_DOC("Queries the user for several configuration options and initializes a new build batch script.")
{
project_setup_scripts__generic(app, &global_part, false, true, true);
}
// BOTTOM

View File

@ -41,6 +41,7 @@ struct Project_Command{
String out;
bool32 footer_panel;
bool32 save_dirty_files;
bool32 cursor_at_end;
};
struct Project_Command_Array{
@ -76,6 +77,14 @@ struct Project_Setup_Status{
bool32 everything_exists;
};
struct Project_Key_Strings{
bool32 success;
String script_file;
String code_file;
String output_dir;
String binary_file;
};
#endif
// BOTTOM

48
4ed.cpp
View File

@ -137,31 +137,31 @@ inline void
output_file_append(System_Functions *system, Models *models, Editing_File *file, String value){
if (!file->is_dummy){
i32 end = buffer_size(&file->state.buffer);
edit_single(system, models, file,
end, end, value.str, value.size);
edit_single(system, models, file, end, end, value.str, value.size);
}
}
internal void
file_cursor_to_end(System_Functions *system, Models *models, Editing_File *file){
Assert(file != 0);
i32 pos = buffer_size(&file->state.buffer);
for (Panel *panel = models->layout.used_sentinel.next;
panel != &models->layout.used_sentinel;
panel = panel->next){
View *view = panel->view;
if (view->transient.file_data.file != file){
continue;
}
view_cursor_move(system, view, pos);
}
}
inline void
do_feedback_message(System_Functions *system, Models *models, String value, b32 set_to_start = 0){
do_feedback_message(System_Functions *system, Models *models, String value){
Editing_File *file = models->message_buffer;
if (file != 0){
output_file_append(system, models, file, value);
i32 pos = 0;
if (!set_to_start){
pos = buffer_size(&file->state.buffer);
}
for (Panel *panel = models->layout.used_sentinel.next;
panel != &models->layout.used_sentinel;
panel = panel->next){
View *view = panel->view;
if (view->transient.file_data.file != file){
continue;
}
view_cursor_move(system, view, pos);
}
file_cursor_to_end(system, models, file);
}
}
@ -1559,15 +1559,16 @@ App_Step_Sig(app_step){
CLI_Process *proc_ptr = list->procs;
for (u32 i = 0; i < list->count; ++i, ++proc_ptr){
Editing_File *file = proc_ptr->out_file;
CLI_Handles *cli = &proc_ptr->cli;
b32 edited_file = false;
u32 amount = 0;
system->cli_begin_update(cli);
if (system->cli_update_step(cli, dest, max, &amount)){
if (file != 0){
if (file != 0 && amount > 0){
amount = eol_in_place_convert_in(dest, amount);
output_file_append(system, models, file, make_string(dest, amount));
edited_file = true;
}
}
@ -1578,13 +1579,16 @@ App_Step_Sig(app_step){
append(&str, make_lit_string("exited with code "));
append_int_to_str(&str, cli->exit);
output_file_append(system, models, file, str);
edited_file = true;
}
procs_to_free[proc_free_count++] = proc_ptr;
}
if (proc_ptr->cursor_at_end && file != 0){
file_cursor_to_end(system, models, file);
}
}
// TODO(allen): proc_ptr->cursor_at_end
for (i32 i = proc_free_count - 1; i >= 0; --i){
cli_list_free_proc(list, procs_to_free[i]);
}

View File

@ -286,14 +286,6 @@ DOC_SEE(Command_Line_Interface_Flag)
file = working_set_alloc_always(working_set, general);
Assert(file != 0);
#if 0
if (file == 0){
append(&feedback_str, make_lit_string("ERROR: unable to allocate a new buffer\n"));
result = false;
goto done;
}
#endif
String name = push_string(part, buffer_id.name, buffer_id.name_len);
buffer_bind_name(models, general, part, working_set, file, name);
init_read_only_file(system, models, file);
@ -366,7 +358,10 @@ DOC_SEE(Command_Line_Interface_Flag)
}
// NOTE(allen): Attept to execute the command.
if (!cli_list_call(system, &vars->cli_processes, path_string.str, command_string.str, file, ((flags & CLI_CursorAtEnd) != 0))){
char *path_str = path_string.str;
char *command_str = command_string.str;
b32 cursor_at_end = ((flags & CLI_CursorAtEnd) != 0);
if (!cli_list_call(system, &vars->cli_processes, path_str, command_str, file, cursor_at_end)){
append(&feedback_str, "ERROR: Failed to make the cli call\n");
result = false;
}

View File

@ -26,7 +26,7 @@ build_x86_mac = "echo build: x86 & ./build.sh -DDEV_BUILD_X86";
command_list = {
{ .name = "build x64",
.out = "*compilation*", .footer_panel = true, .save_dirty_files = true,
.out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = true,
.cmd = { {"echo build: x64 & build.bat" , .os = "win" },
{"echo build: x64 & ./build.sh", .os = "linux"},
{"echo build: x64 & ./build.sh", .os = "mac" }, }, },