improvements to custom.cpp

This commit is contained in:
Allen Webster 2016-03-04 01:06:11 -05:00
parent 7b6306683a
commit 18eda91724
13 changed files with 306 additions and 196 deletions

View File

@ -639,7 +639,7 @@ CUSTOM_COMMAND_SIG(execute_any_cli){
hot_directory = make_fixed_width_string(even_more_space); hot_directory = make_fixed_width_string(even_more_space);
hot_directory.size = app->directory_get_hot(app, hot_directory.str, hot_directory.memory_size); 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_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_path, hot_directory.str, hot_directory.size);
push_parameter(app, par_cli_command, bar_cmd.string.str, bar_cmd.string.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 // An example of calling build by setting all
// parameters directly. This only works if build.bat can be called // parameters directly. This only works if build.bat can be called
// from the directory the application is launched at. // 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_name, literal("*compilation*"));
push_parameter(app, par_cli_path, literal(".")); push_parameter(app, par_cli_path, literal("."));
push_parameter(app, par_cli_command, literal("build")); push_parameter(app, par_cli_command, literal("build"));
@ -743,21 +743,24 @@ CUSTOM_COMMAND_SIG(build_search){
// //
// Step 2: app->file_exists queries the file system to see if "<somedir>/build.bat" exists. // Step 2: app->file_exists queries the file system to see if "<somedir>/build.bat" exists.
// If it does exist several parameters are pushed and cmdid_command_line is executed: // 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 // - par_cli_flags: flags for specifiying behaviors
// is already being used for output on the same buffer // 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_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 // - 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 // - par_cli_command: sets the actual command to be executed, this can be almost any
// that you could execute through a command line interface // 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.
// 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.
// //
// 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. // app->directory_cd. The cd function can also be used to navigate to subdirectories.
@ -778,7 +781,7 @@ CUSTOM_COMMAND_SIG(build_search){
if (app->file_exists(app, dir.str, dir.size)){ if (app->file_exists(app, dir.str, dir.size)){
dir.size = old_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_name, literal("*compilation*"));
push_parameter(app, par_cli_path, dir.str, dir.size); 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); 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{ struct Scroll_Velocity{
float x, y; float x, y;
}; };
Scroll_Velocity scroll_velocity[16] = {0}; Scroll_Velocity scroll_velocity_[16] = {0};
Scroll_Velocity *scroll_velocity = scroll_velocity_;
static int static int
smooth_camera_step(float target, float *current, float *vel, float S, float T){ 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; return result;
} }
extern "C" SCROLL_RULE_SIG(scroll_rule){ SCROLL_RULE_SIG(smooth_scroll_rule){
Scroll_Velocity *velocity = scroll_velocity + view_id; Scroll_Velocity *velocity = scroll_velocity + view_id;
int result = 0; int result = 0;
if (velocity->x == 0.f){ 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. // global and once set they always apply, regardless of what map is active.
set_hook(context, hook_start, my_start); set_hook(context, hook_start, my_start);
set_hook(context, hook_open_file, my_file_settings); set_hook(context, hook_open_file, my_file_settings);
set_scroll_rule(context, smooth_scroll_rule);
begin_map(context, mapid_global); begin_map(context, mapid_global);

View File

@ -1,4 +1,5 @@
#include "4coder_version.h"
#include "4coder_keycodes.h" #include "4coder_keycodes.h"
#include "4coder_buffer_types.h" #include "4coder_buffer_types.h"
@ -218,7 +219,6 @@ enum Command_ID{
cmdid_page_up, cmdid_page_up,
cmdid_page_down, cmdid_page_down,
cmdid_open_color_tweaker, cmdid_open_color_tweaker,
cmdid_close_minor_view,
cmdid_cursor_mark_swap, cmdid_cursor_mark_swap,
cmdid_open_menu, cmdid_open_menu,
cmdid_set_settings, cmdid_set_settings,
@ -238,13 +238,17 @@ enum Param_ID{
par_key_mapid, par_key_mapid,
par_cli_path, par_cli_path,
par_cli_command, par_cli_command,
par_cli_overlap_with_conflict, par_cli_flags,
par_cli_always_bind_to_view,
par_clear_blank_lines, par_clear_blank_lines,
// never below this // never below this
par_type_count 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{ enum Hook_ID{
hook_start, hook_start,
hook_open_file, hook_open_file,
@ -252,6 +256,12 @@ enum Hook_ID{
hook_type_count 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 // 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 // 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. // them all const... but that causes a lot problems for C++ reasons.
@ -474,7 +484,6 @@ struct Application_Links{
struct Custom_API{ struct Custom_API{
Get_Binding_Data_Function *get_bindings; Get_Binding_Data_Function *get_bindings;
Scroll_Rule_Function *scroll_rule;
}; };
// NOTE(allen): definitions for the buffer that communicates to 4ed.exe // NOTE(allen): definitions for the buffer that communicates to 4ed.exe
@ -517,7 +526,7 @@ struct Binding_Unit{
} callback; } callback;
struct{ struct{
int hook_id; int hook_id;
Custom_Command_Function *func; void *func;
} hook; } hook;
}; };
}; };

View File

@ -162,6 +162,16 @@ set_hook(Bind_Helper *helper, int hook_id, Custom_Command_Function *func){
write_unit(helper, unit); 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 inline void
end_bind_helper(Bind_Helper *helper){ end_bind_helper(Bind_Helper *helper){
if (helper->header){ if (helper->header){

3
4coder_version.h Normal file
View File

@ -0,0 +1,3 @@
#define MAJOR 3
#define MINOR 4
#define PATCH 5

220
4ed.cpp
View File

@ -194,7 +194,7 @@ panel_make_empty(System_Functions *system, Exchange *exchange, App_Vars *vars, P
View_And_ID new_view; View_And_ID new_view;
Assert(panel->view == 0); 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 = new_view.view;
panel->view->panel = panel; panel->view->panel = panel;
@ -539,7 +539,7 @@ COMMAND_DECL(word_complete){
COMMAND_DECL(set_mark){ COMMAND_DECL(set_mark){
ProfileMomentFunction(); ProfileMomentFunction();
REQ_OPEN_VIEW(view); USE_VIEW(view);
REQ_FILE(file, view); REQ_FILE(file, view);
view->mark = (i32)view->cursor.pos; view->mark = (i32)view->cursor.pos;
@ -548,7 +548,7 @@ COMMAND_DECL(set_mark){
COMMAND_DECL(copy){ COMMAND_DECL(copy){
ProfileMomentFunction(); ProfileMomentFunction();
USE_MODELS(models); USE_MODELS(models);
REQ_OPEN_VIEW(view); USE_VIEW(view);
REQ_FILE(file, view); REQ_FILE(file, view);
// TODO(allen): deduplicate // TODO(allen): deduplicate
@ -755,7 +755,7 @@ COMMAND_DECL(history_forward){
COMMAND_DECL(interactive_new){ COMMAND_DECL(interactive_new){
ProfileMomentFunction(); ProfileMomentFunction();
USE_MODELS(models); USE_MODELS(models);
REQ_OPEN_VIEW(view); USE_VIEW(view);
view_show_interactive(system, view, &models->map_ui, view_show_interactive(system, view, &models->map_ui,
IAct_New, IInt_Sys_File_List, make_lit_string("New: ")); IAct_New, IInt_Sys_File_List, make_lit_string("New: "));
@ -813,7 +813,7 @@ COMMAND_DECL(interactive_open){
ProfileMomentFunction(); ProfileMomentFunction();
USE_MODELS(models); USE_MODELS(models);
USE_PANEL(panel); USE_PANEL(panel);
REQ_OPEN_VIEW(view); USE_VIEW(view);
Delay *delay = &models->delay1; Delay *delay = &models->delay1;
@ -846,9 +846,6 @@ COMMAND_DECL(interactive_open){
} }
} }
else{ else{
View *view = panel->view;
Assert(view);
view_show_interactive(system, view, &models->map_ui, view_show_interactive(system, view, &models->map_ui,
IAct_Open, IInt_Sys_File_List, make_lit_string("Open: ")); IAct_Open, IInt_Sys_File_List, make_lit_string("Open: "));
} }
@ -1537,7 +1534,7 @@ COMMAND_DECL(close_minor_view){
if (view->file){ if (view->file){
map = app_get_map(models, view->file->settings.base_map_id); 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){ 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){ COMMAND_DECL(command_line){
ProfileMomentFunction(); ProfileMomentFunction();
USE_VARS(vars); USE_VARS(vars);
USE_MODELS(models); USE_MODELS(models);
USE_PANEL(panel); USE_PANEL(panel);
USE_VIEW(view);
Partition *part = &models->mem.part;
char *buffer_name = 0; char *buffer_name = 0;
char *path = 0; char *path = 0;
char *script = 0; char *script = 0;
int buffer_name_len = 0; i32 buffer_id = 0;
int path_len = 0; i32 buffer_name_len = 0;
int script_len = 0; i32 path_len = 0;
i32 script_len = 0;
u32 flags = CLI_OverlapWithConflict; u32 flags = CLI_OverlapWithConflict;
Command_Parameter *end = param_stack_end(&command->part); Command_Parameter *end = param_stack_end(&command->part);
@ -1650,115 +1648,135 @@ COMMAND_DECL(command_line){
switch (p){ switch (p){
case par_name: case par_name:
{ {
if (buffer_name == 0){
char *new_buffer_name = dynamic_to_string(&param->param.value, &buffer_name_len); char *new_buffer_name = dynamic_to_string(&param->param.value, &buffer_name_len);
if (new_buffer_name){ if (new_buffer_name){
buffer_name = new_buffer_name; buffer_name = new_buffer_name;
} }
} }break;
case par_buffer_id:
{
buffer_id = dynamic_to_int(&param->param.value);
}break; }break;
case par_cli_path: case par_cli_path:
{ {
if (path == 0){
char *new_cli_path = dynamic_to_string(&param->param.value, &path_len); char *new_cli_path = dynamic_to_string(&param->param.value, &path_len);
if (new_cli_path){ if (new_cli_path){
path = new_cli_path; path = new_cli_path;
} }
}
}break; }break;
case par_cli_command: case par_cli_command:
{ {
if (script == 0){
char *new_command = dynamic_to_string(&param->param.value, &script_len); char *new_command = dynamic_to_string(&param->param.value, &script_len);
if (new_command){ if (new_command){
script = new_command; script = new_command;
} }
}
}break; }break;
case par_cli_overlap_with_conflict: case par_cli_flags:
{ {
if (dynamic_to_int(&param->param.value)) flags = (u32)dynamic_to_int(&param->param.value);
flags |= CLI_OverlapWithConflict;
else
flags &= (~CLI_OverlapWithConflict);
}break;
case par_cli_always_bind_to_view:
{
if (dynamic_to_int(&param->param.value))
flags |= CLI_OverlapWithConflict;
else
flags &= (~CLI_OverlapWithConflict);
}break; }break;
} }
} }
{ {
Working_Set *working_set = &models->working_set; Working_Set *working_set = &models->working_set;
Editing_File *file; CLI_Process *procs = vars->cli_processes.procs, *proc = 0;
i32 index = 0; Get_File_Result file = {};
b32 bind_to_new_view; b32 bind_to_new_view = 1;
if (buffer_name == 0 || path == 0 || script == 0){
return;
}
if (vars->cli_processes.count < vars->cli_processes.max){ if (vars->cli_processes.count < vars->cli_processes.max){
file = working_set_contains(working_set, make_string_slowly(buffer_name)); if (buffer_id){
bind_to_new_view = 1; if (buffer_id > 0 && buffer_id < working_set->file_index_count){
file.file = working_set->files + buffer_id;
if (!file){ file.index = buffer_id;
Get_File_Result get_file = working_set_get_available_file(working_set); }
file = get_file.file;
index = get_file.index;
} }
else{ 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; i32 proc_count = vars->cli_processes.count;
for (i32 i = 0; i < proc_count; ++i){ View_Iter iter;
if (vars->cli_processes.procs[i].out_file == file){ i32 i;
for (i = 0; i < proc_count; ++i){
if (procs[i].out_file == file.file){
if (flags & CLI_OverlapWithConflict) if (flags & CLI_OverlapWithConflict)
vars->cli_processes.procs[i].out_file = 0; procs[i].out_file = 0;
else file = 0; else
file.file = 0;
break; break;
} }
} }
index = (i32)(file - models->working_set.files);
if (file){ if (file.file){
if (!(flags & CLI_AlwaysBindToView)){ if (!(flags & CLI_AlwaysBindToView)){
View_Iter iter; iter = file_view_iter_init(&models->layout, file.file, 0);
iter = file_view_iter_init(&models->layout, file, 0);
if (file_view_iter_good(iter)){ if (file_view_iter_good(iter)){
bind_to_new_view = 0; bind_to_new_view = 0;
} }
} }
}
}
if (file){ file_create_super_locked(system, models, file.file, buffer_name);
file_create_super_locked(system, models, file, buffer_name); file.file->settings.unimportant = 1;
file->settings.unimportant = 1; table_add(&working_set->table, file.file->name.source_path, file.index);
table_add(&working_set->table, file->name.source_path, index);
if (bind_to_new_view){
view_file_in_panel(command, panel, file);
}
i32 i = vars->cli_processes.count++;
CLI_Process *proc = vars->cli_processes.procs + i;
if (!system->cli_call(path, script, &proc->cli)){
--vars->cli_processes.count;
}
proc->out_file = file;
} }
else{ else{
// TODO(allen): feedback message - no available file // TODO(allen): feedback message - no available file
return;
}
}
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;
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";
}
}
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;
}
end_temp_memory(temp);
} }
} }
else{ else{
// TODO(allen): feedback message - no available process slot // 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 internal void
fill_view_summary(View_Summary *view, View *file_view, Live_Views *live_set, Working_Set *working_set){ fill_view_summary(View_Summary *view, View *file_view, Live_Views *live_set, Working_Set *working_set){
view->exists = 1; 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){ if (file_view->file){
view->buffer_id = (int)(file_view->file - working_set->files); view->buffer_id = (int)(file_view->file - working_set->files);
view->mark = view_compute_cursor_from_pos(file_view, file_view->mark); view->mark = view_compute_cursor_from_pos(file_view, file_view->mark);
view->cursor = file_view->cursor; view->cursor = file_view->cursor;
view->preferred_x = file_view->preferred_x; 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){ GET_VIEW_MAX_INDEX_SIG(external_get_view_max_index){
Command_Data *cmd = (Command_Data*)app->cmd_context; Command_Data *cmd = (Command_Data*)app->cmd_context;
Live_Views *live_set = cmd->live_set; Live_Views *live_set = cmd->live_set;
int max = live_set->max; int max = live_set->max + 1;
return(max); return(max);
} }
@ -2095,8 +2120,9 @@ extern "C"{
int max = live_set->max; int max = live_set->max;
View *vptr; View *vptr;
index -= 1;
if (index >= 0 && index < max){ 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); fill_view_summary(&view, vptr, live_set, &cmd->models->working_set);
} }
@ -2127,7 +2153,7 @@ extern "C"{
if (view->exists){ if (view->exists){
live_set = cmd->live_set; 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; result = 1;
if (seek.type == buffer_seek_line_char && seek.character <= 0){ if (seek.type == buffer_seek_line_char && seek.character <= 0){
seek.character = 1; seek.character = 1;
@ -2151,7 +2177,7 @@ extern "C"{
if (view->exists){ if (view->exists){
live_set = cmd->live_set; 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; result = 1;
if (seek.type == buffer_seek_line_char && seek.character <= 0){ if (seek.type == buffer_seek_line_char && seek.character <= 0){
seek.character = 1; seek.character = 1;
@ -2177,7 +2203,7 @@ extern "C"{
if (view->exists){ if (view->exists){
live_set = cmd->live_set; 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; result = 1;
if (turn_on){ if (turn_on){
view_set_temp_highlight(vptr, start, end); view_set_temp_highlight(vptr, start, end);
@ -2203,7 +2229,7 @@ extern "C"{
if (view->exists){ if (view->exists){
models = cmd->models; models = cmd->models;
live_set = cmd->live_set; 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; working_set = &models->working_set;
max = working_set->file_index_count; max = working_set->file_index_count;
if (buffer_id >= 0 && buffer_id < max){ if (buffer_id >= 0 && buffer_id < max){
@ -2346,7 +2372,7 @@ setup_file_commands(Command_Map *commands, Partition *part, Command_Map *parent)
internal void internal void
setup_top_commands(Command_Map *commands, Partition *part, Command_Map *parent){ 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 internal void
@ -2412,7 +2438,6 @@ setup_command_table(){
SET(page_up); SET(page_up);
SET(page_down); SET(page_down);
SET(open_color_tweaker); SET(open_color_tweaker);
SET(close_minor_view);
SET(cursor_mark_swap); SET(cursor_mark_swap);
SET(open_menu); SET(open_menu);
SET(set_settings); SET(set_settings);
@ -2877,25 +2902,21 @@ App_Init_Sig(app_init){
} }
{ {
char *vptr = 0; View *vptr = 0;
View *v = 0;
i32 i = 0; i32 i = 0;
i32 max = 0; i32 max = 0;
i32 view_size = sizeof(View);
vars->live_set.count = 0; vars->live_set.count = 0;
vars->live_set.max = panel_max_count; vars->live_set.max = panel_max_count;
vars->live_set.stride = view_size; vars->live_set.views = push_array(partition, View, vars->live_set.max);
vars->live_set.views = push_block(partition, view_size*vars->live_set.max);
dll_init_sentinel(&vars->live_set.free_sentinel); dll_init_sentinel(&vars->live_set.free_sentinel);
max = vars->live_set.max; max = vars->live_set.max;
vptr = (char*)vars->live_set.views; vptr = vars->live_set.views;
for (i = 0; i < max; ++i, vptr += view_size){ for (i = 0; i < max; ++i, ++vptr){
v = (View*)(vptr); dll_insert(&vars->live_set.free_sentinel, vptr);
dll_insert(&vars->live_set.free_sentinel, v);
} }
} }
@ -2905,9 +2926,7 @@ App_Init_Sig(app_init){
b32 did_top = 0; b32 did_top = 0;
b32 did_file = 0; b32 did_file = 0;
if (models->config_api.scroll_rule == 0){ models->scroll_rule = fallback_scroll_rule;
models->config_api.scroll_rule = fallback_scroll_rule;
}
setup_command_table(); setup_command_table();
@ -3010,8 +3029,13 @@ App_Init_Sig(app_init){
case unit_hook: case unit_hook:
{ {
int hook_id = unit->hook.hook_id; int hook_id = unit->hook.hook_id;
if (hook_id >= 0 && hook_id < hook_type_count){ if (hook_id >= 0){
models->hooks[hook_id] = unit->hook.func; 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; }break;
} }

View File

@ -57,6 +57,7 @@ struct App_Models{
Panel *prev_mouse_panel; Panel *prev_mouse_panel;
Custom_API config_api; Custom_API config_api;
Scroll_Rule_Function *scroll_rule;
}; };
// BOTTOM // BOTTOM

View File

@ -28,12 +28,6 @@ struct View_Mode{
i32 rewrite; i32 rewrite;
}; };
struct Incremental_Search{
String str;
b32 reverse;
i32 pos;
};
enum View_Widget_Type{ enum View_Widget_Type{
FWIDG_NONE, FWIDG_NONE,
FWIDG_TIMELINES, FWIDG_TIMELINES,
@ -76,7 +70,6 @@ struct View{
Panel *panel; Panel *panel;
Command_Map *map; Command_Map *map;
Scroll_Rule_Function *scroll_rule;
i32 id; i32 id;
Editing_File *file; Editing_File *file;
@ -130,22 +123,13 @@ struct View{
i32 scroll_i; i32 scroll_i;
f32 scroll_min_limit; f32 scroll_min_limit;
union{
Incremental_Search isearch;
struct{
String str;
} gotoline;
};
Full_Cursor temp_highlight; Full_Cursor temp_highlight;
i32 temp_highlight_end_pos; i32 temp_highlight_end_pos;
b32 show_temp_highlight; b32 show_temp_highlight;
View_Mode mode, next_mode; View_Mode mode, next_mode;
View_Widget widget; View_Widget widget;
Query_Set query_set; Query_Set query_set;
i32 scrub_max; i32 scrub_max;
b32 unwrapped_lines; b32 unwrapped_lines;
@ -594,20 +578,18 @@ file_create_empty(
b32 result = 1; b32 result = 1;
String empty_str = {}; String empty_str = {};
file_create_from_string(system, mem, working_set, file, filename, set, font_id, empty_str); file_create_from_string(system, mem, working_set, file, filename, set, font_id, empty_str);
return result; return (result);
} }
internal b32 internal b32
file_create_super_locked( file_create_super_locked(
System_Functions *system, System_Functions *system, App_Models *models,
App_Models *models, Editing_File *file, char *filename){
Editing_File *file,
char *filename){
b32 result = 1; b32 result = 1;
String empty_str = {}; String empty_str = {};
file_create_from_string(system, &models->mem, &models->working_set, file_create_from_string(system, &models->mem, &models->working_set,
file, filename, models->font_set, models->global_font.font_id, empty_str, 1); file, filename, models->font_set, models->global_font.font_id, empty_str, 1);
return result; return (result);
} }
struct Get_File_Result{ struct Get_File_Result{
@ -615,6 +597,7 @@ struct Get_File_Result{
i32 index; i32 index;
}; };
// TODO(allen): convert buffers to a dll allocation scheme
internal Get_File_Result internal Get_File_Result
working_set_get_available_file(Working_Set *working_set){ working_set_get_available_file(Working_Set *working_set){
Get_File_Result result = {}; Get_File_Result result = {};
@ -2641,22 +2624,23 @@ view_show_config(View *fview, Command_Map *gui_map){
} }
inline void 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){ Interactive_Action action, Interactive_Interaction interaction, String query){
fview->ui_state = {}; view->ui_state = {};
fview->map_for_file = fview->map; view->map_for_file = view->map;
fview->map = gui_map; view->map = gui_map;
fview->locked = 1; view->locked = 1;
fview->showing_ui = VUI_Interactive; view->showing_ui = VUI_Interactive;
fview->action = action; view->action = action;
fview->interaction = interaction; view->interaction = interaction;
fview->finished = 0; view->finished = 0;
copy(&fview->query, query); copy(&view->query, query);
fview->dest.size = 0; view->dest.str[0] = 0;
view->dest.size = 0;
hot_directory_clean_end(fview->hot_directory); hot_directory_clean_end(view->hot_directory);
hot_directory_reload(system, fview->hot_directory, fview->working_set); hot_directory_reload(system, view->hot_directory, view->working_set);
} }
inline void inline void
@ -2670,21 +2654,23 @@ view_show_theme(View *fview, Command_Map *gui_map){
} }
inline void inline void
view_show_file(View *fview, Command_Map *file_map){ view_show_file(View *view, Command_Map *file_map, Editing_File *file){
fview->ui_state = {}; view->ui_state = {};
if (file_map){ if (file_map){
fview->map = file_map; view->map = file_map;
} }
else{ else{
fview->map = fview->map_for_file; view->map = view->map_for_file;
} }
fview->locked = 0; view->file = file;
fview->showing_ui = VUI_None; view->locked = 0;
view->showing_ui = VUI_None;
} }
internal void internal void
interactive_view_complete(View *view){ interactive_view_complete(View *view){
Panel *panel = view->panel; Panel *panel = view->panel;
Editing_File *file = 0;
switch (view->action){ switch (view->action){
case IAct_Open: case IAct_Open:
delayed_open(view->delay, view->hot_directory->string, panel); delayed_open(view->delay, view->hot_directory->string, panel);
@ -2692,6 +2678,7 @@ interactive_view_complete(View *view){
case IAct_Save_As: case IAct_Save_As:
delayed_save_as(view->delay, view->hot_directory->string, panel); delayed_save_as(view->delay, view->hot_directory->string, panel);
file = view->file;
break; break;
case IAct_New: case IAct_New:
@ -2704,6 +2691,7 @@ interactive_view_complete(View *view){
case IAct_Kill: case IAct_Kill:
delayed_try_kill(view->delay, view->dest, panel); delayed_try_kill(view->delay, view->dest, panel);
file = view->file;
break; break;
case IAct_Sure_To_Kill: case IAct_Sure_To_Kill:
@ -2723,7 +2711,7 @@ interactive_view_complete(View *view){
} }
break; break;
} }
view_show_file(view, 0); view_show_file(view, 0, 0);
} }
internal void 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 // 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 line_height = (f32)view->font_height;
f32 cursor_y = view_get_cursor_y(view); f32 cursor_y = view_get_cursor_y(view);
f32 target_y = view->target_y; 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_x != view->prev_target_x) is_new_target = 1;
if (view->target_y != view->prev_target_y) 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->target_x, view->target_y,
&view->scroll_x, &view->scroll_y, &view->scroll_x, &view->scroll_y,
view->id, is_new_target)){ view->id + 1, is_new_target)){
result = 1; result = 1;
} }
@ -4166,20 +4154,18 @@ view_change_size(System_Functions *system, General_Memory *general, View *view){
} }
struct Live_Views{ struct Live_Views{
void *views; View *views;
View free_sentinel; View free_sentinel;
i32 count, max; i32 count, max;
i32 stride;
}; };
internal View* inline View*
live_set_get_view(Live_Views *live_set, i32 id){ live_set_get_view(Live_Views *live_set, i32 id){
void *result = ((char*)live_set->views + id); return (live_set->views + id);
return (View*)result;
} }
internal View_And_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 = {}; View_And_ID result = {};
Assert(live_set->count < live_set->max); 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; result.view->id = result.id;
dll_remove(result.view); dll_remove(result.view);
memset(result.view, 0, live_set->stride); memset(result.view, 0, sizeof(View));
result.view->scroll_rule = scroll_rule;
return(result); return(result);
} }

View File

@ -108,6 +108,7 @@ char* generate_keycode_enum(){
return(filename); return(filename);
} }
//////////////////////////////////////////////////////////////////////////////////////////////////
char daction_enum_name[] = "Action_Type"; char daction_enum_name[] = "Action_Type";
char *daction_enum[] = { char *daction_enum[] = {
"OPEN", "OPEN",
@ -272,15 +273,63 @@ char* generate_delayed_action(){
return(filename); 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(){ int main(){
char *filename; char *filename;
filename = generate_keycode_enum(); filename = generate_keycode_enum();
printf("gen success: %s\n", filename); printf("gen success: %s\n", filename);
filename = generate_delayed_action(); filename = generate_delayed_action();
printf("gen success: %s\n", filename); printf("gen success: %s\n", filename);
filename = generate_version();
printf("gen success: %s\n", filename);
} }
// BOTTOM // BOTTOM

View File

@ -11,6 +11,9 @@
// NOTE(allen): This is an experiment, BUT remember a lot of people shit on templates. // 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! // 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<typename T> template<typename T>
inline void inline void
@ -35,6 +38,7 @@ dll_remove(T *v){
v->prev->next = v->next; v->prev->next = v->next;
} }
// for(dll_items(iterator, sentinel_ptr)){...}
#define dll_items(it, st) ((it) = (st)->next); ((it) != (st)); ((it) = (it)->next) #define dll_items(it, st) ((it) = (st)->next); ((it) != (st)); ((it) = (it)->next)
// BOTTOM // BOTTOM

View File

@ -1,19 +1,10 @@
/* #define MAJOR 3
* Mr. 4th Dimention - Allen Webster #define MINOR 4
* #define PATCH 5
* 01.03.2016 #define VERSION_NUMBER "alpha 3.4.5"
*
* Shared header for version stuff
*
*/
#define VERSION_NUMBER "alpha 3.4.4"
#ifdef FRED_SUPER #ifdef FRED_SUPER
#define VERSION_TYPE " super!" #define VERSION_TYPE " super!"
#else #else
#define VERSION_TYPE "" #define VERSION_TYPE ""
#endif #endif
#define VERSION VERSION_NUMBER VERSION_TYPE #define VERSION VERSION_NUMBER VERSION_TYPE

View File

@ -7,7 +7,7 @@ SET clset=64
SET WARNINGS=/W4 /wd4310 /wd4100 /wd4201 /wd4505 /wd4996 /wd4127 /wd4510 /wd4512 /wd4610 /WX SET WARNINGS=/W4 /wd4310 /wd4100 /wd4201 /wd4505 /wd4996 /wd4127 /wd4510 /wd4512 /wd4610 /WX
SET STUFF=/GR- /nologo SET STUFF=/GR- /nologo
SET DEBUG=/Zi SET DEBUG=/Zi
SET EXPORTS=/EXPORT:get_bindings /EXPORT:scroll_rule SET EXPORTS=/EXPORT:get_bindings
SET SRC=4coder_custom.cpp SET SRC=4coder_custom.cpp
cl %WARNINGS% %STUFF% %DEBUG% %SRC% /Fe4coder_custom /LD /link /INCREMENTAL:NO /OPT:REF %EXPORTS% cl %WARNINGS% %STUFF% %DEBUG% %SRC% /Fe4coder_custom /LD /link /INCREMENTAL:NO /OPT:REF %EXPORTS%

View File

@ -11,6 +11,7 @@
#include "4ed_config.h" #include "4ed_config.h"
#include "4ed_meta.h" #include "4ed_meta.h"
#define FCPP_FORBID_MALLOC #define FCPP_FORBID_MALLOC

View File

@ -1743,9 +1743,6 @@ main(int argc, char **argv){
if (win32vars.custom){ if (win32vars.custom){
win32vars.custom_api.get_bindings = (Get_Binding_Data_Function*) win32vars.custom_api.get_bindings = (Get_Binding_Data_Function*)
GetProcAddress(win32vars.custom, "get_bindings"); GetProcAddress(win32vars.custom, "get_bindings");
win32vars.custom_api.scroll_rule = (Scroll_Rule_Function*)
GetProcAddress(win32vars.custom, "scroll_rule");
} }
#endif #endif