From d4db77b3fbf232bc9286014b5c46ec69916590c4 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sat, 3 Aug 2019 17:49:40 -0700 Subject: [PATCH] New file listing API --- 4coder_API/4coder_types.h | 27 +- 4coder_api_transition_30_31.cpp | 7 - 4coder_base_types.cpp | 1 + 4coder_generated/app_functions.h | 13 +- 4coder_generated/command_metadata.h | 54 ++-- 4coder_jump_sticky.cpp | 2 - 4coder_lists.cpp | 26 +- 4coder_project_commands.cpp | 19 +- 4ed.cpp | 4 +- 4ed_api_implementation.cpp | 62 +---- 4ed_edit.cpp | 2 +- 4ed_file.cpp | 8 +- 4ed_hot_directory.cpp | 83 ++---- 4ed_hot_directory.h | 7 +- 4ed_system.h | 16 +- 4ed_working_set.cpp | 11 +- platform_all/4ed_link_system_functions.cpp | 2 +- platform_win32/win32_4ed_functions.cpp | 292 ++++++++------------- things_ive_broken.txt | 7 +- 19 files changed, 232 insertions(+), 411 deletions(-) diff --git a/4coder_API/4coder_types.h b/4coder_API/4coder_types.h index c0ebcf62..5fdeda08 100644 --- a/4coder_API/4coder_types.h +++ b/4coder_API/4coder_types.h @@ -448,34 +448,15 @@ STRUCT File_Attributes{ File_Attribute_Flag flags; }; -/* -DOC(File_Info describes the name and type of a file.) -DOC_SEE(File_List) -*/ STRUCT File_Info{ - // TODO(allen): Can we replace file_name this with the updated string type? - // This will be API breaking in a way I can't easily wrap, but it's probably the - // right long term thing to do... Think more later. - /* DOC(This field is a null terminated string specifying the name of the file.) */ - char *filename; - /* DOC(This field specifies the length of the filename string not counting the null terminator.) */ - i32 filename_len; - /* DOC(This field indicates that the description is for a folder not a file.) */ - b32 folder; - // TODO(allen): Can we just stick File_Attributes in here? Or at least File_Attribute_Flag? + File_Info *next; + String_Const_u8 file_name; + File_Attributes attributes; }; -/* DOC(File_List is a list of File_Info structs.) -DOC_SEE(File_Info) */ STRUCT File_List{ - /* DOC(This field is for inernal use.) */ - void *block; - /* DOC(This field is an array of File_Info structs.) */ - File_Info *infos; - /* DOC(This field specifies the number of struts in the info array.) */ + File_Info **infos; u32 count; - /* DOC(This field is for internal use.) */ - u32 block_size; }; /* DOC(Buffer_Identifier acts as a loosely typed description of a buffer that can either be a name or an id.) */ diff --git a/4coder_api_transition_30_31.cpp b/4coder_api_transition_30_31.cpp index e9a4a85b..6e3595cf 100644 --- a/4coder_api_transition_30_31.cpp +++ b/4coder_api_transition_30_31.cpp @@ -569,13 +569,6 @@ directory_set_hot(Application_Links *app, char *str, i32 len){ return(set_hot_directory(app, SCu8(str, len))); } -static File_List -get_file_list(Application_Links *app, char *dir, i32 len){ - File_List list = {}; - get_file_list(app, SCu8(dir, len), &list); - return(list); -} - static b32 file_exists(Application_Links *app, char *file_name, i32 len){ File_Attributes attributes = get_file_attributes(app, SCu8(file_name, len)); diff --git a/4coder_base_types.cpp b/4coder_base_types.cpp index 520c7ffb..f4ac01a7 100644 --- a/4coder_base_types.cpp +++ b/4coder_base_types.cpp @@ -3119,6 +3119,7 @@ SCany(String_Const_u32 str){ #define string_litinit(s) {(s), sizeof(s) - 1} #define string_u8_litexpr(s) SCu8((u8*)(s), sizeof(s) - 1) #define string_u8_litinit(s) {(u8*)(s), sizeof(s) - 1} +#define string_u16_litexpr(s) SCu16((u16*)(s), sizeof(s)/2 - 1) #define string_expand(s) (i32)(s).size, (char*)(s).str diff --git a/4coder_generated/app_functions.h b/4coder_generated/app_functions.h index 32e87c45..551d2ac8 100644 --- a/4coder_generated/app_functions.h +++ b/4coder_generated/app_functions.h @@ -136,8 +136,7 @@ struct Application_Links; #define FINALIZE_COLOR_SIG(n) argb_color n(Application_Links *app, int_color color) #define PUSH_HOT_DIRECTORY_SIG(n) String_Const_u8 n(Application_Links *app, Arena *arena) #define SET_HOT_DIRECTORY_SIG(n) b32 n(Application_Links *app, String_Const_u8 string) -#define GET_FILE_LIST_SIG(n) b32 n(Application_Links *app, String_Const_u8 directory, File_List *list_out) -#define FREE_FILE_LIST_SIG(n) void n(Application_Links *app, File_List list) +#define GET_FILE_LIST_SIG(n) File_List n(Application_Links *app, Arena *arena, String_Const_u8 directory) #define SET_GUI_UP_DOWN_KEYS_SIG(n) void n(Application_Links *app, Key_Code up_key, Key_Modifier up_key_modifier, Key_Code down_key, Key_Modifier down_key_modifier) #define MEMORY_ALLOCATE_SIG(n) void* n(Application_Links *app, i32 size) #define MEMORY_SET_PROTECTION_SIG(n) b32 n(Application_Links *app, void *ptr, i32 size, Memory_Protect_Flags flags) @@ -311,7 +310,6 @@ typedef FINALIZE_COLOR_SIG(Finalize_Color_Function); typedef PUSH_HOT_DIRECTORY_SIG(Push_Hot_Directory_Function); typedef SET_HOT_DIRECTORY_SIG(Set_Hot_Directory_Function); typedef GET_FILE_LIST_SIG(Get_File_List_Function); -typedef FREE_FILE_LIST_SIG(Free_File_List_Function); typedef SET_GUI_UP_DOWN_KEYS_SIG(Set_GUI_Up_Down_Keys_Function); typedef MEMORY_ALLOCATE_SIG(Memory_Allocate_Function); typedef MEMORY_SET_PROTECTION_SIG(Memory_Set_Protection_Function); @@ -487,7 +485,6 @@ Finalize_Color_Function *finalize_color; Push_Hot_Directory_Function *push_hot_directory; Set_Hot_Directory_Function *set_hot_directory; Get_File_List_Function *get_file_list; -Free_File_List_Function *free_file_list; Set_GUI_Up_Down_Keys_Function *set_gui_up_down_keys; Memory_Allocate_Function *memory_allocate; Memory_Set_Protection_Function *memory_set_protection; @@ -662,7 +659,6 @@ Finalize_Color_Function *finalize_color_; Push_Hot_Directory_Function *push_hot_directory_; Set_Hot_Directory_Function *set_hot_directory_; Get_File_List_Function *get_file_list_; -Free_File_List_Function *free_file_list_; Set_GUI_Up_Down_Keys_Function *set_gui_up_down_keys_; Memory_Allocate_Function *memory_allocate_; Memory_Set_Protection_Function *memory_set_protection_; @@ -845,7 +841,6 @@ app_links->finalize_color_ = Finalize_Color;\ app_links->push_hot_directory_ = Push_Hot_Directory;\ app_links->set_hot_directory_ = Set_Hot_Directory;\ app_links->get_file_list_ = Get_File_List;\ -app_links->free_file_list_ = Free_File_List;\ app_links->set_gui_up_down_keys_ = Set_GUI_Up_Down_Keys;\ app_links->memory_allocate_ = Memory_Allocate;\ app_links->memory_set_protection_ = Memory_Set_Protection;\ @@ -1019,8 +1014,7 @@ static void get_theme_colors(Application_Links *app, Theme_Color *colors, i32 co static argb_color finalize_color(Application_Links *app, int_color color){return(app->finalize_color(app, color));} static String_Const_u8 push_hot_directory(Application_Links *app, Arena *arena){return(app->push_hot_directory(app, arena));} static b32 set_hot_directory(Application_Links *app, String_Const_u8 string){return(app->set_hot_directory(app, string));} -static b32 get_file_list(Application_Links *app, String_Const_u8 directory, File_List *list_out){return(app->get_file_list(app, directory, list_out));} -static void free_file_list(Application_Links *app, File_List list){(app->free_file_list(app, list));} +static File_List get_file_list(Application_Links *app, Arena *arena, String_Const_u8 directory){return(app->get_file_list(app, arena, directory));} static void set_gui_up_down_keys(Application_Links *app, Key_Code up_key, Key_Modifier up_key_modifier, Key_Code down_key, Key_Modifier down_key_modifier){(app->set_gui_up_down_keys(app, up_key, up_key_modifier, down_key, down_key_modifier));} static void* memory_allocate(Application_Links *app, i32 size){return(app->memory_allocate(app, size));} static b32 memory_set_protection(Application_Links *app, void *ptr, i32 size, Memory_Protect_Flags flags){return(app->memory_set_protection(app, ptr, size, flags));} @@ -1194,8 +1188,7 @@ static void get_theme_colors(Application_Links *app, Theme_Color *colors, i32 co static argb_color finalize_color(Application_Links *app, int_color color){return(app->finalize_color_(app, color));} static String_Const_u8 push_hot_directory(Application_Links *app, Arena *arena){return(app->push_hot_directory_(app, arena));} static b32 set_hot_directory(Application_Links *app, String_Const_u8 string){return(app->set_hot_directory_(app, string));} -static b32 get_file_list(Application_Links *app, String_Const_u8 directory, File_List *list_out){return(app->get_file_list_(app, directory, list_out));} -static void free_file_list(Application_Links *app, File_List list){(app->free_file_list_(app, list));} +static File_List get_file_list(Application_Links *app, Arena *arena, String_Const_u8 directory){return(app->get_file_list_(app, arena, directory));} static void set_gui_up_down_keys(Application_Links *app, Key_Code up_key, Key_Modifier up_key_modifier, Key_Code down_key, Key_Modifier down_key_modifier){(app->set_gui_up_down_keys_(app, up_key, up_key_modifier, down_key, down_key_modifier));} static void* memory_allocate(Application_Links *app, i32 size){return(app->memory_allocate_(app, size));} static b32 memory_set_protection(Application_Links *app, void *ptr, i32 size, Memory_Protect_Flags flags){return(app->memory_set_protection_(app, ptr, size, flags));} diff --git a/4coder_generated/command_metadata.h b/4coder_generated/command_metadata.h index dfbcec63..5f120b9f 100644 --- a/4coder_generated/command_metadata.h +++ b/4coder_generated/command_metadata.h @@ -395,12 +395,12 @@ static Command_Metadata fcoder_metacmd_table[237] = { { PROC_LINKS(lister__write_character__file_path, 0), "lister__write_character__file_path", 34, "A lister mode command that inserts a character into the text field of a file system list.", 89, "w:\\4ed\\code\\4coder_lists.cpp", 28, 183 }, { PROC_LINKS(lister__backspace_text_field__file_path, 0), "lister__backspace_text_field__file_path", 39, "A lister mode command that backspaces one character from the text field of a file system list.", 94, "w:\\4ed\\code\\4coder_lists.cpp", 28, 208 }, { PROC_LINKS(lister__write_character__fixed_list, 0), "lister__write_character__fixed_list", 35, "A lister mode command that handles input for the fixed sure to kill list.", 73, "w:\\4ed\\code\\4coder_lists.cpp", 28, 249 }, -{ PROC_LINKS(interactive_switch_buffer, 0), "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "w:\\4ed\\code\\4coder_lists.cpp", 28, 725 }, -{ PROC_LINKS(interactive_kill_buffer, 0), "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "w:\\4ed\\code\\4coder_lists.cpp", 28, 744 }, -{ PROC_LINKS(interactive_open_or_new, 0), "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "w:\\4ed\\code\\4coder_lists.cpp", 28, 817 }, -{ PROC_LINKS(interactive_new, 0), "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\4coder_lists.cpp", 28, 856 }, -{ PROC_LINKS(interactive_open, 0), "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\4coder_lists.cpp", 28, 889 }, -{ PROC_LINKS(command_lister, 0), "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "w:\\4ed\\code\\4coder_lists.cpp", 28, 971 }, +{ PROC_LINKS(interactive_switch_buffer, 0), "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "w:\\4ed\\code\\4coder_lists.cpp", 28, 723 }, +{ PROC_LINKS(interactive_kill_buffer, 0), "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "w:\\4ed\\code\\4coder_lists.cpp", 28, 742 }, +{ PROC_LINKS(interactive_open_or_new, 0), "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "w:\\4ed\\code\\4coder_lists.cpp", 28, 815 }, +{ PROC_LINKS(interactive_new, 0), "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\4coder_lists.cpp", 28, 854 }, +{ PROC_LINKS(interactive_open, 0), "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\4coder_lists.cpp", 28, 887 }, +{ PROC_LINKS(command_lister, 0), "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "w:\\4ed\\code\\4coder_lists.cpp", 28, 969 }, { PROC_LINKS(auto_tab_whole_file, 0), "auto_tab_whole_file", 19, "Audo-indents the entire current buffer.", 39, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 546 }, { PROC_LINKS(auto_tab_line_at_cursor, 0), "auto_tab_line_at_cursor", 23, "Auto-indents the line on which the cursor sits.", 47, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 555 }, { PROC_LINKS(auto_tab_range, 0), "auto_tab_range", 14, "Auto-indents the range between the cursor and the mark.", 55, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 565 }, @@ -425,16 +425,16 @@ static Command_Metadata fcoder_metacmd_table[237] = { { PROC_LINKS(goto_first_jump_direct, 0), "goto_first_jump_direct", 22, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "w:\\4ed\\code\\4coder_jump_direct.cpp", 34, 88 }, { PROC_LINKS(newline_or_goto_position_direct, 0), "newline_or_goto_position_direct", 31, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "w:\\4ed\\code\\4coder_jump_direct.cpp", 34, 103 }, { 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, "w:\\4ed\\code\\4coder_jump_direct.cpp", 34, 120 }, -{ PROC_LINKS(goto_jump_at_cursor_sticky, 0), "goto_jump_at_cursor_sticky", 26, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 354 }, -{ PROC_LINKS(goto_jump_at_cursor_same_panel_sticky, 0), "goto_jump_at_cursor_same_panel_sticky", 37, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list.", 167, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 381 }, -{ PROC_LINKS(goto_next_jump_sticky, 0), "goto_next_jump_sticky", 21, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 480 }, -{ PROC_LINKS(goto_prev_jump_sticky, 0), "goto_prev_jump_sticky", 21, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.", 127, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 497 }, -{ PROC_LINKS(goto_next_jump_no_skips_sticky, 0), "goto_next_jump_no_skips_sticky", 30, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, and does not skip sub jump locations.", 132, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 510 }, -{ PROC_LINKS(goto_prev_jump_no_skips_sticky, 0), "goto_prev_jump_no_skips_sticky", 30, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.", 136, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 527 }, -{ PROC_LINKS(goto_first_jump_sticky, 0), "goto_first_jump_sticky", 22, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 541 }, -{ PROC_LINKS(goto_first_jump_same_panel_sticky, 0), "goto_first_jump_same_panel_sticky", 33, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer and views the buffer in the panel where the jump list was.", 153, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 558 }, -{ 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, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 580 }, -{ 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, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 597 }, +{ PROC_LINKS(goto_jump_at_cursor_sticky, 0), "goto_jump_at_cursor_sticky", 26, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 352 }, +{ PROC_LINKS(goto_jump_at_cursor_same_panel_sticky, 0), "goto_jump_at_cursor_same_panel_sticky", 37, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list.", 167, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 379 }, +{ PROC_LINKS(goto_next_jump_sticky, 0), "goto_next_jump_sticky", 21, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 478 }, +{ PROC_LINKS(goto_prev_jump_sticky, 0), "goto_prev_jump_sticky", 21, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.", 127, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 495 }, +{ PROC_LINKS(goto_next_jump_no_skips_sticky, 0), "goto_next_jump_no_skips_sticky", 30, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, and does not skip sub jump locations.", 132, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 508 }, +{ PROC_LINKS(goto_prev_jump_no_skips_sticky, 0), "goto_prev_jump_no_skips_sticky", 30, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.", 136, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 525 }, +{ PROC_LINKS(goto_first_jump_sticky, 0), "goto_first_jump_sticky", 22, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 539 }, +{ PROC_LINKS(goto_first_jump_same_panel_sticky, 0), "goto_first_jump_same_panel_sticky", 33, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer and views the buffer in the panel where the jump list was.", 153, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 556 }, +{ 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, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 578 }, +{ 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, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 595 }, { PROC_LINKS(view_jump_list_with_lister, 0), "view_jump_list_with_lister", 26, "When executed on a buffer with jumps, creates a persistent lister for all the jumps", 83, "w:\\4ed\\code\\4coder_jump_lister.cpp", 34, 104 }, { PROC_LINKS(copy, 0), "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "w:\\4ed\\code\\4coder_clipboard.cpp", 32, 19 }, { PROC_LINKS(cut, 0), "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "w:\\4ed\\code\\4coder_clipboard.cpp", 32, 28 }, @@ -448,17 +448,17 @@ static Command_Metadata fcoder_metacmd_table[237] = { { PROC_LINKS(build_in_build_panel, 0), "build_in_build_panel", 20, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*. Puts the *compilation* buffer in a panel at the footer of the current view.", 230, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 163 }, { PROC_LINKS(close_build_panel, 0), "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 178 }, { PROC_LINKS(change_to_build_panel, 0), "change_to_build_panel", 21, "If the special build panel is open, makes the build panel the active panel.", 75, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 184 }, -{ 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, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 928 }, -{ 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, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 934 }, -{ PROC_LINKS(open_all_code_recursive, 0), "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 940 }, -{ 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, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 948 }, -{ 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, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 955 }, -{ 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, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 978 }, -{ 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, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1313 }, -{ 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, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1320 }, -{ 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, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1326 }, -{ 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, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1332 }, -{ PROC_LINKS(project_command_lister, 0), "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1347 }, +{ 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, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 921 }, +{ 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, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 927 }, +{ PROC_LINKS(open_all_code_recursive, 0), "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 933 }, +{ 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, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 941 }, +{ 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, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 948 }, +{ 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, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 971 }, +{ 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, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1306 }, +{ 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, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1313 }, +{ 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, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1319 }, +{ 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, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1325 }, +{ PROC_LINKS(project_command_lister, 0), "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1340 }, { PROC_LINKS(list_all_functions_current_buffer, 0), "list_all_functions_current_buffer", 33, "Creates a jump list of lines of the current buffer that appear to define or declare functions.", 94, "w:\\4ed\\code\\4coder_function_list.cpp", 36, 266 }, { PROC_LINKS(list_all_functions_current_buffer_lister, 0), "list_all_functions_current_buffer_lister", 40, "Creates a lister of locations that look like function definitions and declarations in the buffer.", 97, "w:\\4ed\\code\\4coder_function_list.cpp", 36, 276 }, { PROC_LINKS(list_all_functions_all_buffers, 0), "list_all_functions_all_buffers", 30, "Creates a jump list of lines from all buffers that appear to define or declare functions.", 89, "w:\\4ed\\code\\4coder_function_list.cpp", 36, 288 }, diff --git a/4coder_jump_sticky.cpp b/4coder_jump_sticky.cpp index 02ae0bff..bd0dd0a3 100644 --- a/4coder_jump_sticky.cpp +++ b/4coder_jump_sticky.cpp @@ -106,8 +106,6 @@ init_marker_list(Application_Links *app, Heap *heap, Buffer_ID buffer, Marker_Li Arena *scratch = context_get_arena(app); Temp_Memory temp = begin_temp(scratch); - String_Const_u8 buffer_name = push_buffer_base_name(app, scratch, buffer); - Sticky_Jump_Array jumps = parse_buffer_to_jump_array(app, scratch, buffer); Range_Array buffer_ranges = get_ranges_of_duplicate_keys(scratch, &jumps.jumps->jump_buffer_id, sizeof(*jumps.jumps), jumps.count); Sort_Pair_i32 *range_index_buffer_id_pairs = push_array(scratch, Sort_Pair_i32, buffer_ranges.count); diff --git a/4coder_lists.cpp b/4coder_lists.cpp index 367be5ab..0f2011d4 100644 --- a/4coder_lists.cpp +++ b/4coder_lists.cpp @@ -526,6 +526,8 @@ generate_all_buffers_list(Application_Links *app, Lister *lister){ static void generate_hot_directory_file_list(Application_Links *app, Lister *lister){ + Scratch_Block scratch(app); + Temp_Memory temp = begin_temp(&lister->arena); String_Const_u8 hot = push_hot_directory(app, &lister->arena); if (!character_is_slash(string_get_character(hot, hot.size - 1))){ @@ -534,11 +536,10 @@ generate_hot_directory_file_list(Application_Links *app, Lister *lister){ lister_set_text_field(lister, hot); lister_set_key(lister, string_front_of_path(hot)); - File_List file_list = {}; - get_file_list(app, hot, &file_list); + File_List file_list = get_file_list(app, scratch, hot); end_temp(temp); - File_Info *one_past_last = file_list.infos + file_list.count; + File_Info **one_past_last = file_list.infos + file_list.count; lister_begin_new_item_set(app, lister); @@ -547,31 +548,30 @@ generate_hot_directory_file_list(Application_Links *app, Lister *lister){ if (hot.str != 0){ String_Const_u8 empty_string = string_u8_litexpr(""); Lister_Prealloced_String empty_string_prealloced = lister_prealloced(empty_string); - for (File_Info *info = file_list.infos; + for (File_Info **info = file_list.infos; info < one_past_last; info += 1){ - if (!info->folder) continue; - String_Const_u8 file_name = push_u8_stringf(&lister->arena, "%.*s/", info->filename_len, info->filename); + if (!HasFlag((**info).attributes.flags, FileAttribute_IsDirectory)) continue; + String_Const_u8 file_name = push_u8_stringf(&lister->arena, "%.*s/", + string_expand((**info).file_name)); lister_add_item(lister, lister_prealloced(file_name), empty_string_prealloced, file_name.str, 0); } - for (File_Info *info = file_list.infos; + for (File_Info **info = file_list.infos; info < one_past_last; info += 1){ - if (info->folder) continue; - String_Const_u8 file_name = push_string_copy(&lister->arena, SCu8(info->filename, info->filename_len)); + if (HasFlag((**info).attributes.flags, FileAttribute_IsDirectory)) continue; + String_Const_u8 file_name = push_string_copy(&lister->arena, (**info).file_name); char *is_loaded = ""; char *status_flag = ""; - Buffer_ID buffer = {}; { Temp_Memory path_temp = begin_temp(&lister->arena); List_String_Const_u8 list = {}; string_list_push(&lister->arena, &list, hot); - string_list_push_overlap(&lister->arena, &list, '/', - SCu8(info->filename, info->filename_len)); + string_list_push_overlap(&lister->arena, &list, '/', (**info).file_name); String_Const_u8 full_file_path = string_list_flatten(&lister->arena, list); buffer = get_buffer_by_file_name(app, full_file_path, AccessAll); end_temp(path_temp); @@ -590,8 +590,6 @@ generate_hot_directory_file_list(Application_Links *app, Lister *lister){ lister_add_item(lister, lister_prealloced(file_name), lister_prealloced(status), file_name.str, 0); } } - - free_file_list(app, file_list); } static void diff --git a/4coder_project_commands.cpp b/4coder_project_commands.cpp index 534efc4b..2568fb2b 100644 --- a/4coder_project_commands.cpp +++ b/4coder_project_commands.cpp @@ -91,20 +91,15 @@ open_all_files_in_directory_pattern_match__recursive(Application_Links *app, Project_File_Pattern_Array blacklist, u32 flags){ Scratch_Block scratch(app); - File_List list = {}; - get_file_list(app, path, &list); + File_List list = get_file_list(app, scratch, path); - File_Info *info = list.infos; + File_Info **info = list.infos; for (u32 i = 0; i < list.count; ++i, ++info){ - String_Const_u8 file_name = SCu8(info->filename, info->filename_len); + String_Const_u8 file_name = (**info).file_name; - if (info->folder){ - if ((flags & OpenAllFilesFlag_Recursive) == 0){ - continue; - } - if (match_in_pattern_array(file_name, blacklist)){ - continue; - } + if (HasFlag((**info).attributes.flags, FileAttribute_IsDirectory)){ + if ((flags & OpenAllFilesFlag_Recursive) == 0) continue; + if (match_in_pattern_array(file_name, blacklist)) continue; String_Const_u8 new_path = push_u8_stringf(scratch, "%.*s%.*s/", string_expand(path), @@ -126,8 +121,6 @@ open_all_files_in_directory_pattern_match__recursive(Application_Links *app, create_buffer(app, full_path, 0); } } - - free_file_list(app, list); } static Project_File_Pattern_Array diff --git a/4ed.cpp b/4ed.cpp index d74b268f..5d323598 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -981,7 +981,7 @@ App_Init_Sig(app_init){ } // NOTE(allen): miscellaneous init - hot_directory_init(&models->hot_directory, current_directory); + hot_directory_init(system, arena, &models->hot_directory, current_directory); child_process_container_init(&models->child_processes, models); models->user_up_key = key_up; models->user_down_key = key_down; @@ -1028,7 +1028,7 @@ App_Step_Sig(app_step){ for (;system->get_file_change(buffer, buffer_size, &mem_too_small, &size);){ Assert(!mem_too_small); Editing_File_Name canon = {}; - if (get_canon_name(system, SCu8(buffer, size), &canon)){ + if (get_canon_name(system, scratch, SCu8(buffer, size), &canon)){ Editing_File *file = working_set_contains_canon(working_set, string_from_file_name(&canon)); if (file != 0){ if (file->state.ignore_behind_os == 0){ diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 71841662..eba9b285 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -304,7 +304,8 @@ DOC_SEE(Access_Flag) System_Functions *system = models->system; Editing_File_Name canon = {}; Buffer_ID result = false; - if (get_canon_name(system, file_name, &canon)){ + Scratch_Block scratch(app); + if (get_canon_name(system, scratch, file_name, &canon)){ Working_Set *working_set = &models->working_set; Editing_File *file = working_set_contains_canon(working_set, string_from_file_name(&canon)); if (api_check_buffer(file, access)){ @@ -3147,8 +3148,7 @@ DOC_SEE(directory_set_hot) Models *models = (Models*)app->cmd_context; Hot_Directory *hot = &models->hot_directory; hot_directory_clean_end(hot); - String_Const_u8 result = push_string_copy(arena, SCu8(hot->string_space, hot->string_size)); - return(result); + return(push_string_copy(arena, hot->string)); } // TODO(allen): redocument @@ -3163,56 +3163,16 @@ DOC_SEE(directory_get_hot) */{ Models *models = (Models*)app->cmd_context; Hot_Directory *hot = &models->hot_directory; - b32 success = false; - if (string.size < sizeof(hot->string_space)){ - hot_directory_set(models->system, hot, string); - success = true; - } - return(success); + hot_directory_set(models->system, hot, string); + return(true); } -// TODO(allen): redocument -API_EXPORT b32 -Get_File_List(Application_Links *app, String_Const_u8 directory, File_List *list_out) -/* -DOC_PARAM(dir, This parameter specifies the directory whose files will be enumerated in the returned list; it need not be null terminated.) -DOC_PARAM(len, This parameter the length of the dir string.) -DOC_RETURN(This call returns a File_List struct containing pointers to the names of the files in the specified directory. The File_List returned should be passed to free_file_list when it is no longer in use.) -DOC_SEE(File_List) -*/{ +API_EXPORT File_List +Get_File_List(Application_Links *app, Arena *arena, String_Const_u8 directory){ Models *models = (Models*)app->cmd_context; System_Functions *system = models->system; - block_zero_struct(list_out); - Editing_File_Name canon = {}; - b32 result = false; - if (get_canon_name(system, directory, &canon)){ - Arena *scratch = &models->mem.arena; - Temp_Memory temp = begin_temp(scratch); - char *str = 0; - if (canon.name_size < sizeof(canon.name_space)){ - canon.name_space[canon.name_size] = 0; - str = (char*)canon.name_space; - } - else{ - String_Const_u8 s = push_string_copy(scratch, string_from_file_name(&canon)); - str = (char*)s.str; - } - system->set_file_list(list_out, str, 0, 0, 0); - end_temp(temp); - result = true; - } - return(result); -} - -API_EXPORT void -Free_File_List(Application_Links *app, File_List list) -/* -DOC_PARAM(list, This parameter provides the file list to be freed.) -DOC(After this call the file list passed in should not be read or written to.) -DOC_SEE(File_List) -*/{ - Models *models = (Models*)app->cmd_context; - models->system->set_file_list(&list, 0, 0, 0, 0); + String_Const_u8 canonical_directory = system->get_canonical(arena, directory); + return(system->get_file_list(arena, canonical_directory)); } API_EXPORT void @@ -3626,7 +3586,7 @@ Text_Layout_Line_On_Screen(Application_Links *app, Text_Layout_ID layout_id, i64 Face *face = font_set_face_from_id(&models->font_set, file->settings.font_id); f32 line_height = face->height; bot += line_height; - + result = Rf32(layout.coordinates.on_screen_p0.x, top, layout.coordinates.on_screen_p0.x + layout.coordinates.dim.x, bot); @@ -3740,7 +3700,7 @@ Compute_Render_Layout(Application_Links *app, View_ID view_id, Buffer_ID buffer_ linalloc_clear(&view->layout_arena); } Buffer_Render_Item *items = push_array(&view->layout_arena, Buffer_Render_Item, max); - + b32 wrapped = (!file->settings.unwrapped_lines); Full_Cursor intermediate_cursor = file_compute_cursor(models, file, seek_line_char(buffer_point.line_number, 1)); diff --git a/4ed_edit.cpp b/4ed_edit.cpp index fc8ca209..07372853 100644 --- a/4ed_edit.cpp +++ b/4ed_edit.cpp @@ -531,7 +531,7 @@ create_file(Models *models, String_Const_u8 file_name, Buffer_Create_Flag flags) // NOTE(allen): Try to get the file by canon name. if (HasFlag(flags, BufferCreate_NeverAttachToFile) == 0){ - if (get_canon_name(system, file_name, &canon)){ + if (get_canon_name(system, scratch, file_name, &canon)){ has_canon_name = true; file = working_set_contains_canon(working_set, string_from_file_name(&canon)); } diff --git a/4ed_file.cpp b/4ed_file.cpp index c4d662f0..8cc0cd31 100644 --- a/4ed_file.cpp +++ b/4ed_file.cpp @@ -138,6 +138,7 @@ file_name_terminate(Editing_File_Name *name){ //////////////////////////////// +// TODO(allen): file_name should be String_Const_u8 internal b32 save_file_to_name(System_Functions *system, Models *models, Editing_File *file, u8 *file_name){ b32 result = false; @@ -188,10 +189,9 @@ save_file_to_name(System_Functions *system, Models *models, Editing_File *file, } if (!using_actual_file_name){ - char space[512]; - umem length = cstring_length(file_name); - system->get_canonical((char*)file_name, (u32)length, space, sizeof(space)); - if (string_match(SCu8(space), string_from_file_name(&file->canon))){ + String_Const_u8 s_file_name = SCu8(file_name); + String_Const_u8 canonical_file_name = system->get_canonical(scratch, s_file_name); + if (string_match(canonical_file_name, string_from_file_name(&file->canon))){ using_actual_file_name = true; } } diff --git a/4ed_hot_directory.cpp b/4ed_hot_directory.cpp index e78a3708..3ce38a50 100644 --- a/4ed_hot_directory.cpp +++ b/4ed_hot_directory.cpp @@ -11,34 +11,34 @@ internal void hot_directory_clean_end(Hot_Directory *hot_directory){ - String_Const_u8 str = SCu8(hot_directory->string_space, hot_directory->string_size); + String_Const_u8 str = hot_directory->string; if (!character_is_slash(string_get_character(str, str.size - 1))){ - str = string_remove_last_folder(str); - str.str[str.size] = 0; + hot_directory->string = string_remove_last_folder(str); } } internal i32 -hot_directory_quick_partition(File_Info *infos, i32 start, i32 pivot){ - File_Info *p = infos + pivot; - File_Info *a = infos + start; +hot_directory_quick_partition(File_Info **infos, i32 start, i32 pivot){ + File_Info **p = infos + pivot; + File_Info **a = infos + start; for (i32 i = start; i < pivot; ++i, ++a){ - i32 comp = p->folder - a->folder; + b32 p_folder = (HasFlag((**p).attributes.flags, FileAttribute_IsDirectory)); + b32 a_folder = (HasFlag((**a).attributes.flags, FileAttribute_IsDirectory)); + i32 comp = p_folder - a_folder; if (comp == 0){ - comp = string_compare(SCu8(a->filename, a->filename_len), - SCu8(p->filename, p->filename_len)); + comp = string_compare((**a).file_name, (**p).file_name); } if (comp < 0){ - Swap(File_Info, *a, infos[start]); + Swap(File_Info*, *a, infos[start]); ++start; } } - Swap(File_Info, *p, infos[start]); - return start; + Swap(File_Info*, *p, infos[start]); + return(start); } internal void -hot_directory_quick_sort(File_Info *infos, i32 start, i32 pivot){ +hot_directory_quick_sort(File_Info **infos, i32 start, i32 pivot){ i32 mid = hot_directory_quick_partition(infos, start, pivot); if (start < mid-1) hot_directory_quick_sort(infos, start, mid-1); if (mid+1 < pivot) hot_directory_quick_sort(infos, mid+1, pivot); @@ -54,55 +54,30 @@ hot_directory_fixup(Hot_Directory *hot_directory){ internal void hot_directory_set(System_Functions *system, Hot_Directory *hot_directory, String_Const_u8 str){ - b32 success = (str.size < sizeof(hot_directory->string_space)); - if (success){ - block_copy(hot_directory->string_space, str.str, str.size); - hot_directory->string_space[str.size] = 0; - hot_directory->string_size = str.size; - if (str.size > 0){ - u32 canon_max = sizeof(hot_directory->canon_dir_space); - u8 *canon_str = hot_directory->canon_dir_space; - u32 canon_length = 0; - system->set_file_list(&hot_directory->file_list, (char*)hot_directory->string_space, (char*)canon_str, &canon_length, canon_max); - if (canon_length > 0){ - hot_directory->canon_dir_size = canon_length; - if (!character_is_slash(hot_directory->canon_dir_space[canon_length - 1])){ - hot_directory->canon_dir_space[hot_directory->canon_dir_size] = '/'; - hot_directory->canon_dir_size += 1; - hot_directory->canon_dir_space[hot_directory->canon_dir_size] = 0; - } - } - else{ - hot_directory->canon_dir_size = 0; - } - } - else{ - system->set_file_list(&hot_directory->file_list, 0, 0, 0, 0); - hot_directory->canon_dir_size = 0; - } - } - hot_directory_fixup(hot_directory); + linalloc_clear(&hot_directory->arena); + hot_directory->string = push_string_copy(&hot_directory->arena, str); + hot_directory->canonical = system->get_canonical(&hot_directory->arena, str); + hot_directory->file_list = system->get_file_list(&hot_directory->arena, hot_directory->canonical); } internal void -hot_directory_reload(System_Functions *system, Hot_Directory *hot_directory){ - String_Const_u8 string = SCu8(hot_directory->string_space, hot_directory->string_size); +hot_directory_reload(System_Functions *system, Arena *scratch, Hot_Directory *hot_directory){ + Temp_Memory temp = begin_temp(scratch); + String_Const_u8 string = push_string_copy(scratch, hot_directory->string); hot_directory_set(system, hot_directory, string); + end_temp(temp); } internal void -hot_directory_init(Hot_Directory *hot_directory, String_Const_u8 dir){ - hot_directory->string_size = 0; - umem size = clamp_top(dir.size, sizeof(hot_directory->string_space)); - block_copy(hot_directory->string_space, dir.str, size); - if (dir.size < sizeof(hot_directory->string_space)){ - if (hot_directory->string_space[size - 1] != '/'){ - hot_directory->string_space[size] = '/'; - size = clamp_top(size + 1, sizeof(hot_directory->string_space)); - hot_directory->string_space[size] = 0; - hot_directory->string_size = size; - } +hot_directory_init(System_Functions *system, Arena *scratch, Hot_Directory *hot_directory, String_Const_u8 directory){ + hot_directory->arena = make_arena_system(system); + Temp_Memory temp = begin_temp(scratch); + String_Const_u8 dir = directory; + if (!character_is_slash(string_get_character(directory, directory.size - 1))){ + dir = push_u8_stringf(scratch, "%.*s/", string_expand(directory)); } + hot_directory_set(system, hot_directory, dir); + end_temp(temp); } // BOTTOM diff --git a/4ed_hot_directory.h b/4ed_hot_directory.h index 2ad726f3..362700cb 100644 --- a/4ed_hot_directory.h +++ b/4ed_hot_directory.h @@ -13,10 +13,9 @@ #define FRED_HOT_DIRECTORY_H struct Hot_Directory{ - u8 string_space[256]; - umem string_size; - u8 canon_dir_space[256]; - umem canon_dir_size; + Arena arena; + String_Const_u8 string; + String_Const_u8 canonical; File_List file_list; }; diff --git a/4ed_system.h b/4ed_system.h index b713f5fd..a3a0e92a 100644 --- a/4ed_system.h +++ b/4ed_system.h @@ -19,19 +19,13 @@ struct Plat_Handle{ u32 d[4]; }; -internal b32 -handle_equal(Plat_Handle a, Plat_Handle b){ - b32 result = (memcmp(&a, &b, sizeof(a)) == 0); - return(result); -} - // files -#define Sys_Set_File_List_Sig(name) void name(File_List *file_list, char *directory, char *canon_directory_out, u32 *canon_directory_size_out, u32 canon_directory_max) -typedef Sys_Set_File_List_Sig(System_Set_File_List); - -#define Sys_Get_Canonical_Sig(name) u32 name(char *filename, u32 len, char *buffer, u32 max) +#define Sys_Get_Canonical_Sig(n) String_Const_u8 n(Arena *arena, String_Const_u8 name) typedef Sys_Get_Canonical_Sig(System_Get_Canonical); +#define Sys_Get_File_List_Sig(name) File_List name(Arena *arena, String_Const_u8 directory) +typedef Sys_Get_File_List_Sig(System_Get_File_List); + // file load/save #define Sys_Quick_File_Attributes_Sig(name) File_Attributes name(String_Const_u8 file_name) typedef Sys_Quick_File_Attributes_Sig(System_Quick_File_Attributes); @@ -230,8 +224,8 @@ struct System_Functions{ Graphics_Fill_Texture_Function *fill_texture; // files (tracked api): 11 - System_Set_File_List *set_file_list; System_Get_Canonical *get_canonical; + System_Get_File_List *get_file_list; System_Add_Listener *add_listener; System_Remove_Listener *remove_listener; System_Get_File_Change *get_file_change; diff --git a/4ed_working_set.cpp b/4ed_working_set.cpp index 2afafe1e..3236741a 100644 --- a/4ed_working_set.cpp +++ b/4ed_working_set.cpp @@ -285,10 +285,15 @@ working_set_clipboard_roll_down(Working_Set *working){ //////////////////////////////// +// TODO(allen): get rid of this??? internal b32 -get_canon_name(System_Functions *system, String_Const_u8 file_name, Editing_File_Name *canon_name){ - canon_name->name_size = system->get_canonical((char*)file_name.str, (u32)file_name.size, - (char*)canon_name->name_space, sizeof(canon_name->name_space)); +get_canon_name(System_Functions *system, Arena *scratch, String_Const_u8 file_name, Editing_File_Name *canon_name){ + Temp_Memory temp = begin_temp(scratch); + String_Const_u8 canonical = system->get_canonical(scratch, file_name); + umem size = Min(sizeof(canon_name->name_space), canonical.size); + block_copy(canon_name->name_space, canonical.str, size); + canon_name->name_size = size; + end_temp(temp); file_name_terminate(canon_name); return(canon_name->name_size > 0); } diff --git a/platform_all/4ed_link_system_functions.cpp b/platform_all/4ed_link_system_functions.cpp index f1f00e7e..658e72fa 100644 --- a/platform_all/4ed_link_system_functions.cpp +++ b/platform_all/4ed_link_system_functions.cpp @@ -15,8 +15,8 @@ internal void link_system_code(){ - SYSLINK(set_file_list); SYSLINK(get_canonical); + SYSLINK(get_file_list); SYSLINK(add_listener); SYSLINK(remove_listener); SYSLINK(get_file_change); diff --git a/platform_win32/win32_4ed_functions.cpp b/platform_win32/win32_4ed_functions.cpp index 1f3f0cec..6667ed88 100644 --- a/platform_win32/win32_4ed_functions.cpp +++ b/platform_win32/win32_4ed_functions.cpp @@ -118,205 +118,63 @@ win32_remove_unc_prefix_characters(String_Const_u8 path){ return(path); } -internal -Sys_Set_File_List_Sig(system_set_file_list){ - b32 clear_list = true; - if (directory != 0){ - u8 dir_space[MAX_PATH + 32]; - umem directory_original_length = cstring_length(directory); - block_copy(dir_space, directory, directory_original_length); - dir_space[directory_original_length] = 0; - String_Const_u8 dir = SCu8(dir_space, directory_original_length); - - HANDLE dir_handle = CreateFile_utf8(&shared_vars.scratch, dir.str, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, 0); - - if (dir_handle != INVALID_HANDLE_VALUE){ - DWORD final_length = GetFinalPathNameByHandle_utf8(&shared_vars.scratch, dir_handle, dir_space, sizeof(dir_space), 0); - CloseHandle(dir_handle); - - if (final_length + 3 < sizeof(dir_space)){ - u8 *c_str_dir = dir_space; - if (c_str_dir[final_length - 1] == 0){ - --final_length; - } - String_Const_u8 str_dir = SCu8(c_str_dir, final_length); - String_Const_u8 adjusted_str_dir = win32_remove_unc_prefix_characters(str_dir); - - c_str_dir = adjusted_str_dir.str; - final_length = (DWORD)(adjusted_str_dir.size); - c_str_dir[final_length] = '\\'; - c_str_dir[final_length + 1] = '*'; - c_str_dir[final_length + 2] = 0; - - if (canon_directory_out != 0){ - if (final_length + 1 < canon_directory_max){ - memcpy(canon_directory_out, c_str_dir, final_length); - if (canon_directory_out[final_length-1] != '\\'){ - canon_directory_out[final_length++] = '\\'; - } - canon_directory_out[final_length] = 0; - *canon_directory_size_out = final_length; - } - else{ - block_copy(canon_directory_out, directory, directory_original_length); - canon_directory_out[directory_original_length] = 0; - *canon_directory_size_out = (i32)directory_original_length; - } - } - - WIN32_FIND_DATA find_data; - HANDLE search = FindFirstFile_utf8(&shared_vars.scratch, c_str_dir, &find_data); - - if (search != INVALID_HANDLE_VALUE){ - u32 character_count = 0; - u32 file_count = 0; - BOOL more_files = true; - do{ - b32 nav_dir = - (find_data.cFileName[0] == '.' && find_data.cFileName[1] == 0) ||(find_data.cFileName[0] == '.' && find_data.cFileName[1] == '.' && find_data.cFileName[2] == 0); - if (!nav_dir){ - ++file_count; - u32 size = 0; - for(;find_data.cFileName[size];++size); - character_count += size + 1; - } - more_files = FindNextFile(search, &find_data); - }while(more_files); - FindClose(search); - - u32 remaining_size = character_count*2; - u32 required_size = remaining_size + file_count*sizeof(File_Info); - if (file_list->block_size < required_size){ - system_memory_free(file_list->block, 0); - file_list->block = system_memory_allocate(required_size); - file_list->block_size = required_size; - } - - file_list->infos = (File_Info*)file_list->block; - u8 *name = (u8*)(file_list->infos + file_count); - u32 corrected_file_count = 0; - if (file_list->block != 0){ - search = FindFirstFile_utf8(&shared_vars.scratch, c_str_dir, &find_data); - - if (search != INVALID_HANDLE_VALUE){ - File_Info *info = file_list->infos; - more_files = true; - do{ - b32 nav_dir = - (find_data.cFileName[0] == '.' && find_data.cFileName[1] == 0) ||(find_data.cFileName[0] == '.' && find_data.cFileName[1] == '.' && find_data.cFileName[2] == 0); - - if (!nav_dir){ - u32 attribs = find_data.dwFileAttributes; - info->folder = (attribs & FILE_ATTRIBUTE_DIRECTORY) != 0; - info->filename = (char*)name; - - u16 *src = (u16*)find_data.cFileName; - u32 src_len = 0; - for (;src[src_len];++src_len); - - u8 *dst = name; - u32 max = remaining_size-1; - - b32 error = false; - u32 length = (u32)utf16_to_utf8_minimal_checking(dst, max, src, src_len, &error); - - if (length <= max && !error){ - name += length; - - info->filename_len = length; - *name++ = 0; - String_Const_u8 fname = SCu8(info->filename, length); - fname = string_mod_replace_character(fname, '\\', '/'); - ++info; - ++corrected_file_count; - } - } - more_files = FindNextFile(search, &find_data); - }while(more_files); - FindClose(search); - - file_list->count = corrected_file_count; - clear_list = false; - } - } - } - } - } - } - - if (clear_list){ - system_memory_free(file_list->block, 0); - file_list->block = 0; - file_list->block_size = 0; - file_list->infos = 0; - file_list->count = 0; - } -} - internal Sys_Get_Canonical_Sig(system_get_canonical){ - u32 result = 0; - - String_Const_char file_name = SCchar(filename, len); - char src_space[MAX_PATH + 32]; - if (len < sizeof(src_space) && - ((character_is_alpha(string_get_character(file_name, 0)) && string_get_character(file_name, 1) == ':') || - string_match(string_prefix(file_name, 2), string_litexpr("\\\\")))){ - memcpy(src_space, filename, len); - src_space[len] = 0; + String_Const_u8 result = {}; + Arena *scratch = &shared_vars.scratch; + Temp_Memory temp = begin_temp(scratch); + if ((character_is_alpha(string_get_character(name, 0)) && + string_get_character(name, 1) == ':') || + string_match(string_prefix(name, 2), string_u8_litexpr("\\\\"))){ - HANDLE file = CreateFile_utf8(&shared_vars.scratch, (u8*)src_space, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + u8 *c_name = push_array(scratch, u8, name.size + 1); + block_copy(c_name, name.str, name.size); + c_name[name.size] = 0; + HANDLE file = CreateFile_utf8(scratch, c_name, GENERIC_READ, 0, 0, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, 0); if (file != INVALID_HANDLE_VALUE){ - DWORD final_length = GetFinalPathNameByHandle_utf8(&shared_vars.scratch, file, (u8*)buffer, max, 0); - - if (final_length + 3 < max){ - if (buffer[final_length - 1] == 0){ - --final_length; - } - String_Const_u8 str_dir = SCu8(buffer, final_length); - String_Const_u8 adjusted_str_dir = win32_remove_unc_prefix_characters(str_dir); - buffer = (char*)adjusted_str_dir.str; - final_length = (i32)adjusted_str_dir.size; - buffer[final_length] = 0; - result = final_length; + DWORD capacity = GetFinalPathNameByHandle_utf8(scratch, file, 0, 0, 0); + u8 *buffer = push_array(arena, u8, capacity); + DWORD length = GetFinalPathNameByHandle_utf8(scratch, file, buffer, capacity, 0); + if (length > 0 && buffer[length - 1] == 0){ + length -= 1; } - + result = SCu8(buffer, length); + result = win32_remove_unc_prefix_characters(result); CloseHandle(file); } else{ - String_Const_u8 src_str = SCu8(filename, len); - String_Const_u8 path_str = string_remove_front_of_path(src_str); - String_Const_u8 front_str = string_front_of_path(src_str); + String_Const_u8 path = string_remove_front_of_path(name); + String_Const_u8 front = string_front_of_path(name); - memcpy(src_space, path_str.str, path_str.size); - src_space[path_str.size] = 0; + u8 *c_path = push_array(scratch, u8, path.size + 1); + block_copy(c_path, path.str, path.size); + c_path[path.size] = 0; - HANDLE dir = CreateFile_utf8(&shared_vars.scratch, (u8*)src_space, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, 0); + HANDLE dir = CreateFile_utf8(scratch, c_path, FILE_LIST_DIRECTORY, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, 0); if (dir != INVALID_HANDLE_VALUE){ - DWORD final_length = GetFinalPathNameByHandle_utf8(&shared_vars.scratch, dir, (u8*)buffer, max, 0); - - if (final_length + 3 < max){ - if (buffer[final_length-1] == 0){ - --final_length; - } - String_Const_u8 str_dir = SCu8(buffer, final_length); - String_Const_u8 adjusted_str_dir = win32_remove_unc_prefix_characters(str_dir); - buffer = (char*)adjusted_str_dir.str; - final_length = (i32)adjusted_str_dir.size; - buffer[final_length++] = '\\'; - memcpy(buffer + final_length, front_str.str, front_str.size); - final_length += (i32)(front_str.size); - buffer[final_length] = 0; - result = final_length; + DWORD capacity = GetFinalPathNameByHandle_utf8(scratch, dir, 0, 0, 0); + u8 *buffer = push_array(arena, u8, capacity + front.size + 1); + DWORD length = GetFinalPathNameByHandle_utf8(scratch, dir, buffer, capacity, 0); + if (length > 0 && buffer[length - 1] == 0){ + length -= 1; } - + buffer[length] = '\\'; + length += 1; + block_copy(buffer + length, front.str, front.size); + length += (DWORD)front.size; + result = SCu8(buffer, length); + result = win32_remove_unc_prefix_characters(result); CloseHandle(dir); } } } - + end_temp(temp); return(result); } @@ -327,17 +185,85 @@ win32_convert_file_attribute_flags(DWORD dwFileAttributes){ return(result); } +internal u64 +win32_u64_from_u32_u32(u32 hi, u32 lo){ + return( (((u64)hi) << 32) | ((u64)lo) ); +} + +internal u64 +win32_u64_from_filetime(FILETIME time){ + return(win32_u64_from_u32_u32(time.dwHighDateTime, time.dwLowDateTime)); +} + internal File_Attributes win32_file_attributes_from_HANDLE(HANDLE file){ BY_HANDLE_FILE_INFORMATION info = {}; GetFileInformationByHandle(file, &info); File_Attributes result = {}; - result.size = ((u64)info.nFileSizeHigh << 32LL) | ((u64)info.nFileSizeLow); - result.last_write_time = ((u64)info.ftLastWriteTime.dwHighDateTime << 32LL) | ((u64)info.ftLastWriteTime.dwLowDateTime); + result.size = win32_u64_from_u32_u32(info.nFileSizeHigh, info.nFileSizeLow); + result.last_write_time = win32_u64_from_filetime(info.ftLastWriteTime); result.flags = win32_convert_file_attribute_flags(info.dwFileAttributes); return(result); } +internal +Sys_Get_File_List_Sig(system_get_file_list){ + File_List result = {}; + Arena *scratch = &shared_vars.scratch; + Temp_Memory temp = begin_temp(scratch); + String_Const_u8 search_pattern = {}; + if (character_is_slash(string_get_character(directory, directory.size - 1))){ + search_pattern = push_u8_stringf(scratch, "%.*s*", string_expand(directory)); + } + else{ + search_pattern = push_u8_stringf(scratch, "%.*s\\*", string_expand(directory)); + } + + WIN32_FIND_DATA find_data = {}; + HANDLE search = FindFirstFile_utf8(&shared_vars.scratch, search_pattern.str, &find_data); + if (search != INVALID_HANDLE_VALUE){ + File_Info *first = 0; + File_Info *last = 0; + i32 count = 0; + + for (;;){ + String_Const_u16 file_name_utf16 = SCu16(find_data.cFileName); + if (!(string_match(file_name_utf16, string_u16_litexpr(L".")) || + string_match(file_name_utf16, string_u16_litexpr(L"..")))){ + String_Const_u8 file_name = string_u8_from_string_u16(arena, file_name_utf16, + StringFill_NullTerminate).string; + + File_Info *info = push_array(arena, File_Info, 1); + sll_queue_push(first, last, info); + count += 1; + + info->file_name = file_name; + info->attributes.size = win32_u64_from_u32_u32(find_data.nFileSizeHigh, + find_data.nFileSizeLow); + info->attributes.last_write_time = win32_u64_from_filetime(find_data.ftLastWriteTime); + info->attributes.flags = win32_convert_file_attribute_flags(find_data.dwFileAttributes); + } + if (!FindNextFile(search, &find_data)){ + break; + } + } + + result.infos = push_array(arena, File_Info*, count); + result.count = count; + + i32 counter = 0; + for (File_Info *node = first; + node != 0; + node = node->next){ + result.infos[counter] = node; + counter += 1; + } + } + + end_temp(temp); + return(result); +} + internal Sys_Quick_File_Attributes_Sig(system_quick_file_attributes){ WIN32_FILE_ATTRIBUTE_DATA info = {}; diff --git a/things_ive_broken.txt b/things_ive_broken.txt index 87eb4c27..d2e56875 100644 --- a/things_ive_broken.txt +++ b/things_ive_broken.txt @@ -47,4 +47,9 @@ set_global_face_by_name -> set_buffer_face_by_font_load_location (with id = 0) mark_enclosures -> draw_enclosures -all *marker_visuals* -> immediate mode rendering \ No newline at end of file +all *marker_visuals* -> immediate mode rendering + +get_file_list +free_file_list +File_Info +File_List