diff --git a/4coder_custom.cpp b/4coder_custom.cpp index 3c9d863b..ea8e44a8 100644 --- a/4coder_custom.cpp +++ b/4coder_custom.cpp @@ -639,7 +639,7 @@ CUSTOM_COMMAND_SIG(execute_any_cli){ hot_directory = make_fixed_width_string(even_more_space); hot_directory.size = app->directory_get_hot(app, hot_directory.str, hot_directory.memory_size); - push_parameter(app, par_cli_overlap_with_conflict, 1); + push_parameter(app, par_cli_flags, CLI_OverlapWithConflict); push_parameter(app, par_name, bar_out.string.str, bar_out.string.size); push_parameter(app, par_cli_path, hot_directory.str, hot_directory.size); push_parameter(app, par_cli_command, bar_cmd.string.str, bar_cmd.string.size); @@ -726,7 +726,7 @@ CUSTOM_COMMAND_SIG(build_at_launch_location){ // An example of calling build by setting all // parameters directly. This only works if build.bat can be called // from the directory the application is launched at. - push_parameter(app, par_cli_overlap_with_conflict, 1); + push_parameter(app, par_cli_flags, CLI_OverlapWithConflict); push_parameter(app, par_name, literal("*compilation*")); push_parameter(app, par_cli_path, literal(".")); push_parameter(app, par_cli_command, literal("build")); @@ -743,23 +743,26 @@ CUSTOM_COMMAND_SIG(build_search){ // // Step 2: app->file_exists queries the file system to see if "/build.bat" exists. // If it does exist several parameters are pushed and cmdid_command_line is executed: - // - par_cli_overlap_with_conflict: whether to launch this process if an existing process - // is already being used for output on the same buffer + // - par_cli_flags: flags for specifiying behaviors + // CLI_OverlapWithConflict - (on by default) if another CLI is still using the output buffer + // that process is detached from the buffer and this process executes outputing to the buffer + // CLI_AlwaysBindToView - if set, the current view always switches to the output buffer + // even if the output buffer is open in another view // // - par_name: the name of the buffer to fill with the output from the process + // - par_buffer_id: the buffer_id of the buffer to to fill with output + // If both are set buffer_id is used and the name is ignored. + // If neither is set the command runs without storing output anywhere. // // - par_cli_path: sets the path from which the command is executed + // If this parameter is unset the command runs from the hot directory. // - // - par_cli_command: sets the actual command to be executed, this can be almost any command - // that you could execute through a command line interface - // - // - // To set par_cli_path: push_parameter makes a copy of the dir string on the stack - // because the string allocated by push_directory is going to change again - // To set par_cli_command: app->push_parameter does not make a copy of the dir because - // dir isn't going to change again. + // - par_cli_command: sets the actual command to be executed, this can be almost any + // command that you could execute through a command line interface. + // If this parameter is unset the command get's it's command from the range between + // the mark and cursor. // - // Step 3: If the batch file did not exist change the dir string to the parent directory using + // Step 3: If the batch file did not exist change the dir string to the parent directory using // app->directory_cd. The cd function can also be used to navigate to subdirectories. // It returns true if it can actually move in the specified direction, and false otherwise. // @@ -778,7 +781,7 @@ CUSTOM_COMMAND_SIG(build_search){ if (app->file_exists(app, dir.str, dir.size)){ dir.size = old_size; - push_parameter(app, par_cli_overlap_with_conflict, 0); + push_parameter(app, par_cli_flags, 0); push_parameter(app, par_name, literal("*compilation*")); push_parameter(app, par_cli_path, dir.str, dir.size); @@ -807,11 +810,43 @@ CUSTOM_COMMAND_SIG(write_and_auto_tab){ exec_command(app, cmdid_auto_tab_line_at_cursor); } +// NOTE(allen|a4.0.0): scroll rule information +// +// The parameters: +// target_x, target_y +// This is where the view would like to be for the purpose of +// following the cursor, doing mouse wheel work, etc. +// +// scroll_x, scroll_y +// These are pointers to where the scrolling actually is. If you bind +// the scroll rule it is you have to update these in some way to move +// the actual location of the scrolling. +// +// view_id +// This corresponds to which view is computing it's new scrolling position. +// This id DOES correspond to the views that View_Summary contains. +// This will always be between 1 and 16 (0 is a null id). +// See below for an example of having state that carries across scroll udpates. +// +// is_new_target +// If the target of the view is different from the last target in either x or y +// this is true, otherwise it is false. +// +// The return: +// Should be true if and only if scroll_x or scroll_y are changed. +// +// Don't try to use the app pointer in a scroll rule, you're asking for trouble. +// +// If you don't bind scroll_rule, nothing bad will happen, yo will get default +// 4coder scrolling behavior. +// + struct Scroll_Velocity{ float x, y; }; -Scroll_Velocity scroll_velocity[16] = {0}; +Scroll_Velocity scroll_velocity_[16] = {0}; +Scroll_Velocity *scroll_velocity = scroll_velocity_; static int smooth_camera_step(float target, float *current, float *vel, float S, float T){ @@ -844,7 +879,7 @@ smooth_camera_step(float target, float *current, float *vel, float S, float T){ return result; } -extern "C" SCROLL_RULE_SIG(scroll_rule){ +SCROLL_RULE_SIG(smooth_scroll_rule){ Scroll_Velocity *velocity = scroll_velocity + view_id; int result = 0; if (velocity->x == 0.f){ @@ -870,6 +905,7 @@ extern "C" GET_BINDING_DATA(get_bindings){ // global and once set they always apply, regardless of what map is active. set_hook(context, hook_start, my_start); set_hook(context, hook_open_file, my_file_settings); + set_scroll_rule(context, smooth_scroll_rule); begin_map(context, mapid_global); diff --git a/4coder_custom.h b/4coder_custom.h index 4dac493d..b925233b 100644 --- a/4coder_custom.h +++ b/4coder_custom.h @@ -1,4 +1,5 @@ +#include "4coder_version.h" #include "4coder_keycodes.h" #include "4coder_buffer_types.h" @@ -218,7 +219,6 @@ enum Command_ID{ cmdid_page_up, cmdid_page_down, cmdid_open_color_tweaker, - cmdid_close_minor_view, cmdid_cursor_mark_swap, cmdid_open_menu, cmdid_set_settings, @@ -238,13 +238,17 @@ enum Param_ID{ par_key_mapid, par_cli_path, par_cli_command, - par_cli_overlap_with_conflict, - par_cli_always_bind_to_view, + par_cli_flags, par_clear_blank_lines, // never below this par_type_count }; +#define CLI_OverlapWithConflict 0x1 +#define CLI_AlwaysBindToView 0x2 + +// These are regular hooks, any of them can be set to any function +// that matches the HOOK_SIG pattern. enum Hook_ID{ hook_start, hook_open_file, @@ -252,6 +256,12 @@ enum Hook_ID{ hook_type_count }; +// These are for special hooks, each must bind to specialized signatures +// that do not necessarily have access to the app pointer. +enum Special_Hook_ID{ + _hook_scroll_rule = hook_type_count, +}; + // NOTE(allen): None of the members of *_Summary structs nor any of the // data pointed to by the members should be modified, I would have made // them all const... but that causes a lot problems for C++ reasons. @@ -474,7 +484,6 @@ struct Application_Links{ struct Custom_API{ Get_Binding_Data_Function *get_bindings; - Scroll_Rule_Function *scroll_rule; }; // NOTE(allen): definitions for the buffer that communicates to 4ed.exe @@ -517,7 +526,7 @@ struct Binding_Unit{ } callback; struct{ int hook_id; - Custom_Command_Function *func; + void *func; } hook; }; }; diff --git a/4coder_helper.h b/4coder_helper.h index 79431b9a..27eb299d 100644 --- a/4coder_helper.h +++ b/4coder_helper.h @@ -162,6 +162,16 @@ set_hook(Bind_Helper *helper, int hook_id, Custom_Command_Function *func){ write_unit(helper, unit); } +inline void +set_scroll_rule(Bind_Helper *helper, Scroll_Rule_Function *func){ + Binding_Unit unit; + unit.type = unit_hook; + unit.hook.hook_id = _hook_scroll_rule; + unit.hook.func = func; + + write_unit(helper, unit); +} + inline void end_bind_helper(Bind_Helper *helper){ if (helper->header){ diff --git a/4coder_version.h b/4coder_version.h new file mode 100644 index 00000000..76fbe46a --- /dev/null +++ b/4coder_version.h @@ -0,0 +1,3 @@ +#define MAJOR 3 +#define MINOR 4 +#define PATCH 5 diff --git a/4ed.cpp b/4ed.cpp index e0c64be6..d71913e6 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -194,7 +194,7 @@ panel_make_empty(System_Functions *system, Exchange *exchange, App_Vars *vars, P View_And_ID new_view; Assert(panel->view == 0); - new_view = live_set_alloc_view(&vars->live_set, models->config_api.scroll_rule); + new_view = live_set_alloc_view(&vars->live_set); panel->view = new_view.view; panel->view->panel = panel; @@ -539,7 +539,7 @@ COMMAND_DECL(word_complete){ COMMAND_DECL(set_mark){ ProfileMomentFunction(); - REQ_OPEN_VIEW(view); + USE_VIEW(view); REQ_FILE(file, view); view->mark = (i32)view->cursor.pos; @@ -548,7 +548,7 @@ COMMAND_DECL(set_mark){ COMMAND_DECL(copy){ ProfileMomentFunction(); USE_MODELS(models); - REQ_OPEN_VIEW(view); + USE_VIEW(view); REQ_FILE(file, view); // TODO(allen): deduplicate @@ -755,7 +755,7 @@ COMMAND_DECL(history_forward){ COMMAND_DECL(interactive_new){ ProfileMomentFunction(); USE_MODELS(models); - REQ_OPEN_VIEW(view); + USE_VIEW(view); view_show_interactive(system, view, &models->map_ui, IAct_New, IInt_Sys_File_List, make_lit_string("New: ")); @@ -813,7 +813,7 @@ COMMAND_DECL(interactive_open){ ProfileMomentFunction(); USE_MODELS(models); USE_PANEL(panel); - REQ_OPEN_VIEW(view); + USE_VIEW(view); Delay *delay = &models->delay1; @@ -846,9 +846,6 @@ COMMAND_DECL(interactive_open){ } } else{ - View *view = panel->view; - Assert(view); - view_show_interactive(system, view, &models->map_ui, IAct_Open, IInt_Sys_File_List, make_lit_string("Open: ")); } @@ -1537,7 +1534,7 @@ COMMAND_DECL(close_minor_view){ if (view->file){ map = app_get_map(models, view->file->settings.base_map_id); } - view_show_file(view, map); + view_show_file(view, map, view->file); } COMMAND_DECL(cursor_mark_swap){ @@ -1625,22 +1622,23 @@ COMMAND_DECL(set_settings){ } } -#define CLI_OverlapWithConflict (1<<0) -#define CLI_AlwaysBindToView (2<<0) - COMMAND_DECL(command_line){ ProfileMomentFunction(); USE_VARS(vars); USE_MODELS(models); USE_PANEL(panel); + USE_VIEW(view); + + Partition *part = &models->mem.part; char *buffer_name = 0; char *path = 0; char *script = 0; - int buffer_name_len = 0; - int path_len = 0; - int script_len = 0; + i32 buffer_id = 0; + i32 buffer_name_len = 0; + i32 path_len = 0; + i32 script_len = 0; u32 flags = CLI_OverlapWithConflict; Command_Parameter *end = param_stack_end(&command->part); @@ -1650,115 +1648,135 @@ COMMAND_DECL(command_line){ switch (p){ case par_name: { - if (buffer_name == 0){ - char *new_buffer_name = dynamic_to_string(¶m->param.value, &buffer_name_len); - if (new_buffer_name){ - buffer_name = new_buffer_name; - } + char *new_buffer_name = dynamic_to_string(¶m->param.value, &buffer_name_len); + if (new_buffer_name){ + buffer_name = new_buffer_name; } }break; + + case par_buffer_id: + { + buffer_id = dynamic_to_int(¶m->param.value); + }break; case par_cli_path: { - if (path == 0){ - char *new_cli_path = dynamic_to_string(¶m->param.value, &path_len); - if (new_cli_path){ - path = new_cli_path; - } + char *new_cli_path = dynamic_to_string(¶m->param.value, &path_len); + if (new_cli_path){ + path = new_cli_path; } }break; case par_cli_command: { - if (script == 0){ - char *new_command = dynamic_to_string(¶m->param.value, &script_len); - if (new_command){ - script = new_command; - } + char *new_command = dynamic_to_string(¶m->param.value, &script_len); + if (new_command){ + script = new_command; } }break; - case par_cli_overlap_with_conflict: + case par_cli_flags: { - if (dynamic_to_int(¶m->param.value)) - flags |= CLI_OverlapWithConflict; - else - flags &= (~CLI_OverlapWithConflict); - }break; - - case par_cli_always_bind_to_view: - { - if (dynamic_to_int(¶m->param.value)) - flags |= CLI_OverlapWithConflict; - else - flags &= (~CLI_OverlapWithConflict); + flags = (u32)dynamic_to_int(¶m->param.value); }break; } } { Working_Set *working_set = &models->working_set; - Editing_File *file; - i32 index = 0; - b32 bind_to_new_view; - - if (buffer_name == 0 || path == 0 || script == 0){ - return; - } + CLI_Process *procs = vars->cli_processes.procs, *proc = 0; + Get_File_Result file = {}; + b32 bind_to_new_view = 1; if (vars->cli_processes.count < vars->cli_processes.max){ - file = working_set_contains(working_set, make_string_slowly(buffer_name)); - bind_to_new_view = 1; - - if (!file){ - Get_File_Result get_file = working_set_get_available_file(working_set); - file = get_file.file; - index = get_file.index; + 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; + } } 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); + } + + if (file.file){ i32 proc_count = vars->cli_processes.count; - for (i32 i = 0; i < proc_count; ++i){ - if (vars->cli_processes.procs[i].out_file == file){ + View_Iter iter; + i32 i; + + for (i = 0; i < proc_count; ++i){ + if (procs[i].out_file == file.file){ if (flags & CLI_OverlapWithConflict) - vars->cli_processes.procs[i].out_file = 0; - else file = 0; + procs[i].out_file = 0; + else + file.file = 0; break; } } - index = (i32)(file - models->working_set.files); - if (file){ + + if (file.file){ if (!(flags & CLI_AlwaysBindToView)){ - View_Iter iter; - iter = file_view_iter_init(&models->layout, file, 0); + iter = file_view_iter_init(&models->layout, file.file, 0); if (file_view_iter_good(iter)){ bind_to_new_view = 0; } } + + file_create_super_locked(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 + return; } } - if (file){ - file_create_super_locked(system, models, file, buffer_name); - file->settings.unimportant = 1; - table_add(&working_set->table, file->name.source_path, index); + if (!path){ + path = models->hot_directory.string.str; + terminate_with_null(&models->hot_directory.string); + } + + { + Temp_Memory temp; + Range range; + Editing_File *view_file; + i32 size; - if (bind_to_new_view){ - view_file_in_panel(command, panel, file); + temp = begin_temp_memory(part); + if (!script){ + view_file = view->file; + if (view_file){ + range = make_range(view->cursor.pos, view->mark); + size = range.end - range.start; + script = push_array(part, char, size + 1); + buffer_stringify(&view_file->state.buffer, range.start, range.end, script); + script[size] = 0; + } + else{ + script = " echo no script specified"; + } } - - i32 i = vars->cli_processes.count++; - CLI_Process *proc = vars->cli_processes.procs + i; + + if (bind_to_new_view){ + view_file_in_panel(command, panel, file.file); + } + + proc = procs + vars->cli_processes.count++; + proc->out_file = file.file; + if (!system->cli_call(path, script, &proc->cli)){ --vars->cli_processes.count; } - proc->out_file = file; - } - else{ - // TODO(allen): feedback message - no available file + end_temp_memory(temp); } } else{ // TODO(allen): feedback message - no available process slot + return; } } } @@ -1793,14 +1811,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)((char*)file_view - (char*)live_set->views) / live_set->stride; + 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; - view->line_height = file_view->font_height; - view->unwrapped_lines = file_view->unwrapped_lines; + } + else{ + view->buffer_id = 0; + view->mark = {}; + view->cursor = {}; + view->preferred_x = 0; } } @@ -2084,7 +2109,7 @@ extern "C"{ GET_VIEW_MAX_INDEX_SIG(external_get_view_max_index){ Command_Data *cmd = (Command_Data*)app->cmd_context; Live_Views *live_set = cmd->live_set; - int max = live_set->max; + int max = live_set->max + 1; return(max); } @@ -2094,9 +2119,10 @@ extern "C"{ Live_Views *live_set = cmd->live_set; int max = live_set->max; View *vptr; - + + index -= 1; if (index >= 0 && index < max){ - vptr = (View*)((char*)live_set->views + live_set->stride*index); + vptr = live_set->views + index; fill_view_summary(&view, vptr, live_set, &cmd->models->working_set); } @@ -2127,7 +2153,7 @@ extern "C"{ if (view->exists){ live_set = cmd->live_set; - vptr = (View*)((char*)live_set->views + live_set->stride * view->view_id); + vptr = live_set->views + view->view_id; result = 1; if (seek.type == buffer_seek_line_char && seek.character <= 0){ seek.character = 1; @@ -2151,7 +2177,7 @@ extern "C"{ if (view->exists){ live_set = cmd->live_set; - vptr = (View*)((char*)live_set->views + live_set->stride * view->view_id); + vptr = live_set->views + view->view_id; result = 1; if (seek.type == buffer_seek_line_char && seek.character <= 0){ seek.character = 1; @@ -2177,7 +2203,7 @@ extern "C"{ if (view->exists){ live_set = cmd->live_set; - vptr = (View*)((char*)live_set->views + live_set->stride * view->view_id); + vptr = live_set->views + view->view_id; result = 1; if (turn_on){ view_set_temp_highlight(vptr, start, end); @@ -2203,7 +2229,7 @@ extern "C"{ if (view->exists){ models = cmd->models; live_set = cmd->live_set; - vptr = (View*)((char*)live_set->views + live_set->stride * view->view_id); + 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){ @@ -2346,7 +2372,7 @@ setup_file_commands(Command_Map *commands, Partition *part, Command_Map *parent) internal void setup_top_commands(Command_Map *commands, Partition *part, Command_Map *parent){ - map_init(commands, part, 5, parent); + map_init(commands, part, 10, parent); } internal void @@ -2412,7 +2438,6 @@ setup_command_table(){ SET(page_up); SET(page_down); SET(open_color_tweaker); - SET(close_minor_view); SET(cursor_mark_swap); SET(open_menu); SET(set_settings); @@ -2877,25 +2902,21 @@ App_Init_Sig(app_init){ } { - char *vptr = 0; - View *v = 0; + View *vptr = 0; i32 i = 0; i32 max = 0; - i32 view_size = sizeof(View); vars->live_set.count = 0; vars->live_set.max = panel_max_count; - vars->live_set.stride = view_size; - vars->live_set.views = push_block(partition, view_size*vars->live_set.max); + vars->live_set.views = push_array(partition, View, vars->live_set.max); dll_init_sentinel(&vars->live_set.free_sentinel); max = vars->live_set.max; - vptr = (char*)vars->live_set.views; - for (i = 0; i < max; ++i, vptr += view_size){ - v = (View*)(vptr); - dll_insert(&vars->live_set.free_sentinel, v); + vptr = vars->live_set.views; + for (i = 0; i < max; ++i, ++vptr){ + dll_insert(&vars->live_set.free_sentinel, vptr); } } @@ -2905,9 +2926,7 @@ App_Init_Sig(app_init){ b32 did_top = 0; b32 did_file = 0; - if (models->config_api.scroll_rule == 0){ - models->config_api.scroll_rule = fallback_scroll_rule; - } + models->scroll_rule = fallback_scroll_rule; setup_command_table(); @@ -3010,8 +3029,13 @@ App_Init_Sig(app_init){ case unit_hook: { int hook_id = unit->hook.hook_id; - if (hook_id >= 0 && hook_id < hook_type_count){ - models->hooks[hook_id] = unit->hook.func; + if (hook_id >= 0){ + if (hook_id < hook_type_count){ + models->hooks[hook_id] = (Hook_Function*)unit->hook.func; + } + else{ + models->scroll_rule = (Scroll_Rule_Function*)unit->hook.func; + } } }break; } diff --git a/4ed_app_settings.h b/4ed_app_settings.h index fc320898..ac2cb371 100644 --- a/4ed_app_settings.h +++ b/4ed_app_settings.h @@ -57,6 +57,7 @@ struct App_Models{ Panel *prev_mouse_panel; Custom_API config_api; + Scroll_Rule_Function *scroll_rule; }; // BOTTOM diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index d8d61bbb..c662d3aa 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -28,12 +28,6 @@ struct View_Mode{ i32 rewrite; }; -struct Incremental_Search{ - String str; - b32 reverse; - i32 pos; -}; - enum View_Widget_Type{ FWIDG_NONE, FWIDG_TIMELINES, @@ -76,7 +70,6 @@ struct View{ Panel *panel; Command_Map *map; - Scroll_Rule_Function *scroll_rule; i32 id; Editing_File *file; @@ -130,22 +123,13 @@ struct View{ i32 scroll_i; f32 scroll_min_limit; - union{ - Incremental_Search isearch; - struct{ - String str; - } gotoline; - }; - Full_Cursor temp_highlight; i32 temp_highlight_end_pos; b32 show_temp_highlight; View_Mode mode, next_mode; View_Widget widget; - Query_Set query_set; - i32 scrub_max; b32 unwrapped_lines; @@ -594,20 +578,18 @@ file_create_empty( b32 result = 1; String empty_str = {}; file_create_from_string(system, mem, working_set, file, filename, set, font_id, empty_str); - return result; + return (result); } internal b32 file_create_super_locked( - System_Functions *system, - App_Models *models, - Editing_File *file, - char *filename){ + 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; + return (result); } struct Get_File_Result{ @@ -615,6 +597,7 @@ struct Get_File_Result{ 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 = {}; @@ -2641,22 +2624,23 @@ view_show_config(View *fview, Command_Map *gui_map){ } inline void -view_show_interactive(System_Functions *system, View *fview, Command_Map *gui_map, +view_show_interactive(System_Functions *system, View *view, Command_Map *gui_map, Interactive_Action action, Interactive_Interaction interaction, String query){ - fview->ui_state = {}; - fview->map_for_file = fview->map; - fview->map = gui_map; - fview->locked = 1; - fview->showing_ui = VUI_Interactive; - fview->action = action; - fview->interaction = interaction; - fview->finished = 0; + 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; + view->finished = 0; - copy(&fview->query, query); - fview->dest.size = 0; + copy(&view->query, query); + view->dest.str[0] = 0; + view->dest.size = 0; - hot_directory_clean_end(fview->hot_directory); - hot_directory_reload(system, fview->hot_directory, fview->working_set); + hot_directory_clean_end(view->hot_directory); + hot_directory_reload(system, view->hot_directory, view->working_set); } inline void @@ -2670,21 +2654,23 @@ view_show_theme(View *fview, Command_Map *gui_map){ } inline void -view_show_file(View *fview, Command_Map *file_map){ - fview->ui_state = {}; +view_show_file(View *view, Command_Map *file_map, Editing_File *file){ + view->ui_state = {}; if (file_map){ - fview->map = file_map; + view->map = file_map; } else{ - fview->map = fview->map_for_file; + view->map = view->map_for_file; } - fview->locked = 0; - fview->showing_ui = VUI_None; + view->file = file; + view->locked = 0; + view->showing_ui = VUI_None; } internal void interactive_view_complete(View *view){ Panel *panel = view->panel; + Editing_File *file = 0; switch (view->action){ case IAct_Open: delayed_open(view->delay, view->hot_directory->string, panel); @@ -2692,6 +2678,7 @@ interactive_view_complete(View *view){ case IAct_Save_As: delayed_save_as(view->delay, view->hot_directory->string, panel); + file = view->file; break; case IAct_New: @@ -2704,6 +2691,7 @@ interactive_view_complete(View *view){ case IAct_Kill: delayed_try_kill(view->delay, view->dest, panel); + file = view->file; break; case IAct_Sure_To_Kill: @@ -2723,7 +2711,7 @@ interactive_view_complete(View *view){ } break; } - view_show_file(view, 0); + view_show_file(view, 0, 0); } internal void @@ -3471,7 +3459,7 @@ step_file_view(System_Functions *system, Exchange *exchange, View *view, i32_Rec } // TODO(allen): Split this into passive step and step that depends on input - if (file && !file->state.is_loading){ + if (view->showing_ui == VUI_None && file && !file->state.is_loading){ f32 line_height = (f32)view->font_height; f32 cursor_y = view_get_cursor_y(view); f32 target_y = view->target_y; @@ -3531,10 +3519,10 @@ step_file_view(System_Functions *system, Exchange *exchange, View *view, i32_Rec if (view->target_x != view->prev_target_x) is_new_target = 1; if (view->target_y != view->prev_target_y) is_new_target = 1; - if (view->scroll_rule( + if (view->models->scroll_rule( view->target_x, view->target_y, &view->scroll_x, &view->scroll_y, - view->id, is_new_target)){ + view->id + 1, is_new_target)){ result = 1; } @@ -4166,20 +4154,18 @@ view_change_size(System_Functions *system, General_Memory *general, View *view){ } struct Live_Views{ - void *views; + View *views; View free_sentinel; i32 count, max; - i32 stride; }; -internal View* +inline View* live_set_get_view(Live_Views *live_set, i32 id){ - void *result = ((char*)live_set->views + id); - return (View*)result; + return (live_set->views + id); } internal View_And_ID -live_set_alloc_view(Live_Views *live_set, Scroll_Rule_Function *scroll_rule){ +live_set_alloc_view(Live_Views *live_set){ View_And_ID result = {}; Assert(live_set->count < live_set->max); @@ -4190,8 +4176,7 @@ live_set_alloc_view(Live_Views *live_set, Scroll_Rule_Function *scroll_rule){ result.view->id = result.id; dll_remove(result.view); - memset(result.view, 0, live_set->stride); - result.view->scroll_rule = scroll_rule; + memset(result.view, 0, sizeof(View)); return(result); } diff --git a/4ed_metagen.cpp b/4ed_metagen.cpp index c3cbb926..4ee8583d 100644 --- a/4ed_metagen.cpp +++ b/4ed_metagen.cpp @@ -108,6 +108,7 @@ char* generate_keycode_enum(){ return(filename); } +////////////////////////////////////////////////////////////////////////////////////////////////// char daction_enum_name[] = "Action_Type"; char *daction_enum[] = { "OPEN", @@ -272,15 +273,63 @@ char* generate_delayed_action(){ return(filename); } +////////////////////////////////////////////////////////////////////////////////////////////////// +#define MAJOR 3 +#define MINOR 4 +#define PATCH 5 + +#define VERS3__(a,b,c) #a"."#b"."#c +#define VERS3_(a,b,c) VERS3__(a,b,c) +#define VERS3 VERS3_(MAJOR, MINOR, PATCH) + +#define VERSION_STRING VERS3 + +char version_header[] = +"#define MAJOR %d\n" +"#define MINOR %d\n" +"#define PATCH %d\n" +"#define VERSION_NUMBER \"alpha %s\"\n" +"#ifdef FRED_SUPER\n" +"#define VERSION_TYPE \" super!\"\n" +"#else\n" +"#define VERSION_TYPE \"\"\n" +"#endif\n" +"#define VERSION VERSION_NUMBER VERSION_TYPE\n"; + +char version_custom[] = +"#define MAJOR %d\n" +"#define MINOR %d\n" +"#define PATCH %d\n"; + +char* generate_version(){ + char *filename = "4ed_version.h & 4coder_version.h"; + char filename_header[] = "4ed_version.h"; + char filename_custom[] = "4coder_version.h"; + FILE *file; + + file = fopen(filename_header, "wb"); + fprintf(file, version_header, MAJOR, MINOR, PATCH, VERSION_STRING); + fclose(file); + + file = fopen(filename_custom, "wb"); + fprintf(file, version_custom, MAJOR, MINOR, PATCH); + fclose(file); + + return(filename); +} + + int main(){ char *filename; - filename = generate_keycode_enum(); printf("gen success: %s\n", filename); filename = generate_delayed_action(); printf("gen success: %s\n", filename); + + filename = generate_version(); + printf("gen success: %s\n", filename); } // BOTTOM diff --git a/4ed_template.cpp b/4ed_template.cpp index a73bd02a..46dbcc63 100644 --- a/4ed_template.cpp +++ b/4ed_template.cpp @@ -11,6 +11,9 @@ // NOTE(allen): This is an experiment, BUT remember a lot of people shit on templates. // So if you start getting a wiff of stupidity from this back out immediately! +// +// experience 1: no badness, haven't seen any anoying template errors +// ... template inline void @@ -35,6 +38,7 @@ dll_remove(T *v){ v->prev->next = v->next; } +// for(dll_items(iterator, sentinel_ptr)){...} #define dll_items(it, st) ((it) = (st)->next); ((it) != (st)); ((it) = (it)->next) // BOTTOM diff --git a/4ed_version.h b/4ed_version.h index 264558e3..4982d620 100644 --- a/4ed_version.h +++ b/4ed_version.h @@ -1,19 +1,10 @@ -/* - * Mr. 4th Dimention - Allen Webster - * - * 01.03.2016 - * - * Shared header for version stuff - * - */ - -#define VERSION_NUMBER "alpha 3.4.4" - +#define MAJOR 3 +#define MINOR 4 +#define PATCH 5 +#define VERSION_NUMBER "alpha 3.4.5" #ifdef FRED_SUPER #define VERSION_TYPE " super!" #else #define VERSION_TYPE "" #endif - #define VERSION VERSION_NUMBER VERSION_TYPE - diff --git a/buildsuper.bat b/buildsuper.bat index 92264923..4e187a6b 100644 --- a/buildsuper.bat +++ b/buildsuper.bat @@ -7,7 +7,7 @@ SET clset=64 SET WARNINGS=/W4 /wd4310 /wd4100 /wd4201 /wd4505 /wd4996 /wd4127 /wd4510 /wd4512 /wd4610 /WX SET STUFF=/GR- /nologo SET DEBUG=/Zi -SET EXPORTS=/EXPORT:get_bindings /EXPORT:scroll_rule +SET EXPORTS=/EXPORT:get_bindings SET SRC=4coder_custom.cpp cl %WARNINGS% %STUFF% %DEBUG% %SRC% /Fe4coder_custom /LD /link /INCREMENTAL:NO /OPT:REF %EXPORTS% diff --git a/linux_4ed.cpp b/linux_4ed.cpp index 3e647e20..d0772d70 100644 --- a/linux_4ed.cpp +++ b/linux_4ed.cpp @@ -11,6 +11,7 @@ #include "4ed_config.h" + #include "4ed_meta.h" #define FCPP_FORBID_MALLOC diff --git a/win32_4ed.cpp b/win32_4ed.cpp index df931d43..f93ed357 100644 --- a/win32_4ed.cpp +++ b/win32_4ed.cpp @@ -1743,9 +1743,6 @@ main(int argc, char **argv){ if (win32vars.custom){ win32vars.custom_api.get_bindings = (Get_Binding_Data_Function*) GetProcAddress(win32vars.custom, "get_bindings"); - - win32vars.custom_api.scroll_rule = (Scroll_Rule_Function*) - GetProcAddress(win32vars.custom, "scroll_rule"); } #endif