cleaned up the child process updating and CLI list managing
This commit is contained in:
parent
bd2ef80f30
commit
a1b0f805d1
|
@ -1,7 +1,7 @@
|
||||||
struct Application_Links;
|
struct Application_Links;
|
||||||
#define GLOBAL_SET_SETTING_SIG(n) bool32 n(Application_Links *app, Global_Setting_ID setting, int32_t value)
|
#define GLOBAL_SET_SETTING_SIG(n) bool32 n(Application_Links *app, Global_Setting_ID setting, int32_t value)
|
||||||
#define EXEC_COMMAND_SIG(n) bool32 n(Application_Links *app, Command_ID command_id)
|
#define EXEC_COMMAND_SIG(n) bool32 n(Application_Links *app, Command_ID command_id)
|
||||||
#define EXEC_SYSTEM_COMMAND_SIG(n) bool32 n(Application_Links *app, View_Summary *view, Buffer_Identifier buffer, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags)
|
#define EXEC_SYSTEM_COMMAND_SIG(n) bool32 n(Application_Links *app, View_Summary *view, Buffer_Identifier buffer_id, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags)
|
||||||
#define CLIPBOARD_POST_SIG(n) void n(Application_Links *app, int32_t clipboard_id, char *str, int32_t len)
|
#define CLIPBOARD_POST_SIG(n) void n(Application_Links *app, int32_t clipboard_id, char *str, int32_t len)
|
||||||
#define CLIPBOARD_COUNT_SIG(n) int32_t n(Application_Links *app, int32_t clipboard_id)
|
#define CLIPBOARD_COUNT_SIG(n) int32_t n(Application_Links *app, int32_t clipboard_id)
|
||||||
#define CLIPBOARD_INDEX_SIG(n) int32_t n(Application_Links *app, int32_t clipboard_id, int32_t item_index, char *out, int32_t len)
|
#define CLIPBOARD_INDEX_SIG(n) int32_t n(Application_Links *app, int32_t clipboard_id, int32_t item_index, char *out, int32_t len)
|
||||||
|
@ -394,7 +394,7 @@ app_links->send_exit_signal_ = Send_Exit_Signal;} while(false)
|
||||||
#if defined(ALLOW_DEP_4CODER)
|
#if defined(ALLOW_DEP_4CODER)
|
||||||
static inline bool32 global_set_setting(Application_Links *app, Global_Setting_ID setting, int32_t value){return(app->global_set_setting(app, setting, value));}
|
static inline bool32 global_set_setting(Application_Links *app, Global_Setting_ID setting, int32_t value){return(app->global_set_setting(app, setting, value));}
|
||||||
static inline bool32 exec_command(Application_Links *app, Command_ID command_id){return(app->exec_command(app, command_id));}
|
static inline bool32 exec_command(Application_Links *app, Command_ID command_id){return(app->exec_command(app, command_id));}
|
||||||
static inline bool32 exec_system_command(Application_Links *app, View_Summary *view, Buffer_Identifier buffer, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags){return(app->exec_system_command(app, view, buffer, path, path_len, command, command_len, flags));}
|
static inline bool32 exec_system_command(Application_Links *app, View_Summary *view, Buffer_Identifier buffer_id, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags){return(app->exec_system_command(app, view, buffer_id, path, path_len, command, command_len, flags));}
|
||||||
static inline void clipboard_post(Application_Links *app, int32_t clipboard_id, char *str, int32_t len){(app->clipboard_post(app, clipboard_id, str, len));}
|
static inline void clipboard_post(Application_Links *app, int32_t clipboard_id, char *str, int32_t len){(app->clipboard_post(app, clipboard_id, str, len));}
|
||||||
static inline int32_t clipboard_count(Application_Links *app, int32_t clipboard_id){return(app->clipboard_count(app, clipboard_id));}
|
static inline int32_t clipboard_count(Application_Links *app, int32_t clipboard_id){return(app->clipboard_count(app, clipboard_id));}
|
||||||
static inline int32_t clipboard_index(Application_Links *app, int32_t clipboard_id, int32_t item_index, char *out, int32_t len){return(app->clipboard_index(app, clipboard_id, item_index, out, len));}
|
static inline int32_t clipboard_index(Application_Links *app, int32_t clipboard_id, int32_t item_index, char *out, int32_t len){return(app->clipboard_index(app, clipboard_id, item_index, out, len));}
|
||||||
|
@ -471,7 +471,7 @@ static inline void send_exit_signal(Application_Links *app){(app->send_exit_sign
|
||||||
#else
|
#else
|
||||||
static inline bool32 global_set_setting(Application_Links *app, Global_Setting_ID setting, int32_t value){return(app->global_set_setting_(app, setting, value));}
|
static inline bool32 global_set_setting(Application_Links *app, Global_Setting_ID setting, int32_t value){return(app->global_set_setting_(app, setting, value));}
|
||||||
static inline bool32 exec_command(Application_Links *app, Command_ID command_id){return(app->exec_command_(app, command_id));}
|
static inline bool32 exec_command(Application_Links *app, Command_ID command_id){return(app->exec_command_(app, command_id));}
|
||||||
static inline bool32 exec_system_command(Application_Links *app, View_Summary *view, Buffer_Identifier buffer, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags){return(app->exec_system_command_(app, view, buffer, path, path_len, command, command_len, flags));}
|
static inline bool32 exec_system_command(Application_Links *app, View_Summary *view, Buffer_Identifier buffer_id, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags){return(app->exec_system_command_(app, view, buffer_id, path, path_len, command, command_len, flags));}
|
||||||
static inline void clipboard_post(Application_Links *app, int32_t clipboard_id, char *str, int32_t len){(app->clipboard_post_(app, clipboard_id, str, len));}
|
static inline void clipboard_post(Application_Links *app, int32_t clipboard_id, char *str, int32_t len){(app->clipboard_post_(app, clipboard_id, str, len));}
|
||||||
static inline int32_t clipboard_count(Application_Links *app, int32_t clipboard_id){return(app->clipboard_count_(app, clipboard_id));}
|
static inline int32_t clipboard_count(Application_Links *app, int32_t clipboard_id){return(app->clipboard_count_(app, clipboard_id));}
|
||||||
static inline int32_t clipboard_index(Application_Links *app, int32_t clipboard_id, int32_t item_index, char *out, int32_t len){return(app->clipboard_index_(app, clipboard_id, item_index, out, len));}
|
static inline int32_t clipboard_index(Application_Links *app, int32_t clipboard_id, int32_t item_index, char *out, int32_t len){return(app->clipboard_index_(app, clipboard_id, item_index, out, len));}
|
||||||
|
|
150
4ed.cpp
150
4ed.cpp
|
@ -145,29 +145,18 @@ global_const char messages[] =
|
||||||
#define DEFAULT_DISPLAY_WIDTH 672
|
#define DEFAULT_DISPLAY_WIDTH 672
|
||||||
#define DEFAULT_MINIMUM_BASE_DISPLAY_WIDTH 550
|
#define DEFAULT_MINIMUM_BASE_DISPLAY_WIDTH 550
|
||||||
|
|
||||||
typedef enum App_State{
|
enum App_State{
|
||||||
APP_STATE_EDIT,
|
APP_STATE_EDIT,
|
||||||
APP_STATE_RESIZING,
|
APP_STATE_RESIZING,
|
||||||
// never below this
|
// never below this
|
||||||
APP_STATE_COUNT
|
APP_STATE_COUNT
|
||||||
} App_State;
|
};
|
||||||
|
|
||||||
typedef struct App_State_Resizing{
|
struct App_State_Resizing{
|
||||||
Panel_Divider *divider;
|
Panel_Divider *divider;
|
||||||
} App_State_Resizing;
|
};
|
||||||
|
|
||||||
typedef struct CLI_Process{
|
struct Command_Data{
|
||||||
CLI_Handles cli;
|
|
||||||
Editing_File *out_file;
|
|
||||||
b32 cursor_at_end;
|
|
||||||
} CLI_Process;
|
|
||||||
|
|
||||||
typedef struct CLI_List{
|
|
||||||
CLI_Process *procs;
|
|
||||||
i32 count, max;
|
|
||||||
} CLI_List;
|
|
||||||
|
|
||||||
typedef struct Command_Data{
|
|
||||||
Models *models;
|
Models *models;
|
||||||
struct App_Vars *vars;
|
struct App_Vars *vars;
|
||||||
System_Functions *system;
|
System_Functions *system;
|
||||||
|
@ -175,9 +164,9 @@ typedef struct Command_Data{
|
||||||
|
|
||||||
i32 screen_width, screen_height;
|
i32 screen_width, screen_height;
|
||||||
Key_Event_Data key;
|
Key_Event_Data key;
|
||||||
} Command_Data;
|
};
|
||||||
|
|
||||||
typedef enum Input_Types{
|
enum Input_Types{
|
||||||
Input_AnyKey,
|
Input_AnyKey,
|
||||||
Input_Esc,
|
Input_Esc,
|
||||||
Input_MouseMove,
|
Input_MouseMove,
|
||||||
|
@ -185,18 +174,18 @@ typedef enum Input_Types{
|
||||||
Input_MouseRightButton,
|
Input_MouseRightButton,
|
||||||
Input_MouseWheel,
|
Input_MouseWheel,
|
||||||
Input_Count
|
Input_Count
|
||||||
} Input_Types;
|
};
|
||||||
|
|
||||||
typedef struct Consumption_Record{
|
struct Consumption_Record{
|
||||||
b32 consumed;
|
b32 consumed;
|
||||||
char consumer[32];
|
char consumer[32];
|
||||||
} Consumption_Record;
|
};
|
||||||
|
|
||||||
typedef struct Available_Input{
|
struct Available_Input{
|
||||||
Key_Input_Data *keys;
|
Key_Input_Data *keys;
|
||||||
Mouse_State *mouse;
|
Mouse_State *mouse;
|
||||||
Consumption_Record records[Input_Count];
|
Consumption_Record records[Input_Count];
|
||||||
} Available_Input;
|
};
|
||||||
|
|
||||||
internal Available_Input
|
internal Available_Input
|
||||||
init_available_input(Key_Input_Data *keys, Mouse_State *mouse){
|
init_available_input(Key_Input_Data *keys, Mouse_State *mouse){
|
||||||
|
@ -297,14 +286,14 @@ struct App_Vars{
|
||||||
};
|
};
|
||||||
global_const App_Vars null_app_vars = {0};
|
global_const App_Vars null_app_vars = {0};
|
||||||
|
|
||||||
typedef enum Coroutine_Type{
|
enum Coroutine_Type{
|
||||||
Co_View,
|
Co_View,
|
||||||
Co_Command
|
Co_Command
|
||||||
} Coroutine_Type;
|
};
|
||||||
typedef struct App_Coroutine_State{
|
struct App_Coroutine_State{
|
||||||
void *co;
|
void *co;
|
||||||
i32 type;
|
i32 type;
|
||||||
} App_Coroutine_State;
|
};
|
||||||
|
|
||||||
inline App_Coroutine_State
|
inline App_Coroutine_State
|
||||||
get_state(Application_Links *app){
|
get_state(Application_Links *app){
|
||||||
|
@ -1353,68 +1342,13 @@ App_Init_Sig(app_init){
|
||||||
hot_directory_init(&models->hot_directory, current_directory);
|
hot_directory_init(&models->hot_directory, current_directory);
|
||||||
|
|
||||||
// NOTE(allen): child proc list setup
|
// NOTE(allen): child proc list setup
|
||||||
i32 max_children = 16;
|
vars->cli_processes = make_cli_list(partition, 16);
|
||||||
partition_align(partition, 8);
|
|
||||||
vars->cli_processes.procs = push_array(partition, CLI_Process, max_children);
|
|
||||||
vars->cli_processes.max = max_children;
|
|
||||||
vars->cli_processes.count = 0;
|
|
||||||
|
|
||||||
// NOTE(allen): init GUI keys
|
// NOTE(allen): init GUI keys
|
||||||
models->user_up_key = key_up;
|
models->user_up_key = key_up;
|
||||||
models->user_down_key = key_down;
|
models->user_down_key = key_down;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal i32
|
|
||||||
update_cli_handle_without_file(System_Functions *system, Models *models, CLI_Handles *cli, char *dest, i32 max){
|
|
||||||
i32 result = 0;
|
|
||||||
u32 amount = 0;
|
|
||||||
|
|
||||||
system->cli_begin_update(cli);
|
|
||||||
if (system->cli_update_step(cli, dest, max, &amount)){
|
|
||||||
result = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (system->cli_end_update(cli)){
|
|
||||||
result = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal i32
|
|
||||||
update_cli_handle_with_file(System_Functions *system, Models *models, CLI_Handles *cli, Editing_File *file, char *dest, i32 max, b32 cursor_at_end){
|
|
||||||
i32 result = 0;
|
|
||||||
u32 amount = 0;
|
|
||||||
|
|
||||||
system->cli_begin_update(cli);
|
|
||||||
if (system->cli_update_step(cli, dest, max, &amount)){
|
|
||||||
amount = eol_in_place_convert_in(dest, amount);
|
|
||||||
output_file_append(system, models, file, make_string(dest, amount), cursor_at_end);
|
|
||||||
result = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (system->cli_end_update(cli)){
|
|
||||||
char str_space[256];
|
|
||||||
String str = make_fixed_width_string(str_space);
|
|
||||||
append_ss(&str, make_lit_string("exited with code "));
|
|
||||||
append_int_to_str(&str, cli->exit);
|
|
||||||
output_file_append(system, models, file, str, cursor_at_end);
|
|
||||||
result = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cursor_at_end){
|
|
||||||
i32 new_cursor = buffer_size(&file->state.buffer);
|
|
||||||
for (View_Iter iter = file_view_iter_init(&models->layout, file, 0);
|
|
||||||
file_view_iter_good(iter);
|
|
||||||
iter = file_view_iter_next(iter)){
|
|
||||||
view_cursor_move(system, iter.view, new_cursor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
App_Step_Sig(app_step){
|
App_Step_Sig(app_step){
|
||||||
PRFL_BEGIN_FRAME();
|
PRFL_BEGIN_FRAME();
|
||||||
|
|
||||||
|
@ -1595,30 +1529,48 @@ App_Step_Sig(app_step){
|
||||||
|
|
||||||
// NOTE(allen): update child processes
|
// NOTE(allen): update child processes
|
||||||
if (input->dt > 0){
|
if (input->dt > 0){
|
||||||
|
Partition *scratch = &models->mem.part;
|
||||||
|
|
||||||
|
CLI_List *list = &vars->cli_processes;
|
||||||
|
|
||||||
Temp_Memory temp = begin_temp_memory(&models->mem.part);
|
Temp_Memory temp = begin_temp_memory(&models->mem.part);
|
||||||
|
CLI_Process **procs_to_free = push_array(scratch, CLI_Process*, list->count);
|
||||||
|
u32 proc_free_count = 0;
|
||||||
|
|
||||||
u32 max = KB(128);
|
u32 max = KB(128);
|
||||||
char *dest = push_array(&models->mem.part, char, max);
|
char *dest = push_array(scratch, char, max);
|
||||||
|
|
||||||
i32 count = vars->cli_processes.count;
|
CLI_Process *proc_ptr = list->procs;
|
||||||
for (i32 i = 0; i < count; ++i){
|
for (u32 i = 0; i < list->count; ++i, ++proc_ptr){
|
||||||
CLI_Process *proc = vars->cli_processes.procs + i;
|
Editing_File *file = proc_ptr->out_file;
|
||||||
Editing_File *file = proc->out_file;
|
|
||||||
|
|
||||||
|
CLI_Handles *cli = &proc_ptr->cli;
|
||||||
|
|
||||||
|
u32 amount = 0;
|
||||||
|
system->cli_begin_update(cli);
|
||||||
|
if (system->cli_update_step(cli, dest, max, &amount)){
|
||||||
if (file != 0){
|
if (file != 0){
|
||||||
i32 r = update_cli_handle_with_file(
|
amount = eol_in_place_convert_in(dest, amount);
|
||||||
system, models, &proc->cli, file, dest, max, proc->cursor_at_end);
|
output_file_append(system, models, file, make_string(dest, amount), proc_ptr->cursor_at_end);
|
||||||
if (r < 0){
|
|
||||||
*proc = vars->cli_processes.procs[--count];
|
|
||||||
--i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
update_cli_handle_without_file(
|
|
||||||
system, models, &proc->cli, dest, max);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vars->cli_processes.count = count;
|
if (system->cli_end_update(cli)){
|
||||||
|
if (file != 0){
|
||||||
|
char str_space[256];
|
||||||
|
String str = make_fixed_width_string(str_space);
|
||||||
|
append(&str, make_lit_string("exited with code "));
|
||||||
|
append_int_to_str(&str, cli->exit);
|
||||||
|
output_file_append(system, models, file, str, proc_ptr->cursor_at_end);
|
||||||
|
}
|
||||||
|
procs_to_free[proc_free_count++] = proc_ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u32 i = 0; i < proc_free_count; ++i){
|
||||||
|
cli_list_free_proc(list, procs_to_free[i]);
|
||||||
|
}
|
||||||
|
|
||||||
end_temp_memory(temp);
|
end_temp_memory(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -216,10 +216,10 @@ DOC_SEE(Command_ID)
|
||||||
|
|
||||||
// TODO(allen): This is a bit of a mess and needs to be fixed.
|
// TODO(allen): This is a bit of a mess and needs to be fixed.
|
||||||
API_EXPORT bool32
|
API_EXPORT bool32
|
||||||
Exec_System_Command(Application_Links *app, View_Summary *view, Buffer_Identifier buffer, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags)
|
Exec_System_Command(Application_Links *app, View_Summary *view, Buffer_Identifier buffer_id, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags)
|
||||||
/*
|
/*
|
||||||
DOC_PARAM(view, If the view parameter is non-null it specifies a view to display the command's output buffer, otherwise the command will still work but if there is a buffer capturing the output it will not automatically be displayed.)
|
DOC_PARAM(view, If the view parameter is non-null it specifies a view to display the command's output buffer, otherwise the command will still work but if there is a buffer capturing the output it will not automatically be displayed.)
|
||||||
DOC_PARAM(buffer, The buffer the command will output to is specified by the buffer parameter. See Buffer_Identifier for information on how this type specifies a buffer. The command will cause a crash if no buffer is specified.)
|
DOC_PARAM(buffer_id, The buffer the command will output to is specified by the buffer parameter. See Buffer_Identifier for information on how this type specifies a buffer. The command will cause a crash if no buffer is specified.)
|
||||||
DOC_PARAM(path, The path parameter specifies the current working directory in which the command shall be executed. The string need not be null terminated.)
|
DOC_PARAM(path, The path parameter specifies the current working directory in which the command shall be executed. The string need not be null terminated.)
|
||||||
DOC_PARAM(path_len, The parameter path_len specifies the length of the path string.)
|
DOC_PARAM(path_len, The parameter path_len specifies the length of the path string.)
|
||||||
DOC_PARAM(command, The command parameter specifies the command that shall be executed. The string need not be null terminated.)
|
DOC_PARAM(command, The command parameter specifies the command that shall be executed. The string need not be null terminated.)
|
||||||
|
@ -239,63 +239,67 @@ DOC_SEE(Command_Line_Interface_Flag)
|
||||||
System_Functions *system = cmd->system;
|
System_Functions *system = cmd->system;
|
||||||
App_Vars *vars = cmd->vars;
|
App_Vars *vars = cmd->vars;
|
||||||
Models *models = cmd->models;
|
Models *models = cmd->models;
|
||||||
|
Partition *part = &models->mem.part;
|
||||||
|
General_Memory *general = &models->mem.general;
|
||||||
|
Working_Set *working_set = &models->working_set;
|
||||||
|
|
||||||
|
bool32 result = true;
|
||||||
char feedback_space[256];
|
char feedback_space[256];
|
||||||
String feedback_str = make_fixed_width_string(feedback_space);
|
String feedback_str = make_fixed_width_string(feedback_space);
|
||||||
|
|
||||||
Working_Set *working_set = &models->working_set;
|
|
||||||
CLI_Process *procs = vars->cli_processes.procs, *proc = 0;
|
|
||||||
Editing_File *file = 0;
|
|
||||||
b32 bind_to_new_view = true;
|
|
||||||
General_Memory *general = &models->mem.general;
|
|
||||||
|
|
||||||
Partition *part = &models->mem.part;
|
|
||||||
Temp_Memory temp = begin_temp_memory(part);
|
Temp_Memory temp = begin_temp_memory(part);
|
||||||
|
|
||||||
bool32 result = true;
|
{
|
||||||
|
// NOTE(allen): Check that it is possible to store a new child process.
|
||||||
|
if (!cli_list_has_space(&vars->cli_processes)){
|
||||||
|
append(&feedback_str, make_lit_string("ERROR: no available process slot\n"));
|
||||||
|
result = false;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
View *vptr = imp_get_view(cmd, view);
|
// NOTE(allen): Try to get the buffer that was specified if it exists.
|
||||||
|
Editing_File *file = get_file_from_identifier(system, working_set, buffer_id);
|
||||||
|
|
||||||
if (vars->cli_processes.count < vars->cli_processes.max){
|
// NOTE(allen): If the file exists check that it is legal.
|
||||||
file = get_file_from_identifier(system, working_set, buffer);
|
if (file != 0){
|
||||||
|
|
||||||
if (file){
|
|
||||||
if (file->settings.read_only == 0){
|
if (file->settings.read_only == 0){
|
||||||
append_ss(&feedback_str, make_lit_string("ERROR: "));
|
append(&feedback_str, make_lit_string("ERROR: "));
|
||||||
append_ss(&feedback_str, file->name.live_name);
|
append(&feedback_str, file->name.live_name);
|
||||||
append_ss(&feedback_str, make_lit_string(" is not a read-only buffer\n"));
|
append(&feedback_str, make_lit_string(" is not a read-only buffer\n"));
|
||||||
do_feedback_message(system, models, feedback_str);
|
|
||||||
result = false;
|
result = false;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (file->settings.never_kill){
|
if (file->settings.never_kill){
|
||||||
append_ss(&feedback_str, make_lit_string("The buffer "));
|
append(&feedback_str, make_lit_string("ERROR: The buffer "));
|
||||||
append_ss(&feedback_str, file->name.live_name);
|
append(&feedback_str, file->name.live_name);
|
||||||
append_ss(&feedback_str, make_lit_string(" is not killable"));
|
append(&feedback_str, make_lit_string(" is not killable"));
|
||||||
do_feedback_message(system, models, feedback_str);
|
|
||||||
result = false;
|
result = false;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (buffer.name){
|
|
||||||
|
// NOTE(allen): If the buffer is specified by name but does not already exist, then create it.
|
||||||
|
if (file == 0 && buffer_id.name){
|
||||||
file = working_set_alloc_always(working_set, general);
|
file = working_set_alloc_always(working_set, general);
|
||||||
if (file == 0){
|
if (file == 0){
|
||||||
append_ss(&feedback_str, make_lit_string("ERROR: unable to allocate a new buffer\n"));
|
append(&feedback_str, make_lit_string("ERROR: unable to allocate a new buffer\n"));
|
||||||
do_feedback_message(system, models, feedback_str);
|
|
||||||
result = false;
|
result = false;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
String name = make_string_terminated(part, buffer.name, buffer.name_len);
|
|
||||||
|
String name = make_string_terminated(part, buffer_id.name, buffer_id.name_len);
|
||||||
buffer_bind_name(general, working_set, file, name);
|
buffer_bind_name(general, working_set, file, name);
|
||||||
init_read_only_file(system, models, file);
|
init_read_only_file(system, models, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE(allen): If there are conflicts in output buffer with an existing child process resolve it.
|
||||||
if (file != 0){
|
if (file != 0){
|
||||||
i32 proc_count = vars->cli_processes.count;
|
CLI_List *list = &vars->cli_processes;
|
||||||
for (i32 i = 0; i < proc_count; ++i){
|
CLI_Process *proc_ptr = list->procs;
|
||||||
if (procs[i].out_file == file){
|
for (u32 i = 0; i < list->count; ++i, ++proc_ptr){
|
||||||
|
if (proc_ptr->out_file == file){
|
||||||
if (flags & CLI_OverlapWithConflict){
|
if (flags & CLI_OverlapWithConflict){
|
||||||
procs[i].out_file = 0;
|
proc_ptr->out_file = 0;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
file = 0;
|
file = 0;
|
||||||
|
@ -304,30 +308,41 @@ DOC_SEE(Command_Line_Interface_Flag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file){
|
if (file == 0){
|
||||||
|
append(&feedback_str, "did not begin command-line command because the target buffer is already in use\n");
|
||||||
|
result = false;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(allen): If we have an output file, prepare it for child proc output.
|
||||||
|
if (file != 0){
|
||||||
file_clear(system, models, file);
|
file_clear(system, models, file);
|
||||||
file->settings.unimportant = true;
|
file->settings.unimportant = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(allen): If we have an output file and we need to bring it up in a new view, do so.
|
||||||
|
if (file != 0){
|
||||||
|
b32 bind_to_new_view = true;
|
||||||
if (!(flags & CLI_AlwaysBindToView)){
|
if (!(flags & CLI_AlwaysBindToView)){
|
||||||
View_Iter iter = file_view_iter_init(&models->layout, file, 0);
|
View_Iter 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 = false;
|
bind_to_new_view = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bind_to_new_view){
|
||||||
|
View *vptr = imp_get_view(cmd, view);
|
||||||
|
if (vptr != 0){
|
||||||
|
view_set_file(system, vptr, file, models);
|
||||||
|
view_show_file(vptr);
|
||||||
}
|
}
|
||||||
else{
|
|
||||||
#define MSG "did not begin command-line command because the target buffer is already in use\n"
|
|
||||||
String msg = make_lit_string(MSG);
|
|
||||||
#undef MSG
|
|
||||||
append_ss(&feedback_str, msg);
|
|
||||||
do_feedback_message(system, models, feedback_str);
|
|
||||||
result = false;
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE(allen): Figure out the root path for the command.
|
||||||
String path_string = {0};
|
String path_string = {0};
|
||||||
if (!path){
|
if (path == 0){
|
||||||
terminate_with_null(&models->hot_directory.string);
|
terminate_with_null(&models->hot_directory.string);
|
||||||
path_string = models->hot_directory.string;
|
path_string = models->hot_directory.string;
|
||||||
}
|
}
|
||||||
|
@ -335,46 +350,27 @@ DOC_SEE(Command_Line_Interface_Flag)
|
||||||
path_string = make_string_terminated(part, path, path_len);
|
path_string = make_string_terminated(part, path, path_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
// NOTE(allen): Figure out the command string.
|
||||||
String command_string = {0};
|
String command_string = {0};
|
||||||
|
if (command == 0){
|
||||||
if (!command){
|
command_string = make_lit_string(" echo no script specified");
|
||||||
#define NO_SCRIPT " echo no script specified"
|
|
||||||
command_string.str = NO_SCRIPT;
|
|
||||||
command_string.size = sizeof(NO_SCRIPT)-1;
|
|
||||||
#undef NO_SCRIPT
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
command_string = make_string_terminated(part, command, command_len);
|
command_string = make_string_terminated(part, command, command_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vptr != 0 && bind_to_new_view){
|
// NOTE(allen): Attept to execute the command.
|
||||||
view_set_file(system, vptr, file, models);
|
if (!cli_list_call(system, &vars->cli_processes, path_string.str, command_string.str, file, ((flags & CLI_CursorAtEnd) != 0))){
|
||||||
view_show_file(vptr);
|
append(&feedback_str, "ERROR: Failed to make the cli call\n");
|
||||||
}
|
|
||||||
|
|
||||||
proc = procs + vars->cli_processes.count++;
|
|
||||||
proc->out_file = file;
|
|
||||||
if (flags & CLI_CursorAtEnd){
|
|
||||||
proc->cursor_at_end = 1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
proc->cursor_at_end = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!system->cli_call(path_string.str, command_string.str, &proc->cli)){
|
|
||||||
--vars->cli_processes.count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
append_ss(&feedback_str, make_lit_string("ERROR: no available process slot\n"));
|
|
||||||
do_feedback_message(system, models, feedback_str);
|
|
||||||
result = false;
|
result = false;
|
||||||
goto done;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done:;
|
done:;
|
||||||
|
if (!result){
|
||||||
|
do_feedback_message(system, models, feedback_str);
|
||||||
|
}
|
||||||
|
|
||||||
end_temp_memory(temp);
|
end_temp_memory(temp);
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,8 @@
|
||||||
#include "4ed_hot_directory.cpp"
|
#include "4ed_hot_directory.cpp"
|
||||||
#include "4ed_parse_contexts.cpp"
|
#include "4ed_parse_contexts.cpp"
|
||||||
|
|
||||||
|
#include "4ed_cli.cpp"
|
||||||
|
|
||||||
#include "4ed_gui.h"
|
#include "4ed_gui.h"
|
||||||
#include "4ed_gui.cpp"
|
#include "4ed_gui.cpp"
|
||||||
#include "4ed_layout.cpp"
|
#include "4ed_layout.cpp"
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Mr. 4th Dimention - Allen Webster
|
||||||
|
*
|
||||||
|
* 17.07.2017
|
||||||
|
*
|
||||||
|
* CLI handling code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TOP
|
||||||
|
|
||||||
|
#if !defined(FRED_CLI_CPP)
|
||||||
|
#define FRED_CLI_CPP
|
||||||
|
|
||||||
|
struct CLI_Process{
|
||||||
|
CLI_Handles cli;
|
||||||
|
Editing_File *out_file;
|
||||||
|
b32 cursor_at_end;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CLI_List{
|
||||||
|
CLI_Process *procs;
|
||||||
|
u32 count;
|
||||||
|
u32 max;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline CLI_List
|
||||||
|
make_cli_list(Partition *part, u32 max){
|
||||||
|
CLI_List list = {0};
|
||||||
|
partition_align(part, 8);
|
||||||
|
list.procs = push_array(part, CLI_Process, max);
|
||||||
|
list.max = max;
|
||||||
|
return(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline b32
|
||||||
|
cli_list_call(System_Functions *system, CLI_List *list, char *path, char *command, Editing_File *file, b32 cursor_at_end){
|
||||||
|
b32 result = false;
|
||||||
|
|
||||||
|
if (list->count < list->max){
|
||||||
|
CLI_Process *proc = &list->procs[list->count++];
|
||||||
|
proc->out_file = file;
|
||||||
|
proc->cursor_at_end = cursor_at_end;
|
||||||
|
result = system->cli_call(path, command, &proc->cli);
|
||||||
|
if (!result){
|
||||||
|
--list->count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
cli_list_free_proc(CLI_List *list, CLI_Process *proc){
|
||||||
|
Assert(proc >= list->procs);
|
||||||
|
Assert(proc < list->procs + list->count);
|
||||||
|
*proc = list->procs[--list->count];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline b32
|
||||||
|
cli_list_has_space(CLI_List *list){
|
||||||
|
b32 has_space = (list->count < list->max);
|
||||||
|
return(has_space);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// BOTTOM
|
||||||
|
|
Loading…
Reference in New Issue