various bug fixes

This commit is contained in:
Allen Webster 2016-03-07 00:13:20 -05:00
parent 32da95069c
commit 264100d81a
18 changed files with 868 additions and 710 deletions

View File

@ -1,9 +1,13 @@
// Alternative customizations, set Custom_Current to select which to apply. // Set which customization you want to use with this define or write your own
#define Custom_Default 0
#define Custom_HandmadeHero 1
#define Custom_Current Custom_Default #define Custom_Current Custom_Default
#define Custom_Default 0
// The following customization schemes are power users only:
#define Custom_HandmadeHero 1
// TOP
#include "4coder_custom.h" #include "4coder_custom.h"
#define FCPP_STRING_IMPLEMENTATION #define FCPP_STRING_IMPLEMENTATION
@ -20,30 +24,32 @@
// as shown here, they may start at 0, and you can only have // as shown here, they may start at 0, and you can only have
// 2^24 of them so don't be wasteful! // 2^24 of them so don't be wasteful!
enum My_Maps{ enum My_Maps{
my_code_map, my_code_map
my_html_map
}; };
HOOK_SIG(my_start){ HOOK_SIG(my_start){
exec_command(app, cmdid_open_panel_vsplit); exec_command(app, cmdid_open_panel_vsplit);
exec_command(app, cmdid_change_active_panel); exec_command(app, cmdid_change_active_panel);
app->change_theme(app, literal("4coder")); app->change_theme(app, literal("4coder"));
app->change_font(app, literal("liberation sans")); app->change_font(app, literal("liberation sans"));
// Theme options: // Theme options:
// "4coder" // "4coder"
// "Handmade Hero" // "Handmade Hero"
// "Twilight" // "Twilight"
// "Woverine" // "Woverine"
// "stb" // "stb"
// Font options: // Font options:
// "liberation sans" // "liberation sans"
// "liberation mono" // "liberation mono"
// "hack" // "hack"
// "cutive mono" // "cutive mono"
// "inconsolata" // "inconsolata"
// no meaning for return
return(0);
} }
HOOK_SIG(my_file_settings){ HOOK_SIG(my_file_settings){
@ -53,7 +59,7 @@ HOOK_SIG(my_file_settings){
// there are no parameter buffers. // there are no parameter buffers.
Buffer_Summary buffer = app->get_parameter_buffer(app, 0); Buffer_Summary buffer = app->get_parameter_buffer(app, 0);
assert(buffer.exists); assert(buffer.exists);
int treat_as_code = 0; int treat_as_code = 0;
if (buffer.file_name && buffer.size < (16 << 20)){ if (buffer.file_name && buffer.size < (16 << 20)){
@ -68,6 +74,49 @@ HOOK_SIG(my_file_settings){
push_parameter(app, par_wrap_lines, !treat_as_code); push_parameter(app, par_wrap_lines, !treat_as_code);
push_parameter(app, par_key_mapid, (treat_as_code)?((int)my_code_map):((int)mapid_file)); push_parameter(app, par_key_mapid, (treat_as_code)?((int)my_code_map):((int)mapid_file));
exec_command(app, cmdid_set_settings); exec_command(app, cmdid_set_settings);
// no meaning for return
return(0);
}
unsigned char blink_t = 0;
HOOK_SIG(my_frame){
// NOTE(allen|a4): Please use me sparingly! This get's called roughly once every *33 ms* if everything is going well.
// But if you start doing a lot in here, there's nothing 4codes does to stop you from making it a lot slower.
int result = 0;
Theme_Color theme_color_1[] = {
{Stag_Cursor, 0x00FF00},
{Stag_At_Cursor, 0x000000}
};
Theme_Color theme_color_2[2] = {
{Stag_Cursor, 0x000000},
{Stag_At_Cursor, 0xFFFFFF}
};
Theme_Color *theme_color;
++blink_t;
if (blink_t == 20 || blink_t == 40){
if (blink_t == 20){
theme_color = theme_color_2;
}
else{
theme_color = theme_color_1;
blink_t = 0;
}
result = 1;
app->set_theme_colors(app, theme_color, 2);
}
// return non-zero if you do anything that might change the screen!
// 4coder won't redraw unless you tell it you've changed something important.
// If you redraw *all* the time it's going to slow 4coder down and increase power consumption.
return(result);
} }
static void static void
@ -92,19 +141,41 @@ CUSTOM_COMMAND_SIG(write_allen_note){
write_string(app, make_lit_string("// NOTE(allen): ")); write_string(app, make_lit_string("// NOTE(allen): "));
} }
static void
basic_seek(Application_Links *app, Command_ID seek_type, unsigned int flags){
push_parameter(app, par_flags, flags);
exec_command(app, seek_type);
}
#define SEEK_COMMAND(n, dir, flags)\
CUSTOM_COMMAND_SIG(seek_##n##_##dir){\
basic_seek(app, cmdid_seek_##dir, flags);\
}
SEEK_COMMAND(whitespace, right, BoundryWhitespace)
SEEK_COMMAND(whitespace, left, BoundryWhitespace)
SEEK_COMMAND(token, right, BoundryToken)
SEEK_COMMAND(token, left, BoundryToken)
SEEK_COMMAND(white_or_token, right, BoundryToken | BoundryWhitespace)
SEEK_COMMAND(white_or_token, left, BoundryToken | BoundryWhitespace)
SEEK_COMMAND(alphanumeric, right, BoundryAlphanumeric)
SEEK_COMMAND(alphanumeric, left, BoundryAlphanumeric)
SEEK_COMMAND(alphanumeric_or_camel, right, BoundryAlphanumeric | BoundryCamelCase)
SEEK_COMMAND(alphanumeric_or_camel, left, BoundryAlphanumeric | BoundryCamelCase)
static void static void
long_braces(Application_Links *app, char *text, int size){ long_braces(Application_Links *app, char *text, int size){
View_Summary view; View_Summary view;
Buffer_Summary buffer; Buffer_Summary buffer;
int pos; int pos;
view = app->get_active_view(app); view = app->get_active_view(app);
buffer = app->get_buffer(app, view.buffer_id); buffer = app->get_buffer(app, view.buffer_id);
pos = view.cursor.pos; pos = view.cursor.pos;
app->buffer_replace_range(app, &buffer, pos, pos, text, size); app->buffer_replace_range(app, &buffer, pos, pos, text, size);
app->view_set_cursor(app, &view, seek_pos(pos + 2), 1); app->view_set_cursor(app, &view, seek_pos(pos + 2), 1);
push_parameter(app, par_range_start, pos); push_parameter(app, par_range_start, pos);
push_parameter(app, par_range_end, pos + size); push_parameter(app, par_range_end, pos + size);
push_parameter(app, par_clear_blank_lines, 0); push_parameter(app, par_clear_blank_lines, 0);
@ -156,13 +227,13 @@ CUSTOM_COMMAND_SIG(paren_wrap){
CUSTOM_COMMAND_SIG(if0_off){ CUSTOM_COMMAND_SIG(if0_off){
View_Summary view; View_Summary view;
Buffer_Summary buffer; Buffer_Summary buffer;
char text1[] = "\n#if 0"; char text1[] = "\n#if 0";
int size1 = sizeof(text1) - 1; int size1 = sizeof(text1) - 1;
char text2[] = "#endif\n"; char text2[] = "#endif\n";
int size2 = sizeof(text2) - 1; int size2 = sizeof(text2) - 1;
Range range; Range range;
int pos; int pos;
@ -177,13 +248,13 @@ CUSTOM_COMMAND_SIG(if0_off){
push_parameter(app, par_range_start, pos); push_parameter(app, par_range_start, pos);
push_parameter(app, par_range_end, pos); push_parameter(app, par_range_end, pos);
exec_command(app, cmdid_auto_tab_range); exec_command(app, cmdid_auto_tab_range);
app->refresh_view(app, &view); app->refresh_view(app, &view);
range = get_range(&view); range = get_range(&view);
pos = range.max; pos = range.max;
app->buffer_replace_range(app, &buffer, pos, pos, text2, size2); app->buffer_replace_range(app, &buffer, pos, pos, text2, size2);
push_parameter(app, par_range_start, pos); push_parameter(app, par_range_start, pos);
push_parameter(app, par_range_end, pos); push_parameter(app, par_range_end, pos);
exec_command(app, cmdid_auto_tab_range); exec_command(app, cmdid_auto_tab_range);
@ -193,14 +264,14 @@ CUSTOM_COMMAND_SIG(backspace_word){
View_Summary view; View_Summary view;
Buffer_Summary buffer; Buffer_Summary buffer;
int pos2, pos1; int pos2, pos1;
view = app->get_active_view(app); view = app->get_active_view(app);
pos2 = view.cursor.pos; pos2 = view.cursor.pos;
exec_command(app, cmdid_seek_alphanumeric_left); exec_command(app, seek_alphanumeric_left);
app->refresh_view(app, &view); app->refresh_view(app, &view);
pos1 = view.cursor.pos; pos1 = view.cursor.pos;
buffer = app->get_buffer(app, view.buffer_id); buffer = app->get_buffer(app, view.buffer_id);
app->buffer_replace_range(app, &buffer, pos1, pos2, 0, 0); app->buffer_replace_range(app, &buffer, pos1, pos2, 0, 0);
} }
@ -209,19 +280,19 @@ CUSTOM_COMMAND_SIG(snipe_token_or_word){
View_Summary view; View_Summary view;
Buffer_Summary buffer; Buffer_Summary buffer;
int pos1, pos2; int pos1, pos2;
view = app->get_active_view(app); view = app->get_active_view(app);
push_parameter(app, par_flags, BoundryToken | BoundryWhitespace); push_parameter(app, par_flags, BoundryToken | BoundryWhitespace);
exec_command(app, cmdid_seek_left); exec_command(app, cmdid_seek_left);
app->refresh_view(app, &view); app->refresh_view(app, &view);
pos1 = view.cursor.pos; pos1 = view.cursor.pos;
push_parameter(app, par_flags, BoundryToken | BoundryWhitespace); push_parameter(app, par_flags, BoundryToken | BoundryWhitespace);
exec_command(app, cmdid_seek_right); exec_command(app, cmdid_seek_right);
app->refresh_view(app, &view); app->refresh_view(app, &view);
pos2 = view.cursor.pos; pos2 = view.cursor.pos;
Range range = make_range(pos1, pos2); Range range = make_range(pos1, pos2);
buffer = app->get_buffer(app, view.buffer_id); buffer = app->get_buffer(app, view.buffer_id);
app->buffer_replace_range(app, &buffer, range.start, range.end, 0, 0); app->buffer_replace_range(app, &buffer, range.start, range.end, 0, 0);
@ -230,13 +301,13 @@ CUSTOM_COMMAND_SIG(snipe_token_or_word){
CUSTOM_COMMAND_SIG(switch_to_compilation){ CUSTOM_COMMAND_SIG(switch_to_compilation){
View_Summary view; View_Summary view;
Buffer_Summary buffer; Buffer_Summary buffer;
char name[] = "*compilation*"; char name[] = "*compilation*";
int name_size = sizeof(name)-1; int name_size = sizeof(name)-1;
view = app->get_active_view(app); view = app->get_active_view(app);
buffer = app->get_buffer_by_name(app, name, name_size); buffer = app->get_buffer_by_name(app, name, name_size);
app->view_set_buffer(app, &view, buffer.buffer_id); app->view_set_buffer(app, &view, buffer.buffer_id);
} }
@ -246,14 +317,14 @@ CUSTOM_COMMAND_SIG(move_up_10){
view = app->get_active_view(app); view = app->get_active_view(app);
x = view.preferred_x; x = view.preferred_x;
if (view.unwrapped_lines){ if (view.unwrapped_lines){
y = view.cursor.unwrapped_y; y = view.cursor.unwrapped_y;
} }
else{ else{
y = view.cursor.wrapped_y; y = view.cursor.wrapped_y;
} }
y -= 10*view.line_height; y -= 10*view.line_height;
app->view_set_cursor(app, &view, seek_xy(x, y, 0, view.unwrapped_lines), 0); app->view_set_cursor(app, &view, seek_xy(x, y, 0, view.unwrapped_lines), 0);
@ -265,16 +336,16 @@ CUSTOM_COMMAND_SIG(move_down_10){
view = app->get_active_view(app); view = app->get_active_view(app);
x = view.preferred_x; x = view.preferred_x;
if (view.unwrapped_lines){ if (view.unwrapped_lines){
y = view.cursor.wrapped_y; y = view.cursor.wrapped_y;
} }
else{ else{
y = view.cursor.wrapped_y; y = view.cursor.wrapped_y;
} }
y += 10*view.line_height; y += 10*view.line_height;
app->view_set_cursor(app, &view, seek_xy(x, y, 0, view.unwrapped_lines), 0); app->view_set_cursor(app, &view, seek_xy(x, y, 0, view.unwrapped_lines), 0);
} }
@ -283,16 +354,16 @@ CUSTOM_COMMAND_SIG(open_file_in_quotes){
Buffer_Summary buffer; Buffer_Summary buffer;
char short_file_name[128]; char short_file_name[128];
int pos, start, end, size; int pos, start, end, size;
view = app->get_active_view(app); view = app->get_active_view(app);
buffer = app->get_buffer(app, view.buffer_id); buffer = app->get_buffer(app, view.buffer_id);
pos = view.cursor.pos; pos = view.cursor.pos;
app->buffer_seek_delimiter(app, &buffer, pos, '"', 1, &end); app->buffer_seek_delimiter(app, &buffer, pos, '"', 1, &end);
app->buffer_seek_delimiter(app, &buffer, pos, '"', 0, &start); app->buffer_seek_delimiter(app, &buffer, pos, '"', 0, &start);
++start; ++start;
size = end - start; size = end - start;
// NOTE(allen): This check is necessary because app->buffer_read_range // NOTE(allen): This check is necessary because app->buffer_read_range
// requiers that the output buffer you provide is at least (end - start) bytes long. // requiers that the output buffer you provide is at least (end - start) bytes long.
if (size < sizeof(short_file_name)){ if (size < sizeof(short_file_name)){
@ -315,10 +386,10 @@ CUSTOM_COMMAND_SIG(goto_line){
int line_number; int line_number;
Query_Bar bar; Query_Bar bar;
char string_space[256]; char string_space[256];
bar.prompt = make_lit_string("Goto Line: "); bar.prompt = make_lit_string("Goto Line: ");
bar.string = make_fixed_width_string(string_space); bar.string = make_fixed_width_string(string_space);
if (query_user_number(app, &bar)){ if (query_user_number(app, &bar)){
line_number = str_to_int(bar.string); line_number = str_to_int(bar.string);
active_view_to_line(app, line_number); active_view_to_line(app, line_number);
@ -334,37 +405,37 @@ isearch(Application_Links *app, int start_reversed){
Buffer_Summary buffer; Buffer_Summary buffer;
User_Input in; User_Input in;
Query_Bar bar; Query_Bar bar;
if (app->start_query_bar(app, &bar, 0) == 0) return; if (app->start_query_bar(app, &bar, 0) == 0) return;
Range match; Range match;
int reverse = start_reversed; int reverse = start_reversed;
int pos; int pos;
view = app->get_active_view(app); view = app->get_active_view(app);
buffer = app->get_buffer(app, view.buffer_id); buffer = app->get_buffer(app, view.buffer_id);
pos = view.cursor.pos; pos = view.cursor.pos;
match = make_range(pos, pos); match = make_range(pos, pos);
char bar_string_space[256]; char bar_string_space[256];
bar.string = make_fixed_width_string(bar_string_space); bar.string = make_fixed_width_string(bar_string_space);
String isearch = make_lit_string("I-Search: "); String isearch = make_lit_string("I-Search: ");
String rsearch = make_lit_string("Reverse-I-Search: "); String rsearch = make_lit_string("Reverse-I-Search: ");
while (1){ while (1){
// NOTE(allen): Change the bar's prompt to match the current direction. // NOTE(allen): Change the bar's prompt to match the current direction.
if (reverse) bar.prompt = rsearch; if (reverse) bar.prompt = rsearch;
else bar.prompt = isearch; else bar.prompt = isearch;
in = app->get_user_input(app, EventOnAnyKey, EventOnEsc | EventOnButton); in = app->get_user_input(app, EventOnAnyKey, EventOnEsc | EventOnButton);
if (in.abort) break; if (in.abort) break;
// NOTE(allen): If we're getting mouse events here it's a 4coder bug, because we // NOTE(allen): If we're getting mouse events here it's a 4coder bug, because we
// only asked to intercept key events. // only asked to intercept key events.
assert(in.type == UserInputKey); assert(in.type == UserInputKey);
int made_change = 0; int made_change = 0;
if (in.key.keycode == '\n' || in.key.keycode == '\t'){ if (in.key.keycode == '\n' || in.key.keycode == '\t'){
break; break;
@ -377,15 +448,15 @@ isearch(Application_Links *app, int start_reversed){
--bar.string.size; --bar.string.size;
made_change = 1; made_change = 1;
} }
int step_forward = 0; int step_forward = 0;
int step_backward = 0; int step_backward = 0;
if (CommandEqual(in.command, search) || if (CommandEqual(in.command, search) ||
in.key.keycode == key_page_down || in.key.keycode == key_down) step_forward = 1; in.key.keycode == key_page_down || in.key.keycode == key_down) step_forward = 1;
if (CommandEqual(in.command, reverse_search) || if (CommandEqual(in.command, reverse_search) ||
in.key.keycode == key_page_down || in.key.keycode == key_up) step_backward = 1; in.key.keycode == key_page_up || in.key.keycode == key_up) step_backward = 1;
int start_pos = pos; int start_pos = pos;
if (step_forward && reverse){ if (step_forward && reverse){
start_pos = match.start + 1; start_pos = match.start + 1;
@ -399,7 +470,7 @@ isearch(Application_Links *app, int start_reversed){
reverse = 1; reverse = 1;
step_backward = 0; step_backward = 0;
} }
if (in.key.keycode != key_back){ if (in.key.keycode != key_back){
int new_pos; int new_pos;
if (reverse){ if (reverse){
@ -432,12 +503,12 @@ isearch(Application_Links *app, int start_reversed){
else{ else{
match.end = match.start + bar.string.size; match.end = match.start + bar.string.size;
} }
app->view_set_highlight(app, &view, match.start, match.end, 1); app->view_set_highlight(app, &view, match.start, match.end, 1);
} }
app->view_set_highlight(app, &view, 0, 0, 0); app->view_set_highlight(app, &view, 0, 0, 0);
if (in.abort) return; if (in.abort) return;
app->view_set_cursor(app, &view, seek_pos(match.min), 1); app->view_set_cursor(app, &view, seek_pos(match.min), 1);
} }
@ -455,22 +526,22 @@ CUSTOM_COMMAND_SIG(rewrite_as_single_caps){
Range range; Range range;
String string; String string;
int is_first, i; int is_first, i;
exec_command(app, cmdid_seek_token_left); exec_command(app, seek_token_left);
view = app->get_active_view(app); view = app->get_active_view(app);
range.min = view.cursor.pos; range.min = view.cursor.pos;
exec_command(app, cmdid_seek_token_right); exec_command(app, seek_token_right);
app->refresh_view(app, &view); app->refresh_view(app, &view);
range.max = view.cursor.pos; range.max = view.cursor.pos;
string.str = (char*)app->memory; string.str = (char*)app->memory;
string.size = range.max - range.min; string.size = range.max - range.min;
assert(string.size < app->memory_size); assert(string.size < app->memory_size);
buffer = app->get_buffer(app, view.buffer_id); buffer = app->get_buffer(app, view.buffer_id);
app->buffer_read_range(app, &buffer, range.min, range.max, string.str); app->buffer_read_range(app, &buffer, range.min, range.max, string.str);
is_first = 1; is_first = 1;
for (i = 0; i < string.size; ++i){ for (i = 0; i < string.size; ++i){
if (char_is_alpha_true(string.str[i])){ if (char_is_alpha_true(string.str[i])){
@ -481,7 +552,7 @@ CUSTOM_COMMAND_SIG(rewrite_as_single_caps){
is_first = 1; is_first = 1;
} }
} }
app->buffer_replace_range(app, &buffer, range.min, range.max, string.str, string.size); app->buffer_replace_range(app, &buffer, range.min, range.max, string.str, string.size);
} }
@ -493,7 +564,7 @@ CUSTOM_COMMAND_SIG(rewrite_as_single_caps){
{ {
rewrite = get_rewrite(app, ByToken); rewrite = get_rewrite(app, ByToken);
string = get_rewrite_string(app, &rewrite, app->memory, app->memory_size); string = get_rewrite_string(app, &rewrite, app->memory, app->memory_size);
is_first = 1; is_first = 1;
for (i = 0; i < string.size; ++i){ for (i = 0; i < string.size; ++i){
if (char_is_alpha_true(string.str[i])){ if (char_is_alpha_true(string.str[i])){
@ -504,7 +575,7 @@ CUSTOM_COMMAND_SIG(rewrite_as_single_caps){
is_first = 1; is_first = 1;
} }
} }
do_rewrite(app, &rewrite, string); do_rewrite(app, &rewrite, string);
} }
#endif #endif
@ -514,17 +585,17 @@ CUSTOM_COMMAND_SIG(replace_in_range){
char replace_space[1024]; char replace_space[1024];
replace.prompt = make_lit_string("Replace: "); replace.prompt = make_lit_string("Replace: ");
replace.string = make_fixed_width_string(replace_space); replace.string = make_fixed_width_string(replace_space);
Query_Bar with; Query_Bar with;
char with_space[1024]; char with_space[1024];
with.prompt = make_lit_string("With: "); with.prompt = make_lit_string("With: ");
with.string = make_fixed_width_string(with_space); with.string = make_fixed_width_string(with_space);
if (!query_user_string(app, &replace)) return; if (!query_user_string(app, &replace)) return;
if (replace.string.size == 0) return; if (replace.string.size == 0) return;
if (!query_user_string(app, &with)) return; if (!query_user_string(app, &with)) return;
String r, w; String r, w;
r = replace.string; r = replace.string;
w = with.string; w = with.string;
@ -540,7 +611,7 @@ CUSTOM_COMMAND_SIG(replace_in_range){
int pos, new_pos; int pos, new_pos;
pos = range.min; pos = range.min;
app->buffer_seek_string(app, &buffer, pos, r.str, r.size, 1, &new_pos); app->buffer_seek_string(app, &buffer, pos, r.str, r.size, 1, &new_pos);
while (new_pos + r.size < range.end){ while (new_pos + r.size < range.end){
app->buffer_replace_range(app, &buffer, new_pos, new_pos + r.size, w.str, w.size); app->buffer_replace_range(app, &buffer, new_pos, new_pos + r.size, w.str, w.size);
range = get_range(&view); range = get_range(&view);
@ -554,45 +625,45 @@ CUSTOM_COMMAND_SIG(query_replace){
char replace_space[1024]; char replace_space[1024];
replace.prompt = make_lit_string("Replace: "); replace.prompt = make_lit_string("Replace: ");
replace.string = make_fixed_width_string(replace_space); replace.string = make_fixed_width_string(replace_space);
Query_Bar with; Query_Bar with;
char with_space[1024]; char with_space[1024];
with.prompt = make_lit_string("With: "); with.prompt = make_lit_string("With: ");
with.string = make_fixed_width_string(with_space); with.string = make_fixed_width_string(with_space);
if (!query_user_string(app, &replace)) return; if (!query_user_string(app, &replace)) return;
if (replace.string.size == 0) return; if (replace.string.size == 0) return;
if (!query_user_string(app, &with)) return; if (!query_user_string(app, &with)) return;
String r, w; String r, w;
r = replace.string; r = replace.string;
w = with.string; w = with.string;
Query_Bar bar; Query_Bar bar;
Buffer_Summary buffer; Buffer_Summary buffer;
View_Summary view; View_Summary view;
int pos, new_pos; int pos, new_pos;
bar.prompt = make_lit_string("Replace? (y)es, (n)ext, (esc)\n"); bar.prompt = make_lit_string("Replace? (y)es, (n)ext, (esc)\n");
bar.string = {}; bar.string = empty_string();
app->start_query_bar(app, &bar, 0); app->start_query_bar(app, &bar, 0);
view = app->get_active_view(app); view = app->get_active_view(app);
buffer = app->get_buffer(app, view.buffer_id); buffer = app->get_buffer(app, view.buffer_id);
pos = view.cursor.pos; pos = view.cursor.pos;
app->buffer_seek_string(app, &buffer, pos, r.str, r.size, 1, &new_pos); app->buffer_seek_string(app, &buffer, pos, r.str, r.size, 1, &new_pos);
User_Input in = {}; User_Input in = {0};
while (new_pos < buffer.size){ while (new_pos < buffer.size){
Range match = make_range(new_pos, new_pos + r.size); Range match = make_range(new_pos, new_pos + r.size);
app->view_set_highlight(app, &view, match.min, match.max, 1); app->view_set_highlight(app, &view, match.min, match.max, 1);
in = app->get_user_input(app, EventOnAnyKey, EventOnButton); in = app->get_user_input(app, EventOnAnyKey, EventOnButton);
if (in.abort || in.key.keycode == key_esc || !key_is_unmodified(&in.key)) break; if (in.abort || in.key.keycode == key_esc || !key_is_unmodified(&in.key)) break;
if (in.key.character == 'y' || in.key.character == 'Y' || in.key.character == '\n' || in.key.character == '\t'){ if (in.key.character == 'y' || in.key.character == 'Y' || in.key.character == '\n' || in.key.character == '\t'){
app->buffer_replace_range(app, &buffer, match.min, match.max, w.str, w.size); app->buffer_replace_range(app, &buffer, match.min, match.max, w.str, w.size);
pos = match.start + w.size; pos = match.start + w.size;
@ -600,7 +671,7 @@ CUSTOM_COMMAND_SIG(query_replace){
else{ else{
pos = match.max; pos = match.max;
} }
app->buffer_seek_string(app, &buffer, pos, r.str, r.size, 1, &new_pos); app->buffer_seek_string(app, &buffer, pos, r.str, r.size, 1, &new_pos);
} }
@ -617,7 +688,7 @@ CUSTOM_COMMAND_SIG(close_all_code){
for (buffer = app->get_buffer_first(app); for (buffer = app->get_buffer_first(app);
buffer.exists; buffer.exists;
app->get_buffer_next(app, &buffer)){ app->get_buffer_next(app, &buffer)){
extension = file_extension(make_string(buffer.file_name, buffer.file_name_len)); extension = file_extension(make_string(buffer.file_name, buffer.file_name_len));
if (match(extension, make_lit_string("cpp")) || if (match(extension, make_lit_string("cpp")) ||
match(extension, make_lit_string("hpp")) || match(extension, make_lit_string("hpp")) ||
@ -639,12 +710,11 @@ CUSTOM_COMMAND_SIG(open_all_code){
String dir = make_string(app->memory, 0, app->memory_size); String dir = make_string(app->memory, 0, app->memory_size);
dir.size = app->directory_get_hot(app, dir.str, dir.memory_size); dir.size = app->directory_get_hot(app, dir.str, dir.memory_size);
int dir_size = dir.size; int dir_size = dir.size;
// NOTE(allen|a3.4.4): Here we get the list of files in this directory. // NOTE(allen|a3.4.4): Here we get the list of files in this directory.
// Notice that we free_file_list at the end. // Notice that we free_file_list at the end.
File_List list = app->get_file_list(app, dir.str, dir.size); File_List list = app->get_file_list(app, dir.str, dir.size);
for (int i = 0; i < list.count; ++i){ for (int i = 0; i < list.count; ++i){
File_Info *info = list.infos + i; File_Info *info = list.infos + i;
if (!info->folder){ if (!info->folder){
@ -660,12 +730,12 @@ CUSTOM_COMMAND_SIG(open_all_code){
dir.size = dir_size; dir.size = dir_size;
append(&dir, info->filename); append(&dir, info->filename);
push_parameter(app, par_name, dir.str, dir.size); push_parameter(app, par_name, dir.str, dir.size);
push_parameter(app, par_do_in_background, 1); //push_parameter(app, par_do_in_background, 1);
exec_command(app, cmdid_interactive_open); exec_command(app, cmdid_interactive_open);
} }
} }
} }
app->free_file_list(app, list); app->free_file_list(app, list);
} }
@ -673,18 +743,18 @@ CUSTOM_COMMAND_SIG(execute_any_cli){
Query_Bar bar_out, bar_cmd; Query_Bar bar_out, bar_cmd;
String hot_directory; String hot_directory;
char space[1024], more_space[1024], even_more_space[1024]; char space[1024], more_space[1024], even_more_space[1024];
bar_out.prompt = make_lit_string("Output Buffer: "); bar_out.prompt = make_lit_string("Output Buffer: ");
bar_out.string = make_fixed_width_string(space); bar_out.string = make_fixed_width_string(space);
if (!query_user_string(app, &bar_out)) return; if (!query_user_string(app, &bar_out)) return;
bar_cmd.prompt = make_lit_string("Command: "); bar_cmd.prompt = make_lit_string("Command: ");
bar_cmd.string = make_fixed_width_string(more_space); bar_cmd.string = make_fixed_width_string(more_space);
if (!query_user_string(app, &bar_cmd)) return; if (!query_user_string(app, &bar_cmd)) return;
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_flags, CLI_OverlapWithConflict); push_parameter(app, par_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);
@ -701,9 +771,9 @@ CUSTOM_COMMAND_SIG(execute_arbitrary_command){
char space[1024]; char space[1024];
bar.prompt = make_lit_string("Command: "); bar.prompt = make_lit_string("Command: ");
bar.string = make_fixed_width_string(space); bar.string = make_fixed_width_string(space);
if (!query_user_string(app, &bar)) return; if (!query_user_string(app, &bar)) return;
// NOTE(allen): Here I chose to end this query bar because when I call another // NOTE(allen): Here I chose to end this query bar because when I call another
// command it might ALSO have query bars and I don't want this one hanging // command it might ALSO have query bars and I don't want this one hanging
// around at that point. Since the bar exists on my stack the result of the query // around at that point. Since the bar exists on my stack the result of the query
@ -719,6 +789,12 @@ CUSTOM_COMMAND_SIG(execute_arbitrary_command){
else if (match(bar.string, make_lit_string("open menu"))){ else if (match(bar.string, make_lit_string("open menu"))){
exec_command(app, cmdid_open_menu); exec_command(app, cmdid_open_menu);
} }
else if (match(bar.string, make_lit_string("dos lines"))){
exec_command(app, cmdid_eol_dosify);
}
else if (match(bar.string, make_lit_string("nix lines"))){
exec_command(app, cmdid_eol_nixify);
}
else{ else{
// TODO(allen): feedback message // TODO(allen): feedback message
} }
@ -805,23 +881,23 @@ CUSTOM_COMMAND_SIG(build_search){
// //
// This doesn't actually change the hot directory of 4coder, it's only effect is to // This doesn't actually change the hot directory of 4coder, it's only effect is to
// modify the string you passed in to reflect the change in directory if that change was possible. // modify the string you passed in to reflect the change in directory if that change was possible.
int keep_going = 1; int keep_going = 1;
int old_size; int old_size;
String dir = make_string(app->memory, 0, app->memory_size); String dir = make_string(app->memory, 0, app->memory_size);
dir.size = app->directory_get_hot(app, dir.str, dir.memory_size); dir.size = app->directory_get_hot(app, dir.str, dir.memory_size);
while (keep_going){ while (keep_going){
old_size = dir.size; old_size = dir.size;
append(&dir, "build.bat"); append(&dir, "build.bat");
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_flags, CLI_OverlapWithConflict); push_parameter(app, par_flags, CLI_OverlapWithConflict);
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);
if (append(&dir, "build")){ if (append(&dir, "build")){
push_parameter(app, par_cli_command, dir.str, dir.size); push_parameter(app, par_cli_command, dir.str, dir.size);
exec_command(app, cmdid_command_line); exec_command(app, cmdid_command_line);
@ -829,7 +905,7 @@ CUSTOM_COMMAND_SIG(build_search){
else{ else{
app->clear_parameters(app); app->clear_parameters(app);
} }
return; return;
} }
dir.size = old_size; dir.size = old_size;
@ -842,9 +918,24 @@ CUSTOM_COMMAND_SIG(build_search){
// TODO(allen): feedback message - couldn't find build.bat // TODO(allen): feedback message - couldn't find build.bat
} }
CUSTOM_COMMAND_SIG(auto_tab_line_at_cursor){
View_Summary view = app->get_active_view(app);
push_parameter(app, par_range_start, view.cursor.pos);
push_parameter(app, par_range_end, view.cursor.pos);
push_parameter(app, par_clear_blank_lines, 0);
exec_command(app, cmdid_auto_tab_range);
}
CUSTOM_COMMAND_SIG(auto_tab_whole_file){
Buffer_Summary buffer = app->get_active_buffer(app);
push_parameter(app, par_range_start, 0);
push_parameter(app, par_range_end, buffer.size);
exec_command(app, cmdid_auto_tab_range);
}
CUSTOM_COMMAND_SIG(write_and_auto_tab){ CUSTOM_COMMAND_SIG(write_and_auto_tab){
exec_command(app, cmdid_write_character); exec_command(app, cmdid_write_character);
exec_command(app, cmdid_auto_tab_line_at_cursor); exec_command(app, auto_tab_line_at_cursor);
} }
// NOTE(allen|a4) See 4coder_styles.h for a list of available style tags. // NOTE(allen|a4) See 4coder_styles.h for a list of available style tags.
@ -857,9 +948,9 @@ CUSTOM_COMMAND_SIG(improve_theme){
{Stag_Margin_Active, 0xDD0088}, {Stag_Margin_Active, 0xDD0088},
{Stag_Cursor, 0xFF0000}, {Stag_Cursor, 0xFF0000},
}; };
int count = ArrayCount(colors); int count = ArrayCount(colors);
app->set_theme_colors(app, colors, count); app->set_theme_colors(app, colors, count);
} }
@ -871,9 +962,9 @@ CUSTOM_COMMAND_SIG(ruin_theme){
{Stag_Margin_Active, 0x323232}, {Stag_Margin_Active, 0x323232},
{Stag_Cursor, 0x00EE00}, {Stag_Cursor, 0x00EE00},
}; };
int count = ArrayCount(colors); int count = ArrayCount(colors);
app->set_theme_colors(app, colors, count); app->set_theme_colors(app, colors, count);
} }
@ -913,7 +1004,7 @@ struct Scroll_Velocity{
}; };
Scroll_Velocity scroll_velocity_[16] = {0}; Scroll_Velocity scroll_velocity_[16] = {0};
Scroll_Velocity *scroll_velocity = scroll_velocity_; Scroll_Velocity *scroll_velocity = scroll_velocity_ - 1;
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){
@ -953,37 +1044,39 @@ SCROLL_RULE_SIG(smooth_scroll_rule){
velocity->x = 1.f; velocity->x = 1.f;
velocity->y = 1.f; velocity->y = 1.f;
} }
if (smooth_camera_step(target_y, scroll_y, &velocity->y, 40.f, 1.f/4.f)){ if (smooth_camera_step(target_y, scroll_y, &velocity->y, 40.f, 1.f/4.f)){
result = 1; result = 1;
} }
if (smooth_camera_step(target_x, scroll_x, &velocity->x, 40.f, 1.f/4.f)){ if (smooth_camera_step(target_x, scroll_x, &velocity->x, 40.f, 1.f/4.f)){
result = 1; result = 1;
} }
return(result); return(result);
} }
#if Custom_Current == Custom_HandmadeHero #if Custom_Current == Custom_HandmadeHero
# include "4coder_handmade_hero.cpp" # include "power/4coder_handmade_hero.cpp"
#endif #endif
extern "C" GET_BINDING_DATA(get_bindings){ extern "C" GET_BINDING_DATA(get_bindings){
Bind_Helper context_actual = begin_bind_helper(data, size); Bind_Helper context_actual = begin_bind_helper(data, size);
Bind_Helper *context = &context_actual; Bind_Helper *context = &context_actual;
#if Custom_Current == Custom_HandmadeHero #if Custom_Current == Custom_HandmadeHero
casey_get_bindings(context); casey_get_bindings(context);
#else #else
// NOTE(allen|a3.1): Right now hooks have no loyalties to maps, all hooks are // NOTE(allen|a3.1): Hooks have no loyalties to maps. All hooks are global
// global and once set they always apply, regardless of what map is active. // 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_hook(context, hook_frame, my_frame); // Example of a frame hook, but disabled by default.
set_scroll_rule(context, smooth_scroll_rule); set_scroll_rule(context, smooth_scroll_rule);
begin_map(context, mapid_global); begin_map(context, mapid_global);
bind(context, 'p', MDFR_CTRL, cmdid_open_panel_vsplit); bind(context, 'p', MDFR_CTRL, cmdid_open_panel_vsplit);
bind(context, '_', MDFR_CTRL, cmdid_open_panel_hsplit); bind(context, '_', MDFR_CTRL, cmdid_open_panel_hsplit);
bind(context, 'P', MDFR_CTRL, cmdid_close_panel); bind(context, 'P', MDFR_CTRL, cmdid_close_panel);
@ -994,17 +1087,17 @@ extern "C" GET_BINDING_DATA(get_bindings){
bind(context, 'i', MDFR_CTRL, cmdid_interactive_switch_buffer); bind(context, 'i', MDFR_CTRL, cmdid_interactive_switch_buffer);
bind(context, 'c', MDFR_ALT, cmdid_open_color_tweaker); bind(context, 'c', MDFR_ALT, cmdid_open_color_tweaker);
bind(context, 'o', MDFR_ALT, open_in_other); bind(context, 'o', MDFR_ALT, open_in_other);
bind(context, 'm', MDFR_ALT, build_search); bind(context, 'm', MDFR_ALT, build_search);
bind(context, ',', MDFR_ALT, switch_to_compilation); bind(context, ',', MDFR_ALT, switch_to_compilation);
bind(context, 'x', MDFR_ALT, execute_arbitrary_command); bind(context, 'x', MDFR_ALT, execute_arbitrary_command);
bind(context, 'z', MDFR_ALT, execute_any_cli); bind(context, 'z', MDFR_ALT, execute_any_cli);
// NOTE(allen): These callbacks may not actually be useful to you, but // NOTE(allen): These callbacks may not actually be useful to you, but
// go look at them and see what they do. // go look at them and see what they do.
bind(context, 'M', MDFR_ALT | MDFR_CTRL, open_my_files); bind(context, 'M', MDFR_ALT | MDFR_CTRL, open_my_files);
bind(context, 'M', MDFR_ALT, build_at_launch_location); bind(context, 'M', MDFR_ALT, build_at_launch_location);
bind(context, '`', MDFR_ALT, improve_theme); bind(context, '`', MDFR_ALT, improve_theme);
bind(context, '~', MDFR_ALT, ruin_theme); bind(context, '~', MDFR_ALT, ruin_theme);
@ -1021,8 +1114,8 @@ extern "C" GET_BINDING_DATA(get_bindings){
inherit_map(context, mapid_file); inherit_map(context, mapid_file);
// NOTE(allen|a3.1): Children can override parent's bindings. // NOTE(allen|a3.1): Children can override parent's bindings.
bind(context, key_right, MDFR_CTRL, cmdid_seek_alphanumeric_or_camel_right); bind(context, key_right, MDFR_CTRL, seek_alphanumeric_or_camel_right);
bind(context, key_left, MDFR_CTRL, cmdid_seek_alphanumeric_or_camel_left); bind(context, key_left, MDFR_CTRL, seek_alphanumeric_or_camel_left);
// NOTE(allen|a3.2): Specific keys can override vanilla keys, // NOTE(allen|a3.2): Specific keys can override vanilla keys,
// and write character writes whichever character corresponds // and write character writes whichever character corresponds
@ -1033,11 +1126,11 @@ extern "C" GET_BINDING_DATA(get_bindings){
bind(context, ']', MDFR_NONE, write_and_auto_tab); bind(context, ']', MDFR_NONE, write_and_auto_tab);
bind(context, ';', MDFR_NONE, write_and_auto_tab); bind(context, ';', MDFR_NONE, write_and_auto_tab);
bind(context, '#', MDFR_NONE, write_and_auto_tab); bind(context, '#', MDFR_NONE, write_and_auto_tab);
bind(context, '\t', MDFR_NONE, cmdid_word_complete); bind(context, '\t', MDFR_NONE, cmdid_word_complete);
bind(context, '\t', MDFR_CTRL, cmdid_auto_tab_range); bind(context, '\t', MDFR_CTRL, cmdid_auto_tab_range);
bind(context, '\t', MDFR_SHIFT, cmdid_auto_tab_line_at_cursor); bind(context, '\t', MDFR_SHIFT, auto_tab_line_at_cursor);
bind(context, '=', MDFR_CTRL, write_increment); bind(context, '=', MDFR_CTRL, write_increment);
bind(context, '-', MDFR_CTRL, write_decrement); bind(context, '-', MDFR_CTRL, write_decrement);
bind(context, 't', MDFR_ALT, write_allen_todo); bind(context, 't', MDFR_ALT, write_allen_todo);
@ -1047,19 +1140,20 @@ extern "C" GET_BINDING_DATA(get_bindings){
bind(context, '}', MDFR_CTRL, open_long_braces_break); bind(context, '}', MDFR_CTRL, open_long_braces_break);
bind(context, '9', MDFR_CTRL, paren_wrap); bind(context, '9', MDFR_CTRL, paren_wrap);
bind(context, 'i', MDFR_ALT, if0_off); bind(context, 'i', MDFR_ALT, if0_off);
bind(context, '1', MDFR_ALT, open_file_in_quotes);
end_map(context); end_map(context);
begin_map(context, mapid_file); begin_map(context, mapid_file);
// NOTE(allen|a3.4.4): Binding this essentially binds // NOTE(allen|a3.4.4): Binding this essentially binds
// all key combos that would normally insert a character // all key combos that would normally insert a character
// into a buffer. If the code for the key is not an enum // into a buffer. If the code for the key is not an enum
// value such as key_left or key_back then it is a vanilla key. // value such as key_left or key_back then it is a vanilla key.
// It is possible to override this binding for individual keys. // It is possible to override this binding for individual keys.
bind_vanilla_keys(context, cmdid_write_character); bind_vanilla_keys(context, cmdid_write_character);
bind(context, key_left, MDFR_NONE, cmdid_move_left); bind(context, key_left, MDFR_NONE, cmdid_move_left);
bind(context, key_right, MDFR_NONE, cmdid_move_right); bind(context, key_right, MDFR_NONE, cmdid_move_right);
bind(context, key_del, MDFR_NONE, cmdid_delete); bind(context, key_del, MDFR_NONE, cmdid_delete);
@ -1070,18 +1164,18 @@ extern "C" GET_BINDING_DATA(get_bindings){
bind(context, key_home, MDFR_NONE, cmdid_seek_beginning_of_line); bind(context, key_home, MDFR_NONE, cmdid_seek_beginning_of_line);
bind(context, key_page_up, MDFR_NONE, cmdid_page_up); bind(context, key_page_up, MDFR_NONE, cmdid_page_up);
bind(context, key_page_down, MDFR_NONE, cmdid_page_down); bind(context, key_page_down, MDFR_NONE, cmdid_page_down);
bind(context, key_right, MDFR_CTRL, cmdid_seek_whitespace_right); bind(context, key_right, MDFR_CTRL, seek_whitespace_right);
bind(context, key_left, MDFR_CTRL, cmdid_seek_whitespace_left); bind(context, key_left, MDFR_CTRL, seek_whitespace_left);
bind(context, key_up, MDFR_CTRL, cmdid_seek_whitespace_up); bind(context, key_up, MDFR_CTRL, cmdid_seek_whitespace_up);
bind(context, key_down, MDFR_CTRL, cmdid_seek_whitespace_down); bind(context, key_down, MDFR_CTRL, cmdid_seek_whitespace_down);
bind(context, key_up, MDFR_ALT, move_up_10); bind(context, key_up, MDFR_ALT, move_up_10);
bind(context, key_down, MDFR_ALT, move_down_10); bind(context, key_down, MDFR_ALT, move_down_10);
bind(context, key_back, MDFR_CTRL, backspace_word); bind(context, key_back, MDFR_CTRL, backspace_word);
bind(context, key_back, MDFR_ALT, snipe_token_or_word); bind(context, key_back, MDFR_ALT, snipe_token_or_word);
bind(context, ' ', MDFR_CTRL, cmdid_set_mark); bind(context, ' ', MDFR_CTRL, cmdid_set_mark);
bind(context, 'm', MDFR_CTRL, cmdid_cursor_mark_swap); bind(context, 'm', MDFR_CTRL, cmdid_cursor_mark_swap);
bind(context, 'c', MDFR_CTRL, cmdid_copy); bind(context, 'c', MDFR_CTRL, cmdid_copy);
@ -1099,31 +1193,31 @@ extern "C" GET_BINDING_DATA(get_bindings){
bind(context, 'u', MDFR_CTRL, cmdid_to_uppercase); bind(context, 'u', MDFR_CTRL, cmdid_to_uppercase);
bind(context, 'j', MDFR_CTRL, cmdid_to_lowercase); bind(context, 'j', MDFR_CTRL, cmdid_to_lowercase);
bind(context, '?', MDFR_CTRL, cmdid_toggle_show_whitespace); bind(context, '?', MDFR_CTRL, cmdid_toggle_show_whitespace);
bind(context, '~', MDFR_CTRL, cmdid_clean_all_lines); bind(context, '~', MDFR_CTRL, cmdid_clean_all_lines);
bind(context, '1', MDFR_CTRL, cmdid_eol_dosify); bind(context, '1', MDFR_CTRL, cmdid_eol_dosify);
bind(context, '!', MDFR_CTRL, cmdid_eol_nixify); bind(context, '!', MDFR_CTRL, cmdid_eol_nixify);
bind(context, 'f', MDFR_CTRL, search); bind(context, 'f', MDFR_CTRL, search);
bind(context, 'r', MDFR_CTRL, reverse_search); bind(context, 'r', MDFR_CTRL, reverse_search);
bind(context, 'g', MDFR_CTRL, goto_line); bind(context, 'g', MDFR_CTRL, goto_line);
bind(context, 'q', MDFR_CTRL, query_replace); bind(context, 'q', MDFR_CTRL, query_replace);
bind(context, 'a', MDFR_CTRL, replace_in_range); bind(context, 'a', MDFR_CTRL, replace_in_range);
bind(context, 's', MDFR_ALT, rewrite_as_single_caps); bind(context, 's', MDFR_ALT, rewrite_as_single_caps);
bind(context, 'K', MDFR_CTRL, cmdid_kill_buffer); bind(context, 'K', MDFR_CTRL, cmdid_kill_buffer);
bind(context, 'O', MDFR_CTRL, cmdid_reopen); bind(context, 'O', MDFR_CTRL, cmdid_reopen);
bind(context, 'w', MDFR_CTRL, cmdid_interactive_save_as); bind(context, 'w', MDFR_CTRL, cmdid_interactive_save_as);
bind(context, 's', MDFR_CTRL, cmdid_save); bind(context, 's', MDFR_CTRL, cmdid_save);
bind(context, '\n', MDFR_SHIFT, write_and_auto_tab); bind(context, '\n', MDFR_SHIFT, write_and_auto_tab);
bind(context, ' ', MDFR_SHIFT, cmdid_write_character); bind(context, ' ', MDFR_SHIFT, cmdid_write_character);
end_map(context); end_map(context);
#endif #endif
end_bind_helper(context); end_bind_helper(context);
return context->write_total; return context->write_total;
} }

View File

@ -154,28 +154,18 @@ typedef struct File_List{
int block_size; int block_size;
} File_List; } File_List;
#define MDFR_NONE 0 #define MDFR_NONE 0x0
#define MDFR_CTRL 1 #define MDFR_CTRL 0x1
#define MDFR_ALT 2 #define MDFR_ALT 0x2
#define MDFR_SHIFT 4 #define MDFR_SHIFT 0x4
enum Command_ID{ enum Command_ID{
cmdid_null, cmdid_null,
cmdid_write_character, cmdid_write_character,
cmdid_seek_left, cmdid_seek_left,
cmdid_seek_right, cmdid_seek_right,
cmdid_seek_whitespace_right,
cmdid_seek_whitespace_left,
cmdid_seek_whitespace_up, cmdid_seek_whitespace_up,
cmdid_seek_whitespace_down, cmdid_seek_whitespace_down,
cmdid_seek_token_left,
cmdid_seek_token_right,
cmdid_seek_white_or_token_left,
cmdid_seek_white_or_token_right,
cmdid_seek_alphanumeric_left,
cmdid_seek_alphanumeric_right,
cmdid_seek_alphanumeric_or_camel_left,
cmdid_seek_alphanumeric_or_camel_right,
cmdid_word_complete, cmdid_word_complete,
cmdid_set_mark, cmdid_set_mark,
cmdid_copy, cmdid_copy,
@ -206,8 +196,6 @@ enum Command_ID{
cmdid_eol_dosify, cmdid_eol_dosify,
cmdid_eol_nixify, cmdid_eol_nixify,
cmdid_auto_tab_range, cmdid_auto_tab_range,
cmdid_auto_tab_line_at_cursor,
cmdid_auto_tab_whole_file,
cmdid_open_panel_vsplit, cmdid_open_panel_vsplit,
cmdid_open_panel_hsplit, cmdid_open_panel_hsplit,
cmdid_close_panel, cmdid_close_panel,
@ -255,6 +243,7 @@ enum Param_ID{
enum Hook_ID{ enum Hook_ID{
hook_start, hook_start,
hook_open_file, hook_open_file,
hook_frame,
// never below this // never below this
hook_type_count hook_type_count
}; };
@ -328,7 +317,7 @@ struct Theme_Color{
#define GET_BINDING_DATA(name) int name(void *data, int size) #define GET_BINDING_DATA(name) int name(void *data, int size)
#define CUSTOM_COMMAND_SIG(name) void name(struct Application_Links *app) #define CUSTOM_COMMAND_SIG(name) void name(struct Application_Links *app)
#define HOOK_SIG(name) void name(struct Application_Links *app) #define HOOK_SIG(name) int name(struct Application_Links *app)
#define SCROLL_RULE_SIG(name) int name(float target_x, float target_y, float *scroll_x, float *scroll_y, int view_id, int is_new_target) #define SCROLL_RULE_SIG(name) int name(float target_x, float target_y, float *scroll_x, float *scroll_y, int view_id, int is_new_target)
extern "C"{ extern "C"{
@ -539,8 +528,17 @@ struct Application_Links{
void *cmd_context; void *cmd_context;
}; };
#define _GET_VERSION_SIG(n) int n(int maj, int min, int patch)
typedef _GET_VERSION_SIG(_Get_Version_Function);
extern "C" _GET_VERSION_SIG(get_alpha_4coder_version){
int result = (maj == MAJOR && min == MINOR && patch == PATCH);
return(result);
}
struct Custom_API{ struct Custom_API{
Get_Binding_Data_Function *get_bindings; Get_Binding_Data_Function *get_bindings;
_Get_Version_Function *get_alpha_4coder_version;
}; };
// NOTE(allen): definitions for the buffer that communicates to 4ed.exe // NOTE(allen): definitions for the buffer that communicates to 4ed.exe
@ -587,5 +585,3 @@ struct Binding_Unit{
} hook; } hook;
}; };
}; };

View File

@ -153,7 +153,7 @@ inherit_map(Bind_Helper *helper, int mapid){
} }
inline void inline void
set_hook(Bind_Helper *helper, int hook_id, Custom_Command_Function *func){ set_hook(Bind_Helper *helper, int hook_id, Hook_Function *func){
Binding_Unit unit; Binding_Unit unit;
unit.type = unit_hook; unit.type = unit_hook;
unit.hook.hook_id = hook_id; unit.hook.hook_id = hook_id;

View File

@ -1,3 +1,15 @@
#define MAJOR 3 #define MAJOR 4
#define MINOR 4 #define MINOR 0
#define PATCH 5 #define PATCH 0
#define VN__(a,b,c) #a"."#b"."#c
#define VN_(a,b,c) VN__(a,b,c)
#define VERSION_NUMBER VN_(MAJOR,MINOR,PATCH)
#define VERSION_STRING "alpha " VERSION_NUMBER
#ifdef FRED_SUPER
#define VERSION_TYPE " super!"
#else
#define VERSION_TYPE
#endif
#define VERSION VERSION_STRING VERSION_TYPE

272
4ed.cpp
View File

@ -55,7 +55,7 @@ struct Complete_State{
}; };
struct Command_Data{ struct Command_Data{
App_Models *models; Models *models;
struct App_Vars *vars; struct App_Vars *vars;
System_Functions *system; System_Functions *system;
Exchange *exchange; Exchange *exchange;
@ -71,7 +71,7 @@ struct Command_Data{
}; };
struct App_Vars{ struct App_Vars{
App_Models models; Models models;
CLI_List cli_processes; CLI_List cli_processes;
@ -88,7 +88,7 @@ struct App_Vars{
}; };
internal i32 internal i32
app_get_or_add_map_index(App_Models *models, i32 mapid){ app_get_or_add_map_index(Models *models, i32 mapid){
i32 result; i32 result;
i32 user_map_count = models->user_map_count; i32 user_map_count = models->user_map_count;
i32 *map_id_table = models->map_id_table; i32 *map_id_table = models->map_id_table;
@ -103,7 +103,7 @@ app_get_or_add_map_index(App_Models *models, i32 mapid){
} }
internal i32 internal i32
app_get_map_index(App_Models *models, i32 mapid){ app_get_map_index(Models *models, i32 mapid){
i32 result; i32 result;
i32 user_map_count = models->user_map_count; i32 user_map_count = models->user_map_count;
i32 *map_id_table = models->map_id_table; i32 *map_id_table = models->map_id_table;
@ -118,7 +118,7 @@ app_get_map_index(App_Models *models, i32 mapid){
} }
internal Command_Map* internal Command_Map*
app_get_map(App_Models *models, i32 mapid){ app_get_map(Models *models, i32 mapid){
Command_Map *map = 0; Command_Map *map = 0;
if (mapid < mapid_global) map = models->user_maps + mapid; if (mapid < mapid_global) map = models->user_maps + mapid;
else if (mapid == mapid_global) map = &models->map_top; else if (mapid == mapid_global) map = &models->map_top;
@ -130,7 +130,7 @@ app_get_map(App_Models *models, i32 mapid){
globalvar Application_Links app_links; globalvar Application_Links app_links;
#define USE_MODELS(n) App_Models *n = command->models #define USE_MODELS(n) Models *n = command->models
#define USE_VARS(n) App_Vars *n = command->vars #define USE_VARS(n) App_Vars *n = command->vars
#define USE_PANEL(n) Panel *n = command->panel #define USE_PANEL(n) Panel *n = command->panel
#define USE_VIEW(n) View *n = command->view #define USE_VIEW(n) View *n = command->view
@ -188,7 +188,7 @@ param_stack_end(Partition *part){
internal View* internal View*
panel_make_empty(System_Functions *system, Exchange *exchange, App_Vars *vars, Panel *panel){ panel_make_empty(System_Functions *system, Exchange *exchange, App_Vars *vars, Panel *panel){
App_Models *models = &vars->models; Models *models = &vars->models;
View_And_ID new_view; View_And_ID new_view;
Assert(panel->view == 0); Assert(panel->view == 0);
@ -883,38 +883,6 @@ struct App_Open_File_Result{
b32 is_new; b32 is_new;
}; };
internal App_Open_File_Result
app_open_file_background(App_Vars *vars, Exchange *exchange, Working_Set *working_set, String filename){
Get_File_Result file;
i32 file_id;
App_Open_File_Result result = {};
result.file = working_set_contains(working_set, filename);
if (result.file == 0){
result.is_new = 1;
file = working_set_get_available_file(working_set);
if (file.file){
result.file = file.file;
file_id = exchange_request_file(exchange, filename.str, filename.size);
if (file_id){
file_init_strings(result.file);
file_set_name(working_set, result.file, filename.str);
file_set_to_loading(result.file);
table_add(&working_set->table, result.file->name.source_path, file.index);
result.sys_id = file_id;
result.file_index = file.index;
}
else{
working_set_free_file(working_set, file.file);
file.file = 0;
}
}
}
return(result);
}
COMMAND_DECL(interactive_open){ COMMAND_DECL(interactive_open){
ProfileMomentFunction(); ProfileMomentFunction();
USE_MODELS(models); USE_MODELS(models);
@ -964,7 +932,7 @@ COMMAND_DECL(interactive_open){
internal void internal void
view_file_in_panel(Command_Data *cmd, Panel *panel, Editing_File *file){ view_file_in_panel(Command_Data *cmd, Panel *panel, Editing_File *file){
System_Functions *system = cmd->system; System_Functions *system = cmd->system;
App_Models *models = cmd->models; Models *models = cmd->models;
Partition old_part; Partition old_part;
Temp_Memory temp; Temp_Memory temp;
@ -1126,15 +1094,13 @@ COMMAND_DECL(kill_buffer){
} }
if (buffer_id != 0){ if (buffer_id != 0){
if (buffer_id > 0 && buffer_id < models->working_set.file_count){ file = working_set_get_file(&models->working_set, buffer_id, 1).file;
file = working_set_get_file(&models->working_set, buffer_id, 1).file; if (file){
if (file){ delayed_kill(delay, file);
delayed_kill(delay, file->name.source_path);
}
} }
} }
else if (file){ else if (file){
delayed_try_kill(delay, file->name.live_name, view->panel); delayed_try_kill(delay, file, view->panel);
} }
} }
@ -1290,7 +1256,7 @@ COMMAND_DECL(auto_tab_range){
} }
} }
if (file->state.token_stack.tokens && file->state.tokens_complete){ if (file->state.token_stack.tokens && file->state.tokens_complete && !file->state.still_lexing){
Range range = make_range(view->cursor.pos, view->mark); Range range = make_range(view->cursor.pos, view->mark);
if (start_set) range.start = r_start; if (start_set) range.start = r_start;
if (end_set) range.end = r_end; if (end_set) range.end = r_end;
@ -1298,42 +1264,6 @@ COMMAND_DECL(auto_tab_range){
} }
} }
COMMAND_DECL(auto_tab_line_at_cursor){
ProfileMomentFunction();
USE_MODELS(models);
REQ_OPEN_VIEW(view);
REQ_FILE(file, view);
int clear_blank_lines = 0;
Command_Parameter *end = param_stack_end(&command->part);
Command_Parameter *param = param_stack_first(&command->part, end);
for (; param < end; param = param_next(param, end)){
int p = dynamic_to_int(&param->param.param);
switch (p){
case par_clear_blank_lines:
clear_blank_lines = dynamic_to_bool(&param->param.value);
break;
}
}
if (file->state.token_stack.tokens && file->state.tokens_complete){
i32 pos = view->cursor.pos;
view_auto_tab_tokens(system, models, view, pos, pos, clear_blank_lines);
}
}
COMMAND_DECL(auto_tab_whole_file){
ProfileMomentFunction();
USE_MODELS(models);
REQ_OPEN_VIEW(view);
REQ_FILE(file, view);
if (file->state.token_stack.tokens && file->state.tokens_complete){
view_auto_tab_tokens(system, models, view, 0, buffer_size(&file->state.buffer), 1);
}
}
COMMAND_DECL(open_panel_vsplit){ COMMAND_DECL(open_panel_vsplit){
ProfileMomentFunction(); ProfileMomentFunction();
USE_VARS(vars); USE_VARS(vars);
@ -2091,7 +2021,7 @@ extern "C"{
GET_PARAMETER_BUFFER_SIG(external_get_parameter_buffer){ GET_PARAMETER_BUFFER_SIG(external_get_parameter_buffer){
Command_Data *cmd = (Command_Data*)app->cmd_context; Command_Data *cmd = (Command_Data*)app->cmd_context;
App_Models *models = cmd->models; Models *models = cmd->models;
Buffer_Summary buffer = {}; Buffer_Summary buffer = {};
if (param_index >= 0 && param_index < models->buffer_param_count){ if (param_index >= 0 && param_index < models->buffer_param_count){
@ -2153,7 +2083,7 @@ extern "C"{
BUFFER_SEEK_STRING_SIG(external_buffer_seek_string){ BUFFER_SEEK_STRING_SIG(external_buffer_seek_string){
Command_Data *cmd = (Command_Data*)app->cmd_context; Command_Data *cmd = (Command_Data*)app->cmd_context;
App_Models *models; Models *models;
Editing_File *file; Editing_File *file;
Working_Set *working_set; Working_Set *working_set;
Partition *part; Partition *part;
@ -2226,7 +2156,7 @@ extern "C"{
Editing_File *file; Editing_File *file;
Working_Set *working_set; Working_Set *working_set;
App_Models *models; Models *models;
int result = 0; int result = 0;
int size; int size;
@ -2435,23 +2365,29 @@ extern "C"{
View *vptr; View *vptr;
Get_File_Result file; Get_File_Result file;
Working_Set *working_set; Working_Set *working_set;
App_Models *models; Models *models;
int result = 0; int result = 0;
int view_id;
if (view->exists){ if (view->exists){
models = cmd->models; models = cmd->models;
live_set = cmd->live_set; live_set = cmd->live_set;
vptr = live_set->views + view->view_id; view_id = view->view_id - 1;
working_set = &models->working_set; if (view_id >= 0 && view_id < live_set->max){
file = working_set_get_file(working_set, buffer_id, 1); vptr = live_set->views + view_id;
working_set = &models->working_set;
file = working_set_get_file(working_set, buffer_id, 1);
if (file.file){ if (file.file){
result = 1; result = 1;
view_set_file(vptr, file.file, models, if (file.file != vptr->file){
cmd->system, models->hooks[hook_open_file], &app_links); view_set_file(vptr, file.file, models,
cmd->system, models->hooks[hook_open_file], &app_links);
}
}
fill_view_summary(view, vptr, live_set, working_set);
} }
fill_view_summary(view, vptr, live_set, working_set);
} }
return(result); return(result);
@ -2647,18 +2583,8 @@ setup_command_table(){
SET(write_character); SET(write_character);
SET(seek_left); SET(seek_left);
SET(seek_right); SET(seek_right);
SET(seek_whitespace_right);
SET(seek_whitespace_left);
SET(seek_whitespace_up); SET(seek_whitespace_up);
SET(seek_whitespace_down); SET(seek_whitespace_down);
SET(seek_token_left);
SET(seek_token_right);
SET(seek_white_or_token_right);
SET(seek_white_or_token_left);
SET(seek_alphanumeric_right);
SET(seek_alphanumeric_left);
SET(seek_alphanumeric_or_camel_right);
SET(seek_alphanumeric_or_camel_left);
SET(word_complete); SET(word_complete);
SET(set_mark); SET(set_mark);
SET(copy); SET(copy);
@ -2688,8 +2614,6 @@ setup_command_table(){
SET(eol_dosify); SET(eol_dosify);
SET(eol_nixify); SET(eol_nixify);
SET(auto_tab_range); SET(auto_tab_range);
SET(auto_tab_line_at_cursor);
SET(auto_tab_whole_file);
SET(open_panel_vsplit); SET(open_panel_vsplit);
SET(open_panel_hsplit); SET(open_panel_hsplit);
SET(close_panel); SET(close_panel);
@ -2715,7 +2639,7 @@ setup_command_table(){
// App Functions // App Functions
internal void internal void
app_hardcode_styles(App_Models *models){ app_hardcode_styles(Models *models){
Interactive_Style file_info_style; Interactive_Style file_info_style;
Style *styles, *style; Style *styles, *style;
styles = models->styles.styles; styles = models->styles.styles;
@ -3120,7 +3044,7 @@ extern "C" SCROLL_RULE_SIG(fallback_scroll_rule){
App_Init_Sig(app_init){ App_Init_Sig(app_init){
App_Vars *vars; App_Vars *vars;
App_Models *models; Models *models;
Partition *partition; Partition *partition;
Panel *panels, *panel; Panel *panels, *panel;
Panel_Divider *dividers, *div; Panel_Divider *dividers, *div;
@ -3450,13 +3374,45 @@ App_Init_Sig(app_init){
models->buffer_param_indices = push_array(partition, i32, models->buffer_param_max); models->buffer_param_indices = push_array(partition, i32, models->buffer_param_max);
} }
internal App_Open_File_Result
app_open_file_background(App_Vars *vars, Exchange *exchange, Working_Set *working_set, String filename){
Get_File_Result file;
i32 file_id;
App_Open_File_Result result = {};
result.file = working_set_contains(working_set, filename);
if (result.file == 0){
result.is_new = 1;
file = working_set_get_available_file(working_set);
if (file.file){
result.file = file.file;
file_id = exchange_request_file(exchange, filename.str, filename.size);
if (file_id){
file_init_strings(result.file);
file_set_name(working_set, result.file, filename.str);
file_set_to_loading(result.file);
table_add(&working_set->table, result.file->name.source_path, file.index);
result.sys_id = file_id;
result.file_index = file.index;
}
else{
working_set_free_file(working_set, file.file);
file.file = 0;
}
}
}
return(result);
}
App_Step_Sig(app_step){ App_Step_Sig(app_step){
ProfileStart(OS_syncing); ProfileStart(OS_syncing);
Application_Step_Result app_result = *result; Application_Step_Result app_result = *result;
app_result.redraw = force_redraw; app_result.redraw = force_redraw;
App_Vars *vars = (App_Vars*)memory->vars_memory; App_Vars *vars = (App_Vars*)memory->vars_memory;
App_Models *models = &vars->models; Models *models = &vars->models;
target->partition = &models->mem.part; target->partition = &models->mem.part;
if (first_step || !time_step){ if (first_step || !time_step){
@ -3715,7 +3671,7 @@ App_Step_Sig(app_step){
} }
} }
ProfileEnd(prepare_commands); ProfileEnd(prepare_commands);
// NOTE(allen): process the command_coroutine if it is unfinished // NOTE(allen): process the command_coroutine if it is unfinished
ProfileStart(command_coroutine); ProfileStart(command_coroutine);
b8 consumed_input[6] = {0}; b8 consumed_input[6] = {0};
@ -3844,7 +3800,15 @@ App_Step_Sig(app_step){
update_command_data(vars, cmd); update_command_data(vars, cmd);
ProfileEnd(command_coroutine); ProfileEnd(command_coroutine);
ProfileStart(frame_hook);
if (models->hooks[hook_frame]){
if ((models->hooks[hook_frame])(&app_links)){
app_result.redraw = 1;
}
}
ProfileStart(frame_hook);
// NOTE(allen): pass raw input to the panels // NOTE(allen): pass raw input to the panels
ProfileStart(step); ProfileStart(step);
@ -4191,17 +4155,53 @@ App_Step_Sig(app_step){
// TODO(allen): Paramter checking in each DACT case. // TODO(allen): Paramter checking in each DACT case.
switch (act->type){ switch (act->type){
case DACT_OPEN: case DACT_TOUCH_FILE:
{ {
App_Open_File_Result result; if (file){
Assert(!file->state.is_dummy);
dll_remove(&file->node);
dll_insert(&models->working_set.used_sentinel, &file->node);
}
}break;
result = app_open_file_background(vars, exchange, working_set, string); case DACT_OPEN:
case DACT_OPEN_BACKGROUND:
{
App_Open_File_Result result = {};
{
String filename = string;
Get_File_Result file;
i32 file_id;
result.file = working_set_contains(working_set, filename);
if (result.file == 0){
result.is_new = 1;
file = working_set_get_available_file(working_set);
if (file.file){
result.file = file.file;
file_id = exchange_request_file(exchange, filename.str, filename.size);
if (file_id){
file_init_strings(result.file);
file_set_name(working_set, result.file, filename.str);
file_set_to_loading(result.file);
table_add(&working_set->table, result.file->name.source_path, file.index);
result.sys_id = file_id;
result.file_index = file.index;
}
else{
working_set_free_file(working_set, file.file);
file.file = 0;
}
}
}
}
if (result.is_new){ if (result.is_new){
if (result.file){ if (result.file){
if (result.sys_id){ if (result.sys_id){
Sys_App_Binding *binding = app_push_file_binding(vars, result.sys_id, result.file_index); Sys_App_Binding *binding = app_push_file_binding(vars, result.sys_id, result.file_index);
binding->success = SysAppCreateView; binding->success = (act->type == DACT_OPEN) ? SysAppCreateView : 0;
binding->fail = 0; binding->fail = 0;
binding->panel = panel; binding->panel = panel;
} }
@ -4211,27 +4211,10 @@ App_Step_Sig(app_step){
} }
} }
else{ else{
Assert(result.file); if (act->type == DACT_OPEN){
if (!result.file->state.is_loading){ Assert(result.file);
view_file_in_panel(cmd, panel, result.file); if (!result.file->state.is_loading){
} view_file_in_panel(cmd, panel, result.file);
}
}break;
case DACT_OPEN_BACKGROUND:
{
App_Open_File_Result result;
result = app_open_file_background(vars, exchange, working_set, string);
if (result.is_new){
if (result.file){
if (result.sys_id){
Sys_App_Binding *binding = app_push_file_binding(vars, result.sys_id, result.file_index);
binding->success = 0;
binding->fail = 0;
binding->panel = panel;
}
else{
delayed_action_repush(&models->delay2, act);
} }
} }
} }
@ -4325,6 +4308,7 @@ App_Step_Sig(app_step){
case DACT_SWITCH: case DACT_SWITCH:
{ {
Editing_File *file = working_set_lookup_file(working_set, string); Editing_File *file = working_set_lookup_file(working_set, string);
if (file){ if (file){
View *view = panel->view; View *view = panel->view;
@ -4336,18 +4320,15 @@ App_Step_Sig(app_step){
case DACT_KILL: case DACT_KILL:
{ {
Editing_File *file = working_set_lookup_file(working_set, string);
if (file){ if (file){
table_remove(&working_set->table, file->name.source_path); table_remove(&working_set->table, file->name.source_path);
kill_file(system, exchange, models, file); kill_file(system, exchange, models, file,
models->hooks[hook_open_file], &app_links);
} }
}break; }break;
case DACT_TRY_KILL: case DACT_TRY_KILL:
{ {
Editing_File *file = 0;
file = working_set_lookup_file(working_set, string);
View *view = 0; View *view = 0;
if (panel){ if (panel){
view = panel->view; view = panel->view;
@ -4356,8 +4337,6 @@ App_Step_Sig(app_step){
view = (models->layout.panels + models->layout.active_panel)->view; view = (models->layout.panels + models->layout.active_panel)->view;
} }
Assert(view);
if (file){ if (file){
if (buffer_needs_save(file)){ if (buffer_needs_save(file)){
view_show_interactive(system, view, &models->map_ui, view_show_interactive(system, view, &models->map_ui,
@ -4366,7 +4345,8 @@ App_Step_Sig(app_step){
} }
else{ else{
table_remove(&working_set->table, file->name.source_path); table_remove(&working_set->table, file->name.source_path);
kill_file(system, exchange, models, file); kill_file(system, exchange, models, file,
models->hooks[hook_open_file], &app_links);
} }
} }
}break; }break;

View File

@ -21,7 +21,7 @@ struct App_Settings{
b32 lctrl_lalt_is_altgr; b32 lctrl_lalt_is_altgr;
}; };
struct App_Models{ struct Models{
Mem_Options mem; Mem_Options mem;
App_Settings settings; App_Settings settings;
@ -37,7 +37,7 @@ struct App_Models{
Coroutine *command_coroutine; Coroutine *command_coroutine;
u32 command_coroutine_flags[2]; u32 command_coroutine_flags[2];
Custom_Command_Function *hooks[hook_type_count]; Hook_Function *hooks[hook_type_count];
i32 *buffer_param_indices; i32 *buffer_param_indices;
i32 buffer_param_count, buffer_param_max; i32 buffer_param_count, buffer_param_max;

View File

@ -8,8 +8,7 @@
*/ */
// TOP // TOP
#include "4ed_version.h"
#include "4ed_config.h" #include "4ed_config.h"
#define BUFFER_EXPERIMENT_SCALPEL 0 #define BUFFER_EXPERIMENT_SCALPEL 0

View File

@ -8,6 +8,7 @@ enum Action_Type{
DACT_SWITCH, DACT_SWITCH,
DACT_TRY_KILL, DACT_TRY_KILL,
DACT_KILL, DACT_KILL,
DACT_TOUCH_FILE,
}; };
struct Delayed_Action{ struct Delayed_Action{
@ -48,6 +49,14 @@ delayed_action_(Delay *delay, Action_Type type){
return(result); return(result);
} }
inline Delayed_Action*
delayed_action_(Delay *delay, Action_Type type, String string){
Delayed_Action *result;
result = delayed_action_(delay, type);
result->string = str_alloc_copy(delay->general, string);
return(result);
}
inline Delayed_Action* inline Delayed_Action*
delayed_action_(Delay *delay, Action_Type type, Panel* panel){ delayed_action_(Delay *delay, Action_Type type, Panel* panel){
Delayed_Action *result; Delayed_Action *result;
@ -57,10 +66,19 @@ delayed_action_(Delay *delay, Action_Type type, Panel* panel){
} }
inline Delayed_Action* inline Delayed_Action*
delayed_action_(Delay *delay, Action_Type type, String string){ delayed_action_(Delay *delay, Action_Type type, Editing_File* file){
Delayed_Action *result; Delayed_Action *result;
result = delayed_action_(delay, type); result = delayed_action_(delay, type);
result->string = str_alloc_copy(delay->general, string); result->file = file;
return(result);
}
inline Delayed_Action*
delayed_action_(Delay *delay, Action_Type type, Editing_File* file, Panel* panel){
Delayed_Action *result;
result = delayed_action_(delay, type);
result->file = file;
result->panel = panel;
return(result); return(result);
} }
@ -110,3 +128,4 @@ delayed_action_repush(Delay *delay, Delayed_Action *act){
#define delayed_switch(delay, ...) delayed_action_(delay, DACT_SWITCH, __VA_ARGS__) #define delayed_switch(delay, ...) delayed_action_(delay, DACT_SWITCH, __VA_ARGS__)
#define delayed_try_kill(delay, ...) delayed_action_(delay, DACT_TRY_KILL, __VA_ARGS__) #define delayed_try_kill(delay, ...) delayed_action_(delay, DACT_TRY_KILL, __VA_ARGS__)
#define delayed_kill(delay, ...) delayed_action_(delay, DACT_KILL, __VA_ARGS__) #define delayed_kill(delay, ...) delayed_action_(delay, DACT_KILL, __VA_ARGS__)
#define delayed_touch_file(delay, ...) delayed_action_(delay, DACT_TOUCH_FILE, __VA_ARGS__)

View File

@ -9,25 +9,6 @@
// TOP // TOP
struct Interactive_Bar{
f32 pos_x, pos_y;
f32 text_shift_x, text_shift_y;
i32_Rect rect;
i16 font_id;
};
internal void
intbar_draw_string(Render_Target *target, Interactive_Bar *bar,
String str, u32 char_color){
i16 font_id = bar->font_id;
draw_string(target, font_id, str,
(i32)(bar->pos_x + bar->text_shift_x),
(i32)(bar->pos_y + bar->text_shift_y),
char_color);
bar->pos_x += font_string_width(target, font_id, str);
}
#include "buffer/4coder_shared.cpp" #include "buffer/4coder_shared.cpp"
#if BUFFER_EXPERIMENT_SCALPEL == 0 #if BUFFER_EXPERIMENT_SCALPEL == 0
@ -360,6 +341,8 @@ internal b32
filename_match(String query, Absolutes *absolutes, String filename, b32 case_sensitive){ filename_match(String query, Absolutes *absolutes, String filename, b32 case_sensitive){
b32 result; b32 result;
result = (query.size == 0); result = (query.size == 0);
replace_char(query, '\\', '/');
replace_char(filename, '\\', '/');
if (!result) result = wildcard_match(absolutes, filename, case_sensitive); if (!result) result = wildcard_match(absolutes, filename, case_sensitive);
return result; return result;
} }
@ -372,6 +355,8 @@ hot_directory_first_match(Hot_Directory *hot_directory,
b32 case_sensitive){ b32 case_sensitive){
Hot_Directory_Match result = {}; Hot_Directory_Match result = {};
replace_char(str, '\\', '/');
Absolutes absolutes; Absolutes absolutes;
if (!exact_match) if (!exact_match)
get_absolutes(str, &absolutes, 1, 1); get_absolutes(str, &absolutes, 1, 1);
@ -442,6 +427,7 @@ inline Editing_File*
working_set_contains(Working_Set *working, String filename){ working_set_contains(Working_Set *working, String filename){
Editing_File *result = 0; Editing_File *result = 0;
i32 id; i32 id;
replace_char(filename, '\\', '/');
if (table_find(&working->table, filename, &id)){ if (table_find(&working->table, filename, &id)){
if (id >= 0 && id <= working->file_max){ if (id >= 0 && id <= working->file_max){
result = working->files + id; result = working->files + id;
@ -450,10 +436,24 @@ working_set_contains(Working_Set *working, String filename){
return (result); return (result);
} }
// TODO(allen): Find a way to choose an ordering for these so it picks better first options. // TODO(allen): Pick better first options.
internal Editing_File* internal Editing_File*
working_set_lookup_file(Working_Set *working_set, String string){ working_set_lookup_file(Working_Set *working_set, String string){
Editing_File *file = working_set_contains(working_set, string); Editing_File *file = 0;
replace_char(string, '\\', '/');
{
File_Node *node, *used_nodes;
used_nodes = &working_set->used_sentinel;
for (dll_items(node, used_nodes)){
file = (Editing_File*)node;
if (string.size == 0 || match(string, file->name.live_name)){
break;
}
}
if (node == used_nodes) file = 0;
}
if (!file){ if (!file){
File_Node *node, *used_nodes; File_Node *node, *used_nodes;

View File

@ -67,7 +67,7 @@ struct View{
View *next, *prev; View *next, *prev;
b32 in_use; b32 in_use;
App_Models *models; Models *models;
Panel *panel; Panel *panel;
Command_Map *map; Command_Map *map;
@ -518,7 +518,7 @@ alloc_for_buffer(void *context, int *size){
} }
internal void internal void
file_create_from_string(System_Functions *system, App_Models *models, file_create_from_string(System_Functions *system, Models *models,
Editing_File *file, char *filename, String val, b8 read_only = 0){ Editing_File *file, char *filename, String val, b8 read_only = 0){
Font_Set *font_set = models->font_set; Font_Set *font_set = models->font_set;
@ -544,7 +544,11 @@ file_create_from_string(System_Functions *system, App_Models *models,
init_success = buffer_end_init(&init, part->base + part->pos, scratch_size); init_success = buffer_end_init(&init, part->base + part->pos, scratch_size);
AllowLocal(init_success); AllowLocal(init_success);
Assert(init_success); Assert(init_success);
if (buffer_size(&file->state.buffer) < val.size){
file->settings.dos_write_mode = 1;
}
file_init_strings(file); file_init_strings(file);
file_set_name(working_set, file, (char*)filename); file_set_name(working_set, file, (char*)filename);
@ -588,7 +592,7 @@ file_create_from_string(System_Functions *system, App_Models *models,
internal b32 internal b32
file_create_empty(System_Functions *system, file_create_empty(System_Functions *system,
App_Models *models, Editing_File *file, char *filename){ Models *models, Editing_File *file, char *filename){
file_create_from_string(system, models, file, filename, {}); file_create_from_string(system, models, file, filename, {});
return (1); return (1);
@ -596,7 +600,7 @@ file_create_empty(System_Functions *system,
internal b32 internal b32
file_create_read_only(System_Functions *system, file_create_read_only(System_Functions *system,
App_Models *models, Editing_File *file, char *filename){ Models *models, Editing_File *file, char *filename){
file_create_from_string(system, models, file, filename, {}, 1); file_create_from_string(system, models, file, filename, {}, 1);
return (1); return (1);
@ -1107,7 +1111,7 @@ file_post_history(General_Memory *general, Editing_File *file,
inline Full_Cursor inline Full_Cursor
view_compute_cursor_from_pos(View *view, i32 pos){ view_compute_cursor_from_pos(View *view, i32 pos){
Editing_File *file = view->file; Editing_File *file = view->file;
App_Models *models = view->models; Models *models = view->models;
Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font; Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font;
Full_Cursor result = {}; Full_Cursor result = {};
@ -1122,7 +1126,7 @@ view_compute_cursor_from_pos(View *view, i32 pos){
inline Full_Cursor inline Full_Cursor
view_compute_cursor_from_unwrapped_xy(View *view, f32 seek_x, f32 seek_y, b32 round_down = 0){ view_compute_cursor_from_unwrapped_xy(View *view, f32 seek_x, f32 seek_y, b32 round_down = 0){
Editing_File *file = view->file; Editing_File *file = view->file;
App_Models *models = view->models; Models *models = view->models;
Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font; Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font;
Full_Cursor result = {}; Full_Cursor result = {};
@ -1139,7 +1143,7 @@ view_compute_cursor_from_unwrapped_xy(View *view, f32 seek_x, f32 seek_y, b32 ro
internal Full_Cursor internal Full_Cursor
view_compute_cursor_from_wrapped_xy(View *view, f32 seek_x, f32 seek_y, b32 round_down = 0){ view_compute_cursor_from_wrapped_xy(View *view, f32 seek_x, f32 seek_y, b32 round_down = 0){
Editing_File *file = view->file; Editing_File *file = view->file;
App_Models *models = view->models; Models *models = view->models;
Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font; Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font;
Full_Cursor result = {}; Full_Cursor result = {};
@ -1156,7 +1160,7 @@ view_compute_cursor_from_wrapped_xy(View *view, f32 seek_x, f32 seek_y, b32 roun
internal Full_Cursor internal Full_Cursor
view_compute_cursor_from_line_pos(View *view, i32 line, i32 pos){ view_compute_cursor_from_line_pos(View *view, i32 line, i32 pos){
Editing_File *file = view->file; Editing_File *file = view->file;
App_Models *models = view->models; Models *models = view->models;
Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font; Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font;
Full_Cursor result = {}; Full_Cursor result = {};
@ -1257,18 +1261,21 @@ view_get_cursor_y(View *view){
internal void internal void
view_set_file( view_set_file(
// NOTE(allen): These parameters are always meaningful // NOTE(allen): These parameters are always meaningful
View *view, Editing_File *file, App_Models *models, View *view, Editing_File *file, Models *models,
// NOTE(allen): Necessary when file != 0 // NOTE(allen): Necessary when file != 0
System_Functions *system, Hook_Function *open_hook, Application_Links *app){ System_Functions *system, Hook_Function *open_hook, Application_Links *app,
// other
b32 set_vui = 1){
Font_Info *fnt_info; Font_Info *fnt_info;
// NOTE(allen): This is actually more like view_set_style right? // TODO(allen): This belongs somewhere else.
fnt_info = get_font_info(models->font_set, models->global_font.font_id); fnt_info = get_font_info(models->font_set, models->global_font.font_id);
view->font_advance = fnt_info->advance; view->font_advance = fnt_info->advance;
view->font_height = fnt_info->height; view->font_height = fnt_info->height;
// NOTE(allen): Stuff that doesn't assume file exists. // NOTE(allen): Stuff that doesn't assume file exists.
view->file = file; view->file = file;
view->cursor = {}; view->cursor = {};
@ -1296,10 +1303,13 @@ view_set_file(
file->settings.is_initialized = 1; file->settings.is_initialized = 1;
} }
} }
// TODO(allen): Fix this: if (set_vui){
view->ui_state = {}; // TODO(allen): Fix this! There should be a way to easily separate setting a file,
view->showing_ui = VUI_None; // and switching to file mode, so that they don't cross over eachother like this.
view->ui_state = {};
view->showing_ui = VUI_None;
}
} }
struct Relative_Scrolling{ struct Relative_Scrolling{
@ -1389,7 +1399,7 @@ file_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step
History_Mode history_mode){ History_Mode history_mode){
if (!file->state.undo.undo.edits) return; if (!file->state.undo.undo.edits) return;
General_Memory *general = &mem->general; General_Memory *general = &mem->general;
b32 can_merge = 0, do_merge = 0; b32 can_merge = 0, do_merge = 0;
switch (step.type){ switch (step.type){
case ED_NORMAL: case ED_NORMAL:
@ -1571,7 +1581,7 @@ file_edit_cursor_fix(System_Functions *system,
Partition *part, General_Memory *general, Partition *part, General_Memory *general,
Editing_File *file, Editing_Layout *layout, Editing_File *file, Editing_Layout *layout,
Cursor_Fix_Descriptor desc){ Cursor_Fix_Descriptor desc){
Full_Cursor temp_cursor; Full_Cursor temp_cursor;
Temp_Memory cursor_temp = begin_temp_memory(part); Temp_Memory cursor_temp = begin_temp_memory(part);
i32 cursor_max = layout->panel_max_count * 2; i32 cursor_max = layout->panel_max_count * 2;
@ -1579,11 +1589,11 @@ file_edit_cursor_fix(System_Functions *system,
f32 y_offset = 0, y_position = 0; f32 y_offset = 0, y_position = 0;
i32 cursor_count = 0; i32 cursor_count = 0;
View *view; View *view;
Panel *panel, *used_panels; Panel *panel, *used_panels;
used_panels = &layout->used_sentinel; used_panels = &layout->used_sentinel;
for (dll_items(panel, used_panels)){ for (dll_items(panel, used_panels)){
view = panel->view; view = panel->view;
if (view->file == file){ if (view->file == file){
@ -1606,14 +1616,14 @@ file_edit_cursor_fix(System_Functions *system,
desc.shift_amount + (desc.end - desc.start)); desc.shift_amount + (desc.end - desc.start));
} }
buffer_unsort_cursors(cursors, cursor_count); buffer_unsort_cursors(cursors, cursor_count);
cursor_count = 0; cursor_count = 0;
for (dll_items(panel, used_panels)){ for (dll_items(panel, used_panels)){
view = panel->view; view = panel->view;
if (view && view->file == file){ if (view && view->file == file){
view_cursor_move(view, cursors[cursor_count++].pos); view_cursor_move(view, cursors[cursor_count++].pos);
view->preferred_x = view_get_cursor_x(view); view->preferred_x = view_get_cursor_x(view);
view->mark = cursors[cursor_count++].pos + 1; view->mark = cursors[cursor_count++].pos + 1;
i32 new_scroll_i = cursors[cursor_count++].pos + 1; i32 new_scroll_i = cursors[cursor_count++].pos + 1;
if (view->scroll_i != new_scroll_i){ if (view->scroll_i != new_scroll_i){
@ -1635,20 +1645,20 @@ file_edit_cursor_fix(System_Functions *system,
} }
} }
} }
end_temp_memory(cursor_temp); end_temp_memory(cursor_temp);
} }
internal void internal void
file_do_single_edit(System_Functions *system, file_do_single_edit(System_Functions *system,
App_Models *models, Editing_File *file, Models *models, Editing_File *file,
Edit_Spec spec, History_Mode history_mode, b32 use_high_permission = 0){ Edit_Spec spec, History_Mode history_mode, b32 use_high_permission = 0){
ProfileMomentFunction(); ProfileMomentFunction();
if (!use_high_permission && file->settings.read_only) return; if (!use_high_permission && file->settings.read_only) return;
Mem_Options *mem = &models->mem; Mem_Options *mem = &models->mem;
Editing_Layout *layout = &models->layout; Editing_Layout *layout = &models->layout;
// NOTE(allen): fixing stuff beforewards???? // NOTE(allen): fixing stuff beforewards????
file_update_history_before_edit(mem, file, spec.step, spec.str, history_mode); file_update_history_before_edit(mem, file, spec.step, spec.str, history_mode);
file_pre_edit_maintenance(system, &mem->general, file); file_pre_edit_maintenance(system, &mem->general, file);
@ -1692,7 +1702,7 @@ file_do_single_edit(System_Functions *system,
Panel *panel, *used_panels; Panel *panel, *used_panels;
used_panels = &layout->used_sentinel; used_panels = &layout->used_sentinel;
for (dll_items(panel, used_panels)){ for (dll_items(panel, used_panels)){
View *view = panel->view; View *view = panel->view;
if (view->file == file){ if (view->file == file){
@ -1716,19 +1726,19 @@ file_do_single_edit(System_Functions *system,
} }
internal void internal void
file_do_white_batch_edit(System_Functions *system, App_Models *models, Editing_File *file, file_do_white_batch_edit(System_Functions *system, Models *models, Editing_File *file,
Edit_Spec spec, History_Mode history_mode, b32 use_high_permission = 0){ Edit_Spec spec, History_Mode history_mode, b32 use_high_permission = 0){
ProfileMomentFunction(); ProfileMomentFunction();
if (!use_high_permission && file->settings.read_only) return; if (!use_high_permission && file->settings.read_only) return;
Mem_Options *mem = &models->mem; Mem_Options *mem = &models->mem;
Editing_Layout *layout = &models->layout; Editing_Layout *layout = &models->layout;
// NOTE(allen): fixing stuff "beforewards"??? // NOTE(allen): fixing stuff "beforewards"???
Assert(spec.str == 0); Assert(spec.str == 0);
file_update_history_before_edit(mem, file, spec.step, 0, history_mode); file_update_history_before_edit(mem, file, spec.step, 0, history_mode);
file_pre_edit_maintenance(system, &mem->general, file); file_pre_edit_maintenance(system, &mem->general, file);
// NOTE(allen): actual text replacement // NOTE(allen): actual text replacement
General_Memory *general = &mem->general; General_Memory *general = &mem->general;
Partition *part = &mem->part; Partition *part = &mem->part;
@ -1772,7 +1782,7 @@ file_do_white_batch_edit(System_Functions *system, App_Models *models, Editing_F
file_edit_cursor_fix(system, part, general, file, layout, desc); file_edit_cursor_fix(system, part, general, file, layout, desc);
} }
// NOTE(allen): token fixing // NOTE(allen): token fixing
if (file->state.tokens_complete){ if (file->state.tokens_complete){
Cpp_Token_Stack tokens = file->state.token_stack; Cpp_Token_Stack tokens = file->state.token_stack;
@ -1803,7 +1813,7 @@ file_do_white_batch_edit(System_Functions *system, App_Models *models, Editing_F
} }
inline void inline void
file_replace_range(System_Functions *system, App_Models *models, Editing_File *file, file_replace_range(System_Functions *system, Models *models, Editing_File *file,
i32 start, i32 end, char *str, i32 len, i32 next_cursor, b32 use_high_permission = 0){ i32 start, i32 end, char *str, i32 len, i32 next_cursor, b32 use_high_permission = 0){
Edit_Spec spec = {}; Edit_Spec spec = {};
spec.step.type = ED_NORMAL; spec.step.type = ED_NORMAL;
@ -1817,7 +1827,7 @@ file_replace_range(System_Functions *system, App_Models *models, Editing_File *f
} }
inline void inline void
view_replace_range(System_Functions *system, App_Models *models, View *view, view_replace_range(System_Functions *system, Models *models, View *view,
i32 start, i32 end, char *str, i32 len, i32 next_cursor){ i32 start, i32 end, char *str, i32 len, i32 next_cursor){
file_replace_range(system, models, view->file, start, end, str, len, next_cursor); file_replace_range(system, models, view->file, start, end, str, len, next_cursor);
} }
@ -1835,10 +1845,10 @@ view_post_paste_effect(View *view, i32 ticks, i32 start, i32 size, u32 color){
internal void internal void
view_undo_redo(System_Functions *system, view_undo_redo(System_Functions *system,
App_Models *models, View *view, Models *models, View *view,
Edit_Stack *stack, Edit_Type expected_type){ Edit_Stack *stack, Edit_Type expected_type){
Editing_File *file = view->file; Editing_File *file = view->file;
if (stack->edit_count > 0){ if (stack->edit_count > 0){
Edit_Step step = stack->edits[stack->edit_count-1]; Edit_Step step = stack->edits[stack->edit_count-1];
@ -1868,12 +1878,12 @@ view_undo_redo(System_Functions *system,
} }
inline void inline void
view_undo(System_Functions *system, App_Models *models, View *view){ view_undo(System_Functions *system, Models *models, View *view){
view_undo_redo(system, models, view, &view->file->state.undo.undo, ED_UNDO); view_undo_redo(system, models, view, &view->file->state.undo.undo, ED_UNDO);
} }
inline void inline void
view_redo(System_Functions *system, App_Models *models, View *view){ view_redo(System_Functions *system, Models *models, View *view){
view_undo_redo(system, models, view, &view->file->state.undo.redo, ED_REDO); view_undo_redo(system, models, view, &view->file->state.undo.redo, ED_REDO);
} }
@ -1942,7 +1952,7 @@ file_dump_history(System_Functions *system, Mem_Options *mem, Editing_File *file
#endif #endif
internal void internal void
view_history_step(System_Functions *system, App_Models *models, View *view, History_Mode history_mode){ view_history_step(System_Functions *system, Models *models, View *view, History_Mode history_mode){
Assert(history_mode != hist_normal); Assert(history_mode != hist_normal);
Editing_File *file = view->file; Editing_File *file = view->file;
@ -2138,17 +2148,17 @@ file_compute_whitespace_edit(Mem_Options *mem, Editing_File *file, i32 cursor_po
} }
internal void internal void
view_clean_whitespace(System_Functions *system, App_Models *models, View *view){ view_clean_whitespace(System_Functions *system, Models *models, View *view){
Mem_Options *mem = &models->mem; Mem_Options *mem = &models->mem;
Editing_File *file = view->file; Editing_File *file = view->file;
Partition *part = &mem->part; Partition *part = &mem->part;
i32 line_count = file->state.buffer.line_count; i32 line_count = file->state.buffer.line_count;
i32 edit_max = line_count * 2; i32 edit_max = line_count * 2;
i32 edit_count = 0; i32 edit_count = 0;
Assert(file && !file->state.is_dummy); Assert(file && !file->state.is_dummy);
Temp_Memory temp = begin_temp_memory(part); Temp_Memory temp = begin_temp_memory(part);
Buffer_Edit *edits = push_array(part, Buffer_Edit, edit_max); Buffer_Edit *edits = push_array(part, Buffer_Edit, edit_max);
@ -2199,7 +2209,7 @@ view_clean_whitespace(System_Functions *system, App_Models *models, View *view){
internal void internal void
view_auto_tab_tokens(System_Functions *system, view_auto_tab_tokens(System_Functions *system,
App_Models *models, View *view, Models *models, View *view,
i32 start, i32 end, b32 empty_blank_lines){ i32 start, i32 end, b32 empty_blank_lines){
#if BUFFER_EXPERIMENT_SCALPEL <= 0 #if BUFFER_EXPERIMENT_SCALPEL <= 0
Editing_File *file = view->file; Editing_File *file = view->file;
@ -2575,9 +2585,9 @@ view_show_config(View *fview, Command_Map *gui_map){
inline void inline void
view_show_interactive(System_Functions *system, View *view, 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){
App_Models *models = view->models; Models *models = view->models;
view->ui_state = {}; view->ui_state = {};
view->map_for_file = view->map; view->map_for_file = view->map;
view->map = gui_map; view->map = gui_map;
@ -2595,12 +2605,13 @@ view_show_interactive(System_Functions *system, View *view, Command_Map *gui_map
} }
inline void inline void
view_show_theme(View *fview, Command_Map *gui_map){ view_show_theme(View *view, Command_Map *gui_map){
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->showing_ui = VUI_Theme; view->showing_ui = VUI_Theme;
fview->color_mode = CV_Mode_Library; view->color_mode = CV_Mode_Library;
view->color = super_color_create(0xFF000000);
} }
inline void inline void
@ -2617,30 +2628,34 @@ view_show_file(View *view, Command_Map *file_map){
internal void internal void
interactive_view_complete(View *view){ interactive_view_complete(View *view){
Models *models = view->models;
Panel *panel = view->panel; Panel *panel = view->panel;
App_Models *models = view->models; Editing_File *old_file = view->file;
Editing_File *file = 0;
switch (view->action){ switch (view->action){
case IAct_Open: case IAct_Open:
delayed_open(&models->delay1, models->hot_directory.string, panel); delayed_open(&models->delay1, models->hot_directory.string, panel);
delayed_touch_file(&models->delay1, old_file);
break; break;
case IAct_Save_As: case IAct_Save_As:
delayed_save_as(&models->delay1, models->hot_directory.string, panel); delayed_save_as(&models->delay1, models->hot_directory.string, panel);
file = view->file;
break; break;
case IAct_New: case IAct_New:
delayed_new(&models->delay1, models->hot_directory.string, panel); if (models->hot_directory.string.size > 0 &&
!char_is_slash(models->hot_directory.string.str[models->hot_directory.string.size-1])){
delayed_new(&models->delay1, models->hot_directory.string, panel);
}
break; break;
case IAct_Switch: case IAct_Switch:
delayed_switch(&models->delay1, view->dest, panel); delayed_switch(&models->delay1, view->dest, panel);
delayed_touch_file(&models->delay1, old_file);
break; break;
case IAct_Kill: case IAct_Kill:
delayed_try_kill(&models->delay1, view->dest, panel); delayed_try_kill(&models->delay1, view->dest, panel);
file = view->file;
break; break;
case IAct_Sure_To_Kill: case IAct_Sure_To_Kill:
@ -2649,7 +2664,8 @@ interactive_view_complete(View *view){
delayed_kill(&models->delay1, view->dest, panel); delayed_kill(&models->delay1, view->dest, panel);
break; break;
case 1:break; case 1:
break;
case 2: case 2:
// TODO(allen): This is fishy! What if the save doesn't happen this time around? // TODO(allen): This is fishy! What if the save doesn't happen this time around?
@ -2661,6 +2677,9 @@ interactive_view_complete(View *view){
break; break;
} }
view_show_file(view, 0); view_show_file(view, 0);
// TODO(allen): This is here to prevent the key press from being passed to the
// underlying file which is a giant pain.
view->file = 0; view->file = 0;
} }
@ -2677,9 +2696,9 @@ update_highlighting(View *view){
view->highlight = {}; view->highlight = {};
return; return;
} }
App_Models *models = view->models; Models *models = view->models;
Style *style = &models->style; Style *style = &models->style;
i32 pos = view_get_cursor_pos(file_view); i32 pos = view_get_cursor_pos(file_view);
char c = buffer_get_char(&file->state.buffer, pos); char c = buffer_get_char(&file->state.buffer, pos);
@ -2749,7 +2768,7 @@ internal b32
theme_library_shit(System_Functions *system, Exchange *exchange, theme_library_shit(System_Functions *system, Exchange *exchange,
View *view, UI_State *state, UI_Layout *layout){ View *view, UI_State *state, UI_Layout *layout){
App_Models *models = view->models; Models *models = view->models;
Mem_Options *mem = &models->mem; Mem_Options *mem = &models->mem;
i32 result = 0; i32 result = 0;
@ -2999,11 +3018,11 @@ theme_library_shit(System_Functions *system, Exchange *exchange,
} }
internal b32 internal b32
theme_adjusting_shit(View *view, UI_State *state, UI_Layout *layout){ theme_adjusting_shit(View *view, UI_State *state, UI_Layout *layout, Super_Color *color){
update_highlighting(view); update_highlighting(view);
App_Models *models = view->models; Models *models = view->models;
Style *style = &models->style; Style *style = &models->style;
i32 result = 0; i32 result = 0;
@ -3125,14 +3144,14 @@ theme_adjusting_shit(View *view, UI_State *state, UI_Layout *layout){
bar_style->pop2_color, bar_style->bar_color, bar_style->pop2_color, bar_style->bar_color,
"Bar Pop 2"); "Bar Pop 2");
view->color = ui.color; *color = ui.hover_color;
return result; return (result);
} }
internal b32 internal b32
theme_shit(System_Functions *system, Exchange *exchange, theme_shit(System_Functions *system, Exchange *exchange,
View *view, View *active, UI_State *state, UI_Layout *layout){ View *view, View *active, UI_State *state, UI_Layout *layout, Super_Color *color){
b32 result = 0; b32 result = 0;
if (view != active){ if (view != active){
@ -3152,7 +3171,7 @@ theme_shit(System_Functions *system, Exchange *exchange,
break; break;
case CV_Mode_Adjusting: case CV_Mode_Adjusting:
if (theme_adjusting_shit(view, state, layout)){ if (theme_adjusting_shit(view, state, layout, color)){
result = 1; result = 1;
} }
break; break;
@ -3167,8 +3186,8 @@ interactive_shit(System_Functions *system, View *view, UI_State *state, UI_Layou
b32 new_dir = 0; b32 new_dir = 0;
b32 complete = 0; b32 complete = 0;
App_Models *models = view->models; Models *models = view->models;
do_label(state, layout, view->query, 1.f); do_label(state, layout, view->query, 1.f);
b32 case_sensitive = 0; b32 case_sensitive = 0;
@ -3268,8 +3287,8 @@ menu_shit(View *view, UI_State *state, UI_Layout *layout){
internal void internal void
config_shit(View *view, UI_State *state, UI_Layout *layout){ config_shit(View *view, UI_State *state, UI_Layout *layout){
i32 id = 0; i32 id = 0;
App_Models *models = view->models; Models *models = view->models;
do_label(state, layout, literal("Config"), 2.f); do_label(state, layout, literal("Config"), 2.f);
if (do_checkbox_list_option(++id, state, layout, make_lit_string("Left Ctrl + Left Alt = AltGr"), if (do_checkbox_list_option(++id, state, layout, make_lit_string("Left Ctrl + Left Alt = AltGr"),
@ -3278,16 +3297,35 @@ config_shit(View *view, UI_State *state, UI_Layout *layout){
} }
} }
struct File_Bar{
f32 pos_x, pos_y;
f32 text_shift_x, text_shift_y;
i32_Rect rect;
i16 font_id;
};
internal void
intbar_draw_string(Render_Target *target, File_Bar *bar, String str, u32 char_color){
i16 font_id = bar->font_id;
draw_string(target, font_id, str,
(i32)(bar->pos_x + bar->text_shift_x),
(i32)(bar->pos_y + bar->text_shift_y),
char_color);
bar->pos_x += font_string_width(target, font_id, str);
}
internal void internal void
do_file_bar(View *view, Editing_File *file, UI_Layout *layout, Render_Target *target){ do_file_bar(View *view, Editing_File *file, UI_Layout *layout, Render_Target *target){
Interactive_Bar bar; File_Bar bar;
App_Models *models = view->models; Models *models = view->models;
Style_Font *font = &models->global_font; Style_Font *font = &models->global_font;
i32 line_height = view->font_height; i32 line_height = view->font_height;
Interactive_Style bar_style = models->style.main.file_info_style; Interactive_Style bar_style = models->style.main.file_info_style;
u32 back_color = bar_style.bar_color; u32 back_color = bar_style.bar_color;
u32 base_color = bar_style.base_color; u32 base_color = bar_style.base_color;
u32 pop1_color = bar_style.pop1_color;
u32 pop2_color = bar_style.pop2_color; u32 pop2_color = bar_style.pop2_color;
bar.rect = layout_rect(layout, line_height + 2); bar.rect = layout_rect(layout, line_height + 2);
@ -3301,7 +3339,7 @@ do_file_bar(View *view, Editing_File *file, UI_Layout *layout, Render_Target *ta
draw_rectangle(target, bar.rect, back_color); draw_rectangle(target, bar.rect, back_color);
intbar_draw_string(target, &bar, file->name.live_name, base_color); intbar_draw_string(target, &bar, file->name.live_name, base_color);
intbar_draw_string(target, &bar, make_lit_string(" - "), base_color); intbar_draw_string(target, &bar, make_lit_string(" -"), base_color);
if (file->state.is_loading){ if (file->state.is_loading){
intbar_draw_string(target, &bar, make_lit_string(" loading"), base_color); intbar_draw_string(target, &bar, make_lit_string(" loading"), base_color);
@ -3309,11 +3347,24 @@ do_file_bar(View *view, Editing_File *file, UI_Layout *layout, Render_Target *ta
else{ else{
char line_number_space[30]; char line_number_space[30];
String line_number = make_string(line_number_space, 0, 30); String line_number = make_string(line_number_space, 0, 30);
append(&line_number, "L#"); append(&line_number, " L#");
append_int_to_str(view->cursor.line, &line_number); append_int_to_str(view->cursor.line, &line_number);
intbar_draw_string(target, &bar, line_number, base_color); intbar_draw_string(target, &bar, line_number, base_color);
intbar_draw_string(target, &bar, make_lit_string(" -"), base_color);
if (file->settings.dos_write_mode){
intbar_draw_string(target, &bar, make_lit_string(" dos"), base_color);
}
else{
intbar_draw_string(target, &bar, make_lit_string(" nix"), base_color);
}
if (file->state.still_lexing){
intbar_draw_string(target, &bar, make_lit_string(" parsing"), pop1_color);
}
if (!file->settings.unimportant){ if (!file->settings.unimportant){
switch (buffer_get_sync(file)){ switch (buffer_get_sync(file)){
case SYNC_BEHIND_OS: case SYNC_BEHIND_OS:
@ -3372,7 +3423,7 @@ internal i32
step_file_view(System_Functions *system, Exchange *exchange, View *view, i32_Rect rect, step_file_view(System_Functions *system, Exchange *exchange, View *view, i32_Rect rect,
b32 is_active, Input_Summary *user_input){ b32 is_active, Input_Summary *user_input){
App_Models *models = view->models; Models *models = view->models;
i32 result = 0; i32 result = 0;
Editing_File *file = view->file; Editing_File *file = view->file;
@ -3519,11 +3570,13 @@ step_file_view(System_Functions *system, Exchange *exchange, View *view, i32_Rec
UI_Layout layout; UI_Layout layout;
begin_layout(&layout, rect); begin_layout(&layout, rect);
Super_Color color = {};
switch (view->showing_ui){ switch (view->showing_ui){
case VUI_None: break; case VUI_None: break;
case VUI_Theme: case VUI_Theme:
{ {
theme_shit(system, exchange, view, 0, &state, &layout); theme_shit(system, exchange, view, 0, &state, &layout, &color);
}break; }break;
case VUI_Interactive: case VUI_Interactive:
{ {
@ -3539,19 +3592,26 @@ step_file_view(System_Functions *system, Exchange *exchange, View *view, i32_Rec
{ {
config_shit(view, &state, &layout); config_shit(view, &state, &layout);
}break; }break;
} }
if (ui_finish_frame(&view->ui_state, &state, &layout, rect, 0, 0)){ i32 did_activation = 0;
if (ui_finish_frame(&view->ui_state, &state, &layout, rect, 0, &did_activation)){
result = 1; result = 1;
} }
if (did_activation){
if (view->showing_ui == VUI_Theme){
view->color = color;
result = 1;
}
}
} }
return(result); return(result);
} }
internal i32 internal i32
draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target){ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target){
App_Models *models = view->models; Models *models = view->models;
Editing_File *file = view->file; Editing_File *file = view->file;
Style *style = &models->style; Style *style = &models->style;
i32 line_height = view->font_height; i32 line_height = view->font_height;
@ -3722,7 +3782,7 @@ draw_file_view(System_Functions *system, Exchange *exchange,
View *view, View *active, i32_Rect rect, b32 is_active, View *view, View *active, i32_Rect rect, b32 is_active,
Render_Target *target, Input_Summary *user_input){ Render_Target *target, Input_Summary *user_input){
App_Models *models = view->models; Models *models = view->models;
Editing_File *file = view->file; Editing_File *file = view->file;
i32 result = 0; i32 result = 0;
@ -3776,7 +3836,9 @@ draw_file_view(System_Functions *system, Exchange *exchange,
begin_layout(&layout, rect); begin_layout(&layout, rect);
rect.y0 -= widget_height; rect.y0 -= widget_height;
Super_Color color = {};
switch (view->showing_ui){ switch (view->showing_ui){
case VUI_None: case VUI_None:
{ {
@ -3790,7 +3852,7 @@ draw_file_view(System_Functions *system, Exchange *exchange,
case VUI_Theme: case VUI_Theme:
{ {
theme_shit(system, exchange, view, active, &state, &layout); theme_shit(system, exchange, view, active, &state, &layout, &color);
}break; }break;
case VUI_Interactive: case VUI_Interactive:
@ -3816,18 +3878,32 @@ draw_file_view(System_Functions *system, Exchange *exchange,
return (result); return (result);
} }
// TODO(allen): Passing this hook and app pointer is a hack. It can go as soon as we start
// initializing files independently of setting them to views.
internal void internal void
kill_file(System_Functions *system, Exchange *exchange, kill_file(System_Functions *system, Exchange *exchange, Models *models, Editing_File *file,
App_Models *models, Editing_File *file){ Hook_Function *open_hook, Application_Links *app){
File_Node *node, *used;
file_close(system, &models->mem.general, file);
working_set_free_file(&models->working_set, file);
used = &models->working_set.used_sentinel;
node = used->next;
for (View_Iter iter = file_view_iter_init(&models->layout, file, 0); for (View_Iter iter = file_view_iter_init(&models->layout, file, 0);
file_view_iter_good(iter); file_view_iter_good(iter);
iter = file_view_iter_next(iter)){ iter = file_view_iter_next(iter)){
iter.view->file = 0; if (node != used){
iter.view->file = 0;
view_set_file(iter.view, (Editing_File*)node, models, system, open_hook, app, 0);
node = node->next;
}
else{
iter.view->file = 0;
view_set_file(iter.view, 0, models, system, open_hook, app, 0);
}
} }
file_close(system, &models->mem.general, file);
working_set_free_file(&models->working_set, file);
} }
inline void inline void
@ -4046,7 +4122,7 @@ struct Live_Views{
}; };
internal View_And_ID internal View_And_ID
live_set_alloc_view(Live_Views *live_set, Panel *panel, App_Models *models){ live_set_alloc_view(Live_Views *live_set, Panel *panel, Models *models){
View_And_ID result = {}; View_And_ID result = {};
Assert(live_set->count < live_set->max); Assert(live_set->count < live_set->max);

View File

@ -64,120 +64,6 @@ free_query_slot(Query_Set *set, Query_Bar *match_bar){
} }
} }
#if 0
enum GUI_Piece_Type{
gui_type_text_input,
gui_type_number_input,
gui_type_label,
gui_type_slider
};
struct GUI_Piece_Header{
i32 type;
i32 padding;
};
// TODO(allen): Inline string for prompt?
struct GUI_Piece_Text_Input{
String *dest;
f32_Rect rect;
String prompt;
};
struct GUI_Piece_Number_Input{
i32 *dest;
f32_Rect rect;
String prompt;
};
struct GUI_Piece_Label{
f32_Rect rect;
String text;
};
struct GUI_Piece_Slider{
i32 *dest;
f32_Rect rect;
i32 max;
};
struct GUI_Layout_Engine{
i32_Rect region;
i32 x, y;
};
struct GUI_Target{
Partition push_buffer;
GUI_Layout_Engine layout;
};
internal void
refresh_gui(GUI_Target *target, i32_Rect region){
target->push_buffer.pos = 0;
target->layout.region = region;
target->layout.x = 0;
target->layout.y = 0;
}
internal void
push_gui_item(GUI_Target *target, GUI_Piece_Header header, void *item, i32 size){
GUI_Piece_Header *ptr;
i32 total_size;
Assert(sizeof(header) == 8);
total_size = sizeof(header) + size;
total_size = ((total_size + 7) & ~7);
ptr = (GUI_Piece_Header*)push_block(&target->push_buffer, size);
if (ptr){
*ptr = header;
memcpy(ptr + 1, item, size);
}
else{
Assert(!"bad situation");
}
}
internal void
push_gui_text_in(GUI_Target *target, String prompt, String *dest){
GUI_Piece_Header header = {};
GUI_Piece_Text_Input item = {};
header.type = gui_type_text_input;
item.dest = dest;
item.rect = gui_layout(target); // ?? what do we need here?
item.prompt = prompt;
push_gui_item(target, header, &item, sizeof(item));
}
internal void
push_gui_number_in(GUI_Target *target, String prompt, i32 *dest){
GUI_Piece_Header header = {};
GUI_Piece_Number_Input item = {};
header.type = gui_type_number_input;
item.dest = dest;
item.rect = gui_layout(target); // ?? what do we need here?
item.prompt = prompt;
push_gui_item(target, header, &item, sizeof(item));
}
internal void
push_gui_label(GUI_Target *target, String text){
GUI_Piece_Header header = {};
GUI_Piece_Label item = {};
header.type = gui_type_label;
item.rect = gui_layout(target); // ?? what do we need here?
item.text = text;
push_gui_item(target, header, &item, sizeof(item));
}
#endif
struct Single_Line_Input_Step{ struct Single_Line_Input_Step{
b8 hit_newline; b8 hit_newline;
b8 hit_ctrl_newline; b8 hit_ctrl_newline;
@ -1492,7 +1378,6 @@ do_live_file_list_box(System_Functions *system, UI_State *state, UI_Layout *layo
return result; return result;
} }
struct Super_Color{ struct Super_Color{
Vec4 hsla; Vec4 hsla;
Vec4 rgba; Vec4 rgba;

View File

@ -154,6 +154,7 @@ char *daction_enum[] = {
"SWITCH", "SWITCH",
"TRY_KILL", "TRY_KILL",
"KILL", "KILL",
"TOUCH_FILE",
}; };
char str_alloc_copy[] = char str_alloc_copy[] =
@ -186,8 +187,10 @@ enum Daction_Field_Handle{
dfph_integer, dfph_integer,
}; };
Daction_Field_Handle dact_param_sets[] = { Daction_Field_Handle dact_param_sets[] = {
dfph_panel, dfph_null,
dfph_string, dfph_null, dfph_string, dfph_null,
dfph_panel, dfph_null,
dfph_file, dfph_null,
dfph_file, dfph_panel, dfph_null,
dfph_string, dfph_panel, dfph_null, dfph_string, dfph_panel, dfph_null,
dfph_string, dfph_file, dfph_null, dfph_string, dfph_file, dfph_null,
dfph_panel, dfph_integer, dfph_null, dfph_panel, dfph_integer, dfph_null,
@ -307,51 +310,6 @@ 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);
}
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
char* bar_style_fields[] = { char* bar_style_fields[] = {
"bar", "bar",
@ -496,9 +454,6 @@ int main(){
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);
filename = generate_style(); filename = generate_style();
printf("gen success: %s\n", filename); printf("gen success: %s\n", filename);
} }

View File

@ -31,6 +31,15 @@ dll_insert(T *pos, T *v){
v->next->prev = v; v->next->prev = v;
} }
template<typename T>
inline void
dll_insert_back(T *pos, T *v){
v->prev = pos->prev;
v->next = pos;
pos->prev = v;
v->prev->next = v;
}
template<typename T> template<typename T>
inline void inline void
dll_remove(T *v){ dll_remove(T *v){

View File

@ -1,10 +0,0 @@
#define MAJOR 3
#define MINOR 4
#define PATCH 5
#define VERSION_NUMBER "alpha 3.4.5"
#ifdef FRED_SUPER
#define VERSION_TYPE " super!"
#else
#define VERSION_TYPE ""
#endif
#define VERSION VERSION_NUMBER VERSION_TYPE

View File

@ -1,4 +1,4 @@
@echo off @echo off
"w:\4ed\misc\build_all.bat" /DFRED_NOT_PACKAGE /Zi "w:\4ed\misc\build_all.bat" /DFRED_SUPER /DFRED_NOT_PACKAGE /Zi
REM "w:\4ed\misc\build_all.bat" /O2 /Zi REM "w:\4ed\misc\build_all.bat" /O2 /Zi

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 SET EXPORTS=/EXPORT:get_bindings /EXPORT:get_alpha_4coder_version
SET SRC=4coder_custom.cpp SET SRC=4coder_custom.cpp
REM SET LINKS=user32.lib gdi32.lib REM SET LINKS=user32.lib gdi32.lib
SET LINKS= SET LINKS=

View File

@ -1,32 +1,37 @@
/* NOTE(casey): /* TODO(casey): Here are our current issues
This is my attempt to make 4coder work close enough to Emacs - Display:
for me to switch! - Jumping to subsequent errors in a file seems to jump to an unrelated position
then scroll back to the actual position, which results in lots of extra scrolling
- Need a way of highlighting the current line like Emacs does for the benefit
of people on The Stream(TM)
- Need a way of changing some things visually so we can indicate the modal state (this has
to be something very obvious - ideally something like
1) Change the line highlight color
2) In modal mode, highlight the whole selected region (mark to cursor) potentially?
- Some way to recenter the view so that the line containing the cursor becomes the
center line vertically.
- NOTE / IMPORTANT / TODO highlighting? Ability to customize? Whatever.
NOTE(casey): Microsoft/Windows is poopsauce. - Indentation:
- Multiple // lines don't seem to indent properly. The first one will go to the correct place, but the subsequent ones will go to the first column regardless?
- Would like the option to indent to hanging parentheses, equals signs, etc. instead of
always just "one tab in from the previous line".
- Need to have better indentation / wrapping control for typing in comments.
Right now it's a bit worse than Emacs, which does automatically put you at
the same margin as the prev. line (4coder just goes back to column 1). It'd
be nice if it got _better_ than Emacs, with no need to manually flow comments,
etc.
TODO(casey): Here are our current issues - Buffer management:
- Have buffers normalize slashes to always be forward-slash - right now I'm doing this manually
- Have buffers normalize slashes to always be forward-slash - Need auto-complete for things like "arbitrary command", with options listed, etc.,
- Cursor setting seems to do no movement first time, and then weird scrolling behavior on so this should either be built into 4ed, or the custom DLL should have the ability
jump-to-same-line subsequently to display possible completions and iterate over internal cmdid's, etc. Possibly
the latter, for maximal ability of customizers to add their own commands?
- Switch-to-buffer with no typing, just return, should switch to the most recently
used buffer that is not currently displayed in a view.
- Kill-buffer should perform this switch automatically, or it should be easy
to build a custom kill buffer that does
- Need a way of highlighting the current line like Emacs does for the benefit
of people on The Stream(TM)
- Need a way of changing some things visually so we can indicate the modal state (this has
to be something very obvious - ideally something like
1) Change the line highlight color
2) In modal mode, highlight the whole selected region (mark to cursor) potentially?
- Macros
- Some way to recenter the view so that the line containing the cursor becomes the
center line vertically.
- NOTE / IMPORTANT / TODO highlighting? Ability to customize? Whatever.
- Macro recording/playback
NOTE(allen): Things that were on the issue list that are now fixed NOTE(allen): Things that were on the issue list that are now fixed
@ -34,13 +39,24 @@
- Need a way of changing some things visually so we can indicate the modal state (this has - Need a way of changing some things visually so we can indicate the modal state (this has
to be something very obvious - ideally something like to be something very obvious - ideally something like
1) Change the cursor color 1) Change the cursor color
2) X 2) Change the header bar color?
3) X
4) Change the header bar color?
- Need a way to set the theme from the custom config file so I don't have to pick it every - Need a way to set the theme from the custom config file so I don't have to pick it every
time. time.
- Switch-to-buffer with no typing, just return, should switch to the most recently
used buffer that is not currently displayed in a view.
- Kill-buffer should perform this switch automatically, or it should be easy
to build a custom kill buffer that does
- Seems like there's no way to switch to buffers whose names are substrings of other
buffers' names without using the mouse?
- Scroll speed seems to slow. It's behind where I am a lot of the time. Should be
_much_ more accelerated than it is, I think - presumably this will be tunable?
- Crash bug with paste-and-indent that sometimes leaves things unindented then crashes
*/ */
// NOTE(casey): Microsoft/Windows is poopsauce.
#include <math.h> #include <math.h>
#include <stdio.h> #include <stdio.h>
@ -273,6 +289,7 @@ HOOK_SIG(casey_start)
exec_command(app, cmdid_open_panel_vsplit); exec_command(app, cmdid_open_panel_vsplit);
app->change_theme(app, literal("Handmade Hero")); app->change_theme(app, literal("Handmade Hero"));
app->change_font(app, literal("liberation mono")); app->change_font(app, literal("liberation mono"));
return(0);
} }
CUSTOM_COMMAND_SIG(casey_open_in_other) CUSTOM_COMMAND_SIG(casey_open_in_other)
@ -291,7 +308,7 @@ CUSTOM_COMMAND_SIG(casey_clean_and_save)
CUSTOM_COMMAND_SIG(casey_newline_and_indent) CUSTOM_COMMAND_SIG(casey_newline_and_indent)
{ {
exec_command(app, cmdid_write_character); exec_command(app, cmdid_write_character);
exec_command(app, cmdid_auto_tab_line_at_cursor); exec_command(app, auto_tab_line_at_cursor);
} }
CUSTOM_COMMAND_SIG(casey_open_file_other_window) CUSTOM_COMMAND_SIG(casey_open_file_other_window)
@ -307,12 +324,17 @@ CUSTOM_COMMAND_SIG(casey_switch_buffer_other_window)
} }
internal void internal void
DeleteAfterCommand(struct Application_Links *app, Command_ID CommandID) DeleteAfterCommand(struct Application_Links *app, unsigned long long CommandID)
{ {
View_Summary view = app->get_active_view(app); View_Summary view = app->get_active_view(app);
int pos2 = view.cursor.pos; int pos2 = view.cursor.pos;
exec_command(app, CommandID); if (CommandID < cmdid_count){
exec_command(app, (Command_ID)CommandID);
}
else{
exec_command(app, (Custom_Command_Function*)CommandID);
}
app->refresh_view(app, &view); app->refresh_view(app, &view);
int pos1 = view.cursor.pos; int pos1 = view.cursor.pos;
@ -324,12 +346,12 @@ DeleteAfterCommand(struct Application_Links *app, Command_ID CommandID)
CUSTOM_COMMAND_SIG(casey_delete_token_left) CUSTOM_COMMAND_SIG(casey_delete_token_left)
{ {
DeleteAfterCommand(app, cmdid_seek_white_or_token_left); DeleteAfterCommand(app, (unsigned long long)seek_white_or_token_left);
} }
CUSTOM_COMMAND_SIG(casey_delete_token_right) CUSTOM_COMMAND_SIG(casey_delete_token_right)
{ {
DeleteAfterCommand(app, cmdid_seek_white_or_token_right); DeleteAfterCommand(app, (unsigned long long)seek_white_or_token_right);
} }
CUSTOM_COMMAND_SIG(casey_kill_to_end_of_line) CUSTOM_COMMAND_SIG(casey_kill_to_end_of_line)
@ -362,21 +384,38 @@ CUSTOM_COMMAND_SIG(casey_paste_and_tab)
CUSTOM_COMMAND_SIG(casey_seek_beginning_of_line_and_tab) CUSTOM_COMMAND_SIG(casey_seek_beginning_of_line_and_tab)
{ {
exec_command(app, cmdid_seek_beginning_of_line); exec_command(app, cmdid_seek_beginning_of_line);
exec_command(app, cmdid_auto_tab_line_at_cursor); exec_command(app, auto_tab_line_at_cursor);
} }
struct switch_to_result struct switch_to_result
{ {
bool Switched; bool Switched;
bool Loaded;
View_Summary view; View_Summary view;
Buffer_Summary buffer; Buffer_Summary buffer;
}; };
inline void
SanitizeSlashes(String Value)
{
for(int At = 0;
At < Value.size;
++At)
{
if(Value.str[At] == '\\')
{
Value.str[At] = '/';
}
}
}
inline switch_to_result inline switch_to_result
SwitchToOrLoadFile(struct Application_Links *app, String FileName, bool CreateIfNotFound = false) SwitchToOrLoadFile(struct Application_Links *app, String FileName, bool CreateIfNotFound = false)
{ {
switch_to_result Result = {}; switch_to_result Result = {};
SanitizeSlashes(FileName);
View_Summary view = app->get_active_view(app); View_Summary view = app->get_active_view(app);
Buffer_Summary buffer = app->get_buffer_by_name(app, FileName.str, FileName.size); Buffer_Summary buffer = app->get_buffer_by_name(app, FileName.str, FileName.size);
@ -399,6 +438,7 @@ SwitchToOrLoadFile(struct Application_Links *app, String FileName, bool CreateIf
Result.buffer = app->get_buffer_by_name(app, FileName.str, FileName.size); Result.buffer = app->get_buffer_by_name(app, FileName.str, FileName.size);
Result.Loaded = true;
Result.Switched = true; Result.Switched = true;
} }
} }
@ -412,6 +452,8 @@ CUSTOM_COMMAND_SIG(casey_load_todo)
SwitchToOrLoadFile(app, ToDoFileName, true); SwitchToOrLoadFile(app, ToDoFileName, true);
} }
inline String Empty() {String Result = {}; return(Result);}
CUSTOM_COMMAND_SIG(casey_load_handmade) CUSTOM_COMMAND_SIG(casey_load_handmade)
{ {
// NOTE(allen|a3.4.4): Here we get the list of files in this directory. // NOTE(allen|a3.4.4): Here we get the list of files in this directory.
@ -854,8 +896,6 @@ CUSTOM_COMMAND_SIG(casey_quick_calc)
Range range = get_range(&view); Range range = get_range(&view);
size_t Size = range.max - range.min; size_t Size = range.max - range.min;
if (Size == 0) return;
char *Stuff = (char *)malloc(Size + 1); char *Stuff = (char *)malloc(Size + 1);
Stuff[Size] = 0; Stuff[Size] = 0;
@ -875,7 +915,106 @@ CUSTOM_COMMAND_SIG(casey_quick_calc)
free(Stuff); free(Stuff);
} }
CUSTOM_COMMAND_SIG(modal_toggle) internal void
OpenProject(Application_Links *app, char *ProjectFileName)
{
FILE *ProjectFile = fopen(ProjectFileName, "r");
if(ProjectFile)
{
fgets(BuildDirectory, sizeof(BuildDirectory) - 1, ProjectFile);
size_t BuildDirSize = strlen(BuildDirectory);
if((BuildDirSize) && (BuildDirectory[BuildDirSize - 1] == '\n'))
{
--BuildDirSize;
}
if((BuildDirSize) && (BuildDirectory[BuildDirSize - 1] != '/'))
{
BuildDirectory[BuildDirSize++] = '/';
BuildDirectory[BuildDirSize] = 0;
}
char FileDirectoryName[4096];
while(fgets(FileDirectoryName, sizeof(FileDirectoryName) - 1, ProjectFile))
{
// NOTE(allen|a3.4.4): Here we get the list of files in this directory.
// Notice that we free_file_list at the end.
String dir = make_string(app->memory, 0, app->memory_size);
append(&dir, FileDirectoryName);
if(dir.size && dir.str[dir.size] == '\n')
{
--dir.size;
}
if(dir.size && dir.str[dir.size] != '/')
{
dir.str[dir.size] = '/';
++dir.size;
}
File_List list = app->get_file_list(app, dir.str, dir.size);
int dir_size = dir.size;
for (int i = 0; i < list.count; ++i)
{
File_Info *info = list.infos + i;
if (!info->folder)
{
String extension = file_extension(info->filename);
if (IsCode(extension))
{
// NOTE(allen): There's no way in the 4coder API to use relative
// paths at the moment, so everything should be full paths. Which is
// managable. Here simply set the dir string size back to where it
// was originally, so that new appends overwrite old ones.
dir.size = dir_size;
append(&dir, info->filename);
push_parameter(app, par_name, dir.str, dir.size);
push_parameter(app, par_do_in_background, 1);
exec_command(app, cmdid_interactive_open);
}
}
}
app->free_file_list(app, list);
}
fclose(ProjectFile);
}
}
CUSTOM_COMMAND_SIG(casey_execute_arbitrary_command)
{
Query_Bar bar;
char space[1024], more_space[1024];
bar.prompt = make_lit_string("Command: ");
bar.string = make_fixed_width_string(space);
if (!query_user_string(app, &bar)) return;
app->end_query_bar(app, &bar, 0);
if(match(bar.string, make_lit_string("project")))
{
// exec_command(app, open_all_code);
}
else if(match(bar.string, make_lit_string("open menu")))
{
exec_command(app, cmdid_open_menu);
}
else
{
bar.prompt = make_fixed_width_string(more_space);
append(&bar.prompt, make_lit_string("Unrecognized: "));
append(&bar.prompt, bar.string);
bar.string.size = 0;
app->start_query_bar(app, &bar, 0);
app->get_user_input(app, EventOnAnyKey | EventOnButton, 0);
}
}
internal void
UpdateModalIndicator(Application_Links *app)
{ {
Theme_Color normal_colors[] = { Theme_Color normal_colors[] = {
{Stag_Cursor, 0x40FF40}, {Stag_Cursor, 0x40FF40},
@ -897,8 +1036,6 @@ CUSTOM_COMMAND_SIG(modal_toggle)
{Stag_Bar, 0x934420} {Stag_Bar, 0x934420}
}; };
GlobalEditMode = !GlobalEditMode;
if (GlobalEditMode){ if (GlobalEditMode){
app->set_theme_colors(app, edit_colors, ArrayCount(edit_colors)); app->set_theme_colors(app, edit_colors, ArrayCount(edit_colors));
} }
@ -911,30 +1048,18 @@ CUSTOM_COMMAND_SIG(modal_toggle)
GetClientRect(GlobalModalIndicator, &Rect); GetClientRect(GlobalModalIndicator, &Rect);
InvalidateRect(GlobalModalIndicator, &Rect, FALSE); InvalidateRect(GlobalModalIndicator, &Rect, FALSE);
#endif #endif
} }
CUSTOM_COMMAND_SIG(casey_arbitrary_command){ CUSTOM_COMMAND_SIG(begin_free_typing)
Query_Bar bar; {
char space[1024]; GlobalEditMode = false;
bar.prompt = make_lit_string("Command: "); UpdateModalIndicator(app);
bar.string = make_fixed_width_string(space); }
if (!query_user_string(app, &bar)) return; CUSTOM_COMMAND_SIG(end_free_typing)
app->end_query_bar(app, &bar, 0); {
GlobalEditMode = true;
if (match(bar.string, make_lit_string("build search"))){ UpdateModalIndicator(app);
exec_command(app, casey_build_search);
}
else if (match(bar.string, make_lit_string("open hmh"))){
exec_command(app, casey_load_handmade);
}
else if (match(bar.string, make_lit_string("open menu"))){
exec_command(app, cmdid_open_menu);
}
else{
// TODO(allen): feedback message
}
} }
#define DEFINE_FULL_BIMODAL_KEY(binding_name,edit_code,normal_code) \ #define DEFINE_FULL_BIMODAL_KEY(binding_name,edit_code,normal_code) \
@ -993,12 +1118,12 @@ DEFINE_MODAL_KEY(modal_u, cmdid_undo);
DEFINE_MODAL_KEY(modal_v, casey_switch_buffer_other_window); DEFINE_MODAL_KEY(modal_v, casey_switch_buffer_other_window);
DEFINE_MODAL_KEY(modal_w, cmdid_cut); DEFINE_MODAL_KEY(modal_w, cmdid_cut);
DEFINE_MODAL_KEY(modal_x, casey_open_file_other_window); DEFINE_MODAL_KEY(modal_x, casey_open_file_other_window);
DEFINE_MODAL_KEY(modal_y, cmdid_auto_tab_line_at_cursor); DEFINE_MODAL_KEY(modal_y, auto_tab_line_at_cursor);
DEFINE_MODAL_KEY(modal_z, cmdid_interactive_open); DEFINE_MODAL_KEY(modal_z, cmdid_interactive_open);
DEFINE_MODAL_KEY(modal_1, casey_build_search); // TODO(casey): Shouldn't need to bind a key for this? DEFINE_MODAL_KEY(modal_1, casey_build_search); // TODO(casey): Shouldn't need to bind a key for this?
DEFINE_MODAL_KEY(modal_2, casey_load_handmade); // TODO(casey): Shouldn't need to bind a key for this? DEFINE_MODAL_KEY(modal_2, casey_load_handmade); // TODO(casey): Shouldn't need to bind a key for this?
DEFINE_MODAL_KEY(modal_3, casey_arbitrary_command); // NOTE(allen): I set this for testing stuff modal_1 and modal_2 don't need to be set anymore DEFINE_MODAL_KEY(modal_3, cmdid_write_character); // TODO(casey): Available
DEFINE_MODAL_KEY(modal_4, cmdid_write_character); // TODO(casey): Available DEFINE_MODAL_KEY(modal_4, cmdid_write_character); // TODO(casey): Available
DEFINE_MODAL_KEY(modal_5, cmdid_write_character); // TODO(casey): Available DEFINE_MODAL_KEY(modal_5, cmdid_write_character); // TODO(casey): Available
DEFINE_MODAL_KEY(modal_6, cmdid_write_character); // TODO(casey): Available DEFINE_MODAL_KEY(modal_6, cmdid_write_character); // TODO(casey): Available
@ -1007,19 +1132,18 @@ DEFINE_MODAL_KEY(modal_8, cmdid_write_character); // TODO(casey): Available
DEFINE_MODAL_KEY(modal_9, cmdid_write_character); // TODO(casey): Available DEFINE_MODAL_KEY(modal_9, cmdid_write_character); // TODO(casey): Available
DEFINE_MODAL_KEY(modal_0, cmdid_kill_buffer); DEFINE_MODAL_KEY(modal_0, cmdid_kill_buffer);
DEFINE_MODAL_KEY(modal_minus, cmdid_write_character); // TODO(casey): Available DEFINE_MODAL_KEY(modal_minus, cmdid_write_character); // TODO(casey): Available
DEFINE_MODAL_KEY(modal_equals, cmdid_write_character); // TODO(casey): Available DEFINE_MODAL_KEY(modal_equals, casey_execute_arbitrary_command);
DEFINE_BIMODAL_KEY(modal_backspace, casey_delete_token_left, cmdid_backspace); DEFINE_BIMODAL_KEY(modal_backspace, casey_delete_token_left, cmdid_backspace);
DEFINE_BIMODAL_KEY(modal_up, cmdid_move_up, cmdid_move_up); DEFINE_BIMODAL_KEY(modal_up, cmdid_move_up, cmdid_move_up);
DEFINE_BIMODAL_KEY(modal_down, cmdid_move_down, cmdid_move_down); DEFINE_BIMODAL_KEY(modal_down, cmdid_move_down, cmdid_move_down);
DEFINE_BIMODAL_KEY(modal_left, cmdid_seek_white_or_token_left, cmdid_move_left); DEFINE_BIMODAL_KEY(modal_left, seek_white_or_token_left, cmdid_move_left);
DEFINE_BIMODAL_KEY(modal_right, cmdid_seek_white_or_token_right, cmdid_move_right); DEFINE_BIMODAL_KEY(modal_right, seek_white_or_token_right, cmdid_move_right);
DEFINE_BIMODAL_KEY(modal_delete, casey_delete_token_right, cmdid_delete); DEFINE_BIMODAL_KEY(modal_delete, casey_delete_token_right, cmdid_delete);
DEFINE_BIMODAL_KEY(modal_home, cmdid_seek_beginning_of_line, casey_seek_beginning_of_line_and_tab); DEFINE_BIMODAL_KEY(modal_home, cmdid_seek_beginning_of_line, casey_seek_beginning_of_line_and_tab);
DEFINE_BIMODAL_KEY(modal_end, cmdid_seek_end_of_line, cmdid_seek_end_of_line); DEFINE_BIMODAL_KEY(modal_end, cmdid_seek_end_of_line, cmdid_seek_end_of_line);
DEFINE_BIMODAL_KEY(modal_page_up, cmdid_page_up, cmdid_seek_whitespace_up); DEFINE_BIMODAL_KEY(modal_page_up, cmdid_page_up, cmdid_seek_whitespace_up);
DEFINE_BIMODAL_KEY(modal_page_down, cmdid_page_down, cmdid_seek_whitespace_down); DEFINE_BIMODAL_KEY(modal_page_down, cmdid_page_down, cmdid_seek_whitespace_down);
//DEFINE_BIMODAL_KEY(modal_escape, cmdid_write_character, cmdid_write_character); // TODO(casey): Available
DEFINE_BIMODAL_KEY(modal_tab, cmdid_word_complete, cmdid_word_complete); DEFINE_BIMODAL_KEY(modal_tab, cmdid_word_complete, cmdid_word_complete);
HOOK_SIG(casey_file_settings) HOOK_SIG(casey_file_settings)
@ -1031,21 +1155,30 @@ HOOK_SIG(casey_file_settings)
Buffer_Summary buffer = app->get_parameter_buffer(app, 0); Buffer_Summary buffer = app->get_parameter_buffer(app, 0);
int treat_as_code = 0; int treat_as_code = 0;
int treat_as_project = 0;
if (buffer.file_name && buffer.size < (16 << 20)) if (buffer.file_name && buffer.size < (16 << 20))
{ {
String ext = file_extension(make_string(buffer.file_name, buffer.file_name_len)); String ext = file_extension(make_string(buffer.file_name, buffer.file_name_len));
treat_as_code = IsCode(ext); treat_as_code = IsCode(ext);
treat_as_project = match(ext, make_lit_string("prj"));
} }
push_parameter(app, par_lex_as_cpp_file, treat_as_code); push_parameter(app, par_lex_as_cpp_file, treat_as_code);
push_parameter(app, par_wrap_lines, !treat_as_code); push_parameter(app, par_wrap_lines, !treat_as_code);
push_parameter(app, par_key_mapid, (treat_as_code)?((int)my_code_map):((int)mapid_file)); push_parameter(app, par_key_mapid, (treat_as_code)?((int)my_code_map):((int)mapid_file));
exec_command(app, cmdid_set_settings); exec_command(app, cmdid_set_settings);
if(treat_as_project)
{
OpenProject(app, buffer.file_name);
exec_command(app, cmdid_kill_buffer);
}
return(0);
} }
// NOTE(allen): This was a bit of fun so I'll leave it in, // NOTE(allen): This was a bit of fun so I'll leave it in, for anyone would like to hack 4coder again.
// incase anyone would like to hack 4coder again.
#if UseHack4Coder #if UseHack4Coder
internal void internal void
hack_place_modal_indicator(void) hack_place_modal_indicator(void)
@ -1116,7 +1249,7 @@ modal_indicator_window_callback(HWND Window,
internal void internal void
hack_4coder(void) hack_4coder(void)
{ {
HWND Window = FindWindow("4coder-win32-wndclass", "4coder-window"); HWND Window = FindWindow("4coder-win32-wndclass", "4coder-window: " VERSION);
ShowWindow(Window, SW_MAXIMIZE); ShowWindow(Window, SW_MAXIMIZE);
WNDCLASSA WindowClass = {}; WNDCLASSA WindowClass = {};
@ -1172,14 +1305,10 @@ casey_get_bindings(Bind_Helper *context)
bind(context, 't', MDFR_NONE, casey_load_todo); bind(context, 't', MDFR_NONE, casey_load_todo);
bind(context, '/', MDFR_NONE, cmdid_change_active_panel); bind(context, '/', MDFR_NONE, cmdid_change_active_panel);
bind(context, 'b', MDFR_NONE, cmdid_interactive_switch_buffer); bind(context, 'b', MDFR_NONE, cmdid_interactive_switch_buffer);
bind(context, '3', MDFR_NONE, casey_arbitrary_command);
bind(context, key_page_up, MDFR_NONE, search);
bind(context, key_page_down, MDFR_NONE, reverse_search);
// NOTE(allen): These don't necessarily need to be here anymore.
// They are now bound to long form commands in casey_arbitrary_command.
bind(context, '2', MDFR_NONE, casey_load_handmade); bind(context, '2', MDFR_NONE, casey_load_handmade);
bind(context, '4', MDFR_NONE, cmdid_open_color_tweaker); bind(context, '4', MDFR_NONE, cmdid_open_color_tweaker);
bind(context, key_page_up, MDFR_NONE, search);
bind(context, key_page_down, MDFR_NONE, reverse_search);
// NOTE(allen): I added this here myself, I believe this is what you want. // NOTE(allen): I added this here myself, I believe this is what you want.
bind(context, 'm', MDFR_NONE, casey_save_and_make_without_asking); bind(context, 'm', MDFR_NONE, casey_save_and_make_without_asking);
@ -1190,9 +1319,11 @@ casey_get_bindings(Bind_Helper *context)
bind_vanilla_keys(context, cmdid_write_character); bind_vanilla_keys(context, cmdid_write_character);
bind(context, key_insert, MDFR_NONE, modal_toggle); bind(context, key_insert, MDFR_NONE, begin_free_typing);
bind(context, '`', MDFR_NONE, modal_toggle); bind(context, '`', MDFR_NONE, begin_free_typing);
bind(context, key_esc, MDFR_NONE, end_free_typing);
bind(context, '\n', MDFR_NONE, casey_newline_and_indent); bind(context, '\n', MDFR_NONE, casey_newline_and_indent);
bind(context, '\n', MDFR_SHIFT, casey_newline_and_indent);
bind(context, 't', MDFR_CTRL, cmdid_timeline_scrub); bind(context, 't', MDFR_CTRL, cmdid_timeline_scrub);

View File

@ -9,7 +9,6 @@
// TOP // TOP
#include "4ed_version.h"
#include "4ed_config.h" #include "4ed_config.h"
#include "4ed_meta.h" #include "4ed_meta.h"
@ -434,6 +433,7 @@ Sys_Set_File_List_Sig(system_set_file_list){
info->filename.size = i; info->filename.size = i;
info->filename.memory_size = info->filename.size + 1; info->filename.memory_size = info->filename.size + 1;
*name++ = 0; *name++ = 0;
replace_char(info->filename, '\\', '/');
++info; ++info;
} }
more_files = FindNextFile(search, &find_data); more_files = FindNextFile(search, &find_data);
@ -1082,7 +1082,7 @@ Win32LoadSystemCode(){
win32vars.system->internal_debug_message = INTERNAL_system_debug_message; win32vars.system->internal_debug_message = INTERNAL_system_debug_message;
#endif #endif
win32vars.system->slash = '\\'; win32vars.system->slash = '/';
} }
#include "system_shared.cpp" #include "system_shared.cpp"
@ -1685,6 +1685,7 @@ main(int argc, char **argv){
String current_directory = make_string(current_directory_mem, written, required); String current_directory = make_string(current_directory_mem, written, required);
terminate_with_null(&current_directory); terminate_with_null(&current_directory);
replace_char(current_directory, '\\', '/');
Command_Line_Parameters clparams; Command_Line_Parameters clparams;
clparams.argv = argv; clparams.argv = argv;
@ -1710,6 +1711,36 @@ main(int argc, char **argv){
printf("%.*s", output_size, memory_vars.target_memory); printf("%.*s", output_size, memory_vars.target_memory);
} }
if (output_size != 0) return 0; if (output_size != 0) return 0;
#ifdef FRED_SUPER
char *custom_file_default = "4coder_custom.dll";
char *custom_file;
if (win32vars.settings.custom_dll) custom_file = win32vars.settings.custom_dll;
else custom_file = custom_file_default;
win32vars.custom = LoadLibraryA(custom_file);
if (!win32vars.custom && custom_file != custom_file_default){
if (!win32vars.settings.custom_dll_is_strict){
win32vars.custom = LoadLibraryA(custom_file_default);
}
}
if (win32vars.custom){
win32vars.custom_api.get_alpha_4coder_version = (_Get_Version_Function*)
GetProcAddress(win32vars.custom, "get_alpha_4coder_version");
//
if (win32vars.custom_api.get_alpha_4coder_version == 0 ||
win32vars.custom_api.get_alpha_4coder_version(MAJOR, MINOR, PATCH) == 0){
printf("Error: application and custom version numbers don't match");
return 22;
}
win32vars.custom_api.get_bindings = (Get_Binding_Data_Function*)
GetProcAddress(win32vars.custom, "get_bindings");
}
#endif
FreeConsole(); FreeConsole();
sysshared_filter_real_files(files, file_count); sysshared_filter_real_files(files, file_count);
@ -1727,25 +1758,6 @@ main(int argc, char **argv){
keycode_init(); keycode_init();
#ifdef FRED_SUPER
char *custom_file_default = "4coder_custom.dll";
char *custom_file;
if (win32vars.settings.custom_dll) custom_file = win32vars.settings.custom_dll;
else custom_file = custom_file_default;
win32vars.custom = LoadLibraryA(custom_file);
if (!win32vars.custom && custom_file != custom_file_default){
if (!win32vars.settings.custom_dll_is_strict){
win32vars.custom = LoadLibraryA(custom_file_default);
}
}
if (win32vars.custom){
win32vars.custom_api.get_bindings = (Get_Binding_Data_Function*)
GetProcAddress(win32vars.custom, "get_bindings");
}
#endif
if (win32vars.custom_api.get_bindings == 0){ if (win32vars.custom_api.get_bindings == 0){
win32vars.custom_api.get_bindings = (Get_Binding_Data_Function*)get_bindings; win32vars.custom_api.get_bindings = (Get_Binding_Data_Function*)get_bindings;
} }