4coder/custom/4coder_lists.cpp

782 lines
30 KiB
C++
Raw Normal View History

/*
4coder_lists.cpp - List helpers and list commands
such as open file, switch buffer, or kill buffer.
*/
// TOP
2019-10-14 05:27:57 +00:00
function void
lister__write_string__default(Application_Links *app){
2019-06-19 02:31:59 +00:00
View_ID view = get_active_view(app, AccessAll);
2019-10-14 05:27:57 +00:00
Lister *lister = view_get_lister(view);
if (lister != 0){
2019-10-14 22:57:47 +00:00
User_Input in = get_current_input(app);
String_Const_u8 string = to_writable(&in);
if (string.str != 0 && string.size > 0){
2019-10-14 05:27:57 +00:00
lister_append_text_field(lister, string);
lister_append_key(lister, string);
2019-10-14 22:57:47 +00:00
lister->item_index = 0;
view_zero_scroll(app, view);
2019-10-14 05:27:57 +00:00
lister_update_filtered_list(app, view, lister);
}
}
}
2019-10-14 05:27:57 +00:00
function void
lister__backspace_text_field__default(Application_Links *app){
2019-06-19 02:31:59 +00:00
View_ID view = get_active_view(app, AccessAll);
2019-10-14 05:27:57 +00:00
Lister *lister = view_get_lister(view);
if (lister != 0){
2019-10-14 22:57:47 +00:00
lister->text_field.string = backspace_utf8(lister->text_field.string);
lister->key_string.string = backspace_utf8(lister->key_string.string);
lister->item_index = 0;
view_zero_scroll(app, view);
2019-10-14 05:27:57 +00:00
lister_update_filtered_list(app, view, lister);
}
}
2019-10-14 05:27:57 +00:00
function void
lister__move_up__default(Application_Links *app){
2019-06-19 02:31:59 +00:00
View_ID view = get_active_view(app, AccessAll);
2019-10-14 05:27:57 +00:00
Lister *lister = view_get_lister(view);
if (lister != 0){
2019-10-14 22:57:47 +00:00
lister->item_index = lister->item_index - 1;
if (lister->item_index < 0){
lister->item_index = lister->filtered.count - 1;
}
2019-10-14 22:57:47 +00:00
lister->set_view_vertical_focus_to_item = true;
2019-10-14 05:27:57 +00:00
lister_update_filtered_list(app, view, lister);
}
}
2019-10-14 05:27:57 +00:00
function void
lister__move_down__default(Application_Links *app){
2019-06-19 02:31:59 +00:00
View_ID view = get_active_view(app, AccessAll);
2019-10-14 05:27:57 +00:00
Lister *lister = view_get_lister(view);
if (lister != 0){
2019-10-14 22:57:47 +00:00
lister->item_index = lister->item_index + 1;
if (lister->item_index > lister->filtered.count - 1){
lister->item_index = 0;
}
2019-10-14 22:57:47 +00:00
lister->set_view_vertical_focus_to_item = true;
2019-10-14 05:27:57 +00:00
lister_update_filtered_list(app, view, lister);
}
}
2019-10-14 05:27:57 +00:00
function void
lister__write_character__file_path(Application_Links *app){
2019-06-19 02:31:59 +00:00
View_ID view = get_active_view(app, AccessAll);
2019-10-14 05:27:57 +00:00
Lister *lister = view_get_lister(view);
if (lister != 0){
2019-10-14 22:57:47 +00:00
User_Input in = get_current_input(app);
String_Const_u8 string = to_writable(&in);
if (string.str != 0 && string.size > 0){
2019-10-14 05:27:57 +00:00
lister_append_text_field(lister, string);
2019-10-14 22:57:47 +00:00
String_Const_u8 front_name = string_front_of_path(lister->text_field.string);
2019-10-14 05:27:57 +00:00
lister_set_key(lister, front_name);
if (character_is_slash(string.str[0])){
2019-10-14 22:57:47 +00:00
String_Const_u8 new_hot = lister->text_field.string;
2019-06-01 23:58:28 +00:00
set_hot_directory(app, new_hot);
2019-10-14 05:27:57 +00:00
lister_call_refresh_handler(app, view, lister);
}
2019-10-14 22:57:47 +00:00
lister->item_index = 0;
view_zero_scroll(app, view);
2019-10-14 05:27:57 +00:00
lister_update_filtered_list(app, view, lister);
}
}
}
2019-10-14 05:27:57 +00:00
function void
lister__backspace_text_field__file_path(Application_Links *app){
2019-06-19 02:31:59 +00:00
View_ID view = get_active_view(app, AccessAll);
2019-10-14 05:27:57 +00:00
Lister *lister = view_get_lister(view);
if (lister != 0){
2019-10-14 22:57:47 +00:00
if (lister->text_field.size > 0){
char last_char = lister->text_field.str[lister->text_field.size - 1];
lister->text_field.string = backspace_utf8(lister->text_field.string);
if (character_is_slash(last_char)){
2019-10-14 22:57:47 +00:00
User_Input input = get_current_input(app);
String_Const_u8 text_field = lister->text_field.string;
2019-06-01 23:58:28 +00:00
String_Const_u8 new_hot = string_remove_last_folder(text_field);
2019-10-11 21:24:03 +00:00
b32 is_modified = has_modifier(&input, KeyCode_Control);
b32 whole_word_backspace = (is_modified == global_config.lister_whole_word_backspace_when_modified);
2019-02-27 21:14:25 +00:00
if (whole_word_backspace){
2019-10-14 22:57:47 +00:00
lister->text_field.size = new_hot.size;
}
2019-06-01 23:58:28 +00:00
set_hot_directory(app, new_hot);
2019-02-27 21:14:25 +00:00
// TODO(allen): We have to protect against lister_call_refresh_handler changing
// the text_field here. Clean this up.
2019-10-14 22:57:47 +00:00
String_u8 dingus = lister->text_field;
2019-10-14 05:27:57 +00:00
lister_call_refresh_handler(app, view, lister);
2019-10-14 22:57:47 +00:00
lister->text_field = dingus;
}
else{
2019-10-14 22:57:47 +00:00
String_Const_u8 text_field = lister->text_field.string;
2019-06-01 23:58:28 +00:00
String_Const_u8 new_key = string_front_of_path(text_field);
2019-10-14 05:27:57 +00:00
lister_set_key(lister, new_key);
}
2019-10-14 22:57:47 +00:00
lister->item_index = 0;
view_zero_scroll(app, view);
2019-10-14 05:27:57 +00:00
lister_update_filtered_list(app, view, lister);
}
}
}
2019-10-13 21:45:41 +00:00
function Lister_Activation_Code
2019-10-14 05:27:57 +00:00
lister__key_stroke__fixed_list(Application_Links *app){
2019-10-13 21:45:41 +00:00
Lister_Activation_Code result = ListerActivation_Continue;
2019-06-19 02:31:59 +00:00
View_ID view = get_active_view(app, AccessAll);
2019-10-14 05:27:57 +00:00
Lister *lister = view_get_lister(view);
if (lister != 0){
2019-10-14 22:57:47 +00:00
User_Input in = get_current_input(app);
2019-10-13 21:45:41 +00:00
if (in.event.kind == InputEventKind_KeyStroke){
2018-08-05 07:09:18 +00:00
void *user_data = 0;
b32 did_shortcut_key = false;
2019-10-14 22:57:47 +00:00
for (Lister_Node *node = lister->options.first;
2018-08-05 07:09:18 +00:00
node != 0;
node = node->next){
2019-10-13 21:45:41 +00:00
Key_Code *key_code = (Key_Code*)(node + 1);
if (*key_code == in.event.key.code){
2018-08-05 07:09:18 +00:00
user_data = node->user_data;
did_shortcut_key = true;
break;
}
}
if (did_shortcut_key){
2019-10-14 05:27:57 +00:00
result = lister_call_activate_handler(app, view, lister, user_data, false);
2018-08-05 07:09:18 +00:00
}
}
}
2019-10-13 21:45:41 +00:00
return(result);
}
////////////////////////////////
2019-10-14 05:27:57 +00:00
function Lister_Handlers
2018-08-05 07:09:18 +00:00
lister_get_default_handlers(void){
Lister_Handlers handlers = {};
handlers.write_character = lister__write_string__default;
2018-08-05 07:09:18 +00:00
handlers.backspace = lister__backspace_text_field__default;
handlers.navigate_up = lister__move_up__default;
handlers.navigate_down = lister__move_down__default;
return(handlers);
}
2019-10-14 05:27:57 +00:00
function Lister_Handlers
2018-08-05 07:09:18 +00:00
lister_get_fixed_list_handlers(void){
Lister_Handlers handlers = {};
2018-08-05 07:09:18 +00:00
handlers.navigate_up = lister__move_up__default;
handlers.navigate_down = lister__move_down__default;
2019-10-13 21:45:41 +00:00
handlers.key_stroke = lister__key_stroke__fixed_list;
2018-08-05 07:09:18 +00:00
return(handlers);
}
2019-10-14 05:27:57 +00:00
function void
run_lister_with_refresh_handler(Application_Links *app, char *query_string,
Lister_Handlers handlers,
void *user_data, i32 user_data_size,
View_ID view){
2018-08-05 07:09:18 +00:00
if (handlers.refresh != 0){
2019-10-14 05:27:57 +00:00
Scratch_Block scratch(app);
Lister *lister = begin_lister(app, scratch, view, user_data, user_data_size);
2019-10-14 22:57:47 +00:00
lister_set_map(lister, &framework_mapping, mapid_global);
2019-10-14 05:27:57 +00:00
lister_set_query(lister, query_string);
2019-10-14 22:57:47 +00:00
lister->handlers = handlers;
2019-10-14 05:27:57 +00:00
handlers.refresh(app, lister);
lister_run(app, view, lister);
}
2018-08-05 07:09:18 +00:00
else{
2019-06-01 23:58:28 +00:00
Scratch_Block scratch(app);
List_String_Const_u8 list = {};
string_list_push(scratch, &list, string_u8_litexpr("ERROR: No refresh handler specified for lister (query_string = \""));
string_list_push(scratch, &list, SCu8(query_string));
string_list_push(scratch, &list, string_u8_litexpr("\")\n"));
String_Const_u8 str = string_list_flatten(scratch, list);
print_message(app, str);
}
}
2019-10-14 05:27:57 +00:00
global_const i32 default_string_size_estimation = 0;
2019-10-14 05:27:57 +00:00
function i32
lister__get_arena_size_(i32 option_count, i32 user_data_size,
i32 estimated_string_space_size){
i32 arena_size = (user_data_size + 7 + option_count*sizeof(Lister_Node) + estimated_string_space_size);
return(arena_size);
}
2019-10-14 05:27:57 +00:00
function void
run_lister_with_options_array(Application_Links *app, char *query_string,
Lister_Activation_Type *activate,
void *user_data, i32 user_data_size,
Lister_Option *options, i32 option_count,
i32 estimated_string_space_size,
View_ID view){
Scratch_Block scratch(app);
Lister *lister = begin_lister(app, scratch, view, user_data, user_data_size);
2019-10-14 22:57:47 +00:00
lister_set_map(lister, &framework_mapping, mapid_global);
for (i32 i = 0; i < option_count; i += 1){
2019-10-14 05:27:57 +00:00
lister_add_item(lister, options[i].string, options[i].status, options[i].user_data, 0);
}
2019-10-14 05:27:57 +00:00
lister_set_query(lister, query_string);
2019-10-14 22:57:47 +00:00
lister->handlers = lister_get_default_handlers();
lister->handlers.activate = activate;
2019-10-14 05:27:57 +00:00
lister_run(app, view, lister);
}
function void
run_lister_with_fixed_options(Application_Links *app, char *query_string,
Lister_Handlers handlers,
void *user_data, i32 user_data_size,
Lister_Fixed_Option *options, i32 option_count,
i32 estimated_string_space_size,
View_ID view){
Scratch_Block scratch(app);
Lister *lister = begin_lister(app, scratch, view, user_data, user_data_size);
2019-10-14 22:57:47 +00:00
lister_set_map(lister, &framework_mapping, mapid_global);
for (i32 i = 0; i < option_count; i += 1){
2019-10-13 21:45:41 +00:00
Key_Code code = options[i].key_code;
2019-10-14 05:27:57 +00:00
void *extra = lister_add_item(lister, SCu8(options[i].string), SCu8(options[i].status),
options[i].user_data, sizeof(code));
2019-10-13 21:45:41 +00:00
block_copy(extra, &code, sizeof(code));
}
2019-10-14 05:27:57 +00:00
lister_set_query(lister, query_string);
2019-10-14 22:57:47 +00:00
lister->handlers = handlers;
lister->handlers.refresh = 0;
2019-10-14 05:27:57 +00:00
lister_run(app, view, lister);
}
function void
run_lister_with_fixed_options(Application_Links *app, char *query_string,
Lister_Activation_Type *activate,
void *user_data, i32 user_data_size,
Lister_Fixed_Option *options, i32 option_count,
i32 estimated_string_space_size,
View_ID view){
2018-08-05 07:09:18 +00:00
Lister_Handlers handlers = lister_get_fixed_list_handlers();
handlers.activate = activate;
2019-10-14 05:27:57 +00:00
run_lister_with_fixed_options(app, query_string,
handlers, user_data, user_data_size,
options, option_count,
estimated_string_space_size,
view);
2018-08-10 21:52:57 +00:00
}
////////////////////////////////
2019-10-14 05:27:57 +00:00
function void
generate_all_buffers_list__output_buffer(Application_Links *app, Lister *lister, Buffer_ID buffer){
2019-06-19 02:31:59 +00:00
Dirty_State dirty = buffer_get_dirty_state(app, buffer);
2019-06-01 23:58:28 +00:00
String_Const_u8 status = {};
switch (dirty){
2019-06-01 23:58:28 +00:00
case DirtyState_UnsavedChanges: status = string_u8_litexpr("*"); break;
case DirtyState_UnloadedChanges: status = string_u8_litexpr("!"); break;
case DirtyState_UnsavedChangesAndUnloadedChanges: status = string_u8_litexpr("*!"); break;
}
Scratch_Block scratch(app);
String_Const_u8 buffer_name = push_buffer_unique_name(app, scratch, buffer);
lister_add_item(lister, buffer_name, status, IntAsPtr(buffer), 0);
}
2019-10-14 05:27:57 +00:00
function void
generate_all_buffers_list(Application_Links *app, Lister *lister){
2019-06-01 23:58:28 +00:00
lister_begin_new_item_set(app, lister);
Buffer_ID buffers_currently_being_viewed[16];
i32 currently_viewed_buffer_count = 0;
// List currently viewed buffers
{
2019-06-19 02:31:59 +00:00
for (View_ID view = get_view_next(app, 0, AccessAll);
view != 0;
2019-06-19 02:31:59 +00:00
view = get_view_next(app, view, AccessAll)){
Buffer_ID new_buffer_id = view_get_buffer(app, view, AccessAll);
for (i32 i = 0; i < currently_viewed_buffer_count; i += 1){
if (new_buffer_id == buffers_currently_being_viewed[i]){
goto skip0;
}
}
buffers_currently_being_viewed[currently_viewed_buffer_count++] = new_buffer_id;
skip0:;
}
}
// Regular Buffers
{
2019-06-19 02:31:59 +00:00
for (Buffer_ID buffer = get_buffer_next(app, 0, AccessAll);
buffer != 0;
2019-06-19 02:31:59 +00:00
buffer = get_buffer_next(app, buffer, AccessAll)){
for (i32 i = 0; i < currently_viewed_buffer_count; i += 1){
if (buffer == buffers_currently_being_viewed[i]){
goto skip1;
}
}
if (!buffer_has_name_with_star(app, buffer)){
generate_all_buffers_list__output_buffer(app, lister, buffer);
}
skip1:;
}
}
// Buffers Starting with *
{
2019-06-19 02:31:59 +00:00
for (Buffer_ID buffer = get_buffer_next(app, 0, AccessAll);
buffer != 0;
2019-06-19 02:31:59 +00:00
buffer = get_buffer_next(app, buffer, AccessAll)){
for (i32 i = 0; i < currently_viewed_buffer_count; i += 1){
if (buffer == buffers_currently_being_viewed[i]){
goto skip2;
}
}
if (buffer_has_name_with_star(app, buffer)){
generate_all_buffers_list__output_buffer(app, lister, buffer);
}
skip2:;
}
}
// Buffers That Are Open in Views
for (i32 i = 0; i < currently_viewed_buffer_count; i += 1){
generate_all_buffers_list__output_buffer(app, lister, buffers_currently_being_viewed[i]);
}
}
2019-10-14 05:27:57 +00:00
function void
generate_hot_directory_file_list(Application_Links *app, Lister *lister){
2019-08-04 00:49:40 +00:00
Scratch_Block scratch(app);
Temp_Memory temp = begin_temp(lister->arena);
String_Const_u8 hot = push_hot_directory(app, lister->arena);
2019-06-01 23:58:28 +00:00
if (!character_is_slash(string_get_character(hot, hot.size - 1))){
hot = push_u8_stringf(lister->arena, "%.*s/", string_expand(hot));
}
2019-06-01 23:58:28 +00:00
lister_set_text_field(lister, hot);
lister_set_key(lister, string_front_of_path(hot));
File_List file_list = system_get_file_list(scratch, hot);
2019-06-01 23:58:28 +00:00
end_temp(temp);
2019-08-04 00:49:40 +00:00
File_Info **one_past_last = file_list.infos + file_list.count;
2019-06-01 23:58:28 +00:00
lister_begin_new_item_set(app, lister);
hot = push_hot_directory(app, lister->arena);
push_align(lister->arena, 8);
if (hot.str != 0){
2019-06-01 23:58:28 +00:00
String_Const_u8 empty_string = string_u8_litexpr("");
Lister_Prealloced_String empty_string_prealloced = lister_prealloced(empty_string);
2019-08-04 00:49:40 +00:00
for (File_Info **info = file_list.infos;
info < one_past_last;
info += 1){
2019-08-04 00:49:40 +00:00
if (!HasFlag((**info).attributes.flags, FileAttribute_IsDirectory)) continue;
String_Const_u8 file_name = push_u8_stringf(lister->arena, "%.*s/",
2019-08-04 00:49:40 +00:00
string_expand((**info).file_name));
lister_add_item(lister, lister_prealloced(file_name), empty_string_prealloced, file_name.str, 0);
}
2019-08-04 00:49:40 +00:00
for (File_Info **info = file_list.infos;
info < one_past_last;
info += 1){
2019-08-04 00:49:40 +00:00
if (HasFlag((**info).attributes.flags, FileAttribute_IsDirectory)) continue;
String_Const_u8 file_name = push_string_copy(lister->arena, (**info).file_name);
char *is_loaded = "";
char *status_flag = "";
Buffer_ID buffer = {};
{
Temp_Memory path_temp = begin_temp(lister->arena);
2019-06-01 23:58:28 +00:00
List_String_Const_u8 list = {};
string_list_push(lister->arena, &list, hot);
string_list_push_overlap(lister->arena, &list, '/', (**info).file_name);
String_Const_u8 full_file_path = string_list_flatten(lister->arena, list);
2019-06-19 02:31:59 +00:00
buffer = get_buffer_by_file_name(app, full_file_path, AccessAll);
2019-06-01 23:58:28 +00:00
end_temp(path_temp);
}
if (buffer != 0){
is_loaded = "LOADED";
2019-06-19 02:31:59 +00:00
Dirty_State dirty = buffer_get_dirty_state(app, buffer);
switch (dirty){
case DirtyState_UnsavedChanges: status_flag = " *"; break;
case DirtyState_UnloadedChanges: status_flag = " !"; break;
2019-02-25 23:49:16 +00:00
case DirtyState_UnsavedChangesAndUnloadedChanges: status_flag = " *!"; break;
}
}
String_Const_u8 status = push_u8_stringf(lister->arena, "%s%s", is_loaded, status_flag);
lister_add_item(lister, lister_prealloced(file_name), lister_prealloced(status), file_name.str, 0);
}
}
}
2019-10-14 05:27:57 +00:00
function void
run_lister_buffer_list(Application_Links *app, char *query_string, Lister_Activation_Type *activate_procedure,
void *user_data, i32 user_data_size, View_ID target_view){
2018-08-05 07:09:18 +00:00
Lister_Handlers handlers = lister_get_default_handlers();
handlers.activate = activate_procedure;
handlers.refresh = generate_all_buffers_list;
2019-10-14 05:27:57 +00:00
run_lister_with_refresh_handler(app, query_string, handlers, user_data, user_data_size, target_view);
2018-08-05 07:09:18 +00:00
}
2019-10-14 05:27:57 +00:00
function void
run_lister_file_system_list(Application_Links *app, char *query_string, Lister_Activation_Type *activate_procedure,
void *user_data, i32 user_data_size, View_ID target_view){
2018-08-05 07:09:18 +00:00
Lister_Handlers handlers = lister_get_default_handlers();
handlers.activate = activate_procedure;
handlers.refresh = generate_hot_directory_file_list;
handlers.write_character = lister__write_character__file_path;
handlers.backspace = lister__backspace_text_field__file_path;
2019-10-14 05:27:57 +00:00
run_lister_with_refresh_handler(app, query_string, handlers, user_data, user_data_size, target_view);
2018-08-05 07:09:18 +00:00
}
////////////////////////////////
enum{
SureToKill_NULL = 0,
SureToKill_No = 1,
SureToKill_Yes = 2,
SureToKill_Save = 3,
};
2019-10-14 22:57:47 +00:00
struct Confirm_Kill_Data{
Buffer_ID id;
b32 do_kill;
};
2019-10-14 05:27:57 +00:00
function Lister_Activation_Code
activate_confirm_kill(Application_Links *app, View_ID view, Lister *lister,
String_Const_u8 text_field, void *user_data, b32 clicked){
i32 behavior = (i32)PtrAsInt(user_data);
2019-10-14 22:57:47 +00:00
Confirm_Kill_Data *data = (Confirm_Kill_Data*)(lister->user_data);
2018-08-05 07:09:18 +00:00
switch (behavior){
case SureToKill_No:
{}break;
case SureToKill_Yes:
{
2019-10-14 22:57:47 +00:00
data->do_kill = true;
2018-08-05 07:09:18 +00:00
}break;
case SureToKill_Save:
{
Scratch_Block scratch(app);
2019-10-14 22:57:47 +00:00
String_Const_u8 file_name = push_buffer_file_name(app, scratch, data->id);
if (buffer_save(app, data->id, file_name, BufferSave_IgnoreDirtyFlag)){
data->do_kill = true;
2018-08-05 07:09:18 +00:00
}
else{
2019-06-18 22:56:09 +00:00
String_Const_u8 str = push_u8_stringf(scratch, "Did not close '%.*s' because it did not successfully save.",
2019-06-01 23:58:28 +00:00
string_expand(file_name));
print_message(app, str);
2018-08-05 07:09:18 +00:00
}
}break;
}
2019-10-14 05:27:57 +00:00
lister_default(app, view, lister, ListerActivation_Finished);
2019-10-13 21:45:41 +00:00
return(ListerActivation_Finished);
2018-08-05 07:09:18 +00:00
}
2019-10-14 22:57:47 +00:00
function b32
do_gui_sure_to_kill(Application_Links *app, Buffer_ID buffer, View_ID view){
2018-08-05 07:09:18 +00:00
Lister_Fixed_Option options[] = {
2019-10-13 21:45:41 +00:00
{"(N)o" , "", KeyCode_N, IntAsPtr(SureToKill_No) },
{"(Y)es" , "", KeyCode_Y, IntAsPtr(SureToKill_Yes) },
{"(S)ave and Kill", "", KeyCode_S, IntAsPtr(SureToKill_Save)},
2018-08-05 07:09:18 +00:00
};
i32 option_count = sizeof(options)/sizeof(options[0]);
2019-10-14 22:57:47 +00:00
Confirm_Kill_Data data = {};
data.id = buffer;
2019-10-14 05:27:57 +00:00
run_lister_with_fixed_options(app, "There are unsaved changes, close anyway?",
2019-10-14 22:57:47 +00:00
activate_confirm_kill, &data, sizeof(data),
2019-10-14 05:27:57 +00:00
options, option_count, default_string_size_estimation,
view);
2019-10-14 22:57:47 +00:00
return(data.do_kill);
2018-08-05 07:09:18 +00:00
}
2019-10-14 05:27:57 +00:00
function Lister_Activation_Code
activate_confirm_close_4coder(Application_Links *app,
View_ID view, Lister *lister,
2019-06-01 23:58:28 +00:00
String_Const_u8 text_field, void *user_data, b32 clicked){
i32 behavior = (i32)PtrAsInt(user_data);
2019-10-14 22:57:47 +00:00
b32 *do_exit = (b32*)user_data;
2018-08-05 07:09:18 +00:00
switch (behavior){
case SureToKill_No:
{}break;
case SureToKill_Yes:
{
allow_immediate_close_without_checking_for_changes = true;
2019-10-14 22:57:47 +00:00
*do_exit = true;
2018-08-05 07:09:18 +00:00
}break;
case SureToKill_Save:
{
save_all_dirty_buffers(app);
allow_immediate_close_without_checking_for_changes = true;
2019-10-14 22:57:47 +00:00
*do_exit = true;
2018-08-05 07:09:18 +00:00
}break;
}
2019-10-14 05:27:57 +00:00
lister_default(app, view, lister, ListerActivation_Finished);
2019-10-13 21:45:41 +00:00
return(ListerActivation_Finished);
2018-08-05 07:09:18 +00:00
}
2019-10-14 22:57:47 +00:00
function b32
do_gui_sure_to_close_4coder(Application_Links *app, View_ID view){
2018-08-05 07:09:18 +00:00
Lister_Fixed_Option options[] = {
2019-10-13 21:45:41 +00:00
{"(N)o" , "", KeyCode_N, (void*)SureToKill_No },
{"(Y)es" , "", KeyCode_Y, (void*)SureToKill_Yes },
{"(S)ave All and Close", "", KeyCode_S, (void*)SureToKill_Save},
2018-08-05 07:09:18 +00:00
};
i32 option_count = sizeof(options)/sizeof(options[0]);
2019-10-14 22:57:47 +00:00
b32 do_exit = false;
2019-10-14 05:27:57 +00:00
run_lister_with_fixed_options(app, "There are one or more buffers with unsave changes, close anyway?",
2019-10-14 22:57:47 +00:00
activate_confirm_close_4coder,
&do_exit, sizeof(do_exit),
2019-10-14 05:27:57 +00:00
options, option_count, default_string_size_estimation,
view);
2019-10-14 22:57:47 +00:00
return(do_exit);
2018-08-05 07:09:18 +00:00
}
////////////////////////////////
2019-10-14 05:27:57 +00:00
function Lister_Activation_Code
activate_switch_buffer(Application_Links *app,
View_ID view, Lister *lister,
2019-06-01 23:58:28 +00:00
String_Const_u8 text_field, void *user_data, b32 activated_by_mouse){
if (user_data != 0){
2018-08-10 21:52:57 +00:00
Buffer_ID buffer_id = (Buffer_ID)(PtrAsInt(user_data));
view_set_buffer(app, view, buffer_id, SetBuffer_KeepOriginalGUI);
}
2019-10-14 05:27:57 +00:00
lister_default(app, view, lister, ListerActivation_Finished);
2019-10-13 21:45:41 +00:00
return(ListerActivation_Finished);
}
CUSTOM_COMMAND_SIG(interactive_switch_buffer)
CUSTOM_DOC("Interactively switch to an open buffer.")
{
2019-06-19 02:31:59 +00:00
View_ID view = get_active_view(app, AccessAll);
2019-10-14 05:27:57 +00:00
run_lister_buffer_list(app, "Switch:", activate_switch_buffer, 0, 0, view);
}
2019-10-14 05:27:57 +00:00
function Lister_Activation_Code
activate_kill_buffer(Application_Links *app,
View_ID view, Lister *lister,
2019-06-01 23:58:28 +00:00
String_Const_u8 text_field, void *user_data, b32 activated_by_mouse){
2019-10-14 05:27:57 +00:00
lister_default(app, view, lister, ListerActivation_Finished);
if (user_data != 0){
2019-06-19 02:31:59 +00:00
Buffer_ID buffer = (Buffer_ID)(PtrAsInt(user_data));
try_buffer_kill(app, buffer, view, 0);
}
2019-10-13 21:45:41 +00:00
return(ListerActivation_Finished);
}
CUSTOM_COMMAND_SIG(interactive_kill_buffer)
CUSTOM_DOC("Interactively kill an open buffer.")
{
2019-06-19 02:31:59 +00:00
View_ID view = get_active_view(app, AccessAll);
2019-10-14 05:27:57 +00:00
run_lister_buffer_list(app, "Kill:", activate_kill_buffer, 0, 0, view);
}
2019-10-14 05:27:57 +00:00
function Lister_Activation_Code
2019-06-01 23:58:28 +00:00
activate_open_or_new__generic(Application_Links *app, View_ID view,
String_Const_u8 path, String_Const_u8 file_name, b32 is_folder,
2018-08-05 07:09:18 +00:00
Buffer_Create_Flag flags){
Lister_Activation_Code result = 0;
2018-08-05 07:09:18 +00:00
if (file_name.size == 0){
2019-06-01 23:58:28 +00:00
#define M "Zero length file_name passed to activate_open_or_new__generic\n"
print_message(app, string_u8_litexpr(M));
#undef M
result = ListerActivation_Finished;
}
else{
Scratch_Block scratch(app, Scratch_Share);
2019-06-01 23:58:28 +00:00
String_Const_u8 full_file_name = {};
if (character_is_slash(string_get_character(path, path.size - 1))){
path = string_chop(path, 1);
}
2019-06-18 22:56:09 +00:00
full_file_name = push_u8_stringf(scratch, "%.*s/%.*s", string_expand(path), string_expand(file_name));
2018-08-05 07:09:18 +00:00
if (is_folder){
2019-06-01 23:58:28 +00:00
set_hot_directory(app, full_file_name);
result = ListerActivation_ContinueAndRefresh;
}
else{
2019-06-19 02:31:59 +00:00
Buffer_ID buffer = create_buffer(app, full_file_name, flags);
if (buffer != 0){
view_set_buffer(app, view, buffer, SetBuffer_KeepOriginalGUI);
}
result = ListerActivation_Finished;
}
2018-08-05 07:09:18 +00:00
}
return(result);
}
2019-10-14 05:27:57 +00:00
function Lister_Activation_Code
activate_open_or_new(Application_Links *app,
View_ID view, Lister *lister,
2019-06-01 23:58:28 +00:00
String_Const_u8 text_field, void *user_data, b32 clicked){
2018-08-05 07:09:18 +00:00
Lister_Activation_Code result = 0;
2019-06-01 23:58:28 +00:00
String_Const_u8 file_name = {};
2018-08-05 07:09:18 +00:00
if (user_data == 0){
2019-06-01 23:58:28 +00:00
file_name = string_front_of_path(text_field);
2018-08-05 07:09:18 +00:00
}
else{
2019-06-01 23:58:28 +00:00
file_name = SCu8((u8*)user_data);
2018-08-05 07:09:18 +00:00
}
if (file_name.size == 0){
result = ListerActivation_Finished;
}
else{
2019-10-14 22:57:47 +00:00
String_Const_u8 path = lister->text_field.string;
2019-06-01 23:58:28 +00:00
if (!character_is_slash(string_get_character(path, path.size - 1))){
path = string_remove_last_folder(path);
}
2019-06-01 23:58:28 +00:00
b32 is_folder = (character_is_slash(string_get_character(file_name, file_name.size - 1)) &&
user_data != 0);
2018-08-05 07:09:18 +00:00
Buffer_Create_Flag flags = 0;
2019-06-01 23:58:28 +00:00
result = activate_open_or_new__generic(app, view, path, file_name, is_folder, flags);
}
2019-10-14 05:27:57 +00:00
lister_default(app, view, lister, result);
2019-10-13 21:45:41 +00:00
return(result);
}
CUSTOM_COMMAND_SIG(interactive_open_or_new)
CUSTOM_DOC("Interactively open a file out of the file system.")
{
2019-06-19 02:31:59 +00:00
View_ID view = get_active_view(app, AccessAll);
2019-10-14 05:27:57 +00:00
run_lister_file_system_list(app, "Open:", activate_open_or_new, 0, 0, view);
}
2019-10-14 05:27:57 +00:00
function Lister_Activation_Code
activate_new(Application_Links *app,
View_ID view, Lister *lister,
2019-06-01 23:58:28 +00:00
String_Const_u8 text_field, void *user_data, b32 clicked){
Lister_Activation_Code result = 0;
2019-06-01 23:58:28 +00:00
String_Const_u8 file_name = string_front_of_path(text_field);
if (user_data != 0){
2019-06-01 23:58:28 +00:00
String_Const_u8 item_name = SCu8((u8*)user_data);
if (item_name.str[item_name.size - 1] == '/'){
file_name = item_name;
}
2018-08-05 07:09:18 +00:00
else if (clicked){
file_name = item_name;
}
}
if (file_name.size == 0){
result = ListerActivation_Finished;
}
else{
2019-10-14 22:57:47 +00:00
String_Const_u8 path = lister->text_field.string;
2019-06-01 23:58:28 +00:00
if (character_is_slash(string_get_character(path, path.size - 1))){
path = string_remove_last_folder(path);
}
2019-06-01 23:58:28 +00:00
b32 is_folder = (character_is_slash(string_get_character(file_name, file_name.size - 1)) &&
user_data != 0);
2018-08-05 07:09:18 +00:00
Buffer_Create_Flag flags = BufferCreate_AlwaysNew;
2019-06-01 23:58:28 +00:00
result = activate_open_or_new__generic(app, view, path, file_name, is_folder, flags);
}
2019-10-14 05:27:57 +00:00
lister_default(app, view, lister, result);
2019-10-13 21:45:41 +00:00
return(result);
}
CUSTOM_COMMAND_SIG(interactive_new)
CUSTOM_DOC("Interactively creates a new file.")
{
2019-06-19 02:31:59 +00:00
View_ID view = get_active_view(app, AccessAll);
2019-10-14 05:27:57 +00:00
run_lister_file_system_list(app, "New:", activate_new, 0, 0, view);
}
2019-10-14 05:27:57 +00:00
function Lister_Activation_Code
activate_open(Application_Links *app,
View_ID view, Lister *lister,
2019-06-01 23:58:28 +00:00
String_Const_u8 text_field, void *user_data, b32 clicked){
Lister_Activation_Code result = 0;
2019-06-01 23:58:28 +00:00
String_Const_u8 file_name = {};
if (user_data != 0){
2019-06-01 23:58:28 +00:00
file_name = SCu8((u8*)user_data);
}
if (file_name.size == 0){
result = ListerActivation_Finished;
}
else{
2019-10-14 22:57:47 +00:00
String_Const_u8 path = lister->text_field.string;
2019-06-01 23:58:28 +00:00
if (!character_is_slash(string_get_character(path, path.size - 1))){
path = string_remove_last_folder(path);
}
2019-06-01 23:58:28 +00:00
b32 is_folder = (character_is_slash(string_get_character(file_name, file_name.size - 1)) &&
user_data != 0);
2018-08-05 07:09:18 +00:00
Buffer_Create_Flag flags = BufferCreate_NeverNew;
2019-06-01 23:58:28 +00:00
result = activate_open_or_new__generic(app, view, path, file_name, is_folder, flags);
}
2019-10-14 05:27:57 +00:00
lister_default(app, view, lister, result);
2019-10-13 21:45:41 +00:00
return(result);
}
CUSTOM_COMMAND_SIG(interactive_open)
CUSTOM_DOC("Interactively opens a file.")
{
2019-06-19 02:31:59 +00:00
View_ID view = get_active_view(app, AccessAll);
2019-10-14 05:27:57 +00:00
run_lister_file_system_list(app, "Open:", activate_open, 0, 0, view);
}
2019-02-25 23:42:13 +00:00
#if 0
2019-10-14 05:27:57 +00:00
function Lister_Activation_Code
activate_select_theme(Application_Links *app,
View_ID view, struct Lister *lister,
String_Const_u8 text_field, void *user_data, b32 activated_by_mouse){
change_theme_by_index(app, (i32)PtrAsInt(user_data));
2019-10-14 05:27:57 +00:00
lister_default(app, scratch, view, state, ListerActivation_Finished);
return(ListerActivation_Finished);
2018-08-10 21:52:57 +00:00
}
CUSTOM_COMMAND_SIG(open_color_tweaker)
CUSTOM_DOC("Opens the 4coder theme selector list.")
{
}
2019-02-25 23:42:13 +00:00
#endif
2018-08-10 21:52:57 +00:00
////////////////////////////////
2019-10-14 05:27:57 +00:00
function Lister_Activation_Code
activate_command(Application_Links *app,
View_ID view, Lister *lister,
2019-06-01 23:58:28 +00:00
String_Const_u8 text_field, void *user_data, b32 activated_by_mouse){
2019-10-14 05:27:57 +00:00
lister_default(app, view, lister, ListerActivation_Finished);
if (user_data != 0){
Custom_Command_Function *command = (Custom_Command_Function*)user_data;
command(app);
}
2019-10-13 21:45:41 +00:00
return(ListerActivation_Finished);
}
2019-10-14 05:27:57 +00:00
function void
2019-03-30 22:10:17 +00:00
launch_custom_command_lister(Application_Links *app, i32 *command_ids, i32 command_id_count){
if (command_ids == 0){
command_id_count = command_one_past_last_id;
}
Scratch_Block scratch(app, Scratch_Share);
2019-06-19 02:31:59 +00:00
View_ID view = get_active_view(app, AccessAll);
2019-06-01 23:58:28 +00:00
Lister_Option *options = push_array(scratch, Lister_Option, command_id_count);
2019-03-30 22:10:17 +00:00
for (i32 i = 0; i < command_id_count; i += 1){
i32 j = i;
if (command_ids != 0){
j = command_ids[i];
}
j = clamp(0, j, command_one_past_last_id);
2019-06-01 23:58:28 +00:00
options[i].string = SCu8(fcoder_metacmd_table[j].name);
options[i].status = SCu8(fcoder_metacmd_table[j].description);
2019-03-30 22:10:17 +00:00
options[i].user_data = (void*)fcoder_metacmd_table[j].proc;
}
2019-10-14 05:27:57 +00:00
run_lister_with_options_array(app, "Command:", activate_command, 0, 0, options, command_id_count, 0, view);
}
2019-03-30 22:10:17 +00:00
CUSTOM_COMMAND_SIG(command_lister)
CUSTOM_DOC("Opens an interactive list of all registered commands.")
{
launch_custom_command_lister(app, 0, 0);
}
// BOTTOM