Create folders from interactive_open_or_new

master
Allen Webster 2020-01-14 15:35:14 -08:00
parent 8c6335afb4
commit 2865860b24
5 changed files with 137 additions and 54 deletions

View File

@ -2978,7 +2978,7 @@ make_base_allocator(Base_Allocator_Reserve_Signature *func_reserve,
}
function Data
base_allocate__inner(Base_Allocator *allocator, u64 size, String_Const_u8 location){
u64 full_size = 0;
u64 full_size = 0;
void *memory = allocator->reserve(allocator->user_data, size, &full_size, location);
allocator->commit(allocator->user_data, memory, full_size);
return(make_data(memory, (u64)full_size));
@ -4399,6 +4399,26 @@ string_front_of_path(String_Const_u32 str){
return(str);
}
function String_Const_u8
string_remove_front_folder_of_path(String_Const_u8 str){
i64 slash_pos = string_find_last_slash(string_chop(str, 1));
if (slash_pos < 0){
str.size = 0;
}
else{
str.size = slash_pos + 1;
}
return(str);
}
function String_Const_u8
string_front_folder_of_path(String_Const_u8 str){
i64 slash_pos = string_find_last_slash(string_chop(str, 1));
if (slash_pos >= 0){
str = string_skip(str, slash_pos + 1);
}
return(str);
}
function String_Const_char
string_file_extension(String_Const_char string){
return(string_skip(string, string_find_last(string, '.') + 1));
@ -4752,7 +4772,7 @@ string_find_first(String_Const_u8 str, String_Const_u8 needle, String_Match_Rule
i = str.size;
if (str.size >= needle.size){
i = 0;
u8 c = character_to_upper(needle.str[0]);
u8 c = character_to_upper(needle.str[0]);
u64 one_past_last = str.size - needle.size + 1;
for (;i < one_past_last; i += 1){
if (character_to_upper(str.str[i]) == c){
@ -4776,7 +4796,7 @@ string_find_first(String_Const_u16 str, String_Const_u16 needle, String_Match_Ru
i = str.size;
if (str.size >= needle.size){
i = 0;
u16 c = character_to_upper(needle.str[0]);
u16 c = character_to_upper(needle.str[0]);
u64 one_past_last = str.size - needle.size + 1;
for (;i < one_past_last; i += 1){
if (character_to_upper(str.str[i]) == c){
@ -4800,7 +4820,7 @@ string_find_first(String_Const_u32 str, String_Const_u32 needle, String_Match_Ru
i = str.size;
if (str.size >= needle.size){
i = 0;
u32 c = character_to_upper(needle.str[0]);
u32 c = character_to_upper(needle.str[0]);
u64 one_past_last = str.size - needle.size + 1;
for (;i < one_past_last; i += 1){
if (character_to_upper(str.str[i]) == c){
@ -5285,7 +5305,7 @@ push_string_copy(Arena *arena, u64 size, String_Const_Any src){
return(string);
}
function String_Const_u8_Array
function String_Const_u8_Array
push_string_array_copy(Arena *arena, String_Const_u8_Array src){
String_Const_u8_Array result = {};
result.vals = push_array(arena, String_Const_u8, src.count);

View File

@ -472,7 +472,7 @@ run_lister(Application_Links *app, Lister *lister){
case InputEventKind_TextInsert:
{
if (lister->handlers.write_character != 0){
lister->handlers.write_character(app);
result = lister->handlers.write_character(app);
}
}break;
@ -627,7 +627,7 @@ run_lister(Application_Links *app, Lister *lister){
switch (in.event.core.code){
case CoreCode_Animate:
{
lister_update_filtered_list(app, lister);
lister_update_filtered_list(app, lister);
}break;
default:
@ -716,8 +716,9 @@ lister_add_item(Lister *lister, String_Const_u8 string, String_Const_u8 status,
user_data, extra_space));
}
function void
function Lister_Activation_Code
lister__write_string__default(Application_Links *app){
Lister_Activation_Code result = ListerActivation_Continue;
View_ID view = get_active_view(app, Access_Always);
Lister *lister = view_get_lister(view);
if (lister != 0){
@ -731,6 +732,7 @@ lister__write_string__default(Application_Links *app){
lister_update_filtered_list(app, lister);
}
}
return(result);
}
function void

View File

@ -39,6 +39,7 @@ struct Lister_Node_Ptr_Array{
i32 count;
};
typedef Lister_Activation_Code Lister_Write_Character_Function(Application_Links *app);
typedef Lister_Activation_Code Lister_Key_Stroke_Function(Application_Links *app);
typedef void Lister_Navigate_Function(Application_Links *app,
View_ID view, struct Lister *lister,
@ -46,7 +47,7 @@ typedef void Lister_Navigate_Function(Application_Links *app,
struct Lister_Handlers{
Lister_Regenerate_List_Function_Type *refresh;
Custom_Command_Function *write_character;
Lister_Write_Character_Function *write_character;
Custom_Command_Function *backspace;
Lister_Navigate_Function *navigate;
Lister_Key_Stroke_Function *key_stroke;

View File

@ -222,7 +222,7 @@ get_color_table_from_user(Application_Links *app, String_Const_u8 query, Color_T
Lister_Result l_result = run_lister(app, lister);
Color_Table *result = 0;
Color_Table *result = 0;
if (!l_result.canceled){
result = (Color_Table*)l_result.user_data;
}
@ -236,8 +236,9 @@ get_color_table_from_user(Application_Links *app){
////////////////////////////////
function void
function Lister_Activation_Code
lister__write_character__file_path(Application_Links *app){
Lister_Activation_Code result = ListerActivation_Continue;
View_ID view = get_this_ctx_view(app, Access_Always);
Lister *lister = view_get_lister(view);
if (lister != 0){
@ -245,18 +246,20 @@ lister__write_character__file_path(Application_Links *app){
String_Const_u8 string = to_writable(&in);
if (string.str != 0 && string.size > 0){
lister_append_text_field(lister, string);
String_Const_u8 front_name = string_front_of_path(lister->text_field.string);
lister_set_key(lister, front_name);
if (character_is_slash(string.str[0])){
String_Const_u8 new_hot = lister->text_field.string;
set_hot_directory(app, new_hot);
lister_call_refresh_handler(app, lister);
lister->out.text_field = lister->text_field.string;
result = ListerActivation_Finished;
}
else{
String_Const_u8 front_name = string_front_of_path(lister->text_field.string);
lister_set_key(lister, front_name);
}
lister->item_index = 0;
lister_zero_scroll(lister);
lister_update_filtered_list(app, lister);
}
}
return(result);
}
function void
@ -374,15 +377,13 @@ struct File_Name_Result{
};
function File_Name_Result
get_file_name_from_user(Application_Links *app, Arena *arena, String_Const_u8 query,
View_ID view){
get_file_name_from_user(Application_Links *app, Arena *arena, String_Const_u8 query, View_ID view){
Lister_Handlers handlers = lister_get_default_handlers();
handlers.refresh = generate_hot_directory_file_list;
handlers.write_character = lister__write_character__file_path;
handlers.backspace = lister__backspace_text_field__file_path;
Lister_Result l_result =
run_lister_with_refresh_handler(app, arena, query, handlers);
Lister_Result l_result = run_lister_with_refresh_handler(app, arena, query, handlers);
File_Name_Result result = {};
result.canceled = l_result.canceled;
@ -391,12 +392,18 @@ get_file_name_from_user(Application_Links *app, Arena *arena, String_Const_u8 qu
if (l_result.user_data != 0){
String_Const_u8 name = SCu8((u8*)l_result.user_data);
result.file_name_activated = name;
result.is_folder =
character_is_slash(string_get_character(name, name.size -1 ));
result.is_folder = character_is_slash(string_get_character(name, name.size - 1));
}
result.file_name_in_text_field = string_front_of_path(l_result.text_field);
String_Const_u8 path = string_remove_front_of_path(l_result.text_field);
String_Const_u8 path = {};
if (result.file_name_in_text_field.size == 0 && l_result.text_field.size > 0){
result.file_name_in_text_field = string_front_folder_of_path(l_result.text_field);
path = string_remove_front_folder_of_path(l_result.text_field);
}
else{
path = string_remove_front_of_path(l_result.text_field);
}
if (character_is_slash(string_get_character(path, path.size - 1))){
path = string_chop(path, 1);
}
@ -407,8 +414,7 @@ get_file_name_from_user(Application_Links *app, Arena *arena, String_Const_u8 qu
}
function File_Name_Result
get_file_name_from_user(Application_Links *app, Arena *arena, char *query,
View_ID view){
get_file_name_from_user(Application_Links *app, Arena *arena, char *query, View_ID view){
return(get_file_name_from_user(app, arena, SCu8(query), view));
}
@ -429,8 +435,7 @@ do_buffer_kill_user_check(Application_Links *app, Buffer_ID buffer, View_ID view
lister_choice(scratch, &list, "(Y)es" , "", KeyCode_Y, SureToKill_Yes);
lister_choice(scratch, &list, "(S)ave", "", KeyCode_S, SureToKill_Save);
Lister_Choice *choice =
get_choice_from_user(app, "There are unsaved changes, close anyway?", list);
Lister_Choice *choice = get_choice_from_user(app, "There are unsaved changes, close anyway?", list);
b32 do_kill = false;
if (choice != 0){
@ -507,7 +512,7 @@ CUSTOM_DOC("Interactively switch to an open buffer.")
{
Buffer_ID buffer = get_buffer_from_user(app, "Switch:");
if (buffer != 0){
View_ID view = get_this_ctx_view(app, Access_Always);
View_ID view = get_this_ctx_view(app, Access_Always);
view_set_buffer(app, view, buffer, 0);
}
}
@ -524,6 +529,50 @@ CUSTOM_DOC("Interactively kill an open buffer.")
////////////////////////////////
enum{
SureToCreateFolder_NULL = 0,
SureToCreateFolder_No = 1,
SureToCreateFolder_Yes = 2,
};
function b32
query_create_folder(Application_Links *app, String_Const_u8 folder_name){
Scratch_Block scratch(app);
Lister_Choice_List list = {};
lister_choice(scratch, &list, "(N)o" , "", KeyCode_N, SureToKill_No);
lister_choice(scratch, &list, "(Y)es" , "", KeyCode_Y, SureToKill_Yes);
String_Const_u8 message = push_u8_stringf(scratch, "Create the folder %.*s?", string_expand(folder_name));
Lister_Choice *choice = get_choice_from_user(app, message, list);
b32 did_create_folder = false;
if (choice != 0){
switch (choice->user_data){
case SureToCreateFolder_No:
{}break;
case SureToCreateFolder_Yes:
{
String_Const_u8 hot = push_hot_directory(app, scratch);
String_Const_u8 fixed_folder_name = folder_name;
for (;fixed_folder_name.size > 0 &&
character_is_slash(fixed_folder_name.str[fixed_folder_name.size - 1]);){
fixed_folder_name = string_chop(fixed_folder_name, 1);
}
if (fixed_folder_name.size > 0){
String_Const_u8 cmd = push_u8_stringf(scratch, "mkdir %.*s", string_expand(fixed_folder_name));
exec_system_command(app, 0, buffer_identifier(0), hot, cmd, 0);
did_create_folder = true;
}
}break;
}
}
return(did_create_folder);
}
////////////////////////////////
function Lister_Activation_Code
activate_open_or_new__generic(Application_Links *app, View_ID view,
String_Const_u8 path, String_Const_u8 file_name,
@ -566,8 +615,7 @@ CUSTOM_DOC("Interactively open a file out of the file system.")
for (;;){
Scratch_Block scratch(app);
View_ID view = get_this_ctx_view(app, Access_Always);
File_Name_Result result = get_file_name_from_user(app, scratch, "Open:",
view);
File_Name_Result result = get_file_name_from_user(app, scratch, "Open:", view);
if (result.canceled) break;
String_Const_u8 file_name = result.file_name_activated;
@ -577,15 +625,27 @@ CUSTOM_DOC("Interactively open a file out of the file system.")
if (file_name.size == 0) break;
String_Const_u8 path = result.path_in_text_field;
String_Const_u8 full_file_name =
push_u8_stringf(scratch, "%.*s/%.*s",
string_expand(path), string_expand(file_name));
String_Const_u8 full_file_name = push_u8_stringf(scratch, "%.*s/%.*s",
string_expand(path), string_expand(file_name));
if (result.is_folder){
set_hot_directory(app, full_file_name);
continue;
}
if (character_is_slash(file_name.str[file_name.size - 1])){
File_Attributes attribs = system_quick_file_attributes(scratch, full_file_name);
if (HasFlag(attribs.flags, FileAttribute_IsDirectory)){
set_hot_directory(app, full_file_name);
continue;
}
if (query_create_folder(app, file_name)){
set_hot_directory(app, full_file_name);
continue;
}
break;
}
Buffer_ID buffer = create_buffer(app, full_file_name, 0);
if (buffer != 0){
view_set_buffer(app, view, buffer, 0);
@ -670,20 +730,20 @@ CUSTOM_DOC("Opens an interactive list of all registered commands.")
{
View_ID view = get_this_ctx_view(app, Access_Always);
if (view != 0){
Command_Lister_Status_Rule rule = {};
Buffer_ID buffer = view_get_buffer(app, view, Access_Visible);
Managed_Scope buffer_scope = buffer_get_managed_scope(app, buffer);
Command_Map_ID *map_id_ptr = scope_attachment(app, buffer_scope, buffer_map_id, Command_Map_ID);
if (map_id_ptr != 0){
rule = command_lister_status_bindings(&framework_mapping, *map_id_ptr);
}
else{
rule = command_lister_status_descriptions();
}
Custom_Command_Function *func = get_command_from_user(app, "Command:", &rule);
if (func != 0){
view_enqueue_command_function(app, view, func);
}
Command_Lister_Status_Rule rule = {};
Buffer_ID buffer = view_get_buffer(app, view, Access_Visible);
Managed_Scope buffer_scope = buffer_get_managed_scope(app, buffer);
Command_Map_ID *map_id_ptr = scope_attachment(app, buffer_scope, buffer_map_id, Command_Map_ID);
if (map_id_ptr != 0){
rule = command_lister_status_bindings(&framework_mapping, *map_id_ptr);
}
else{
rule = command_lister_status_descriptions();
}
Custom_Command_Function *func = get_command_from_user(app, "Command:", &rule);
if (func != 0){
view_enqueue_command_function(app, view, func);
}
}
}

View File

@ -274,7 +274,7 @@ static Command_Metadata fcoder_metacmd_table[229] = {
{ PROC_LINKS(close_build_panel, 0), false, "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "w:\\4ed\\code\\custom\\4coder_build_commands.cpp", 44, 180 },
{ PROC_LINKS(close_panel, 0), false, "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 619 },
{ PROC_LINKS(command_documentation, 0), true, "command_documentation", 21, "Prompts the user to select a command then loads a doc buffer for that item", 74, "w:\\4ed\\code\\custom\\4coder_docs.cpp", 34, 190 },
{ PROC_LINKS(command_lister, 0), true, "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 668 },
{ PROC_LINKS(command_lister, 0), true, "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 728 },
{ PROC_LINKS(comment_line, 0), false, "comment_line", 12, "Insert '//' at the beginning of the line after leading whitespace.", 66, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 125 },
{ PROC_LINKS(comment_line_toggle, 0), false, "comment_line_toggle", 19, "Turns uncommented lines into commented lines and vice versa for comments starting with '//'.", 92, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 149 },
{ PROC_LINKS(copy, 0), false, "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "w:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 19 },
@ -314,11 +314,11 @@ static Command_Metadata fcoder_metacmd_table[229] = {
{ PROC_LINKS(if_read_only_goto_position, 0), false, "if_read_only_goto_position", 26, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 562 },
{ PROC_LINKS(if_read_only_goto_position_same_panel, 0), false, "if_read_only_goto_position_same_panel", 37, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 579 },
{ PROC_LINKS(increase_face_size, 0), false, "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 671 },
{ PROC_LINKS(interactive_kill_buffer, 0), true, "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 515 },
{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 597 },
{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 634 },
{ PROC_LINKS(interactive_open_or_new, 0), true, "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 563 },
{ PROC_LINKS(interactive_switch_buffer, 0), true, "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 505 },
{ PROC_LINKS(interactive_kill_buffer, 0), true, "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 520 },
{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 657 },
{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 694 },
{ PROC_LINKS(interactive_open_or_new, 0), true, "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 612 },
{ PROC_LINKS(interactive_switch_buffer, 0), true, "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 510 },
{ PROC_LINKS(jump_to_definition, 0), true, "jump_to_definition", 18, "List all definitions in the code index and jump to one chosen by the user.", 74, "w:\\4ed\\code\\custom\\4coder_code_index_listers.cpp", 48, 12 },
{ PROC_LINKS(keyboard_macro_finish_recording, 0), false, "keyboard_macro_finish_recording", 31, "Stop macro recording, do nothing if macro recording is not already started", 74, "w:\\4ed\\code\\custom\\4coder_keyboard_macro.cpp", 44, 54 },
{ PROC_LINKS(keyboard_macro_replay, 0), false, "keyboard_macro_replay", 21, "Replay the most recently recorded keyboard macro", 48, "w:\\4ed\\code\\custom\\4coder_keyboard_macro.cpp", 44, 77 },
@ -448,7 +448,7 @@ static Command_Metadata fcoder_metacmd_table[229] = {
{ PROC_LINKS(snippet_lister, 0), true, "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 237 },
{ PROC_LINKS(suppress_mouse, 0), false, "suppress_mouse", 14, "Hides the mouse and causes all mosue input (clicks, position, wheel) to be ignored.", 83, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 403 },
{ PROC_LINKS(swap_panels, 0), false, "swap_panels", 11, "Swaps the active panel with it's sibling.", 41, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1513 },
{ PROC_LINKS(theme_lister, 0), true, "theme_lister", 12, "Opens an interactive list of all registered themes.", 51, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 692 },
{ PROC_LINKS(theme_lister, 0), true, "theme_lister", 12, "Opens an interactive list of all registered themes.", 51, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 752 },
{ PROC_LINKS(to_lowercase, 0), false, "to_lowercase", 12, "Converts all ascii text in the range between the cursor and the mark to lowercase.", 82, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 563 },
{ PROC_LINKS(to_uppercase, 0), false, "to_uppercase", 12, "Converts all ascii text in the range between the cursor and the mark to uppercase.", 82, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 550 },
{ PROC_LINKS(toggle_filebar, 0), false, "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 656 },