diff --git a/4coder_custom.cpp b/4coder_custom.cpp index ea8e44a8..cd0efa3f 100644 --- a/4coder_custom.cpp +++ b/4coder_custom.cpp @@ -33,43 +33,49 @@ HOOK_SIG(my_start){ } HOOK_SIG(my_file_settings){ - Buffer_Summary buffer = app->get_active_buffer(app); - - // NOTE(allen|a3.4.2): Whenever you ask for a buffer, you can check that - // the exists field is set to true. Reasons why the buffer might not exist: - // -The active panel does not contain a buffer and get_active_buffer was used - // -The index provided to get_buffer was out of range [0,max) or that index is associated to a dummy buffer - // -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)){ - 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)); - exec_command(app, cmdid_set_settings); - } + // NOTE(allen|a4): In hooks that want parameters, such as this file + // created hook. The file created hook is guaranteed to have only + // and exactly one buffer parameter. In normal command callbacks + // there are no parameter buffers. + Buffer_Summary buffer = app->get_parameter_buffer(app, 0); + assert(buffer.exists); + + int treat_as_code = 0; + + if (buffer.file_name && buffer.size < (16 << 20)){ + 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)); + exec_command(app, cmdid_set_settings); +} + +static void +write_string(Application_Links *app, String string){ + Buffer_Summary buffer = app->get_active_buffer(app); + app->buffer_replace_range(app, &buffer, buffer.buffer_cursor_pos, buffer.buffer_cursor_pos, string.str, string.size); } CUSTOM_COMMAND_SIG(write_increment){ - char text[] = "++"; - int size = sizeof(text) - 1; - Buffer_Summary buffer = app->get_active_buffer(app); - app->buffer_replace_range(app, &buffer, buffer.buffer_cursor_pos, buffer.buffer_cursor_pos, text, size); + write_string(app, make_lit_string("++")); } CUSTOM_COMMAND_SIG(write_decrement){ - char text[] = "--"; - int size = sizeof(text) - 1; - Buffer_Summary buffer = app->get_active_buffer(app); - app->buffer_replace_range(app, &buffer, buffer.buffer_cursor_pos, buffer.buffer_cursor_pos, text, size); + write_string(app, make_lit_string("--")); +} + +CUSTOM_COMMAND_SIG(write_allen_todo){ + write_string(app, make_lit_string("// TODO(allen): ")); +} + +CUSTOM_COMMAND_SIG(write_allen_note){ + write_string(app, make_lit_string("// NOTE(allen): ")); } static void @@ -137,7 +143,7 @@ CUSTOM_COMMAND_SIG(if0_off){ View_Summary view; Buffer_Summary buffer; - char text1[] = "#if 0\n"; + char text1[] = "\n#if 0"; int size1 = sizeof(text1) - 1; char text2[] = "#endif\n"; @@ -192,8 +198,6 @@ CUSTOM_COMMAND_SIG(switch_to_compilation){ char name[] = "*compilation*"; int name_size = sizeof(name)-1; - // TODO(allen): This will only work for file views for now. Fix up this - // view nonsense so that view types aren't such an issue. view = app->get_active_view(app); buffer = app->get_buffer_by_name(app, name, name_size); @@ -446,7 +450,7 @@ CUSTOM_COMMAND_SIG(rewrite_as_single_caps){ // TODO(allen): // get range by specific "word" type (for example "get token range") // read range by specific "word" type -// Dream API: for rewrite_as_single_caps +// Dream API for rewrite_as_single_caps: #if 0 { rewrite = get_rewrite(app, ByToken); @@ -479,6 +483,8 @@ CUSTOM_COMMAND_SIG(replace_in_range){ with.string = make_fixed_width_string(with_space); if (!query_user_string(app, &replace)) return; + if (replace.string.size == 0) return; + if (!query_user_string(app, &with)) return; String r, w; @@ -517,6 +523,8 @@ CUSTOM_COMMAND_SIG(query_replace){ with.string = make_fixed_width_string(with_space); if (!query_user_string(app, &replace)) return; + if (replace.string.size == 0) return; + if (!query_user_string(app, &with)) return; String r, w; @@ -567,11 +575,11 @@ CUSTOM_COMMAND_SIG(query_replace){ CUSTOM_COMMAND_SIG(close_all_code){ String extension; Buffer_Summary buffer; - int max, i; - max = app->get_buffer_max_index(app); - for (i = 0; i < max; ++i){ - buffer = app->get_buffer(app, i); + for (buffer = app->get_buffer_first(app); + buffer.exists; + app->get_buffer_next(app, &buffer)){ + extension = file_extension(make_string(buffer.file_name, buffer.file_name_len)); if (match(extension, make_lit_string("cpp")) || match(extension, make_lit_string("hpp")) || @@ -901,6 +909,7 @@ 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); @@ -921,6 +930,7 @@ extern "C" GET_BINDING_DATA(get_bindings){ bind(context, 'o', MDFR_ALT, open_in_other); bind(context, 'm', MDFR_ALT, build_search); + bind(context, ',', MDFR_ALT, switch_to_compilation); bind(context, 'x', MDFR_ALT, execute_arbitrary_command); bind(context, 'z', MDFR_ALT, execute_any_cli); @@ -962,6 +972,8 @@ extern "C" GET_BINDING_DATA(get_bindings){ bind(context, '=', MDFR_CTRL, write_increment); bind(context, '-', MDFR_CTRL, write_decrement); + bind(context, 't', MDFR_ALT, write_allen_todo); + bind(context, 'n', MDFR_ALT, write_allen_note); bind(context, '[', MDFR_CTRL, open_long_braces); bind(context, '{', MDFR_CTRL, open_long_braces_semicolon); bind(context, '}', MDFR_CTRL, open_long_braces_break); @@ -1039,7 +1051,7 @@ extern "C" GET_BINDING_DATA(get_bindings){ 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 b925233b..e5bb7a29 100644 --- a/4coder_custom.h +++ b/4coder_custom.h @@ -342,9 +342,12 @@ struct Application_Links; #define FREE_FILE_LIST_SIG(name) void name(Application_Links *app, File_List list) // Direct buffer manipulation -#define GET_BUFFER_MAX_INDEX_SIG(name) int name(Application_Links *app) +#define GET_BUFFER_FIRST_SIG(name) Buffer_Summary name(Application_Links *app) +#define GET_BUFFER_NEXT_SIG(name) void name(Application_Links *app, Buffer_Summary *buffer) + #define GET_BUFFER_SIG(name) Buffer_Summary name(Application_Links *app, int index) #define GET_ACTIVE_BUFFER_SIG(name) Buffer_Summary name(Application_Links *app) +#define GET_PARAMETER_BUFFER_SIG(name) Buffer_Summary name(Application_Links *app, int param_index) #define GET_BUFFER_BY_NAME(name) Buffer_Summary name(Application_Links *app, char *filename, int len) #define REFRESH_BUFFER_SIG(name) int name(Application_Links *app, Buffer_Summary *buffer) @@ -355,7 +358,9 @@ struct Application_Links; #define BUFFER_SET_POS_SIG(name) int name(Application_Links *app, Buffer_Summary *buffer, int pos) // File view manipulation -#define GET_VIEW_MAX_INDEX_SIG(name) int name(Application_Links *app) +#define GET_VIEW_FIRST_SIG(name) View_Summary name(Application_Links *app) +#define GET_VIEW_NEXT_SIG(name) void name(Application_Links *app, View_Summary *view) + #define GET_VIEW_SIG(name) View_Summary name(Application_Links *app, int index) #define GET_ACTIVE_VIEW_SIG(name) View_Summary name(Application_Links *app) @@ -398,9 +403,12 @@ extern "C"{ typedef FREE_FILE_LIST_SIG(Free_File_List_Function); // Buffer manipulation - typedef GET_BUFFER_MAX_INDEX_SIG(Get_Buffer_Max_Index_Function); + typedef GET_BUFFER_FIRST_SIG(Get_Buffer_First_Function); + typedef GET_BUFFER_NEXT_SIG(Get_Buffer_Next_Function); + typedef GET_BUFFER_SIG(Get_Buffer_Function); typedef GET_ACTIVE_BUFFER_SIG(Get_Active_Buffer_Function); + typedef GET_PARAMETER_BUFFER_SIG(Get_Parameter_Buffer_Function); typedef GET_BUFFER_BY_NAME(Get_Buffer_By_Name_Function); typedef REFRESH_BUFFER_SIG(Refresh_Buffer_Function); @@ -411,7 +419,9 @@ extern "C"{ typedef BUFFER_SET_POS_SIG(Buffer_Set_Pos_Function); // View manipulation - typedef GET_VIEW_MAX_INDEX_SIG(Get_View_Max_Index_Function); + typedef GET_VIEW_FIRST_SIG(Get_View_First_Function); + typedef GET_VIEW_NEXT_SIG(Get_View_Next_Function); + typedef GET_VIEW_SIG(Get_View_Function); typedef GET_ACTIVE_VIEW_SIG(Get_Active_View_Function); @@ -448,9 +458,12 @@ struct Application_Links{ Free_File_List_Function *free_file_list; // Buffer manipulation - Get_Buffer_Max_Index_Function *get_buffer_max_index; + Get_Buffer_First_Function *get_buffer_first; + Get_Buffer_Next_Function *get_buffer_next; + Get_Buffer_Function *get_buffer; Get_Active_Buffer_Function *get_active_buffer; + Get_Parameter_Buffer_Function *get_parameter_buffer; Get_Buffer_By_Name_Function *get_buffer_by_name; Refresh_Buffer_Function *refresh_buffer; @@ -461,7 +474,9 @@ struct Application_Links{ Buffer_Set_Pos_Function *buffer_set_pos; // View manipulation - Get_View_Max_Index_Function *get_view_max_index; + Get_View_First_Function *get_view_first; + Get_View_Next_Function *get_view_next; + Get_View_Function *get_view; Get_Active_View_Function *get_active_view; diff --git a/4ed.cpp b/4ed.cpp index d71913e6..14853246 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -137,11 +137,11 @@ globalvar Application_Links app_links; #define USE_FILE(n,v) Editing_File *n = (v)->file #define USE_EXCHANGE(n) Exchange *n = command->exchange -#define REQ_OPEN_VIEW(n) View *n = command->panel->view; if (n->locked) return -#define REQ_FILE_HISTORY(n,v) Editing_File *n = (v)->file; if (!n || !buffer_good(&n->state.buffer) || n->state.is_dummy || !n->state.undo.undo.edits) return -#define REQ_FILE_LOADING(n,v) Editing_File *n = (v)->file; if (!n || n->state.is_dummy) return -#define REQ_FILE(n,v) Editing_File *n = (v)->file; if (!n || !buffer_good(&n->state.buffer) || n->state.is_dummy) return -#define REQ_COLOR_VIEW(n) Color_View *n = view_to_color_view(command->view); if (!n) return +#define REQ_OPEN_VIEW(n) View *n = command->panel->view; if (view_lock_level(n) > LockLevel_Open) return +#define REQ_READABLE_VIEW(n) View *n = command->panel->view; if (view_lock_level(n) > LockLevel_NoWrite) return + +#define REQ_FILE(n,v) Editing_File *n = (v)->file; if (!n) return +#define REQ_FILE_HISTORY(n,v) Editing_File *n = (v)->file; if (!n || !n->state.undo.undo.edits) return #define COMMAND_DECL(n) internal void command_##n(System_Functions *system, Command_Data *command, Command_Binding binding) @@ -189,20 +189,14 @@ param_stack_end(Partition *part){ internal View* panel_make_empty(System_Functions *system, Exchange *exchange, App_Vars *vars, Panel *panel){ App_Models *models = &vars->models; - - View *file_view; View_And_ID new_view; Assert(panel->view == 0); - new_view = live_set_alloc_view(&vars->live_set); - panel->view = new_view.view; - panel->view->panel = panel; + new_view = live_set_alloc_view(&vars->live_set, panel, models); + view_set_file(new_view.view, 0, models, 0, 0, 0); + new_view.view->map = app_get_map(models, mapid_global); - file_view = file_view_init(panel->view, models); - view_set_file(file_view, 0, models, 0, 0, 0); - panel->view->map = app_get_map(models, mapid_global); - - return(file_view); + return(new_view.view); } COMMAND_DECL(null){ @@ -229,7 +223,7 @@ COMMAND_DECL(write_character){ COMMAND_DECL(seek_whitespace_right){ ProfileMomentFunction(); - REQ_OPEN_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); i32 pos = buffer_seek_whitespace_right(&file->state.buffer, view->cursor.pos); @@ -238,7 +232,7 @@ COMMAND_DECL(seek_whitespace_right){ COMMAND_DECL(seek_whitespace_left){ ProfileMomentFunction(); - REQ_OPEN_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); i32 pos = buffer_seek_whitespace_left(&file->state.buffer, view->cursor.pos); @@ -247,7 +241,7 @@ COMMAND_DECL(seek_whitespace_left){ COMMAND_DECL(seek_whitespace_up){ ProfileMomentFunction(); - REQ_OPEN_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); i32 pos = buffer_seek_whitespace_up(&file->state.buffer, view->cursor.pos); @@ -256,7 +250,7 @@ COMMAND_DECL(seek_whitespace_up){ COMMAND_DECL(seek_whitespace_down){ ProfileMomentFunction(); - REQ_OPEN_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); i32 pos = buffer_seek_whitespace_down(&file->state.buffer, view->cursor.pos); @@ -294,7 +288,7 @@ seek_token_right(Cpp_Token_Stack *tokens, i32 pos){ COMMAND_DECL(seek_token_left){ ProfileMomentFunction(); - REQ_OPEN_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); if (file->state.tokens_complete){ @@ -305,7 +299,7 @@ COMMAND_DECL(seek_token_left){ COMMAND_DECL(seek_token_right){ ProfileMomentFunction(); - REQ_OPEN_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); if (file->state.tokens_complete){ @@ -316,7 +310,7 @@ COMMAND_DECL(seek_token_right){ COMMAND_DECL(seek_white_or_token_right){ ProfileMomentFunction(); - REQ_OPEN_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); i32 token_pos, white_pos; @@ -332,7 +326,7 @@ COMMAND_DECL(seek_white_or_token_right){ COMMAND_DECL(seek_white_or_token_left){ ProfileMomentFunction(); - REQ_OPEN_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); i32 token_pos, white_pos; @@ -348,7 +342,7 @@ COMMAND_DECL(seek_white_or_token_left){ COMMAND_DECL(seek_alphanumeric_right){ ProfileMomentFunction(); - REQ_OPEN_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); i32 pos = buffer_seek_alphanumeric_right(&file->state.buffer, view->cursor.pos); @@ -357,7 +351,7 @@ COMMAND_DECL(seek_alphanumeric_right){ COMMAND_DECL(seek_alphanumeric_left){ ProfileMomentFunction(); - REQ_OPEN_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); i32 pos = buffer_seek_alphanumeric_left(&file->state.buffer, view->cursor.pos); @@ -366,7 +360,7 @@ COMMAND_DECL(seek_alphanumeric_left){ COMMAND_DECL(seek_alphanumeric_or_camel_right){ ProfileMomentFunction(); - REQ_OPEN_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); i32 pos = buffer_seek_alphanumeric_or_camel_right(&file->state.buffer, view->cursor.pos); @@ -375,7 +369,7 @@ COMMAND_DECL(seek_alphanumeric_or_camel_right){ COMMAND_DECL(seek_alphanumeric_or_camel_left){ ProfileMomentFunction(); - REQ_OPEN_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); i32 pos = buffer_seek_alphanumeric_or_camel_left(&file->state.buffer, view->cursor.pos); @@ -410,9 +404,6 @@ COMMAND_DECL(word_complete){ char *spare; i32 size; - i32 buffer_count, i, j; - Editing_File *file_ptr; - i32 match_size; b32 do_init = 0; @@ -463,27 +454,35 @@ COMMAND_DECL(word_complete){ 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; + { + File_Node *node, *used_nodes; + Editing_File *file_ptr; + i32 buffer_count, j; - ranges[1].buffer = buffer; - ranges[1].start = word_end; - ranges[1].size = size_of_buffer - word_end; + buffer_count = working_set->file_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; - 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){ - ranges[j].buffer = &file_ptr->state.buffer; - ranges[j].start = 0; - ranges[j].size = buffer_size(ranges[j].buffer); - ++j; + ranges[1].buffer = buffer; + ranges[1].start = word_end; + ranges[1].size = size_of_buffer - word_end; + + used_nodes = &working_set->used_sentinel; + j = 2; + for (dll_items(node, used_nodes)){ + file_ptr = (Editing_File*)node; + if (file_ptr != file){ + ranges[j].buffer = &file_ptr->state.buffer; + ranges[j].start = 0; + ranges[j].size = buffer_size(ranges[j].buffer); + ++j; + } } + complete_state->set.count = j; } - 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, @@ -539,7 +538,7 @@ COMMAND_DECL(word_complete){ COMMAND_DECL(set_mark){ ProfileMomentFunction(); - USE_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); view->mark = (i32)view->cursor.pos; @@ -548,7 +547,7 @@ COMMAND_DECL(set_mark){ COMMAND_DECL(copy){ ProfileMomentFunction(); USE_MODELS(models); - USE_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); // TODO(allen): deduplicate @@ -646,8 +645,7 @@ COMMAND_DECL(paste){ for (iter = file_view_iter_init(&models->layout, file, 0); file_view_iter_good(iter); iter = file_view_iter_next(iter)){ - view_post_paste_effect(iter.view, 20, pos_left, src->size, - iter.view->style->main.paste_color); + view_post_paste_effect(iter.view, 20, pos_left, src->size, models->style.main.paste_color); } } } @@ -679,8 +677,7 @@ COMMAND_DECL(paste_next){ for (iter = file_view_iter_init(&models->layout, file, 0); file_view_iter_good(iter); iter = file_view_iter_next(iter)){ - view_post_paste_effect(iter.view, 20, range.start, src->size, - iter.view->style->main.paste_color); + view_post_paste_effect(iter.view, 20, range.start, src->size, models->style.main.paste_color); } } else{ @@ -801,7 +798,8 @@ app_open_file_background(App_Vars *vars, Exchange *exchange, Working_Set *workin result.file_index = file.index; } else{ - file_get_dummy(file.file); + working_set_free_file(working_set, file.file); + file.file = 0; } } } @@ -859,20 +857,17 @@ view_file_in_panel(Command_Data *cmd, Panel *panel, Editing_File *file){ Partition old_part; Temp_Memory temp; View *old_view; - View *file_view; Partition *part; - file_view = file_view_init(panel->view, models); - old_view = cmd->view; - cmd->view = panel->view; - - part = &models->mem.part; old_part = cmd->part; + + cmd->view = panel->view; + part = &models->mem.part; temp = begin_temp_memory(part); cmd->part = partition_sub_part(part, Kbytes(16)); - view_set_file(file_view, file, models, system, + view_set_file(panel->view, file, models, system, models->hooks[hook_open_file], &app_links); cmd->part = old_part; @@ -898,7 +893,7 @@ COMMAND_DECL(reopen){ i32 index = 0; if (file_id){ file_set_to_loading(file); - index = working_set_get_index(&models->working_set, file); + index = (i32)(file - models->working_set.files); app_push_file_binding(vars, file_id, index); view_set_file(view, file, models, system, @@ -1007,7 +1002,7 @@ COMMAND_DECL(kill_buffer){ USE_FILE(file, view); Delay *delay = &models->delay1; - int buffer_id = -1; + int buffer_id = 0; Command_Parameter *end = param_stack_end(&command->part); Command_Parameter *param = param_stack_first(&command->part, end); @@ -1018,10 +1013,10 @@ COMMAND_DECL(kill_buffer){ } } - if (buffer_id != -1){ - if (buffer_id > 0 && buffer_id < models->working_set.file_max_count){ - file = models->working_set.files + buffer_id; - if (!file->state.is_dummy){ + if (buffer_id != 0){ + if (buffer_id > 0 && buffer_id < models->working_set.file_count){ + file = working_set_get_file(&models->working_set, buffer_id, 1).file; + if (file){ delayed_kill(delay, file->name.source_path); } } @@ -1033,7 +1028,7 @@ COMMAND_DECL(kill_buffer){ COMMAND_DECL(toggle_line_wrap){ ProfileMomentFunction(); - USE_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); Relative_Scrolling scrolling = view_get_relative_scrolling(view); @@ -1057,7 +1052,7 @@ COMMAND_DECL(toggle_line_wrap){ COMMAND_DECL(toggle_show_whitespace){ ProfileMomentFunction(); - USE_VIEW(view); + REQ_READABLE_VIEW(view); view->show_whitespace = !view->show_whitespace; } @@ -1065,7 +1060,7 @@ COMMAND_DECL(toggle_tokens){ #if BUFFER_EXPERIMENT_SCALPEL <= 0 ProfileMomentFunction(); USE_MODELS(models); - USE_VIEW(view); + REQ_OPEN_VIEW(view); REQ_FILE(file, view); if (file->settings.tokens_exist){ @@ -1111,7 +1106,7 @@ case_change_range(System_Functions *system, COMMAND_DECL(to_uppercase){ ProfileMomentFunction(); USE_MODELS(models); - USE_VIEW(view); + REQ_OPEN_VIEW(view); REQ_FILE(file, view); case_change_range(system, &models->mem, view, file, 'a', 'z', (u8)('A' - 'a')); } @@ -1119,7 +1114,7 @@ COMMAND_DECL(to_uppercase){ COMMAND_DECL(to_lowercase){ ProfileMomentFunction(); USE_MODELS(models); - USE_VIEW(view); + REQ_OPEN_VIEW(view); REQ_FILE(file, view); case_change_range(system, &models->mem, view, file, 'A', 'Z', (u8)('a' - 'A')); } @@ -1127,7 +1122,7 @@ COMMAND_DECL(to_lowercase){ COMMAND_DECL(clean_all_lines){ ProfileMomentFunction(); USE_MODELS(models); - USE_VIEW(view); + REQ_OPEN_VIEW(view); REQ_FILE(file, view); view_clean_whitespace(system, models, view); @@ -1135,7 +1130,7 @@ COMMAND_DECL(clean_all_lines){ COMMAND_DECL(eol_dosify){ ProfileMomentFunction(); - USE_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); file->settings.dos_write_mode = 1; @@ -1144,7 +1139,7 @@ COMMAND_DECL(eol_dosify){ COMMAND_DECL(eol_nixify){ ProfileMomentFunction(); - USE_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); file->settings.dos_write_mode = 0; @@ -1154,7 +1149,7 @@ COMMAND_DECL(eol_nixify){ COMMAND_DECL(auto_tab_range){ ProfileMomentFunction(); USE_MODELS(models); - USE_VIEW(view); + REQ_OPEN_VIEW(view); REQ_FILE(file, view); int r_start = 0, r_end = 0; @@ -1187,14 +1182,14 @@ COMMAND_DECL(auto_tab_range){ Range range = make_range(view->cursor.pos, view->mark); if (start_set) range.start = r_start; if (end_set) range.end = r_end; - view_auto_tab_tokens(system, &models->mem, view, &models->layout, range.start, range.end, clear_blank_lines); + view_auto_tab_tokens(system, models, view, range.start, range.end, clear_blank_lines); } } COMMAND_DECL(auto_tab_line_at_cursor){ ProfileMomentFunction(); USE_MODELS(models); - USE_VIEW(view); + REQ_OPEN_VIEW(view); REQ_FILE(file, view); int clear_blank_lines = 0; @@ -1212,18 +1207,18 @@ COMMAND_DECL(auto_tab_line_at_cursor){ if (file->state.token_stack.tokens && file->state.tokens_complete){ i32 pos = view->cursor.pos; - view_auto_tab_tokens(system, &models->mem, view, &models->layout, pos, pos, clear_blank_lines); + view_auto_tab_tokens(system, models, view, pos, pos, clear_blank_lines); } } COMMAND_DECL(auto_tab_whole_file){ ProfileMomentFunction(); USE_MODELS(models); - USE_VIEW(view); + REQ_OPEN_VIEW(view); REQ_FILE(file, view); if (file->state.token_stack.tokens && file->state.tokens_complete){ - view_auto_tab_tokens(system, &models->mem, view, &models->layout, 0, buffer_size(&file->state.buffer), 1); + view_auto_tab_tokens(system, models, view, 0, buffer_size(&file->state.buffer), 1); } } @@ -1366,7 +1361,7 @@ COMMAND_DECL(close_panel){ COMMAND_DECL(move_left){ ProfileMomentFunction(); - REQ_OPEN_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); i32 pos = view->cursor.pos; @@ -1376,7 +1371,7 @@ COMMAND_DECL(move_left){ COMMAND_DECL(move_right){ ProfileMomentFunction(); - REQ_OPEN_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); i32 size = buffer_size(&file->state.buffer); @@ -1431,7 +1426,7 @@ COMMAND_DECL(backspace){ COMMAND_DECL(move_up){ ProfileMomentFunction(); USE_MODELS(models); - USE_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); f32 font_height = (f32)get_font_info(models->font_set, models->global_font.font_id)->height; @@ -1446,7 +1441,7 @@ COMMAND_DECL(move_up){ COMMAND_DECL(move_down){ ProfileMomentFunction(); USE_MODELS(models); - USE_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); f32 font_height = (f32)get_font_info(models->font_set, models->global_font.font_id)->height; @@ -1458,7 +1453,7 @@ COMMAND_DECL(move_down){ COMMAND_DECL(seek_end_of_line){ ProfileMomentFunction(); - USE_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); i32 pos = view_find_end_of_line(view, view->cursor.pos); @@ -1467,7 +1462,7 @@ COMMAND_DECL(seek_end_of_line){ COMMAND_DECL(seek_beginning_of_line){ ProfileMomentFunction(); - USE_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); i32 pos = view_find_beginning_of_line(view, view->cursor.pos); @@ -1476,7 +1471,7 @@ COMMAND_DECL(seek_beginning_of_line){ COMMAND_DECL(page_down){ ProfileMomentFunction(); - USE_VIEW(view); + REQ_READABLE_VIEW(view); f32 height = view_compute_height(view); f32 max_target_y = view_compute_max_target_y(view); @@ -1490,7 +1485,7 @@ COMMAND_DECL(page_down){ COMMAND_DECL(page_up){ ProfileMomentFunction(); - USE_VIEW(view); + REQ_READABLE_VIEW(view); f32 height = view_compute_height(view); @@ -1539,7 +1534,7 @@ COMMAND_DECL(close_minor_view){ COMMAND_DECL(cursor_mark_swap){ ProfileMomentFunction(); - USE_VIEW(view); + REQ_READABLE_VIEW(view); i32 pos = view->cursor.pos; view_cursor_move(view, view->mark); @@ -1553,8 +1548,8 @@ COMMAND_DECL(user_callback){ COMMAND_DECL(set_settings){ ProfileMomentFunction(); - USE_VIEW(view); - REQ_FILE_LOADING(file, view); + REQ_READABLE_VIEW(view); + REQ_FILE(file, view); USE_MODELS(models); Command_Parameter *end = param_stack_end(&command->part); @@ -1640,6 +1635,7 @@ COMMAND_DECL(command_line){ i32 path_len = 0; i32 script_len = 0; u32 flags = CLI_OverlapWithConflict; + b32 do_in_background = 0; Command_Parameter *end = param_stack_end(&command->part); Command_Parameter *param = param_stack_first(&command->part, end); @@ -1659,6 +1655,11 @@ COMMAND_DECL(command_line){ buffer_id = dynamic_to_int(¶m->param.value); }break; + case par_do_in_background: + { + do_in_background = 1; + }break; + case par_cli_path: { char *new_cli_path = dynamic_to_string(¶m->param.value, &path_len); @@ -1686,20 +1687,21 @@ COMMAND_DECL(command_line){ Working_Set *working_set = &models->working_set; CLI_Process *procs = vars->cli_processes.procs, *proc = 0; Get_File_Result file = {}; - b32 bind_to_new_view = 1; + b32 bind_to_new_view = !do_in_background; if (vars->cli_processes.count < vars->cli_processes.max){ if (buffer_id){ - if (buffer_id > 0 && buffer_id < working_set->file_index_count){ - file.file = working_set->files + buffer_id; - file.index = buffer_id; - } + file = working_set_get_file(working_set, buffer_id, 1); } else{ file.file = working_set_contains(working_set, make_string(buffer_name, buffer_name_len)); file.index = (i32)(file.file - working_set->files); if (file.file == 0) file = working_set_get_available_file(working_set); + else{ + // TODO(allen): feedback message - no available file + return; + } } if (file.file){ @@ -1716,7 +1718,7 @@ COMMAND_DECL(command_line){ break; } } - + if (file.file){ if (!(flags & CLI_AlwaysBindToView)){ iter = file_view_iter_init(&models->layout, file.file, 0); @@ -1725,12 +1727,12 @@ COMMAND_DECL(command_line){ } } - file_create_super_locked(system, models, file.file, buffer_name); + file_create_read_only(system, models, file.file, buffer_name); file.file->settings.unimportant = 1; table_add(&working_set->table, file.file->name.source_path, file.index); } else{ - // TODO(allen): feedback message - no available file + // TODO(allen): feedback message - file conflict return; } } @@ -1791,9 +1793,11 @@ globalvar Command_Function command_table[cmdid_count]; internal void fill_buffer_summary(Buffer_Summary *buffer, Editing_File *file, Working_Set *working_set){ - buffer->exists = 1; + *buffer = {}; if (!file->state.is_dummy){ + buffer->exists = 1; buffer->ready = file_is_ready(file); + buffer->is_lexed = file->settings.tokens_exist; buffer->buffer_id = (int)(file - working_set->files); buffer->size = file->state.buffer.size; @@ -1809,23 +1813,21 @@ fill_buffer_summary(Buffer_Summary *buffer, Editing_File *file, Working_Set *wor } internal void -fill_view_summary(View_Summary *view, View *file_view, Live_Views *live_set, Working_Set *working_set){ - view->exists = 1; - view->view_id = (int)(file_view - live_set->views) + 1; - view->line_height = file_view->font_height; - view->unwrapped_lines = file_view->unwrapped_lines; - - if (file_view->file){ - view->buffer_id = (int)(file_view->file - working_set->files); - view->mark = view_compute_cursor_from_pos(file_view, file_view->mark); - view->cursor = file_view->cursor; - view->preferred_x = file_view->preferred_x; - } - else{ - view->buffer_id = 0; - view->mark = {}; - view->cursor = {}; - view->preferred_x = 0; +fill_view_summary(View_Summary *view, View *vptr, Live_Views *live_set, Working_Set *working_set){ + *view = {}; + + if (vptr->in_use){ + view->exists = 1; + view->view_id = (int)(vptr - live_set->views) + 1; + view->line_height = vptr->font_height; + view->unwrapped_lines = vptr->unwrapped_lines; + + if (vptr->file){ + view->buffer_id = (int)(vptr->file - working_set->files); + view->mark = view_compute_cursor_from_pos(vptr, vptr->mark); + view->cursor = vptr->cursor; + view->preferred_x = vptr->preferred_x; + } } } @@ -1833,7 +1835,7 @@ extern "C"{ EXECUTE_COMMAND_SIG(external_exec_command_keep_stack){ Command_Data *cmd = (Command_Data*)app->cmd_context; Command_Function function = command_table[command_id]; - Command_Binding binding; + Command_Binding binding = {}; binding.function = function; if (function) function(cmd->system, cmd, binding); @@ -1894,20 +1896,40 @@ extern "C"{ system->set_file_list(&list, make_string(0, 0)); } - GET_BUFFER_MAX_INDEX_SIG(external_get_buffer_max_index){ + GET_BUFFER_FIRST_SIG(external_get_buffer_first){ Command_Data *cmd = (Command_Data*)app->cmd_context; - int max = cmd->models->working_set.file_index_count; - return(max); + Working_Set *working_set = &cmd->models->working_set; + Buffer_Summary result = {}; + if (working_set->file_count > 0){ + fill_buffer_summary(&result, (Editing_File*)working_set->used_sentinel.next, working_set); + } + return(result); + } + + GET_BUFFER_NEXT_SIG(external_get_buffer_next){ + Command_Data *cmd = (Command_Data*)app->cmd_context; + Working_Set *working_set = &cmd->models->working_set; + Editing_File *file; + + file = working_set_get_file(working_set, buffer->buffer_id, 1).file; + if (file){ + file = (Editing_File*)file->node.next; + fill_buffer_summary(buffer, file, working_set); + } + else{ + *buffer = {}; + } } GET_BUFFER_SIG(external_get_buffer){ Command_Data *cmd = (Command_Data*)app->cmd_context; Working_Set *working_set = &cmd->models->working_set; - int max = working_set->file_index_count; Buffer_Summary buffer = {}; + Get_File_Result file; - if (index >= 0 && index < max){ - fill_buffer_summary(&buffer, working_set->files + index, working_set); + file = working_set_get_file(working_set, index, 1); + if (file.file){ + fill_buffer_summary(&buffer, file.file, working_set); } return(buffer); @@ -1920,13 +1942,25 @@ extern "C"{ file = cmd->view->file; - if (file && !file->state.is_dummy){ + if (file){ fill_buffer_summary(&buffer, file, &cmd->models->working_set); } return(buffer); } + GET_PARAMETER_BUFFER_SIG(external_get_parameter_buffer){ + Command_Data *cmd = (Command_Data*)app->cmd_context; + App_Models *models = cmd->models; + Buffer_Summary buffer = {}; + + if (param_index >= 0 && param_index < models->buffer_param_count){ + buffer = external_get_buffer(app, models->buffer_param_indices[param_index]); + } + + return(buffer); + } + GET_BUFFER_BY_NAME(external_get_buffer_by_name){ Command_Data *cmd = (Command_Data*)app->cmd_context; Buffer_Summary buffer = {}; @@ -1936,8 +1970,8 @@ extern "C"{ working_set = &cmd->models->working_set; if (table_find(&working_set->table, make_string(filename, len), &index)){ - file = working_set->files + index; - if (!file->state.is_dummy && file_is_ready(file)){ + file = working_set_get_file(working_set, index, 1).file; + if (file){ fill_buffer_summary(&buffer, file, working_set); } } @@ -1961,8 +1995,8 @@ extern "C"{ if (buffer->exists){ working_set = &cmd->models->working_set; - file = working_set->files + buffer->buffer_id; - if (!file->state.is_dummy && file_is_ready(file)){ + file = working_set_get_file(working_set, buffer->buffer_id, 1).file; + if (file && file_is_ready(file)){ size = buffer_size(&file->state.buffer); result = 1; @@ -1999,8 +2033,8 @@ extern "C"{ if (buffer->exists){ models = cmd->models; working_set = &models->working_set; - file = working_set->files + buffer->buffer_id; - if (!file->state.is_dummy && file_is_ready(file)){ + file = working_set_get_file(working_set, buffer->buffer_id, 1).file; + if (file && file_is_ready(file)){ size = buffer_size(&file->state.buffer); if (start < 0 && !seek_forward) *out = start; @@ -2034,8 +2068,8 @@ extern "C"{ if (buffer->exists){ working_set = &cmd->models->working_set; - file = working_set->files + buffer->buffer_id; - if (!file->state.is_dummy && file_is_ready(file)){ + file = working_set_get_file(working_set, buffer->buffer_id, 1).file; + if (file && file_is_ready(file)){ size = buffer_size(&file->state.buffer); if (0 <= start && start <= end && end <= size){ result = 1; @@ -2062,8 +2096,8 @@ extern "C"{ if (buffer->exists){ models = cmd->models; working_set = &models->working_set; - file = working_set->files + buffer->buffer_id; - if (!file->state.is_dummy && file_is_ready(file)){ + file = working_set_get_file(working_set, buffer->buffer_id, 1).file; + if (file && file_is_ready(file)){ size = buffer_size(&file->state.buffer); if (0 <= start && start <= end && end <= size){ result = 1; @@ -2092,8 +2126,8 @@ extern "C"{ if (buffer->exists){ working_set = &cmd->models->working_set; - file = working_set->files + buffer->buffer_id; - if (!file->state.is_dummy && file_is_ready(file)){ + file = working_set_get_file(working_set, buffer->buffer_id, 1).file; + if (file && file_is_ready(file)){ result = 1; size = buffer_size(&file->state.buffer); if (pos < 0) pos = 0; @@ -2106,13 +2140,43 @@ extern "C"{ return(result); } - GET_VIEW_MAX_INDEX_SIG(external_get_view_max_index){ + GET_VIEW_FIRST_SIG(external_get_view_first){ Command_Data *cmd = (Command_Data*)app->cmd_context; - Live_Views *live_set = cmd->live_set; - int max = live_set->max + 1; - return(max); + Editing_Layout *layout = &cmd->models->layout; + View_Summary view = {}; + + Panel *panel = layout->used_sentinel.next; + + Assert(panel != &layout->used_sentinel); + fill_view_summary(&view, panel->view, &cmd->vars->live_set, &cmd->models->working_set); + + return(view); } - + + GET_VIEW_NEXT_SIG(external_get_view_next){ + Command_Data *cmd = (Command_Data*)app->cmd_context; + Editing_Layout *layout = &cmd->models->layout; + Live_Views *live_set = &cmd->vars->live_set; + View *vptr; + Panel *panel; + int index = view->view_id - 1; + + if (index >= 0 && index < live_set->max){ + vptr = live_set->views + index; + panel = vptr->panel; + if (panel) panel = panel->next; + if (panel && panel != &layout->used_sentinel){ + fill_view_summary(view, panel->view, &cmd->vars->live_set, &cmd->models->working_set); + } + else{ + *view = {}; + } + } + else{ + *view = {}; + } + } + GET_VIEW_SIG(external_get_view){ Command_Data *cmd = (Command_Data*)app->cmd_context; View_Summary view = {}; @@ -2150,19 +2214,23 @@ extern "C"{ Live_Views *live_set; View *vptr; int result = 0; + int view_id; if (view->exists){ live_set = cmd->live_set; - vptr = live_set->views + view->view_id; - result = 1; - if (seek.type == buffer_seek_line_char && seek.character <= 0){ - seek.character = 1; + view_id = view->view_id - 1; + if (view_id >= 0 && view_id < live_set->max){ + vptr = live_set->views + view_id; + result = 1; + if (seek.type == buffer_seek_line_char && seek.character <= 0){ + seek.character = 1; + } + vptr->cursor = view_compute_cursor(vptr, seek); + if (set_preferred_x){ + vptr->preferred_x = view_get_cursor_x(vptr); + } + fill_view_summary(view, vptr, live_set, &cmd->models->working_set); } - vptr->cursor = view_compute_cursor(vptr, seek); - if (set_preferred_x){ - vptr->preferred_x = view_get_cursor_x(vptr); - } - fill_view_summary(view, vptr, live_set, &cmd->models->working_set); } return(result); @@ -2174,22 +2242,23 @@ extern "C"{ View *vptr; Full_Cursor cursor; int result = 0; + int view_id; if (view->exists){ live_set = cmd->live_set; - vptr = live_set->views + view->view_id; - result = 1; - if (seek.type == buffer_seek_line_char && seek.character <= 0){ - seek.character = 1; + view_id = view->view_id - 1; + if (view_id >= 0 && view_id < live_set->max){ + vptr = live_set->views + view_id; + result = 1; + if (seek.type != buffer_seek_pos){ + cursor = view_compute_cursor(vptr, seek); + vptr->mark = cursor.pos; + } + else{ + vptr->mark = seek.pos; + } + fill_view_summary(view, vptr, live_set, &cmd->models->working_set); } - if (seek.type != buffer_seek_pos){ - cursor = view_compute_cursor(vptr, seek); - vptr->mark = cursor.pos; - } - else{ - vptr->mark = seek.pos; - } - fill_view_summary(view, vptr, live_set, &cmd->models->working_set); } return(result); @@ -2200,18 +2269,22 @@ extern "C"{ Live_Views *live_set; View *vptr; int result = 0; + int view_id; if (view->exists){ live_set = cmd->live_set; - vptr = live_set->views + view->view_id; - result = 1; - if (turn_on){ - view_set_temp_highlight(vptr, start, end); + view_id = view->view_id - 1; + if (view_id >= 0 && view_id < live_set->max){ + vptr = live_set->views + view_id; + result = 1; + if (turn_on){ + view_set_temp_highlight(vptr, start, end); + } + else{ + vptr->show_temp_highlight = 0; + } + fill_view_summary(view, vptr, live_set, &cmd->models->working_set); } - else{ - vptr->show_temp_highlight = 0; - } - fill_view_summary(view, vptr, live_set, &cmd->models->working_set); } return(result); @@ -2221,23 +2294,22 @@ extern "C"{ Command_Data *cmd = (Command_Data*)app->cmd_context; Live_Views *live_set; View *vptr; - Editing_File *file; + Get_File_Result file; Working_Set *working_set; App_Models *models; - int max, result = 0; + int result = 0; if (view->exists){ models = cmd->models; live_set = cmd->live_set; vptr = live_set->views + view->view_id; working_set = &models->working_set; - max = working_set->file_index_count; - if (buffer_id >= 0 && buffer_id < max){ - file = working_set->files + buffer_id; - if (!file->state.is_dummy){ - view_set_file(vptr, file, models, - cmd->system, models->hooks[hook_open_file], &app_links); - } + file = working_set_get_file(working_set, buffer_id, 1); + + if (file.file){ + result = 1; + view_set_file(vptr, file.file, models, + cmd->system, models->hooks[hook_open_file], &app_links); } fill_view_summary(view, vptr, live_set, working_set); @@ -2317,9 +2389,12 @@ app_links_init(System_Functions *system, void *data, int size){ 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_first = external_get_buffer_first; + app_links.get_buffer_next = external_get_buffer_next; + app_links.get_buffer = external_get_buffer; app_links.get_active_buffer = external_get_active_buffer; + app_links.get_parameter_buffer = external_get_parameter_buffer; app_links.get_buffer_by_name = external_get_buffer_by_name; app_links.refresh_buffer = external_refresh_buffer; @@ -2328,7 +2403,9 @@ app_links_init(System_Functions *system, void *data, int size){ app_links.buffer_read_range = external_buffer_read_range; app_links.buffer_replace_range = external_buffer_replace_range; - app_links.get_view_max_index = external_get_view_max_index; + app_links.get_view_first = external_get_view_first; + app_links.get_view_next = external_get_view_next; + app_links.get_view = external_get_view; app_links.get_active_view = external_get_active_view; @@ -3047,7 +3124,7 @@ App_Init_Sig(app_init){ if (!did_top) setup_top_commands(&models->map_top, &models->mem.part, global); if (!did_file) setup_file_commands(&models->map_file, &models->mem.part, global); -#if 1 || !defined(FRED_SUPER) +#if defined(FRED_SUPER) models->hooks[hook_start] = 0; #endif @@ -3103,20 +3180,31 @@ App_Init_Sig(app_init){ font_set_add(partition, models->font_set, file_name, name, pt_size); } } - + // NOTE(allen): file setup - models->working_set.file_index_count = 1; - models->working_set.file_max_count = 120; - models->working_set.files = push_array( - partition, Editing_File, models->working_set.file_max_count); + { + models->working_set.file_count = 0; + models->working_set.file_max = 119; + models->working_set.files = push_array( + partition, Editing_File, models->working_set.file_max + 1); - file_get_dummy(&models->working_set.files[0]); + models->working_set.files[0].state.is_dummy = 1; - models->working_set.table.max = models->working_set.file_max_count * 3 / 2; - models->working_set.table.count = 0; - models->working_set.table.table = push_array( - partition, File_Table_Entry, models->working_set.table.max); - memset(models->working_set.table.table, 0, sizeof(File_Table_Entry) * models->working_set.table.max); + dll_init_sentinel(&models->working_set.free_sentinel); + dll_init_sentinel(&models->working_set.used_sentinel); + + Editing_File *file = models->working_set.files + 1; + i32 max = models->working_set.file_max; + for (i32 i = 0; i < max; ++i, ++file){ + dll_insert(&models->working_set.free_sentinel, &file->node); + } + + models->working_set.table.max = models->working_set.file_max * 3 / 2; + models->working_set.table.count = 0; + models->working_set.table.table = push_array( + partition, File_Table_Entry, models->working_set.table.max); + memset(models->working_set.table.table, 0, sizeof(File_Table_Entry) * models->working_set.table.max); + } // NOTE(allen): clipboard setup models->working_set.clipboard_max_size = ArrayCount(models->working_set.clipboards); @@ -3146,15 +3234,15 @@ App_Init_Sig(app_init){ models->palette_size = 40; models->palette = push_array(partition, u32, models->palette_size); - + // NOTE(allen): init first panel Panel_And_ID p = layout_alloc_panel(&models->layout); panel_make_empty(system, exchange, vars, p.panel); models->layout.active_panel = p.id; - + String hdbase = make_fixed_width_string(models->hot_dir_base_); hot_directory_init(&models->hot_directory, hdbase, current_directory, system->slash); - + // NOTE(allen): child proc list setup i32 max_children = 16; partition_align(partition, 8); @@ -3166,6 +3254,12 @@ App_Init_Sig(app_init){ vars->sys_app_max = exchange->file.max; vars->sys_app_count = 0; vars->sys_app_bindings = (Sys_App_Binding*)push_array(partition, Sys_App_Binding, vars->sys_app_max); + + // NOTE(allen): parameter setup + i32 max = models->working_set.file_max; + models->buffer_param_indices = push_array(partition, i32, max); + models->buffer_param_max = max; + models->buffer_param_count = 0; } App_Step_Sig(app_step){ @@ -3186,15 +3280,21 @@ App_Step_Sig(app_step){ String *dest = working_set_next_clipboard_string(&models->mem.general, &models->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 < models->working_set.file_index_count; ++i){ - Editing_File *file = models->working_set.files + i; + { + File_Node *node, *used_nodes; + Editing_File *file; + u64 time_stamp; - if (!file->state.is_dummy){ - u64 time_stamp = system->file_time_stamp(make_c_str(file->name.source_path)); + used_nodes = &models->working_set.used_sentinel; + for (dll_items(node, used_nodes)){ + file = (Editing_File*)node; + time_stamp = system->file_time_stamp(make_c_str(file->name.source_path)); + + // TODO(allen): This is a bit wasteful! Let's dial it in a bit. 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){ @@ -3222,17 +3322,12 @@ App_Step_Sig(app_step){ for (system->cli_begin_update(&proc->cli); 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; - spec.step.edit.start = buffer_size(&out_file->state.buffer); - spec.step.edit.end = spec.step.edit.start; - spec.step.edit.len = amount; - spec.step.pre_pos = new_cursor; - spec.step.post_pos = spec.step.edit.start + amount; - spec.str = (u8*)dest; - file_do_single_edit(system, &models->mem, out_file, &models->layout, spec, hist_normal); + + i32 end = buffer_size(&out_file->state.buffer); + file_replace_range(system, models, out_file, + end, end, dest, amount, end + amount, 1); app_result.redraw = 1; - new_cursor = spec.step.post_pos; + new_cursor = end + amount; } if (system->cli_end_update(&proc->cli)){ @@ -3244,24 +3339,16 @@ App_Step_Sig(app_step){ 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); - spec.step.edit.end = spec.step.edit.start; - spec.step.edit.len = str.size; - spec.step.pre_pos = new_cursor; - spec.step.post_pos = spec.step.edit.start + str.size; - spec.str = (u8*)str.str; - file_do_single_edit(system, &models->mem, out_file, - &models->layout, spec, hist_normal); + i32 end = buffer_size(&out_file->state.buffer); + file_replace_range(system, models, out_file, + end, end, str.str, str.size, end + str.size, 1); app_result.redraw = 1; - new_cursor = spec.step.post_pos; + new_cursor = end + str.size; } new_cursor = 0; - View_Iter iter; - for (iter = file_view_iter_init(&models->layout, out_file, 0); + for (View_Iter iter = file_view_iter_init(&models->layout, out_file, 0); file_view_iter_good(iter); iter = file_view_iter_next(iter)){ view_cursor_move(iter.view, new_cursor); @@ -3424,7 +3511,7 @@ App_Step_Sig(app_step){ i32 i; String file_name; - Panel *panel = &models->layout.used_sentinel; + Panel *panel = models->layout.used_sentinel.next; for (i = 0; i < models->settings.init_files_count; ++i, panel = panel->next){ file_name = make_string_slowly(models->settings.init_files[i]); @@ -3569,70 +3656,6 @@ App_Step_Sig(app_step){ update_command_data(vars, cmd); ProfileEnd(command_coroutine); - - // NOTE(allen): pass raw input to the panels - ProfileStart(step); - - 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; - if (!consumed_input[0]){ - active_input.keys = key_data; - } - else if (!consumed_input[1]){ - for (i32 i = 0; i < key_data.count; ++i){ - Key_Event_Data key = get_single_key(&key_data, i); - if (key.keycode == key_esc){ - active_input.keys.count = 1; - active_input.keys.keys[0] = key; - break; - } - } - } - - 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, *used_panels; - View *view; - b32 active; - - used_panels = &models->layout.used_sentinel; - for (dll_items(panel, used_panels)){ - view = panel->view; - active = (panel == cmd->panel); - Input_Summary input = (active)?(active_input):(dead_input); - if (panel == mouse_panel && !mouse->out_of_window){ - input.mouse = mouse_state; - } - if (step_file_view(system, exchange, view, panel->inner, active, &input)){ - app_result.redraw = 1; - } - } - } - - update_command_data(vars, cmd); - ProfileEnd(step); // NOTE(allen): command execution ProfileStart(command); @@ -3697,6 +3720,70 @@ App_Step_Sig(app_step){ update_command_data(vars, cmd); ProfileEnd(command); + // NOTE(allen): pass raw input to the panels + ProfileStart(step); + + 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; + if (!consumed_input[0]){ + active_input.keys = key_data; + } + else if (!consumed_input[1]){ + for (i32 i = 0; i < key_data.count; ++i){ + Key_Event_Data key = get_single_key(&key_data, i); + if (key.keycode == key_esc){ + active_input.keys.count = 1; + active_input.keys.keys[0] = key; + break; + } + } + } + + 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, *used_panels; + View *view; + b32 active; + + used_panels = &models->layout.used_sentinel; + for (dll_items(panel, used_panels)){ + view = panel->view; + active = (panel == cmd->panel); + Input_Summary input = (active)?(active_input):(dead_input); + if (panel == mouse_panel && !mouse->out_of_window){ + input.mouse = mouse_state; + } + if (step_file_view(system, exchange, view, panel->inner, active, &input)){ + app_result.redraw = 1; + } + } + } + + update_command_data(vars, cmd); + ProfileEnd(step); + ProfileStart(resizing); // NOTE(allen): panel resizing switch (vars->state){ @@ -3823,14 +3910,15 @@ App_Step_Sig(app_step){ Working_Set *working_set = &models->working_set; if (exchange_file_ready(exchange, binding->sys_id, &data, &size, &max)){ - ed_file = working_set->files + binding->app_id; + ed_file = working_set_get_file(working_set, binding->app_id, 1).file; + Assert(ed_file); + filename = exchange_file_filename(exchange, binding->sys_id); preload_settings = ed_file->preload; if (data){ String val = make_string((char*)data, size); // TODO(allen): reduce to just passing models - file_create_from_string(system, mem, working_set, ed_file, filename, - models->font_set, models->global_font.font_id, val); + file_create_from_string(system, models, ed_file, filename, val); if (ed_file->settings.tokens_exist){ file_first_lex_parallel(system, general, ed_file); @@ -3844,27 +3932,24 @@ App_Step_Sig(app_step){ } else{ if (binding->fail & SysAppCreateNewBuffer){ - file_create_empty(system, mem, working_set, ed_file, filename, - models->font_set, models->global_font.font_id); + file_create_empty(system, models, ed_file, filename); if (binding->fail & SysAppCreateView){ view_file_in_panel(cmd, binding->panel, ed_file); } } else{ table_remove(&models->working_set.table, ed_file->name.source_path); - file_get_dummy(ed_file); + working_set_free_file(&models->working_set, ed_file); } app_result.redraw = 1; } - if (!ed_file->state.is_dummy){ - for (View_Iter iter = file_view_iter_init(&models->layout, ed_file, 0); - file_view_iter_good(iter); - iter = file_view_iter_next(iter)){ - view_measure_wraps(system, general, iter.view); - view_cursor_move(iter.view, preload_settings.start_line, 0); - } + for (View_Iter iter = file_view_iter_init(&models->layout, ed_file, 0); + file_view_iter_good(iter); + iter = file_view_iter_next(iter)){ + view_measure_wraps(system, general, iter.view); + view_cursor_move(iter.view, preload_settings.start_line, 0); } exchange_free_file(exchange, binding->sys_id); @@ -3879,7 +3964,7 @@ App_Step_Sig(app_step){ exchange_clear_file(exchange, binding->sys_id); } - Editing_File *file = get_file(working_set, binding->app_id); + Editing_File *file = working_set_get_file(working_set, binding->app_id, 1).file; if (file){ file_synchronize_times(system, file, file->name.source_path.str); } @@ -3901,7 +3986,6 @@ App_Step_Sig(app_step){ // NOTE(allen): process as many delayed actions as possible ProfileStart(delayed_actions); if (models->delay1.count > 0){ - Style_Font *global_font = &models->global_font; Working_Set *working_set = &models->working_set; Mem_Options *mem = &models->mem; General_Memory *general = &mem->general; @@ -3939,10 +4023,8 @@ App_Step_Sig(app_step){ } } else{ - if (result.file->state.is_dummy || result.file->state.is_loading){ - // do nothing - } - else{ + Assert(result.file); + if (!result.file->state.is_loading){ view_file_in_panel(cmd, panel, result.file); } } @@ -3997,10 +4079,10 @@ App_Step_Sig(app_step){ else if (string.str && string.size > 0){ file = working_set_lookup_file(working_set, string); } - if (file && !file->state.is_dummy){ + if (file){ 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)); + app_push_file_binding(vars, sys_id, (i32)(file - working_set->files)); } else{ delayed_action_repush(&models->delay2, act); @@ -4012,8 +4094,7 @@ App_Step_Sig(app_step){ { if (!file){ if (panel){ - View *view; - view = panel->view; + View *view = panel->view; Assert(view); file = view->file; } @@ -4023,12 +4104,12 @@ App_Step_Sig(app_step){ } // TODO(allen): We could handle the case where someone tries to save the same thing // twice... that would be nice to have under control. - if (file && !file->state.is_dummy && buffer_needs_save(file)){ + if (file){ i32 sys_id = file_save(system, exchange, mem, file, file->name.source_path.str); if (sys_id){ // TODO(allen): This is fishy! Shouldn't we bind it to a file name instead? This file // might be killed before we get notified that the saving is done! - app_push_file_binding(vars, sys_id, get_file_id(working_set, file)); + app_push_file_binding(vars, sys_id, (i32)(file - working_set->files)); } else{ delayed_action_repush(&models->delay2, act); @@ -4039,8 +4120,7 @@ App_Step_Sig(app_step){ 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, - models->font_set, global_font->font_id); + file_create_empty(system, models, file.file, string.str); table_add(&working_set->table, file.file->name.source_path, file.index); View *view = panel->view; @@ -4071,7 +4151,7 @@ App_Step_Sig(app_step){ 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, &models->layout); + kill_file(system, exchange, models, file); } }break; @@ -4098,7 +4178,7 @@ App_Step_Sig(app_step){ } else{ table_remove(&working_set->table, file->name.source_path); - kill_file(system, exchange, general, file, &models->layout); + kill_file(system, exchange, models, file); } } }break; @@ -4136,16 +4216,16 @@ App_Step_Sig(app_step){ if (models->global_font.font_changed){ models->global_font.font_changed = 0; - Editing_File *file = models->working_set.files; - for (i32 i = models->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(models->font_set, models->global_font.font_id)->font; - float *advance_data = 0; - if (font) advance_data = font->advance_data; - - file_measure_starts_widths(system, &models->mem.general, - &file->state.buffer, advance_data); - } + File_Node *node, *used_nodes; + Editing_File *file; + Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font; + float *advance_data = 0; + if (font) advance_data = font->advance_data; + + used_nodes = &models->working_set.used_sentinel; + for (dll_items(node, used_nodes)){ + file = (Editing_File*)node; + file_measure_starts_widths(system, &models->mem.general, &file->state.buffer, advance_data); } Panel *panel, *used_panels; diff --git a/4ed_app_settings.h b/4ed_app_settings.h index ac2cb371..0387853b 100644 --- a/4ed_app_settings.h +++ b/4ed_app_settings.h @@ -39,6 +39,9 @@ struct App_Models{ Custom_Command_Function *hooks[hook_type_count]; + i32 *buffer_param_indices; + i32 buffer_param_count, buffer_param_max; + Font_Set *font_set; Style_Font global_font; Style style; diff --git a/4ed_file.cpp b/4ed_file.cpp index a10307d2..ec776908 100644 --- a/4ed_file.cpp +++ b/4ed_file.cpp @@ -92,14 +92,13 @@ struct Text_Effect{ // file is still streaming in, and all operations except for the // initial allocation of the file. struct Editing_File_Settings{ - Font_Set *set; i32 base_map_id; i32 dos_write_mode; b32 unwrapped_lines; b8 tokens_exist; - b8 super_locked; b8 is_initialized; b8 unimportant; + b8 read_only; }; // NOTE(allen): This part of the Editing_File is cleared whenever @@ -142,7 +141,12 @@ struct Editing_File_Name{ String extension; }; +struct File_Node{ + File_Node *next, *prev; +}; + struct Editing_File{ + File_Node node; Editing_File_Settings settings; union{ Editing_File_State state; @@ -237,7 +241,9 @@ table_remove(File_Table *table, String name){ struct Working_Set{ Editing_File *files; - i32 file_index_count, file_max_count; + i32 file_count, file_max; + File_Node free_sentinel; + File_Node used_sentinel; File_Table table; @@ -418,11 +424,11 @@ working_set_contains(Working_Set *working, String filename){ Editing_File *result = 0; i32 id; if (table_find(&working->table, filename, &id)){ - if (id < working->file_max_count){ + if (id >= 0 && id < working->file_max){ result = working->files + id; } } - return result; + return (result); } // TODO(allen): Find a way to choose an ordering for these so it picks better first options. @@ -431,19 +437,74 @@ working_set_lookup_file(Working_Set *working_set, String string){ Editing_File *file = working_set_contains(working_set, string); if (!file){ - i32 file_i; - i32 end = working_set->file_index_count; - file = working_set->files; - for (file_i = 0; file_i < end; ++file_i, ++file){ - if (file->name.live_name.str && - (string.size == 0 || has_substr(file->name.live_name, string))){ - break; - } - } - if (file_i == end) file = 0; + File_Node *node, *used_nodes; + used_nodes = &working_set->used_sentinel; + for (dll_items(node, used_nodes)){ + file = (Editing_File*)node; + if (string.size == 0 || has_substr(file->name.live_name, string)){ + break; + } + } + if (node == used_nodes) file = 0; } - return file; + return (file); +} + +struct Get_File_Result{ + Editing_File *file; + i32 index; +}; + +internal Get_File_Result +working_set_get_available_file(Working_Set *working_set){ + Get_File_Result result = {}; + File_Node *node; + + if (working_set->file_count < working_set->file_max){ + node = working_set->free_sentinel.next; + Assert(node != &working_set->free_sentinel); + + result.file = (Editing_File*)node; + result.index = (i32)(result.file - working_set->files); + + ++working_set->file_count; + + dll_remove(node); + *result.file = {}; + dll_insert(&working_set->used_sentinel, node); + } + + return result; +} + +inline void +working_set_free_file(Working_Set *working_set, Editing_File *file){ + file->state.is_dummy = 1; + dll_remove(&file->node); + dll_insert(&working_set->free_sentinel, &file->node); + --working_set->file_count; +} + +inline Get_File_Result +working_set_get_file(Working_Set *working_set, i32 id, b32 require_active){ + Get_File_Result result = {}; + if (id > 0 && id <= working_set->file_max){ + result.file = working_set->files + id; + result.index = id; + if (result.file->state.is_dummy && require_active){ + result.file = 0; + result.index = 0; + } + } + return(result); +} + +inline void +file_set_to_loading(Editing_File *file){ + file->state = {}; + file->settings = {}; + file->state.is_loading = 1; } // BOTTOM diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index c662d3aa..32adc1ab 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -65,6 +65,7 @@ enum Color_View_Mode{ struct View{ View *next, *prev; + b32 in_use; App_Models *models; @@ -74,18 +75,6 @@ struct View{ Editing_File *file; - Editing_Layout *layout; - - Style_Font *global_font; - Style *style; - Working_Set *working_set; - Delay *delay; - Font_Set *font_set; - App_Settings *settings; - Hot_Directory *hot_directory; - Mem_Options *mem; - Style_Library *styles; - UI_State ui_state; View_UI showing_ui; @@ -94,8 +83,8 @@ struct View{ Interactive_Action action; b32 finished; char query_[256]; - String query; char dest_[256]; + String query; String dest; i32 user_action; @@ -134,7 +123,7 @@ struct View{ b32 unwrapped_lines; b32 show_whitespace; - b32 locked; + b32 file_locked; i32 line_count, line_max; f32 *line_wrap_y; @@ -148,10 +137,17 @@ struct View_And_ID{ i32 id; }; -inline void -view_set_first(View *new_view, Panel *panel){ - new_view->panel = panel; - panel->view = new_view; +#define LockLevel_Open 0 +#define LockLevel_NoWrite 1 +#define LockLevel_NoUpdate 2 + +inline i32 +view_lock_level(View *view){ + i32 result = LockLevel_Open; + if (view->showing_ui != VUI_None) result = LockLevel_NoUpdate; + else if (view->file_locked || + (view->file && view->file->settings.read_only)) result = LockLevel_NoWrite; + return(result); } inline f32 @@ -166,22 +162,50 @@ view_compute_height(View *view){ return (f32)(panel->inner.y1 - panel->inner.y0); } -inline i32 -get_file_id(Working_Set *working_set, Editing_File *file){ - i32 result = (i32)(file - working_set->files); - return(result); -} +struct View_Iter{ + View *view; + + Editing_File *file; + View *skip; + Panel *used_panels; + Panel *panel; +}; -inline Editing_File* -get_file(Working_Set *working_set, i32 file_id){ - Editing_File *result = working_set->files + file_id; - if (!buffer_good(&result->state.buffer) || result->state.is_dummy){ - result = 0; +internal View_Iter +file_view_iter_next(View_Iter iter){ + View *file_view; + + for (iter.panel = iter.panel->next; iter.panel != iter.used_panels; iter.panel = iter.panel->next){ + file_view = iter.panel->view; + if (file_view != iter.skip && (file_view->file == iter.file || iter.file == 0)){ + iter.view = file_view; + break; + } } + + return(iter); +} + +internal View_Iter +file_view_iter_init(Editing_Layout *layout, Editing_File *file, View *skip){ + View_Iter result; + result.used_panels = &layout->used_sentinel; + result.panel = result.used_panels; + result.file = file; + result.skip = skip; + + result = file_view_iter_next(result); + return(result); } -inline bool32 +internal b32 +file_view_iter_good(View_Iter iter){ + b32 result = (iter.panel != iter.used_panels); + return(result); +} + +inline b32 starts_new_line(u8 character){ return (character == '\n'); } @@ -196,9 +220,6 @@ file_init_strings(Editing_File *file){ inline void file_set_name(Working_Set *working_set, Editing_File *file, char *filename){ String f, ext; - Editing_File *file_ptr; - i32 i, count, file_x, original_len; - b32 hit_conflict; Assert(file->name.live_name.str != 0); @@ -216,28 +237,35 @@ file_set_name(Working_Set *working_set, Editing_File *file, char *filename){ copy(&file->name.extension, ext); } - original_len = file->name.live_name.size; - count = working_set->file_index_count; - hit_conflict = 1; - file_x = 0; - while (hit_conflict){ - hit_conflict = 0; - file_ptr = working_set->files; - for (i = 0; i < count; ++i, ++file_ptr){ - if (file_ptr != file && !file_ptr->state.is_dummy && file_is_ready(file_ptr)){ - if (match(file->name.live_name, file_ptr->name.live_name)){ - ++file_x; - hit_conflict = 1; - break; + { + File_Node *node, *used_nodes; + Editing_File *file_ptr; + i32 file_x, original_len; + b32 hit_conflict; + + used_nodes = &working_set->used_sentinel; + original_len = file->name.live_name.size; + hit_conflict = 1; + file_x = 0; + while (hit_conflict){ + hit_conflict = 0; + for (dll_items(node, used_nodes)){ + file_ptr = (Editing_File*)node; + if (file_ptr != file && file_is_ready(file_ptr)){ + if (match(file->name.live_name, file_ptr->name.live_name)){ + ++file_x; + hit_conflict = 1; + break; + } } } - } - if (hit_conflict){ - file->name.live_name.size = original_len; - append(&file->name.live_name, " <"); - append_int_to_str(file_x, &file->name.live_name); - append(&file->name.live_name, ">"); + if (hit_conflict){ + file->name.live_name.size = original_len; + append(&file->name.live_name, " <"); + append_int_to_str(file_x, &file->name.live_name); + append(&file->name.live_name, ">"); + } } } } @@ -402,17 +430,6 @@ file_measure_starts_widths(System_Functions *system, General_Memory *general, buffer->widths_count = state.count; } -internal void -file_remeasure_starts_(System_Functions *system, - General_Memory *general, Buffer_Type *buffer, - i32 line_start, i32 line_end, i32 line_shift, - i32 character_shift){ - ProfileMomentFunction(); - Assert(buffer->line_starts); - file_grow_starts_widths_as_needed(general, buffer, line_shift); - buffer_remeasure_starts(buffer, line_start, line_end, line_shift, character_shift); -} - struct Opaque_Font_Advance{ void *data; int stride; @@ -501,13 +518,13 @@ alloc_for_buffer(void *context, int *size){ } internal void -file_create_from_string(System_Functions *system, Mem_Options *mem, - Working_Set *working_set, Editing_File *file, char *filename, - Font_Set *set, i16 font_id, - String val, b8 super_locked = 0){ - - General_Memory *general = &mem->general; - Partition *part = &mem->part; +file_create_from_string(System_Functions *system, App_Models *models, + Editing_File *file, char *filename, String val, b8 read_only = 0){ + + Font_Set *font_set = models->font_set; + Working_Set *working_set = &models->working_set; + General_Memory *general = &models->mem.general; + Partition *part = &models->mem.part; Buffer_Init_Type init; i32 page_size, scratch_size, init_success; @@ -531,17 +548,17 @@ file_create_from_string(System_Functions *system, Mem_Options *mem, file_init_strings(file); file_set_name(working_set, file, (char*)filename); - file->state.font_id = font_id; + file->state.font_id = models->global_font.font_id; file_synchronize_times(system, file, filename); - Render_Font *font = get_font_info(set, font_id)->font; + Render_Font *font = get_font_info(font_set, file->state.font_id)->font; float *advance_data = 0; if (font) advance_data = font->advance_data; file_measure_starts_widths(system, general, &file->state.buffer, advance_data); - file->settings.super_locked = super_locked; - if (!super_locked){ + file->settings.read_only = read_only; + if (!read_only){ i32 request_size = Kbytes(64); file->state.undo.undo.max = request_size; file->state.undo.undo.strings = (u8*)general_memory_allocate(general, request_size, BUBBLE_UNDO_STRING); @@ -570,59 +587,19 @@ file_create_from_string(System_Functions *system, Mem_Options *mem, } internal b32 -file_create_empty( - System_Functions *system, Mem_Options *mem, - Working_Set *working_set, Editing_File *file, - char *filename, Font_Set *set, i16 font_id){ +file_create_empty(System_Functions *system, + App_Models *models, Editing_File *file, char *filename){ - b32 result = 1; - String empty_str = {}; - file_create_from_string(system, mem, working_set, file, filename, set, font_id, empty_str); - return (result); + file_create_from_string(system, models, file, filename, {}); + return (1); } internal b32 -file_create_super_locked( - System_Functions *system, App_Models *models, - Editing_File *file, char *filename){ - b32 result = 1; - String empty_str = {}; - file_create_from_string(system, &models->mem, &models->working_set, - file, filename, models->font_set, models->global_font.font_id, empty_str, 1); - return (result); -} - -struct Get_File_Result{ - Editing_File *file; - i32 index; -}; - -// TODO(allen): convert buffers to a dll allocation scheme -internal Get_File_Result -working_set_get_available_file(Working_Set *working_set){ - Get_File_Result result = {}; - - for (i32 buffer_index = 1; buffer_index < working_set->file_max_count; ++buffer_index){ - if (buffer_index == working_set->file_index_count || - working_set->files[buffer_index].state.is_dummy){ - result.index = buffer_index; - result.file = working_set->files + buffer_index; - if (buffer_index == working_set->file_index_count){ - ++working_set->file_index_count; - } - break; - } - } - - if (result.file) *result.file = {}; - - return result; -} - -internal i32 -working_set_get_index(Working_Set *working_set, Editing_File *file){ - i32 index = (i32)(file - working_set->files); - return(index); +file_create_read_only(System_Functions *system, + App_Models *models, Editing_File *file, char *filename){ + + file_create_from_string(system, models, file, filename, {}, 1); + return (1); } internal void @@ -660,19 +637,6 @@ file_close(System_Functions *system, General_Memory *general, Editing_File *file } } -inline void -file_get_dummy(Editing_File *file){ - *file = {}; - file->state.is_dummy = 1; -} - -inline void -file_set_to_loading(Editing_File *file){ - file->state = {}; - file->settings = {}; - file->state.is_loading = 1; -} - struct Shift_Information{ i32 start, end, amount; }; @@ -863,10 +827,6 @@ file_relex_parallel(System_Functions *system, } } -internal bool32 -file_grow_as_needed_(General_Memory *general, Editing_File *file, i32 new_size){ -} - internal void undo_stack_grow_string(General_Memory *general, Edit_Stack *stack, i32 extra_size){ i32 old_max = stack->max; @@ -1147,7 +1107,8 @@ file_post_history(General_Memory *general, Editing_File *file, inline Full_Cursor view_compute_cursor_from_pos(View *view, i32 pos){ Editing_File *file = view->file; - Render_Font *font = get_font_info(view->font_set, view->global_font->font_id)->font; + App_Models *models = view->models; + Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font; Full_Cursor result = {}; if (font){ @@ -1161,7 +1122,8 @@ view_compute_cursor_from_pos(View *view, i32 pos){ inline Full_Cursor view_compute_cursor_from_unwrapped_xy(View *view, f32 seek_x, f32 seek_y, b32 round_down = 0){ Editing_File *file = view->file; - Render_Font *font = get_font_info(view->font_set, view->global_font->font_id)->font; + App_Models *models = view->models; + Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font; Full_Cursor result = {}; if (font){ @@ -1175,10 +1137,10 @@ view_compute_cursor_from_unwrapped_xy(View *view, f32 seek_x, f32 seek_y, b32 ro } internal Full_Cursor -view_compute_cursor_from_wrapped_xy(View *view, f32 seek_x, f32 seek_y, - b32 round_down = 0){ +view_compute_cursor_from_wrapped_xy(View *view, f32 seek_x, f32 seek_y, b32 round_down = 0){ Editing_File *file = view->file; - Render_Font *font = get_font_info(view->font_set, view->global_font->font_id)->font; + App_Models *models = view->models; + Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font; Full_Cursor result = {}; if (font){ @@ -1188,13 +1150,14 @@ view_compute_cursor_from_wrapped_xy(View *view, f32 seek_x, f32 seek_y, max_width, (f32)view->font_height, font->advance_data); } - return result; + return (result); } internal Full_Cursor view_compute_cursor_from_line_pos(View *view, i32 line, i32 pos){ Editing_File *file = view->file; - Render_Font *font = get_font_info(view->font_set, view->global_font->font_id)->font; + App_Models *models = view->models; + Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font; Full_Cursor result = {}; if (font){ @@ -1203,7 +1166,7 @@ view_compute_cursor_from_line_pos(View *view, i32 line, i32 pos){ view->line_wrap_y, max_width, (f32)view->font_height, font->advance_data); } - return result; + return (result); } inline Full_Cursor @@ -1228,7 +1191,7 @@ view_compute_cursor(View *view, Buffer_Seek seek){ break; } - return result; + return (result); } inline Full_Cursor @@ -1294,40 +1257,29 @@ view_get_cursor_y(View *view){ internal void view_set_file( // NOTE(allen): These parameters are always meaningful - View *view, - Editing_File *file, - App_Models *models, + View *view, Editing_File *file, App_Models *models, // NOTE(allen): Necessary when file != 0 - System_Functions *system, - Hook_Function *open_hook, - Application_Links *app){ + System_Functions *system, Hook_Function *open_hook, Application_Links *app){ Font_Info *fnt_info; // NOTE(allen): This is actually more like view_set_style right? fnt_info = get_font_info(models->font_set, models->global_font.font_id); - view->global_font = &models->global_font; - view->style = &models->style; view->font_advance = fnt_info->advance; view->font_height = fnt_info->height; // NOTE(allen): Stuff that doesn't assume file exists. view->file = file; - view->cursor = {}; // NOTE(allen): Stuff that does assume file exists. - if (file){ - // NOTE(allen): Isn't this a bit clumsy? - file->settings.set = models->font_set; - - view->locked = file->settings.super_locked; + //view->locked = file->settings.super_locked; view->unwrapped_lines = file->settings.unwrapped_lines; if (file_is_ready(file)){ - view_measure_wraps(system, &view->mem->general, view); + view_measure_wraps(system, &models->mem.general, view); view->cursor = view_compute_cursor_from_pos(view, file->state.cursor_pos); view->reinit_scrolling = 1; @@ -1338,7 +1290,9 @@ view_set_file( // Just accept it and pass the file to the open hook when it is loaded. if (file){ if (open_hook && file->settings.is_initialized == 0){ + models->buffer_param_indices[models->buffer_param_count++] = (i32)(file - models->working_set.files); open_hook(app); + models->buffer_param_count = 0; file->settings.is_initialized = 1; } } @@ -1683,10 +1637,14 @@ file_edit_cursor_fix(System_Functions *system, internal void file_do_single_edit(System_Functions *system, - Mem_Options *mem, Editing_File *file, - Editing_Layout *layout, Edit_Spec spec, History_Mode history_mode){ + App_Models *models, Editing_File *file, + Edit_Spec spec, History_Mode history_mode, b32 use_high_permission = 0){ ProfileMomentFunction(); - + if (!use_high_permission && file->settings.read_only) return; + + Mem_Options *mem = &models->mem; + Editing_Layout *layout = &models->layout; + // NOTE(allen): fixing stuff beforewards???? file_update_history_before_edit(mem, file, spec.step, spec.str, history_mode); file_pre_edit_maintenance(system, &mem->general, file); @@ -1722,7 +1680,7 @@ file_do_single_edit(System_Functions *system, i32 new_line_count = buffer_count_newlines(&file->state.buffer, start, start+str_len); i32 line_shift = new_line_count - replaced_line_count; - Render_Font *font = get_font_info(file->settings.set, file->state.font_id)->font; + Render_Font *font = get_font_info(models->font_set, file->state.font_id)->font; file_grow_starts_widths_as_needed(general, buffer, line_shift); buffer_remeasure_starts(buffer, line_start, line_end, line_shift, shift_amount); @@ -1754,17 +1712,14 @@ file_do_single_edit(System_Functions *system, } internal void -view_do_white_batch_edit(System_Functions *system, Mem_Options *mem, View *view, Editing_File *file, - Editing_Layout *layout, Edit_Spec spec, History_Mode history_mode){ - if (view->locked) return; - Assert(file); +file_do_white_batch_edit(System_Functions *system, App_Models *models, Editing_File *file, + Edit_Spec spec, History_Mode history_mode, b32 use_high_permission = 0){ ProfileMomentFunction(); + if (!use_high_permission && file->settings.read_only) return; - // NOTE(allen): fixing stuff "beforewards"???? - Assert(spec.str == 0); - file_update_history_before_edit(mem, file, spec.step, 0, history_mode); - file_pre_edit_maintenance(system, &mem->general, file); - + Mem_Options *mem = &models->mem; + Editing_Layout *layout = &models->layout; + // NOTE(allen): actual text replacement General_Memory *general = &mem->general; Partition *part = &mem->part; @@ -1779,8 +1734,9 @@ view_do_white_batch_edit(System_Functions *system, Mem_Options *mem, View *view, i32 scratch_size = partition_remaining(part); Buffer_Batch_State state = {}; i32 request_amount; - while (buffer_batch_edit_step(&state, &file->state.buffer, batch, (char*)str_base, batch_size, - part->base + part->pos, scratch_size, &request_amount)){ + while (buffer_batch_edit_step(&state, &file->state.buffer, batch, + (char*)str_base, batch_size, part->base + part->pos, + scratch_size, &request_amount)){ void *new_data = 0; if (request_amount > 0){ new_data = general_memory_allocate(general, request_amount, BUBBLE_BUFFER); @@ -1789,6 +1745,25 @@ view_do_white_batch_edit(System_Functions *system, Mem_Options *mem, View *view, if (old_data) general_memory_free(general, old_data); } + // NOTE(allen): meta data + { + Buffer_Measure_Starts state = {}; + Render_Font *font = get_font_info(models->font_set, file->state.font_id)->font; + float *advance_data = 0; + if (font) advance_data = font->advance_data; + buffer_measure_starts_widths(&state, &file->state.buffer, advance_data); + } + + // NOTE(allen): cursor fixing + { + Cursor_Fix_Descriptor desc = {}; + desc.is_batch = 1; + desc.batch = batch; + desc.batch_size = batch_size; + + file_edit_cursor_fix(system, part, general, file, layout, desc); + } + // NOTE(allen): token fixing if (file->state.tokens_complete){ Cpp_Token_Stack tokens = file->state.token_stack; @@ -1816,29 +1791,11 @@ view_do_white_batch_edit(System_Functions *system, Mem_Options *mem, View *view, token->start += shift_amount; } } - - // NOTE(allen): meta data - { - Buffer_Measure_Starts state = {}; - Render_Font *font = get_font_info(file->settings.set, file->state.font_id)->font; - float *advance_data = 0; - if (font) advance_data = font->advance_data; - buffer_measure_starts_widths(&state, &file->state.buffer, advance_data); - } - - // NOTE(allen): cursor fixing - Cursor_Fix_Descriptor desc = {}; - desc.is_batch = 1; - desc.batch = batch; - desc.batch_size = batch_size; - - file_edit_cursor_fix(system, part, general, file, layout, desc); } inline void -file_replace_range(System_Functions *system, - App_Models *models, Editing_File *file, - i32 start, i32 end, char *str, i32 len, i32 next_cursor){ +file_replace_range(System_Functions *system, App_Models *models, Editing_File *file, + i32 start, i32 end, char *str, i32 len, i32 next_cursor, b32 use_high_permission = 0){ Edit_Spec spec = {}; spec.step.type = ED_NORMAL; spec.step.edit.start = start; @@ -1847,22 +1804,13 @@ file_replace_range(System_Functions *system, spec.step.pre_pos = file->state.cursor_pos; spec.step.post_pos = next_cursor; spec.str = (u8*)str; - file_do_single_edit(system, &models->mem, file, &models->layout, spec, hist_normal); + file_do_single_edit(system, models, file, spec, hist_normal, use_high_permission); } inline void view_replace_range(System_Functions *system, App_Models *models, View *view, i32 start, i32 end, char *str, i32 len, i32 next_cursor){ - if (view->locked) return; - Edit_Spec spec = {}; - spec.step.type = ED_NORMAL; - spec.step.edit.start = start; - spec.step.edit.end = end; - spec.step.edit.len = len; - spec.step.pre_pos = view->cursor.pos; - spec.step.post_pos = next_cursor; - spec.str = (u8*)str; - file_do_single_edit(system, &models->mem, view->file, &models->layout, spec, hist_normal); + file_replace_range(system, models, view->file, start, end, str, len, next_cursor); } inline void @@ -1878,10 +1826,11 @@ view_post_paste_effect(View *view, i32 ticks, i32 start, i32 size, u32 color){ internal void view_undo_redo(System_Functions *system, - Mem_Options *mem, Editing_Layout *layout, View *view, Editing_File *file, + App_Models *models, View *view, Edit_Stack *stack, Edit_Type expected_type){ - if (view->locked) return; - if (file && stack->edit_count > 0){ + Editing_File *file = view->file; + + if (stack->edit_count > 0){ Edit_Step step = stack->edits[stack->edit_count-1]; Assert(step.type == expected_type); @@ -1893,32 +1842,30 @@ view_undo_redo(System_Functions *system, spec.step.edit.str_start = 0; spec.str = stack->strings + step.edit.str_start; - file_do_single_edit(system, mem, file, layout, spec, hist_normal); + file_do_single_edit(system, models, file, spec, hist_normal); if (expected_type == ED_UNDO) view_cursor_move(view, step.pre_pos); else view_cursor_move(view, step.post_pos); view->mark = view->cursor.pos; view_post_paste_effect(view, 10, step.edit.start, step.edit.len, - view->style->main.undo_color); + models->style.main.undo_color); } else{ TentativeAssert(spec.step.special_type == 1); - view_do_white_batch_edit(system, mem, view, file, layout, spec, hist_normal); + file_do_white_batch_edit(system, models, view->file, spec, hist_normal); } } } inline void view_undo(System_Functions *system, App_Models *models, View *view){ - Editing_File *file = view->file; - view_undo_redo(system, &models->mem, &models->layout, view, file, &file->state.undo.undo, ED_UNDO); + view_undo_redo(system, models, view, &view->file->state.undo.undo, ED_UNDO); } inline void view_redo(System_Functions *system, App_Models *models, View *view){ - Editing_File *file = view->file; - view_undo_redo(system, &models->mem, &models->layout, view, file, &file->state.undo.redo, ED_REDO); + view_undo_redo(system, models, view, &view->file->state.undo.redo, ED_REDO); } inline u8* @@ -1986,8 +1933,7 @@ file_dump_history(System_Functions *system, Mem_Options *mem, Editing_File *file #endif internal void -view_history_step(System_Functions *system, Mem_Options *mem, Editing_Layout *layout, View *view, History_Mode history_mode){ - if (view->locked) return; +view_history_step(System_Functions *system, App_Models *models, View *view, History_Mode history_mode){ Assert(history_mode != hist_normal); Editing_File *file = view->file; @@ -2018,7 +1964,7 @@ view_history_step(System_Functions *system, Mem_Options *mem, Editing_Layout *la spec.step.edit.str_start = 0; spec.str = file->state.undo.history.strings + step.edit.str_start; - file_do_single_edit(system, mem, file, layout, spec, history_mode); + file_do_single_edit(system, models, file, spec, history_mode); switch (spec.step.type){ case ED_NORMAL: @@ -2035,16 +1981,11 @@ view_history_step(System_Functions *system, Mem_Options *mem, Editing_Layout *la } else{ TentativeAssert(spec.step.special_type == 1); - view_do_white_batch_edit(system, mem, view, file, layout, spec, history_mode); + file_do_white_batch_edit(system, models, view->file, spec, history_mode); } } } -inline void -view_history_step(System_Functions *system, App_Models *models, View *view, History_Mode history_mode){ - view_history_step(system, &models->mem, &models->layout, view, history_mode); -} - // TODO(allen): write these as streamed operations internal i32 view_find_end_of_line(View *view, i32 pos){ @@ -2190,7 +2131,6 @@ file_compute_whitespace_edit(Mem_Options *mem, Editing_File *file, i32 cursor_po internal void view_clean_whitespace(System_Functions *system, App_Models *models, View *view){ Mem_Options *mem = &models->mem; - Editing_Layout *layout = &models->layout; Editing_File *file = view->file; Partition *part = &mem->part; @@ -2242,7 +2182,7 @@ view_clean_whitespace(System_Functions *system, App_Models *models, View *view){ file_compute_whitespace_edit(mem, file, view->cursor.pos, edits, str_base, str_size, inverse_array, inv_str, part->max - part->pos, edit_count); - view_do_white_batch_edit(system, mem, view, file, layout, spec, hist_normal); + file_do_white_batch_edit(system, models, view->file, spec, hist_normal); } end_temp_memory(temp); @@ -2250,13 +2190,15 @@ view_clean_whitespace(System_Functions *system, App_Models *models, View *view){ internal void view_auto_tab_tokens(System_Functions *system, - Mem_Options *mem, View *view, Editing_Layout *layout, + App_Models *models, View *view, i32 start, i32 end, b32 empty_blank_lines){ #if BUFFER_EXPERIMENT_SCALPEL <= 0 Editing_File *file = view->file; - Assert(file && !file->state.is_dummy); + Mem_Options *mem = &models->mem; Partition *part = &mem->part; Buffer *buffer = &file->state.buffer; + + Assert(file && !file->state.is_dummy); Cpp_Token_Stack tokens = file->state.token_stack; Assert(tokens.tokens); @@ -2434,7 +2376,7 @@ view_auto_tab_tokens(System_Functions *system, file_compute_whitespace_edit(mem, file, view->cursor.pos, edits, str_base, str_size, inverse_array, inv_str, part->max - part->pos, edit_count); - view_do_white_batch_edit(system, mem, view, file, layout, spec, hist_normal); + file_do_white_batch_edit(system, models, view->file, spec, hist_normal); } { @@ -2525,7 +2467,7 @@ internal void remeasure_file_view(System_Functions *system, View *view, i32_Rect rect){ if (file_is_ready(view->file)){ Relative_Scrolling relative = view_get_relative_scrolling(view); - view_measure_wraps(system, &view->mem->general, view); + view_measure_wraps(system, &view->models->mem.general, view); view_cursor_move(view, view->cursor.pos); view->preferred_x = view_get_cursor_x(view); view_set_relative_scrolling(view, relative); @@ -2576,10 +2518,10 @@ undo_shit(System_Functions *system, View *view, UI_State *state, UI_Layout *layo i32 count = file->state.undo.edit_history_cursor; if (do_undo_slider(wid, state, layout, mid, count, &file->state.undo, &new_count)){ for (i32 i = 0; i < scrub_max && new_count < count; ++i){ - view_history_step(system, view->mem, view->layout, view, hist_backward); + view_history_step(system, view->models, view, hist_backward); } for (i32 i = 0; i < scrub_max && new_count > count; ++i){ - view_history_step(system, view->mem, view->layout, view, hist_forward); + view_history_step(system, view->models, view, hist_forward); } } } @@ -2610,7 +2552,6 @@ view_show_menu(View *fview, Command_Map *gui_map){ fview->ui_state = {}; fview->map_for_file = fview->map; fview->map = gui_map; - fview->locked = 1; fview->showing_ui = VUI_Menu; } @@ -2619,17 +2560,18 @@ view_show_config(View *fview, Command_Map *gui_map){ fview->ui_state = {}; fview->map_for_file = fview->map; fview->map = gui_map; - fview->locked = 1; fview->showing_ui = VUI_Config; } inline void view_show_interactive(System_Functions *system, View *view, Command_Map *gui_map, Interactive_Action action, Interactive_Interaction interaction, String query){ + + App_Models *models = view->models; + view->ui_state = {}; view->map_for_file = view->map; view->map = gui_map; - view->locked = 1; view->showing_ui = VUI_Interactive; view->action = action; view->interaction = interaction; @@ -2639,8 +2581,8 @@ view_show_interactive(System_Functions *system, View *view, Command_Map *gui_map view->dest.str[0] = 0; view->dest.size = 0; - hot_directory_clean_end(view->hot_directory); - hot_directory_reload(system, view->hot_directory, view->working_set); + hot_directory_clean_end(&models->hot_directory); + hot_directory_reload(system, &models->hot_directory, &models->working_set); } inline void @@ -2648,7 +2590,6 @@ view_show_theme(View *fview, Command_Map *gui_map){ fview->ui_state = {}; fview->map_for_file = fview->map; fview->map = gui_map; - fview->locked = 1; fview->showing_ui = VUI_Theme; fview->color_mode = CV_Mode_Library; } @@ -2663,41 +2604,41 @@ view_show_file(View *view, Command_Map *file_map, Editing_File *file){ view->map = view->map_for_file; } view->file = file; - view->locked = 0; view->showing_ui = VUI_None; } internal void interactive_view_complete(View *view){ Panel *panel = view->panel; + App_Models *models = view->models; Editing_File *file = 0; switch (view->action){ case IAct_Open: - delayed_open(view->delay, view->hot_directory->string, panel); + delayed_open(&models->delay1, models->hot_directory.string, panel); break; case IAct_Save_As: - delayed_save_as(view->delay, view->hot_directory->string, panel); + delayed_save_as(&models->delay1, models->hot_directory.string, panel); file = view->file; break; case IAct_New: - delayed_new(view->delay, view->hot_directory->string, panel); + delayed_new(&models->delay1, models->hot_directory.string, panel); break; case IAct_Switch: - delayed_switch(view->delay, view->dest, panel); + delayed_switch(&models->delay1, view->dest, panel); break; case IAct_Kill: - delayed_try_kill(view->delay, view->dest, panel); + delayed_try_kill(&models->delay1, view->dest, panel); file = view->file; break; case IAct_Sure_To_Kill: switch (view->user_action){ case 0: - delayed_kill(view->delay, view->dest, panel); + delayed_kill(&models->delay1, view->dest, panel); break; case 1:break; @@ -2705,8 +2646,8 @@ interactive_view_complete(View *view){ case 2: // TODO(allen): This is fishy! What if the save doesn't happen this time around? // We need to ensure delayed acts happen in order I think. - delayed_save(view->delay, view->dest, panel); - delayed_kill(view->delay, view->dest, panel); + delayed_save(&models->delay1, view->dest, panel); + delayed_kill(&models->delay1, view->dest, panel); break; } break; @@ -2727,8 +2668,10 @@ update_highlighting(View *view){ view->highlight = {}; return; } - - Style *style = view->style; + + App_Models *models = view->models; + + Style *style = &models->style; i32 pos = view_get_cursor_pos(file_view); char c = buffer_get_char(&file->state.buffer, pos); @@ -2797,7 +2740,8 @@ internal b32 theme_library_shit(System_Functions *system, Exchange *exchange, View *view, UI_State *state, UI_Layout *layout){ - Mem_Options *mem = view->mem; + App_Models *models = view->models; + Mem_Options *mem = &models->mem; i32 result = 0; @@ -2805,9 +2749,9 @@ theme_library_shit(System_Functions *system, Exchange *exchange, ui.state = state; ui.layout = layout; - ui.fonts = view->font_set; - ui.hot_directory = view->hot_directory; - ui.styles = view->styles; + ui.fonts = models->font_set; + ui.hot_directory = &models->hot_directory; + ui.styles = &models->styles; Color_View_Mode mode = view->color_mode; @@ -2824,7 +2768,7 @@ theme_library_shit(System_Functions *system, Exchange *exchange, case CV_Mode_Library: { do_label(ui.state, ui.layout, literal("Current Theme - Click to Edit")); - if (do_style_preview(&ui, view->style)){ + if (do_style_preview(&ui, &models->style)){ view->color_mode = CV_Mode_Adjusting; view->ui_state.selected = {}; ui.state->view_y = 0; @@ -2842,23 +2786,23 @@ theme_library_shit(System_Functions *system, Exchange *exchange, } if (do_button(-3, ui.state, ui.layout, "Import", 2)){ view->color_mode = CV_Mode_Import_File; - hot_directory_clean_end(view->hot_directory); - hot_directory_reload(system, view->hot_directory, view->working_set); + hot_directory_clean_end(&models->hot_directory); + hot_directory_reload(system, &models->hot_directory, &models->working_set); } if (do_button(-4, ui.state, ui.layout, "Export", 2)){ view->color_mode = CV_Mode_Export; - hot_directory_clean_end(view->hot_directory); - hot_directory_reload(system, view->hot_directory, view->working_set); + hot_directory_clean_end(&models->hot_directory); + hot_directory_reload(system, &models->hot_directory, &models->working_set); memset(view->import_export_check, 0, sizeof(view->import_export_check)); } do_label(ui.state, ui.layout, literal("Theme Library - Click to Select")); - i32 style_count = view->styles->count; - Style *style = view->styles->styles; + i32 style_count = models->styles.count; + Style *style = models->styles.styles; for (i32 i = 0; i < style_count; ++i, ++style){ if (do_style_preview(&ui, style)){ - style_copy(view->style, style); + style_copy(&models->style, style); result = 1; } } @@ -2867,7 +2811,7 @@ theme_library_shit(System_Functions *system, Exchange *exchange, case CV_Mode_Import_File: { do_label(ui.state, ui.layout, literal("Current Theme")); - do_style_preview(&ui, view->style); + do_style_preview(&ui, &models->style); b32 file_selected = 0; @@ -2896,8 +2840,8 @@ theme_library_shit(System_Functions *system, Exchange *exchange, sizeof(view->import_export_check)); view->import_file_id = exchange_request_file(exchange, - view->hot_directory->string.str, - view->hot_directory->string.size); + models->hot_directory.string.str, + models->hot_directory.string.size); view->color_mode = CV_Mode_Import_Wait; } @@ -2937,7 +2881,7 @@ theme_library_shit(System_Functions *system, Exchange *exchange, case CV_Mode_Export_File: { do_label(ui.state, ui.layout, literal("Current Theme")); - do_style_preview(&ui, view->style); + do_style_preview(&ui, &models->style); b32 file_selected = 0; @@ -2988,7 +2932,7 @@ theme_library_shit(System_Functions *system, Exchange *exchange, case CV_Mode_Import: { do_label(ui.state, ui.layout, literal("Current Theme")); - do_style_preview(&ui, view->style); + do_style_preview(&ui, &models->style); i32 style_count = view->inspecting_styles.count; Style *styles = view->inspecting_styles.styles; @@ -3019,7 +2963,7 @@ theme_library_shit(System_Functions *system, Exchange *exchange, case CV_Mode_Export: { do_label(ui.state, ui.layout, literal("Current Theme")); - do_style_preview(&ui, view->style); + do_style_preview(&ui, &models->style); do_label(ui.state, ui.layout, literal("Export Which Themes?")); begin_row(ui.layout, 2); @@ -3030,8 +2974,8 @@ theme_library_shit(System_Functions *system, Exchange *exchange, view->color_mode = CV_Mode_Library; } - i32 style_count = view->styles->count; - Style *style = view->styles->styles; + i32 style_count = models->styles.count; + Style *style = models->styles.styles; b8 *export_check = view->import_export_check; for (i32 i = 0; i < style_count; ++i, ++style){ if (do_style_preview(&ui, style, export_check[i])){ @@ -3042,29 +2986,31 @@ theme_library_shit(System_Functions *system, Exchange *exchange, }break; } - return result; + return (result); } internal b32 theme_adjusting_shit(View *view, UI_State *state, UI_Layout *layout){ update_highlighting(view); - Style *style = view->style; + App_Models *models = view->models; + + Style *style = &models->style; i32 result = 0; Color_UI ui; ui.state = state; ui.layout = layout; - ui.fonts = view->font_set; - ui.global_font = view->global_font; + ui.fonts = models->font_set; + ui.global_font = &models->global_font; ui.highlight = view->highlight; ui.color = view->color; ui.has_hover_color = 0; ui.state->sub_id1_change = 0; ui.hex_advance = font_get_max_width(ui.fonts, ui.state->font_id, "0123456789abcdefx"); - ui.palette = view->palette; - ui.palette_size = view->palette_size; + ui.palette = models->palette; + ui.palette_size = models->palette_size; i32_Rect bar_rect = ui.layout->rect; bar_rect.x0 = bar_rect.x1 - 20; @@ -3212,6 +3158,8 @@ interactive_shit(System_Functions *system, View *view, UI_State *state, UI_Layou b32 new_dir = 0; b32 complete = 0; + App_Models *models = view->models; + do_label(state, layout, view->query, 1.f); b32 case_sensitive = 0; @@ -3224,20 +3172,19 @@ interactive_shit(System_Functions *system, View *view, UI_State *state, UI_Layou { b32 is_new = (view->action == IAct_New); - if (do_file_list_box(system, state, - layout, view->hot_directory, 0, !is_new, case_sensitive, + if (do_file_list_box(system, state, layout, + &models->hot_directory, 0, !is_new, case_sensitive, &new_dir, &complete, 0)){ result = 1; } if (new_dir){ - hot_directory_reload(system, - view->hot_directory, view->working_set); + hot_directory_reload(system, &models->hot_directory, &models->working_set); } }break; case IInt_Live_File_List: { - if (do_live_file_list_box(system, state, layout, view->working_set, &view->dest, &complete)){ + if (do_live_file_list_box(system, state, layout, &models->working_set, &view->dest, &complete)){ result = 1; } }break; @@ -3312,21 +3259,23 @@ menu_shit(View *view, UI_State *state, UI_Layout *layout){ internal void config_shit(View *view, UI_State *state, UI_Layout *layout){ i32 id = 0; - + App_Models *models = view->models; + do_label(state, layout, literal("Config"), 2.f); if (do_checkbox_list_option(++id, state, layout, make_lit_string("Left Ctrl + Left Alt = AltGr"), - view->settings->lctrl_lalt_is_altgr)){ - view->settings->lctrl_lalt_is_altgr = !view->settings->lctrl_lalt_is_altgr; + models->settings.lctrl_lalt_is_altgr)){ + models->settings.lctrl_lalt_is_altgr = !models->settings.lctrl_lalt_is_altgr; } } internal void do_file_bar(View *view, Editing_File *file, UI_Layout *layout, Render_Target *target){ Interactive_Bar bar; - Style_Font *font = view->global_font; + App_Models *models = view->models; + Style_Font *font = &models->global_font; i32 line_height = view->font_height; - Interactive_Style bar_style = view->style->main.file_info_style; + Interactive_Style bar_style = models->style.main.file_info_style; u32 back_color = bar_style.bar_color; u32 base_color = bar_style.base_color; @@ -3414,6 +3363,7 @@ internal i32 step_file_view(System_Functions *system, Exchange *exchange, View *view, i32_Rect rect, b32 is_active, Input_Summary *user_input){ + App_Models *models = view->models; i32 result = 0; Editing_File *file = view->file; @@ -3421,7 +3371,7 @@ step_file_view(System_Functions *system, Exchange *exchange, View *view, i32_Rec { UI_State state = ui_state_init(&view->widget.state, 0, user_input, - view->style, view->global_font->font_id, view->font_set, 0, 1); + &models->style, models->global_font.font_id, models->font_set, 0, 1); UI_Layout layout; begin_layout(&layout, rect); @@ -3555,7 +3505,7 @@ step_file_view(System_Functions *system, Exchange *exchange, View *view, i32_Rec { UI_State state = ui_state_init(&view->ui_state, 0, user_input, - view->style, view->global_font->font_id, view->font_set, view->working_set, 1); + &models->style, models->global_font.font_id, models->font_set, &models->working_set, 1); UI_Layout layout; begin_layout(&layout, rect); @@ -3592,8 +3542,9 @@ step_file_view(System_Functions *system, Exchange *exchange, View *view, i32_Rec internal i32 draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target){ + App_Models *models = view->models; Editing_File *file = view->file; - Style *style = view->style; + Style *style = &models->style; i32 line_height = view->font_height; i32 max_x = rect.x1 - rect.x0; @@ -3608,7 +3559,7 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target token_stack = file->state.token_stack; } - Partition *part = &view->mem->part; + Partition *part = &models->mem.part; Temp_Memory temp = begin_temp_memory(part); @@ -3616,8 +3567,8 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target i32 max = partition_remaining(part) / sizeof(Buffer_Render_Item); Buffer_Render_Item *items = push_array(part, Buffer_Render_Item, max); - i16 font_id = view->global_font->font_id; - Render_Font *font = get_font_info(view->font_set, font_id)->font; + i16 font_id = models->global_font.font_id; + Render_Font *font = get_font_info(models->font_set, font_id)->font; float *advance_data = 0; if (font) advance_data = font->advance_data; @@ -3762,6 +3713,7 @@ draw_file_view(System_Functions *system, Exchange *exchange, View *view, View *active, i32_Rect rect, b32 is_active, Render_Target *target, Input_Summary *user_input){ + App_Models *models = view->models; Editing_File *file = view->file; i32 result = 0; @@ -3769,7 +3721,7 @@ draw_file_view(System_Functions *system, Exchange *exchange, { UI_State state = ui_state_init(&view->widget.state, target, 0, - view->style, view->global_font->font_id, view->font_set, 0, 0); + &models->style, models->global_font.font_id, models->font_set, 0, 0); UI_Layout layout; begin_layout(&layout, rect); @@ -3809,7 +3761,7 @@ draw_file_view(System_Functions *system, Exchange *exchange, UI_State state = ui_state_init(&view->ui_state, target, user_input, - view->style, view->global_font->font_id, view->font_set, view->working_set, 0); + &models->style, models->global_font.font_id, models->font_set, &models->working_set, 0); UI_Layout layout; begin_layout(&layout, rect); @@ -3857,97 +3809,22 @@ draw_file_view(System_Functions *system, Exchange *exchange, internal void kill_file(System_Functions *system, Exchange *exchange, - General_Memory *general, Editing_File *file, - Editing_Layout *layout){ + App_Models *models, Editing_File *file){ - View *view; - - Panel *panel, *used_panels; - used_panels = &layout->used_sentinel; - - for (dll_items(panel, used_panels)){ - view = panel->view; - Assert(view); - if (view->file == file){ - view->file = 0; - } + for (View_Iter iter = file_view_iter_init(&models->layout, file, 0); + file_view_iter_good(iter); + iter = file_view_iter_next(iter)){ + iter.view->file = 0; } - file_close(system, general, file); - file_get_dummy(file); + file_close(system, &models->mem.general, file); + working_set_free_file(&models->working_set, file); } inline void free_file_view(View *view){ if (view->line_wrap_y) - general_memory_free(&view->mem->general, view->line_wrap_y); -} - -internal View* -file_view_init(View *view, App_Models *models){ - - view->models = models; - view->layout = &models->layout; - view->working_set = &models->working_set; - view->delay = &models->delay1; - view->settings = &models->settings; - view->hot_directory = &models->hot_directory; - view->mem = &models->mem; - view->styles = &models->styles; - view->font_set = models->font_set; - - view->scrub_max = 1; - - // TODO(allen): Make "interactive" mode customizable just like the query bars! - view->query = make_fixed_width_string(view->query_); - view->dest = make_fixed_width_string(view->dest_); - - init_query_set(&view->query_set); - - return(view); -} - -struct View_Iter{ - View *view; - - Editing_File *file; - View *skip; - Panel *used_panels; - Panel *panel; -}; - -internal View_Iter -file_view_iter_next(View_Iter iter){ - Panel *panel; - View *file_view; - - for (panel = iter.panel; panel != iter.used_panels; panel = panel->next){ - file_view = panel->view; - if (file_view != iter.skip && file_view->file == iter.file){ - iter.view = file_view; - break; - } - } - - return(iter); -} - -internal View_Iter -file_view_iter_init(Editing_Layout *layout, Editing_File *file, View *skip){ - View_Iter result; - result.used_panels = &layout->used_sentinel; - result.panel = result.used_panels->next; - result.file = file; - result.skip = skip; - - return(result); -} - -internal b32 -file_view_iter_good(View_Iter iter){ - b32 result = 1; - if (iter.panel != iter.used_panels) result = 0; - return(result); + general_memory_free(&view->models->mem.general, view->line_wrap_y); } struct Search_Range{ @@ -4159,13 +4036,8 @@ struct Live_Views{ i32 count, max; }; -inline View* -live_set_get_view(Live_Views *live_set, i32 id){ - return (live_set->views + id); -} - internal View_And_ID -live_set_alloc_view(Live_Views *live_set){ +live_set_alloc_view(Live_Views *live_set, Panel *panel, App_Models *models){ View_And_ID result = {}; Assert(live_set->count < live_set->max); @@ -4178,6 +4050,19 @@ live_set_alloc_view(Live_Views *live_set){ dll_remove(result.view); memset(result.view, 0, sizeof(View)); + result.view->in_use = 1; + panel->view = result.view; + result.view->panel = panel; + + result.view->models = models; + result.view->scrub_max = 1; + + // TODO(allen): Make "interactive" mode customizable just like the query bars! + result.view->query = make_fixed_width_string(result.view->query_); + result.view->dest = make_fixed_width_string(result.view->dest_); + + init_query_set(&result.view->query_set); + return(result); } @@ -4187,6 +4072,7 @@ live_set_free_view(System_Functions *system, Exchange *exchange, Live_Views *liv --live_set->count; free_file_view(view); dll_insert(&live_set->free_sentinel, view); + view->in_use = 0; } // BOTTOM diff --git a/4ed_gui.cpp b/4ed_gui.cpp index d6b57246..704db153 100644 --- a/4ed_gui.cpp +++ b/4ed_gui.cpp @@ -1461,27 +1461,31 @@ do_live_file_list_box(System_Functions *system, UI_State *state, UI_Layout *layo Absolutes absolutes; get_absolutes(*string, &absolutes, 1, 1); - i32 count = working_set->file_index_count; - Editing_File *files = working_set->files; - for (i32 i = 0; i < count; ++i){ - Editing_File *file = files + i; + Editing_File *file; + File_Node *node, *used_nodes; + i32 i = 0; + used_nodes = &working_set->used_sentinel; + + for (dll_items(node, used_nodes)){ + file = (Editing_File*)node; + Assert(!file->state.is_dummy); - if (!file->state.is_dummy){ - String message = message_nothing; - switch (buffer_get_sync(file)){ + String message = message_nothing; + switch (buffer_get_sync(file)){ case SYNC_BEHIND_OS: message = message_unsynced; break; case SYNC_UNSAVED: message = message_unsaved; break; - } - - if (filename_match(*string, &absolutes, file->name.live_name, 1)){ - if (do_file_option(100+i, state, layout, file->name.live_name, 0, message, system->slash)){ - result = 1; - *selected = 1; - copy(string, file->name.source_path); - terminate_with_null(string); - } + } + + if (filename_match(*string, &absolutes, file->name.live_name, 1)){ + if (do_file_option(100+i, state, layout, file->name.live_name, 0, message, system->slash)){ + result = 1; + *selected = 1; + copy(string, file->name.source_path); + terminate_with_null(string); } } + + ++i; } } diff --git a/buffer/4coder_buffer_abstract.cpp b/buffer/4coder_buffer_abstract.cpp index 59ab0b86..7433b014 100644 --- a/buffer/4coder_buffer_abstract.cpp +++ b/buffer/4coder_buffer_abstract.cpp @@ -934,19 +934,19 @@ typedef struct Seek_State{ internal_4tech int cursor_seek_step(Seek_State *state, Buffer_Seek seek, int xy_seek, float max_width, - float font_height, float *advances, int size, char ch){ + float font_height, float *advances, int size, char ch){ Full_Cursor cursor, prev_cursor; float ch_width; int result; float x, px, y; - + cursor = state->cursor; prev_cursor = state->prev_cursor; - + result = 1; prev_cursor = cursor; switch (ch){ - case '\n': + case '\n': ++cursor.line; cursor.unwrapped_y += font_height; cursor.wrapped_y += font_height; @@ -954,51 +954,51 @@ cursor_seek_step(Seek_State *state, Buffer_Seek seek, int xy_seek, float max_wid cursor.unwrapped_x = 0; cursor.wrapped_x = 0; break; - - default: + + default: ++cursor.character; if (ch == '\r') ch_width = *(float*)(advances + '\\') + *(float*)(advances + 'r'); else ch_width = *(float*)(advances + ch); - + if (cursor.wrapped_x + ch_width >= max_width){ cursor.wrapped_y += font_height; cursor.wrapped_x = 0; prev_cursor = cursor; } - + cursor.unwrapped_x += ch_width; cursor.wrapped_x += ch_width; - + break; } - + ++cursor.pos; - + if (cursor.pos > size){ cursor = prev_cursor; result = 0; goto cursor_seek_step_end; } - + x = y = px = 0; - + switch (seek.type){ - case buffer_seek_pos: + case buffer_seek_pos: if (cursor.pos > seek.pos){ cursor = prev_cursor; result = 0; goto cursor_seek_step_end; }break; - - case buffer_seek_wrapped_xy: + + case buffer_seek_wrapped_xy: x = cursor.wrapped_x; px = prev_cursor.wrapped_x; y = cursor.wrapped_y; break; - - case buffer_seek_unwrapped_xy: + + case buffer_seek_unwrapped_xy: x = cursor.unwrapped_x; px = prev_cursor.unwrapped_x; y = cursor.unwrapped_y; break; - - case buffer_seek_line_char: + + case buffer_seek_line_char: if (cursor.line == seek.line && cursor.character >= seek.character){ result = 0; goto cursor_seek_step_end; @@ -1009,21 +1009,21 @@ cursor_seek_step(Seek_State *state, Buffer_Seek seek, int xy_seek, float max_wid goto cursor_seek_step_end; }break; } - + if (xy_seek){ if (y > seek.y){ cursor = prev_cursor; result = 0; goto cursor_seek_step_end; } - + if (y > seek.y - font_height && x >= seek.x){ if (!seek.round_down){ if (ch != '\n' && (seek.x - px) < (x - seek.x)) cursor = prev_cursor; result = 0; goto cursor_seek_step_end; } - + if (x > seek.x){ cursor = prev_cursor; result = 0; @@ -1031,8 +1031,8 @@ cursor_seek_step(Seek_State *state, Buffer_Seek seek, int xy_seek, float max_wid } } } - -cursor_seek_step_end: + + cursor_seek_step_end: state->cursor = cursor; state->prev_cursor = prev_cursor; return(result); @@ -1053,8 +1053,21 @@ buffer_cursor_seek(Buffer_Type *buffer, Buffer_Seek seek, float max_width, state.cursor = cursor; - if (advance_data){ + switch(seek.type){ + case buffer_seek_pos: + if (cursor.pos >= seek.pos) goto buffer_cursor_seek_end; + + case buffer_seek_wrapped_xy: + if (seek.x == 0 && cursor.wrapped_y >= seek.y) goto buffer_cursor_seek_end; + + case buffer_seek_unwrapped_xy: + if (seek.x == 0 && cursor.unwrapped_y >= seek.y) goto buffer_cursor_seek_end; + + case buffer_seek_line_char: + if (cursor.line >= seek.line && cursor.character >= seek.character) goto buffer_cursor_seek_end; + } + if (advance_data){ size = buffer_size(buffer); xy_seek = (seek.type == buffer_seek_wrapped_xy || seek.type == buffer_seek_unwrapped_xy); @@ -1076,7 +1089,6 @@ buffer_cursor_seek(Buffer_Type *buffer, Buffer_Seek seek, float max_width, font_height, advance_data, size, 0); assert_4tech(result == 0); } - } buffer_cursor_seek_end: diff --git a/buildsuper.bat b/buildsuper.bat index 4e187a6b..20a80a32 100644 --- a/buildsuper.bat +++ b/buildsuper.bat @@ -9,8 +9,10 @@ SET STUFF=/GR- /nologo SET DEBUG=/Zi SET EXPORTS=/EXPORT:get_bindings SET SRC=4coder_custom.cpp +REM SET LINKS=user32.lib gdi32.lib +SET LINKS= -cl %WARNINGS% %STUFF% %DEBUG% %SRC% /Fe4coder_custom /LD /link /INCREMENTAL:NO /OPT:REF %EXPORTS% +cl %WARNINGS% %STUFF% %DEBUG% %SRC% %LINKS% /Fe4coder_custom /LD /link /INCREMENTAL:NO /OPT:REF %EXPORTS% REM file spammation preventation del *.exp