various bug fixes
This commit is contained in:
parent
32da95069c
commit
264100d81a
|
@ -1,9 +1,13 @@
|
|||
// Alternative customizations, set Custom_Current to select which to apply.
|
||||
#define Custom_Default 0
|
||||
#define Custom_HandmadeHero 1
|
||||
|
||||
// Set which customization you want to use with this define or write your own
|
||||
#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"
|
||||
|
||||
#define FCPP_STRING_IMPLEMENTATION
|
||||
|
@ -20,30 +24,32 @@
|
|||
// as shown here, they may start at 0, and you can only have
|
||||
// 2^24 of them so don't be wasteful!
|
||||
enum My_Maps{
|
||||
my_code_map,
|
||||
my_html_map
|
||||
my_code_map
|
||||
};
|
||||
|
||||
HOOK_SIG(my_start){
|
||||
exec_command(app, cmdid_open_panel_vsplit);
|
||||
exec_command(app, cmdid_change_active_panel);
|
||||
|
||||
|
||||
app->change_theme(app, literal("4coder"));
|
||||
app->change_font(app, literal("liberation sans"));
|
||||
|
||||
|
||||
// Theme options:
|
||||
// "4coder"
|
||||
// "Handmade Hero"
|
||||
// "Twilight"
|
||||
// "Woverine"
|
||||
// "stb"
|
||||
|
||||
|
||||
// Font options:
|
||||
// "liberation sans"
|
||||
// "liberation mono"
|
||||
// "hack"
|
||||
// "cutive mono"
|
||||
// "inconsolata"
|
||||
|
||||
// no meaning for return
|
||||
return(0);
|
||||
}
|
||||
|
||||
HOOK_SIG(my_file_settings){
|
||||
|
@ -53,7 +59,7 @@ HOOK_SIG(my_file_settings){
|
|||
// there are no parameter buffers.
|
||||
Buffer_Summary buffer = app->get_parameter_buffer(app, 0);
|
||||
assert(buffer.exists);
|
||||
|
||||
|
||||
int treat_as_code = 0;
|
||||
|
||||
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_key_mapid, (treat_as_code)?((int)my_code_map):((int)mapid_file));
|
||||
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
|
||||
|
@ -92,19 +141,41 @@ CUSTOM_COMMAND_SIG(write_allen_note){
|
|||
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
|
||||
long_braces(Application_Links *app, char *text, int size){
|
||||
View_Summary view;
|
||||
Buffer_Summary buffer;
|
||||
int pos;
|
||||
|
||||
|
||||
view = app->get_active_view(app);
|
||||
buffer = app->get_buffer(app, view.buffer_id);
|
||||
|
||||
|
||||
pos = view.cursor.pos;
|
||||
app->buffer_replace_range(app, &buffer, pos, pos, text, size);
|
||||
app->view_set_cursor(app, &view, seek_pos(pos + 2), 1);
|
||||
|
||||
|
||||
push_parameter(app, par_range_start, pos);
|
||||
push_parameter(app, par_range_end, pos + size);
|
||||
push_parameter(app, par_clear_blank_lines, 0);
|
||||
|
@ -156,13 +227,13 @@ CUSTOM_COMMAND_SIG(paren_wrap){
|
|||
CUSTOM_COMMAND_SIG(if0_off){
|
||||
View_Summary view;
|
||||
Buffer_Summary buffer;
|
||||
|
||||
|
||||
char text1[] = "\n#if 0";
|
||||
int size1 = sizeof(text1) - 1;
|
||||
|
||||
|
||||
char text2[] = "#endif\n";
|
||||
int size2 = sizeof(text2) - 1;
|
||||
|
||||
|
||||
Range range;
|
||||
int pos;
|
||||
|
||||
|
@ -177,13 +248,13 @@ CUSTOM_COMMAND_SIG(if0_off){
|
|||
push_parameter(app, par_range_start, pos);
|
||||
push_parameter(app, par_range_end, pos);
|
||||
exec_command(app, cmdid_auto_tab_range);
|
||||
|
||||
|
||||
app->refresh_view(app, &view);
|
||||
range = get_range(&view);
|
||||
pos = range.max;
|
||||
|
||||
|
||||
app->buffer_replace_range(app, &buffer, pos, pos, text2, size2);
|
||||
|
||||
|
||||
push_parameter(app, par_range_start, pos);
|
||||
push_parameter(app, par_range_end, pos);
|
||||
exec_command(app, cmdid_auto_tab_range);
|
||||
|
@ -193,14 +264,14 @@ CUSTOM_COMMAND_SIG(backspace_word){
|
|||
View_Summary view;
|
||||
Buffer_Summary buffer;
|
||||
int pos2, pos1;
|
||||
|
||||
|
||||
view = app->get_active_view(app);
|
||||
|
||||
|
||||
pos2 = view.cursor.pos;
|
||||
exec_command(app, cmdid_seek_alphanumeric_left);
|
||||
exec_command(app, seek_alphanumeric_left);
|
||||
app->refresh_view(app, &view);
|
||||
pos1 = view.cursor.pos;
|
||||
|
||||
|
||||
buffer = app->get_buffer(app, view.buffer_id);
|
||||
app->buffer_replace_range(app, &buffer, pos1, pos2, 0, 0);
|
||||
}
|
||||
|
@ -209,19 +280,19 @@ CUSTOM_COMMAND_SIG(snipe_token_or_word){
|
|||
View_Summary view;
|
||||
Buffer_Summary buffer;
|
||||
int pos1, pos2;
|
||||
|
||||
|
||||
view = app->get_active_view(app);
|
||||
|
||||
|
||||
push_parameter(app, par_flags, BoundryToken | BoundryWhitespace);
|
||||
exec_command(app, cmdid_seek_left);
|
||||
app->refresh_view(app, &view);
|
||||
pos1 = view.cursor.pos;
|
||||
|
||||
|
||||
push_parameter(app, par_flags, BoundryToken | BoundryWhitespace);
|
||||
exec_command(app, cmdid_seek_right);
|
||||
app->refresh_view(app, &view);
|
||||
pos2 = view.cursor.pos;
|
||||
|
||||
|
||||
Range range = make_range(pos1, pos2);
|
||||
buffer = app->get_buffer(app, view.buffer_id);
|
||||
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){
|
||||
View_Summary view;
|
||||
Buffer_Summary buffer;
|
||||
|
||||
|
||||
char name[] = "*compilation*";
|
||||
int name_size = sizeof(name)-1;
|
||||
|
||||
view = app->get_active_view(app);
|
||||
buffer = app->get_buffer_by_name(app, name, name_size);
|
||||
|
||||
|
||||
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);
|
||||
x = view.preferred_x;
|
||||
|
||||
|
||||
if (view.unwrapped_lines){
|
||||
y = view.cursor.unwrapped_y;
|
||||
}
|
||||
else{
|
||||
y = view.cursor.wrapped_y;
|
||||
}
|
||||
|
||||
|
||||
y -= 10*view.line_height;
|
||||
|
||||
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);
|
||||
x = view.preferred_x;
|
||||
|
||||
|
||||
if (view.unwrapped_lines){
|
||||
y = view.cursor.wrapped_y;
|
||||
}
|
||||
else{
|
||||
y = view.cursor.wrapped_y;
|
||||
}
|
||||
|
||||
|
||||
y += 10*view.line_height;
|
||||
|
||||
|
||||
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;
|
||||
char short_file_name[128];
|
||||
int pos, start, end, size;
|
||||
|
||||
|
||||
view = app->get_active_view(app);
|
||||
buffer = app->get_buffer(app, view.buffer_id);
|
||||
pos = view.cursor.pos;
|
||||
app->buffer_seek_delimiter(app, &buffer, pos, '"', 1, &end);
|
||||
app->buffer_seek_delimiter(app, &buffer, pos, '"', 0, &start);
|
||||
|
||||
|
||||
++start;
|
||||
size = end - start;
|
||||
|
||||
|
||||
// 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.
|
||||
if (size < sizeof(short_file_name)){
|
||||
|
@ -315,10 +386,10 @@ CUSTOM_COMMAND_SIG(goto_line){
|
|||
int line_number;
|
||||
Query_Bar bar;
|
||||
char string_space[256];
|
||||
|
||||
|
||||
bar.prompt = make_lit_string("Goto Line: ");
|
||||
bar.string = make_fixed_width_string(string_space);
|
||||
|
||||
|
||||
if (query_user_number(app, &bar)){
|
||||
line_number = str_to_int(bar.string);
|
||||
active_view_to_line(app, line_number);
|
||||
|
@ -334,37 +405,37 @@ isearch(Application_Links *app, int start_reversed){
|
|||
Buffer_Summary buffer;
|
||||
User_Input in;
|
||||
Query_Bar bar;
|
||||
|
||||
|
||||
if (app->start_query_bar(app, &bar, 0) == 0) return;
|
||||
|
||||
|
||||
Range match;
|
||||
int reverse = start_reversed;
|
||||
int pos;
|
||||
|
||||
|
||||
view = app->get_active_view(app);
|
||||
buffer = app->get_buffer(app, view.buffer_id);
|
||||
|
||||
|
||||
pos = view.cursor.pos;
|
||||
match = make_range(pos, pos);
|
||||
|
||||
|
||||
char bar_string_space[256];
|
||||
bar.string = make_fixed_width_string(bar_string_space);
|
||||
|
||||
|
||||
String isearch = make_lit_string("I-Search: ");
|
||||
String rsearch = make_lit_string("Reverse-I-Search: ");
|
||||
|
||||
|
||||
while (1){
|
||||
// NOTE(allen): Change the bar's prompt to match the current direction.
|
||||
if (reverse) bar.prompt = rsearch;
|
||||
else bar.prompt = isearch;
|
||||
|
||||
|
||||
in = app->get_user_input(app, EventOnAnyKey, EventOnEsc | EventOnButton);
|
||||
if (in.abort) break;
|
||||
|
||||
|
||||
// NOTE(allen): If we're getting mouse events here it's a 4coder bug, because we
|
||||
// only asked to intercept key events.
|
||||
assert(in.type == UserInputKey);
|
||||
|
||||
|
||||
int made_change = 0;
|
||||
if (in.key.keycode == '\n' || in.key.keycode == '\t'){
|
||||
break;
|
||||
|
@ -377,15 +448,15 @@ isearch(Application_Links *app, int start_reversed){
|
|||
--bar.string.size;
|
||||
made_change = 1;
|
||||
}
|
||||
|
||||
|
||||
int step_forward = 0;
|
||||
int step_backward = 0;
|
||||
|
||||
|
||||
if (CommandEqual(in.command, search) ||
|
||||
in.key.keycode == key_page_down || in.key.keycode == key_down) step_forward = 1;
|
||||
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;
|
||||
if (step_forward && reverse){
|
||||
start_pos = match.start + 1;
|
||||
|
@ -399,7 +470,7 @@ isearch(Application_Links *app, int start_reversed){
|
|||
reverse = 1;
|
||||
step_backward = 0;
|
||||
}
|
||||
|
||||
|
||||
if (in.key.keycode != key_back){
|
||||
int new_pos;
|
||||
if (reverse){
|
||||
|
@ -432,12 +503,12 @@ isearch(Application_Links *app, int start_reversed){
|
|||
else{
|
||||
match.end = match.start + bar.string.size;
|
||||
}
|
||||
|
||||
|
||||
app->view_set_highlight(app, &view, match.start, match.end, 1);
|
||||
}
|
||||
app->view_set_highlight(app, &view, 0, 0, 0);
|
||||
if (in.abort) return;
|
||||
|
||||
|
||||
app->view_set_cursor(app, &view, seek_pos(match.min), 1);
|
||||
}
|
||||
|
||||
|
@ -455,22 +526,22 @@ CUSTOM_COMMAND_SIG(rewrite_as_single_caps){
|
|||
Range range;
|
||||
String string;
|
||||
int is_first, i;
|
||||
|
||||
exec_command(app, cmdid_seek_token_left);
|
||||
|
||||
exec_command(app, seek_token_left);
|
||||
view = app->get_active_view(app);
|
||||
range.min = view.cursor.pos;
|
||||
|
||||
exec_command(app, cmdid_seek_token_right);
|
||||
|
||||
exec_command(app, seek_token_right);
|
||||
app->refresh_view(app, &view);
|
||||
range.max = view.cursor.pos;
|
||||
|
||||
|
||||
string.str = (char*)app->memory;
|
||||
string.size = range.max - range.min;
|
||||
assert(string.size < app->memory_size);
|
||||
|
||||
|
||||
buffer = app->get_buffer(app, view.buffer_id);
|
||||
app->buffer_read_range(app, &buffer, range.min, range.max, string.str);
|
||||
|
||||
|
||||
is_first = 1;
|
||||
for (i = 0; i < string.size; ++i){
|
||||
if (char_is_alpha_true(string.str[i])){
|
||||
|
@ -481,7 +552,7 @@ CUSTOM_COMMAND_SIG(rewrite_as_single_caps){
|
|||
is_first = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
string = get_rewrite_string(app, &rewrite, app->memory, app->memory_size);
|
||||
|
||||
|
||||
is_first = 1;
|
||||
for (i = 0; i < string.size; ++i){
|
||||
if (char_is_alpha_true(string.str[i])){
|
||||
|
@ -504,7 +575,7 @@ CUSTOM_COMMAND_SIG(rewrite_as_single_caps){
|
|||
is_first = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
do_rewrite(app, &rewrite, string);
|
||||
}
|
||||
#endif
|
||||
|
@ -514,17 +585,17 @@ CUSTOM_COMMAND_SIG(replace_in_range){
|
|||
char replace_space[1024];
|
||||
replace.prompt = make_lit_string("Replace: ");
|
||||
replace.string = make_fixed_width_string(replace_space);
|
||||
|
||||
|
||||
Query_Bar with;
|
||||
char with_space[1024];
|
||||
with.prompt = make_lit_string("With: ");
|
||||
with.string = make_fixed_width_string(with_space);
|
||||
|
||||
|
||||
if (!query_user_string(app, &replace)) return;
|
||||
if (replace.string.size == 0) return;
|
||||
|
||||
|
||||
if (!query_user_string(app, &with)) return;
|
||||
|
||||
|
||||
String r, w;
|
||||
r = replace.string;
|
||||
w = with.string;
|
||||
|
@ -540,7 +611,7 @@ CUSTOM_COMMAND_SIG(replace_in_range){
|
|||
int pos, new_pos;
|
||||
pos = range.min;
|
||||
app->buffer_seek_string(app, &buffer, pos, r.str, r.size, 1, &new_pos);
|
||||
|
||||
|
||||
while (new_pos + r.size < range.end){
|
||||
app->buffer_replace_range(app, &buffer, new_pos, new_pos + r.size, w.str, w.size);
|
||||
range = get_range(&view);
|
||||
|
@ -554,45 +625,45 @@ CUSTOM_COMMAND_SIG(query_replace){
|
|||
char replace_space[1024];
|
||||
replace.prompt = make_lit_string("Replace: ");
|
||||
replace.string = make_fixed_width_string(replace_space);
|
||||
|
||||
|
||||
Query_Bar with;
|
||||
char with_space[1024];
|
||||
with.prompt = make_lit_string("With: ");
|
||||
with.string = make_fixed_width_string(with_space);
|
||||
|
||||
|
||||
if (!query_user_string(app, &replace)) return;
|
||||
if (replace.string.size == 0) return;
|
||||
|
||||
|
||||
if (!query_user_string(app, &with)) return;
|
||||
|
||||
|
||||
String r, w;
|
||||
r = replace.string;
|
||||
w = with.string;
|
||||
|
||||
|
||||
Query_Bar bar;
|
||||
Buffer_Summary buffer;
|
||||
View_Summary view;
|
||||
int pos, new_pos;
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
||||
view = app->get_active_view(app);
|
||||
buffer = app->get_buffer(app, view.buffer_id);
|
||||
|
||||
pos = view.cursor.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){
|
||||
Range match = make_range(new_pos, new_pos + r.size);
|
||||
app->view_set_highlight(app, &view, match.min, match.max, 1);
|
||||
|
||||
|
||||
in = app->get_user_input(app, EventOnAnyKey, EventOnButton);
|
||||
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'){
|
||||
app->buffer_replace_range(app, &buffer, match.min, match.max, w.str, w.size);
|
||||
pos = match.start + w.size;
|
||||
|
@ -600,7 +671,7 @@ CUSTOM_COMMAND_SIG(query_replace){
|
|||
else{
|
||||
pos = match.max;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
buffer.exists;
|
||||
app->get_buffer_next(app, &buffer)){
|
||||
|
||||
|
||||
extension = file_extension(make_string(buffer.file_name, buffer.file_name_len));
|
||||
if (match(extension, make_lit_string("cpp")) ||
|
||||
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);
|
||||
dir.size = app->directory_get_hot(app, dir.str, dir.memory_size);
|
||||
int dir_size = dir.size;
|
||||
|
||||
|
||||
|
||||
// NOTE(allen|a3.4.4): Here we get the list of files in this directory.
|
||||
// Notice that we free_file_list at the end.
|
||||
File_List list = app->get_file_list(app, dir.str, dir.size);
|
||||
|
||||
|
||||
for (int i = 0; i < list.count; ++i){
|
||||
File_Info *info = list.infos + i;
|
||||
if (!info->folder){
|
||||
|
@ -660,12 +730,12 @@ CUSTOM_COMMAND_SIG(open_all_code){
|
|||
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);
|
||||
//push_parameter(app, par_do_in_background, 1);
|
||||
exec_command(app, cmdid_interactive_open);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
app->free_file_list(app, list);
|
||||
}
|
||||
|
||||
|
@ -673,18 +743,18 @@ CUSTOM_COMMAND_SIG(execute_any_cli){
|
|||
Query_Bar bar_out, bar_cmd;
|
||||
String hot_directory;
|
||||
char space[1024], more_space[1024], even_more_space[1024];
|
||||
|
||||
|
||||
bar_out.prompt = make_lit_string("Output Buffer: ");
|
||||
bar_out.string = make_fixed_width_string(space);
|
||||
if (!query_user_string(app, &bar_out)) return;
|
||||
|
||||
|
||||
bar_cmd.prompt = make_lit_string("Command: ");
|
||||
bar_cmd.string = make_fixed_width_string(more_space);
|
||||
if (!query_user_string(app, &bar_cmd)) return;
|
||||
|
||||
|
||||
hot_directory = make_fixed_width_string(even_more_space);
|
||||
hot_directory.size = app->directory_get_hot(app, hot_directory.str, hot_directory.memory_size);
|
||||
|
||||
|
||||
push_parameter(app, par_flags, CLI_OverlapWithConflict);
|
||||
push_parameter(app, par_name, bar_out.string.str, bar_out.string.size);
|
||||
push_parameter(app, par_cli_path, hot_directory.str, hot_directory.size);
|
||||
|
@ -701,9 +771,9 @@ CUSTOM_COMMAND_SIG(execute_arbitrary_command){
|
|||
char space[1024];
|
||||
bar.prompt = make_lit_string("Command: ");
|
||||
bar.string = make_fixed_width_string(space);
|
||||
|
||||
|
||||
if (!query_user_string(app, &bar)) return;
|
||||
|
||||
|
||||
// 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
|
||||
// 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"))){
|
||||
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{
|
||||
// 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
|
||||
// modify the string you passed in to reflect the change in directory if that change was possible.
|
||||
|
||||
|
||||
int keep_going = 1;
|
||||
int old_size;
|
||||
String dir = make_string(app->memory, 0, app->memory_size);
|
||||
dir.size = app->directory_get_hot(app, dir.str, dir.memory_size);
|
||||
|
||||
|
||||
while (keep_going){
|
||||
old_size = dir.size;
|
||||
append(&dir, "build.bat");
|
||||
|
||||
|
||||
if (app->file_exists(app, dir.str, dir.size)){
|
||||
dir.size = old_size;
|
||||
|
||||
|
||||
push_parameter(app, par_flags, CLI_OverlapWithConflict);
|
||||
push_parameter(app, par_name, literal("*compilation*"));
|
||||
push_parameter(app, par_cli_path, dir.str, dir.size);
|
||||
|
||||
|
||||
if (append(&dir, "build")){
|
||||
push_parameter(app, par_cli_command, dir.str, dir.size);
|
||||
exec_command(app, cmdid_command_line);
|
||||
|
@ -829,7 +905,7 @@ CUSTOM_COMMAND_SIG(build_search){
|
|||
else{
|
||||
app->clear_parameters(app);
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
dir.size = old_size;
|
||||
|
@ -842,9 +918,24 @@ CUSTOM_COMMAND_SIG(build_search){
|
|||
// 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){
|
||||
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.
|
||||
|
@ -857,9 +948,9 @@ CUSTOM_COMMAND_SIG(improve_theme){
|
|||
{Stag_Margin_Active, 0xDD0088},
|
||||
{Stag_Cursor, 0xFF0000},
|
||||
};
|
||||
|
||||
|
||||
int count = ArrayCount(colors);
|
||||
|
||||
|
||||
app->set_theme_colors(app, colors, count);
|
||||
}
|
||||
|
||||
|
@ -871,9 +962,9 @@ CUSTOM_COMMAND_SIG(ruin_theme){
|
|||
{Stag_Margin_Active, 0x323232},
|
||||
{Stag_Cursor, 0x00EE00},
|
||||
};
|
||||
|
||||
|
||||
int count = ArrayCount(colors);
|
||||
|
||||
|
||||
app->set_theme_colors(app, colors, count);
|
||||
}
|
||||
|
||||
|
@ -913,7 +1004,7 @@ struct Scroll_Velocity{
|
|||
};
|
||||
|
||||
Scroll_Velocity scroll_velocity_[16] = {0};
|
||||
Scroll_Velocity *scroll_velocity = scroll_velocity_;
|
||||
Scroll_Velocity *scroll_velocity = scroll_velocity_ - 1;
|
||||
|
||||
static int
|
||||
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->y = 1.f;
|
||||
}
|
||||
|
||||
|
||||
if (smooth_camera_step(target_y, scroll_y, &velocity->y, 40.f, 1.f/4.f)){
|
||||
result = 1;
|
||||
}
|
||||
if (smooth_camera_step(target_x, scroll_x, &velocity->x, 40.f, 1.f/4.f)){
|
||||
result = 1;
|
||||
}
|
||||
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
#if Custom_Current == Custom_HandmadeHero
|
||||
# include "4coder_handmade_hero.cpp"
|
||||
# include "power/4coder_handmade_hero.cpp"
|
||||
#endif
|
||||
|
||||
extern "C" GET_BINDING_DATA(get_bindings){
|
||||
Bind_Helper context_actual = begin_bind_helper(data, size);
|
||||
Bind_Helper *context = &context_actual;
|
||||
|
||||
|
||||
#if Custom_Current == Custom_HandmadeHero
|
||||
casey_get_bindings(context);
|
||||
#else
|
||||
|
||||
// NOTE(allen|a3.1): Right now hooks have no loyalties to maps, all hooks are
|
||||
// global and once set they always apply, regardless of what map is active.
|
||||
|
||||
// NOTE(allen|a3.1): Hooks have no loyalties to maps. All hooks are global
|
||||
// and once set they always apply, regardless of what map is active.
|
||||
set_hook(context, hook_start, my_start);
|
||||
set_hook(context, hook_open_file, my_file_settings);
|
||||
//set_hook(context, hook_frame, my_frame); // Example of a frame hook, but disabled by default.
|
||||
|
||||
set_scroll_rule(context, smooth_scroll_rule);
|
||||
|
||||
|
||||
begin_map(context, mapid_global);
|
||||
|
||||
|
||||
bind(context, 'p', MDFR_CTRL, cmdid_open_panel_vsplit);
|
||||
bind(context, '_', MDFR_CTRL, cmdid_open_panel_hsplit);
|
||||
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, 'c', MDFR_ALT, cmdid_open_color_tweaker);
|
||||
bind(context, 'o', MDFR_ALT, open_in_other);
|
||||
|
||||
|
||||
bind(context, 'm', MDFR_ALT, build_search);
|
||||
bind(context, ',', MDFR_ALT, switch_to_compilation);
|
||||
bind(context, 'x', MDFR_ALT, execute_arbitrary_command);
|
||||
bind(context, 'z', MDFR_ALT, execute_any_cli);
|
||||
|
||||
|
||||
// NOTE(allen): These callbacks may not actually be useful to you, but
|
||||
// go look at them and see what they do.
|
||||
bind(context, 'M', MDFR_ALT | MDFR_CTRL, open_my_files);
|
||||
bind(context, 'M', MDFR_ALT, build_at_launch_location);
|
||||
|
||||
|
||||
bind(context, '`', MDFR_ALT, improve_theme);
|
||||
bind(context, '~', MDFR_ALT, ruin_theme);
|
||||
|
||||
|
@ -1021,8 +1114,8 @@ extern "C" GET_BINDING_DATA(get_bindings){
|
|||
inherit_map(context, mapid_file);
|
||||
|
||||
// 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_left, MDFR_CTRL, cmdid_seek_alphanumeric_or_camel_left);
|
||||
bind(context, key_right, MDFR_CTRL, seek_alphanumeric_or_camel_right);
|
||||
bind(context, key_left, MDFR_CTRL, seek_alphanumeric_or_camel_left);
|
||||
|
||||
// NOTE(allen|a3.2): Specific keys can override vanilla keys,
|
||||
// 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, '\t', MDFR_NONE, cmdid_word_complete);
|
||||
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_decrement);
|
||||
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, '9', MDFR_CTRL, paren_wrap);
|
||||
bind(context, 'i', MDFR_ALT, if0_off);
|
||||
|
||||
bind(context, '1', MDFR_ALT, open_file_in_quotes);
|
||||
|
||||
end_map(context);
|
||||
|
||||
|
||||
|
||||
|
||||
begin_map(context, mapid_file);
|
||||
|
||||
|
||||
// NOTE(allen|a3.4.4): Binding this essentially binds
|
||||
// all key combos that would normally insert a character
|
||||
// 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.
|
||||
// It is possible to override this binding for individual keys.
|
||||
bind_vanilla_keys(context, cmdid_write_character);
|
||||
|
||||
|
||||
bind(context, key_left, MDFR_NONE, cmdid_move_left);
|
||||
bind(context, key_right, MDFR_NONE, cmdid_move_right);
|
||||
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_page_up, MDFR_NONE, cmdid_page_up);
|
||||
bind(context, key_page_down, MDFR_NONE, cmdid_page_down);
|
||||
|
||||
bind(context, key_right, MDFR_CTRL, cmdid_seek_whitespace_right);
|
||||
bind(context, key_left, MDFR_CTRL, cmdid_seek_whitespace_left);
|
||||
|
||||
bind(context, key_right, MDFR_CTRL, seek_whitespace_right);
|
||||
bind(context, key_left, MDFR_CTRL, seek_whitespace_left);
|
||||
bind(context, key_up, MDFR_CTRL, cmdid_seek_whitespace_up);
|
||||
bind(context, key_down, MDFR_CTRL, cmdid_seek_whitespace_down);
|
||||
|
||||
|
||||
bind(context, key_up, MDFR_ALT, move_up_10);
|
||||
bind(context, key_down, MDFR_ALT, move_down_10);
|
||||
|
||||
|
||||
bind(context, key_back, MDFR_CTRL, backspace_word);
|
||||
bind(context, key_back, MDFR_ALT, snipe_token_or_word);
|
||||
|
||||
|
||||
bind(context, ' ', MDFR_CTRL, cmdid_set_mark);
|
||||
bind(context, 'm', MDFR_CTRL, cmdid_cursor_mark_swap);
|
||||
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, 'j', MDFR_CTRL, cmdid_to_lowercase);
|
||||
bind(context, '?', MDFR_CTRL, cmdid_toggle_show_whitespace);
|
||||
|
||||
|
||||
bind(context, '~', MDFR_CTRL, cmdid_clean_all_lines);
|
||||
bind(context, '1', MDFR_CTRL, cmdid_eol_dosify);
|
||||
bind(context, '!', MDFR_CTRL, cmdid_eol_nixify);
|
||||
|
||||
|
||||
bind(context, 'f', MDFR_CTRL, search);
|
||||
bind(context, 'r', MDFR_CTRL, reverse_search);
|
||||
bind(context, 'g', MDFR_CTRL, goto_line);
|
||||
bind(context, 'q', MDFR_CTRL, query_replace);
|
||||
bind(context, 'a', MDFR_CTRL, replace_in_range);
|
||||
bind(context, 's', MDFR_ALT, rewrite_as_single_caps);
|
||||
|
||||
|
||||
bind(context, 'K', MDFR_CTRL, cmdid_kill_buffer);
|
||||
bind(context, 'O', MDFR_CTRL, cmdid_reopen);
|
||||
bind(context, 'w', MDFR_CTRL, cmdid_interactive_save_as);
|
||||
bind(context, 's', MDFR_CTRL, cmdid_save);
|
||||
|
||||
|
||||
bind(context, '\n', MDFR_SHIFT, write_and_auto_tab);
|
||||
bind(context, ' ', MDFR_SHIFT, cmdid_write_character);
|
||||
|
||||
|
||||
end_map(context);
|
||||
#endif
|
||||
|
||||
end_bind_helper(context);
|
||||
|
||||
|
||||
return context->write_total;
|
||||
}
|
||||
|
||||
|
|
|
@ -154,28 +154,18 @@ typedef struct File_List{
|
|||
int block_size;
|
||||
} File_List;
|
||||
|
||||
#define MDFR_NONE 0
|
||||
#define MDFR_CTRL 1
|
||||
#define MDFR_ALT 2
|
||||
#define MDFR_SHIFT 4
|
||||
#define MDFR_NONE 0x0
|
||||
#define MDFR_CTRL 0x1
|
||||
#define MDFR_ALT 0x2
|
||||
#define MDFR_SHIFT 0x4
|
||||
|
||||
enum Command_ID{
|
||||
cmdid_null,
|
||||
cmdid_write_character,
|
||||
cmdid_seek_left,
|
||||
cmdid_seek_right,
|
||||
cmdid_seek_whitespace_right,
|
||||
cmdid_seek_whitespace_left,
|
||||
cmdid_seek_whitespace_up,
|
||||
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_set_mark,
|
||||
cmdid_copy,
|
||||
|
@ -206,8 +196,6 @@ enum Command_ID{
|
|||
cmdid_eol_dosify,
|
||||
cmdid_eol_nixify,
|
||||
cmdid_auto_tab_range,
|
||||
cmdid_auto_tab_line_at_cursor,
|
||||
cmdid_auto_tab_whole_file,
|
||||
cmdid_open_panel_vsplit,
|
||||
cmdid_open_panel_hsplit,
|
||||
cmdid_close_panel,
|
||||
|
@ -255,6 +243,7 @@ enum Param_ID{
|
|||
enum Hook_ID{
|
||||
hook_start,
|
||||
hook_open_file,
|
||||
hook_frame,
|
||||
// never below this
|
||||
hook_type_count
|
||||
};
|
||||
|
@ -328,7 +317,7 @@ struct Theme_Color{
|
|||
|
||||
#define GET_BINDING_DATA(name) int name(void *data, int size)
|
||||
#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)
|
||||
|
||||
extern "C"{
|
||||
|
@ -539,8 +528,17 @@ struct Application_Links{
|
|||
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{
|
||||
Get_Binding_Data_Function *get_bindings;
|
||||
_Get_Version_Function *get_alpha_4coder_version;
|
||||
};
|
||||
|
||||
// NOTE(allen): definitions for the buffer that communicates to 4ed.exe
|
||||
|
@ -587,5 +585,3 @@ struct Binding_Unit{
|
|||
} hook;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -153,7 +153,7 @@ inherit_map(Bind_Helper *helper, int mapid){
|
|||
}
|
||||
|
||||
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;
|
||||
unit.type = unit_hook;
|
||||
unit.hook.hook_id = hook_id;
|
||||
|
|
|
@ -1,3 +1,15 @@
|
|||
#define MAJOR 3
|
||||
#define MINOR 4
|
||||
#define PATCH 5
|
||||
#define MAJOR 4
|
||||
#define MINOR 0
|
||||
#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
272
4ed.cpp
|
@ -55,7 +55,7 @@ struct Complete_State{
|
|||
};
|
||||
|
||||
struct Command_Data{
|
||||
App_Models *models;
|
||||
Models *models;
|
||||
struct App_Vars *vars;
|
||||
System_Functions *system;
|
||||
Exchange *exchange;
|
||||
|
@ -71,7 +71,7 @@ struct Command_Data{
|
|||
};
|
||||
|
||||
struct App_Vars{
|
||||
App_Models models;
|
||||
Models models;
|
||||
|
||||
CLI_List cli_processes;
|
||||
|
||||
|
@ -88,7 +88,7 @@ struct App_Vars{
|
|||
};
|
||||
|
||||
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 user_map_count = models->user_map_count;
|
||||
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
|
||||
app_get_map_index(App_Models *models, i32 mapid){
|
||||
app_get_map_index(Models *models, i32 mapid){
|
||||
i32 result;
|
||||
i32 user_map_count = models->user_map_count;
|
||||
i32 *map_id_table = models->map_id_table;
|
||||
|
@ -118,7 +118,7 @@ app_get_map_index(App_Models *models, i32 mapid){
|
|||
}
|
||||
|
||||
internal Command_Map*
|
||||
app_get_map(App_Models *models, i32 mapid){
|
||||
app_get_map(Models *models, i32 mapid){
|
||||
Command_Map *map = 0;
|
||||
if (mapid < mapid_global) map = models->user_maps + mapid;
|
||||
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;
|
||||
|
||||
#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_PANEL(n) Panel *n = command->panel
|
||||
#define USE_VIEW(n) View *n = command->view
|
||||
|
@ -188,7 +188,7 @@ param_stack_end(Partition *part){
|
|||
|
||||
internal View*
|
||||
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;
|
||||
|
||||
Assert(panel->view == 0);
|
||||
|
@ -883,38 +883,6 @@ struct App_Open_File_Result{
|
|||
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){
|
||||
ProfileMomentFunction();
|
||||
USE_MODELS(models);
|
||||
|
@ -964,7 +932,7 @@ COMMAND_DECL(interactive_open){
|
|||
internal void
|
||||
view_file_in_panel(Command_Data *cmd, Panel *panel, Editing_File *file){
|
||||
System_Functions *system = cmd->system;
|
||||
App_Models *models = cmd->models;
|
||||
Models *models = cmd->models;
|
||||
|
||||
Partition old_part;
|
||||
Temp_Memory temp;
|
||||
|
@ -1126,15 +1094,13 @@ COMMAND_DECL(kill_buffer){
|
|||
}
|
||||
|
||||
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;
|
||||
if (file){
|
||||
delayed_kill(delay, file->name.source_path);
|
||||
}
|
||||
file = working_set_get_file(&models->working_set, buffer_id, 1).file;
|
||||
if (file){
|
||||
delayed_kill(delay, 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);
|
||||
if (start_set) range.start = r_start;
|
||||
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(¶m->param.param);
|
||||
switch (p){
|
||||
case par_clear_blank_lines:
|
||||
clear_blank_lines = dynamic_to_bool(¶m->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){
|
||||
ProfileMomentFunction();
|
||||
USE_VARS(vars);
|
||||
|
@ -2091,7 +2021,7 @@ extern "C"{
|
|||
|
||||
GET_PARAMETER_BUFFER_SIG(external_get_parameter_buffer){
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
App_Models *models = cmd->models;
|
||||
Models *models = cmd->models;
|
||||
Buffer_Summary buffer = {};
|
||||
|
||||
if (param_index >= 0 && param_index < models->buffer_param_count){
|
||||
|
@ -2153,7 +2083,7 @@ extern "C"{
|
|||
|
||||
BUFFER_SEEK_STRING_SIG(external_buffer_seek_string){
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
App_Models *models;
|
||||
Models *models;
|
||||
Editing_File *file;
|
||||
Working_Set *working_set;
|
||||
Partition *part;
|
||||
|
@ -2226,7 +2156,7 @@ extern "C"{
|
|||
Editing_File *file;
|
||||
Working_Set *working_set;
|
||||
|
||||
App_Models *models;
|
||||
Models *models;
|
||||
|
||||
int result = 0;
|
||||
int size;
|
||||
|
@ -2435,23 +2365,29 @@ extern "C"{
|
|||
View *vptr;
|
||||
Get_File_Result file;
|
||||
Working_Set *working_set;
|
||||
App_Models *models;
|
||||
Models *models;
|
||||
int result = 0;
|
||||
int view_id;
|
||||
|
||||
if (view->exists){
|
||||
models = cmd->models;
|
||||
live_set = cmd->live_set;
|
||||
vptr = live_set->views + view->view_id;
|
||||
working_set = &models->working_set;
|
||||
file = working_set_get_file(working_set, buffer_id, 1);
|
||||
view_id = view->view_id - 1;
|
||||
if (view_id >= 0 && view_id < live_set->max){
|
||||
vptr = live_set->views + view_id;
|
||||
working_set = &models->working_set;
|
||||
file = working_set_get_file(working_set, buffer_id, 1);
|
||||
|
||||
if (file.file){
|
||||
result = 1;
|
||||
view_set_file(vptr, file.file, models,
|
||||
cmd->system, models->hooks[hook_open_file], &app_links);
|
||||
if (file.file){
|
||||
result = 1;
|
||||
if (file.file != vptr->file){
|
||||
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);
|
||||
|
@ -2647,18 +2583,8 @@ setup_command_table(){
|
|||
SET(write_character);
|
||||
SET(seek_left);
|
||||
SET(seek_right);
|
||||
SET(seek_whitespace_right);
|
||||
SET(seek_whitespace_left);
|
||||
SET(seek_whitespace_up);
|
||||
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(set_mark);
|
||||
SET(copy);
|
||||
|
@ -2688,8 +2614,6 @@ setup_command_table(){
|
|||
SET(eol_dosify);
|
||||
SET(eol_nixify);
|
||||
SET(auto_tab_range);
|
||||
SET(auto_tab_line_at_cursor);
|
||||
SET(auto_tab_whole_file);
|
||||
SET(open_panel_vsplit);
|
||||
SET(open_panel_hsplit);
|
||||
SET(close_panel);
|
||||
|
@ -2715,7 +2639,7 @@ setup_command_table(){
|
|||
// App Functions
|
||||
|
||||
internal void
|
||||
app_hardcode_styles(App_Models *models){
|
||||
app_hardcode_styles(Models *models){
|
||||
Interactive_Style file_info_style;
|
||||
Style *styles, *style;
|
||||
styles = models->styles.styles;
|
||||
|
@ -3120,7 +3044,7 @@ extern "C" SCROLL_RULE_SIG(fallback_scroll_rule){
|
|||
|
||||
App_Init_Sig(app_init){
|
||||
App_Vars *vars;
|
||||
App_Models *models;
|
||||
Models *models;
|
||||
Partition *partition;
|
||||
Panel *panels, *panel;
|
||||
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);
|
||||
}
|
||||
|
||||
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){
|
||||
ProfileStart(OS_syncing);
|
||||
Application_Step_Result app_result = *result;
|
||||
app_result.redraw = force_redraw;
|
||||
|
||||
App_Vars *vars = (App_Vars*)memory->vars_memory;
|
||||
App_Models *models = &vars->models;
|
||||
Models *models = &vars->models;
|
||||
target->partition = &models->mem.part;
|
||||
|
||||
if (first_step || !time_step){
|
||||
|
@ -3715,7 +3671,7 @@ App_Step_Sig(app_step){
|
|||
}
|
||||
}
|
||||
ProfileEnd(prepare_commands);
|
||||
|
||||
|
||||
// NOTE(allen): process the command_coroutine if it is unfinished
|
||||
ProfileStart(command_coroutine);
|
||||
b8 consumed_input[6] = {0};
|
||||
|
@ -3844,7 +3800,15 @@ App_Step_Sig(app_step){
|
|||
update_command_data(vars, cmd);
|
||||
|
||||
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
|
||||
ProfileStart(step);
|
||||
|
||||
|
@ -4191,17 +4155,53 @@ App_Step_Sig(app_step){
|
|||
|
||||
// TODO(allen): Paramter checking in each DACT case.
|
||||
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.file){
|
||||
if (result.sys_id){
|
||||
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->panel = panel;
|
||||
}
|
||||
|
@ -4211,27 +4211,10 @@ App_Step_Sig(app_step){
|
|||
}
|
||||
}
|
||||
else{
|
||||
Assert(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);
|
||||
if (act->type == DACT_OPEN){
|
||||
Assert(result.file);
|
||||
if (!result.file->state.is_loading){
|
||||
view_file_in_panel(cmd, panel, result.file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4325,6 +4308,7 @@ App_Step_Sig(app_step){
|
|||
case DACT_SWITCH:
|
||||
{
|
||||
Editing_File *file = working_set_lookup_file(working_set, string);
|
||||
|
||||
if (file){
|
||||
View *view = panel->view;
|
||||
|
||||
|
@ -4336,18 +4320,15 @@ App_Step_Sig(app_step){
|
|||
|
||||
case DACT_KILL:
|
||||
{
|
||||
Editing_File *file = working_set_lookup_file(working_set, string);
|
||||
if (file){
|
||||
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;
|
||||
|
||||
case DACT_TRY_KILL:
|
||||
{
|
||||
Editing_File *file = 0;
|
||||
file = working_set_lookup_file(working_set, string);
|
||||
|
||||
View *view = 0;
|
||||
if (panel){
|
||||
view = panel->view;
|
||||
|
@ -4356,8 +4337,6 @@ App_Step_Sig(app_step){
|
|||
view = (models->layout.panels + models->layout.active_panel)->view;
|
||||
}
|
||||
|
||||
Assert(view);
|
||||
|
||||
if (file){
|
||||
if (buffer_needs_save(file)){
|
||||
view_show_interactive(system, view, &models->map_ui,
|
||||
|
@ -4366,7 +4345,8 @@ App_Step_Sig(app_step){
|
|||
}
|
||||
else{
|
||||
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;
|
||||
|
|
|
@ -21,7 +21,7 @@ struct App_Settings{
|
|||
b32 lctrl_lalt_is_altgr;
|
||||
};
|
||||
|
||||
struct App_Models{
|
||||
struct Models{
|
||||
Mem_Options mem;
|
||||
App_Settings settings;
|
||||
|
||||
|
@ -37,7 +37,7 @@ struct App_Models{
|
|||
Coroutine *command_coroutine;
|
||||
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_count, buffer_param_max;
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
#include "4ed_version.h"
|
||||
|
||||
#include "4ed_config.h"
|
||||
|
||||
#define BUFFER_EXPERIMENT_SCALPEL 0
|
||||
|
|
|
@ -8,6 +8,7 @@ enum Action_Type{
|
|||
DACT_SWITCH,
|
||||
DACT_TRY_KILL,
|
||||
DACT_KILL,
|
||||
DACT_TOUCH_FILE,
|
||||
};
|
||||
|
||||
struct Delayed_Action{
|
||||
|
@ -48,6 +49,14 @@ delayed_action_(Delay *delay, Action_Type type){
|
|||
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*
|
||||
delayed_action_(Delay *delay, Action_Type type, Panel* panel){
|
||||
Delayed_Action *result;
|
||||
|
@ -57,10 +66,19 @@ delayed_action_(Delay *delay, Action_Type type, Panel* panel){
|
|||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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_try_kill(delay, ...) delayed_action_(delay, DACT_TRY_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__)
|
||||
|
|
42
4ed_file.cpp
42
4ed_file.cpp
|
@ -9,25 +9,6 @@
|
|||
|
||||
// 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"
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL == 0
|
||||
|
@ -360,6 +341,8 @@ internal b32
|
|||
filename_match(String query, Absolutes *absolutes, String filename, b32 case_sensitive){
|
||||
b32 result;
|
||||
result = (query.size == 0);
|
||||
replace_char(query, '\\', '/');
|
||||
replace_char(filename, '\\', '/');
|
||||
if (!result) result = wildcard_match(absolutes, filename, case_sensitive);
|
||||
return result;
|
||||
}
|
||||
|
@ -372,6 +355,8 @@ hot_directory_first_match(Hot_Directory *hot_directory,
|
|||
b32 case_sensitive){
|
||||
Hot_Directory_Match result = {};
|
||||
|
||||
replace_char(str, '\\', '/');
|
||||
|
||||
Absolutes absolutes;
|
||||
if (!exact_match)
|
||||
get_absolutes(str, &absolutes, 1, 1);
|
||||
|
@ -442,6 +427,7 @@ inline Editing_File*
|
|||
working_set_contains(Working_Set *working, String filename){
|
||||
Editing_File *result = 0;
|
||||
i32 id;
|
||||
replace_char(filename, '\\', '/');
|
||||
if (table_find(&working->table, filename, &id)){
|
||||
if (id >= 0 && id <= working->file_max){
|
||||
result = working->files + id;
|
||||
|
@ -450,10 +436,24 @@ working_set_contains(Working_Set *working, String filename){
|
|||
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*
|
||||
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){
|
||||
File_Node *node, *used_nodes;
|
||||
|
|
|
@ -67,7 +67,7 @@ struct View{
|
|||
View *next, *prev;
|
||||
b32 in_use;
|
||||
|
||||
App_Models *models;
|
||||
Models *models;
|
||||
|
||||
Panel *panel;
|
||||
Command_Map *map;
|
||||
|
@ -518,7 +518,7 @@ alloc_for_buffer(void *context, int *size){
|
|||
}
|
||||
|
||||
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){
|
||||
|
||||
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);
|
||||
AllowLocal(init_success);
|
||||
Assert(init_success);
|
||||
|
||||
|
||||
if (buffer_size(&file->state.buffer) < val.size){
|
||||
file->settings.dos_write_mode = 1;
|
||||
}
|
||||
|
||||
file_init_strings(file);
|
||||
file_set_name(working_set, file, (char*)filename);
|
||||
|
||||
|
@ -588,7 +592,7 @@ file_create_from_string(System_Functions *system, App_Models *models,
|
|||
|
||||
internal b32
|
||||
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, {});
|
||||
return (1);
|
||||
|
@ -596,7 +600,7 @@ file_create_empty(System_Functions *system,
|
|||
|
||||
internal b32
|
||||
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);
|
||||
return (1);
|
||||
|
@ -1107,7 +1111,7 @@ file_post_history(General_Memory *general, Editing_File *file,
|
|||
inline Full_Cursor
|
||||
view_compute_cursor_from_pos(View *view, i32 pos){
|
||||
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;
|
||||
|
||||
Full_Cursor result = {};
|
||||
|
@ -1122,7 +1126,7 @@ view_compute_cursor_from_pos(View *view, i32 pos){
|
|||
inline Full_Cursor
|
||||
view_compute_cursor_from_unwrapped_xy(View *view, f32 seek_x, f32 seek_y, b32 round_down = 0){
|
||||
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;
|
||||
|
||||
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
|
||||
view_compute_cursor_from_wrapped_xy(View *view, f32 seek_x, f32 seek_y, b32 round_down = 0){
|
||||
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;
|
||||
|
||||
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
|
||||
view_compute_cursor_from_line_pos(View *view, i32 line, i32 pos){
|
||||
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;
|
||||
|
||||
Full_Cursor result = {};
|
||||
|
@ -1257,18 +1261,21 @@ view_get_cursor_y(View *view){
|
|||
internal void
|
||||
view_set_file(
|
||||
// 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
|
||||
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;
|
||||
|
||||
// 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);
|
||||
view->font_advance = fnt_info->advance;
|
||||
view->font_height = fnt_info->height;
|
||||
|
||||
|
||||
// NOTE(allen): Stuff that doesn't assume file exists.
|
||||
view->file = file;
|
||||
view->cursor = {};
|
||||
|
@ -1296,10 +1303,13 @@ view_set_file(
|
|||
file->settings.is_initialized = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(allen): Fix this:
|
||||
view->ui_state = {};
|
||||
view->showing_ui = VUI_None;
|
||||
|
||||
if (set_vui){
|
||||
// TODO(allen): Fix this! There should be a way to easily separate setting a file,
|
||||
// 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{
|
||||
|
@ -1389,7 +1399,7 @@ file_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step
|
|||
History_Mode history_mode){
|
||||
if (!file->state.undo.undo.edits) return;
|
||||
General_Memory *general = &mem->general;
|
||||
|
||||
|
||||
b32 can_merge = 0, do_merge = 0;
|
||||
switch (step.type){
|
||||
case ED_NORMAL:
|
||||
|
@ -1571,7 +1581,7 @@ file_edit_cursor_fix(System_Functions *system,
|
|||
Partition *part, General_Memory *general,
|
||||
Editing_File *file, Editing_Layout *layout,
|
||||
Cursor_Fix_Descriptor desc){
|
||||
|
||||
|
||||
Full_Cursor temp_cursor;
|
||||
Temp_Memory cursor_temp = begin_temp_memory(part);
|
||||
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;
|
||||
i32 cursor_count = 0;
|
||||
|
||||
|
||||
View *view;
|
||||
Panel *panel, *used_panels;
|
||||
used_panels = &layout->used_sentinel;
|
||||
|
||||
|
||||
for (dll_items(panel, used_panels)){
|
||||
view = panel->view;
|
||||
if (view->file == file){
|
||||
|
@ -1606,14 +1616,14 @@ file_edit_cursor_fix(System_Functions *system,
|
|||
desc.shift_amount + (desc.end - desc.start));
|
||||
}
|
||||
buffer_unsort_cursors(cursors, cursor_count);
|
||||
|
||||
|
||||
cursor_count = 0;
|
||||
for (dll_items(panel, used_panels)){
|
||||
view = panel->view;
|
||||
if (view && view->file == file){
|
||||
view_cursor_move(view, cursors[cursor_count++].pos);
|
||||
view->preferred_x = view_get_cursor_x(view);
|
||||
|
||||
|
||||
view->mark = cursors[cursor_count++].pos + 1;
|
||||
i32 new_scroll_i = cursors[cursor_count++].pos + 1;
|
||||
if (view->scroll_i != new_scroll_i){
|
||||
|
@ -1635,20 +1645,20 @@ file_edit_cursor_fix(System_Functions *system,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
end_temp_memory(cursor_temp);
|
||||
}
|
||||
|
||||
internal void
|
||||
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){
|
||||
ProfileMomentFunction();
|
||||
if (!use_high_permission && file->settings.read_only) return;
|
||||
|
||||
|
||||
Mem_Options *mem = &models->mem;
|
||||
Editing_Layout *layout = &models->layout;
|
||||
|
||||
|
||||
// NOTE(allen): fixing stuff beforewards????
|
||||
file_update_history_before_edit(mem, file, spec.step, spec.str, history_mode);
|
||||
file_pre_edit_maintenance(system, &mem->general, file);
|
||||
|
@ -1692,7 +1702,7 @@ file_do_single_edit(System_Functions *system,
|
|||
|
||||
Panel *panel, *used_panels;
|
||||
used_panels = &layout->used_sentinel;
|
||||
|
||||
|
||||
for (dll_items(panel, used_panels)){
|
||||
View *view = panel->view;
|
||||
if (view->file == file){
|
||||
|
@ -1716,19 +1726,19 @@ file_do_single_edit(System_Functions *system,
|
|||
}
|
||||
|
||||
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){
|
||||
ProfileMomentFunction();
|
||||
if (!use_high_permission && file->settings.read_only) return;
|
||||
|
||||
Mem_Options *mem = &models->mem;
|
||||
Editing_Layout *layout = &models->layout;
|
||||
|
||||
|
||||
// NOTE(allen): fixing stuff "beforewards"???
|
||||
Assert(spec.str == 0);
|
||||
file_update_history_before_edit(mem, file, spec.step, 0, history_mode);
|
||||
file_pre_edit_maintenance(system, &mem->general, file);
|
||||
|
||||
|
||||
// NOTE(allen): actual text replacement
|
||||
General_Memory *general = &mem->general;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
// NOTE(allen): token fixing
|
||||
if (file->state.tokens_complete){
|
||||
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
|
||||
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){
|
||||
Edit_Spec spec = {};
|
||||
spec.step.type = ED_NORMAL;
|
||||
|
@ -1817,7 +1827,7 @@ file_replace_range(System_Functions *system, App_Models *models, Editing_File *f
|
|||
}
|
||||
|
||||
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){
|
||||
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
|
||||
view_undo_redo(System_Functions *system,
|
||||
App_Models *models, View *view,
|
||||
Models *models, View *view,
|
||||
Edit_Stack *stack, Edit_Type expected_type){
|
||||
Editing_File *file = view->file;
|
||||
|
||||
|
||||
if (stack->edit_count > 0){
|
||||
Edit_Step step = stack->edits[stack->edit_count-1];
|
||||
|
||||
|
@ -1868,12 +1878,12 @@ view_undo_redo(System_Functions *system,
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -1942,7 +1952,7 @@ file_dump_history(System_Functions *system, Mem_Options *mem, Editing_File *file
|
|||
#endif
|
||||
|
||||
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);
|
||||
|
||||
Editing_File *file = view->file;
|
||||
|
@ -2138,17 +2148,17 @@ file_compute_whitespace_edit(Mem_Options *mem, Editing_File *file, i32 cursor_po
|
|||
}
|
||||
|
||||
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;
|
||||
Editing_File *file = view->file;
|
||||
|
||||
|
||||
Partition *part = &mem->part;
|
||||
i32 line_count = file->state.buffer.line_count;
|
||||
i32 edit_max = line_count * 2;
|
||||
i32 edit_count = 0;
|
||||
|
||||
|
||||
Assert(file && !file->state.is_dummy);
|
||||
|
||||
|
||||
Temp_Memory temp = begin_temp_memory(part);
|
||||
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
|
||||
view_auto_tab_tokens(System_Functions *system,
|
||||
App_Models *models, View *view,
|
||||
Models *models, View *view,
|
||||
i32 start, i32 end, b32 empty_blank_lines){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
Editing_File *file = view->file;
|
||||
|
@ -2575,9 +2585,9 @@ view_show_config(View *fview, Command_Map *gui_map){
|
|||
inline void
|
||||
view_show_interactive(System_Functions *system, View *view, Command_Map *gui_map,
|
||||
Interactive_Action action, Interactive_Interaction interaction, String query){
|
||||
|
||||
App_Models *models = view->models;
|
||||
|
||||
|
||||
Models *models = view->models;
|
||||
|
||||
view->ui_state = {};
|
||||
view->map_for_file = view->map;
|
||||
view->map = gui_map;
|
||||
|
@ -2595,12 +2605,13 @@ view_show_interactive(System_Functions *system, View *view, Command_Map *gui_map
|
|||
}
|
||||
|
||||
inline void
|
||||
view_show_theme(View *fview, Command_Map *gui_map){
|
||||
fview->ui_state = {};
|
||||
fview->map_for_file = fview->map;
|
||||
fview->map = gui_map;
|
||||
fview->showing_ui = VUI_Theme;
|
||||
fview->color_mode = CV_Mode_Library;
|
||||
view_show_theme(View *view, Command_Map *gui_map){
|
||||
view->ui_state = {};
|
||||
view->map_for_file = view->map;
|
||||
view->map = gui_map;
|
||||
view->showing_ui = VUI_Theme;
|
||||
view->color_mode = CV_Mode_Library;
|
||||
view->color = super_color_create(0xFF000000);
|
||||
}
|
||||
|
||||
inline void
|
||||
|
@ -2617,30 +2628,34 @@ view_show_file(View *view, Command_Map *file_map){
|
|||
|
||||
internal void
|
||||
interactive_view_complete(View *view){
|
||||
Models *models = view->models;
|
||||
Panel *panel = view->panel;
|
||||
App_Models *models = view->models;
|
||||
Editing_File *file = 0;
|
||||
Editing_File *old_file = view->file;
|
||||
|
||||
switch (view->action){
|
||||
case IAct_Open:
|
||||
delayed_open(&models->delay1, models->hot_directory.string, panel);
|
||||
delayed_touch_file(&models->delay1, old_file);
|
||||
break;
|
||||
|
||||
case IAct_Save_As:
|
||||
delayed_save_as(&models->delay1, models->hot_directory.string, panel);
|
||||
file = view->file;
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
case IAct_Switch:
|
||||
delayed_switch(&models->delay1, view->dest, panel);
|
||||
delayed_touch_file(&models->delay1, old_file);
|
||||
break;
|
||||
|
||||
case IAct_Kill:
|
||||
delayed_try_kill(&models->delay1, view->dest, panel);
|
||||
file = view->file;
|
||||
break;
|
||||
|
||||
case IAct_Sure_To_Kill:
|
||||
|
@ -2649,7 +2664,8 @@ interactive_view_complete(View *view){
|
|||
delayed_kill(&models->delay1, view->dest, panel);
|
||||
break;
|
||||
|
||||
case 1:break;
|
||||
case 1:
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// 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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -2677,9 +2696,9 @@ update_highlighting(View *view){
|
|||
view->highlight = {};
|
||||
return;
|
||||
}
|
||||
|
||||
App_Models *models = view->models;
|
||||
|
||||
|
||||
Models *models = view->models;
|
||||
|
||||
Style *style = &models->style;
|
||||
i32 pos = view_get_cursor_pos(file_view);
|
||||
char c = buffer_get_char(&file->state.buffer, pos);
|
||||
|
@ -2749,7 +2768,7 @@ internal b32
|
|||
theme_library_shit(System_Functions *system, Exchange *exchange,
|
||||
View *view, UI_State *state, UI_Layout *layout){
|
||||
|
||||
App_Models *models = view->models;
|
||||
Models *models = view->models;
|
||||
Mem_Options *mem = &models->mem;
|
||||
|
||||
i32 result = 0;
|
||||
|
@ -2999,11 +3018,11 @@ theme_library_shit(System_Functions *system, Exchange *exchange,
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
App_Models *models = view->models;
|
||||
|
||||
Models *models = view->models;
|
||||
|
||||
Style *style = &models->style;
|
||||
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 Pop 2");
|
||||
|
||||
view->color = ui.color;
|
||||
|
||||
return result;
|
||||
*color = ui.hover_color;
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
internal b32
|
||||
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;
|
||||
|
||||
if (view != active){
|
||||
|
@ -3152,7 +3171,7 @@ theme_shit(System_Functions *system, Exchange *exchange,
|
|||
break;
|
||||
|
||||
case CV_Mode_Adjusting:
|
||||
if (theme_adjusting_shit(view, state, layout)){
|
||||
if (theme_adjusting_shit(view, state, layout, color)){
|
||||
result = 1;
|
||||
}
|
||||
break;
|
||||
|
@ -3167,8 +3186,8 @@ interactive_shit(System_Functions *system, View *view, UI_State *state, UI_Layou
|
|||
b32 new_dir = 0;
|
||||
b32 complete = 0;
|
||||
|
||||
App_Models *models = view->models;
|
||||
|
||||
Models *models = view->models;
|
||||
|
||||
do_label(state, layout, view->query, 1.f);
|
||||
|
||||
b32 case_sensitive = 0;
|
||||
|
@ -3268,8 +3287,8 @@ menu_shit(View *view, UI_State *state, UI_Layout *layout){
|
|||
internal void
|
||||
config_shit(View *view, UI_State *state, UI_Layout *layout){
|
||||
i32 id = 0;
|
||||
App_Models *models = view->models;
|
||||
|
||||
Models *models = view->models;
|
||||
|
||||
do_label(state, layout, literal("Config"), 2.f);
|
||||
|
||||
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
|
||||
do_file_bar(View *view, Editing_File *file, UI_Layout *layout, Render_Target *target){
|
||||
Interactive_Bar bar;
|
||||
App_Models *models = view->models;
|
||||
File_Bar bar;
|
||||
Models *models = view->models;
|
||||
Style_Font *font = &models->global_font;
|
||||
i32 line_height = view->font_height;
|
||||
Interactive_Style bar_style = models->style.main.file_info_style;
|
||||
|
||||
u32 back_color = bar_style.bar_color;
|
||||
u32 base_color = bar_style.base_color;
|
||||
u32 pop1_color = bar_style.pop1_color;
|
||||
u32 pop2_color = bar_style.pop2_color;
|
||||
|
||||
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);
|
||||
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){
|
||||
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{
|
||||
char line_number_space[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);
|
||||
|
||||
|
||||
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){
|
||||
switch (buffer_get_sync(file)){
|
||||
case SYNC_BEHIND_OS:
|
||||
|
@ -3372,7 +3423,7 @@ internal i32
|
|||
step_file_view(System_Functions *system, Exchange *exchange, View *view, i32_Rect rect,
|
||||
b32 is_active, Input_Summary *user_input){
|
||||
|
||||
App_Models *models = view->models;
|
||||
Models *models = view->models;
|
||||
i32 result = 0;
|
||||
Editing_File *file = view->file;
|
||||
|
||||
|
@ -3519,11 +3570,13 @@ step_file_view(System_Functions *system, Exchange *exchange, View *view, i32_Rec
|
|||
UI_Layout layout;
|
||||
begin_layout(&layout, rect);
|
||||
|
||||
Super_Color color = {};
|
||||
|
||||
switch (view->showing_ui){
|
||||
case VUI_None: break;
|
||||
case VUI_Theme:
|
||||
{
|
||||
theme_shit(system, exchange, view, 0, &state, &layout);
|
||||
theme_shit(system, exchange, view, 0, &state, &layout, &color);
|
||||
}break;
|
||||
case VUI_Interactive:
|
||||
{
|
||||
|
@ -3539,19 +3592,26 @@ step_file_view(System_Functions *system, Exchange *exchange, View *view, i32_Rec
|
|||
{
|
||||
config_shit(view, &state, &layout);
|
||||
}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;
|
||||
}
|
||||
if (did_activation){
|
||||
if (view->showing_ui == VUI_Theme){
|
||||
view->color = color;
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal i32
|
||||
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;
|
||||
Style *style = &models->style;
|
||||
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,
|
||||
Render_Target *target, Input_Summary *user_input){
|
||||
|
||||
App_Models *models = view->models;
|
||||
Models *models = view->models;
|
||||
Editing_File *file = view->file;
|
||||
i32 result = 0;
|
||||
|
||||
|
@ -3776,7 +3836,9 @@ draw_file_view(System_Functions *system, Exchange *exchange,
|
|||
begin_layout(&layout, rect);
|
||||
|
||||
rect.y0 -= widget_height;
|
||||
|
||||
|
||||
Super_Color color = {};
|
||||
|
||||
switch (view->showing_ui){
|
||||
case VUI_None:
|
||||
{
|
||||
|
@ -3790,7 +3852,7 @@ draw_file_view(System_Functions *system, Exchange *exchange,
|
|||
|
||||
case VUI_Theme:
|
||||
{
|
||||
theme_shit(system, exchange, view, active, &state, &layout);
|
||||
theme_shit(system, exchange, view, active, &state, &layout, &color);
|
||||
}break;
|
||||
|
||||
case VUI_Interactive:
|
||||
|
@ -3816,18 +3878,32 @@ draw_file_view(System_Functions *system, Exchange *exchange,
|
|||
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
|
||||
kill_file(System_Functions *system, Exchange *exchange,
|
||||
App_Models *models, Editing_File *file){
|
||||
kill_file(System_Functions *system, Exchange *exchange, 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);
|
||||
file_view_iter_good(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
|
||||
|
@ -4046,7 +4122,7 @@ struct Live_Views{
|
|||
};
|
||||
|
||||
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 = {};
|
||||
|
||||
Assert(live_set->count < live_set->max);
|
||||
|
|
115
4ed_gui.cpp
115
4ed_gui.cpp
|
@ -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{
|
||||
b8 hit_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;
|
||||
}
|
||||
|
||||
|
||||
struct Super_Color{
|
||||
Vec4 hsla;
|
||||
Vec4 rgba;
|
||||
|
|
|
@ -154,6 +154,7 @@ char *daction_enum[] = {
|
|||
"SWITCH",
|
||||
"TRY_KILL",
|
||||
"KILL",
|
||||
"TOUCH_FILE",
|
||||
};
|
||||
|
||||
char str_alloc_copy[] =
|
||||
|
@ -186,8 +187,10 @@ enum Daction_Field_Handle{
|
|||
dfph_integer,
|
||||
};
|
||||
Daction_Field_Handle dact_param_sets[] = {
|
||||
dfph_panel, 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_file, dfph_null,
|
||||
dfph_panel, dfph_integer, dfph_null,
|
||||
|
@ -307,51 +310,6 @@ char* generate_delayed_action(){
|
|||
return(filename);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#define MAJOR 3
|
||||
#define MINOR 4
|
||||
#define PATCH 5
|
||||
|
||||
#define VERS3__(a,b,c) #a"."#b"."#c
|
||||
#define VERS3_(a,b,c) VERS3__(a,b,c)
|
||||
#define VERS3 VERS3_(MAJOR, MINOR, PATCH)
|
||||
|
||||
#define VERSION_STRING VERS3
|
||||
|
||||
char version_header[] =
|
||||
"#define MAJOR %d\n"
|
||||
"#define MINOR %d\n"
|
||||
"#define PATCH %d\n"
|
||||
"#define VERSION_NUMBER \"alpha %s\"\n"
|
||||
"#ifdef FRED_SUPER\n"
|
||||
"#define VERSION_TYPE \" super!\"\n"
|
||||
"#else\n"
|
||||
"#define VERSION_TYPE \"\"\n"
|
||||
"#endif\n"
|
||||
"#define VERSION VERSION_NUMBER VERSION_TYPE\n";
|
||||
|
||||
char version_custom[] =
|
||||
"#define MAJOR %d\n"
|
||||
"#define MINOR %d\n"
|
||||
"#define PATCH %d\n";
|
||||
|
||||
char* generate_version(){
|
||||
char *filename = "4ed_version.h & 4coder_version.h";
|
||||
char filename_header[] = "4ed_version.h";
|
||||
char filename_custom[] = "4coder_version.h";
|
||||
FILE *file;
|
||||
|
||||
file = fopen(filename_header, "wb");
|
||||
fprintf(file, version_header, MAJOR, MINOR, PATCH, VERSION_STRING);
|
||||
fclose(file);
|
||||
|
||||
file = fopen(filename_custom, "wb");
|
||||
fprintf(file, version_custom, MAJOR, MINOR, PATCH);
|
||||
fclose(file);
|
||||
|
||||
return(filename);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
char* bar_style_fields[] = {
|
||||
"bar",
|
||||
|
@ -496,9 +454,6 @@ int main(){
|
|||
filename = generate_delayed_action();
|
||||
printf("gen success: %s\n", filename);
|
||||
|
||||
filename = generate_version();
|
||||
printf("gen success: %s\n", filename);
|
||||
|
||||
filename = generate_style();
|
||||
printf("gen success: %s\n", filename);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,15 @@ dll_insert(T *pos, T *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>
|
||||
inline void
|
||||
dll_remove(T *v){
|
||||
|
|
|
@ -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
|
|
@ -1,4 +1,4 @@
|
|||
@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
|
||||
|
|
|
@ -7,7 +7,7 @@ SET clset=64
|
|||
SET WARNINGS=/W4 /wd4310 /wd4100 /wd4201 /wd4505 /wd4996 /wd4127 /wd4510 /wd4512 /wd4610 /WX
|
||||
SET STUFF=/GR- /nologo
|
||||
SET DEBUG=/Zi
|
||||
SET EXPORTS=/EXPORT:get_bindings
|
||||
SET EXPORTS=/EXPORT:get_bindings /EXPORT:get_alpha_4coder_version
|
||||
SET SRC=4coder_custom.cpp
|
||||
REM SET LINKS=user32.lib gdi32.lib
|
||||
SET LINKS=
|
||||
|
|
|
@ -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
|
||||
for me to switch!
|
||||
- Display:
|
||||
- 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
|
||||
- Cursor setting seems to do no movement first time, and then weird scrolling behavior on
|
||||
jump-to-same-line subsequently
|
||||
|
||||
- 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.
|
||||
- Need auto-complete for things like "arbitrary command", with options listed, etc.,
|
||||
so this should either be built into 4ed, or the custom DLL should have the ability
|
||||
to display possible completions and iterate over internal cmdid's, etc. Possibly
|
||||
the latter, for maximal ability of customizers to add their own commands?
|
||||
|
||||
- Macro recording/playback
|
||||
|
||||
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
|
||||
to be something very obvious - ideally something like
|
||||
1) Change the cursor color
|
||||
2) X
|
||||
3) X
|
||||
4) Change the header bar color?
|
||||
2) 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
|
||||
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 <stdio.h>
|
||||
|
||||
|
@ -273,6 +289,7 @@ HOOK_SIG(casey_start)
|
|||
exec_command(app, cmdid_open_panel_vsplit);
|
||||
app->change_theme(app, literal("Handmade Hero"));
|
||||
app->change_font(app, literal("liberation mono"));
|
||||
return(0);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
@ -307,12 +324,17 @@ CUSTOM_COMMAND_SIG(casey_switch_buffer_other_window)
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
int pos1 = view.cursor.pos;
|
||||
|
||||
|
@ -324,12 +346,12 @@ DeleteAfterCommand(struct Application_Links *app, Command_ID CommandID)
|
|||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
@ -362,21 +384,38 @@ CUSTOM_COMMAND_SIG(casey_paste_and_tab)
|
|||
CUSTOM_COMMAND_SIG(casey_seek_beginning_of_line_and_tab)
|
||||
{
|
||||
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
|
||||
{
|
||||
bool Switched;
|
||||
bool Loaded;
|
||||
View_Summary view;
|
||||
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
|
||||
SwitchToOrLoadFile(struct Application_Links *app, String FileName, bool CreateIfNotFound = false)
|
||||
{
|
||||
switch_to_result Result = {};
|
||||
|
||||
SanitizeSlashes(FileName);
|
||||
|
||||
View_Summary view = app->get_active_view(app);
|
||||
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.Loaded = true;
|
||||
Result.Switched = true;
|
||||
}
|
||||
}
|
||||
|
@ -412,6 +452,8 @@ CUSTOM_COMMAND_SIG(casey_load_todo)
|
|||
SwitchToOrLoadFile(app, ToDoFileName, true);
|
||||
}
|
||||
|
||||
inline String Empty() {String Result = {}; return(Result);}
|
||||
|
||||
CUSTOM_COMMAND_SIG(casey_load_handmade)
|
||||
{
|
||||
// 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);
|
||||
|
||||
size_t Size = range.max - range.min;
|
||||
if (Size == 0) return;
|
||||
|
||||
char *Stuff = (char *)malloc(Size + 1);
|
||||
Stuff[Size] = 0;
|
||||
|
||||
|
@ -875,7 +915,106 @@ CUSTOM_COMMAND_SIG(casey_quick_calc)
|
|||
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[] = {
|
||||
{Stag_Cursor, 0x40FF40},
|
||||
|
@ -897,8 +1036,6 @@ CUSTOM_COMMAND_SIG(modal_toggle)
|
|||
{Stag_Bar, 0x934420}
|
||||
};
|
||||
|
||||
GlobalEditMode = !GlobalEditMode;
|
||||
|
||||
if (GlobalEditMode){
|
||||
app->set_theme_colors(app, edit_colors, ArrayCount(edit_colors));
|
||||
}
|
||||
|
@ -911,30 +1048,18 @@ CUSTOM_COMMAND_SIG(modal_toggle)
|
|||
GetClientRect(GlobalModalIndicator, &Rect);
|
||||
InvalidateRect(GlobalModalIndicator, &Rect, FALSE);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(casey_arbitrary_command){
|
||||
Query_Bar bar;
|
||||
char space[1024];
|
||||
bar.prompt = make_lit_string("Command: ");
|
||||
bar.string = make_fixed_width_string(space);
|
||||
CUSTOM_COMMAND_SIG(begin_free_typing)
|
||||
{
|
||||
GlobalEditMode = false;
|
||||
UpdateModalIndicator(app);
|
||||
}
|
||||
|
||||
if (!query_user_string(app, &bar)) return;
|
||||
app->end_query_bar(app, &bar, 0);
|
||||
|
||||
if (match(bar.string, make_lit_string("build search"))){
|
||||
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
|
||||
}
|
||||
CUSTOM_COMMAND_SIG(end_free_typing)
|
||||
{
|
||||
GlobalEditMode = true;
|
||||
UpdateModalIndicator(app);
|
||||
}
|
||||
|
||||
#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_w, cmdid_cut);
|
||||
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_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_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_5, 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_0, cmdid_kill_buffer);
|
||||
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_up, cmdid_move_up, cmdid_move_up);
|
||||
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_right, cmdid_seek_white_or_token_right, cmdid_move_right);
|
||||
DEFINE_BIMODAL_KEY(modal_left, seek_white_or_token_left, cmdid_move_left);
|
||||
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_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_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_escape, cmdid_write_character, cmdid_write_character); // TODO(casey): Available
|
||||
DEFINE_BIMODAL_KEY(modal_tab, cmdid_word_complete, cmdid_word_complete);
|
||||
|
||||
HOOK_SIG(casey_file_settings)
|
||||
|
@ -1031,21 +1155,30 @@ HOOK_SIG(casey_file_settings)
|
|||
Buffer_Summary buffer = app->get_parameter_buffer(app, 0);
|
||||
|
||||
int treat_as_code = 0;
|
||||
int treat_as_project = 0;
|
||||
|
||||
if (buffer.file_name && buffer.size < (16 << 20))
|
||||
{
|
||||
String ext = file_extension(make_string(buffer.file_name, buffer.file_name_len));
|
||||
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_wrap_lines, !treat_as_code);
|
||||
push_parameter(app, par_key_mapid, (treat_as_code)?((int)my_code_map):((int)mapid_file));
|
||||
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,
|
||||
// incase anyone would like to hack 4coder again.
|
||||
// NOTE(allen): This was a bit of fun so I'll leave it in, for anyone would like to hack 4coder again.
|
||||
#if UseHack4Coder
|
||||
internal void
|
||||
hack_place_modal_indicator(void)
|
||||
|
@ -1116,7 +1249,7 @@ modal_indicator_window_callback(HWND Window,
|
|||
internal 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);
|
||||
|
||||
WNDCLASSA WindowClass = {};
|
||||
|
@ -1172,14 +1305,10 @@ casey_get_bindings(Bind_Helper *context)
|
|||
bind(context, 't', MDFR_NONE, casey_load_todo);
|
||||
bind(context, '/', MDFR_NONE, cmdid_change_active_panel);
|
||||
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, '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.
|
||||
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(context, key_insert, MDFR_NONE, modal_toggle);
|
||||
bind(context, '`', MDFR_NONE, modal_toggle);
|
||||
bind(context, key_insert, MDFR_NONE, begin_free_typing);
|
||||
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_SHIFT, casey_newline_and_indent);
|
||||
|
||||
bind(context, 't', MDFR_CTRL, cmdid_timeline_scrub);
|
||||
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
// TOP
|
||||
|
||||
#include "4ed_version.h"
|
||||
#include "4ed_config.h"
|
||||
|
||||
#include "4ed_meta.h"
|
||||
|
@ -434,6 +433,7 @@ Sys_Set_File_List_Sig(system_set_file_list){
|
|||
info->filename.size = i;
|
||||
info->filename.memory_size = info->filename.size + 1;
|
||||
*name++ = 0;
|
||||
replace_char(info->filename, '\\', '/');
|
||||
++info;
|
||||
}
|
||||
more_files = FindNextFile(search, &find_data);
|
||||
|
@ -1082,7 +1082,7 @@ Win32LoadSystemCode(){
|
|||
win32vars.system->internal_debug_message = INTERNAL_system_debug_message;
|
||||
#endif
|
||||
|
||||
win32vars.system->slash = '\\';
|
||||
win32vars.system->slash = '/';
|
||||
}
|
||||
|
||||
#include "system_shared.cpp"
|
||||
|
@ -1685,6 +1685,7 @@ main(int argc, char **argv){
|
|||
|
||||
String current_directory = make_string(current_directory_mem, written, required);
|
||||
terminate_with_null(¤t_directory);
|
||||
replace_char(current_directory, '\\', '/');
|
||||
|
||||
Command_Line_Parameters clparams;
|
||||
clparams.argv = argv;
|
||||
|
@ -1710,6 +1711,36 @@ main(int argc, char **argv){
|
|||
printf("%.*s", output_size, memory_vars.target_memory);
|
||||
}
|
||||
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();
|
||||
|
||||
sysshared_filter_real_files(files, file_count);
|
||||
|
@ -1727,25 +1758,6 @@ main(int argc, char **argv){
|
|||
|
||||
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){
|
||||
win32vars.custom_api.get_bindings = (Get_Binding_Data_Function*)get_bindings;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue