From 82560167073275ede348e14c9300d70215157d44 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sun, 28 Feb 2016 15:30:51 -0500 Subject: [PATCH] a3.4.4 --- .gitignore | 1 + 4coder_buffer_types.h | 19 + 4coder_custom.cpp | 91 +- 4coder_custom.h | 44 +- 4coder_string.h | 25 +- 4ed.cpp | 2207 ++++++++++++++++------------- 4ed.h | 2 + 4ed_color_view.cpp | 2 +- 4ed_delay.cpp | 52 +- 4ed_exchange.cpp | 1 - 4ed_file_view.cpp | 99 +- 4ed_interactive_view.cpp | 8 +- 4ed_metagen.cpp | 55 +- 4ed_system.h | 15 +- buffer/4coder_buffer_abstract.cpp | 2 +- win32_4ed.cpp | 112 +- 16 files changed, 1528 insertions(+), 1207 deletions(-) diff --git a/.gitignore b/.gitignore index 28b4d0f0..29bd3f0b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ vc120.pdb +custom_casey.cpp diff --git a/4coder_buffer_types.h b/4coder_buffer_types.h index 1bfa8ba0..ace28eab 100644 --- a/4coder_buffer_types.h +++ b/4coder_buffer_types.h @@ -201,6 +201,25 @@ dynamic_to_bool(Dynamic *dynamic){ return result; } + +typedef struct File_Info{ + String filename; + int folder; +} File_Info; + +typedef struct File_List{ + // Ignore this, it's for internal stuff. + void *block; + + // The list of files and folders. + File_Info *infos; + int count; + + // Ignore this, it's for internal stuff. + int block_size; +} File_List; + + #endif // BOTTOM diff --git a/4coder_custom.cpp b/4coder_custom.cpp index 52339fa6..b999bdda 100644 --- a/4coder_custom.cpp +++ b/4coder_custom.cpp @@ -34,26 +34,6 @@ HOOK_SIG(my_start){ exec_command(app, cmdid_change_active_panel); } -char *get_extension(const char *filename, int len, int *extension_len){ - char *c = (char*)(filename + len - 1); - char *end = c; - while (*c != '.' && c > filename) --c; - *extension_len = (int)(end - c); - return c+1; -} - -bool str_match(const char *a, int len_a, const char *b, int len_b){ - bool result = 0; - if (len_a == len_b){ - char *end = (char*)(a + len_a); - while (a < end && *a == *b){ - ++a; ++b; - } - if (a == end) result = 1; - } - return result; -} - HOOK_SIG(my_file_settings){ Buffer_Summary buffer = app->get_active_buffer(app); @@ -64,16 +44,15 @@ HOOK_SIG(my_file_settings){ // -The name provided to get_buffer_by_name did not match any of the existing buffers if (buffer.exists){ int treat_as_code = 0; - + if (buffer.file_name && buffer.size < (16 << 20)){ - int extension_len; - char *extension = get_extension(buffer.file_name, buffer.file_name_len, &extension_len); - if (str_match(extension, extension_len, literal("cpp"))) treat_as_code = 1; - else if (str_match(extension, extension_len, literal("h"))) treat_as_code = 1; - else if (str_match(extension, extension_len, literal("c"))) treat_as_code = 1; - else if (str_match(extension, extension_len, literal("hpp"))) treat_as_code = 1; + String ext = file_extension(make_string(buffer.file_name, buffer.file_name_len)); + if (match(ext, make_lit_string("cpp"))) treat_as_code = 1; + else if (match(ext, make_lit_string("h"))) treat_as_code = 1; + else if (match(ext, make_lit_string("c"))) treat_as_code = 1; + else if (match(ext, make_lit_string("hpp"))) treat_as_code = 1; } - + push_parameter(app, par_lex_as_cpp_file, treat_as_code); push_parameter(app, par_wrap_lines, !treat_as_code); push_parameter(app, par_key_mapid, (treat_as_code)?((int)my_code_map):((int)mapid_file)); @@ -290,7 +269,7 @@ CUSTOM_COMMAND_SIG(switch_to_file_in_quotes){ app->buffer_read_range(app, &buffer, start, end, short_file_name); copy(&file_name, make_string(buffer.file_name, buffer.file_name_len)); - truncate_to_path_of_directory(&file_name); + remove_last_folder(&file_name); append(&file_name, make_string(short_file_name, size)); exec_command(app, cmdid_change_active_panel); @@ -467,8 +446,9 @@ CUSTOM_COMMAND_SIG(replace_in_range){ pos = range.min; app->buffer_seek_string(app, &buffer, pos, r.str, r.size, 1, &new_pos); - while (new_pos < range.end){ + while (new_pos + r.size < range.end){ app->buffer_replace_range(app, &buffer, new_pos, new_pos + r.size, w.str, w.size); + range = get_range(&view); pos = new_pos + w.size; app->buffer_seek_string(app, &buffer, pos, r.str, r.size, 1, &new_pos); } @@ -533,6 +513,26 @@ CUSTOM_COMMAND_SIG(query_replace){ app->view_set_cursor(app, &view, seek_pos(pos), 1); } +CUSTOM_COMMAND_SIG(open_all_cpp_and_h){ + String dir = push_directory(app); + File_List list = app->get_file_list(app, dir.str, dir.size); + for (int i = 0; i < list.count; ++i){ + File_Info *info = list.infos + i; + if (!info->folder){ + String extension = file_extension(info->filename); + if (match(extension, make_lit_string("cpp")) || + match(extension, make_lit_string("hpp")) || + match(extension, make_lit_string("c")) || + match(extension, make_lit_string("h"))){ + push_parameter(app, par_name, info->filename.str, info->filename.size); + push_parameter(app, par_do_in_background, 1); + exec_command(app, cmdid_interactive_open); + } + } + } + app->free_file_list(app, list); +} + CUSTOM_COMMAND_SIG(open_in_other){ exec_command(app, cmdid_change_active_panel); exec_command(app, cmdid_interactive_open); @@ -570,7 +570,7 @@ CUSTOM_COMMAND_SIG(build_at_launch_location){ push_parameter(app, par_name, literal("*compilation*")); push_parameter(app, par_cli_path, literal(".")); push_parameter(app, par_cli_command, literal("build")); - exec_command(app, cmdid_build); + exec_command(app, cmdid_command_line); } CUSTOM_COMMAND_SIG(build_search){ @@ -602,18 +602,26 @@ CUSTOM_COMMAND_SIG(build_search){ // Step 3: If the batch file did not exist try to move to the parent directory using // app->directory_cd. The cd function can also be used to navigate to subdirectories. // It returns true if it can actually move in the specified direction, and false otherwise. + // This doesn't actually change the hot directory of 4coder, it's only effect is to + // modify the string you passed in to reflect the change in directory. int keep_going = 1; + int old_size; String dir = push_directory(app); while (keep_going){ - if (app->directory_has_file(app, dir, "build.bat")){ + old_size = dir.size; + append(&dir, "build.bat"); + + if (app->file_exists(app, dir.str, dir.size)){ + dir.size = old_size; + push_parameter(app, par_cli_overlap_with_conflict, 0); push_parameter(app, par_name, literal("*compilation*")); push_parameter(app, par_cli_path, dir.str, dir.size); if (append(&dir, "build")){ push_parameter(app, par_cli_command, dir.str, dir.size); - exec_command(app, cmdid_build); + exec_command(app, cmdid_command_line); } else{ app->clear_parameters(app); @@ -621,8 +629,9 @@ CUSTOM_COMMAND_SIG(build_search){ return; } + dir.size = old_size; - if (app->directory_cd(app, &dir, "..") == 0){ + if (app->directory_cd(app, dir.str, &dir.size, dir.memory_size, literal("..")) == 0){ keep_going = 0; } } @@ -638,7 +647,7 @@ CUSTOM_COMMAND_SIG(write_and_auto_tab){ extern "C" GET_BINDING_DATA(get_bindings){ Bind_Helper context_actual = begin_bind_helper(data, size); Bind_Helper *context = &context_actual; - + // NOTE(allen|a3.1): Right now hooks have no loyalties to maps, all hooks are // global and once set they always apply, regardless of what map is active. set_hook(context, hook_start, my_start); @@ -658,11 +667,14 @@ extern "C" GET_BINDING_DATA(get_bindings){ bind(context, 'x', MDFR_ALT, cmdid_open_menu); bind(context, 'o', MDFR_ALT, open_in_other); + bind(context, 'm', MDFR_ALT, build_search); + bind(context, 'a', MDFR_ALT, open_all_cpp_and_h); + // NOTE(allen): These callbacks may not actually be useful to you, but // go look at them and see what they do. bind(context, 'M', MDFR_ALT | MDFR_CTRL, open_my_files); bind(context, 'M', MDFR_ALT, build_at_launch_location); - bind(context, 'm', MDFR_ALT, build_search); + end_map(context); @@ -693,9 +705,6 @@ extern "C" GET_BINDING_DATA(get_bindings){ bind(context, '\t', MDFR_NONE, cmdid_word_complete); bind(context, '\t', MDFR_CTRL, cmdid_auto_tab_range); bind(context, '\t', MDFR_SHIFT, cmdid_auto_tab_line_at_cursor); - - bind(context, '\n', MDFR_SHIFT, write_and_auto_tab); - bind(context, ' ', MDFR_SHIFT, cmdid_write_character); bind(context, '=', MDFR_CTRL, write_increment); bind(context, '-', MDFR_CTRL, write_decrement); @@ -773,7 +782,11 @@ extern "C" GET_BINDING_DATA(get_bindings){ bind(context, ',', MDFR_ALT, switch_to_compilation); + bind(context, '\n', MDFR_SHIFT, write_and_auto_tab); + bind(context, ' ', MDFR_SHIFT, cmdid_write_character); + end_map(context); + end_bind_helper(context); return context->write_total; diff --git a/4coder_custom.h b/4coder_custom.h index 68283a13..27dc7d90 100644 --- a/4coder_custom.h +++ b/4coder_custom.h @@ -22,10 +22,7 @@ enum Command_ID{ cmdid_seek_alphanumeric_right, cmdid_seek_alphanumeric_or_camel_left, cmdid_seek_alphanumeric_or_camel_right, - //cmdid_search, - //cmdid_reverse_search, cmdid_word_complete, - //cmdid_goto_line, cmdid_set_mark, cmdid_copy, cmdid_cut, @@ -75,7 +72,7 @@ enum Command_ID{ cmdid_cursor_mark_swap, cmdid_open_menu, cmdid_set_settings, - cmdid_build, + cmdid_command_line, // cmdid_count }; @@ -84,6 +81,8 @@ enum Param_ID{ par_range_start, par_range_end, par_name, + par_buffer_id, + par_do_in_background, par_lex_as_cpp_file, par_wrap_lines, par_key_mapid, @@ -156,7 +155,6 @@ struct Query_Bar{ }; #define GET_BINDING_DATA(name) int name(void *data, int size) -#define SET_EXTRA_FONT_SIG(name) void name(Extra_Font *font_out) #define CUSTOM_COMMAND_SIG(name) void name(struct Application_Links *app) #define HOOK_SIG(name) void name(struct Application_Links *app) @@ -175,9 +173,11 @@ struct Application_Links; #define CLEAR_PARAMETERS_SIG(name) void name(Application_Links *context) // File system navigation -#define DIRECTORY_GET_HOT_SIG(name) int name(Application_Links *context, char *buffer, int max) -#define DIRECTORY_HAS_FILE_SIG(name) int name(Application_Links *context, String dir, char *filename) -#define DIRECTORY_CD_SIG(name) int name(Application_Links *context, String *dir, char *rel_path) +#define DIRECTORY_GET_HOT_SIG(name) int name(Application_Links *context, char *out, int capacity) +#define FILE_EXISTS_SIG(name) int name(Application_Links *context, char *filename, int len) +#define DIRECTORY_CD_SIG(name) int name(Application_Links *context, char *dir, int *len, int capacity, char *rel_path, int rel_len) +#define GET_FILE_LIST_SIG(name) File_List name(Application_Links *context, char *dir, int len) +#define FREE_FILE_LIST_SIG(name) void name(Application_Links *context, File_List list) // Direct buffer manipulation #define GET_BUFFER_MAX_INDEX_SIG(name) int name(Application_Links *context) @@ -190,7 +190,6 @@ struct Application_Links; #define BUFFER_SEEK_STRING_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, int start, char *str, int len, int seek_forward, int *out) #define BUFFER_READ_RANGE_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, int start, int end, char *out) #define BUFFER_REPLACE_RANGE_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, int start, int end, char *str, int len) -#define BUFFER_SAVE_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, char *filename, int len) // File view manipulation #define GET_VIEW_MAX_INDEX_SIG(name) int name(Application_Links *context) @@ -216,9 +215,6 @@ struct Application_Links; #define GET_USER_INPUT_SIG(name) User_Input name(Application_Links *context, unsigned int get_type, unsigned int abort_type) // Queries -#define QueryEffectImmediate 0x0 -#define QueryEffectSmooth 0x1 - #define START_QUERY_BAR_SIG(name) int name(Application_Links *context, Query_Bar *bar, unsigned int flags) #define END_QUERY_BAR_SIG(name) void name(Application_Links *context, Query_Bar *bar, unsigned int flags) @@ -230,9 +226,11 @@ extern "C"{ typedef CLEAR_PARAMETERS_SIG(Clear_Parameters_Function); // File system navigation - typedef DIRECTORY_GET_HOT_SIG(Directory_Get_Hot); - typedef DIRECTORY_HAS_FILE_SIG(Directory_Has_File); - typedef DIRECTORY_CD_SIG(Directory_CD); + typedef DIRECTORY_GET_HOT_SIG(Directory_Get_Hot_Function); + typedef FILE_EXISTS_SIG(File_Exists_Function); + typedef DIRECTORY_CD_SIG(Directory_CD_Function); + typedef GET_FILE_LIST_SIG(Get_File_List_Function); + typedef FREE_FILE_LIST_SIG(Free_File_List_Function); // Buffer manipulation typedef GET_BUFFER_MAX_INDEX_SIG(Get_Buffer_Max_Index_Function); @@ -245,7 +243,6 @@ extern "C"{ typedef BUFFER_SEEK_STRING_SIG(Buffer_Seek_String_Function); typedef BUFFER_READ_RANGE_SIG(Buffer_Read_Range_Function); typedef BUFFER_REPLACE_RANGE_SIG(Buffer_Replace_Range_Function); - typedef BUFFER_SAVE_SIG(Buffer_Save_Function); // View manipulation typedef GET_VIEW_MAX_INDEX_SIG(Get_View_Max_Index_Function); @@ -267,8 +264,9 @@ extern "C"{ } struct Application_Links{ - // Application data ptr + // User data void *data; + int size; // Command exectuion Exec_Command_Function *exec_command_keep_stack; @@ -277,9 +275,11 @@ struct Application_Links{ Clear_Parameters_Function *clear_parameters; // File system navigation - Directory_Get_Hot *directory_get_hot; - Directory_Has_File *directory_has_file; - Directory_CD *directory_cd; + Directory_Get_Hot_Function *directory_get_hot; + File_Exists_Function *file_exists; + Directory_CD_Function *directory_cd; + Get_File_List_Function *get_file_list; + Free_File_List_Function *free_file_list; // Buffer manipulation Get_Buffer_Max_Index_Function *get_buffer_max_index; @@ -292,7 +292,6 @@ struct Application_Links{ Buffer_Seek_String_Function *buffer_seek_string; Buffer_Read_Range_Function *buffer_read_range; Buffer_Replace_Range_Function *buffer_replace_range; - Buffer_Save_Function *buffer_save; // View manipulation Get_View_Max_Index_Function *get_view_max_index; @@ -311,6 +310,9 @@ struct Application_Links{ // Queries Start_Query_Bar_Function *start_query_bar; End_Query_Bar_Function *end_query_bar; + + // Internal + void *cmd_context; }; struct Custom_API{ diff --git a/4coder_string.h b/4coder_string.h index f2724562..3fae8d3d 100644 --- a/4coder_string.h +++ b/4coder_string.h @@ -175,12 +175,13 @@ FCPP_LINK int reverse_seek_slash(String str); FCPP_LINK int reverse_seek_slash(String str, int start_pos); inline bool get_front_of_directory(String *dest, String dir) { return append_checked(dest, substr(dir, reverse_seek_slash(dir) + 1)); } inline bool get_path_of_directory(String *dest, String dir) { return append_checked(dest, substr(dir, 0, reverse_seek_slash(dir) + 1)); } -inline void truncate_to_path_of_directory(String *dir) { dir->size = reverse_seek_slash(*dir) + 1; } FCPP_LINK bool set_last_folder(String *dir, char *folder_name, char slash); FCPP_LINK bool set_last_folder(String *dir, String folder_name, char slash); FCPP_LINK String file_extension(String str); FCPP_LINK String file_extension_slowly(char *str); +FCPP_LINK char * file_extension_c(String str); FCPP_LINK bool remove_last_folder(String *str); +FCPP_LINK void replace_char(String str, char replace, char with); inline String make_string(char *str, int size, int mem_size){ String result; @@ -1043,6 +1044,16 @@ file_extension_slowly(char *str){ return make_string(str+i, s-i); } +FCPP_LINK char* +file_extension_c(String str){ + int i; + for (i = str.size - 1; i >= 0; --i){ + if (str.str[i] == '.') break; + } + ++i; + return str.str+i; +} + FCPP_LINK bool remove_last_folder(String *str){ bool result = 0; @@ -1054,11 +1065,21 @@ remove_last_folder(String *str){ return(result); } +FCPP_LINK void +replace_char(String str, char replace, char with){ + char *s = str.str; + int i; + + for (i = 0; i < str.size; ++i, ++s){ + if (*s == replace) *s = with; + } +} + // NOTE(allen): experimental section, things below here are // not promoted to public API level yet. #ifndef ArrayCount -#define ArrayCount(a) ((sizeof(a))/sizeof(a)) +#define ArrayCount(a) ((sizeof(a))/sizeof(*a)) #endif struct Absolutes{ diff --git a/4ed.cpp b/4ed.cpp index 4c651814..95c40043 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -33,9 +33,16 @@ struct CLI_List{ i32 count, max; }; +#define SysAppCreateView 0x1 +#define SysAppCreateNewBuffer 0x2 + struct Sys_App_Binding{ i32 sys_id; i32 app_id; + + u32 success; + u32 fail; + Panel *panel; }; struct Complete_State{ @@ -60,10 +67,10 @@ struct Command_Data{ Exchange *exchange; System_Functions *system; Coroutine *current_coroutine; - + i32 screen_width, screen_height; Key_Event_Data key; - + Partition part; }; @@ -71,7 +78,7 @@ struct App_Vars{ Mem_Options mem; App_Settings settings; - + Command_Map map_top; Command_Map map_file; Command_Map map_ui; @@ -82,22 +89,22 @@ struct App_Vars{ i32 *map_id_table; i32 user_map_count; Command_Binding prev_command; - + Coroutine *command_coroutine; u32 command_coroutine_flags[2]; - + Sys_App_Binding *sys_app_bindings; i32 sys_app_count, sys_app_max; - + Custom_Command_Function *hooks[hook_type_count]; - + Font_Set *font_set; - + Style style; Style_Library styles; u32 *palette; i32 palette_size; - + Editing_Layout layout; Live_Views live_set; Working_Set working_set; @@ -106,19 +113,19 @@ struct App_Vars{ Hot_Directory hot_directory; CLI_List cli_processes; - - Delay delay; + + Delay delay1, delay2; String mini_str; u8 mini_buffer[512]; - + App_State state; App_State_Resizing resizing; Complete_State complete_state; Panel *prev_mouse_panel; - + Command_Data command_data; - + Custom_API config_api; }; @@ -168,6 +175,8 @@ globalvar Application_Links app_links; #define USE_MEM(n) Mem_Options *n = command->mem #define USE_PANEL(n) Panel *n = command->panel #define USE_VIEW(n) View *n = command->view +#define USE_FILE_VIEW(n) File_View *n = view_to_file_view(command->view) +#define USE_FILE(n,v) Editing_File *n = 0; if (v) { (n) = (v)->file; } #define USE_WORKING_SET(n) Working_Set *n = command->working_set #define USE_LAYOUT(n) Editing_Layout *n = command->layout #define USE_LIVE_SET(n) Live_Views *live_set = command->live_set @@ -240,7 +249,7 @@ COMMAND_DECL(write_character){ REQ_FILE(file, view); USE_LAYOUT(layout); USE_MEM(mem); - + char character; i32 pos, next_cursor_pos; @@ -258,7 +267,7 @@ COMMAND_DECL(seek_whitespace_right){ ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); - + i32 pos = buffer_seek_whitespace_right(&file->state.buffer, view->cursor.pos); view_cursor_move(view, pos); } @@ -267,7 +276,7 @@ COMMAND_DECL(seek_whitespace_left){ ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); - + i32 pos = buffer_seek_whitespace_left(&file->state.buffer, view->cursor.pos); view_cursor_move(view, pos); } @@ -276,7 +285,7 @@ COMMAND_DECL(seek_whitespace_up){ ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); - + i32 pos = buffer_seek_whitespace_up(&file->state.buffer, view->cursor.pos); view_cursor_move(view, pos); } @@ -285,7 +294,7 @@ COMMAND_DECL(seek_whitespace_down){ ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); - + i32 pos = buffer_seek_whitespace_down(&file->state.buffer, view->cursor.pos); view_cursor_move(view, pos); } @@ -296,12 +305,12 @@ seek_token_left(Cpp_Token_Stack *tokens, i32 pos){ if (get.token_index == -1){ get.token_index = 0; } - + Cpp_Token *token = tokens->tokens + get.token_index; if (token->start == pos && get.token_index > 0){ --token; } - + return token->start; } @@ -314,7 +323,7 @@ seek_token_right(Cpp_Token_Stack *tokens, i32 pos){ if (get.token_index >= tokens->count){ get.token_index = tokens->count-1; } - + Cpp_Token *token = tokens->tokens + get.token_index; return token->start + token->size; } @@ -323,7 +332,7 @@ COMMAND_DECL(seek_token_left){ ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); - + if (file->state.tokens_complete){ i32 pos = seek_token_left(&file->state.token_stack, view->cursor.pos); view_cursor_move(view, pos); @@ -334,7 +343,7 @@ COMMAND_DECL(seek_token_right){ ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); - + if (file->state.tokens_complete){ i32 pos = seek_token_right(&file->state.token_stack, view->cursor.pos); view_cursor_move(view, pos); @@ -345,7 +354,7 @@ COMMAND_DECL(seek_white_or_token_right){ ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); - + i32 token_pos, white_pos; if (file->state.tokens_complete){ token_pos = seek_token_right(&file->state.token_stack, view->cursor.pos); @@ -361,7 +370,7 @@ COMMAND_DECL(seek_white_or_token_left){ ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); - + i32 token_pos, white_pos; if (file->state.tokens_complete){ token_pos = seek_token_left(&file->state.token_stack, view->cursor.pos); @@ -377,7 +386,7 @@ COMMAND_DECL(seek_alphanumeric_right){ ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); - + i32 pos = buffer_seek_alphanumeric_right(&file->state.buffer, view->cursor.pos); view_cursor_move(view, pos); } @@ -386,7 +395,7 @@ COMMAND_DECL(seek_alphanumeric_left){ ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); - + i32 pos = buffer_seek_alphanumeric_left(&file->state.buffer, view->cursor.pos); view_cursor_move(view, pos); } @@ -404,7 +413,7 @@ COMMAND_DECL(seek_alphanumeric_or_camel_left){ ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); - + i32 pos = buffer_seek_alphanumeric_or_camel_left(&file->state.buffer, view->cursor.pos); view_cursor_move(view, pos); } @@ -417,39 +426,40 @@ COMMAND_DECL(word_complete){ USE_MEM(mem); USE_VARS(vars); USE_WORKING_SET(working_set); - + Partition *part = &mem->part; General_Memory *general = &mem->general; Complete_State *complete_state = &vars->complete_state; Search_Range *ranges; Search_Match match; - + Temp_Memory temp; - + Buffer_Type *buffer; Buffer_Backify_Type loop; char *data; i32 end; i32 size_of_buffer; - + i32 cursor_pos, word_start, word_end; char c; - + char *spare; i32 size; - + i32 buffer_count, i, j; Editing_File *file_ptr; - + i32 match_size; b32 do_init = 0; - + buffer = &file->state.buffer; size_of_buffer = buffer_size(buffer); - if (vars->prev_command.function != command_word_complete){ + if (view->mode.rewrite != 2){ do_init = 1; } + view->next_mode.rewrite = 2; if (complete_state->initialized == 0){ do_init = 1; @@ -477,30 +487,30 @@ COMMAND_DECL(word_complete){ } } double_break:; - + size = word_end - word_start; - + if (size == 0){ complete_state->initialized = 0; return; } - + complete_state->initialized = 1; search_iter_init(general, &complete_state->iter, size); buffer_stringify(buffer, word_start, word_end, complete_state->iter.word.str); complete_state->iter.word.size = size; - + buffer_count = working_set->file_index_count; search_set_init(general, &complete_state->set, buffer_count + 1); ranges = complete_state->set.ranges; ranges[0].buffer = buffer; ranges[0].start = 0; ranges[0].size = word_start; - + ranges[1].buffer = buffer; ranges[1].start = word_end; ranges[1].size = size_of_buffer - word_end; - + file_ptr = working_set->files; for (i = 0, j = 2; i < buffer_count; ++i, ++file_ptr){ if (file_ptr != file && !file_ptr->state.is_dummy){ @@ -511,11 +521,11 @@ COMMAND_DECL(word_complete){ } } complete_state->set.count = j; - + search_hits_init(general, &complete_state->hits, &complete_state->str, 100, Kbytes(4)); search_hit_add(general, &complete_state->hits, &complete_state->str, complete_state->iter.word.str, complete_state->iter.word.size); - + complete_state->word_start = word_start; complete_state->word_end = word_end; } @@ -568,7 +578,7 @@ COMMAND_DECL(set_mark){ ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); - + view->mark = (i32)view->cursor.pos; } @@ -578,11 +588,11 @@ COMMAND_DECL(copy){ REQ_FILE(file, view); USE_WORKING_SET(working_set); USE_MEM(mem); - + // TODO(allen): deduplicate int r_start = 0, r_end = 0; int start_set = 0, end_set = 0; - + Command_Parameter *end = param_stack_end(&command->part); Command_Parameter *param = param_stack_first(&command->part, end); for (; param < end; param = param_next(param, end)){ @@ -592,7 +602,7 @@ COMMAND_DECL(copy){ start_set = 1; r_start = dynamic_to_int(¶m->param.value); break; - + case par_range_end: end_set = 1; r_end = dynamic_to_int(¶m->param.value); @@ -615,11 +625,11 @@ COMMAND_DECL(cut){ USE_WORKING_SET(working_set); USE_LAYOUT(layout); USE_MEM(mem); - + // TODO(allen): deduplicate int r_start = 0, r_end = 0; int start_set = 0, end_set = 0; - + Command_Parameter *end = param_stack_end(&command->part); Command_Parameter *param = param_stack_first(&command->part, end); for (; param < end; param = param_next(param, end)){ @@ -629,7 +639,7 @@ COMMAND_DECL(cut){ start_set = 1; r_start = dynamic_to_int(¶m->param.value); break; - + case par_range_end: end_set = 1; r_end = dynamic_to_int(¶m->param.value); @@ -645,7 +655,7 @@ COMMAND_DECL(cut){ clipboard_copy(system, &mem->general, working_set, range, file); view_replace_range(system, mem, view, layout, range.start, range.end, 0, 0, next_cursor_pos); - + view->mark = range.start; view_cursor_move(view, next_cursor_pos); } @@ -658,34 +668,34 @@ COMMAND_DECL(paste){ USE_WORKING_SET(working_set); USE_LAYOUT(layout); USE_MEM(mem); - + Panel *current_panel; String *src; File_View *current_view; i32 pos_left, next_cursor_pos; i32 panel_count; i32 i; - + if (working_set->clipboard_size > 0){ view->next_mode.rewrite = 1; - + src = working_set_clipboard_head(working_set); pos_left = view->cursor.pos; next_cursor_pos = pos_left+src->size; view_replace_range(system, mem, view, layout, pos_left, pos_left, src->str, src->size, next_cursor_pos); - + view_cursor_move(view, next_cursor_pos); view->mark = pos_left; - + current_panel = layout->panels; panel_count = layout->panel_count; for (i = 0; i < panel_count; ++i, ++current_panel){ current_view = view_to_file_view(current_panel->view); - + if (current_view && current_view->file == file){ view_post_paste_effect(current_view, 20, pos_left, src->size, - current_view->style->main.paste_color); + current_view->style->main.paste_color); } } } @@ -698,30 +708,30 @@ COMMAND_DECL(paste_next){ USE_WORKING_SET(working_set); USE_LAYOUT(layout); USE_MEM(mem); - - if (working_set->clipboard_size > 0 && view->mode.rewrite){ + + if (working_set->clipboard_size > 0 && view->mode.rewrite == 1){ view->next_mode.rewrite = 1; - + Range range = make_range(view->mark, view->cursor.pos); String *src = working_set_clipboard_roll_down(working_set); i32 next_cursor_pos = range.start+src->size; view_replace_range(system, - mem, view, layout, range.start, range.end, - src->str, src->size, next_cursor_pos); - + mem, view, layout, range.start, range.end, + src->str, src->size, next_cursor_pos); + view_cursor_move(view, next_cursor_pos); view->mark = range.start; - + Editing_Layout *layout = command->layout; Panel *panels = layout->panels; i32 panel_count = layout->panel_count; for (i32 i = 0; i < panel_count; ++i){ Panel *current_panel = panels + i; File_View *current_view = view_to_file_view(current_panel->view); - + if (current_view && current_view->file == file){ view_post_paste_effect(current_view, 20, range.start, src->size, - current_view->style->main.paste_color); + current_view->style->main.paste_color); } } } @@ -736,12 +746,12 @@ COMMAND_DECL(delete_range){ REQ_FILE(file, view); USE_LAYOUT(layout); USE_MEM(mem); - + Range range = make_range(view->cursor.pos, view->mark); if (range.start < range.end){ i32 next_cursor_pos = range.start; view_replace_range(system, mem, view, layout, range.start, range.end, - 0, 0, next_cursor_pos); + 0, 0, next_cursor_pos); view_cursor_move(view, next_cursor_pos); view->mark = range.start; } @@ -751,7 +761,7 @@ COMMAND_DECL(timeline_scrub){ ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE_HISTORY(file, view); - + view_set_widget(view, FWIDG_TIMELINES); view->widget.timeline.undo_line = 1; view->widget.timeline.history_line = 1; @@ -763,7 +773,7 @@ COMMAND_DECL(undo){ REQ_FILE_HISTORY(file, view); USE_LAYOUT(layout); USE_MEM(mem); - + view_undo(system, mem, layout, view); } @@ -773,7 +783,7 @@ COMMAND_DECL(redo){ REQ_FILE_HISTORY(file, view); USE_LAYOUT(layout); USE_MEM(mem); - + view_redo(system, mem, layout, view); } @@ -783,7 +793,7 @@ COMMAND_DECL(history_backward){ REQ_FILE_HISTORY(file, view); USE_LAYOUT(layout); USE_MEM(mem); - + view_history_step(system, mem, layout, view, hist_backward); } @@ -793,7 +803,7 @@ COMMAND_DECL(history_forward){ REQ_FILE_HISTORY(file, view); USE_LAYOUT(layout); USE_MEM(mem); - + view_history_step(system, mem, layout, view, hist_forward); } @@ -803,7 +813,7 @@ COMMAND_DECL(save_history){ REQ_FILE_VIEW(view); REQ_FILE(file, view); USE_MEM(mem); - + file_dump_history(system, mem, file, "history_data.hst"); } #endif @@ -819,31 +829,34 @@ COMMAND_DECL(interactive_new){ USE_DELAY(delay); USE_EXCHANGE(exchange); USE_FONT_SET(font_set); - + View *new_view = live_set_alloc_view(live_set, mem); view_replace_minor(system, exchange, new_view, panel, live_set); - + new_view->map = &vars->map_ui; Interactive_View *int_view = interactive_view_init(system, new_view, &vars->hot_directory, - style, working_set, - font_set, delay); + style, working_set, + font_set, delay); int_view->interaction = INTV_SYS_FILE_LIST; int_view->action = INTV_NEW; copy(&int_view->query, "New: "); } -internal void +internal Sys_App_Binding* app_push_file_binding(App_Vars *vars, int sys_id, int app_id){ - Sys_App_Binding binding; + Sys_App_Binding *binding; Assert(vars->sys_app_count < vars->sys_app_max); - binding.sys_id = sys_id; - binding.app_id = app_id; - vars->sys_app_bindings[vars->sys_app_count++] = binding; + binding = vars->sys_app_bindings + vars->sys_app_count++; + binding->sys_id = sys_id; + binding->app_id = app_id; + return(binding); } struct App_Open_File_Result{ Editing_File *file; + i32 sys_id; + i32 file_index; b32 is_new; }; @@ -852,68 +865,29 @@ app_open_file_background(App_Vars *vars, Exchange *exchange, Working_Set *workin Get_File_Result file; i32 file_id; App_Open_File_Result result = {}; - + result.file = working_set_contains(working_set, filename); if (result.file == 0){ + result.is_new = 1; file = working_set_get_available_file(working_set); if (file.file){ + result.file = file.file; file_id = exchange_request_file(exchange, filename.str, filename.size); if (file_id){ - result.is_new = 1; - result.file = file.file; file_init_strings(result.file); file_set_name(working_set, result.file, filename.str); file_set_to_loading(result.file); table_add(&working_set->table, result.file->name.source_path, file.index); - app_push_file_binding(vars, file_id, file.index); + result.sys_id = file_id; + result.file_index = file.index; } else{ file_get_dummy(file.file); } } } - - return(result); -} -internal File_View* -app_open_file(System_Functions *system, App_Vars *vars, Exchange *exchange, - Live_Views *live_set, Working_Set *working_set, Panel *panel, - Command_Data *command_data, String filename){ - App_Open_File_Result file; - Mem_Options *mem = &vars->mem; - File_View *result = 0; - - file = app_open_file_background(vars, exchange, working_set, filename); - - if (file.file){ - Style *style = command_data->style; - - View *new_view = live_set_alloc_view(live_set, mem); - view_replace_major(system, exchange, new_view, panel, live_set); - - File_View *file_view = file_view_init(new_view, &vars->layout); - result = file_view; - - View *old_view = command_data->view; - command_data->view = new_view; - - Partition old_part = command_data->part; - Temp_Memory temp = begin_temp_memory(&mem->part); - command_data->part = partition_sub_part(&mem->part, Kbytes(16)); - - view_set_file(system, file_view, file.file, vars->font_set, - style, vars->hooks[hook_open_file], command_data, - &app_links); - - command_data->part = old_part; - end_temp_memory(temp); - command_data->view = old_view; - - new_view->map = app_get_map(vars, file.file->settings.base_map_id); - } - return(result); } @@ -928,42 +902,81 @@ COMMAND_DECL(interactive_open){ USE_DELAY(delay); USE_EXCHANGE(exchange); USE_FONT_SET(font_set); - + char *filename = 0; int filename_len = 0; - + int do_in_background = 0; + Command_Parameter *end = param_stack_end(&command->part); Command_Parameter *param = param_stack_first(&command->part, end); for (; param < end; param = param_next(param, end)){ - if (param->param.param.type == dynamic_type_int && - param->param.param.int_value == par_name && - param->param.value.type == dynamic_type_string){ - filename = param->param.value.str_value; - filename_len = param->param.value.str_len; - break; + if (param->param.param.type == dynamic_type_int){ + if (param->param.param.int_value == par_name && + param->param.value.type == dynamic_type_string){ + filename = param->param.value.str_value; + filename_len = param->param.value.str_len; + } + else if (param->param.param.int_value == par_do_in_background){ + do_in_background = dynamic_to_int(¶m->param.value); + } } } if (filename){ String string = make_string(filename, filename_len); - app_open_file(system, vars, exchange, - live_set, working_set, panel, - command, string); + if (do_in_background){ + delayed_open_background(delay, string); + } + else{ + delayed_open(delay, string, panel); + } } else{ View *new_view = live_set_alloc_view(live_set, mem); view_replace_minor(system, exchange, new_view, panel, live_set); - + new_view->map = &vars->map_ui; Interactive_View *int_view = interactive_view_init(system, new_view, &vars->hot_directory, - style, working_set, font_set, delay); + style, working_set, font_set, delay); int_view->interaction = INTV_SYS_FILE_LIST; int_view->action = INTV_OPEN; copy(&int_view->query, "Open: "); } } +internal void +view_file_in_panel(Command_Data *cmd, Panel *panel, Editing_File *file){ + Live_Views *live_set = cmd->live_set; + Mem_Options *mem = cmd->mem; + Exchange *exchange = cmd->exchange; + System_Functions *system = cmd->system; + Editing_Layout *layout = cmd->layout; + App_Vars *vars = cmd->vars; + Style *style = cmd->style; + + View *new_view = live_set_alloc_view(live_set, mem); + view_replace_major(system, exchange, new_view, panel, live_set); + + File_View *file_view = file_view_init(new_view, layout); + + View *old_view = cmd->view; + cmd->view = new_view; + + Partition old_part = cmd->part; + Temp_Memory temp = begin_temp_memory(&mem->part); + cmd->part = partition_sub_part(&mem->part, Kbytes(16)); + + view_set_file(system, file_view, file, vars->font_set, + style, vars->hooks[hook_open_file], cmd, &app_links); + + cmd->part = old_part; + end_temp_memory(temp); + cmd->view = old_view; + + new_view->map = app_get_map(vars, file->settings.base_map_id); +} + // TODO(allen): Improvements to reopen // - Preserve existing token stack // - Keep current version open and do some sort of diff to keep @@ -976,7 +989,7 @@ COMMAND_DECL(reopen){ USE_WORKING_SET(working_set); USE_VARS(vars); USE_STYLE(style); - + i32 file_id = exchange_request_file(exchange, expand_str(file->name.source_path)); i32 index = 0; if (file_id){ @@ -985,7 +998,7 @@ COMMAND_DECL(reopen){ app_push_file_binding(vars, file_id, index); view_set_file(system, view, file, vars->font_set, style, - vars->hooks[hook_open_file], command, &app_links); + vars->hooks[hook_open_file], command, &app_links); } else{ // TODO(allen): feedback message @@ -994,12 +1007,53 @@ COMMAND_DECL(reopen){ COMMAND_DECL(save){ ProfileMomentFunction(); - REQ_FILE_VIEW(view); - REQ_FILE(file, view); + USE_FILE_VIEW(view); + USE_FILE(file, view); USE_DELAY(delay); - USE_PANEL(panel); + USE_WORKING_SET(working_set); + + char *filename = 0; + int filename_len = 0; + int buffer_id = -1; + + Command_Parameter *end = param_stack_end(&command->part); + Command_Parameter *param = param_stack_first(&command->part, end); + for (; param < end; param = param_next(param, end)){ + int v = dynamic_to_int(¶m->param.param); + if (v == par_name && param->param.value.type == dynamic_type_string){ + filename = param->param.value.str_value; + filename_len = param->param.value.str_len; + } + else if (v == par_buffer_id && param->param.value.type == dynamic_type_int){ + buffer_id = dynamic_to_int(¶m->param.value); + } + } - delayed_save(delay, file->name.source_path, panel); + String name = {}; + if (filename){ + name = make_string(filename, filename_len); + } + else if (file){ + name = file->name.source_path; + } + + if (name.size != 0){ + if (buffer_id == -1){ + if (file){ + delayed_save(delay, name, file); + } + } + else{ + file = working_set->files + buffer_id; + + if (!file->state.is_dummy && file_is_ready(file)){ + delayed_save(delay, name, file); + } + else{ + delayed_save(delay, name); + } + } + } } COMMAND_DECL(interactive_save_as){ @@ -1013,14 +1067,14 @@ COMMAND_DECL(interactive_save_as){ USE_DELAY(delay); USE_EXCHANGE(exchange); USE_FONT_SET(font_set); - + View *new_view = live_set_alloc_view(live_set, mem); view_replace_minor(system, exchange, new_view, panel, live_set); - + new_view->map = &vars->map_ui; Interactive_View *int_view = interactive_view_init(system, new_view, &vars->hot_directory, style, - working_set, font_set, delay); + working_set, font_set, delay); int_view->interaction = INTV_SYS_FILE_LIST; int_view->action = INTV_SAVE_AS; copy(&int_view->query, "Save As: "); @@ -1048,14 +1102,14 @@ COMMAND_DECL(interactive_switch_buffer){ USE_DELAY(delay); USE_EXCHANGE(exchange); USE_FONT_SET(font_set); - + View *new_view = live_set_alloc_view(live_set, mem); view_replace_minor(system, exchange, new_view, panel, live_set); - + new_view->map = &vars->map_ui; Interactive_View *int_view = interactive_view_init(system, new_view, &vars->hot_directory, style, - working_set, font_set, delay); + working_set, font_set, delay); int_view->interaction = INTV_LIVE_FILE_LIST; int_view->action = INTV_SWITCH; copy(&int_view->query, "Switch File: "); @@ -1072,14 +1126,14 @@ COMMAND_DECL(interactive_kill_buffer){ USE_DELAY(delay); USE_EXCHANGE(exchange); USE_FONT_SET(font_set); - + View *new_view = live_set_alloc_view(live_set, mem); view_replace_minor(system, exchange, new_view, panel, live_set); - + new_view->map = &vars->map_ui; Interactive_View *int_view = interactive_view_init(system, new_view, &vars->hot_directory, style, - working_set, font_set, delay); + working_set, font_set, delay); int_view->interaction = INTV_LIVE_FILE_LIST; int_view->action = INTV_KILL; copy(&int_view->query, "Kill File: "); @@ -1090,7 +1144,7 @@ COMMAND_DECL(kill_buffer){ REQ_FILE_VIEW(view); REQ_FILE(file, view); USE_DELAY(delay); - + delayed_try_kill(delay, file->name.live_name, view->view_base.panel); } @@ -1098,7 +1152,7 @@ COMMAND_DECL(toggle_line_wrap){ ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); - + Relative_Scrolling scrolling = view_get_relative_scrolling(view); if (view->unwrapped_lines){ view->unwrapped_lines = 0; @@ -1130,7 +1184,7 @@ COMMAND_DECL(toggle_tokens){ REQ_FILE_VIEW(view); REQ_FILE(file, view); USE_MEM(mem); - + if (file->settings.tokens_exist){ file_kill_tokens(system, &mem->general, file); } @@ -1142,8 +1196,8 @@ COMMAND_DECL(toggle_tokens){ internal void case_change_range(System_Functions *system, - Mem_Options *mem, File_View *view, Editing_File *file, - u8 a, u8 z, u8 char_delta){ + Mem_Options *mem, File_View *view, Editing_File *file, + u8 a, u8 z, u8 char_delta){ #if BUFFER_EXPERIMENT_SCALPEL <= 0 Range range = make_range(view->cursor.pos, view->mark); if (range.start < range.end){ @@ -1152,12 +1206,12 @@ case_change_range(System_Functions *system, step.edit.start = range.start; step.edit.end = range.end; step.edit.len = range.end - range.start; - + if (file->state.still_lexing) system->cancel_job(BACKGROUND_THREADS, file->state.lex_job); - + file_update_history_before_edit(mem, file, step, 0, hist_normal); - + u8 *data = (u8*)file->state.buffer.data; for (i32 i = range.start; i < range.end; ++i){ if (data[i] >= a && data[i] <= z){ @@ -1193,7 +1247,7 @@ COMMAND_DECL(clean_all_lines){ REQ_FILE(file, view); USE_LAYOUT(layout); USE_MEM(mem); - + view_clean_whitespace(system, mem, view, layout); } @@ -1201,7 +1255,7 @@ COMMAND_DECL(eol_dosify){ ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); - + file->settings.dos_write_mode = 1; file->state.last_4ed_edit_time = system->time(); } @@ -1210,7 +1264,7 @@ COMMAND_DECL(eol_nixify){ ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); - + file->settings.dos_write_mode = 0; file->state.last_4ed_edit_time = system->time(); } @@ -1221,11 +1275,11 @@ COMMAND_DECL(auto_tab_range){ REQ_FILE(file, view); USE_LAYOUT(layout); USE_MEM(mem); - + int r_start = 0, r_end = 0; int start_set = 0, end_set = 0; int clear_blank_lines = 1; - + // TODO(allen): deduplicate Command_Parameter *end = param_stack_end(&command->part); Command_Parameter *param = param_stack_first(&command->part, end); @@ -1236,18 +1290,18 @@ COMMAND_DECL(auto_tab_range){ start_set = 1; r_start = dynamic_to_int(¶m->param.value); break; - + case par_range_end: end_set = 1; r_end = dynamic_to_int(¶m->param.value); break; - + case par_clear_blank_lines: clear_blank_lines = dynamic_to_bool(¶m->param.value); break; } } - + if (file->state.token_stack.tokens && file->state.tokens_complete){ Range range = make_range(view->cursor.pos, view->mark); if (start_set) range.start = r_start; @@ -1264,7 +1318,7 @@ COMMAND_DECL(auto_tab_line_at_cursor){ USE_MEM(mem); int clear_blank_lines = 0; - + Command_Parameter *end = param_stack_end(&command->part); Command_Parameter *param = param_stack_first(&command->part, end); for (; param < end; param = param_next(param, end)){ @@ -1275,7 +1329,7 @@ COMMAND_DECL(auto_tab_line_at_cursor){ break; } } - + if (file->state.token_stack.tokens && file->state.tokens_complete){ i32 pos = view->cursor.pos; view_auto_tab_tokens(system, mem, view, layout, pos, pos, clear_blank_lines); @@ -1298,24 +1352,24 @@ COMMAND_DECL(open_panel_vsplit){ ProfileMomentFunction(); USE_LAYOUT(layout); USE_PANEL(panel); - + i32 panel_count = layout->panel_count; if (panel_count < layout->panel_max_count){ Split_Result split = layout_split_panel(layout, panel, 1); - + Panel *panel1 = panel; Panel *panel2 = split.panel; - + panel2->screen_region = panel1->screen_region; - + panel2->full.x0 = split.divider->pos; panel2->full.x1 = panel1->full.x1; panel1->full.x1 = split.divider->pos; - + panel_fix_internal_area(panel1); panel_fix_internal_area(panel2); panel2->prev_inner = panel2->inner; - + layout->active_panel = (i32)(panel2 - layout->panels); } } @@ -1324,24 +1378,24 @@ COMMAND_DECL(open_panel_hsplit){ ProfileMomentFunction(); USE_LAYOUT(layout); USE_PANEL(panel); - + i32 panel_count = layout->panel_count; if (panel_count < layout->panel_max_count){ Split_Result split = layout_split_panel(layout, panel, 0); - + Panel *panel1 = panel; Panel *panel2 = split.panel; - + panel2->screen_region = panel1->screen_region; - + panel2->full.y0 = split.divider->pos; panel2->full.y1 = panel1->full.y1; panel1->full.y1 = split.divider->pos; - + panel_fix_internal_area(panel1); panel_fix_internal_area(panel2); panel2->prev_inner = panel2->inner; - + layout->active_panel = (i32)(panel2 - layout->panels); } } @@ -1352,16 +1406,16 @@ COMMAND_DECL(close_panel){ USE_PANEL(panel); USE_VIEW(view); USE_EXCHANGE(exchange); - + if (layout->panel_count > 1){ if (view){ live_set_free_view(system, exchange, command->live_set, view); panel->view = 0; } - + Divider_And_ID div = layout_get_divider(layout, panel->parent); Assert(div.divider->child1 == -1 || div.divider->child2 == -1); - + i32 child; if (div.divider->child1 == -1){ child = div.divider->child2; @@ -1385,16 +1439,16 @@ COMMAND_DECL(close_panel){ Assert(layout->root == div.id); layout->root = child; } - + if (child != -1){ Divider_And_ID chi = layout_get_divider(layout, child); chi.divider->parent = parent; chi.divider->which_child = div.divider->which_child; } - + layout_free_divider(layout, div.divider); layout_free_panel(layout, panel); - + if (child == -1){ panel = layout->panels; layout->active_panel = -1; @@ -1412,7 +1466,7 @@ COMMAND_DECL(close_panel){ else{ layout->active_panel = layout->active_panel % layout->panel_count; } - + layout_fix_all_panels(layout); } } @@ -1421,7 +1475,7 @@ COMMAND_DECL(move_left){ ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); - + i32 pos = view->cursor.pos; if (pos > 0) --pos; view_cursor_move(view, pos); @@ -1431,7 +1485,7 @@ COMMAND_DECL(move_right){ ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); - + i32 size = buffer_size(&file->state.buffer); i32 pos = view->cursor.pos; if (pos < size) ++pos; @@ -1451,9 +1505,9 @@ COMMAND_DECL(delete){ i32 start, end; start = cursor_pos; end = cursor_pos+1; - + Assert(end - start > 0); - + i32 next_cursor_pos = start; view_replace_range(system, mem, view, layout, start, end, 0, 0, next_cursor_pos); view_cursor_move(view, next_cursor_pos); @@ -1466,17 +1520,17 @@ COMMAND_DECL(backspace){ REQ_FILE(file, view); USE_LAYOUT(layout); USE_MEM(mem); - + i32 size = buffer_size(&file->state.buffer); i32 cursor_pos = view->cursor.pos; if (cursor_pos > 0 && cursor_pos <= size){ i32 start, end; end = cursor_pos; start = cursor_pos-1; - + i32 shift = (end - start); Assert(shift > 0); - + i32 next_cursor_pos = view->cursor.pos - shift; view_replace_range(system, mem, view, layout, start, end, 0, 0, next_cursor_pos); view_cursor_move(view, next_cursor_pos); @@ -1488,7 +1542,7 @@ COMMAND_DECL(move_up){ REQ_FILE_VIEW(view); REQ_FILE(file, view); USE_FONT_SET(font_set); - + f32 font_height = (f32)get_font_info(font_set, view->style->font_id)->height; f32 cy = view_get_cursor_y(view)-font_height; f32 px = view->preferred_x; @@ -1515,7 +1569,7 @@ COMMAND_DECL(seek_end_of_line){ ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); - + i32 pos = view_find_end_of_line(view, view->cursor.pos); view_cursor_move(view, pos); } @@ -1524,7 +1578,7 @@ COMMAND_DECL(seek_beginning_of_line){ ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); - + i32 pos = view_find_beginning_of_line(view, view->cursor.pos); view_cursor_move(view, pos); } @@ -1532,10 +1586,10 @@ COMMAND_DECL(seek_beginning_of_line){ COMMAND_DECL(page_down){ ProfileMomentFunction(); REQ_FILE_VIEW(view); - + f32 height = view_compute_height(view); f32 max_target_y = view_compute_max_target_y(view); - + view->target_y += height; if (view->target_y > max_target_y) view->target_y = max_target_y; @@ -1546,22 +1600,22 @@ COMMAND_DECL(page_down){ COMMAND_DECL(page_up){ ProfileMomentFunction(); REQ_FILE_VIEW(view); - + f32 height = view_compute_height(view); - + view->target_y -= height; if (view->target_y < 0) view->target_y = 0; - + view->cursor = view_compute_cursor_from_xy( view, 0, view->target_y + (height - view->font_height)*.5f); } inline void open_theme_options(System_Functions *system, Exchange *exchange, - App_Vars *vars, Live_Views *live_set, Mem_Options *mem, Panel *panel){ + App_Vars *vars, Live_Views *live_set, Mem_Options *mem, Panel *panel){ View *new_view = live_set_alloc_view(live_set, mem); view_replace_minor(system, exchange, new_view, panel, live_set); - + new_view->map = &vars->map_ui; Color_View *color_view = color_view_init(new_view, &vars->working_set); color_view->hot_directory = &vars->hot_directory; @@ -1579,20 +1633,20 @@ COMMAND_DECL(open_color_tweaker){ USE_MEM(mem); USE_PANEL(panel); USE_EXCHANGE(exchange); - + open_theme_options(system, exchange, vars, live_set, mem, panel); } inline void open_config_options(System_Functions *system, Exchange *exchange, - App_Vars *vars, Live_Views *live_set, Mem_Options *mem, Panel *panel){ + App_Vars *vars, Live_Views *live_set, Mem_Options *mem, Panel *panel){ View *new_view = live_set_alloc_view(live_set, mem); view_replace_minor(system, exchange, new_view, panel, live_set); - + new_view->map = &vars->map_ui; config_view_init(new_view, &vars->style, - &vars->working_set, vars->font_set, - &vars->settings); + &vars->working_set, vars->font_set, + &vars->settings); } COMMAND_DECL(open_config){ @@ -1602,7 +1656,7 @@ COMMAND_DECL(open_config){ USE_MEM(mem); USE_PANEL(panel); USE_EXCHANGE(exchange); - + open_config_options(system, exchange, vars, live_set, mem, panel); } @@ -1615,13 +1669,13 @@ COMMAND_DECL(open_menu){ USE_WORKING_SET(working_set); USE_STYLE(style); USE_EXCHANGE(exchange); - + View *new_view = live_set_alloc_view(live_set, mem); view_replace_minor(system, exchange, new_view, panel, live_set); - + new_view->map = &vars->map_ui; Menu_View *menu_view = menu_view_init(new_view, style, working_set, - &vars->delay, vars->font_set); + &vars->delay1, vars->font_set); AllowLocal(menu_view); } @@ -1634,10 +1688,10 @@ COMMAND_DECL(open_debug_view){ USE_PANEL(panel); USE_MEM(mem); USE_EXCHANGE(exchange); - + View *new_view = live_set_alloc_view(live_set, mem); view_replace_major(system, exchange, new_view, panel, live_set); - + new_view->map = &vars->map_debug; Debug_View *debug_view = debug_view_init(new_view); debug_view->font_id = style->font_id; @@ -1664,14 +1718,14 @@ COMMAND_DECL(close_minor_view){ USE_PANEL(panel); USE_LIVE_SET(live_set); USE_EXCHANGE(exchange); - + view_remove_minor(system, exchange, panel, live_set); } COMMAND_DECL(cursor_mark_swap){ ProfileMomentFunction(); REQ_FILE_VIEW(view); - + i32 pos = view->cursor.pos; view_cursor_move(view, view->mark); view->mark = pos; @@ -1688,68 +1742,68 @@ COMMAND_DECL(set_settings){ REQ_FILE_LOADING(file, view); USE_VARS(vars); USE_MEM(mem); - + Command_Parameter *end = param_stack_end(&command->part); Command_Parameter *param = param_stack_first(&command->part, end); for (; param < end; param = param_next(param, end)){ int p = dynamic_to_int(¶m->param.param); switch (p){ - case par_lex_as_cpp_file: - { + case par_lex_as_cpp_file: + { #if BUFFER_EXPERIMENT_SCALPEL <= 0 - int v = dynamic_to_bool(¶m->param.value); - if (file->settings.tokens_exist){ - if (!v) file_kill_tokens(system, &mem->general, file); - } - else{ - if (v) file_first_lex_parallel(system, &mem->general, file); - } + int v = dynamic_to_bool(¶m->param.value); + if (file->settings.tokens_exist){ + if (!v) file_kill_tokens(system, &mem->general, file); + } + else{ + if (v) file_first_lex_parallel(system, &mem->general, file); + } #endif - }break; - - case par_wrap_lines: - { - int v = dynamic_to_bool(¶m->param.value); - if (view->unwrapped_lines){ - if (v){ - view->unwrapped_lines = 0; - file->settings.unwrapped_lines = 0; - - if (!file->state.is_loading){ - Relative_Scrolling scrolling = view_get_relative_scrolling(view); - view->target_x = 0; - view->cursor = - view_compute_cursor_from_pos(view, view->cursor.pos); - view_set_relative_scrolling(view, scrolling); + }break; + + case par_wrap_lines: + { + int v = dynamic_to_bool(¶m->param.value); + if (view->unwrapped_lines){ + if (v){ + view->unwrapped_lines = 0; + file->settings.unwrapped_lines = 0; + + if (!file->state.is_loading){ + Relative_Scrolling scrolling = view_get_relative_scrolling(view); + view->target_x = 0; + view->cursor = + view_compute_cursor_from_pos(view, view->cursor.pos); + view_set_relative_scrolling(view, scrolling); + } } } - } - else{ - if (!v){ - view->unwrapped_lines = 1; - file->settings.unwrapped_lines = 1; - - if (!file->state.is_loading){ - Relative_Scrolling scrolling = view_get_relative_scrolling(view); - view->cursor = - view_compute_cursor_from_pos(view, view->cursor.pos); - view_set_relative_scrolling(view, scrolling); + else{ + if (!v){ + view->unwrapped_lines = 1; + file->settings.unwrapped_lines = 1; + + if (!file->state.is_loading){ + Relative_Scrolling scrolling = view_get_relative_scrolling(view); + view->cursor = + view_compute_cursor_from_pos(view, view->cursor.pos); + view_set_relative_scrolling(view, scrolling); + } } } - } - }break; - - case par_key_mapid: - { - int v = dynamic_to_int(¶m->param.value); - if (v == mapid_global) file->settings.base_map_id = mapid_global; - else if (v == mapid_file) file->settings.base_map_id = mapid_file; - else if (v < mapid_global){ - int index = app_get_map_index(vars, v); - if (index < vars->user_map_count) file->settings.base_map_id = v; - else file->settings.base_map_id = mapid_file; - } - }break; + }break; + + case par_key_mapid: + { + int v = dynamic_to_int(¶m->param.value); + if (v == mapid_global) file->settings.base_map_id = mapid_global; + else if (v == mapid_file) file->settings.base_map_id = mapid_file; + else if (v < mapid_global){ + int index = app_get_map_index(vars, v); + if (index < vars->user_map_count) file->settings.base_map_id = v; + else file->settings.base_map_id = mapid_file; + } + }break; } } } @@ -1759,25 +1813,25 @@ COMMAND_DECL(set_settings){ internal void build(System_Functions *system, Mem_Options *mem, - App_Vars *vars, Working_Set *working_set, - Font_Set *font_set, Style *style, - Live_Views *live_set, Exchange *exchange, - Panel *panel, Command_Data *command, - String hot_directory, - char *buffer_name, i32 buffer_name_len, - char *path, i32 path_len, - char *script, i32 script_len, - u32 flags){ + App_Vars *vars, Working_Set *working_set, + Font_Set *font_set, Style *style, + Live_Views *live_set, Exchange *exchange, + Panel *panel, Command_Data *command, + String hot_directory, + char *buffer_name, i32 buffer_name_len, + char *path, i32 path_len, + char *script, i32 script_len, + u32 flags){ if (buffer_name == 0 || path == 0 || script == 0){ return; } - + if (vars->cli_processes.count < vars->cli_processes.max){ Editing_Layout *layout = &vars->layout; Editing_File *file = working_set_contains(working_set, make_string_slowly(buffer_name)); i32 index; b32 bind_to_new_view = 1; - + if (!file){ Get_File_Result get_file = working_set_get_available_file(working_set); file = get_file.file; @@ -1807,22 +1861,25 @@ build(System_Functions *system, Mem_Options *mem, } } } - + if (file){ file_create_super_locked(system, mem, working_set, file, buffer_name, font_set, style->font_id); file->settings.unimportant = 1; table_add(&working_set->table, file->name.source_path, index); - + if (bind_to_new_view){ +#if 0 View *new_view = live_set_alloc_view(live_set, mem); view_replace_major(system, exchange, new_view, panel, live_set); - + File_View *file_view = file_view_init(new_view, layout); view_set_file(system, file_view, file, font_set, style, - vars->hooks[hook_open_file], command, &app_links); + vars->hooks[hook_open_file], command, &app_links); new_view->map = app_get_map(vars, file->settings.base_map_id); +#endif + view_file_in_panel(command, panel, file); } - + i32 i = vars->cli_processes.count++; CLI_Process *proc = vars->cli_processes.procs + i; if (!system->cli_call(path, script, &proc->cli)){ @@ -1839,7 +1896,7 @@ build(System_Functions *system, Mem_Options *mem, } } -COMMAND_DECL(build){ +COMMAND_DECL(command_line){ ProfileMomentFunction(); USE_VARS(vars); USE_MEM(mem); @@ -1853,73 +1910,73 @@ COMMAND_DECL(build){ char *buffer_name = 0; char *path = 0; char *script = 0; - + int buffer_name_len = 0; int path_len = 0; int script_len = 0; u32 flags = CLI_OverlapWithConflict; - + Command_Parameter *end = param_stack_end(&command->part); Command_Parameter *param = param_stack_first(&command->part, end); for (; param < end; param = param_next(param, end)){ int p = dynamic_to_int(¶m->param.param); switch (p){ - case par_name: - { - if (buffer_name == 0){ - char *new_buffer_name = dynamic_to_string(¶m->param.value, &buffer_name_len); - if (new_buffer_name){ - buffer_name = new_buffer_name; + case par_name: + { + if (buffer_name == 0){ + char *new_buffer_name = dynamic_to_string(¶m->param.value, &buffer_name_len); + if (new_buffer_name){ + buffer_name = new_buffer_name; + } } - } - }break; + }break; - case par_cli_path: - { - if (path == 0){ - char *new_cli_path = dynamic_to_string(¶m->param.value, &path_len); - if (new_cli_path){ - path = new_cli_path; + case par_cli_path: + { + if (path == 0){ + char *new_cli_path = dynamic_to_string(¶m->param.value, &path_len); + if (new_cli_path){ + path = new_cli_path; + } } - } - }break; + }break; - case par_cli_command: - { - if (script == 0){ - char *new_command = dynamic_to_string(¶m->param.value, &script_len); - if (new_command){ - script = new_command; + case par_cli_command: + { + if (script == 0){ + char *new_command = dynamic_to_string(¶m->param.value, &script_len); + if (new_command){ + script = new_command; + } } - } - }break; - - case par_cli_overlap_with_conflict: - { - if (dynamic_to_int(¶m->param.value)) - flags |= CLI_OverlapWithConflict; - else - flags &= (~CLI_OverlapWithConflict); - }break; - - case par_cli_always_bind_to_view: - { - if (dynamic_to_int(¶m->param.value)) - flags |= CLI_OverlapWithConflict; - else - flags &= (~CLI_OverlapWithConflict); - }break; + }break; + + case par_cli_overlap_with_conflict: + { + if (dynamic_to_int(¶m->param.value)) + flags |= CLI_OverlapWithConflict; + else + flags &= (~CLI_OverlapWithConflict); + }break; + + case par_cli_always_bind_to_view: + { + if (dynamic_to_int(¶m->param.value)) + flags |= CLI_OverlapWithConflict; + else + flags &= (~CLI_OverlapWithConflict); + }break; } } - + build(system, mem, vars, working_set, - font_set, style, live_set, exchange, - panel, command, - vars->hot_directory.string, - buffer_name, buffer_name_len, - path, path_len, - script, script_len, - flags); + font_set, style, live_set, exchange, + panel, command, + vars->hot_directory.string, + buffer_name, buffer_name_len, + path, path_len, + script, script_len, + flags); } internal void @@ -1964,7 +2021,7 @@ fill_view_summary(File_View_Summary *view, File_View *file_view, Live_Views *liv extern "C"{ EXECUTE_COMMAND_SIG(external_exec_command_keep_stack){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; Command_Function function = command_table[command_id]; Command_Binding binding; binding.function = function; @@ -1972,18 +2029,18 @@ extern "C"{ update_command_data(cmd->vars, cmd); } - + PUSH_PARAMETER_SIG(external_push_parameter){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; Partition *part = &cmd->part; Command_Parameter *cmd_param = push_struct(part, Command_Parameter); cmd_param->type = 0; cmd_param->param.param = param; cmd_param->param.value = value; } - + PUSH_MEMORY_SIG(external_push_memory){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; Partition *part = &cmd->part; Command_Parameter *base = push_struct(part, Command_Parameter); char *result = push_array(part, char, len); @@ -1995,75 +2052,89 @@ extern "C"{ base->inline_string.len = len; return(result); } - + CLEAR_PARAMETERS_SIG(external_clear_parameters){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; cmd->part.pos = 0; } - + DIRECTORY_GET_HOT_SIG(external_directory_get_hot){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; Hot_Directory *hot = &cmd->vars->hot_directory; - i32 copy_max = max - 1; + i32 copy_max = capacity - 1; hot_directory_clean_end(hot); if (copy_max > hot->string.size) copy_max = hot->string.size; - memcpy(buffer, hot->string.str, copy_max); - buffer[copy_max] = 0; - return(copy_max); + memcpy(out, hot->string.str, copy_max); + out[copy_max] = 0; + return(hot->string.size); + } + + GET_FILE_LIST_SIG(external_get_file_list){ + Command_Data *cmd = (Command_Data*)context->cmd_context; + System_Functions *system = cmd->system; + File_List result = {}; + system->set_file_list(&result, make_string(dir, len)); + return(result); + } + + FREE_FILE_LIST_SIG(external_free_file_list){ + Command_Data *cmd = (Command_Data*)context->cmd_context; + System_Functions *system = cmd->system; + system->set_file_list(&list, make_string(0, 0)); } GET_BUFFER_MAX_INDEX_SIG(external_get_buffer_max_index){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; Working_Set *working_set = cmd->working_set; int max = working_set->file_index_count; return(max); } - + GET_BUFFER_SIG(external_get_buffer){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; Editing_File *file; Working_Set *working_set = cmd->working_set; int max = working_set->file_index_count; Buffer_Summary buffer = {}; - + if (index >= 0 && index < max){ file = working_set->files + index; if (!file->state.is_dummy){ fill_buffer_summary(&buffer, file, working_set); } } - + return(buffer); } - + GET_ACTIVE_BUFFER_SIG(external_get_active_buffer){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; File_View *view; Editing_File *file; Working_Set *working_set; Buffer_Summary buffer = {}; - + view = view_to_file_view(cmd->view); if (view){ file = view->file; working_set = cmd->working_set; - + if (file && !file->state.is_dummy){ fill_buffer_summary(&buffer, file, working_set); } } - + return(buffer); } - + GET_BUFFER_BY_NAME(external_get_buffer_by_name){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; Editing_File *file; Working_Set *working_set; i32 index; Buffer_Summary buffer = {}; - + working_set = cmd->working_set; if (table_find(&working_set->table, make_string(filename, len), &index)){ file = working_set->files + index; @@ -2071,31 +2142,31 @@ extern "C"{ fill_buffer_summary(&buffer, file, working_set); } } - + return(buffer); } - + REFRESH_BUFFER_SIG(external_refresh_buffer){ int result; *buffer = external_get_buffer(context, buffer->buffer_id); result = buffer->exists; return(result); } - + BUFFER_SEEK_DELIMITER_SIG(external_buffer_seek_delimiter){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; Editing_File *file; Working_Set *working_set; int result = 0; int size; - + if (buffer->exists){ working_set = cmd->working_set; file = working_set->files + buffer->buffer_id; if (!file->state.is_dummy && file_is_ready(file)){ size = buffer_size(&file->state.buffer); result = 1; - + if (start < 0 && !seek_forward) *out = start; else if (start >= size && seek_forward) *out = start; else{ @@ -2106,16 +2177,16 @@ extern "C"{ *out = buffer_reverse_seek_delimiter(&file->state.buffer, start, delim); } } - + fill_buffer_summary(buffer, file, working_set); } } return(result); } - + BUFFER_SEEK_STRING_SIG(external_buffer_seek_string){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; Editing_File *file; Working_Set *working_set; Temp_Memory temp; @@ -2123,13 +2194,13 @@ extern "C"{ char *spare; int result = 0; int size; - + if (buffer->exists){ working_set = cmd->working_set; file = working_set->files + buffer->buffer_id; if (!file->state.is_dummy && file_is_ready(file)){ size = buffer_size(&file->state.buffer); - + if (start < 0 && !seek_forward) *out = start; else if (start >= size && seek_forward) *out = start; else{ @@ -2151,14 +2222,14 @@ extern "C"{ return(result); } - + BUFFER_READ_RANGE_SIG(external_buffer_read_range){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; Editing_File *file; Working_Set *working_set; int result = 0; int size; - + if (buffer->exists){ working_set = cmd->working_set; file = working_set->files + buffer->buffer_id; @@ -2171,23 +2242,23 @@ extern "C"{ fill_buffer_summary(buffer, file, working_set); } } - + return(result); } - + BUFFER_REPLACE_RANGE_SIG(external_buffer_replace_range){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; Editing_File *file; Working_Set *working_set; - + System_Functions *system; Mem_Options *mem; Editing_Layout *layout; - + int result = 0; int size; int next_cursor, pos; - + if (buffer->exists){ working_set = cmd->working_set; file = working_set->files + buffer->buffer_id; @@ -2195,61 +2266,41 @@ extern "C"{ size = buffer_size(&file->state.buffer); if (0 <= start && start <= end && end <= size){ result = 1; - + system = cmd->system; mem = cmd->mem; layout = cmd->layout; - + pos = file->state.cursor_pos; if (pos < start) next_cursor = pos; else if (pos < end) next_cursor = start + len; else next_cursor = pos + end - start + len; - + file_replace_range(system, mem, file, layout, start, end, str, len, next_cursor); } fill_buffer_summary(buffer, file, working_set); } } - + return(result); } - - BUFFER_SAVE_SIG(external_buffer_save){ - Command_Data *cmd = (Command_Data*)context->data; - Editing_File *file; - Working_Set *working_set; - Delay *delay; - int result = 0; - - if (buffer->exists){ - delay = cmd->delay; - working_set = cmd->working_set; - file = working_set->files + buffer->buffer_id; - if (!file->state.is_dummy && file_is_ready(file) && buffer_needs_save(file)){ - delayed_save(delay, file->name.source_path, file); - result = 1; - } - } - - return(result); - } - + GET_VIEW_MAX_INDEX_SIG(external_get_view_max_index){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; Live_Views *live_set = cmd->live_set; int max = live_set->max; return(max); } - + GET_FILE_VIEW_SIG(external_get_file_view){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; Live_Views *live_set = cmd->live_set; int max = live_set->max; View *vptr; File_View *file_view; File_View_Summary view = {}; - + if (index >= 0 && index < max){ vptr = (View*)((char*)live_set->views + live_set->stride*index); file_view = view_to_file_view(vptr); @@ -2257,37 +2308,37 @@ extern "C"{ fill_view_summary(&view, file_view, cmd->live_set, cmd->working_set); } } - + return(view); } - + GET_ACTIVE_FILE_VIEW_SIG(external_get_active_file_view){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; File_View_Summary view = {}; File_View *file_view; - + file_view = view_to_file_view(cmd->view); if (file_view){ fill_view_summary(&view, file_view, cmd->live_set, cmd->working_set); } - + return(view); } - + REFRESH_FILE_VIEW_SIG(external_refresh_file_view){ int result; *view = external_get_file_view(context, view->view_id); result = view->exists; return(result); } - + VIEW_SET_CURSOR_SIG(external_view_set_cursor){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; Live_Views *live_set; View *vptr; File_View *file_view; int result = 0; - + if (view->exists){ live_set = cmd->live_set; vptr = (View*)((char*)live_set->views + live_set->stride * view->view_id); @@ -2301,18 +2352,18 @@ extern "C"{ fill_view_summary(view, file_view, cmd->live_set, cmd->working_set); } } - + return(result); } - + VIEW_SET_MARK_SIG(external_view_set_mark){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; Live_Views *live_set; View *vptr; File_View *file_view; Full_Cursor cursor; int result = 0; - + if (view->exists){ live_set = cmd->live_set; vptr = (View*)((char*)live_set->views + live_set->stride * view->view_id); @@ -2329,17 +2380,17 @@ extern "C"{ fill_view_summary(view, file_view, cmd->live_set, cmd->working_set); } } - + return(result); } - + VIEW_SET_HIGHLIGHT_SIG(external_view_set_highlight){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; Live_Views *live_set; View *vptr; File_View *file_view; int result = 0; - + if (view->exists){ live_set = cmd->live_set; vptr = (View*)((char*)live_set->views + live_set->stride * view->view_id); @@ -2355,19 +2406,19 @@ extern "C"{ fill_view_summary(view, file_view, cmd->live_set, cmd->working_set); } } - + return(result); } - + VIEW_SET_BUFFER_SIG(external_view_set_buffer){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; Live_Views *live_set; View *vptr; File_View *file_view; Editing_File *file; Working_Set *working_set; int max, result = 0; - + if (view->exists){ live_set = cmd->live_set; vptr = (View*)((char*)live_set->views + live_set->stride * view->view_id); @@ -2382,54 +2433,54 @@ extern "C"{ cmd->vars->hooks[hook_open_file], cmd, &app_links); } } - + fill_view_summary(view, file_view, cmd->live_set, cmd->working_set); } } - + return(result); } - + GET_USER_INPUT_SIG(external_get_user_input){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; System_Functions *system = cmd->system; Coroutine *coroutine = cmd->current_coroutine; User_Input result; - + Assert(coroutine); *((u32*)coroutine->out+0) = get_type; *((u32*)coroutine->out+1) = abort_type; system->yield_coroutine(coroutine); result = *(User_Input*)coroutine->in; - + return(result); } - + START_QUERY_BAR_SIG(external_start_query_bar){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; Query_Slot *slot = 0; View *vptr; File_View *file_view; - + vptr = cmd->view; file_view = view_to_file_view(vptr); - + if (file_view){ slot = alloc_query_slot(&file_view->query_set); slot->query_bar = bar; } - + return(slot != 0); } - + END_QUERY_BAR_SIG(external_end_query_bar){ - Command_Data *cmd = (Command_Data*)context->data; + Command_Data *cmd = (Command_Data*)context->cmd_context; View *vptr; File_View *file_view; - + vptr = cmd->view; file_view = view_to_file_view(vptr); - + if (file_view){ free_query_slot(&file_view->query_set, bar); } @@ -2445,44 +2496,55 @@ internal void command_caller(Coroutine *coroutine){ Command_In *cmd_in = (Command_In*)coroutine->in; Command_Data *cmd = cmd_in->cmd; + View *view = cmd->view; + // TODO(allen): this isn't really super awesome, could have issues if + // the file view get's change out under us. + File_View *fview = view_to_file_view(view); + if (fview) fview->next_mode = {}; cmd_in->bind.function(cmd->system, cmd, cmd_in->bind); + fview = view_to_file_view(view); + if (fview) fview->mode = fview->next_mode; } internal void -app_links_init(System_Functions *system){ +app_links_init(System_Functions *system, void *data, int size){ + app_links.data = data; + app_links.size = size; + app_links.exec_command_keep_stack = external_exec_command_keep_stack; app_links.push_parameter = external_push_parameter; app_links.push_memory = external_push_memory; app_links.clear_parameters = external_clear_parameters; - + app_links.directory_get_hot = external_directory_get_hot; - app_links.directory_has_file = system->directory_has_file; + app_links.file_exists = system->file_exists; app_links.directory_cd = system->directory_cd; - + app_links.get_file_list = external_get_file_list; + app_links.free_file_list = external_free_file_list; + app_links.get_buffer_max_index = external_get_buffer_max_index; app_links.get_buffer = external_get_buffer; app_links.get_active_buffer = external_get_active_buffer; app_links.get_buffer_by_name = external_get_buffer_by_name; - + app_links.refresh_buffer = external_refresh_buffer; app_links.buffer_seek_delimiter = external_buffer_seek_delimiter; app_links.buffer_seek_string = external_buffer_seek_string; app_links.buffer_read_range = external_buffer_read_range; app_links.buffer_replace_range = external_buffer_replace_range; - app_links.buffer_save = external_buffer_save; - + app_links.get_view_max_index = external_get_view_max_index; app_links.get_file_view = external_get_file_view; app_links.get_active_file_view = external_get_active_file_view; - + app_links.refresh_file_view = external_refresh_file_view; app_links.view_set_cursor = external_view_set_cursor; app_links.view_set_mark = external_view_set_mark; app_links.view_set_highlight = external_view_set_highlight; app_links.view_set_buffer = external_view_set_buffer; - + app_links.get_user_input = external_get_user_input; - + app_links.start_query_bar = external_start_query_bar; app_links.end_query_bar = external_end_query_bar; } @@ -2491,7 +2553,7 @@ app_links_init(System_Functions *system){ internal void setup_debug_commands(Command_Map *commands, Partition *part, Command_Map *parent){ map_init(commands, part, 6, parent); - + map_add(commands, 'm', MDFR_NONE, command_debug_memory); map_add(commands, 'o', MDFR_NONE, command_debug_os_events); } @@ -2500,9 +2562,9 @@ setup_debug_commands(Command_Map *commands, Partition *part, Command_Map *parent internal void setup_ui_commands(Command_Map *commands, Partition *part, Command_Map *parent){ map_init(commands, part, 32, parent); - + commands->vanilla_keyboard_default.function = command_null; - + // TODO(allen): This is hacky, when the new UI stuff happens, let's fix it, and by that // I mean actually fix it, don't just say you fixed it with something stupid again. u8 mdfr; @@ -2531,7 +2593,7 @@ setup_top_commands(Command_Map *commands, Partition *part, Command_Map *parent){ internal void setup_command_table(){ #define SET(n) command_table[cmdid_##n] = command_##n - + SET(null); SET(write_character); SET(seek_whitespace_right); @@ -2595,8 +2657,8 @@ setup_command_table(){ SET(cursor_mark_swap); SET(open_menu); SET(set_settings); - SET(build); - + SET(command_line); + #undef SET } @@ -2610,11 +2672,11 @@ app_hardcode_styles(App_Vars *vars){ style = styles; i16 fonts = 1; - + ///////////////// style_set_name(style, make_lit_string("4coder")); style->font_id = fonts + 0; - + style->main.back_color = 0xFF0C0C0C; style->main.margin_color = 0xFF181818; style->main.margin_hover_color = 0xFF252525; @@ -2635,13 +2697,13 @@ app_hardcode_styles(App_Vars *vars){ style->main.include_color = style->main.str_constant_color; style->main.preproc_color = style->main.default_color; style->main.special_character_color = 0xFFFF0000; - + style->main.paste_color = 0xFFDDEE00; style->main.undo_color = 0xFF00DDEE; - + style->main.highlight_junk_color = 0xff3a0000; style->main.highlight_white_color = 0xff003a3a; - + file_info_style.bar_color = 0xFF888888; file_info_style.bar_active_color = 0xFF666666; file_info_style.base_color = 0xFF000000; @@ -2650,17 +2712,17 @@ app_hardcode_styles(App_Vars *vars){ style->main.file_info_style = file_info_style; style->font_changed = 1; ++style; - + ///////////////// *style = *(style-1); style_set_name(style, make_lit_string("4coder-mono")); style->font_id = fonts + 1; ++style; - + ///////////////// style_set_name(style, make_lit_string("Handmade Hero")); style->font_id = fonts + 1; - + style->main.back_color = 0xFF161616; style->main.margin_color = 0xFF262626; style->main.margin_hover_color = 0xFF333333; @@ -2668,7 +2730,7 @@ app_hardcode_styles(App_Vars *vars){ style->main.cursor_color = 0xFF40FF40; style->main.at_cursor_color = style->main.back_color; style->main.mark_color = 0xFF808080; - style->main.highlight_color = 0xFF191970; + style->main.highlight_color = 0xFF703419; style->main.at_highlight_color = 0xFFCDAA7D; style->main.default_color = 0xFFCDAA7D; style->main.comment_color = 0xFF7F7F7F; @@ -2681,14 +2743,14 @@ app_hardcode_styles(App_Vars *vars){ style->main.include_color = style->main.str_constant_color; style->main.preproc_color = style->main.default_color; style->main.special_character_color = 0xFFFF0000; - + style->main.paste_color = 0xFFFFBB00; style->main.undo_color = 0xFFFF00BB; style->main.undo_color = 0xFF80005D; - + style->main.highlight_junk_color = 0xFF3A0000; style->main.highlight_white_color = 0xFF003A3A; - + file_info_style.bar_color = 0xFFCACACA; file_info_style.bar_active_color = 0xFFA8A8A8; file_info_style.base_color = 0xFF000000; @@ -2697,11 +2759,11 @@ app_hardcode_styles(App_Vars *vars){ style->main.file_info_style = file_info_style; style->font_changed = 1; ++style; - + ///////////////// style_set_name(style, make_lit_string("Twilight")); style->font_id = fonts + 2; - + style->main.back_color = 0xFF090D12; style->main.margin_color = 0xFF1A2634; style->main.margin_hover_color = 0xFF2D415B; @@ -2722,13 +2784,13 @@ app_hardcode_styles(App_Vars *vars){ style->main.include_color = style->main.str_constant_color; style->main.preproc_color = style->main.default_color; style->main.special_character_color = 0xFFFF0000; - + style->main.paste_color = 0xFFDDEE00; style->main.undo_color = 0xFF00DDEE; - + style->main.highlight_junk_color = 0xff3a0000; style->main.highlight_white_color = 0xFF151F2A; - + file_info_style.bar_color = 0xFF315E68; file_info_style.bar_active_color = 0xFF0F3C46; file_info_style.base_color = 0xFF000000; @@ -2737,11 +2799,11 @@ app_hardcode_styles(App_Vars *vars){ style->main.file_info_style = file_info_style; style->font_changed = 1; ++style; - + ///////////////// style_set_name(style, make_lit_string("Wolverine")); style->font_id = fonts + 3; - + style->main.back_color = 0xFF070711; style->main.margin_color = 0xFF111168; style->main.margin_hover_color = 0xFF191996; @@ -2762,13 +2824,13 @@ app_hardcode_styles(App_Vars *vars){ style->main.include_color = style->main.str_constant_color; style->main.preproc_color = style->main.default_color; style->main.special_character_color = 0xFFFF0000; - + style->main.paste_color = 0xFF900090; style->main.undo_color = 0xFF606090; - + style->main.highlight_junk_color = 0xff3a0000; style->main.highlight_white_color = 0xff003a3a; - + file_info_style.bar_color = 0xFF7082F9; file_info_style.bar_active_color = 0xFF4E60D7; file_info_style.base_color = 0xFF000000; @@ -2777,11 +2839,11 @@ app_hardcode_styles(App_Vars *vars){ style->main.file_info_style = file_info_style; style->font_changed = 1; ++style; - + ///////////////// style_set_name(style, make_lit_string("stb")); style->font_id = fonts + 4; - + style->main.back_color = 0xFFD6D6D6; style->main.margin_color = 0xFF9E9E9E; style->main.margin_hover_color = 0xFF7E7E7E; @@ -2802,13 +2864,13 @@ app_hardcode_styles(App_Vars *vars){ style->main.include_color = style->main.str_constant_color; style->main.preproc_color = style->main.default_color; style->main.special_character_color = 0xFF9A0000; - + style->main.paste_color = 0xFF00B8B8; style->main.undo_color = 0xFFB800B8; - + style->main.highlight_junk_color = 0xFFFF7878; style->main.highlight_white_color = 0xFFBCBCBC; - + file_info_style.bar_color = 0xFF606060; file_info_style.bar_active_color = 0xFF3E3E3E; file_info_style.base_color = 0xFF000000; @@ -2817,7 +2879,7 @@ app_hardcode_styles(App_Vars *vars){ style->main.file_info_style = file_info_style; style->font_changed = 1; ++style; - + vars->styles.count = (i32)(style - styles); vars->styles.max = ArrayCount(vars->styles.styles); style_copy(&vars->style, vars->styles.styles); @@ -2858,7 +2920,7 @@ enum Command_Line_Action{ void init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings, - Command_Line_Parameters clparams){ + Command_Line_Parameters clparams){ char *arg; Command_Line_Action action = CLAct_Nothing; i32 i,index; @@ -2939,14 +3001,14 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings, plat_settings->maximize_window = 1; action = CLAct_Nothing; }break; - + case CLAct_WindowPosition: { if (i + 1 < clparams.argc){ plat_settings->set_window_pos = 1; plat_settings->window_x = str_to_int(clparams.argv[i]); plat_settings->window_y = str_to_int(clparams.argv[i+1]); - + ++i; } action = CLAct_Nothing; @@ -2962,9 +3024,9 @@ app_setup_memory(Application_Memory *memory){ Assert(vars); *vars = {}; vars->mem.part = _partition; - + general_memory_open(&vars->mem.general, memory->target_memory, memory->target_memory_size); - + return(vars); } @@ -3006,32 +3068,32 @@ App_Read_Command_Line_Sig(app_read_command_line){ } App_Init_Sig(app_init){ - app_links_init(system); - + app_links_init(system, memory->user_memory, memory->user_memory_size); + App_Vars *vars = (App_Vars*)memory->vars_memory; vars->config_api = api; - app_links.data = &vars->command_data; - + app_links.cmd_context = &vars->command_data; + Partition *partition = &vars->mem.part; target->partition = partition; - + i32 panel_max_count = vars->layout.panel_max_count = 16; i32 divider_max_count = panel_max_count - 1; vars->layout.panel_count = 1; - + Panel *panels = vars->layout.panels = push_array(partition, Panel, panel_max_count); - + Panel_Divider *dividers = vars->layout.dividers = push_array(partition, Panel_Divider, divider_max_count); - + Panel_Divider *divider = dividers; for (i32 i = 0; i < divider_max_count-1; ++i, ++divider){ divider->next_free = (divider + 1); } divider->next_free = 0; vars->layout.free_divider = dividers; - + vars->live_set.count = 0; vars->live_set.max = 1 + 2*panel_max_count; i32 view_sizes[] = { @@ -3043,7 +3105,7 @@ App_Init_Sig(app_init){ sizeof(Debug_View), #endif }; - + i32 view_chunk_size = 0; for (i32 i = 0; i < ArrayCount(view_sizes); ++i){ view_chunk_size = Max(view_chunk_size, view_sizes[i]); @@ -3051,7 +3113,7 @@ App_Init_Sig(app_init){ vars->live_set.stride = view_chunk_size; vars->live_set.views = (File_View*) push_block(partition, view_chunk_size*vars->live_set.max); - + char *views_ = (char*)vars->live_set.views; for (i32 i = panel_max_count-2; i >= 0; --i){ View *view = (View*)(views_ + i*view_chunk_size); @@ -3063,9 +3125,9 @@ App_Init_Sig(app_init){ view->next_free = 0; } vars->live_set.free_view = (View*)views_; - + setup_command_table(); - + Command_Map *global = &vars->map_top; Assert(vars->config_api.get_bindings != 0); @@ -3076,24 +3138,24 @@ App_Init_Sig(app_init){ // So that it doesn't interfere with the command maps as they allocate // their own memory. i32 wanted_size = vars->config_api.get_bindings(data, size); - + b32 did_top = 0; b32 did_file = 0; if (wanted_size <= size){ partition_allocate(partition, wanted_size); - + Binding_Unit *unit = (Binding_Unit*)data; if (unit->type == unit_header && unit->header.error == 0){ Binding_Unit *end = unit + unit->header.total_size; - + i32 user_map_count = unit->header.user_map_count; - + vars->map_id_table = push_array( &vars->mem.part, i32, user_map_count); - + vars->user_maps = push_array( &vars->mem.part, Command_Map, user_map_count); - + vars->user_map_count = user_map_count; Command_Map *mapptr = 0; @@ -3180,23 +3242,23 @@ App_Init_Sig(app_init){ } } } - + if (!did_top) setup_top_commands(&vars->map_top, &vars->mem.part, global); if (!did_file) setup_file_commands(&vars->map_file, &vars->mem.part, global); - + #if !defined(FRED_SUPER) vars->hooks[hook_start] = 0; #endif - + setup_ui_commands(&vars->map_ui, &vars->mem.part, global); #if FRED_INTERNAL setup_debug_commands(&vars->map_debug, &vars->mem.part, global); #endif - + vars->font_set = &target->font_set; - + font_set_init(vars->font_set, partition, 16, 4); - + { struct Font_Setup{ char *c_file_name; @@ -3207,86 +3269,92 @@ App_Init_Sig(app_init){ }; #define LitStr(n) n, sizeof(n)-1 - + Font_Setup font_setup[] = { {LitStr("LiberationSans-Regular.ttf"), - LitStr("liberation sans"), - 16}, + LitStr("liberation sans"), + 16}, {LitStr("liberation-mono.ttf"), - LitStr("liberation mono"), - 16}, - + LitStr("liberation mono"), + 16}, + {LitStr("Hack-Regular.ttf"), - LitStr("hack"), - 16}, - + LitStr("hack"), + 16}, + {LitStr("CutiveMono-Regular.ttf"), - LitStr("cutive mono"), - 16}, - + LitStr("cutive mono"), + 16}, + {LitStr("Inconsolata-Regular.ttf"), - LitStr("inconsolata"), - 16}, - + LitStr("inconsolata"), + 16}, + }; i32 font_count = ArrayCount(font_setup); - + for (i32 i = 0; i < font_count; ++i){ String file_name = make_string(font_setup[i].c_file_name, - font_setup[i].file_name_len); + font_setup[i].file_name_len); String name = make_string(font_setup[i].c_name, - font_setup[i].name_len); + font_setup[i].name_len); i32 pt_size = font_setup[i].pt_size; - + font_set_add(partition, vars->font_set, file_name, name, pt_size); } } - + // NOTE(allen): file setup vars->working_set.file_index_count = 1; vars->working_set.file_max_count = 120; vars->working_set.files = push_array(partition, Editing_File, vars->working_set.file_max_count); - + file_get_dummy(&vars->working_set.files[0]); - + vars->working_set.table.max = vars->working_set.file_max_count * 3 / 2; vars->working_set.table.count = 0; vars->working_set.table.table = push_array(partition, File_Table_Entry, vars->working_set.table.max); memset(vars->working_set.table.table, 0, sizeof(File_Table_Entry) * vars->working_set.table.max); - + // NOTE(allen): clipboard setup vars->working_set.clipboard_max_size = ArrayCount(vars->working_set.clipboards); vars->working_set.clipboard_size = 0; vars->working_set.clipboard_current = 0; vars->working_set.clipboard_rolling = 0; - + // TODO(allen): more robust allocation solution for the clipboard if (clipboard.str){ String *dest = working_set_next_clipboard_string(&vars->mem.general, &vars->working_set, clipboard.size); copy(dest, make_string((char*)clipboard.str, clipboard.size)); } - + // NOTE(allen): delay setup - vars->delay.max = 128; - vars->delay.acts = (Delayed_Action*)general_memory_allocate( - &vars->mem.general, vars->delay.max*sizeof(Delayed_Action), 0); - + vars->delay1.general = &vars->mem.general; + vars->delay1.max = 16; + vars->delay1.acts = (Delayed_Action*)general_memory_allocate( + &vars->mem.general, vars->delay1.max*sizeof(Delayed_Action), 0); + + vars->delay2.general = &vars->mem.general; + vars->delay2.max = 16; + vars->delay2.acts = (Delayed_Action*)general_memory_allocate( + &vars->mem.general, vars->delay2.max*sizeof(Delayed_Action), 0); + // NOTE(allen): style setup app_hardcode_styles(vars); - + vars->palette_size = 40; vars->palette = push_array(partition, u32, vars->palette_size); - + panel_init(&panels[0]); String hdbase = make_fixed_width_string(vars->hot_dir_base_); hot_directory_init(&vars->hot_directory, hdbase, current_directory, system->slash); vars->mini_str = make_string((char*)vars->mini_buffer, 0, 512); - + // NOTE(allen): child proc list setup i32 max_children = 16; partition_align(partition, 8); @@ -3304,31 +3372,31 @@ App_Step_Sig(app_step){ ProfileStart(OS_syncing); Application_Step_Result app_result = *result; app_result.redraw = force_redraw; - + App_Vars *vars = (App_Vars*)memory->vars_memory; target->partition = &vars->mem.part; - + if (first_step || !time_step){ app_result.redraw = 1; } - + Panel *panels = vars->layout.panels; Panel *active_panel = &panels[vars->layout.active_panel]; - + // NOTE(allen): OS clipboard event handling if (clipboard.str){ String *dest = working_set_next_clipboard_string(&vars->mem.general, &vars->working_set, clipboard.size); dest->size = eol_convert_in(dest->str, clipboard.str, clipboard.size); } - + // TODO(allen): profile this make sure it's not costing me too much power. // NOTE(allen): check files are up to date for (i32 i = 0; i < vars->working_set.file_index_count; ++i){ Editing_File *file = vars->working_set.files + i; - + if (!file->state.is_dummy){ u64 time_stamp = system->file_time_stamp(make_c_str(file->name.source_path)); - + if (time_stamp > 0){ file->state.last_sys_write_time = time_stamp; if (file->state.last_sys_write_time != file->state.last_4ed_write_time){ @@ -3337,24 +3405,24 @@ App_Step_Sig(app_step){ } } } - + // NOTE(allen): update child processes if (time_step){ Temp_Memory temp = begin_temp_memory(&vars->mem.part); u32 max = Kbytes(32); char *dest = push_array(&vars->mem.part, char, max); u32 amount; - + i32 count = vars->cli_processes.count; for (i32 i = 0; i < count; ++i){ CLI_Process *proc = vars->cli_processes.procs + i; Editing_File *out_file = proc->out_file; - + if (out_file != 0){ i32 new_cursor = out_file->state.cursor_pos; for (system->cli_begin_update(&proc->cli); - system->cli_update_step(&proc->cli, dest, max, &amount);){ + system->cli_update_step(&proc->cli, dest, max, &amount);){ amount = eol_in_place_convert_in(dest, amount); Edit_Spec spec = {}; spec.step.type = ED_NORMAL; @@ -3365,11 +3433,11 @@ App_Step_Sig(app_step){ spec.step.post_pos = spec.step.edit.start + amount; spec.str = (u8*)dest; file_do_single_edit(system, &vars->mem, out_file, - &vars->layout, spec, hist_normal); + &vars->layout, spec, hist_normal); app_result.redraw = 1; new_cursor = spec.step.post_pos; } - + if (system->cli_end_update(&proc->cli)){ *proc = vars->cli_processes.procs[--count]; --i; @@ -3378,7 +3446,7 @@ App_Step_Sig(app_step){ String str = make_fixed_width_string(str_space); append(&str, "exited with code "); append_int_to_str(proc->cli.exit, &str); - + Edit_Spec spec = {}; spec.step.type = ED_NORMAL; spec.step.edit.start = buffer_size(&out_file->state.buffer); @@ -3388,11 +3456,11 @@ App_Step_Sig(app_step){ spec.step.post_pos = spec.step.edit.start + str.size; spec.str = (u8*)str.str; file_do_single_edit(system, &vars->mem, out_file, - &vars->layout, spec, hist_normal); + &vars->layout, spec, hist_normal); app_result.redraw = 1; new_cursor = spec.step.post_pos; } - + Panel *panel = vars->layout.panels; i32 panel_count = vars->layout.panel_count; for (i32 i = 0; i < panel_count; ++i, ++panel){ @@ -3405,24 +3473,24 @@ App_Step_Sig(app_step){ } } } - + vars->cli_processes.count = count; end_temp_memory(temp); } - + // NOTE(allen): reorganizing panels on screen i32 prev_width = vars->layout.full_width; i32 prev_height = vars->layout.full_height; i32 prev_y_off = 0; i32 prev_x_off = 0; - + i32 y_off = 0; i32 x_off = 0; i32 full_width = vars->layout.full_width = target->width; i32 full_height = vars->layout.full_height = target->height; - + if (prev_width != full_width || prev_height != full_height || - prev_x_off != x_off || prev_y_off != y_off){ + prev_x_off != x_off || prev_y_off != y_off){ layout_refit(&vars->layout, prev_x_off, prev_y_off, prev_width, prev_height); int view_count = vars->layout.panel_max_count; for (i32 view_i = 0; view_i < view_count; ++view_i){ @@ -3435,7 +3503,7 @@ App_Step_Sig(app_step){ } app_result.redraw = 1; } - + // NOTE(allen): prepare input information Key_Summary key_data = {}; for (i32 i = 0; i < input->press_count; ++i){ @@ -3444,11 +3512,11 @@ App_Step_Sig(app_step){ for (i32 i = 0; i < input->hold_count; ++i){ key_data.keys[key_data.count++] = input->hold[i]; } - + mouse->wheel = -mouse->wheel; - + ProfileEnd(OS_syncing); - + ProfileStart(hover_status); // NOTE(allen): detect mouse hover status i32 mx = mouse->x; @@ -3458,7 +3526,7 @@ App_Step_Sig(app_step){ Panel *mouse_panel = 0; i32 mouse_panel_i = 0; i32 panel_count = vars->layout.panel_count; - + mouse_panel = panels; for (mouse_panel_i = 0; mouse_panel_i < panel_count; ++mouse_panel_i, ++mouse_panel){ if (hit_check(mx, my, mouse_panel->inner)){ @@ -3470,17 +3538,17 @@ App_Step_Sig(app_step){ break; } } - + if (!(mouse_in_edit_area || mouse_in_margin_area)){ mouse_panel = 0; mouse_panel_i = 0; } - + b32 mouse_on_divider = 0; b32 mouse_divider_vertical = 0; i32 mouse_divider_id = 0; i32 mouse_divider_side = 0; - + if (mouse_in_margin_area){ Panel *panel = mouse_panel; if (mx >= panel->inner.x0 && mx < panel->inner.x1){ @@ -3501,20 +3569,20 @@ App_Step_Sig(app_step){ mouse_divider_side = 1; } } - + if (vars->layout.panel_count > 1){ i32 which_child; mouse_divider_id = panel->parent; which_child = panel->which_child; for (;;){ Divider_And_ID div = layout_get_divider(&vars->layout, mouse_divider_id); - + if (which_child == mouse_divider_side && - div.divider->v_divider == mouse_divider_vertical){ + div.divider->v_divider == mouse_divider_vertical){ mouse_on_divider = 1; break; } - + if (mouse_divider_id == vars->layout.root){ break; } @@ -3530,11 +3598,11 @@ App_Step_Sig(app_step){ } } ProfileEnd(hover_status); - + // NOTE(allen): prepare to start executing commands ProfileStart(command_coroutine); Command_Data *cmd = &vars->command_data; - + cmd->mem = &vars->mem; cmd->panel = active_panel; cmd->view = active_panel->view; @@ -3542,60 +3610,52 @@ App_Step_Sig(app_step){ cmd->layout = &vars->layout; cmd->live_set = &vars->live_set; cmd->style = &vars->style; - cmd->delay = &vars->delay; + cmd->delay = &vars->delay1; cmd->vars = vars; cmd->exchange = exchange; cmd->screen_width = target->width; cmd->screen_height = target->height; cmd->system = system; - + Temp_Memory param_stack_temp = begin_temp_memory(&vars->mem.part); cmd->part = partition_sub_part(&vars->mem.part, 16 << 10); - + if (first_step){ if (vars->hooks[hook_start]){ vars->hooks[hook_start](&app_links); cmd->part.pos = 0; } - + i32 i; String file_name; - File_View *fview; - Editing_File *file; Panel *panel = vars->layout.panels; for (i = 0; i < vars->settings.init_files_count; ++i, ++panel){ file_name = make_string_slowly(vars->settings.init_files[i]); - + if (i < vars->layout.panel_count){ - fview = app_open_file(system, vars, exchange, &vars->live_set, &vars->working_set, panel, cmd, file_name); - + delayed_open(&vars->delay1, file_name, panel); if (i == 0){ - if (fview){ - file = fview->file; - if (file){ - file->preload.start_line = vars->settings.initial_line; - } - } + delayed_set_line(&vars->delay1, panel, vars->settings.initial_line); } } else{ - app_open_file_background(vars, exchange, &vars->working_set, file_name); + delayed_open_background(&vars->delay1, file_name); } } } ProfileEnd(hover_status); - + // NOTE(allen): process the command_coroutine if it is unfinished ProfileStart(command_coroutine); b8 consumed_input[6] = {0}; - + if (vars->command_coroutine != 0){ Coroutine *command_coroutine = vars->command_coroutine; u32 get_flags = vars->command_coroutine_flags[0]; u32 abort_flags = vars->command_coroutine_flags[1]; - + get_flags |= abort_flags; - + if ((get_flags & EventOnAnyKey) || (get_flags & EventOnEsc)){ for (i32 key_i = 0; key_i < key_data.count; ++key_i){ Key_Event_Data key = get_single_key(&key_data, key_i); @@ -3613,14 +3673,14 @@ App_Step_Sig(app_step){ user_in.key = key; user_in.command = (unsigned long long)cmd_bind.custom; user_in.abort = 0; - + if ((EventOnEsc & abort_flags) && key.keycode == key_esc){ user_in.abort = 1; } else if (EventOnAnyKey & abort_flags){ user_in.abort = 1; } - + if (EventOnAnyKey & get_flags){ pass_in = 1; consumed_input[0] = 1; @@ -3631,16 +3691,16 @@ App_Step_Sig(app_step){ } consumed_input[1] = 1; } - + if (pass_in){ cmd->current_coroutine = vars->command_coroutine; - vars->command_coroutine = system->resume_coroutine(command_coroutine, &user_in, - vars->command_coroutine_flags); + vars->command_coroutine = system->resume_coroutine(command_coroutine, + &user_in, vars->command_coroutine_flags); app_result.redraw = 1; - + // TOOD(allen): Deduplicate - // TODO(allen): Allow a view to clean up however it wants after a command finishes, - // or after transfering to another view mid command. + // TODO(allen): Allow a view to clean up however it wants after a command + // finishes, or after transfering to another view mid command. File_View *fview = view_to_file_view(view); if (fview != 0 && vars->command_coroutine == 0){ init_query_set(&fview->query_set); @@ -3649,16 +3709,17 @@ App_Step_Sig(app_step){ } } } - + if (vars->command_coroutine != 0 && (get_flags & EventOnMouse)){ View *view = active_panel->view; b32 pass_in = 0; - + User_Input user_in; user_in.type = UserInputMouse; user_in.mouse = *mouse; + user_in.command = 0; user_in.abort = 0; - + if (abort_flags & EventOnMouseMove){ user_in.abort = 1; } @@ -3666,7 +3727,7 @@ App_Step_Sig(app_step){ pass_in = 1; consumed_input[2] = 1; } - + if (mouse->press_l || mouse->release_l || mouse->l){ if (abort_flags & EventOnLeftButton){ user_in.abort = 1; @@ -3676,7 +3737,7 @@ App_Step_Sig(app_step){ consumed_input[3] = 1; } } - + if (mouse->press_r || mouse->release_r || mouse->r){ if (abort_flags & EventOnRightButton){ user_in.abort = 1; @@ -3686,7 +3747,7 @@ App_Step_Sig(app_step){ consumed_input[4] = 1; } } - + if (mouse->wheel != 0){ if (abort_flags & EventOnWheel){ user_in.abort = 1; @@ -3696,7 +3757,7 @@ App_Step_Sig(app_step){ consumed_input[5] = 1; } } - + if (pass_in){ cmd->current_coroutine = vars->command_coroutine; vars->command_coroutine = system->resume_coroutine(command_coroutine, &user_in, @@ -3714,79 +3775,15 @@ App_Step_Sig(app_step){ } } ProfileEnd(command_coroutine); - - // NOTE(allen): command execution - ProfileStart(command); - - cmd->panel = active_panel; - cmd->view = active_panel->view; - - if (!consumed_input[0] || !consumed_input[1]){ - b32 consumed_input2[2] = {0}; - - for (i32 key_i = 0; key_i < key_data.count; ++key_i){ - switch (vars->state){ - case APP_STATE_EDIT: - { - Key_Event_Data key = get_single_key(&key_data, key_i); - b32 hit_esc = (key.keycode == key_esc); - cmd->key = key; - - if (hit_esc || !consumed_input[0]){ - if (hit_esc){ - consumed_input[0] = 1; - } - else{ - consumed_input[1] = 1; - } - - View *view = active_panel->view; - - Command_Map *map = 0; - if (view) map = view->map; - if (map == 0) map = &vars->map_top; - Command_Binding cmd_bind = map_extract_recursive(map, key); - - if (cmd_bind.function){ - Coroutine *command_coroutine = system->create_coroutine(command_caller); - vars->command_coroutine = command_coroutine; - Command_In cmd_in; - cmd_in.cmd = cmd; - cmd_in.bind = cmd_bind; - - cmd->current_coroutine = vars->command_coroutine; - vars->command_coroutine = system->launch_coroutine(vars->command_coroutine, - &cmd_in, vars->command_coroutine_flags); - app_result.redraw = 1; - } - } - }break; - - case APP_STATE_RESIZING: - { - if (key_data.count > 0){ - vars->state = APP_STATE_EDIT; - } - }break; - } - } - - consumed_input[0] |= consumed_input2[0]; - consumed_input[1] |= consumed_input2[1]; - } - - active_panel = panels + vars->layout.active_panel; - ProfileEnd(command); - // NOTE(allen): pass raw input to the panels ProfileStart(step); View *active_view = active_panel->view; - + Input_Summary dead_input = {}; dead_input.mouse.x = mouse->x; dead_input.mouse.y = mouse->y; - + Input_Summary active_input = {}; active_input.mouse.x = mouse->x; active_input.mouse.y = mouse->y; @@ -3803,25 +3800,25 @@ App_Step_Sig(app_step){ } } } - + Mouse_State mouse_state = *mouse; - + if (consumed_input[3]){ mouse_state.l = 0; mouse_state.press_l = 0; mouse_state.release_l = 0; } - + if (consumed_input[4]){ mouse_state.r = 0; mouse_state.press_r = 0; mouse_state.release_r = 0; } - + if (consumed_input[5]){ mouse_state.wheel = 0; } - + { Panel *panel = panels; for (i32 panel_i = vars->layout.panel_count; panel_i > 0; --panel_i, ++panel){ @@ -3834,111 +3831,176 @@ App_Step_Sig(app_step){ input.mouse = mouse_state; } if (view_->do_view(system, exchange, view_, panel->inner, active_view, - VMSG_STEP, 0, &input, &active_input)){ + VMSG_STEP, 0, &input, &active_input)){ app_result.redraw = 1; } } } } ProfileEnd(step); - + + // NOTE(allen): command execution + ProfileStart(command); + + cmd->panel = active_panel; + cmd->view = active_panel->view; + + if (!consumed_input[0] || !consumed_input[1]){ + b32 consumed_input2[2] = {0}; + + for (i32 key_i = 0; key_i < key_data.count; ++key_i){ + switch (vars->state){ + case APP_STATE_EDIT: + { + Key_Event_Data key = get_single_key(&key_data, key_i); + b32 hit_esc = (key.keycode == key_esc); + cmd->key = key; + + if (hit_esc || !consumed_input[0]){ + View *view = active_panel->view; + + Command_Map *map = 0; + if (view) map = view->map; + if (map == 0) map = &vars->map_top; + Command_Binding cmd_bind = map_extract_recursive(map, key); + + if (cmd_bind.function){ + if (hit_esc){ + consumed_input2[1] = 1; + } + else{ + consumed_input2[0] = 1; + } + + Coroutine *command_coroutine = system->create_coroutine(command_caller); + vars->command_coroutine = command_coroutine; + + Command_In cmd_in; + cmd_in.cmd = cmd; + cmd_in.bind = cmd_bind; + + cmd->current_coroutine = vars->command_coroutine; + vars->command_coroutine = system->launch_coroutine(vars->command_coroutine, + &cmd_in, vars->command_coroutine_flags); + vars->prev_command = cmd_bind; + app_result.redraw = 1; + } + } + }break; + + case APP_STATE_RESIZING: + { + if (key_data.count > 0){ + vars->state = APP_STATE_EDIT; + } + }break; + } + } + + consumed_input[0] |= consumed_input2[0]; + consumed_input[1] |= consumed_input2[1]; + } + + active_panel = panels + vars->layout.active_panel; + ProfileEnd(command); + ProfileStart(resizing); // NOTE(allen): panel resizing switch (vars->state){ - case APP_STATE_EDIT: - { - if (mouse->press_l && mouse_on_divider){ - vars->state = APP_STATE_RESIZING; - Divider_And_ID div = layout_get_divider(&vars->layout, mouse_divider_id); - vars->resizing.divider = div.divider; - - i32 min, max; - { - i32 mid, MIN, MAX; - mid = div.divider->pos; - if (mouse_divider_vertical){ - MIN = 0; - MAX = MIN + vars->layout.full_width; + case APP_STATE_EDIT: + { + if (mouse->press_l && mouse_on_divider){ + vars->state = APP_STATE_RESIZING; + Divider_And_ID div = layout_get_divider(&vars->layout, mouse_divider_id); + vars->resizing.divider = div.divider; + + i32 min, max; + { + i32 mid, MIN, MAX; + mid = div.divider->pos; + if (mouse_divider_vertical){ + MIN = 0; + MAX = MIN + vars->layout.full_width; + } + else{ + MIN = 0; + MAX = MIN + vars->layout.full_height; + } + min = MIN; + max = MAX; + + i32 divider_id = div.id; + do{ + Divider_And_ID other_div = layout_get_divider(&vars->layout, divider_id); + b32 divider_match = (other_div.divider->v_divider == mouse_divider_vertical); + i32 pos = other_div.divider->pos; + if (divider_match && pos > mid && pos < max){ + max = pos; + } + else if (divider_match && pos < mid && pos > min){ + min = pos; + } + divider_id = other_div.divider->parent; + }while(divider_id != -1); + + Temp_Memory temp = begin_temp_memory(&vars->mem.part); + i32 *divider_stack = push_array(&vars->mem.part, i32, vars->layout.panel_count); + i32 top = 0; + divider_stack[top++] = div.id; + + while (top > 0){ + Divider_And_ID other_div = layout_get_divider(&vars->layout, divider_stack[--top]); + b32 divider_match = (other_div.divider->v_divider == mouse_divider_vertical); + i32 pos = other_div.divider->pos; + if (divider_match && pos > mid && pos < max){ + max = pos; + } + else if (divider_match && pos < mid && pos > min){ + min = pos; + } + if (other_div.divider->child1 != -1){ + divider_stack[top++] = other_div.divider->child1; + } + if (other_div.divider->child2 != -1){ + divider_stack[top++] = other_div.divider->child2; + } + } + + end_temp_memory(temp); + } + + vars->resizing.min = min; + vars->resizing.max = max; + } + }break; + + case APP_STATE_RESIZING: + { + app_result.redraw = 1; + if (mouse->l){ + Panel_Divider *divider = vars->resizing.divider; + if (divider->v_divider){ + divider->pos = mx; } else{ - MIN = 0; - MAX = MIN + vars->layout.full_height; + divider->pos = my; } - min = MIN; - max = MAX; - - i32 divider_id = div.id; - do{ - Divider_And_ID other_div = layout_get_divider(&vars->layout, divider_id); - b32 divider_match = (other_div.divider->v_divider == mouse_divider_vertical); - i32 pos = other_div.divider->pos; - if (divider_match && pos > mid && pos < max){ - max = pos; - } - else if (divider_match && pos < mid && pos > min){ - min = pos; - } - divider_id = other_div.divider->parent; - }while(divider_id != -1); - - Temp_Memory temp = begin_temp_memory(&vars->mem.part); - i32 *divider_stack = push_array(&vars->mem.part, i32, vars->layout.panel_count); - i32 top = 0; - divider_stack[top++] = div.id; - - while (top > 0){ - Divider_And_ID other_div = layout_get_divider(&vars->layout, divider_stack[--top]); - b32 divider_match = (other_div.divider->v_divider == mouse_divider_vertical); - i32 pos = other_div.divider->pos; - if (divider_match && pos > mid && pos < max){ - max = pos; - } - else if (divider_match && pos < mid && pos > min){ - min = pos; - } - if (other_div.divider->child1 != -1){ - divider_stack[top++] = other_div.divider->child1; - } - if (other_div.divider->child2 != -1){ - divider_stack[top++] = other_div.divider->child2; - } + + if (divider->pos < vars->resizing.min){ + divider->pos = vars->resizing.min; } - - end_temp_memory(temp); - } - - vars->resizing.min = min; - vars->resizing.max = max; - } - }break; - - case APP_STATE_RESIZING: - { - app_result.redraw = 1; - if (mouse->l){ - Panel_Divider *divider = vars->resizing.divider; - if (divider->v_divider){ - divider->pos = mx; + else if (divider->pos > vars->resizing.max){ + divider->pos = vars->resizing.max - 1; + } + + layout_fix_all_panels(&vars->layout); } else{ - divider->pos = my; + vars->state = APP_STATE_EDIT; } - - if (divider->pos < vars->resizing.min){ - divider->pos = vars->resizing.min; - } - else if (divider->pos > vars->resizing.max){ - divider->pos = vars->resizing.max - 1; - } - - layout_fix_all_panels(&vars->layout); - } - else{ - vars->state = APP_STATE_EDIT; - } - }break; + }break; } - + if (mouse_in_edit_area && mouse_panel != 0 && mouse->press_l){ active_panel = mouse_panel; vars->layout.active_panel = mouse_panel_i; @@ -3946,238 +4008,22 @@ App_Step_Sig(app_step){ } ProfileEnd(resizing); - // NOTE(allen): process as many delayed actions as possible - ProfileStart(delayed_actions); - if (vars->delay.count > 0){ - Style *style = &vars->style; - Working_Set *working_set = &vars->working_set; - Live_Views *live_set = &vars->live_set; - Mem_Options *mem = &vars->mem; - General_Memory *general = &vars->mem.general; - - i32 count = vars->delay.count; - vars->delay.count = 0; - - for (i32 i = 0; i < count; ++i){ - Delayed_Action *act = vars->delay.acts + i; - String *string = &act->string; - Panel *panel = act->panel; - Editing_File *file = act->file; - - switch (act->type){ - case DACT_OPEN: - { - cmd->view = (View*) - app_open_file(system, vars, exchange, - live_set, working_set, panel, - cmd, *string); - }break; - - case DACT_SAVE_AS: - { - if (!file){ - View *view = panel->view; - File_View *fview = view_to_file_view(view); - - if (!fview && view->is_minor) fview = view_to_file_view(view->major); - - if (fview){ - file = working_set_lookup_file(working_set, *string); - } - } - if (file && !file->state.is_dummy){ - i32 sys_id = file_save_and_set_names(system, exchange, mem, working_set, file, string->str); - app_push_file_binding(vars, sys_id, get_file_id(working_set, file)); - } - }break; - - case DACT_SAVE: - { - if (!file){ - file = working_set_lookup_file(working_set, *string); - } - if (!file->state.is_dummy && buffer_needs_save(file)){ - i32 sys_id = file_save(system, exchange, mem, file, file->name.source_path.str); - app_push_file_binding(vars, sys_id, get_file_id(working_set, file)); - } - }break; - - case DACT_NEW: - { - Get_File_Result file = working_set_get_available_file(working_set); - file_create_empty(system, mem, working_set, file.file, string->str, - vars->font_set, style->font_id); - table_add(&working_set->table, file.file->name.source_path, file.index); - - View *new_view = live_set_alloc_view(live_set, mem); - view_replace_major(system, exchange, new_view, panel, live_set); - - File_View *file_view = file_view_init(new_view, &vars->layout); - cmd->view = (View*)file_view; - view_set_file(system, file_view, file.file, vars->font_set, style, - vars->hooks[hook_open_file], cmd, &app_links); - new_view->map = app_get_map(vars, file.file->settings.base_map_id); -#if BUFFER_EXPERIMENT_SCALPEL <= 0 - if (file.file->settings.tokens_exist) - file_first_lex_parallel(system, general, file.file); -#endif - }break; - - case DACT_SWITCH: - { - Editing_File *file = working_set_lookup_file(working_set, *string); - if (file){ - View *new_view = live_set_alloc_view(live_set, mem); - view_replace_major(system, exchange, new_view, panel, live_set); - - File_View *file_view = file_view_init(new_view, &vars->layout); - cmd->view = (View*)file_view; - - view_set_file(system, file_view, file, vars->font_set, style, - vars->hooks[hook_open_file], cmd, &app_links); - - new_view->map = app_get_map(vars, file->settings.base_map_id); - } - }break; - - case DACT_KILL: - { - Editing_File *file = working_set_lookup_file(working_set, *string); - if (file){ - table_remove(&working_set->table, file->name.source_path); - kill_file(system, exchange, general, file, live_set, &vars->layout); - } - }break; - - case DACT_TRY_KILL: - { - Editing_File *file = working_set_lookup_file(working_set, *string); - if (file){ - if (buffer_needs_save(file)){ - View *new_view = live_set_alloc_view(live_set, mem); - view_replace_minor(system, exchange, new_view, panel, live_set); - - new_view->map = &vars->map_ui; - Interactive_View *int_view = - interactive_view_init(system, new_view, &vars->hot_directory, style, - working_set, vars->font_set, &vars->delay); - int_view->interaction = INTV_SURE_TO_KILL_INTER; - int_view->action = INTV_SURE_TO_KILL; - copy(&int_view->query, "Are you sure?"); - copy(&int_view->dest, file->name.live_name); - } - else{ - table_remove(&working_set->table, file->name.source_path); - kill_file(system, exchange, general, file, live_set, &vars->layout); - view_remove_minor(system, exchange, panel, live_set); - } - } - }break; - - case DACT_CLOSE_MINOR: - { - view_remove_minor(system, exchange, panel, live_set); - }break; - - case DACT_CLOSE_MAJOR: - { - view_remove_major(system, exchange, panel, live_set); - }break; - - case DACT_THEME_OPTIONS: - { - open_theme_options(system, exchange, vars, live_set, mem, panel); - }break; - - case DACT_KEYBOARD_OPTIONS: - { - open_config_options(system, exchange, vars, live_set, mem, panel); - }break; - } - } - } - ProfileEnd(delayed_actions); - - end_temp_memory(param_stack_temp); - - ProfileStart(resize); - // NOTE(allen): send resize messages to panels that have changed size - { - Panel *panel = panels; - for (i32 panel_i = vars->layout.panel_count; panel_i > 0; --panel_i, ++panel){ - i32_Rect prev = panel->prev_inner; - i32_Rect inner = panel->inner; - if (prev.x0 != inner.x0 || prev.y0 != inner.y0 || - prev.x1 != inner.x1 || prev.y1 != inner.y1){ - View *view = panel->view; - if (view){ - view->do_view(system, exchange, - view, inner, active_view, - VMSG_RESIZE, 0, &dead_input, &active_input); - view = (view->is_minor)?view->major:0; - if (view){ - view->do_view(system, exchange, - view, inner, active_view, - VMSG_RESIZE, 0, &dead_input, &active_input); - } - } - } - panel->prev_inner = inner; - } - } - ProfileEnd(resize); - - ProfileStart(style_change); - // NOTE(allen): send style change messages if the style has changed - if (vars->style.font_changed){ - vars->style.font_changed = 0; - - Editing_File *file = vars->working_set.files; - for (i32 i = vars->working_set.file_index_count; i > 0; --i, ++file){ - if (buffer_good(&file->state.buffer) && !file->state.is_dummy){ - Render_Font *font = get_font_info(vars->font_set, vars->style.font_id)->font; - float *advance_data = 0; - if (font) advance_data = font->advance_data; - - file_measure_starts_widths(system, &vars->mem.general, - &file->state.buffer, advance_data); - } - } - - Panel *panel = panels; - for (i32 panel_i = vars->layout.panel_count; panel_i > 0; --panel_i, ++panel){ - View *view = panel->view; - if (view){ - view->do_view(system, exchange, - view, panel->inner, active_view, - VMSG_STYLE_CHANGE, 0, &dead_input, &active_input); - view = (view->is_minor)?view->major:0; - if (view){ - view->do_view(system, exchange, - view, panel->inner, active_view, - VMSG_STYLE_CHANGE, 0, &dead_input, &active_input); - } - } - } - } - ProfileEnd(style_change); - - // NOTE(allen): processing bindings between system and application + // NOTE(allen): processing sys app bindings ProfileStart(sys_app_bind_processing); for (i32 i = 0; i < vars->sys_app_count; ++i){ Sys_App_Binding *binding; b32 remove = 0; b32 failed = 0; binding = vars->sys_app_bindings + i; - + byte *data; i32 size, max; Editing_File *ed_file; Editing_File_Preload preload_settings; char *filename; - + Working_Set *working_set = &vars->working_set; - + if (exchange_file_ready(exchange, binding->sys_id, &data, &size, &max)){ ed_file = working_set->files + binding->app_id; filename = exchange_file_filename(exchange, binding->sys_id); @@ -4185,21 +4031,41 @@ App_Step_Sig(app_step){ if (data){ String val = make_string((char*)data, size); file_create_from_string(system, &vars->mem, working_set, ed_file, filename, - vars->font_set, vars->style.font_id, val); - - if (ed_file->settings.tokens_exist) + vars->font_set, vars->style.font_id, val); + + if (ed_file->settings.tokens_exist){ file_first_lex_parallel(system, &vars->mem.general, ed_file); + } + + if ((binding->success & SysAppCreateView) && binding->panel != 0){ + view_file_in_panel(cmd, binding->panel, ed_file); + } + + app_result.redraw = 1; } else{ - file_create_empty(system, &vars->mem, working_set, ed_file, filename, - vars->font_set, vars->style.font_id); + if (binding->fail & SysAppCreateNewBuffer){ + file_create_empty(system, &vars->mem, working_set, ed_file, filename, + vars->font_set, vars->style.font_id); + if (binding->fail & SysAppCreateView){ + view_file_in_panel(cmd, binding->panel, ed_file); + } + } + else{ + table_remove(&vars->working_set.table, ed_file->name.source_path); + file_get_dummy(ed_file); + } + + app_result.redraw = 1; } - - for (File_View_Iter iter = file_view_iter_init(&vars->layout, ed_file, 0); - file_view_iter_good(iter); - iter = file_view_iter_next(iter)){ - view_file_loaded_init(system, iter.view, 0); - view_cursor_move(iter.view, preload_settings.start_line, 0); + + if (!ed_file->state.is_dummy){ + for (File_View_Iter iter = file_view_iter_init(&vars->layout, ed_file, 0); + file_view_iter_good(iter); + iter = file_view_iter_next(iter)){ + view_file_loaded_init(system, iter.view, 0); + view_cursor_move(iter.view, preload_settings.start_line, 0); + } } exchange_free_file(exchange, binding->sys_id); @@ -4232,6 +4098,305 @@ App_Step_Sig(app_step){ } ProfileEnd(sys_app_bind_processing); + // NOTE(allen): process as many delayed actions as possible + ProfileStart(delayed_actions); + if (vars->delay1.count > 0){ + Style *style = &vars->style; + Working_Set *working_set = &vars->working_set; + Live_Views *live_set = &vars->live_set; + Mem_Options *mem = &vars->mem; + General_Memory *general = &vars->mem.general; + + i32 count = vars->delay1.count; + vars->delay1.count = 0; + vars->delay2.count = 0; + + Delayed_Action *act = vars->delay1.acts; + for (i32 i = 0; i < count; ++i, ++act){ + String string = act->string; + Panel *panel = act->panel; + Editing_File *file = act->file; + i32 integer = act->integer; + + // TODO(allen): Paramter checking in each DACT case. + switch (act->type){ + case DACT_OPEN: + { + App_Open_File_Result result; + + result = app_open_file_background(vars, exchange, working_set, string); + + if (result.is_new){ + if (result.file){ + if (result.sys_id){ + Sys_App_Binding *binding = app_push_file_binding(vars, result.sys_id, result.file_index); + binding->success = SysAppCreateView; + binding->fail = 0; + binding->panel = panel; + } + else{ + delayed_action_repush(&vars->delay2, act); + } + } + } + else{ + if (result.file->state.is_dummy || result.file->state.is_loading){ + // do nothing + } + else{ + view_file_in_panel(cmd, panel, result.file); + } + } + }break; + + case DACT_OPEN_BACKGROUND: + { + App_Open_File_Result result; + result = app_open_file_background(vars, exchange, working_set, string); + if (result.is_new && result.file == 0){ + delayed_action_repush(&vars->delay2, act); + } + else{ + Sys_App_Binding *binding = app_push_file_binding(vars, result.sys_id, result.file_index); + binding->success = 0; + binding->fail = 0; + binding->panel = panel; + } + }break; + + case DACT_SET_LINE: + { + // TODO(allen): deduplicate + View *view = panel->view; + File_View *fview = view_to_file_view(view); + if (!file){ + if (!fview && view->is_minor) fview = view_to_file_view(view->major); + if (fview){ + file = working_set_lookup_file(working_set, string); + } + } + if (file && !file->state.is_dummy){ + if (file->state.is_loading){ + file->preload.start_line = integer; + } + else{ + view_cursor_move(fview, integer, 0); + } + } + }break; + + case DACT_SAVE_AS: + { + // TODO(allen): deduplicate + View *view = panel->view; + File_View *fview = view_to_file_view(view); + if (!file){ + if (!fview && view->is_minor) fview = view_to_file_view(view->major); + if (fview){ + file = working_set_lookup_file(working_set, string); + } + } + if (file && !file->state.is_dummy){ + i32 sys_id = file_save_and_set_names(system, exchange, mem, working_set, file, string.str); + if (sys_id){ + app_push_file_binding(vars, sys_id, get_file_id(working_set, file)); + } + else{ + delayed_action_repush(&vars->delay2, act); + } + } + }break; + + case DACT_SAVE: + { + if (!file){ + if (panel){ + View *view = panel->view; + File_View *fview = view_to_file_view(view); + if (fview){ + file = fview->file; + } + } + else{ + file = working_set_lookup_file(working_set, string); + } + } + if (!file->state.is_dummy && buffer_needs_save(file)){ + i32 sys_id = file_save(system, exchange, mem, file, file->name.source_path.str); + if (sys_id){ + app_push_file_binding(vars, sys_id, get_file_id(working_set, file)); + } + else{ + delayed_action_repush(&vars->delay2, act); + } + } + }break; + + case DACT_NEW: + { + Get_File_Result file = working_set_get_available_file(working_set); + file_create_empty(system, mem, working_set, file.file, string.str, + vars->font_set, style->font_id); + table_add(&working_set->table, file.file->name.source_path, file.index); + + View *new_view = live_set_alloc_view(live_set, mem); + view_replace_major(system, exchange, new_view, panel, live_set); + + File_View *file_view = file_view_init(new_view, &vars->layout); + cmd->view = (View*)file_view; + view_set_file(system, file_view, file.file, vars->font_set, style, + vars->hooks[hook_open_file], cmd, &app_links); + new_view->map = app_get_map(vars, file.file->settings.base_map_id); +#if BUFFER_EXPERIMENT_SCALPEL <= 0 + if (file.file->settings.tokens_exist) + file_first_lex_parallel(system, general, file.file); +#endif + }break; + + case DACT_SWITCH: + { + Editing_File *file = working_set_lookup_file(working_set, string); + if (file){ + View *new_view = live_set_alloc_view(live_set, mem); + view_replace_major(system, exchange, new_view, panel, live_set); + + File_View *file_view = file_view_init(new_view, &vars->layout); + cmd->view = (View*)file_view; + + view_set_file(system, file_view, file, vars->font_set, style, + vars->hooks[hook_open_file], cmd, &app_links); + + new_view->map = app_get_map(vars, file->settings.base_map_id); + } + }break; + + case DACT_KILL: + { + Editing_File *file = working_set_lookup_file(working_set, string); + if (file){ + table_remove(&working_set->table, file->name.source_path); + kill_file(system, exchange, general, file, live_set, &vars->layout); + } + }break; + + case DACT_TRY_KILL: + { + Editing_File *file = working_set_lookup_file(working_set, string); + if (file){ + if (buffer_needs_save(file)){ + View *new_view = live_set_alloc_view(live_set, mem); + view_replace_minor(system, exchange, new_view, panel, live_set); + + new_view->map = &vars->map_ui; + Interactive_View *int_view = + interactive_view_init(system, new_view, &vars->hot_directory, style, + working_set, vars->font_set, &vars->delay1); + int_view->interaction = INTV_SURE_TO_KILL_INTER; + int_view->action = INTV_SURE_TO_KILL; + copy(&int_view->query, "Are you sure?"); + copy(&int_view->dest, file->name.live_name); + } + else{ + table_remove(&working_set->table, file->name.source_path); + kill_file(system, exchange, general, file, live_set, &vars->layout); + view_remove_minor(system, exchange, panel, live_set); + } + } + }break; + + case DACT_CLOSE_MINOR: + { + view_remove_minor(system, exchange, panel, live_set); + }break; + + case DACT_CLOSE_MAJOR: + { + view_remove_major(system, exchange, panel, live_set); + }break; + + case DACT_THEME_OPTIONS: + { + open_theme_options(system, exchange, vars, live_set, mem, panel); + }break; + + case DACT_KEYBOARD_OPTIONS: + { + open_config_options(system, exchange, vars, live_set, mem, panel); + }break; + } + + if (string.str){ + general_memory_free(&mem->general, string.str); + } + } + Swap(vars->delay1, vars->delay2); + } + ProfileEnd(delayed_actions); + + end_temp_memory(param_stack_temp); + + ProfileStart(resize); + // NOTE(allen): send resize messages to panels that have changed size + { + Panel *panel = panels; + for (i32 panel_i = vars->layout.panel_count; panel_i > 0; --panel_i, ++panel){ + i32_Rect prev = panel->prev_inner; + i32_Rect inner = panel->inner; + if (prev.x0 != inner.x0 || prev.y0 != inner.y0 || + prev.x1 != inner.x1 || prev.y1 != inner.y1){ + View *view = panel->view; + if (view){ + view->do_view(system, exchange, + view, inner, active_view, + VMSG_RESIZE, 0, &dead_input, &active_input); + view = (view->is_minor)?view->major:0; + if (view){ + view->do_view(system, exchange, + view, inner, active_view, + VMSG_RESIZE, 0, &dead_input, &active_input); + } + } + } + panel->prev_inner = inner; + } + } + ProfileEnd(resize); + + ProfileStart(style_change); + // NOTE(allen): send style change messages if the style has changed + if (vars->style.font_changed){ + vars->style.font_changed = 0; + + Editing_File *file = vars->working_set.files; + for (i32 i = vars->working_set.file_index_count; i > 0; --i, ++file){ + if (buffer_good(&file->state.buffer) && !file->state.is_dummy){ + Render_Font *font = get_font_info(vars->font_set, vars->style.font_id)->font; + float *advance_data = 0; + if (font) advance_data = font->advance_data; + + file_measure_starts_widths(system, &vars->mem.general, + &file->state.buffer, advance_data); + } + } + + Panel *panel = panels; + for (i32 panel_i = vars->layout.panel_count; panel_i > 0; --panel_i, ++panel){ + View *view = panel->view; + if (view){ + view->do_view(system, exchange, + view, panel->inner, active_view, + VMSG_STYLE_CHANGE, 0, &dead_input, &active_input); + view = (view->is_minor)?view->major:0; + if (view){ + view->do_view(system, exchange, + view, panel->inner, active_view, + VMSG_STYLE_CHANGE, 0, &dead_input, &active_input); + } + } + } + } + ProfileEnd(style_change); + ProfileStart(redraw); if (mouse_panel != vars->prev_mouse_panel) app_result.redraw = 1; if (app_result.redraw){ diff --git a/4ed.h b/4ed.h index 2f178dbe..ab05756e 100644 --- a/4ed.h +++ b/4ed.h @@ -17,6 +17,8 @@ struct Application_Memory{ i32 vars_memory_size; void *target_memory; i32 target_memory_size; + void *user_memory; + i32 user_memory_size; }; #define KEY_INPUT_BUFFER_SIZE 4 diff --git a/4ed_color_view.cpp b/4ed_color_view.cpp index d6b3601c..fd604225 100644 --- a/4ed_color_view.cpp +++ b/4ed_color_view.cpp @@ -1510,7 +1510,7 @@ do_file_list_box(System_Functions *system, UI_State *state, UI_Layout *layout, b8 is_folder = (info->folder != 0); b8 ext_match = (match(file_extension(filename), p4c_extension) != 0); b8 name_match = (filename_match(front_name, &absolutes, filename, case_sensitive) != 0); - b8 is_loaded = (file != 0); + b8 is_loaded = (file != 0 && file_is_ready(file)); String message = message_nothing; if (is_loaded){ diff --git a/4ed_delay.cpp b/4ed_delay.cpp index cddd049d..45e3e87d 100644 --- a/4ed_delay.cpp +++ b/4ed_delay.cpp @@ -1,5 +1,7 @@ enum Action_Type{ DACT_OPEN, + DACT_OPEN_BACKGROUND, + DACT_SET_LINE, DACT_SAVE_AS, DACT_SAVE, DACT_NEW, @@ -17,18 +19,33 @@ struct Delayed_Action{ String string; Panel* panel; Editing_File* file; + i32 integer; }; struct Delay{ + General_Memory* general; Delayed_Action* acts; i32 count; i32 max; }; +internal String +str_alloc_copy(General_Memory *general, String str){ + String result; + result.memory_size = str.memory_size + 1; + result.size = str.size; + result.str = (char*)general_memory_allocate(general, result.memory_size, 0); + memcpy(result.str, str.str, str.size); + result.str[result.size] = 0; + return(result);} + inline Delayed_Action* delayed_action_(Delay *delay, Action_Type type){ Delayed_Action *result; - Assert(delay->count < delay->max); + if (delay->count == delay->max){ + delay->max *= 2; + delay->acts = (Delayed_Action*)general_memory_reallocate(delay->general, delay->acts, delay->count*sizeof(Delayed_Action), delay->max*sizeof(Delayed_Action), 0); + } result = delay->acts + delay->count++; *result = {}; result->type = type; @@ -43,11 +60,19 @@ delayed_action_(Delay *delay, Action_Type type, Panel* panel){ return(result); } +inline Delayed_Action* +delayed_action_(Delay *delay, Action_Type type, String string){ + Delayed_Action *result; + result = delayed_action_(delay, type); + result->string = str_alloc_copy(delay->general, string); + return(result); +} + inline Delayed_Action* delayed_action_(Delay *delay, Action_Type type, String string, Panel* panel){ Delayed_Action *result; result = delayed_action_(delay, type); - result->string = string; + result->string = str_alloc_copy(delay->general, string); result->panel = panel; return(result); } @@ -56,12 +81,33 @@ inline Delayed_Action* delayed_action_(Delay *delay, Action_Type type, String string, Editing_File* file){ Delayed_Action *result; result = delayed_action_(delay, type); - result->string = string; + result->string = str_alloc_copy(delay->general, string); result->file = file; return(result); } +inline Delayed_Action* +delayed_action_(Delay *delay, Action_Type type, Panel* panel, i32 integer){ + Delayed_Action *result; + result = delayed_action_(delay, type); + result->panel = panel; + result->integer = integer; + return(result); +} + +inline Delayed_Action* +delayed_action_repush(Delay *delay, Delayed_Action *act){ + Delayed_Action *new_act = delayed_action_(delay, (Action_Type)0); + *new_act = *act; + if (act->string.str){ + new_act->string = str_alloc_copy(delay->general, act->string); + } + return(new_act); +} + #define delayed_open(delay, ...) delayed_action_(delay, DACT_OPEN, __VA_ARGS__) +#define delayed_open_background(delay, ...) delayed_action_(delay, DACT_OPEN_BACKGROUND, __VA_ARGS__) +#define delayed_set_line(delay, ...) delayed_action_(delay, DACT_SET_LINE, __VA_ARGS__) #define delayed_save_as(delay, ...) delayed_action_(delay, DACT_SAVE_AS, __VA_ARGS__) #define delayed_save(delay, ...) delayed_action_(delay, DACT_SAVE, __VA_ARGS__) #define delayed_new(delay, ...) delayed_action_(delay, DACT_NEW, __VA_ARGS__) diff --git a/4ed_exchange.cpp b/4ed_exchange.cpp index 06c9d696..7908cace 100644 --- a/4ed_exchange.cpp +++ b/4ed_exchange.cpp @@ -198,7 +198,6 @@ exchange_free_file(Exchange *exchange, i32 file_id){ ex__file_remove(file); ex__file_insert(&files->free_list, file); ex__check(files); - --files->num_active; } } diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index 06de587b..7926f7b7 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -31,8 +31,8 @@ struct File_View_Widget{ File_View_Widget_Type type; i32 height; struct{ - bool32 undo_line; - bool32 history_line; + b32 undo_line; + b32 history_line; } timeline; }; @@ -208,36 +208,33 @@ file_save(System_Functions *system, Exchange *exchange, Mem_Options *mem, Editing_File *file, char *filename){ i32 result = 0; -#if BUFFER_EXPERIMENT_SCALPEL <= 3 i32 max, size; - byte *data; b32 dos_write_mode = file->settings.dos_write_mode; - - if (dos_write_mode) - max = buffer_size(&file->state.buffer) + file->state.buffer.line_count + 1; - else - max = buffer_size(&file->state.buffer); + char *data; + Buffer_Type *buffer = &file->state.buffer; - data = (byte*)general_memory_allocate(&mem->general, max, 0); + if (dos_write_mode) + max = buffer_size(buffer) + buffer->line_count + 1; + else + max = buffer_size(buffer); + + data = (char*)general_memory_allocate(&mem->general, max, 0); Assert(data); if (dos_write_mode) - size = buffer_convert_out(&file->state.buffer, (char*)data, max); + size = buffer_convert_out(buffer, data, max); else - buffer_stringify(&file->state.buffer, 0, size = max, (char*)data); + buffer_stringify(buffer, 0, size = max, data); - i32 filename_len = str_size(filename); - result = exchange_save_file(exchange, filename, filename_len, - data, size, max); + result = exchange_save_file(exchange, filename, str_size(filename), (byte*)data, size, max); if (result == 0){ general_memory_free(&mem->general, data); } file_synchronize_times(system, file, filename); -#endif - return result; + return(result); } inline b32 @@ -270,28 +267,41 @@ enum File_Bubble_Type{ #define GROW_SUCCESS 2 internal i32 -file_grow_starts_as_needed(General_Memory *general, Buffer_Type *buffer, i32 additional_lines){ - bool32 result = GROW_NOT_NEEDED; -#if BUFFER_EXPERIMENT_SCALPEL <= 3 +file_grow_starts_widths_as_needed(General_Memory *general, Buffer_Type *buffer, i32 additional_lines){ + b32 result = GROW_NOT_NEEDED; i32 max = buffer->line_max; i32 count = buffer->line_count; i32 target_lines = count + additional_lines; + Assert(max == buffer->widths_max); + if (target_lines > max || max == 0){ max = LargeRoundUp(target_lines + max, Kbytes(1)); - i32 *new_lines = (i32*) - general_memory_reallocate(general, buffer->line_starts, - sizeof(i32)*count, sizeof(i32)*max, BUBBLE_STARTS); + + f32 *new_widths = (f32*)general_memory_reallocate( + general, buffer->line_widths, + sizeof(f32)*count, sizeof(f32)*max, BUBBLE_WIDTHS); + + i32 *new_lines = (i32*)general_memory_reallocate( + general, buffer->line_starts, + sizeof(i32)*count, sizeof(i32)*max, BUBBLE_STARTS); + if (new_lines){ buffer->line_starts = new_lines; buffer->line_max = max; + } + if (new_widths){ + buffer->line_widths = new_widths; + buffer->widths_max = max; + } + if (new_lines && new_widths){ result = GROW_SUCCESS; } else{ result = GROW_FAILED; } } -#endif - return result; + + return(result); } internal void @@ -345,16 +355,14 @@ file_measure_starts_widths(System_Functions *system, General_Memory *general, } internal void -file_remeasure_starts(System_Functions *system, +file_remeasure_starts_(System_Functions *system, General_Memory *general, Buffer_Type *buffer, i32 line_start, i32 line_end, i32 line_shift, i32 character_shift){ -#if BUFFER_EXPERIMENT_SCALPEL <= 3 ProfileMomentFunction(); Assert(buffer->line_starts); - file_grow_starts_as_needed(general, buffer, line_shift); + file_grow_starts_widths_as_needed(general, buffer, line_shift); buffer_remeasure_starts(buffer, line_start, line_end, line_shift, character_shift); -#endif } struct Opaque_Font_Advance{ @@ -370,9 +378,9 @@ get_opaque_font_advance(Render_Font *font){ return result; } +#if 0 internal void file_grow_widths_as_needed(General_Memory *general, Buffer_Type *buffer){ -#if BUFFER_EXPERIMENT_SCALPEL <= 3 i32 line_count = buffer->line_count; if (line_count > buffer->widths_max || buffer->widths_max == 0){ i32 new_max = LargeRoundUp(line_count, Kbytes(1)); @@ -388,18 +396,16 @@ file_grow_widths_as_needed(General_Memory *general, Buffer_Type *buffer){ } buffer->widths_max = new_max; } -#endif } +#endif internal void -file_remeasure_widths(System_Functions *system, +file_remeasure_widths_(System_Functions *system, General_Memory *general, Buffer_Type *buffer, Render_Font *font, i32 line_start, i32 line_end, i32 line_shift){ -#if BUFFER_EXPERIMENT_SCALPEL <= 3 ProfileMomentFunction(); - file_grow_widths_as_needed(general, buffer); + file_grow_starts_widths_as_needed(general, buffer, line_shift); buffer_remeasure_widths(buffer, font->advance_data, line_start, line_end, line_shift); -#endif } inline i32 @@ -1806,20 +1812,18 @@ file_do_single_edit(System_Functions *system, if (old_data) general_memory_free(general, old_data); } + Buffer_Type *buffer = &file->state.buffer; i32 line_start = buffer_get_line_index(&file->state.buffer, start); i32 line_end = buffer_get_line_index(&file->state.buffer, end); i32 replaced_line_count = line_end - line_start; i32 new_line_count = buffer_count_newlines(&file->state.buffer, start, start+str_len); i32 line_shift = new_line_count - replaced_line_count; - file_remeasure_starts(system, general, &file->state.buffer, - line_start, line_end, line_shift, shift_amount); - Render_Font *font = get_font_info(file->settings.set, file->state.font_id)->font; - if (font){ - file_remeasure_widths(system, general, &file->state.buffer, - font, line_start, line_end, line_shift); - } + + file_grow_starts_widths_as_needed(general, buffer, line_shift); + buffer_remeasure_starts(buffer, line_start, line_end, line_shift, shift_amount); + buffer_remeasure_widths(buffer, font->advance_data, line_start, line_end, line_shift); i32 panel_count = layout->panel_count; Panel *current_panel = layout->panels; @@ -2276,13 +2280,11 @@ working_set_lookup_file(Working_Set *working_set, String string){ internal void clipboard_copy(System_Functions *system, General_Memory *general, Working_Set *working, Range range, Editing_File *file){ -#if BUFFER_EXPERIMENT_SCALPEL <= 3 i32 size = range.end - range.start; String *dest = working_set_next_clipboard_string(general, working, size); buffer_stringify(&file->state.buffer, range.start, range.end, dest->str); dest->size = size; system->post_clipboard(*dest); -#endif } internal Edit_Spec @@ -2290,7 +2292,6 @@ file_compute_whitespace_edit(Mem_Options *mem, Editing_File *file, i32 cursor_po Buffer_Edit *edits, char *str_base, i32 str_size, Buffer_Edit *inverse_array, char *inv_str, i32 inv_max, i32 edit_count){ -#if BUFFER_EXPERIMENT_SCALPEL <= 3 General_Memory *general = &mem->general; i32 inv_str_pos = 0; @@ -2315,16 +2316,12 @@ file_compute_whitespace_edit(Mem_Options *mem, Editing_File *file, i32 cursor_po spec.step.inverse_child_count = edit_count; spec.step.pre_pos = cursor_pos; spec.step.post_pos = cursor_pos; -#else - Edit_Spec spec = {}; -#endif return spec; } internal void view_clean_whitespace(System_Functions *system, Mem_Options *mem, File_View *view, Editing_Layout *layout){ -#if BUFFER_EXPERIMENT_SCALPEL <= 3 Editing_File *file = view->file; Assert(file && !file->state.is_dummy); Partition *part = &mem->part; @@ -2378,7 +2375,6 @@ view_clean_whitespace(System_Functions *system, Mem_Options *mem, File_View *vie } end_temp_memory(temp); -#endif } internal void @@ -3294,7 +3290,8 @@ command_reverse_search(System_Functions*,Command_Data*,Command_Binding); inline void free_file_view(View *view){ File_View *fview = (File_View*)view; - general_memory_free(&view->mem->general, fview->line_wrap_y); + if (fview->line_wrap_y) + general_memory_free(&view->mem->general, fview->line_wrap_y); if (fview->links) general_memory_free(&view->mem->general, fview->links); } diff --git a/4ed_interactive_view.cpp b/4ed_interactive_view.cpp index b95cc8e7..6ef77bad 100644 --- a/4ed_interactive_view.cpp +++ b/4ed_interactive_view.cpp @@ -34,6 +34,7 @@ struct Interactive_View{ UI_State state; Interactive_View_Interaction interaction; Interactive_View_Action action; + int finished; char query_[256]; String query; @@ -98,8 +99,9 @@ interactive_view_complete(Interactive_View *view){ internal i32 step_draw_int_view(System_Functions *system, Interactive_View *view, - Render_Target *target, i32_Rect rect, - Input_Summary *user_input, b32 input_stage){ + Render_Target *target, i32_Rect rect, + Input_Summary *user_input, b32 input_stage){ + if (view->finished) return 0; i32 result = 0; UI_State state = @@ -182,6 +184,7 @@ step_draw_int_view(System_Functions *system, Interactive_View *view, } if (complete){ + view->finished = 1; interactive_view_complete(view); } @@ -222,6 +225,7 @@ interactive_view_init(System_Functions *system, View *view, result->working_set = working_set; result->font_set = font_set; result->delay = delay; + result->finished = 0; return result; } diff --git a/4ed_metagen.cpp b/4ed_metagen.cpp index 8922ebbf..4758ff46 100644 --- a/4ed_metagen.cpp +++ b/4ed_metagen.cpp @@ -112,6 +112,8 @@ char* generate_keycode_enum(){ char daction_enum_name[] = "Action_Type"; char *daction_enum[] = { "OPEN", + "OPEN_BACKGROUND", + "SET_LINE", "SAVE_AS", "SAVE", "NEW", @@ -124,6 +126,18 @@ char *daction_enum[] = { "KEYBOARD_OPTIONS" }; +char str_alloc_copy[] = +"internal String\n" +"str_alloc_copy(General_Memory *general, String str){\n" +" String result;\n" +" result.memory_size = str.memory_size + 1;\n" +" result.size = str.size;\n" +" result.str = (char*)general_memory_allocate(general, result.memory_size, 0);\n" +" memcpy(result.str, str.str, str.size);\n" +" result.str[result.size] = 0;\n" +" return(result);" +"}\n\n"; + char daction_name[] = "Delayed_Action"; Struct_Field daction_fields[] = { {"Action_Type", "type"}, @@ -132,27 +146,31 @@ Struct_Field daction_fields_primary[] = { {"String", "string"}, {"Panel*", "panel"}, {"Editing_File*", "file"}, + {"i32", "integer"}, }; enum Daction_Field_Handle{ dfph_null, dfph_string, dfph_panel, dfph_file, + dfph_integer, }; Daction_Field_Handle dact_param_sets[] = { dfph_panel, dfph_null, + dfph_string, dfph_null, dfph_string, dfph_panel, dfph_null, - dfph_string, dfph_file, dfph_null + dfph_string, dfph_file, dfph_null, + dfph_panel, dfph_integer, dfph_null, }; char delay_name[] = "Delay"; Struct_Field delay_fields[] = { + {"General_Memory*", "general"}, {"Delayed_Action*", "acts"}, {"i32", "count"}, {"i32", "max"}, }; -// TODO(allen): Make delay buffer expandable (general memory probably) char delayed_action_function_top[] = "inline Delayed_Action*\n" "delayed_action_(Delay *delay, Action_Type type"; @@ -160,7 +178,11 @@ char delayed_action_function_top[] = char delayed_action_function_bottom[] = "){\n" " Delayed_Action *result;\n" -" Assert(delay->count < delay->max);\n" +" if (delay->count == delay->max){\n" +" delay->max *= 2;\n" +" delay->acts = (Delayed_Action*)general_memory_reallocate(" +"delay->general, delay->acts, delay->count*sizeof(Delayed_Action), delay->max*sizeof(Delayed_Action), 0);\n" +" }\n" " result = delay->acts + delay->count++;\n" " *result = {};\n" " result->type = type;\n" @@ -177,6 +199,9 @@ char delayed_action_specialized_middle[] = char delayed_action_special_line[] = " result->%s = %s;\n"; +char delayed_action_special_string_line[] = +" result->%s = str_alloc_copy(delay->general, %s);\n"; + char delayed_action_specialized_bottom[] = " return(result);\n" "}\n\n"; @@ -184,6 +209,17 @@ char delayed_action_specialized_bottom[] = char delayed_action_macro[] = "#define delayed_%s(delay, ...) delayed_action_(delay, DACT_%s, __VA_ARGS__)\n"; +char delayed_action_repush_function[] = +"inline Delayed_Action*\n" +"delayed_action_repush(Delay *delay, Delayed_Action *act){\n" +" Delayed_Action *new_act = delayed_action_(delay, (Action_Type)0);\n" +" *new_act = *act;\n" +" if (act->string.str){\n" +" new_act->string = str_alloc_copy(delay->general, act->string);\n" +" }\n" +" return(new_act);\n" +"}\n\n"; + char* generate_delayed_action(){ FILE *file; char *filename = "4ed_delay.cpp"; @@ -207,6 +243,7 @@ char* generate_delayed_action(){ struct_fields(file, delay_fields, ArrayCount(delay_fields)); struct_end(file); + fprintf(file, "%s", str_alloc_copy); fprintf(file, "%s%s", delayed_action_function_top, delayed_action_function_bottom); for (i = 0; i < ArrayCount(dact_param_sets); ++i){ @@ -218,12 +255,20 @@ char* generate_delayed_action(){ } fprintf(file, "%s", delayed_action_specialized_middle); for (; dact_param_sets[j] != dfph_null; ++j){ - Struct_Field field = daction_fields_primary[dact_param_sets[j] - 1]; - fprintf(file, delayed_action_special_line, field.name, field.name); + int handle = (int)(dact_param_sets[j]); + Struct_Field field = daction_fields_primary[handle - 1]; + if (handle == dfph_string){ + fprintf(file, delayed_action_special_string_line, field.name, field.name); + } + else{ + fprintf(file, delayed_action_special_line, field.name, field.name); + } } fprintf(file, "%s", delayed_action_specialized_bottom); } + fprintf(file, "%s", delayed_action_repush_function); + for (i = 0; i < ArrayCount(daction_enum); ++i){ to_lower(daction_enum[i], scratch); fprintf(file, delayed_action_macro, scratch, daction_enum[i]); diff --git a/4ed_system.h b/4ed_system.h index 9d4e5feb..07aab46d 100644 --- a/4ed_system.h +++ b/4ed_system.h @@ -13,17 +13,6 @@ struct Plat_Handle{ u32 d[4]; }; -struct File_Info{ - String filename; - b32 folder; -}; - -struct File_List{ - void *block; - File_Info *infos; - i32 count, block_size; -}; - #define Sys_File_Time_Stamp_Sig(name) u64 name(char *filename) typedef Sys_File_Time_Stamp_Sig(System_File_Time_Stamp); @@ -187,8 +176,8 @@ struct System_Functions{ System_Set_File_List *set_file_list; // file system navigation (4coder_custom.h): 2 - Directory_Has_File *directory_has_file; - Directory_CD *directory_cd; + File_Exists_Function *file_exists; + Directory_CD_Function *directory_cd; // clipboard: 1 System_Post_Clipboard *post_clipboard; diff --git a/buffer/4coder_buffer_abstract.cpp b/buffer/4coder_buffer_abstract.cpp index 0607791a..59ab0b86 100644 --- a/buffer/4coder_buffer_abstract.cpp +++ b/buffer/4coder_buffer_abstract.cpp @@ -120,7 +120,7 @@ buffer_reverse_seek_delimiter(Buffer_Type *buffer, int pos, char delim){ buffer_backify_next(&loop)){ end = loop.size + loop.absolute_pos; data = loop.data - loop.absolute_pos; - for (; pos > 0; --pos){ + for (; pos >= 0; --pos){ if (data[pos] == delim) goto double_break; } } diff --git a/win32_4ed.cpp b/win32_4ed.cpp index 7843a53f..21b023e4 100644 --- a/win32_4ed.cpp +++ b/win32_4ed.cpp @@ -24,6 +24,8 @@ #include "4ed_dll_reader.h" +#include + #include "4coder_custom.cpp" #undef exec_command @@ -261,7 +263,17 @@ internal Data system_load_file(char *filename){ Data result = {}; HANDLE file; - file = CreateFile((char*)filename, GENERIC_READ, 0, 0, + + String fname_str = make_string_slowly(filename); + if (fname_str.size >= 1024) return result; + + char fixed_space[1024]; + String fixed_str = make_fixed_width_string(fixed_space); + copy(&fixed_str, fname_str); + terminate_with_null(&fixed_str); + replace_char(fixed_str, '/', '\\'); + + file = CreateFile((char*)fixed_str.str, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (!file || file == INVALID_HANDLE_VALUE){ return result; @@ -397,8 +409,9 @@ Sys_Set_File_List_Sig(system_set_file_list){ i32 required_size = count + file_count * sizeof(File_Info); if (file_list->block_size < required_size){ - Win32FreeMemory(file_list->block); + Win32FreeMemory(file_list->block); file_list->block = Win32GetMemory(required_size); + file_list->block_size = required_size; } file_list->infos = (File_Info*)file_list->block; @@ -436,37 +449,32 @@ Sys_Set_File_List_Sig(system_set_file_list){ } } } + else{ + Win32FreeMemory(file_list->block); + } } internal -DIRECTORY_HAS_FILE_SIG(system_directory_has_file){ - char *full_filename; - char space[1024]; +FILE_EXISTS_SIG(system_file_exists){ + char full_filename_space[1024]; + String full_filename; HANDLE file; b32 result; - i32 len; - - full_filename = 0; - len = str_size(filename); - if (dir.memory_size - dir.size - 1 >= len){ - full_filename = dir.str; - memcpy(dir.str + dir.size, filename, len + 1); - } - else if (dir.size + len + 1 < 1024){ - full_filename = space; - memcpy(full_filename, dir.str, dir.size); - memcpy(full_filename + dir.size, filename, len + 1); - } result = 0; - if (full_filename){ - file = CreateFile((char*)full_filename, GENERIC_READ, 0, 0, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + + if (len < sizeof(full_filename_space)){ + full_filename = make_fixed_width_string(full_filename_space); + copy(&full_filename, make_string(filename, len)); + terminate_with_null(&full_filename); + + file = CreateFile(full_filename.str, GENERIC_READ, 0, 0, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + if (file != INVALID_HANDLE_VALUE){ CloseHandle(file); result = 1; } - dir.str[dir.size] = 0; } return(result); @@ -480,34 +488,35 @@ b32 Win32DirectoryExists(char *path){ internal DIRECTORY_CD_SIG(system_directory_cd){ + String directory = make_string(dir, *len, capacity); b32 result = 0; i32 old_size; - i32 len; if (rel_path[0] != 0){ if (rel_path[0] == '.' && rel_path[1] == 0){ result = 1; } else if (rel_path[0] == '.' && rel_path[1] == '.' && rel_path[2] == 0){ - result = remove_last_folder(dir); - terminate_with_null(dir); + result = remove_last_folder(&directory); + terminate_with_null(&directory); } else{ - len = str_size(rel_path); - if (dir->size + len + 1 > dir->memory_size){ - old_size = dir->size; - append_partial(dir, rel_path); - append_partial(dir, "\\"); - if (Win32DirectoryExists(dir->str)){ + if (directory.size + rel_len + 1 > directory.memory_size){ + old_size = directory.size; + append_partial(&directory, rel_path); + append_partial(&directory, "\\"); + if (Win32DirectoryExists(directory.str)){ result = 1; } else{ - dir->size = old_size; + directory.size = old_size; } } } } + *len = directory.size; + return(result); } @@ -975,7 +984,7 @@ Sys_To_Binary_Path(system_to_binary_path){ i32 size = GetModuleFileName(0, out_filename->str, max); if (size > 0 && size < max-1){ out_filename->size = size; - truncate_to_path_of_directory(out_filename); + remove_last_folder(out_filename); if (append(out_filename, filename) && terminate_with_null(out_filename)){ translate_success = 1; } @@ -1047,7 +1056,7 @@ Win32LoadSystemCode(){ win32vars.system->file_time_stamp = system_file_time_stamp; win32vars.system->set_file_list = system_set_file_list; - win32vars.system->directory_has_file = system_directory_has_file; + win32vars.system->file_exists = system_file_exists; win32vars.system->directory_cd = system_directory_cd; win32vars.system->post_clipboard = system_post_clipboard; @@ -1555,20 +1564,23 @@ UpdateLoop(LPVOID param){ } } } - - Assert(d == exchange_vars.file.num_active); - + + int free_list_count = 0; for (file = exchange_vars.file.free_list.next; - file != &exchange_vars.file.free_list; - file = file->next){ + file != &exchange_vars.file.free_list; + file = file->next){ + ++free_list_count; if (file->data){ system_free_memory(file->data); } } if (exchange_vars.file.free_list.next != &exchange_vars.file.free_list){ + Assert(free_list_count != 0); ex__insert_range(exchange_vars.file.free_list.next, exchange_vars.file.free_list.prev, - &exchange_vars.file.available); + &exchange_vars.file.available); + + exchange_vars.file.num_active -= free_list_count; } ex__check(&exchange_vars.file); @@ -1633,19 +1645,19 @@ main(int argc, char **argv){ for (i32 i = 0; i+1 < ArrayCount(win32vars.coroutine_data); ++i){ win32vars.coroutine_data[i].next = win32vars.coroutine_data + i + 1; } - + LPVOID base; #if FRED_INTERNAL base = (LPVOID)Tbytes(1); #else base = (LPVOID)0; #endif - - memory_vars.vars_memory_size = Mbytes(2); + + memory_vars.vars_memory_size = Mbytes(2); memory_vars.vars_memory = VirtualAlloc(base, memory_vars.vars_memory_size, - MEM_COMMIT | MEM_RESERVE, - PAGE_READWRITE); - + MEM_COMMIT | MEM_RESERVE, + PAGE_READWRITE); + #if FRED_INTERNAL base = (LPVOID)Tbytes(2); #else @@ -1653,6 +1665,12 @@ main(int argc, char **argv){ #endif memory_vars.target_memory_size = Mbytes(512); memory_vars.target_memory = VirtualAlloc(base, memory_vars.target_memory_size, + MEM_COMMIT | MEM_RESERVE, + PAGE_READWRITE); + + base = (LPVOID)0; + memory_vars.user_memory_size = Mbytes(2); + memory_vars.user_memory = VirtualAlloc(base, memory_vars.target_memory_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); // @@ -1905,7 +1923,7 @@ main(int argc, char **argv){ } - File_Slot file_slots[120]; + File_Slot file_slots[32]; sysshared_init_file_exchange(&exchange_vars, file_slots, ArrayCount(file_slots), 0); Font_Load_Parameters params[32];