New file listing API
This commit is contained in:
parent
2b28efa3bf
commit
d4db77b3fb
|
@ -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.) */
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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));}
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
4
4ed.cpp
4
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){
|
||||
|
|
|
@ -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);
|
||||
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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
16
4ed_system.h
16
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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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_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("\\\\"))){
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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 = {};
|
||||
|
|
|
@ -48,3 +48,8 @@ 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
|
||||
|
||||
get_file_list
|
||||
free_file_list
|
||||
File_Info
|
||||
File_List
|
||||
|
|
Loading…
Reference in New Issue