Fixed several bugs, setup regression tests, working on organizing code for aggressive cleanup

This commit is contained in:
Allen Webster 2018-03-24 03:06:45 -07:00
parent 294c87a306
commit 17704c6036
44 changed files with 8410 additions and 8121 deletions

View File

@ -1099,6 +1099,46 @@ CUSTOM_DOC("Deletes the file of the current buffer if 4coder has the appropriate
} }
} }
CUSTOM_COMMAND_SIG(save_to_query)
CUSTOM_DOC("Queries the user for a name and saves the contents of the current buffer, altering the buffer's name too.")
{
View_Summary view = get_active_view(app, AccessAll);
Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessAll);
// Query the user
Query_Bar bar;
char prompt_space[4096];
bar.prompt = make_fixed_width_string(prompt_space);
append(&bar.prompt, "Save '");
append(&bar.prompt, make_string(buffer.buffer_name, buffer.buffer_name_len));
append(&bar.prompt, "' to: ");
char name_space[4096];
bar.string = make_fixed_width_string(name_space);
if (!query_user_string(app, &bar)) return;
if (bar.string.size == 0) return;
char new_file_name_space[4096];
String new_file_name = make_fixed_width_string(new_file_name_space);
int32_t hot_dir_size = directory_get_hot(app, 0, 0);
if (new_file_name.size + hot_dir_size <= new_file_name.memory_size){
new_file_name.size += directory_get_hot(app, new_file_name.str + new_file_name.size, new_file_name.memory_size - new_file_name.size);
//append(&new_file_name, "/");
if (append(&new_file_name, bar.string)){
if (save_buffer(app, &buffer, new_file_name.str, new_file_name.size, BufferSave_IgnoreDirtyFlag)){
Buffer_Summary new_buffer = create_buffer(app, new_file_name.str, new_file_name.size, BufferCreate_NeverNew|BufferCreate_JustChangedFile);
if (new_buffer.exists){
if (new_buffer.buffer_id != buffer.buffer_id){
kill_buffer(app, buffer_identifier(buffer.buffer_id), 0, BufferKill_AlwaysKill);
view_set_buffer(app, &view, new_buffer.buffer_id, 0);
}
}
}
}
}
}
CUSTOM_COMMAND_SIG(rename_file_query) CUSTOM_COMMAND_SIG(rename_file_query)
CUSTOM_DOC("Queries the user for a new name and renames the file of the current buffer, altering the buffer's name too.") CUSTOM_DOC("Queries the user for a new name and renames the file of the current buffer, altering the buffer's name too.")
{ {

View File

@ -293,7 +293,7 @@ OPEN_FILE_HOOK_SIG(default_file_settings){
buffer_set_setting(app, &buffer, BufferSetting_LexWithoutStrings, true); buffer_set_setting(app, &buffer, BufferSetting_LexWithoutStrings, true);
buffer_set_setting(app, &buffer, BufferSetting_VirtualWhitespace, true); buffer_set_setting(app, &buffer, BufferSetting_VirtualWhitespace, true);
} }
else if (treat_as_code && enable_code_wrapping && buffer.size < (512 << 10)){ else if (treat_as_code && enable_code_wrapping && buffer.size < (128 << 10)){
// NOTE(allen|a4.0.12): There is a little bit of grossness going on here. // NOTE(allen|a4.0.12): There is a little bit of grossness going on here.
// If we set BufferSetting_Lex to true, it will launch a lexing job. // If we set BufferSetting_Lex to true, it will launch a lexing job.
// If a lexing job is active when we set BufferSetting_VirtualWhitespace, the call can fail. // If a lexing job is active when we set BufferSetting_VirtualWhitespace, the call can fail.

View File

@ -354,15 +354,15 @@ CUSTOM_DOC("Create a copy of the line on which the cursor sits.")
Temp_Memory temp = begin_temp_memory(part); Temp_Memory temp = begin_temp_memory(part);
String line_string = {0}; String line_string = {0};
read_line(app, part, &buffer, view.cursor.line, &line_string); char *before_line = push_array(part, char, 1);
if (read_line(app, part, &buffer, view.cursor.line, &line_string)){
push_array(part, char, 1); *before_line = '\n';
++line_string.memory_size; line_string.str = before_line;
append_s_char(&line_string, '\n'); line_string.size += 1;
int32_t pos = buffer_get_line_end(app, &buffer, view.cursor.line) + 1;
buffer_replace_range(app, &buffer, pos, pos, line_string.str, line_string.size);
int32_t pos = buffer_get_line_end(app, &buffer, view.cursor.line);
buffer_replace_range(app, &buffer, pos, pos, line_string.str, line_string.size);
}
end_temp_memory(temp); end_temp_memory(temp);
} }

View File

@ -1,7 +1,7 @@
#define command_id(c) (fcoder_metacmd_ID_##c) #define command_id(c) (fcoder_metacmd_ID_##c)
#define command_metadata(c) (&fcoder_metacmd_table[command_id(c)]) #define command_metadata(c) (&fcoder_metacmd_table[command_id(c)])
#define command_metadata_by_id(id) (&fcoder_metacmd_table[id]) #define command_metadata_by_id(id) (&fcoder_metacmd_table[id])
#define command_one_past_last_id 194 #define command_one_past_last_id 195
#if defined(CUSTOM_COMMAND_SIG) #if defined(CUSTOM_COMMAND_SIG)
#define PROC_LINKS(x,y) x #define PROC_LINKS(x,y) x
#else #else
@ -148,6 +148,7 @@ CUSTOM_COMMAND_SIG(reverse_search);
CUSTOM_COMMAND_SIG(reverse_search_identifier); CUSTOM_COMMAND_SIG(reverse_search_identifier);
CUSTOM_COMMAND_SIG(save); CUSTOM_COMMAND_SIG(save);
CUSTOM_COMMAND_SIG(save_all_dirty_buffers); CUSTOM_COMMAND_SIG(save_all_dirty_buffers);
CUSTOM_COMMAND_SIG(save_to_query);
CUSTOM_COMMAND_SIG(scope_absorb_down); CUSTOM_COMMAND_SIG(scope_absorb_down);
CUSTOM_COMMAND_SIG(search); CUSTOM_COMMAND_SIG(search);
CUSTOM_COMMAND_SIG(search_identifier); CUSTOM_COMMAND_SIG(search_identifier);
@ -213,7 +214,7 @@ char *source_name;
int32_t source_name_len; int32_t source_name_len;
int32_t line_number; int32_t line_number;
}; };
static Command_Metadata fcoder_metacmd_table[194] = { static Command_Metadata fcoder_metacmd_table[195] = {
{ PROC_LINKS(allow_mouse, 0), "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "C:\\work\\4ed\\code\\4coder_default_framework.h", 47, 232 }, { PROC_LINKS(allow_mouse, 0), "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "C:\\work\\4ed\\code\\4coder_default_framework.h", 47, 232 },
{ PROC_LINKS(auto_tab_line_at_cursor, 0), "auto_tab_line_at_cursor", 23, "Auto-indents the line on which the cursor sits.", 47, "C:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 667 }, { PROC_LINKS(auto_tab_line_at_cursor, 0), "auto_tab_line_at_cursor", 23, "Auto-indents the line on which the cursor sits.", 47, "C:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 667 },
{ PROC_LINKS(auto_tab_range, 0), "auto_tab_range", 14, "Auto-indents the range between the cursor and the mark.", 55, "C:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 678 }, { PROC_LINKS(auto_tab_range, 0), "auto_tab_range", 14, "Auto-indents the range between the cursor and the mark.", 55, "C:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 678 },
@ -277,12 +278,12 @@ static Command_Metadata fcoder_metacmd_table[194] = {
{ PROC_LINKS(if0_off, 0), "if0_off", 7, "Surround the range between the cursor and mark with an '#if 0' and an '#endif'", 78, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 537 }, { PROC_LINKS(if0_off, 0), "if0_off", 7, "Surround the range between the cursor and mark with an '#if 0' and an '#endif'", 78, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 537 },
{ PROC_LINKS(increase_face_size, 0), "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 617 }, { PROC_LINKS(increase_face_size, 0), "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 617 },
{ PROC_LINKS(increase_line_wrap, 0), "increase_line_wrap", 18, "Increases the current buffer's width for line wrapping.", 55, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 595 }, { PROC_LINKS(increase_line_wrap, 0), "increase_line_wrap", 18, "Increases the current buffer's width for line wrapping.", 55, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 595 },
{ PROC_LINKS(interactive_kill_buffer, 0), "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1215 }, { PROC_LINKS(interactive_kill_buffer, 0), "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1255 },
{ PROC_LINKS(interactive_new, 0), "interactive_new", 15, "Interactively creates a new file.", 33, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1191 }, { PROC_LINKS(interactive_new, 0), "interactive_new", 15, "Interactively creates a new file.", 33, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1231 },
{ PROC_LINKS(interactive_open, 0), "interactive_open", 16, "Interactively opens a file.", 27, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1197 }, { PROC_LINKS(interactive_open, 0), "interactive_open", 16, "Interactively opens a file.", 27, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1237 },
{ PROC_LINKS(interactive_open_or_new, 0), "interactive_open_or_new", 23, "Interactively opens or creates a new file.", 42, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1203 }, { PROC_LINKS(interactive_open_or_new, 0), "interactive_open_or_new", 23, "Interactively opens or creates a new file.", 42, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1243 },
{ PROC_LINKS(interactive_switch_buffer, 0), "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1209 }, { PROC_LINKS(interactive_switch_buffer, 0), "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1249 },
{ PROC_LINKS(kill_buffer, 0), "kill_buffer", 11, "Kills the current buffer.", 25, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1233 }, { PROC_LINKS(kill_buffer, 0), "kill_buffer", 11, "Kills the current buffer.", 25, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1273 },
{ PROC_LINKS(kill_rect, 0), "kill_rect", 9, "Delete characters in a rectangular region. Range testing is done by unwrapped-xy coordinates.", 93, "C:\\work\\4ed\\code\\power\\4coder_experiments.cpp", 50, 31 }, { PROC_LINKS(kill_rect, 0), "kill_rect", 9, "Delete characters in a rectangular region. Range testing is done by unwrapped-xy coordinates.", 93, "C:\\work\\4ed\\code\\power\\4coder_experiments.cpp", 50, 31 },
{ PROC_LINKS(left_adjust_view, 0), "left_adjust_view", 16, "Sets the left size of the view near the x position of the cursor.", 65, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 151 }, { PROC_LINKS(left_adjust_view, 0), "left_adjust_view", 16, "Sets the left size of the view near the x position of the cursor.", 65, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 151 },
{ PROC_LINKS(list_all_functions_current_buffer, 0), "list_all_functions_current_buffer", 33, "Creates a jump list of lines of the current buffer that appear to define or declare functions.", 94, "C:\\work\\4ed\\code\\4coder_function_list.cpp", 45, 348 }, { PROC_LINKS(list_all_functions_current_buffer, 0), "list_all_functions_current_buffer", 33, "Creates a jump list of lines of the current buffer that appear to define or declare functions.", 94, "C:\\work\\4ed\\code\\4coder_function_list.cpp", 45, 348 },
@ -297,7 +298,7 @@ static Command_Metadata fcoder_metacmd_table[194] = {
{ PROC_LINKS(list_all_substring_locations, 0), "list_all_substring_locations", 28, "Queries the user for a string and lists all case-sensitive substring matches found in all open buffers.", 103, "C:\\work\\4ed\\code\\4coder_search.cpp", 38, 712 }, { PROC_LINKS(list_all_substring_locations, 0), "list_all_substring_locations", 28, "Queries the user for a string and lists all case-sensitive substring matches found in all open buffers.", 103, "C:\\work\\4ed\\code\\4coder_search.cpp", 38, 712 },
{ PROC_LINKS(list_all_substring_locations_case_insensitive, 0), "list_all_substring_locations_case_insensitive", 45, "Queries the user for a string and lists all case-insensitive substring matches found in all open buffers.", 105, "C:\\work\\4ed\\code\\4coder_search.cpp", 38, 732 }, { PROC_LINKS(list_all_substring_locations_case_insensitive, 0), "list_all_substring_locations_case_insensitive", 45, "Queries the user for a string and lists all case-insensitive substring matches found in all open buffers.", 105, "C:\\work\\4ed\\code\\4coder_search.cpp", 38, 732 },
{ PROC_LINKS(load_project, 0), "load_project", 12, "Looks for a project.4coder file in the current directory and tries to load it. Looks in parent directories until a project file is found or there are no more parents.", 167, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 408 }, { PROC_LINKS(load_project, 0), "load_project", 12, "Looks for a project.4coder file in the current directory and tries to load it. Looks in parent directories until a project file is found or there are no more parents.", 167, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 408 },
{ PROC_LINKS(make_directory_query, 0), "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1144 }, { PROC_LINKS(make_directory_query, 0), "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1184 },
{ PROC_LINKS(miblo_decrement_basic, 0), "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "C:\\work\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 52, 119 }, { PROC_LINKS(miblo_decrement_basic, 0), "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "C:\\work\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 52, 119 },
{ PROC_LINKS(miblo_decrement_time_stamp, 0), "miblo_decrement_time_stamp", 26, "Decrement a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss", 81, "C:\\work\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 52, 392 }, { PROC_LINKS(miblo_decrement_time_stamp, 0), "miblo_decrement_time_stamp", 26, "Decrement a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss", 81, "C:\\work\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 52, 392 },
{ PROC_LINKS(miblo_decrement_time_stamp_minute, 0), "miblo_decrement_time_stamp_minute", 33, "Decrement a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "C:\\work\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 52, 404 }, { PROC_LINKS(miblo_decrement_time_stamp_minute, 0), "miblo_decrement_time_stamp_minute", 33, "Decrement a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "C:\\work\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 52, 404 },
@ -320,8 +321,8 @@ static Command_Metadata fcoder_metacmd_table[194] = {
{ PROC_LINKS(newline_or_goto_position_sticky, 0), "newline_or_goto_position_sticky", 31, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "C:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 585 }, { PROC_LINKS(newline_or_goto_position_sticky, 0), "newline_or_goto_position_sticky", 31, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "C:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 585 },
{ PROC_LINKS(open_all_code, 0), "open_all_code", 13, "Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.", 164, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 165 }, { PROC_LINKS(open_all_code, 0), "open_all_code", 13, "Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.", 164, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 165 },
{ PROC_LINKS(open_all_code_recursive, 0), "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 180 }, { PROC_LINKS(open_all_code_recursive, 0), "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 180 },
{ PROC_LINKS(open_color_tweaker, 0), "open_color_tweaker", 18, "Opens the 4coder colors and fonts selector menu.", 48, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1239 }, { PROC_LINKS(open_color_tweaker, 0), "open_color_tweaker", 18, "Opens the 4coder colors and fonts selector menu.", 48, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1279 },
{ PROC_LINKS(open_debug, 0), "open_debug", 10, "Opens a debug view for internal use.", 36, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1245 }, { PROC_LINKS(open_debug, 0), "open_debug", 10, "Opens a debug view for internal use.", 36, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1285 },
{ PROC_LINKS(open_file_in_quotes, 0), "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 634 }, { PROC_LINKS(open_file_in_quotes, 0), "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 634 },
{ PROC_LINKS(open_in_other, 0), "open_in_other", 13, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file, displaying it in the other view.", 127, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 651 }, { PROC_LINKS(open_in_other, 0), "open_in_other", 13, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file, displaying it in the other view.", 127, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 651 },
{ PROC_LINKS(open_long_braces, 0), "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 513 }, { PROC_LINKS(open_long_braces, 0), "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 513 },
@ -342,18 +343,19 @@ static Command_Metadata fcoder_metacmd_table[194] = {
{ PROC_LINKS(query_replace, 0), "query_replace", 13, "Queries the user for two strings, and incrementally replaces every occurence of the first string with the second string.", 120, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 997 }, { PROC_LINKS(query_replace, 0), "query_replace", 13, "Queries the user for two strings, and incrementally replaces every occurence of the first string with the second string.", 120, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 997 },
{ PROC_LINKS(query_replace_identifier, 0), "query_replace_identifier", 24, "Queries the user for a string, and incrementally replace every occurence of the word or token found at the cursor with the specified string.", 140, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1018 }, { PROC_LINKS(query_replace_identifier, 0), "query_replace_identifier", 24, "Queries the user for a string, and incrementally replace every occurence of the word or token found at the cursor with the specified string.", 140, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1018 },
{ PROC_LINKS(query_replace_selection, 0), "query_replace_selection", 23, "Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string.", 141, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 240 }, { PROC_LINKS(query_replace_selection, 0), "query_replace_selection", 23, "Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string.", 141, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 240 },
{ PROC_LINKS(redo, 0), "redo", 4, "Advances forewards through the undo history.", 44, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1185 }, { PROC_LINKS(redo, 0), "redo", 4, "Advances forewards through the undo history.", 44, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1225 },
{ PROC_LINKS(reload_current_project, 0), "reload_current_project", 22, "If a project file has already been loaded, reloads the same file. Useful for when the project configuration is changed.", 120, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 479 }, { PROC_LINKS(reload_current_project, 0), "reload_current_project", 22, "If a project file has already been loaded, reloads the same file. Useful for when the project configuration is changed.", 120, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 479 },
{ PROC_LINKS(remap_interactive, 0), "remap_interactive", 17, "Switch to a named key binding map.", 34, "C:\\work\\4ed\\code\\4coder_default_framework.h", 47, 743 }, { PROC_LINKS(remap_interactive, 0), "remap_interactive", 17, "Switch to a named key binding map.", 34, "C:\\work\\4ed\\code\\4coder_default_framework.h", 47, 743 },
{ PROC_LINKS(rename_file_query, 0), "rename_file_query", 17, "Queries the user for a new name and renames the file of the current buffer, altering the buffer's name too.", 107, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1102 }, { PROC_LINKS(rename_file_query, 0), "rename_file_query", 17, "Queries the user for a new name and renames the file of the current buffer, altering the buffer's name too.", 107, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1142 },
{ PROC_LINKS(rename_parameter, 0), "rename_parameter", 16, "If the cursor is found to be on the name of a function parameter in the signature of a function definition, all occurences within the scope of the function will be replaced with a new provided string.", 200, "C:\\work\\4ed\\code\\power\\4coder_experiments.cpp", 50, 387 }, { PROC_LINKS(rename_parameter, 0), "rename_parameter", 16, "If the cursor is found to be on the name of a function parameter in the signature of a function definition, all occurences within the scope of the function will be replaced with a new provided string.", 200, "C:\\work\\4ed\\code\\power\\4coder_experiments.cpp", 50, 387 },
{ PROC_LINKS(reopen, 0), "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1221 }, { PROC_LINKS(reopen, 0), "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1261 },
{ PROC_LINKS(replace_all_occurrences, 0), "replace_all_occurrences", 23, "Queries the user for two strings, and replaces all occurrences of the first string with the second string in all open buffers.", 126, "C:\\work\\4ed\\code\\power\\4coder_experiments.cpp", 50, 773 }, { PROC_LINKS(replace_all_occurrences, 0), "replace_all_occurrences", 23, "Queries the user for two strings, and replaces all occurrences of the first string with the second string in all open buffers.", 126, "C:\\work\\4ed\\code\\power\\4coder_experiments.cpp", 50, 773 },
{ PROC_LINKS(replace_in_range, 0), "replace_in_range", 16, "Queries the user for two strings, and replaces all occurences of the first string in the range between the cursor and the mark with the second string.", 150, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 894 }, { PROC_LINKS(replace_in_range, 0), "replace_in_range", 16, "Queries the user for two strings, and replaces all occurences of the first string in the range between the cursor and the mark with the second string.", 150, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 894 },
{ PROC_LINKS(reverse_search, 0), "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 865 }, { PROC_LINKS(reverse_search, 0), "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 865 },
{ PROC_LINKS(reverse_search_identifier, 0), "reverse_search_identifier", 25, "Begins an incremental search up through the current buffer for the word or token under the cursor.", 98, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 883 }, { PROC_LINKS(reverse_search_identifier, 0), "reverse_search_identifier", 25, "Begins an incremental search up through the current buffer for the word or token under the cursor.", 98, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 883 },
{ PROC_LINKS(save, 0), "save", 4, "Saves the current buffer.", 25, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1227 }, { PROC_LINKS(save, 0), "save", 4, "Saves the current buffer.", 25, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1267 },
{ PROC_LINKS(save_all_dirty_buffers, 0), "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1041 }, { PROC_LINKS(save_all_dirty_buffers, 0), "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1041 },
{ PROC_LINKS(save_to_query, 0), "save_to_query", 13, "Queries the user for a name and saves the contents of the current buffer, altering the buffer's name too.", 105, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1102 },
{ PROC_LINKS(scope_absorb_down, 0), "scope_absorb_down", 17, "If a scope is currently selected, and a statement or block statement is present below the current scope, the statement is moved into the scope.", 143, "C:\\work\\4ed\\code\\4coder_scope_commands.cpp", 46, 751 }, { PROC_LINKS(scope_absorb_down, 0), "scope_absorb_down", 17, "If a scope is currently selected, and a statement or block statement is present below the current scope, the statement is moved into the scope.", 143, "C:\\work\\4ed\\code\\4coder_scope_commands.cpp", 46, 751 },
{ PROC_LINKS(search, 0), "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 858 }, { PROC_LINKS(search, 0), "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 858 },
{ PROC_LINKS(search_identifier, 0), "search_identifier", 17, "Begins an incremental search down through the current buffer for the word or token under the cursor.", 100, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 872 }, { PROC_LINKS(search_identifier, 0), "search_identifier", 17, "Begins an incremental search down through the current buffer for the word or token under the cursor.", 100, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 872 },
@ -395,7 +397,7 @@ static Command_Metadata fcoder_metacmd_table[194] = {
{ PROC_LINKS(toggle_mouse, 0), "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "C:\\work\\4ed\\code\\4coder_default_framework.h", 47, 238 }, { PROC_LINKS(toggle_mouse, 0), "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "C:\\work\\4ed\\code\\4coder_default_framework.h", 47, 238 },
{ PROC_LINKS(toggle_show_whitespace, 0), "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 652 }, { PROC_LINKS(toggle_show_whitespace, 0), "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 652 },
{ PROC_LINKS(toggle_virtual_whitespace, 0), "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 641 }, { PROC_LINKS(toggle_virtual_whitespace, 0), "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 641 },
{ PROC_LINKS(undo, 0), "undo", 4, "Advances backwards through the undo history.", 44, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1179 }, { PROC_LINKS(undo, 0), "undo", 4, "Advances backwards through the undo history.", 44, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1219 },
{ PROC_LINKS(view_buffer_other_panel, 0), "view_buffer_other_panel", 23, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 721 }, { PROC_LINKS(view_buffer_other_panel, 0), "view_buffer_other_panel", 23, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 721 },
{ PROC_LINKS(word_complete, 0), "word_complete", 13, "Iteratively tries completing the word to the left of the cursor with other words in open buffers that have the same prefix string.", 130, "C:\\work\\4ed\\code\\4coder_search.cpp", 38, 863 }, { PROC_LINKS(word_complete, 0), "word_complete", 13, "Iteratively tries completing the word to the left of the cursor with other words in open buffers that have the same prefix string.", 130, "C:\\work\\4ed\\code\\4coder_search.cpp", 38, 863 },
{ PROC_LINKS(write_and_auto_tab, 0), "write_and_auto_tab", 18, "Inserts a character and auto-indents the line on which the cursor sits.", 71, "C:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 690 }, { PROC_LINKS(write_and_auto_tab, 0), "write_and_auto_tab", 18, "Inserts a character and auto-indents the line on which the cursor sits.", 71, "C:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 690 },
@ -549,57 +551,58 @@ static int32_t fcoder_metacmd_ID_reverse_search = 136;
static int32_t fcoder_metacmd_ID_reverse_search_identifier = 137; static int32_t fcoder_metacmd_ID_reverse_search_identifier = 137;
static int32_t fcoder_metacmd_ID_save = 138; static int32_t fcoder_metacmd_ID_save = 138;
static int32_t fcoder_metacmd_ID_save_all_dirty_buffers = 139; static int32_t fcoder_metacmd_ID_save_all_dirty_buffers = 139;
static int32_t fcoder_metacmd_ID_scope_absorb_down = 140; static int32_t fcoder_metacmd_ID_save_to_query = 140;
static int32_t fcoder_metacmd_ID_search = 141; static int32_t fcoder_metacmd_ID_scope_absorb_down = 141;
static int32_t fcoder_metacmd_ID_search_identifier = 142; static int32_t fcoder_metacmd_ID_search = 142;
static int32_t fcoder_metacmd_ID_seek_alphanumeric_left = 143; static int32_t fcoder_metacmd_ID_search_identifier = 143;
static int32_t fcoder_metacmd_ID_seek_alphanumeric_or_camel_left = 144; static int32_t fcoder_metacmd_ID_seek_alphanumeric_left = 144;
static int32_t fcoder_metacmd_ID_seek_alphanumeric_or_camel_right = 145; static int32_t fcoder_metacmd_ID_seek_alphanumeric_or_camel_left = 145;
static int32_t fcoder_metacmd_ID_seek_alphanumeric_right = 146; static int32_t fcoder_metacmd_ID_seek_alphanumeric_or_camel_right = 146;
static int32_t fcoder_metacmd_ID_seek_beginning_of_line = 147; static int32_t fcoder_metacmd_ID_seek_alphanumeric_right = 147;
static int32_t fcoder_metacmd_ID_seek_beginning_of_textual_line = 148; static int32_t fcoder_metacmd_ID_seek_beginning_of_line = 148;
static int32_t fcoder_metacmd_ID_seek_end_of_line = 149; static int32_t fcoder_metacmd_ID_seek_beginning_of_textual_line = 149;
static int32_t fcoder_metacmd_ID_seek_end_of_textual_line = 150; static int32_t fcoder_metacmd_ID_seek_end_of_line = 150;
static int32_t fcoder_metacmd_ID_seek_token_left = 151; static int32_t fcoder_metacmd_ID_seek_end_of_textual_line = 151;
static int32_t fcoder_metacmd_ID_seek_token_right = 152; static int32_t fcoder_metacmd_ID_seek_token_left = 152;
static int32_t fcoder_metacmd_ID_seek_white_or_token_left = 153; static int32_t fcoder_metacmd_ID_seek_token_right = 153;
static int32_t fcoder_metacmd_ID_seek_white_or_token_right = 154; static int32_t fcoder_metacmd_ID_seek_white_or_token_left = 154;
static int32_t fcoder_metacmd_ID_seek_whitespace_down = 155; static int32_t fcoder_metacmd_ID_seek_white_or_token_right = 155;
static int32_t fcoder_metacmd_ID_seek_whitespace_down_end_line = 156; static int32_t fcoder_metacmd_ID_seek_whitespace_down = 156;
static int32_t fcoder_metacmd_ID_seek_whitespace_left = 157; static int32_t fcoder_metacmd_ID_seek_whitespace_down_end_line = 157;
static int32_t fcoder_metacmd_ID_seek_whitespace_right = 158; static int32_t fcoder_metacmd_ID_seek_whitespace_left = 158;
static int32_t fcoder_metacmd_ID_seek_whitespace_up = 159; static int32_t fcoder_metacmd_ID_seek_whitespace_right = 159;
static int32_t fcoder_metacmd_ID_seek_whitespace_up_end_line = 160; static int32_t fcoder_metacmd_ID_seek_whitespace_up = 160;
static int32_t fcoder_metacmd_ID_select_all = 161; static int32_t fcoder_metacmd_ID_seek_whitespace_up_end_line = 161;
static int32_t fcoder_metacmd_ID_set_bindings_choose = 162; static int32_t fcoder_metacmd_ID_select_all = 162;
static int32_t fcoder_metacmd_ID_set_bindings_default = 163; static int32_t fcoder_metacmd_ID_set_bindings_choose = 163;
static int32_t fcoder_metacmd_ID_set_bindings_mac_default = 164; static int32_t fcoder_metacmd_ID_set_bindings_default = 164;
static int32_t fcoder_metacmd_ID_set_mark = 165; static int32_t fcoder_metacmd_ID_set_bindings_mac_default = 165;
static int32_t fcoder_metacmd_ID_setup_new_project = 166; static int32_t fcoder_metacmd_ID_set_mark = 166;
static int32_t fcoder_metacmd_ID_show_filebar = 167; static int32_t fcoder_metacmd_ID_setup_new_project = 167;
static int32_t fcoder_metacmd_ID_show_scrollbar = 168; static int32_t fcoder_metacmd_ID_show_filebar = 168;
static int32_t fcoder_metacmd_ID_snipe_token_or_word = 169; static int32_t fcoder_metacmd_ID_show_scrollbar = 169;
static int32_t fcoder_metacmd_ID_snipe_token_or_word_right = 170; static int32_t fcoder_metacmd_ID_snipe_token_or_word = 170;
static int32_t fcoder_metacmd_ID_suppress_mouse = 171; static int32_t fcoder_metacmd_ID_snipe_token_or_word_right = 171;
static int32_t fcoder_metacmd_ID_swap_buffers_between_panels = 172; static int32_t fcoder_metacmd_ID_suppress_mouse = 172;
static int32_t fcoder_metacmd_ID_to_lowercase = 173; static int32_t fcoder_metacmd_ID_swap_buffers_between_panels = 173;
static int32_t fcoder_metacmd_ID_to_uppercase = 174; static int32_t fcoder_metacmd_ID_to_lowercase = 174;
static int32_t fcoder_metacmd_ID_toggle_filebar = 175; static int32_t fcoder_metacmd_ID_to_uppercase = 175;
static int32_t fcoder_metacmd_ID_toggle_fullscreen = 176; static int32_t fcoder_metacmd_ID_toggle_filebar = 176;
static int32_t fcoder_metacmd_ID_toggle_line_wrap = 177; static int32_t fcoder_metacmd_ID_toggle_fullscreen = 177;
static int32_t fcoder_metacmd_ID_toggle_mouse = 178; static int32_t fcoder_metacmd_ID_toggle_line_wrap = 178;
static int32_t fcoder_metacmd_ID_toggle_show_whitespace = 179; static int32_t fcoder_metacmd_ID_toggle_mouse = 179;
static int32_t fcoder_metacmd_ID_toggle_virtual_whitespace = 180; static int32_t fcoder_metacmd_ID_toggle_show_whitespace = 180;
static int32_t fcoder_metacmd_ID_undo = 181; static int32_t fcoder_metacmd_ID_toggle_virtual_whitespace = 181;
static int32_t fcoder_metacmd_ID_view_buffer_other_panel = 182; static int32_t fcoder_metacmd_ID_undo = 182;
static int32_t fcoder_metacmd_ID_word_complete = 183; static int32_t fcoder_metacmd_ID_view_buffer_other_panel = 183;
static int32_t fcoder_metacmd_ID_write_and_auto_tab = 184; static int32_t fcoder_metacmd_ID_word_complete = 184;
static int32_t fcoder_metacmd_ID_write_block = 185; static int32_t fcoder_metacmd_ID_write_and_auto_tab = 185;
static int32_t fcoder_metacmd_ID_write_character = 186; static int32_t fcoder_metacmd_ID_write_block = 186;
static int32_t fcoder_metacmd_ID_write_explicit_enum_flags = 187; static int32_t fcoder_metacmd_ID_write_character = 187;
static int32_t fcoder_metacmd_ID_write_explicit_enum_values = 188; static int32_t fcoder_metacmd_ID_write_explicit_enum_flags = 188;
static int32_t fcoder_metacmd_ID_write_hack = 189; static int32_t fcoder_metacmd_ID_write_explicit_enum_values = 189;
static int32_t fcoder_metacmd_ID_write_note = 190; static int32_t fcoder_metacmd_ID_write_hack = 190;
static int32_t fcoder_metacmd_ID_write_todo = 191; static int32_t fcoder_metacmd_ID_write_note = 191;
static int32_t fcoder_metacmd_ID_write_underscore = 192; static int32_t fcoder_metacmd_ID_write_todo = 192;
static int32_t fcoder_metacmd_ID_write_zero_struct = 193; static int32_t fcoder_metacmd_ID_write_underscore = 193;
static int32_t fcoder_metacmd_ID_write_zero_struct = 194;

View File

@ -25,7 +25,7 @@ bind(context, 'm', MDFR_ALT, build_in_build_panel);
bind(context, 'z', MDFR_ALT, execute_any_cli); bind(context, 'z', MDFR_ALT, execute_any_cli);
bind(context, 'Z', MDFR_ALT, execute_previous_cli); bind(context, 'Z', MDFR_ALT, execute_previous_cli);
bind(context, 'x', MDFR_ALT, execute_arbitrary_command); bind(context, 'x', MDFR_ALT, execute_arbitrary_command);
bind(context, 's', MDFR_ALT, show_scrollbar); bind(context, 'W', MDFR_ALT, show_scrollbar);
bind(context, 'w', MDFR_ALT, hide_scrollbar); bind(context, 'w', MDFR_ALT, hide_scrollbar);
bind(context, 'b', MDFR_ALT, toggle_filebar); bind(context, 'b', MDFR_ALT, toggle_filebar);
bind(context, '@', MDFR_ALT, toggle_mouse); bind(context, '@', MDFR_ALT, toggle_mouse);
@ -102,6 +102,7 @@ bind(context, 'Q', MDFR_CTRL, query_replace_identifier);
bind(context, 'q', MDFR_ALT, query_replace_selection); bind(context, 'q', MDFR_ALT, query_replace_selection);
bind(context, 'r', MDFR_CTRL, reverse_search); bind(context, 'r', MDFR_CTRL, reverse_search);
bind(context, 's', MDFR_CTRL, save); bind(context, 's', MDFR_CTRL, save);
bind(context, 's', MDFR_ALT, save_to_query);
bind(context, 't', MDFR_CTRL, search_identifier); bind(context, 't', MDFR_CTRL, search_identifier);
bind(context, 'T', MDFR_CTRL, list_all_locations_of_identifier); bind(context, 'T', MDFR_CTRL, list_all_locations_of_identifier);
bind(context, 'u', MDFR_CTRL, to_uppercase); bind(context, 'u', MDFR_CTRL, to_uppercase);
@ -181,7 +182,7 @@ bind(context, 'm', MDFR_CTRL, build_in_build_panel);
bind(context, 'z', MDFR_CTRL, execute_any_cli); bind(context, 'z', MDFR_CTRL, execute_any_cli);
bind(context, 'Z', MDFR_CTRL, execute_previous_cli); bind(context, 'Z', MDFR_CTRL, execute_previous_cli);
bind(context, 'x', MDFR_CTRL, execute_arbitrary_command); bind(context, 'x', MDFR_CTRL, execute_arbitrary_command);
bind(context, 's', MDFR_CTRL, show_scrollbar); bind(context, 'W', MDFR_CTRL, show_scrollbar);
bind(context, 'w', MDFR_CTRL, hide_scrollbar); bind(context, 'w', MDFR_CTRL, hide_scrollbar);
bind(context, 'b', MDFR_CTRL, toggle_filebar); bind(context, 'b', MDFR_CTRL, toggle_filebar);
bind(context, '@', MDFR_CTRL, toggle_mouse); bind(context, '@', MDFR_CTRL, toggle_mouse);
@ -256,6 +257,7 @@ bind(context, 'q', MDFR_CMND, query_replace);
bind(context, 'Q', MDFR_CMND, query_replace_identifier); bind(context, 'Q', MDFR_CMND, query_replace_identifier);
bind(context, 'r', MDFR_CMND, reverse_search); bind(context, 'r', MDFR_CMND, reverse_search);
bind(context, 's', MDFR_CMND, save); bind(context, 's', MDFR_CMND, save);
bind(context, 's', MDFR_CTRL, save_to_query);
bind(context, 't', MDFR_CMND, search_identifier); bind(context, 't', MDFR_CMND, search_identifier);
bind(context, 'T', MDFR_CMND, list_all_locations_of_identifier); bind(context, 'T', MDFR_CMND, list_all_locations_of_identifier);
bind(context, 'u', MDFR_CMND, to_uppercase); bind(context, 'u', MDFR_CMND, to_uppercase);
@ -367,7 +369,7 @@ static Meta_Key_Bind fcoder_binds_for_default_mapid_global[48] = {
{0, 122, 2, "execute_any_cli", 15, LINK_PROCS(execute_any_cli)}, {0, 122, 2, "execute_any_cli", 15, LINK_PROCS(execute_any_cli)},
{0, 90, 2, "execute_previous_cli", 20, LINK_PROCS(execute_previous_cli)}, {0, 90, 2, "execute_previous_cli", 20, LINK_PROCS(execute_previous_cli)},
{0, 120, 2, "execute_arbitrary_command", 25, LINK_PROCS(execute_arbitrary_command)}, {0, 120, 2, "execute_arbitrary_command", 25, LINK_PROCS(execute_arbitrary_command)},
{0, 115, 2, "show_scrollbar", 14, LINK_PROCS(show_scrollbar)}, {0, 87, 2, "show_scrollbar", 14, LINK_PROCS(show_scrollbar)},
{0, 119, 2, "hide_scrollbar", 14, LINK_PROCS(hide_scrollbar)}, {0, 119, 2, "hide_scrollbar", 14, LINK_PROCS(hide_scrollbar)},
{0, 98, 2, "toggle_filebar", 14, LINK_PROCS(toggle_filebar)}, {0, 98, 2, "toggle_filebar", 14, LINK_PROCS(toggle_filebar)},
{0, 64, 2, "toggle_mouse", 12, LINK_PROCS(toggle_mouse)}, {0, 64, 2, "toggle_mouse", 12, LINK_PROCS(toggle_mouse)},
@ -392,7 +394,7 @@ static Meta_Key_Bind fcoder_binds_for_default_mapid_global[48] = {
{0, 55326, 0, "project_fkey_command", 20, LINK_PROCS(project_fkey_command)}, {0, 55326, 0, "project_fkey_command", 20, LINK_PROCS(project_fkey_command)},
{0, 55327, 0, "project_fkey_command", 20, LINK_PROCS(project_fkey_command)}, {0, 55327, 0, "project_fkey_command", 20, LINK_PROCS(project_fkey_command)},
}; };
static Meta_Key_Bind fcoder_binds_for_default_mapid_file[67] = { static Meta_Key_Bind fcoder_binds_for_default_mapid_file[68] = {
{1, 0, 0, "write_character", 15, LINK_PROCS(write_character)}, {1, 0, 0, "write_character", 15, LINK_PROCS(write_character)},
{0, 55308, 0, "click_set_cursor", 16, LINK_PROCS(click_set_cursor)}, {0, 55308, 0, "click_set_cursor", 16, LINK_PROCS(click_set_cursor)},
{0, 55310, 0, "click_set_mark", 14, LINK_PROCS(click_set_mark)}, {0, 55310, 0, "click_set_mark", 14, LINK_PROCS(click_set_mark)},
@ -444,6 +446,7 @@ static Meta_Key_Bind fcoder_binds_for_default_mapid_file[67] = {
{0, 113, 2, "query_replace_selection", 23, LINK_PROCS(query_replace_selection)}, {0, 113, 2, "query_replace_selection", 23, LINK_PROCS(query_replace_selection)},
{0, 114, 1, "reverse_search", 14, LINK_PROCS(reverse_search)}, {0, 114, 1, "reverse_search", 14, LINK_PROCS(reverse_search)},
{0, 115, 1, "save", 4, LINK_PROCS(save)}, {0, 115, 1, "save", 4, LINK_PROCS(save)},
{0, 115, 2, "save_to_query", 13, LINK_PROCS(save_to_query)},
{0, 116, 1, "search_identifier", 17, LINK_PROCS(search_identifier)}, {0, 116, 1, "search_identifier", 17, LINK_PROCS(search_identifier)},
{0, 84, 1, "list_all_locations_of_identifier", 32, LINK_PROCS(list_all_locations_of_identifier)}, {0, 84, 1, "list_all_locations_of_identifier", 32, LINK_PROCS(list_all_locations_of_identifier)},
{0, 117, 1, "to_uppercase", 12, LINK_PROCS(to_uppercase)}, {0, 117, 1, "to_uppercase", 12, LINK_PROCS(to_uppercase)},
@ -497,7 +500,7 @@ static Meta_Key_Bind fcoder_binds_for_default_default_code_map[32] = {
}; };
static Meta_Sub_Map fcoder_submaps_for_default[3] = { static Meta_Sub_Map fcoder_submaps_for_default[3] = {
{"mapid_global", 12, "The following bindings apply in all situations.", 47, 0, 0, fcoder_binds_for_default_mapid_global, 48}, {"mapid_global", 12, "The following bindings apply in all situations.", 47, 0, 0, fcoder_binds_for_default_mapid_global, 48},
{"mapid_file", 10, "The following bindings apply in general text files and most apply in code files, but some are overriden by other commands specific to code files.", 145, 0, 0, fcoder_binds_for_default_mapid_file, 67}, {"mapid_file", 10, "The following bindings apply in general text files and most apply in code files, but some are overriden by other commands specific to code files.", 145, 0, 0, fcoder_binds_for_default_mapid_file, 68},
{"default_code_map", 16, "The following commands only apply in files where the lexer (syntax highlighting) is turned on.", 94, "mapid_file", 10, fcoder_binds_for_default_default_code_map, 32}, {"default_code_map", 16, "The following commands only apply in files where the lexer (syntax highlighting) is turned on.", 94, "mapid_file", 10, fcoder_binds_for_default_default_code_map, 32},
}; };
static Meta_Key_Bind fcoder_binds_for_mac_default_mapid_global[48] = { static Meta_Key_Bind fcoder_binds_for_mac_default_mapid_global[48] = {
@ -525,7 +528,7 @@ static Meta_Key_Bind fcoder_binds_for_mac_default_mapid_global[48] = {
{0, 122, 1, "execute_any_cli", 15, LINK_PROCS(execute_any_cli)}, {0, 122, 1, "execute_any_cli", 15, LINK_PROCS(execute_any_cli)},
{0, 90, 1, "execute_previous_cli", 20, LINK_PROCS(execute_previous_cli)}, {0, 90, 1, "execute_previous_cli", 20, LINK_PROCS(execute_previous_cli)},
{0, 120, 1, "execute_arbitrary_command", 25, LINK_PROCS(execute_arbitrary_command)}, {0, 120, 1, "execute_arbitrary_command", 25, LINK_PROCS(execute_arbitrary_command)},
{0, 115, 1, "show_scrollbar", 14, LINK_PROCS(show_scrollbar)}, {0, 87, 1, "show_scrollbar", 14, LINK_PROCS(show_scrollbar)},
{0, 119, 1, "hide_scrollbar", 14, LINK_PROCS(hide_scrollbar)}, {0, 119, 1, "hide_scrollbar", 14, LINK_PROCS(hide_scrollbar)},
{0, 98, 1, "toggle_filebar", 14, LINK_PROCS(toggle_filebar)}, {0, 98, 1, "toggle_filebar", 14, LINK_PROCS(toggle_filebar)},
{0, 64, 1, "toggle_mouse", 12, LINK_PROCS(toggle_mouse)}, {0, 64, 1, "toggle_mouse", 12, LINK_PROCS(toggle_mouse)},
@ -550,7 +553,7 @@ static Meta_Key_Bind fcoder_binds_for_mac_default_mapid_global[48] = {
{0, 55326, 0, "project_fkey_command", 20, LINK_PROCS(project_fkey_command)}, {0, 55326, 0, "project_fkey_command", 20, LINK_PROCS(project_fkey_command)},
{0, 55327, 0, "project_fkey_command", 20, LINK_PROCS(project_fkey_command)}, {0, 55327, 0, "project_fkey_command", 20, LINK_PROCS(project_fkey_command)},
}; };
static Meta_Key_Bind fcoder_binds_for_mac_default_mapid_file[65] = { static Meta_Key_Bind fcoder_binds_for_mac_default_mapid_file[66] = {
{1, 0, 0, "write_character", 15, LINK_PROCS(write_character)}, {1, 0, 0, "write_character", 15, LINK_PROCS(write_character)},
{1, 0, 2, "write_character", 15, LINK_PROCS(write_character)}, {1, 0, 2, "write_character", 15, LINK_PROCS(write_character)},
{0, 55308, 0, "click_set_cursor", 16, LINK_PROCS(click_set_cursor)}, {0, 55308, 0, "click_set_cursor", 16, LINK_PROCS(click_set_cursor)},
@ -600,6 +603,7 @@ static Meta_Key_Bind fcoder_binds_for_mac_default_mapid_file[65] = {
{0, 81, 4, "query_replace_identifier", 24, LINK_PROCS(query_replace_identifier)}, {0, 81, 4, "query_replace_identifier", 24, LINK_PROCS(query_replace_identifier)},
{0, 114, 4, "reverse_search", 14, LINK_PROCS(reverse_search)}, {0, 114, 4, "reverse_search", 14, LINK_PROCS(reverse_search)},
{0, 115, 4, "save", 4, LINK_PROCS(save)}, {0, 115, 4, "save", 4, LINK_PROCS(save)},
{0, 115, 1, "save_to_query", 13, LINK_PROCS(save_to_query)},
{0, 116, 4, "search_identifier", 17, LINK_PROCS(search_identifier)}, {0, 116, 4, "search_identifier", 17, LINK_PROCS(search_identifier)},
{0, 84, 4, "list_all_locations_of_identifier", 32, LINK_PROCS(list_all_locations_of_identifier)}, {0, 84, 4, "list_all_locations_of_identifier", 32, LINK_PROCS(list_all_locations_of_identifier)},
{0, 117, 4, "to_uppercase", 12, LINK_PROCS(to_uppercase)}, {0, 117, 4, "to_uppercase", 12, LINK_PROCS(to_uppercase)},
@ -653,7 +657,7 @@ static Meta_Key_Bind fcoder_binds_for_mac_default_default_code_map[32] = {
}; };
static Meta_Sub_Map fcoder_submaps_for_mac_default[3] = { static Meta_Sub_Map fcoder_submaps_for_mac_default[3] = {
{"mapid_global", 12, "The following bindings apply in all situations.", 47, 0, 0, fcoder_binds_for_mac_default_mapid_global, 48}, {"mapid_global", 12, "The following bindings apply in all situations.", 47, 0, 0, fcoder_binds_for_mac_default_mapid_global, 48},
{"mapid_file", 10, "The following bindings apply in general text files and most apply in code files, but some are overriden by other commands specific to code files.", 145, 0, 0, fcoder_binds_for_mac_default_mapid_file, 65}, {"mapid_file", 10, "The following bindings apply in general text files and most apply in code files, but some are overriden by other commands specific to code files.", 145, 0, 0, fcoder_binds_for_mac_default_mapid_file, 66},
{"default_code_map", 16, "The following commands only apply in files where the lexer (syntax highlighting) is turned on.", 94, "mapid_file", 10, fcoder_binds_for_mac_default_default_code_map, 32}, {"default_code_map", 16, "The following commands only apply in files where the lexer (syntax highlighting) is turned on.", 94, "mapid_file", 10, fcoder_binds_for_mac_default_default_code_map, 32},
}; };
static Meta_Mapping fcoder_meta_maps[2] = { static Meta_Mapping fcoder_meta_maps[2] = {

189
4ed.cpp
View File

@ -394,10 +394,15 @@ do_feedback_message(System_Functions *system, Models *models, String value, b32
if (!set_to_start){ if (!set_to_start){
pos = buffer_size(&file->state.buffer); pos = buffer_size(&file->state.buffer);
} }
for (View_Iter iter = file_view_iter_init(&models->layout, file, 0);
file_view_iter_good(iter); for (Panel *panel = models->layout.used_sentinel.next;
iter = file_view_iter_next(iter)){ panel != &models->layout.used_sentinel;
view_cursor_move(system, iter.view, pos); panel = panel->next){
View *view = panel->view;
if (view->transient.file_data.file != file){
continue;
}
view_cursor_move(system, view, pos);
} }
} }
} }
@ -420,12 +425,10 @@ do_feedback_message(System_Functions *system, Models *models, String value, b32
n = __panel__->view; \ n = __panel__->view; \
}while(false) }while(false)
#define REQ_OPEN_VIEW(n) USE_VIEW(n); if (view_lock_level(n) > LockLevel_Open) return #define REQ_OPEN_VIEW(n) USE_VIEW(n); if (view_lock_flags(n) != 0) return
#define REQ_READABLE_VIEW(n) USE_VIEW(n); if (view_lock_level(n) > LockLevel_Protected) return #define REQ_FILE(n,v) Editing_File *n = (v)->transient.file_data.file; if (n == 0) return
#define REQ_FILE_HISTORY(n,v) Editing_File *n = (v)->transient.file_data.file; if (n == 0 || n->state.undo.undo.edits == 0) return
#define REQ_FILE(n,v) Editing_File *n = (v)->file_data.file; if (!n) return
#define REQ_FILE_HISTORY(n,v) Editing_File *n = (v)->file_data.file; if (!n || !n->state.undo.undo.edits) return
#define COMMAND_DECL(n) internal void command_##n(System_Functions *system, Command_Data *command, Command_Binding binding) #define COMMAND_DECL(n) internal void command_##n(System_Functions *system, Command_Data *command, Command_Binding binding)
@ -434,7 +437,7 @@ panel_make_empty(System_Functions *system, Models *models, Panel *panel){
Assert(panel->view == 0); Assert(panel->view == 0);
View_And_ID new_view = live_set_alloc_view(&models->live_set, panel, models); View_And_ID new_view = live_set_alloc_view(&models->live_set, panel, models);
view_set_file(system, new_view.view, models->scratch_buffer, models); view_set_file(system, new_view.view, models->scratch_buffer, models);
new_view.view->map = models->scratch_buffer->settings.base_map_id; new_view.view->transient.map = models->scratch_buffer->settings.base_map_id;
return(new_view.view); return(new_view.view);
} }
@ -446,9 +449,7 @@ COMMAND_DECL(undo){
USE_MODELS(models); USE_MODELS(models);
REQ_OPEN_VIEW(view); REQ_OPEN_VIEW(view);
REQ_FILE_HISTORY(file, view); REQ_FILE_HISTORY(file, view);
view_undo_redo(system, models, view, &file->state.undo.undo, ED_UNDO); view_undo_redo(system, models, view, &file->state.undo.undo, ED_UNDO);
Assert(file->state.undo.undo.size >= 0); Assert(file->state.undo.undo.size >= 0);
} }
@ -456,9 +457,7 @@ COMMAND_DECL(redo){
USE_MODELS(models); USE_MODELS(models);
REQ_OPEN_VIEW(view); REQ_OPEN_VIEW(view);
REQ_FILE_HISTORY(file, view); REQ_FILE_HISTORY(file, view);
view_undo_redo(system, models, view, &file->state.undo.redo, ED_REDO); view_undo_redo(system, models, view, &file->state.undo.redo, ED_REDO);
Assert(file->state.undo.undo.size >= 0); Assert(file->state.undo.undo.size >= 0);
} }
@ -500,7 +499,7 @@ COMMAND_DECL(reopen){
Temp_Memory temp = begin_temp_memory(part); Temp_Memory temp = begin_temp_memory(part);
char *buffer = push_array(part, char, size); char *buffer = push_array(part, char, size);
if (buffer){ if (buffer != 0){
if (system->load_file(handle, buffer, size)){ if (system->load_file(handle, buffer, size)){
system->load_close(handle); system->load_close(handle);
@ -511,14 +510,19 @@ COMMAND_DECL(reopen){
int32_t column_number[16]; int32_t column_number[16];
View *vptrs[16]; View *vptrs[16];
i32 vptr_count = 0; i32 vptr_count = 0;
for (View_Iter iter = file_view_iter_init(&models->layout, file, 0);
file_view_iter_good(iter); for (Panel *panel = models->layout.used_sentinel.next;
iter = file_view_iter_next(iter)){ panel != &models->layout.used_sentinel;
vptrs[vptr_count] = iter.view; panel = panel->next){
edit_poss[vptr_count] = iter.view->edit_pos[0]; View *view = panel->view;
line_number[vptr_count] = iter.view->edit_pos[0].cursor.line; if (view->transient.file_data.file != file){
column_number[vptr_count] = iter.view->edit_pos[0].cursor.character; continue;
iter.view->edit_pos = 0; }
vptrs[vptr_count] = view;
edit_poss[vptr_count] = view->transient.edit_pos[0];
line_number[vptr_count] = view->transient.edit_pos[0].cursor.line;
column_number[vptr_count] = view->transient.edit_pos[0].cursor.character;
view->transient.edit_pos = 0;
++vptr_count; ++vptr_count;
} }
@ -531,8 +535,8 @@ COMMAND_DECL(reopen){
int32_t line = line_number[i]; int32_t line = line_number[i];
int32_t character = column_number[i]; int32_t character = column_number[i];
*vptrs[i]->edit_pos = edit_poss[i]; *vptrs[i]->transient.edit_pos = edit_poss[i];
Full_Cursor cursor = view_compute_cursor(system, vptrs[i], seek_line_char(line, character), 0); Full_Cursor cursor = file_compute_cursor(system, file, seek_line_char(line, character), 0);
view_set_cursor(vptrs[i], cursor, true, file->settings.unwrapped_lines); view_set_cursor(vptrs[i], cursor, true, file->settings.unwrapped_lines);
} }
@ -596,8 +600,8 @@ COMMAND_DECL(kill_buffer){
internal void internal void
case_change_range(System_Functions *system, Models *models, View *view, Editing_File *file, u8 a, u8 z, u8 char_delta){ case_change_range(System_Functions *system, Models *models, View *view, Editing_File *file, u8 a, u8 z, u8 char_delta){
Range range = {0}; Range range = {0};
range.min = Min(view->edit_pos->cursor.pos, view->edit_pos->mark); range.min = Min(view->transient.edit_pos->cursor.pos, view->transient.edit_pos->mark);
range.max = Max(view->edit_pos->cursor.pos, view->edit_pos->mark); range.max = Max(view->transient.edit_pos->cursor.pos, view->transient.edit_pos->mark);
if (range.start < range.end){ if (range.start < range.end){
Edit_Step step = {}; Edit_Step step = {};
step.type = ED_NORMAL; step.type = ED_NORMAL;
@ -634,7 +638,7 @@ COMMAND_DECL(open_debug){
USE_VIEW(view); USE_VIEW(view);
USE_MODELS(models); USE_MODELS(models);
view_show_GUI(view, models, VUI_Debug); view_show_GUI(view, models, VUI_Debug);
view->debug_vars = null_debug_vars; view->transient.debug_vars = null_debug_vars;
} }
COMMAND_DECL(user_callback){ COMMAND_DECL(user_callback){
@ -1412,12 +1416,18 @@ App_Init_Sig(app_init){
models->live_set.views = push_array(partition, View, models->live_set.max); models->live_set.views = push_array(partition, View, models->live_set.max);
dll_init_sentinel(&models->live_set.free_sentinel); //dll_init_sentinel
models->live_set.free_sentinel.transient.next = &models->live_set.free_sentinel;
models->live_set.free_sentinel.transient.prev = &models->live_set.free_sentinel;
i32 max = models->live_set.max; i32 max = models->live_set.max;
View *view = models->live_set.views; View *view = models->live_set.views;
for (i32 i = 0; i < max; ++i, ++view){ for (i32 i = 0; i < max; ++i, ++view){
dll_insert(&models->live_set.free_sentinel, view); //dll_insert(&models->live_set.free_sentinel, view);
view->transient.next = models->live_set.free_sentinel.transient.next;
view->transient.prev = &models->live_set.free_sentinel;
models->live_set.free_sentinel.transient.next = view;
view->transient.next->transient.prev = view;
View_Persistent *persistent = &view->persistent; View_Persistent *persistent = &view->persistent;
persistent->id = i; persistent->id = i;
@ -1745,19 +1755,18 @@ App_Step_Sig(app_step){
b32 mouse_in_margin_area = false; b32 mouse_in_margin_area = false;
Panel *mouse_panel = 0; Panel *mouse_panel = 0;
{ for (Panel *panel = models->layout.used_sentinel.next;
Panel *used_panels = &models->layout.used_sentinel, *panel = 0; panel != &models->layout.used_sentinel;
for (dll_items(panel, used_panels)){ panel = panel->next){
if (hit_check(mx, my, panel->inner)){ if (hit_check(mx, my, panel->inner)){
mouse_panel = panel; mouse_panel = panel;
mouse_in_edit_area = true; mouse_in_edit_area = true;
break; break;
} }
else if (hit_check(mx, my, panel->full)){ else if (hit_check(mx, my, panel->full)){
mouse_panel = panel; mouse_panel = panel;
mouse_in_margin_area = true; mouse_in_margin_area = true;
break; break;
}
} }
} }
@ -1906,24 +1915,19 @@ App_Step_Sig(app_step){
models->hook_start(&models->app_links, files, files_count, flags, flags_count); models->hook_start(&models->app_links, files, files_count, flags, flags_count);
} }
Panel *panel = models->layout.used_sentinel.next;
for (i32 i = 0; i < models->settings.init_files_count; ++i, panel = panel->next){
Assert(panel->view->file_data.file != 0);
}
} }
// NOTE(allen): respond if the user is trying to kill the application // NOTE(allen): respond if the user is trying to kill the application
if (input->trying_to_kill){ if (input->trying_to_kill){
b32 there_is_unsaved = 0; b32 there_is_unsaved = false;
app_result.animating = 1; app_result.animating = true;
File_Node *node, *sent; for (File_Node *node = models->working_set.used_sentinel.next;
sent = &models->working_set.used_sentinel; node != &models->working_set.used_sentinel;
for (dll_items(node, sent)){ node = node->next){
Editing_File *file = (Editing_File*)node; Editing_File *file = (Editing_File*)node;
if (buffer_needs_save(file)){ if (buffer_needs_save(file)){
there_is_unsaved = 1; there_is_unsaved = true;
break; break;
} }
} }
@ -1944,7 +1948,7 @@ App_Step_Sig(app_step){
command_coroutine = 0; command_coroutine = 0;
} }
if (view != 0){ if (view != 0){
init_query_set(&view->query_set); init_query_set(&view->transient.query_set);
} }
if (view == 0){ if (view == 0){
@ -2044,7 +2048,7 @@ App_Step_Sig(app_step){
i32 map = mapid_global; i32 map = mapid_global;
if (view != 0){ if (view != 0){
map = view->map; map = view->transient.map;
} }
Command_Binding cmd_bind = map_extract_recursive(&models->mapping, map, key); Command_Binding cmd_bind = map_extract_recursive(&models->mapping, map, key);
@ -2124,7 +2128,7 @@ App_Step_Sig(app_step){
// TODO(allen): Should I somehow allow a view to clean up however it wants after a // TODO(allen): Should I somehow allow a view to clean up however it wants after a
// command finishes, or after transfering to another view mid command? // command finishes, or after transfering to another view mid command?
if (view != 0 && models->command_coroutine == 0){ if (view != 0 && models->command_coroutine == 0){
init_query_set(&view->query_set); init_query_set(&view->transient.query_set);
} }
if (models->command_coroutine == 0) break; if (models->command_coroutine == 0) break;
} }
@ -2149,22 +2153,18 @@ App_Step_Sig(app_step){
Mouse_State mouse_state = get_mouse_state(&vars->available_input); Mouse_State mouse_state = get_mouse_state(&vars->available_input);
{ {
Panel *panel = 0, *used_panels = 0;
View *view = 0;
b32 active = 0;
Input_Summary summary = {0};
Command_Data *command = cmd; Command_Data *command = cmd;
USE_VIEW(active_view); USE_VIEW(active_view);
USE_PANEL(active_panel); USE_PANEL(active_panel);
used_panels = &models->layout.used_sentinel; for (Panel *panel = models->layout.used_sentinel.next;
for (dll_items(panel, used_panels)){ panel != &models->layout.used_sentinel;
view = panel->view; panel = panel->next){
active = (panel == active_panel); View *view = panel->view;
summary = (active)?(active_input):(dead_input); b32 active = (panel == active_panel);
Input_Summary summary = (active)?(active_input):(dead_input);
view->changed_context_in_step = 0; view->transient.changed_context_in_step = 0;
View_Step_Result result = step_file_view(system, view, models, active_view, summary); View_Step_Result result = step_file_view(system, view, models, active_view, summary);
@ -2178,7 +2178,7 @@ App_Step_Sig(app_step){
consume_input(&vars->available_input, Input_Esc, "file view step"); consume_input(&vars->available_input, Input_Esc, "file view step");
} }
if (view->changed_context_in_step == 0){ if (view->transient.changed_context_in_step == 0){
active = (panel == active_panel); active = (panel == active_panel);
summary = (active)?(active_input):(dead_input); summary = (active)?(active_input):(dead_input);
if (panel == mouse_panel && !input->mouse.out_of_window){ if (panel == mouse_panel && !input->mouse.out_of_window){
@ -2186,22 +2186,22 @@ App_Step_Sig(app_step){
} }
b32 file_scroll = false; b32 file_scroll = false;
GUI_Scroll_Vars *scroll_vars = &view->gui_scroll; GUI_Scroll_Vars *scroll_vars = &view->transient.gui_scroll;
if (view->showing_ui == VUI_None){ if (view->transient.showing_ui == VUI_None){
Assert(view->file_data.file != 0); Assert(view->transient.file_data.file != 0);
scroll_vars = &view->edit_pos->scroll; scroll_vars = &view->transient.edit_pos->scroll;
file_scroll = true; file_scroll = true;
} }
i32 max_y = 0; i32 max_y = 0;
if (view->showing_ui == VUI_None){ if (view->transient.showing_ui == VUI_None){
max_y = view_compute_max_target_y(view); max_y = view_compute_max_target_y(view);
} }
else{ else{
max_y = view->gui_max_y; max_y = view->transient.gui_max_y;
} }
Input_Process_Result ip_result = do_step_file_view(system, view, models, panel->inner, active, &summary, *scroll_vars, view->scroll_region, max_y); Input_Process_Result ip_result = do_step_file_view(system, view, models, panel->inner, active, &summary, *scroll_vars, view->transient.scroll_region, max_y);
if (ip_result.is_animating){ if (ip_result.is_animating){
app_result.animating = 1; app_result.animating = 1;
@ -2214,7 +2214,7 @@ App_Step_Sig(app_step){
} }
if (ip_result.has_max_y_suggestion){ if (ip_result.has_max_y_suggestion){
view->gui_max_y = ip_result.max_y; view->transient.gui_max_y = ip_result.max_y;
} }
if (!gui_scroll_eq(scroll_vars, &ip_result.vars)){ if (!gui_scroll_eq(scroll_vars, &ip_result.vars)){
@ -2226,7 +2226,7 @@ App_Step_Sig(app_step){
} }
} }
view->scroll_region = ip_result.region; view->transient.scroll_region = ip_result.region;
} }
} }
} }
@ -2252,7 +2252,7 @@ App_Step_Sig(app_step){
USE_VIEW(view); USE_VIEW(view);
Assert(view != 0); Assert(view != 0);
Command_Binding cmd_bind = map_extract_recursive(&models->mapping, view->map, key); Command_Binding cmd_bind = map_extract_recursive(&models->mapping, view->transient.map, key);
if (cmd_bind.function){ if (cmd_bind.function){
if (key.keycode == key_esc){ if (key.keycode == key_esc){
@ -2472,7 +2472,7 @@ App_Step_Sig(app_step){
Panel *active_panel = &models->layout.panels[models->layout.active_panel]; Panel *active_panel = &models->layout.panels[models->layout.active_panel];
View *view = active_panel->view; View *view = active_panel->view;
init_query_set(&view->query_set); init_query_set(&view->transient.query_set);
} }
models->layout.active_panel = new_panel_id; models->layout.active_panel = new_panel_id;
@ -2482,12 +2482,13 @@ App_Step_Sig(app_step){
// NOTE(allen): on the first frame there should be no scrolling // NOTE(allen): on the first frame there should be no scrolling
if (input->first_step){ if (input->first_step){
Panel *panel = 0, *used_panels = &models->layout.used_sentinel; for (Panel *panel = models->layout.used_sentinel.next;
for (dll_items(panel, used_panels)){ panel != &models->layout.used_sentinel;
panel = panel->next){
View *view = panel->view; View *view = panel->view;
GUI_Scroll_Vars *scroll_vars = &view->gui_scroll; GUI_Scroll_Vars *scroll_vars = &view->transient.gui_scroll;
if (view->edit_pos){ if (view->transient.edit_pos != 0){
scroll_vars = &view->edit_pos->scroll; scroll_vars = &view->transient.edit_pos->scroll;
} }
scroll_vars->scroll_x = (f32)scroll_vars->target_x; scroll_vars->scroll_x = (f32)scroll_vars->target_x;
scroll_vars->scroll_y = (f32)scroll_vars->target_y; scroll_vars->scroll_y = (f32)scroll_vars->target_y;
@ -2495,9 +2496,9 @@ App_Step_Sig(app_step){
} }
// NOTE(allen): if this is the last frame, run the exit hook // NOTE(allen): if this is the last frame, run the exit hook
if (!models->keep_playing && models->hooks[hook_exit]){ if (!models->keep_playing && models->hooks[hook_exit] != 0){
if (!models->hooks[hook_exit](&models->app_links)){ if (!models->hooks[hook_exit](&models->app_links)){
models->keep_playing = 1; models->keep_playing = true;
} }
} }
@ -2510,9 +2511,9 @@ App_Step_Sig(app_step){
USE_VIEW(active_view); USE_VIEW(active_view);
// NOTE(allen): render the panels // NOTE(allen): render the panels
Panel *panel, *used_panels; for (Panel *panel = models->layout.used_sentinel.next;
used_panels = &models->layout.used_sentinel; panel != &models->layout.used_sentinel;
for (dll_items(panel, used_panels)){ panel = panel->next){
i32_Rect full = panel->full; i32_Rect full = panel->full;
i32_Rect inner = panel->inner; i32_Rect inner = panel->inner;
@ -2524,10 +2525,10 @@ App_Step_Sig(app_step){
draw_rectangle(target, full, back_color); draw_rectangle(target, full, back_color);
b32 file_scroll = false; b32 file_scroll = false;
GUI_Scroll_Vars *scroll_vars = &view->gui_scroll; GUI_Scroll_Vars *scroll_vars = &view->transient.gui_scroll;
if (view->showing_ui == VUI_None){ if (view->transient.showing_ui == VUI_None){
Assert(view->file_data.file != 0); Assert(view->transient.file_data.file != 0);
scroll_vars = &view->edit_pos->scroll; scroll_vars = &view->transient.edit_pos->scroll;
file_scroll = true; file_scroll = true;
} }

View File

@ -13,12 +13,7 @@
inline b32 inline b32
access_test(u32 lock_flags, u32 access_flags){ access_test(u32 lock_flags, u32 access_flags){
b32 result = 0; b32 result = ((lock_flags & ~access_flags) == 0);
if ((lock_flags & ~access_flags) == 0){
result = 1;
}
return(result); return(result);
} }
@ -70,32 +65,28 @@ fill_buffer_summary(Buffer_Summary *buffer, Editing_File *file, Command_Data *cm
internal void internal void
fill_view_summary(System_Functions *system, View_Summary *view, View *vptr, Live_Views *live_set, Working_Set *working_set){ fill_view_summary(System_Functions *system, View_Summary *view, View *vptr, Live_Views *live_set, Working_Set *working_set){
Buffer_ID buffer_id = 0; File_Viewing_Data *data = &vptr->transient.file_data;
File_Viewing_Data *data = &vptr->file_data;
*view = null_view_summary; *view = null_view_summary;
if (vptr->in_use){ if (vptr->transient.in_use){
view->exists = 1; view->exists = true;
view->view_id = (int32_t)(vptr - live_set->views) + 1; view->view_id = (int32_t)(vptr - live_set->views) + 1;
view->line_height = (f32)(vptr->line_height); view->line_height = (f32)(vptr->transient.line_height);
view->unwrapped_lines = data->file->settings.unwrapped_lines; view->unwrapped_lines = data->file->settings.unwrapped_lines;
view->show_whitespace = data->show_whitespace; view->show_whitespace = data->show_whitespace;
view->lock_flags = view_lock_flags(vptr); view->lock_flags = view_lock_flags(vptr);
Assert(data->file); view->buffer_id = vptr->transient.file_data.file->id.id;
buffer_id = vptr->file_data.file->id.id; Assert(data->file != 0);
view->mark = file_compute_cursor(system, data->file, seek_pos(vptr->transient.edit_pos->mark), 0);
view->cursor = vptr->transient.edit_pos->cursor;
view->preferred_x = vptr->transient.edit_pos->preferred_x;
view->buffer_id = buffer_id; view->view_region = vptr->transient.panel->inner;
view->file_region = vptr->transient.file_region;
view->mark = view_compute_cursor(system, vptr, seek_pos(vptr->edit_pos->mark), 0); view->scroll_vars = vptr->transient.edit_pos->scroll;
view->cursor = vptr->edit_pos->cursor;
view->preferred_x = vptr->edit_pos->preferred_x;
view->view_region = vptr->panel->inner;
view->file_region = vptr->file_region;
view->scroll_vars = vptr->edit_pos->scroll;
} }
} }
@ -143,7 +134,7 @@ imp_get_view(Command_Data *cmd, View_ID view_id){
view_id = view_id - 1; view_id = view_id - 1;
if (view_id >= 0 && view_id < live_set->max){ if (view_id >= 0 && view_id < live_set->max){
vptr = live_set->views + view_id; vptr = live_set->views + view_id;
if (!vptr->in_use){ if (!vptr->transient.in_use){
vptr = 0; vptr = 0;
} }
} }
@ -337,8 +328,7 @@ DOC_SEE(Command_Line_Interface_Flag)
if (file != 0){ if (file != 0){
b32 bind_to_new_view = true; b32 bind_to_new_view = true;
if (!(flags & CLI_AlwaysBindToView)){ if (!(flags & CLI_AlwaysBindToView)){
View_Iter iter = file_view_iter_init(&models->layout, file, 0); if (file_is_viewed(&models->layout, file)){
if (file_view_iter_good(iter)){
bind_to_new_view = false; bind_to_new_view = false;
} }
} }
@ -1062,10 +1052,14 @@ DOC_SEE(Buffer_Setting_ID)
file->settings.base_map_id = value; file->settings.base_map_id = value;
} }
for (View_Iter iter = file_view_iter_init(&models->layout, file, 0); for (Panel *panel = models->layout.used_sentinel.next;
file_view_iter_good(iter); panel != &models->layout.used_sentinel;
iter = file_view_iter_next(iter)){ panel = panel->next){
iter.view->map = file->settings.base_map_id; View *view = panel->view;
if (view->transient.file_data.file != file){
continue;
}
view->transient.map = file->settings.base_map_id;
} }
}break; }break;
@ -1453,7 +1447,7 @@ internal_get_view_next(Command_Data *cmd, View_Summary *view){
if (index >= 0 && index < live_set->max){ if (index >= 0 && index < live_set->max){
View *vptr = live_set->views + index; View *vptr = live_set->views + index;
Panel *panel = vptr->panel; Panel *panel = vptr->transient.panel;
if (panel != 0){ if (panel != 0){
panel = panel->next; panel = panel->next;
} }
@ -1580,7 +1574,7 @@ DOC_SEE(View_Split_Position)
System_Functions *system = cmd->system; System_Functions *system = cmd->system;
Models *models = cmd->models; Models *models = cmd->models;
View *vptr = imp_get_view(cmd, view_location); View *vptr = imp_get_view(cmd, view_location);
Panel *panel = vptr->panel; Panel *panel = vptr->transient.panel;
View_Summary result = {0}; View_Summary result = {0};
if (models->layout.panel_count < models->layout.panel_max_count){ if (models->layout.panel_count < models->layout.panel_max_count){
@ -1644,86 +1638,79 @@ in the system, the call will fail.)
bool32 result = 0; bool32 result = 0;
if (vptr){ if (vptr != 0 && models->layout.panel_count > 1){
if (models->layout.panel_count > 1){ Panel *panel = vptr->transient.panel;
Panel *panel = vptr->panel;
Divider_And_ID div, parent_div, child_div; live_set_free_view(&models->live_set, vptr, models);
i32 child; panel->view = 0;
i32 parent;
i32 which_child;
i32 active;
live_set_free_view(&models->live_set, vptr, models); Divider_And_ID div = layout_get_divider(&models->layout, panel->parent);
panel->view = 0;
div = layout_get_divider(&models->layout, panel->parent); // This divider cannot have two child dividers.
Assert(div.divider->child1 == -1 || div.divider->child2 == -1);
// This divider cannot have two child dividers. // Get the child who needs to fill in this node's spot
Assert(div.divider->child1 == -1 || div.divider->child2 == -1); i32 child = div.divider->child1;
if (child == -1) child = div.divider->child2;
// Get the child who needs to fill in this node's spot i32 parent = div.divider->parent;
child = div.divider->child1; i32 which_child = div.divider->which_child;
if (child == -1) child = div.divider->child2;
parent = div.divider->parent; // Fill the child in the slot this node use to hold
which_child = div.divider->which_child; if (parent == -1){
Assert(models->layout.root == div.id);
// Fill the child in the slot this node use to hold models->layout.root = child;
if (parent == -1){
Assert(models->layout.root == div.id);
models->layout.root = child;
}
else{
parent_div = layout_get_divider(&models->layout, parent);
if (which_child == -1){
parent_div.divider->child1 = child;
}
else{
parent_div.divider->child2 = child;
}
}
// If there was a child divider, give it information about it's new parent.
if (child != -1){
child_div = layout_get_divider(&models->layout, child);
child_div.divider->parent = parent;
child_div.divider->which_child = div.divider->which_child;
}
// What is the new active panel?
active = -1;
if (child == -1){
Panel *panel_ptr = 0;
Panel *used_panels = &models->layout.used_sentinel;
for (dll_items(panel_ptr, used_panels)){
if (panel_ptr != panel && panel_ptr->parent == div.id){
panel_ptr->parent = parent;
panel_ptr->which_child = which_child;
active = (i32)(panel_ptr - models->layout.panels);
break;
}
}
}
else{
Panel *panel_ptr = panel->next;
if (panel_ptr == &models->layout.used_sentinel) panel_ptr = panel_ptr->next;
Assert(panel_ptr != panel);
active = (i32)(panel_ptr - models->layout.panels);
}
Assert(active != -1 && panel != models->layout.panels + active);
// If the panel we're closing was previously active, we have to switch to it's sibling.
if (models->layout.active_panel == (i32)(panel - models->layout.panels)){
models->layout.active_panel = active;
}
layout_free_divider(&models->layout, div.divider);
layout_free_panel(&models->layout, panel);
layout_fix_all_panels(&models->layout);
} }
else{
Divider_And_ID parent_div = layout_get_divider(&models->layout, parent);
if (which_child == -1){
parent_div.divider->child1 = child;
}
else{
parent_div.divider->child2 = child;
}
}
// If there was a child divider, give it information about it's new parent.
if (child != -1){
Divider_And_ID child_div = layout_get_divider(&models->layout, child);
child_div.divider->parent = parent;
child_div.divider->which_child = div.divider->which_child;
}
// What is the new active panel?
i32 active = -1;
if (child == -1){
for (Panel *panel_ptr = models->layout.used_sentinel.next;
panel_ptr != &models->layout.used_sentinel;
panel_ptr = panel_ptr->next){
if (panel_ptr != panel && panel_ptr->parent == div.id){
panel_ptr->parent = parent;
panel_ptr->which_child = which_child;
active = (i32)(panel_ptr - models->layout.panels);
break;
}
}
}
else{
Panel *panel_ptr = panel->next;
if (panel_ptr == &models->layout.used_sentinel) panel_ptr = panel_ptr->next;
Assert(panel_ptr != panel);
active = (i32)(panel_ptr - models->layout.panels);
}
Assert(active != -1 && panel != models->layout.panels + active);
// If the panel we're closing was previously active, we have to switch to it's sibling.
if (models->layout.active_panel == (i32)(panel - models->layout.panels)){
models->layout.active_panel = active;
}
layout_free_divider(&models->layout, div.divider);
layout_free_panel(&models->layout, panel);
layout_fix_all_panels(&models->layout);
} }
return(result); return(result);
} }
@ -1744,10 +1731,9 @@ DOC_SEE(get_active_view)
View *vptr = imp_get_view(cmd, view); View *vptr = imp_get_view(cmd, view);
bool32 result = false; bool32 result = false;
if (vptr){ if (vptr != 0){
result = true; result = true;
Panel *panel = vptr->transient.panel;
Panel *panel = vptr->panel;
models->layout.active_panel = (i32)(panel - models->layout.panels); models->layout.active_panel = (i32)(panel - models->layout.panels);
} }
@ -1766,13 +1752,28 @@ DOC_RETURN(returns non-zero on success)
View *vptr = imp_get_view(cmd, view); View *vptr = imp_get_view(cmd, view);
int32_t result = 0; int32_t result = 0;
if (vptr){ if (vptr != 0){
result = 1; result = 1;
switch (setting){ switch (setting){
case ViewSetting_ShowWhitespace: *value_out = vptr->file_data.show_whitespace; break; case ViewSetting_ShowWhitespace:
case ViewSetting_ShowScrollbar: *value_out = !vptr->hide_scrollbar; break; {
case ViewSetting_ShowFileBar: *value_out = !vptr->hide_file_bar; break; *value_out = vptr->transient.file_data.show_whitespace;
default: result = 0; break; }break;
case ViewSetting_ShowScrollbar:
{
*value_out = !vptr->transient.hide_scrollbar;
}break;
case ViewSetting_ShowFileBar:
{
*value_out = !vptr->transient.hide_file_bar;
}break;
default:
{
result = 0;
}break;
} }
} }
@ -1793,22 +1794,22 @@ DOC_SEE(View_Setting_ID)
View *vptr = imp_get_view(cmd, view); View *vptr = imp_get_view(cmd, view);
bool32 result = false; bool32 result = false;
if (vptr){ if (vptr != 0){
result = true; result = true;
switch (setting){ switch (setting){
case ViewSetting_ShowWhitespace: case ViewSetting_ShowWhitespace:
{ {
vptr->file_data.show_whitespace = value; vptr->transient.file_data.show_whitespace = value;
}break; }break;
case ViewSetting_ShowScrollbar: case ViewSetting_ShowScrollbar:
{ {
vptr->hide_scrollbar = !value; vptr->transient.hide_scrollbar = !value;
}break; }break;
case ViewSetting_ShowFileBar: case ViewSetting_ShowFileBar:
{ {
vptr->hide_file_bar = !value; vptr->transient.hide_file_bar = !value;
}break; }break;
default: default:
@ -1838,10 +1839,10 @@ DOC_RETURN(This call returns non-zero on success.)
Editing_Layout *layout = &models->layout; Editing_Layout *layout = &models->layout;
View *vptr = imp_get_view(cmd, view); View *vptr = imp_get_view(cmd, view);
if (vptr){ if (vptr != 0){
result = true; result = true;
Panel *panel = vptr->panel; Panel *panel = vptr->transient.panel;
Panel_Divider *div = layout->dividers + panel->parent; Panel_Divider *div = layout->dividers + panel->parent;
if (panel->which_child == 1){ if (panel->which_child == 1){
@ -1872,11 +1873,12 @@ DOC_SEE(Full_Cursor)
View *vptr = imp_get_view(cmd, view); View *vptr = imp_get_view(cmd, view);
bool32 result = false; bool32 result = false;
if (vptr){ if (vptr != 0){
Editing_File *file = vptr->file_data.file; Editing_File *file = vptr->transient.file_data.file;
if (file != 0 && !file->is_loading){ Assert(file != 0);
if (!file->is_loading){
result = true; result = true;
*cursor_out = view_compute_cursor(system, vptr, seek, 0); *cursor_out = file_compute_cursor(system, file, seek, 0);
fill_view_summary(system, view, vptr, cmd); fill_view_summary(system, view, vptr, cmd);
} }
} }
@ -1897,15 +1899,14 @@ DOC_SEE(Buffer_Seek)
Command_Data *cmd = (Command_Data*)app->cmd_context; Command_Data *cmd = (Command_Data*)app->cmd_context;
System_Functions *system = cmd->system; System_Functions *system = cmd->system;
View *vptr = imp_get_view(cmd, view); View *vptr = imp_get_view(cmd, view);
Editing_File *file = 0;
bool32 result = false; bool32 result = false;
if (vptr){ if (vptr){
file = vptr->file_data.file; Editing_File *file = vptr->transient.file_data.file;
Assert(file); Assert(file != 0);
if (!file->is_loading){ if (!file->is_loading){
result = true; result = true;
Full_Cursor cursor = view_compute_cursor(system, vptr, seek, 0); Full_Cursor cursor = file_compute_cursor(system, file, seek, 0);
view_set_cursor(vptr, cursor, set_preferred_x, file->settings.unwrapped_lines); view_set_cursor(vptr, cursor, set_preferred_x, file->settings.unwrapped_lines);
fill_view_summary(system, view, vptr, cmd); fill_view_summary(system, view, vptr, cmd);
} }
@ -1925,12 +1926,12 @@ DOC_SEE(GUI_Scroll_Vars)
Command_Data *cmd = (Command_Data*)app->cmd_context; Command_Data *cmd = (Command_Data*)app->cmd_context;
System_Functions *system = cmd->system; System_Functions *system = cmd->system;
View *vptr = imp_get_view(cmd, view); View *vptr = imp_get_view(cmd, view);
Editing_File *file = 0;
bool32 result = false; bool32 result = false;
if (vptr){ if (vptr != 0){
file = vptr->file_data.file; Editing_File *file = vptr->transient.file_data.file;
if (file && !file->is_loading){ Assert(file != 0);
if (!file->is_loading){
result = true; result = true;
view_set_scroll(system, vptr, scroll); view_set_scroll(system, vptr, scroll);
fill_view_summary(system, view, vptr, cmd); fill_view_summary(system, view, vptr, cmd);
@ -1952,21 +1953,20 @@ DOC_SEE(Buffer_Seek)
Command_Data *cmd = (Command_Data*)app->cmd_context; Command_Data *cmd = (Command_Data*)app->cmd_context;
System_Functions *system = cmd->system; System_Functions *system = cmd->system;
View *vptr = imp_get_view(cmd, view); View *vptr = imp_get_view(cmd, view);
Editing_File *file = 0;
Full_Cursor cursor = {0};
bool32 result = false; bool32 result = false;
if (vptr){ if (vptr != 0){
file = vptr->file_data.file; Editing_File *file = vptr->transient.file_data.file;
if (file && !file->is_loading){ Assert(file != 0);
if (!file->is_loading){
if (seek.type != buffer_seek_pos){ if (seek.type != buffer_seek_pos){
result = true; result = true;
cursor = view_compute_cursor(system, vptr, seek, 0); Full_Cursor cursor = file_compute_cursor(system, file, seek, 0);
vptr->edit_pos->mark = cursor.pos; vptr->transient.edit_pos->mark = cursor.pos;
} }
else{ else{
result = true; result = true;
vptr->edit_pos->mark = seek.pos; vptr->transient.edit_pos->mark = seek.pos;
} }
fill_view_summary(system, view, vptr, cmd); fill_view_summary(system, view, vptr, cmd);
} }
@ -1995,13 +1995,13 @@ and the turn_on set to false, will switch back to showing the cursor.
View *vptr = imp_get_view(cmd, view); View *vptr = imp_get_view(cmd, view);
bool32 result = false; bool32 result = false;
if (vptr){ if (vptr != 0){
result = true; result = true;
if (turn_on){ if (turn_on){
view_set_temp_highlight(system, vptr, start, end); view_set_temp_highlight(system, vptr, start, end);
} }
else{ else{
vptr->file_data.show_temp_highlight = 0; vptr->transient.file_data.show_temp_highlight = false;
} }
fill_view_summary(system, view, vptr, cmd); fill_view_summary(system, view, vptr, cmd);
} }
@ -2025,12 +2025,11 @@ DOC_SEE(Set_Buffer_Flag)
Models *models = cmd->models; Models *models = cmd->models;
bool32 result = false; bool32 result = false;
if (vptr){ if (vptr != 0){
Editing_File *file = working_set_get_active_file(&models->working_set, buffer_id); Editing_File *file = working_set_get_active_file(&models->working_set, buffer_id);
if (file != 0){ if (file != 0){
result = true; result = true;
if (file != vptr->file_data.file){ if (file != vptr->transient.file_data.file){
view_set_file(system, vptr, file, models); view_set_file(system, vptr, file, models);
if (!(flags & SetBuffer_KeepOriginalGUI)){ if (!(flags & SetBuffer_KeepOriginalGUI)){
view_show_file(vptr, models); view_show_file(vptr, models);
@ -2168,12 +2167,11 @@ only use for this call is in an interactive command that makes calls to get_user
*/{ */{
Command_Data *command = (Command_Data*)app->cmd_context; Command_Data *command = (Command_Data*)app->cmd_context;
USE_VIEW(vptr); USE_VIEW(vptr);
Query_Slot *slot = 0; Query_Slot *slot = alloc_query_slot(&vptr->transient.query_set);
slot = alloc_query_slot(&vptr->query_set);
slot->query_bar = bar;
bool32 result = (slot != 0); bool32 result = (slot != 0);
if (result){
slot->query_bar = bar;
}
return(result); return(result);
} }
@ -2186,7 +2184,7 @@ DOC(Stops showing the particular query bar specified by the bar parameter.)
*/{ */{
Command_Data *command = (Command_Data*)app->cmd_context; Command_Data *command = (Command_Data*)app->cmd_context;
USE_VIEW(vptr); USE_VIEW(vptr);
free_query_slot(&vptr->query_set, bar); free_query_slot(&vptr->transient.query_set, bar);
} }
API_EXPORT void API_EXPORT void
@ -2201,6 +2199,14 @@ DOC(This call posts a string to the *messages* buffer.)
do_feedback_message(cmd->system, models, make_string(str, len)); do_feedback_message(cmd->system, models, make_string(str, len));
} }
internal void
style_set_colors(Style *style, Theme *theme){
for (u32 i = 0; i < Stag_COUNT; ++i){
u32 *color_ptr = style_index_by_tag(&style->main, i);
*color_ptr = theme->colors[i];
}
}
API_EXPORT void API_EXPORT void
Create_Theme(Application_Links *app, Theme *theme, char *name, int32_t len) Create_Theme(Application_Links *app, Theme *theme, char *name, int32_t len)
/* /*
@ -2210,22 +2216,26 @@ DOC_PARAM(len, The length of the name string.)
DOC(This call creates a new theme. If the given name is already the name of a string, the old string will be replaced with the new one. This call does not set the current theme.) DOC(This call creates a new theme. If the given name is already the name of a string, the old string will be replaced with the new one. This call does not set the current theme.)
*/{ */{
Command_Data *cmd = (Command_Data*)app->cmd_context; Command_Data *cmd = (Command_Data*)app->cmd_context;
Style_Library *styles = &cmd->models->styles; Style_Library *library = &cmd->models->styles;
String theme_name = make_string(name, len); String theme_name = make_string(name, len);
b32 hit_existing_theme = false; b32 hit_existing_theme = false;
i32 count = styles->count; i32 count = library->count;
Style *s = styles->styles; Style *style = library->styles;
for (i32 i = 0; i < count; ++i, ++s){ for (i32 i = 0; i < count; ++i, ++style){
if (match_ss(s->name, theme_name)){ if (match(style->name, theme_name)){
style_set_colors(s, theme); style_set_colors(style, theme);
hit_existing_theme = true; hit_existing_theme = true;
break; break;
} }
} }
if (!hit_existing_theme){ if (!hit_existing_theme){
style_add(styles, theme, make_string(name, len)); if (library->count < library->max){
Style *style = &library->styles[library->count++];
style_set_colors(style, theme);
style_set_name(style, make_string(name, len));
}
} }
} }
@ -2607,18 +2617,20 @@ Directory_Get_Hot(Application_Links *app, char *out, int32_t capacity)
DOC_PARAM(out, On success this character buffer is filled with the 4coder 'hot directory'.) DOC_PARAM(out, On success this character buffer is filled with the 4coder 'hot directory'.)
DOC_PARAM(capacity, Specifies the capacity in bytes of the of the out buffer.) DOC_PARAM(capacity, Specifies the capacity in bytes of the of the out buffer.)
DOC(4coder has a concept of a 'hot directory' which is the directory most recently accessed in the GUI. Whenever the GUI is opened it shows the hot directory. In the future this will be deprecated and eliminated in favor of more flexible hot directories created and controlled in the custom layer.) DOC(4coder has a concept of a 'hot directory' which is the directory most recently accessed in the GUI. Whenever the GUI is opened it shows the hot directory. In the future this will be deprecated and eliminated in favor of more flexible hot directories created and controlled in the custom layer.)
DOC_RETURN(This call returns the length of the hot directory string whether or not it was successfully copied into the output buffer. The call is successful if and only if capacity is greater than or the return size.) DOC_RETURN(This call returns the length of the hot directory string whether or not it was successfully copied into the output buffer. The call is successful if and only if capacity is greater than or equal to the return size.)
DOC_SEE(directory_set_hot) DOC_SEE(directory_set_hot)
*/{ */{
Command_Data *cmd = (Command_Data*)app->cmd_context; Command_Data *cmd = (Command_Data*)app->cmd_context;
Hot_Directory *hot = &cmd->models->hot_directory; Hot_Directory *hot = &cmd->models->hot_directory;
i32 copy_max = capacity - 1;
hot_directory_clean_end(hot); hot_directory_clean_end(hot);
if (copy_max > hot->string.size){ if (capacity > 0){
copy_max = hot->string.size; i32 copy_max = capacity - 1;
if (copy_max > hot->string.size){
copy_max = hot->string.size;
}
memcpy(out, hot->string.str, copy_max);
out[copy_max] = 0;
} }
memcpy(out, hot->string.str, copy_max);
out[copy_max] = 0;
return(hot->string.size); return(hot->string.size);
} }

View File

@ -44,34 +44,38 @@
#include "4ed_linked_node_macros.h" #include "4ed_linked_node_macros.h"
#include "4ed_log.h" #include "4ed_log.h"
#include "4ed_gui.h"
#include "4ed_buffer_model.h"
#include "4ed_translation.h"
#include "4ed_buffer.h"
#include "4ed_undo.h"
#include "4ed_file.h"
#include "4ed_style.h"
#include "4ed_hot_directory.h"
#include "4ed_view.h"
#include "4ed_font.cpp" #include "4ed_font.cpp"
//check
#include "4ed_translation.cpp" #include "4ed_translation.cpp"
#include "4ed_render_target.cpp" #include "4ed_render_target.cpp"
#include "4ed_render_fill.cpp" #include "4ed_render_fill.cpp"
#include "4ed_style.h"
#include "4ed_style.cpp"
#include "4ed_command.cpp" #include "4ed_command.cpp"
//check
#include "4ed_buffer.cpp" #include "4ed_buffer.cpp"
#include "4ed_undo.cpp" //check
#include "4ed_file.cpp" #include "4ed_file.cpp"
#include "4ed_working_set.cpp" #include "4ed_working_set.cpp"
//check
#include "4ed_hot_directory.cpp" #include "4ed_hot_directory.cpp"
#include "4ed_parse_contexts.cpp" #include "4ed_parse_contexts.cpp"
#include "4ed_cli.cpp" #include "4ed_cli.cpp"
//check
#include "4ed_gui.h"
#include "4ed_gui.cpp" #include "4ed_gui.cpp"
#include "4ed_layout.cpp" #include "4ed_layout.cpp"
#include "4ed_view.cpp"
#include "4ed_app_models.h" #include "4ed_app_models.h"
#include "4ed_file_view.cpp" #include "4ed_view.cpp"
#include "4ed.cpp" #include "4ed.cpp"
// BOTTOM // BOTTOM

View File

@ -15,11 +15,6 @@
#include "4coder_helper/4coder_seek_types.h" #include "4coder_helper/4coder_seek_types.h"
struct Cursor_With_Index{
i32 pos;
i32 index;
};
inline void inline void
write_cursor_with_index(Cursor_With_Index *positions, i32 *count, i32 pos){ write_cursor_with_index(Cursor_With_Index *positions, i32 *count, i32 pos){
positions[(*count)].index = *count; positions[(*count)].index = *count;
@ -278,18 +273,6 @@ eol_in_place_convert_out(char *data, i32 size, i32 max, i32 *size_out){
// Implementation of the gap buffer // Implementation of the gap buffer
// //
struct Gap_Buffer{
char *data;
i32 size1;
i32 gap_size;
i32 size2;
i32 max;
i32 *line_starts;
i32 line_count;
i32 line_max;
};
inline i32 inline i32
buffer_good(Gap_Buffer *buffer){ buffer_good(Gap_Buffer *buffer){
i32 good = (buffer->data != 0); i32 good = (buffer->data != 0);
@ -302,12 +285,6 @@ buffer_size(Gap_Buffer *buffer){
return(size); return(size);
} }
struct Gap_Buffer_Init{
Gap_Buffer *buffer;
char *data;
i32 size;
};
internal Gap_Buffer_Init internal Gap_Buffer_Init
buffer_begin_init(Gap_Buffer *buffer, char *data, i32 size){ buffer_begin_init(Gap_Buffer *buffer, char *data, i32 size){
Gap_Buffer_Init init; Gap_Buffer_Init init;
@ -366,18 +343,6 @@ buffer_end_init(Gap_Buffer_Init *init, void *scratch, i32 scratch_size){
return(result); return(result);
} }
struct Gap_Buffer_Stream{
Gap_Buffer *buffer;
char *data;
i32 end;
i32 separated;
i32 absolute_end;
b32 use_termination_character;
char terminator;
};
global Gap_Buffer_Stream null_buffer_stream = {0};
internal b32 internal b32
buffer_stringify_loop(Gap_Buffer_Stream *stream, Gap_Buffer *buffer, i32 start, i32 end){ buffer_stringify_loop(Gap_Buffer_Stream *stream, Gap_Buffer *buffer, i32 start, i32 end){
b32 result = 0; b32 result = 0;
@ -494,11 +459,6 @@ buffer_replace_range(Gap_Buffer *buffer, i32 start, i32 end, char *str, i32 len,
return(result); return(result);
} }
struct Buffer_Batch_State{
i32 i;
i32 shift_total;
};
// TODO(allen): Now that we are just using Gap_Buffer we could afford to improve // TODO(allen): Now that we are just using Gap_Buffer we could afford to improve
// this for the Gap_Buffer's behavior. // this for the Gap_Buffer's behavior.
internal i32 internal i32
@ -610,12 +570,6 @@ buffer_count_newlines(Gap_Buffer *buffer, i32 start, i32 end){
return(count); return(count);
} }
struct Buffer_Measure_Starts{
i32 i;
i32 count;
i32 start;
};
// TODO(allen): Rewrite this with a duff routine // TODO(allen): Rewrite this with a duff routine
// Also make it so that the array goes one past the end // Also make it so that the array goes one past the end
// and stores the size in the extra spot. // and stores the size in the extra spot.
@ -728,56 +682,6 @@ buffer_measure_character_starts(System_Functions *system, Font_Pointers font, Ga
Assert(line_index-1 == buffer->line_count); Assert(line_index-1 == buffer->line_count);
} }
enum{
BLStatus_Finished,
BLStatus_NeedWrapLineShift,
BLStatus_NeedLineShift,
BLStatus_NeedWrapDetermination,
};
struct Buffer_Layout_Stop{
u32 status;
i32 line_index;
i32 wrap_line_index;
i32 pos;
i32 next_line_pos;
f32 x;
};
struct Buffer_Measure_Wrap_Params{
Gap_Buffer *buffer;
i32 *wrap_line_index;
System_Functions *system;
Font_Pointers font;
b32 virtual_white;
};
struct Buffer_Measure_Wrap_State{
Gap_Buffer_Stream stream;
i32 i;
i32 size;
b32 still_looping;
i32 line_index;
i32 current_wrap_index;
f32 current_adv;
f32 x;
b32 skipping_whitespace;
i32 wrap_unit_end;
b32 did_wrap;
b32 first_of_the_line;
Translation_State tran;
Translation_Emits emits;
u32 J;
Buffer_Model_Step step;
Buffer_Model_Behavior behavior;
i32 __pc__;
};
// duff-routine defines // duff-routine defines
#define DrCase(PC) case PC: goto resumespot_##PC #define DrCase(PC) case PC: goto resumespot_##PC
#define DrYield(PC, n) { *S_ptr = S; S_ptr->__pc__ = PC; return(n); resumespot_##PC:; } #define DrYield(PC, n) { *S_ptr = S; S_ptr->__pc__ = PC; return(n); resumespot_##PC:; }
@ -1295,45 +1199,6 @@ buffer_partial_from_line_character(Gap_Buffer *buffer, i32 line, i32 character){
return(result); return(result);
} }
struct Buffer_Cursor_Seek_Params{
Gap_Buffer *buffer;
Buffer_Seek seek;
System_Functions *system;
Font_Pointers font;
i32 *wrap_line_index;
i32 *character_starts;
b32 virtual_white;
b32 return_hint;
Full_Cursor *cursor_out;
};
struct Buffer_Cursor_Seek_State{
Full_Cursor next_cursor;
Full_Cursor this_cursor;
Full_Cursor prev_cursor;
Gap_Buffer_Stream stream;
b32 still_looping;
i32 i;
i32 size;
i32 wrap_unit_end;
b32 first_of_the_line;
b32 xy_seek;
f32 ch_width;
i32 font_height;
Translation_State tran;
Translation_Emits emits;
u32 J;
Buffer_Model_Step step;
Buffer_Model_Behavior behavior;
i32 __pc__;
};
// dialogical-routine defines // dialogical-routine defines
#define DrCase(PC) case PC: goto resumespot_##PC #define DrCase(PC) case PC: goto resumespot_##PC
#define DrYield(PC, n) { *S_ptr = S; S_ptr->__pc__ = PC; return(n); resumespot_##PC:; } #define DrYield(PC, n) { *S_ptr = S; S_ptr->__pc__ = PC; return(n); resumespot_##PC:; }
@ -1683,12 +1548,6 @@ buffer_invert_edit(Gap_Buffer *buffer, Buffer_Edit edit, Buffer_Edit *inverse, c
buffer_invert_edit_shift(buffer, edit, inverse, strings, str_pos, max, 0); buffer_invert_edit_shift(buffer, edit, inverse, strings, str_pos, max, 0);
} }
struct Buffer_Invert_Batch{
i32 i;
i32 shift_amount;
i32 len;
};
internal i32 internal i32
buffer_invert_batch(Buffer_Invert_Batch *state, Gap_Buffer *buffer, Buffer_Edit *edits, i32 count, buffer_invert_batch(Buffer_Invert_Batch *state, Gap_Buffer *buffer, Buffer_Edit *edits, i32 count,
Buffer_Edit *inverse, char *strings, i32 *str_pos, i32 max){ Buffer_Edit *inverse, char *strings, i32 *str_pos, i32 max){
@ -1715,29 +1574,6 @@ buffer_invert_batch(Buffer_Invert_Batch *state, Gap_Buffer *buffer, Buffer_Edit
return(result); return(result);
} }
enum Buffer_Render_Flag{
BRFlag_Special_Character = (1 << 0),
BRFlag_Ghost_Character = (1 << 1)
};
struct Buffer_Render_Item{
i32 index;
u32 codepoint;
u32 flags;
f32 x0, y0;
f32 x1, y1;
};
struct Render_Item_Write{
Buffer_Render_Item *item;
f32 x, y;
System_Functions *system;
Font_Pointers font;
i32 font_height;
f32 x_min;
f32 x_max;
};
inline Render_Item_Write inline Render_Item_Write
write_render_item(Render_Item_Write write, i32 index, u32 codepoint, u32 flags){ write_render_item(Render_Item_Write write, i32 index, u32 codepoint, u32 flags){
@ -1760,55 +1596,6 @@ write_render_item(Render_Item_Write write, i32 index, u32 codepoint, u32 flags){
return(write); return(write);
} }
struct Buffer_Render_Params{
Gap_Buffer *buffer;
Buffer_Render_Item *items;
i32 max;
i32 *count;
f32 port_x;
f32 port_y;
f32 clip_w;
f32 scroll_x;
f32 scroll_y;
f32 width;
f32 height;
Full_Cursor start_cursor;
i32 wrapped;
System_Functions *system;
Font_Pointers font;
b32 virtual_white;
i32 wrap_slashes;
};
struct Buffer_Render_State{
Gap_Buffer_Stream stream;
b32 still_looping;
i32 i;
i32 size;
f32 shift_x;
f32 shift_y;
f32 ch_width;
Render_Item_Write write;
f32 byte_advance;
i32 line;
i32 wrap_line;
b32 skipping_whitespace;
b32 first_of_the_line;
i32 wrap_unit_end;
Translation_State tran;
Translation_Emits emits;
u32 J;
Buffer_Model_Step step;
Buffer_Model_Behavior behavior;
i32 __pc__;
};
// duff-routine defines // duff-routine defines
#define DrCase(PC) case PC: goto resumespot_##PC #define DrCase(PC) case PC: goto resumespot_##PC
#define DrYield(PC, n) { *S_ptr = S; S_ptr->__pc__ = PC; return(n); resumespot_##PC:; } #define DrYield(PC, n) { *S_ptr = S; S_ptr->__pc__ = PC; return(n); resumespot_##PC:; }

230
4ed_buffer.h Normal file
View File

@ -0,0 +1,230 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 24.01.2018
*
* Buffer types
*
*/
// TOP
#if !defined(FRED_BUFFER_H)
#define FRED_BUFFER_H
struct Cursor_With_Index{
i32 pos;
i32 index;
};
struct Gap_Buffer{
char *data;
i32 size1;
i32 gap_size;
i32 size2;
i32 max;
i32 *line_starts;
i32 line_count;
i32 line_max;
};
struct Gap_Buffer_Init{
Gap_Buffer *buffer;
char *data;
i32 size;
};
struct Gap_Buffer_Stream{
Gap_Buffer *buffer;
char *data;
i32 end;
i32 separated;
i32 absolute_end;
b32 use_termination_character;
char terminator;
};
global Gap_Buffer_Stream null_buffer_stream = {0};
struct Buffer_Batch_State{
i32 i;
i32 shift_total;
};
struct Buffer_Measure_Starts{
i32 i;
i32 count;
i32 start;
};
enum{
BLStatus_Finished,
BLStatus_NeedWrapLineShift,
BLStatus_NeedLineShift,
BLStatus_NeedWrapDetermination,
};
struct Buffer_Layout_Stop{
u32 status;
i32 line_index;
i32 wrap_line_index;
i32 pos;
i32 next_line_pos;
f32 x;
};
struct Buffer_Measure_Wrap_Params{
Gap_Buffer *buffer;
i32 *wrap_line_index;
System_Functions *system;
Font_Pointers font;
b32 virtual_white;
};
struct Buffer_Measure_Wrap_State{
Gap_Buffer_Stream stream;
i32 i;
i32 size;
b32 still_looping;
i32 line_index;
i32 current_wrap_index;
f32 current_adv;
f32 x;
b32 skipping_whitespace;
i32 wrap_unit_end;
b32 did_wrap;
b32 first_of_the_line;
Translation_State tran;
Translation_Emits emits;
u32 J;
Buffer_Model_Step step;
Buffer_Model_Behavior behavior;
i32 __pc__;
};
struct Buffer_Cursor_Seek_Params{
Gap_Buffer *buffer;
Buffer_Seek seek;
System_Functions *system;
Font_Pointers font;
i32 *wrap_line_index;
i32 *character_starts;
b32 virtual_white;
b32 return_hint;
Full_Cursor *cursor_out;
};
struct Buffer_Cursor_Seek_State{
Full_Cursor next_cursor;
Full_Cursor this_cursor;
Full_Cursor prev_cursor;
Gap_Buffer_Stream stream;
b32 still_looping;
i32 i;
i32 size;
i32 wrap_unit_end;
b32 first_of_the_line;
b32 xy_seek;
f32 ch_width;
i32 font_height;
Translation_State tran;
Translation_Emits emits;
u32 J;
Buffer_Model_Step step;
Buffer_Model_Behavior behavior;
i32 __pc__;
};
struct Buffer_Invert_Batch{
i32 i;
i32 shift_amount;
i32 len;
};
enum Buffer_Render_Flag{
BRFlag_Special_Character = (1 << 0),
BRFlag_Ghost_Character = (1 << 1)
};
struct Buffer_Render_Item{
i32 index;
u32 codepoint;
u32 flags;
f32 x0, y0;
f32 x1, y1;
};
struct Render_Item_Write{
Buffer_Render_Item *item;
f32 x, y;
System_Functions *system;
Font_Pointers font;
i32 font_height;
f32 x_min;
f32 x_max;
};
struct Buffer_Render_Params{
Gap_Buffer *buffer;
Buffer_Render_Item *items;
i32 max;
i32 *count;
f32 port_x;
f32 port_y;
f32 clip_w;
f32 scroll_x;
f32 scroll_y;
f32 width;
f32 height;
Full_Cursor start_cursor;
i32 wrapped;
System_Functions *system;
Font_Pointers font;
b32 virtual_white;
i32 wrap_slashes;
};
struct Buffer_Render_State{
Gap_Buffer_Stream stream;
b32 still_looping;
i32 i;
i32 size;
f32 shift_x;
f32 shift_y;
f32 ch_width;
Render_Item_Write write;
f32 byte_advance;
i32 line;
i32 wrap_line;
b32 skipping_whitespace;
b32 first_of_the_line;
i32 wrap_unit_end;
Translation_State tran;
Translation_Emits emits;
u32 J;
Buffer_Model_Step step;
Buffer_Model_Behavior behavior;
i32 __pc__;
};
#endif
// BOTTOM

View File

@ -13,22 +13,6 @@
// Edit Position Basics // Edit Position Basics
// //
enum Edit_Pos_Set_Type{
EditPos_None,
EditPos_CursorSet,
EditPos_ScrollSet
};
struct File_Edit_Positions{
GUI_Scroll_Vars scroll;
Full_Cursor cursor;
i32 mark;
f32 preferred_x;
i32 scroll_i;
i32 last_set_type;
b32 in_view;
};
static File_Edit_Positions null_edit_pos = {0};
internal void internal void
edit_pos_set_cursor(File_Edit_Positions *edit_pos, Full_Cursor cursor, b32 set_preferred_x, b32 unwrapped_lines){ edit_pos_set_cursor(File_Edit_Positions *edit_pos, Full_Cursor cursor, b32 set_preferred_x, b32 unwrapped_lines){
edit_pos->cursor = cursor; edit_pos->cursor = cursor;
@ -47,26 +31,10 @@ edit_pos_set_scroll(File_Edit_Positions *edit_pos, GUI_Scroll_Vars scroll){
edit_pos->last_set_type = EditPos_ScrollSet; edit_pos->last_set_type = EditPos_ScrollSet;
} }
// TODO(NAME): Replace this with markers over time.
//
// Highlighting Information
//
struct Text_Effect{
i32 start, end;
u32 color;
f32 seconds_down, seconds_max;
};
// //
// Editing_File // Editing_File
// //
union Buffer_Slot_ID{
Buffer_ID id;
i16 part[2];
};
inline Buffer_Slot_ID inline Buffer_Slot_ID
to_file_id(i32 id){ to_file_id(i32 id){
Buffer_Slot_ID result; Buffer_Slot_ID result;
@ -74,110 +42,6 @@ to_file_id(i32 id){
return(result); return(result);
} }
struct Marker_Array{
Marker_Array *next, *prev;
Buffer_Slot_ID buffer_id;
u32 count, sim_max, max;
Marker marker_0;
};
global_const u32 sizeof_marker_array = sizeof(Marker_Array) - sizeof(Marker);
struct Editing_File_Markers{
Marker_Array sentinel;
u32 array_count;
u32 marker_count;
};
struct Editing_File_Settings{
i32 base_map_id;
i32 display_width;
i32 minimum_base_display_width;
i32 wrap_indicator;
Parse_Context_ID parse_context_id;
b32 dos_write_mode;
b32 virtual_white;
Face_ID font_id;
b8 unwrapped_lines;
b8 tokens_exist;
b8 tokens_without_strings;
b8 is_initialized;
b8 unimportant;
b8 read_only;
b8 never_kill;
u8 pad[1];
};
global_const Editing_File_Settings null_editing_file_settings = {0};
struct Editing_Hacks{
b32 suppression_mode;
b32 needs_wraps_and_fix_cursor;
};
struct Editing_File_State{
Gap_Buffer buffer;
i32 *wrap_line_index;
i32 wrap_max;
i32 *character_starts;
i32 character_start_max;
f32 *line_indents;
i32 line_indent_max;
i32 wrap_line_count;
i32 *wrap_positions;
i32 wrap_position_count;
i32 wrap_position_max;
Undo_Data undo;
Cpp_Token_Array token_array;
Cpp_Token_Array swap_array;
u32 lex_job;
b32 tokens_complete;
b32 still_lexing;
Text_Effect paste_effect;
Dirty_State dirty;
u32 ignore_behind_os;
File_Edit_Positions edit_pos_space[16];
File_Edit_Positions *edit_poss[16];
i32 edit_poss_count;
Editing_Hacks hacks;
};
global_const Editing_File_State null_editing_file_state = {0};
struct Editing_File_Name{
char name_[256];
String name;
};
struct File_Node{
File_Node *next;
File_Node *prev;
};
struct Editing_File{
// NOTE(allen): node must be the first member of Editing_File!
File_Node node;
Editing_File_Settings settings;
b32 is_loading;
b32 is_dummy;
Editing_File_State state;
Editing_File_Markers markers;
Editing_File_Name base_name;
Editing_File_Name unique_name;
Editing_File_Name canon;
Buffer_Slot_ID id;
};
static Editing_File null_editing_file = {0};
// //
// Handling a file's Marker Arrays // Handling a file's Marker Arrays
// //
@ -207,9 +71,9 @@ clear_file_markers_state(General_Memory *general, Editing_File_Markers *markers)
internal void* internal void*
allocate_markers_state(General_Memory *general, Editing_File *file, u32 new_array_max){ allocate_markers_state(General_Memory *general, Editing_File *file, u32 new_array_max){
u32 memory_size = sizeof_marker_array + sizeof(Marker)*new_array_max; u32 memory_size = sizeof(Marker_Array) + sizeof(Marker)*new_array_max;
memory_size = l_round_up_u32(memory_size, KB(4)); memory_size = l_round_up_u32(memory_size, KB(4));
u32 real_max = (memory_size - sizeof_marker_array)/sizeof(Marker); u32 real_max = (memory_size - sizeof(Marker_Array))/sizeof(Marker);
Marker_Array *array = (Marker_Array*)general_memory_allocate(general, memory_size); Marker_Array *array = (Marker_Array*)general_memory_allocate(general, memory_size);
dll_insert_back(&file->markers.sentinel, array); dll_insert_back(&file->markers.sentinel, array);
@ -243,7 +107,7 @@ markers_set(Editing_File *file, void *handle, u32 first_index, u32 count, Marker
file->markers.marker_count += new_count - markers->count; file->markers.marker_count += new_count - markers->count;
markers->count = new_count; markers->count = new_count;
} }
Marker *dst = &markers->marker_0; Marker *dst = MarkerArrayBase(markers);
memcpy(dst + first_index, source, sizeof(Marker)*count); memcpy(dst + first_index, source, sizeof(Marker)*count);
result = true; result = true;
} }
@ -260,7 +124,7 @@ markers_get(Editing_File *file, void *handle, u32 first_index, u32 count, Marker
Marker_Array *markers = (Marker_Array*)handle; Marker_Array *markers = (Marker_Array*)handle;
if (markers->buffer_id.id == file->id.id){ if (markers->buffer_id.id == file->id.id){
if (first_index + count <= markers->count){ if (first_index + count <= markers->count){
Marker *src = &markers->marker_0; Marker *src = MarkerArrayBase(markers);
memcpy(output, src + first_index, sizeof(Marker)*count); memcpy(output, src + first_index, sizeof(Marker)*count);
result = true; result = true;
} }
@ -465,9 +329,9 @@ file_is_ready(Editing_File *file){
inline void inline void
file_set_to_loading(Editing_File *file){ file_set_to_loading(Editing_File *file){
file->state = null_editing_file_state; memset(&file->state, 0, sizeof(file->state));
file->settings = null_editing_file_settings; memset(&file->settings, 0, sizeof(file->settings));
file->is_loading = 1; file->is_loading = true;
} }
inline void inline void

145
4ed_file.h Normal file
View File

@ -0,0 +1,145 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 24.01.2018
*
* Buffer types
*
*/
// TOP
#if !defined(FRED_FILE_H)
#define FRED_FILE_H
enum Edit_Pos_Set_Type{
EditPos_None,
EditPos_CursorSet,
EditPos_ScrollSet
};
struct File_Edit_Positions{
GUI_Scroll_Vars scroll;
Full_Cursor cursor;
i32 mark;
f32 preferred_x;
i32 scroll_i;
i32 last_set_type;
b32 in_view;
};
// TODO(NAME): Replace this with markers over time.
struct Text_Effect{
i32 start, end;
u32 color;
f32 seconds_down, seconds_max;
};
union Buffer_Slot_ID{
Buffer_ID id;
i16 part[2];
};
struct Marker_Array{
Marker_Array *next, *prev;
Buffer_Slot_ID buffer_id;
u32 count, sim_max, max;
};
#define MarkerArrayBase(array) (Marker*)((u8*)(array) + sizeof(Marker_Array))
struct Editing_File_Markers{
Marker_Array sentinel;
u32 array_count;
u32 marker_count;
};
struct Editing_File_Settings{
i32 base_map_id;
i32 display_width;
i32 minimum_base_display_width;
i32 wrap_indicator;
Parse_Context_ID parse_context_id;
b32 dos_write_mode;
b32 virtual_white;
Face_ID font_id;
b8 unwrapped_lines;
b8 tokens_exist;
b8 tokens_without_strings;
b8 is_initialized;
b8 unimportant;
b8 read_only;
b8 never_kill;
u8 pad[1];
};
struct Editing_Hacks{
b32 suppression_mode;
b32 needs_wraps_and_fix_cursor;
};
struct Editing_File_State{
Gap_Buffer buffer;
i32 *wrap_line_index;
i32 wrap_max;
i32 *character_starts;
i32 character_start_max;
f32 *line_indents;
i32 line_indent_max;
i32 wrap_line_count;
i32 *wrap_positions;
i32 wrap_position_count;
i32 wrap_position_max;
Undo_Data undo;
Cpp_Token_Array token_array;
Cpp_Token_Array swap_array;
u32 lex_job;
b32 tokens_complete;
b32 still_lexing;
Text_Effect paste_effect;
Dirty_State dirty;
u32 ignore_behind_os;
File_Edit_Positions edit_pos_space[16];
File_Edit_Positions *edit_poss[16];
i32 edit_poss_count;
Editing_Hacks hacks;
};
struct Editing_File_Name{
char name_[256];
String name;
};
struct File_Node{
File_Node *next;
File_Node *prev;
};
struct Editing_File{
// NOTE(allen): node must be the first member of Editing_File!
File_Node node;
Editing_File_Settings settings;
b32 is_loading;
b32 is_dummy;
Editing_File_State state;
Editing_File_Markers markers;
Editing_File_Name base_name;
Editing_File_Name unique_name;
Editing_File_Name canon;
Buffer_Slot_ID id;
};
#endif
// BOTTOM

File diff suppressed because it is too large Load Diff

83
4ed_generated_style.h Normal file
View File

@ -0,0 +1,83 @@
struct Interactive_Style{
u32 bar_color;
u32 bar_active_color;
u32 base_color;
u32 pop1_color;
u32 pop2_color;
};
struct Style_Main_Data{
u32 back_color;
u32 margin_color;
u32 margin_hover_color;
u32 margin_active_color;
u32 list_item_color;
u32 list_item_hover_color;
u32 list_item_active_color;
u32 cursor_color;
u32 at_cursor_color;
u32 highlight_color;
u32 at_highlight_color;
u32 mark_color;
u32 default_color;
u32 comment_color;
u32 keyword_color;
u32 str_constant_color;
u32 char_constant_color;
u32 int_constant_color;
u32 float_constant_color;
u32 bool_constant_color;
u32 preproc_color;
u32 include_color;
u32 special_character_color;
u32 ghost_character_color;
u32 highlight_junk_color;
u32 highlight_white_color;
u32 paste_color;
u32 undo_color;
u32 next_undo_color;
Interactive_Style file_info_style;
};
inline u32*
style_index_by_tag(Style_Main_Data *s, u32 tag){
u32 *result = 0;
switch (tag){
case Stag_Bar: result = &s->file_info_style.bar_color; break;
case Stag_Bar_Active: result = &s->file_info_style.bar_active_color; break;
case Stag_Base: result = &s->file_info_style.base_color; break;
case Stag_Pop1: result = &s->file_info_style.pop1_color; break;
case Stag_Pop2: result = &s->file_info_style.pop2_color; break;
case Stag_Back: result = &s->back_color; break;
case Stag_Margin: result = &s->margin_color; break;
case Stag_Margin_Hover: result = &s->margin_hover_color; break;
case Stag_Margin_Active: result = &s->margin_active_color; break;
case Stag_List_Item: result = &s->list_item_color; break;
case Stag_List_Item_Hover: result = &s->list_item_hover_color; break;
case Stag_List_Item_Active: result = &s->list_item_active_color; break;
case Stag_Cursor: result = &s->cursor_color; break;
case Stag_At_Cursor: result = &s->at_cursor_color; break;
case Stag_Highlight: result = &s->highlight_color; break;
case Stag_At_Highlight: result = &s->at_highlight_color; break;
case Stag_Mark: result = &s->mark_color; break;
case Stag_Default: result = &s->default_color; break;
case Stag_Comment: result = &s->comment_color; break;
case Stag_Keyword: result = &s->keyword_color; break;
case Stag_Str_Constant: result = &s->str_constant_color; break;
case Stag_Char_Constant: result = &s->char_constant_color; break;
case Stag_Int_Constant: result = &s->int_constant_color; break;
case Stag_Float_Constant: result = &s->float_constant_color; break;
case Stag_Bool_Constant: result = &s->bool_constant_color; break;
case Stag_Preproc: result = &s->preproc_color; break;
case Stag_Include: result = &s->include_color; break;
case Stag_Special_Character: result = &s->special_character_color; break;
case Stag_Ghost_Character: result = &s->ghost_character_color; break;
case Stag_Highlight_Junk: result = &s->highlight_junk_color; break;
case Stag_Highlight_White: result = &s->highlight_white_color; break;
case Stag_Paste: result = &s->paste_color; break;
case Stag_Undo: result = &s->undo_color; break;
case Stag_Next_Undo: result = &s->next_undo_color; break;
}
return(result);
}

View File

@ -9,17 +9,6 @@
// TOP // TOP
struct Query_Slot{
Query_Slot *next;
Query_Bar *query_bar;
};
struct Query_Set{
Query_Slot slots[8];
Query_Slot *free_slot;
Query_Slot *used_slot;
};
internal void internal void
init_query_set(Query_Set *set){ init_query_set(Query_Set *set){
Query_Slot *slot = set->slots; Query_Slot *slot = set->slots;
@ -63,12 +52,6 @@ free_query_slot(Query_Set *set, Query_Bar *match_bar){
} }
} }
struct Super_Color{
Vec4 hsla;
Vec4 rgba;
u32 *out;
};
internal Super_Color internal Super_Color
super_color_create(u32 packed){ super_color_create(u32 packed){
Super_Color result = {}; Super_Color result = {};
@ -112,91 +95,6 @@ super_color_post_byte(Super_Color *color, i32 channel, u8 byte){
return packed; return packed;
} }
struct GUI_Target{
Partition push;
GUI_id active;
GUI_id mouse_hot;
GUI_id auto_hot;
GUI_id hover;
// TODO(allen): Can we remove original yet?
GUI_Scroll_Vars scroll_original;
i32_Rect region_original;
//GUI_Scroll_Vars scroll_updated;
i32_Rect region_updated;
// TODO(allen): Would rather have a way of tracking this
// for more than one list. Perhaps just throw in a hash table?
// Or maybe this only needs to be tracked for the active list.
i32 list_max;
b32 has_list_index_position;
i32_Rect list_index_position;
i32 list_view_min;
i32 list_view_max;
GUI_id scroll_id;
// TODO(allen): is currently ignored in the wheel code, reevaluate?
i32 delta;
b32 has_keys;
b32 animating;
b32 did_file;
};
struct GUI_Item_Update{
i32 partition_point;
b32 has_adjustment;
i32 adjustment_value;
b32 has_index_position;
i32_Rect index_position;
};
struct GUI_Header{
i32 type;
i32 size;
};
struct GUI_Interactive{
GUI_Header h;
GUI_id id;
};
struct GUI_Edit{
GUI_Header h;
GUI_id id;
void *out;
};
enum GUI_Command_Type{
guicom_null,
guicom_begin_serial,
guicom_end_serial,
guicom_top_bar,
guicom_file,
guicom_text_field,
guicom_color_button,
guicom_font_button,
guicom_text_with_cursor,
guicom_begin_list,
guicom_end_list,
guicom_file_option,
guicom_fixed_option,
guicom_button,
guicom_fixed_option_checkbox,
guicom_style_preview,
guicom_scrollable,
guicom_scrollable_bar,
guicom_scrollable_top,
guicom_scrollable_slider,
guicom_scrollable_bottom,
guicom_scrollable_invisible,
guicom_begin_scrollable_section,
guicom_end_scrollable_section,
};
inline b32 inline b32
gui_id_eq(GUI_id id1, GUI_id id2){ gui_id_eq(GUI_id id1, GUI_id id2){
b32 result = (id1.id[0] == id2.id[0] && id1.id[1] == id2.id[1]); b32 result = (id1.id[0] == id2.id[0] && id1.id[1] == id2.id[1]);
@ -720,38 +618,6 @@ gui_activate_scrolling(GUI_Target *target){
target->active = gui_id_scrollbar(); target->active = gui_id_scrollbar();
} }
struct GUI_Section{
i32 max_v, v, top_v;
};
struct GUI_List_Vars{
b32 in_list;
i32 index;
i32 auto_hot;
i32 auto_activate;
};
struct GUI_Session{
i32_Rect full_rect;
i32_Rect rect;
i32 suggested_max_y;
i32 clip_y;
i32 line_height;
b32 is_scrollable;
i32 scrollable_items_bottom;
i32_Rect scroll_region;
i32_Rect scroll_rect;
f32 scroll_top, scroll_bottom;
GUI_List_Vars list;
GUI_Section sections[64];
i32 t;
};
#define GUIScrollbarWidth 16 #define GUIScrollbarWidth 16
// TODO(allen): We can probably totally get rid of this now. // TODO(allen): We can probably totally get rid of this now.
@ -924,16 +790,6 @@ gui_read_out(void **ptr){
return(result); return(result);
} }
struct GUI_Interpret_Result{
b32 has_info;
b32 auto_hot;
b32 auto_activate;
i32 screen_orientation;
b32 has_region;
i32_Rect region;
};
internal GUI_Interpret_Result internal GUI_Interpret_Result
gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h, gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h,
GUI_Scroll_Vars vars, i32_Rect region, i32 max_y){ GUI_Scroll_Vars vars, i32_Rect region, i32 max_y){
@ -1212,11 +1068,6 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h,
return(result); return(result);
} }
struct GUI_View_Jump{
i32 view_min;
i32 view_max;
};
internal GUI_View_Jump internal GUI_View_Jump
gui_compute_view_jump(i32_Rect scroll_region, i32_Rect position){ gui_compute_view_jump(i32_Rect scroll_region, i32_Rect position){
GUI_View_Jump jump = {0}; GUI_View_Jump jump = {0};

162
4ed_gui.h
View File

@ -1,3 +1,13 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 20.02.2016
*
* GUI system for 4coder
*
*/
// TOP
#ifndef FCODER_GUI_H #ifndef FCODER_GUI_H
#define FCODER_GUI_H #define FCODER_GUI_H
@ -55,4 +65,156 @@ struct GUI_Functions{
GUI_File_Function *file; GUI_File_Function *file;
}; };
struct Query_Slot{
Query_Slot *next;
Query_Bar *query_bar;
};
struct Query_Set{
Query_Slot slots[8];
Query_Slot *free_slot;
Query_Slot *used_slot;
};
struct Super_Color{
Vec4 hsla;
Vec4 rgba;
u32 *out;
};
struct GUI_Target{
Partition push;
GUI_id active;
GUI_id mouse_hot;
GUI_id auto_hot;
GUI_id hover;
// TODO(allen): Can we remove original yet?
GUI_Scroll_Vars scroll_original;
i32_Rect region_original;
//GUI_Scroll_Vars scroll_updated;
i32_Rect region_updated;
// TODO(allen): Would rather have a way of tracking this
// for more than one list. Perhaps just throw in a hash table?
// Or maybe this only needs to be tracked for the active list.
i32 list_max;
b32 has_list_index_position;
i32_Rect list_index_position;
i32 list_view_min;
i32 list_view_max;
GUI_id scroll_id;
// TODO(allen): is currently ignored in the wheel code, reevaluate?
i32 delta;
b32 has_keys;
b32 animating;
b32 did_file;
};
struct GUI_Item_Update{
i32 partition_point;
b32 has_adjustment;
i32 adjustment_value;
b32 has_index_position;
i32_Rect index_position;
};
struct GUI_Header{
i32 type;
i32 size;
};
struct GUI_Interactive{
GUI_Header h;
GUI_id id;
};
struct GUI_Edit{
GUI_Header h;
GUI_id id;
void *out;
};
enum GUI_Command_Type{
guicom_null,
guicom_begin_serial,
guicom_end_serial,
guicom_top_bar,
guicom_file,
guicom_text_field,
guicom_color_button,
guicom_font_button,
guicom_text_with_cursor,
guicom_begin_list,
guicom_end_list,
guicom_file_option,
guicom_fixed_option,
guicom_button,
guicom_fixed_option_checkbox,
guicom_style_preview,
guicom_scrollable,
guicom_scrollable_bar,
guicom_scrollable_top,
guicom_scrollable_slider,
guicom_scrollable_bottom,
guicom_scrollable_invisible,
guicom_begin_scrollable_section,
guicom_end_scrollable_section,
};
struct GUI_Section{
i32 max_v, v, top_v;
};
struct GUI_List_Vars{
b32 in_list;
i32 index;
i32 auto_hot;
i32 auto_activate;
};
struct GUI_Session{
i32_Rect full_rect;
i32_Rect rect;
i32 suggested_max_y;
i32 clip_y;
i32 line_height;
b32 is_scrollable;
i32 scrollable_items_bottom;
i32_Rect scroll_region;
i32_Rect scroll_rect;
f32 scroll_top, scroll_bottom;
GUI_List_Vars list;
GUI_Section sections[64];
i32 t;
};
struct GUI_Interpret_Result{
b32 has_info;
b32 auto_hot;
b32 auto_activate;
i32 screen_orientation;
b32 has_region;
i32_Rect region;
};
struct GUI_View_Jump{
i32 view_min;
i32 view_max;
};
#endif #endif
// BOTTOM

View File

@ -9,14 +9,6 @@
// TOP // TOP
struct Hot_Directory{
char string_space[256];
char canon_dir_space[256];
String string;
String canon_dir;
File_List file_list;
};
internal void internal void
hot_directory_clean_end(Hot_Directory *hot_directory){ hot_directory_clean_end(Hot_Directory *hot_directory){
String *str = &hot_directory->string; String *str = &hot_directory->string;

26
4ed_hot_directory.h Normal file
View File

@ -0,0 +1,26 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 24.01.2018
*
* Buffer types
*
*/
// TOP
#if !defined(FRED_HOT_DIRECTORY_H)
#define FRED_HOT_DIRECTORY_H
struct Hot_Directory{
char string_space[256];
char canon_dir_space[256];
String string;
String canon_dir;
File_List file_list;
};
#endif
// BOTTOM

View File

@ -9,22 +9,14 @@
// TOP // TOP
// NOTE(allen): These macros are setup to work on structs #if !defined(FRED_LINKED_NODE_MACROS_H)
// with a next and prev pointer where the type of the struct #define FRED_LINKED_NODE_MACROS_H
// is the same as the type of the next/prev pointers.
#define dll_init_sentinel(s) (s)->next=(s),(s)->prev=(s) #define dll_init_sentinel(s) (s)->next=(s),(s)->prev=(s)
#define dll_insert(p,n) (n)->next=(p)->next,(n)->prev=(p),(p)->next=(n),(n)->next->prev=(n) #define dll_insert(p,n) (n)->next=(p)->next,(n)->prev=(p),(p)->next=(n),(n)->next->prev=(n)
#define dll_insert_back(p,n) (n)->prev=(p)->prev,(n)->next=(p),(p)->prev=(n),(n)->prev->next=(n) #define dll_insert_back(p,n) (n)->prev=(p)->prev,(n)->next=(p),(p)->prev=(n),(n)->prev->next=(n)
#define dll_remove(n) (n)->next->prev=(n)->prev,(n)->prev->next=(n)->next #define dll_remove(n) (n)->next->prev=(n)->prev,(n)->prev->next=(n)->next
// HACK(allen): I don't like this anymore, get rid of it.
// for(dll_items(iterator, sentinel_ptr)){...}
#define dll_items(it, st) ((it) = (st)->next); ((it) != (st)); ((it) = (it)->next)
// NOTE(allen): These macros work on structs with a next
// pointer to the saem type as the containing struct.
#define sll_clear(f,l) (f)=(l)=0 #define sll_clear(f,l) (f)=(l)=0
#define sll_push(f,l,n) if((f)==0&&(l)==0){(f)=(l)=(n);}else{(l)->next=(n);(l)=(n);}(l)->next=0 #define sll_push(f,l,n) if((f)==0&&(l)==0){(f)=(l)=(n);}else{(l)->next=(n);(l)=(n);}(l)->next=0
#define sll_pop(f,l) if((f)!=(l)){(f)=(f)->next;}else{(f)=(l)=0;} #define sll_pop(f,l) if((f)!=(l)){(f)=(f)->next;}else{(f)=(l)=0;}
@ -33,9 +25,7 @@
#define sll_insert(p,v) do{ (v)->next=(p)->next; (p)->next = (v); }while(0) #define sll_insert(p,v) do{ (v)->next=(p)->next; (p)->next = (v); }while(0)
#define sll_remove(p,v) do{ Assert((p)->next == (v)); (p)->next = (v)->next; }while(0) #define sll_remove(p,v) do{ Assert((p)->next == (v)); (p)->next = (v)->next; }while(0)
// HACK(allen): I don't like this anymore, get rid of it. #endif
// for(sll_items(iterator, sentinel_ptr)){...}
#define sll_items(it, st) ((it) = (st)->next); ((it) != (st)); ((it) = (it)->next)
// BOTTOM // BOTTOM

View File

@ -1 +0,0 @@
struct Application_Links;

View File

@ -1,59 +0,0 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 28.08.2015
*
* Styles for 4coder
*
*/
// TOP
struct Style_Font{
Face_ID font_id;
};
struct Style{
char name_[24];
String name;
Style_Main_Data main;
};
internal void
style_copy(Style *dst, Style *src){
*dst = *src;
dst->name.str = dst->name_;
}
internal void
style_set_name(Style *style, String name){
i32 count = ArrayCount(style->name_);
style->name = make_string_cap(style->name_, 0, count - 1);
copy_ss(&style->name, name);
terminate_with_null(&style->name);
}
struct Style_Library{
Style styles[64];
i32 count, max;
};
internal void
style_set_colors(Style *style, Theme *theme){
for (u32 i = 0; i < Stag_COUNT; ++i){
u32 *color_ptr = style_index_by_tag(&style->main, i);
*color_ptr = theme->colors[i];
}
}
internal void
style_add(Style_Library *library, Theme *theme, String name){
if (library->count < library->max){
Style *style = &library->styles[library->count++];
style_set_colors(style, theme);
style_set_name(style, name);
}
}
// BOTTOM

View File

@ -1,83 +1,49 @@
struct Interactive_Style{ /*
u32 bar_color; * Mr. 4th Dimention - Allen Webster
u32 bar_active_color; *
u32 base_color; * 28.08.2015
u32 pop1_color; *
u32 pop2_color; * Styles for 4coder
*
*/
// TOP
#if !defined(FRED_STYLE_H)
#define FRED_STYLE_H
#include "4ed_generated_style.h"
struct Style_Font{
Face_ID font_id;
}; };
struct Style_Main_Data{ struct Style{
u32 back_color; char name_[24];
u32 margin_color; String name;
u32 margin_hover_color; Style_Main_Data main;
u32 margin_active_color;
u32 list_item_color;
u32 list_item_hover_color;
u32 list_item_active_color;
u32 cursor_color;
u32 at_cursor_color;
u32 highlight_color;
u32 at_highlight_color;
u32 mark_color;
u32 default_color;
u32 comment_color;
u32 keyword_color;
u32 str_constant_color;
u32 char_constant_color;
u32 int_constant_color;
u32 float_constant_color;
u32 bool_constant_color;
u32 preproc_color;
u32 include_color;
u32 special_character_color;
u32 ghost_character_color;
u32 highlight_junk_color;
u32 highlight_white_color;
u32 paste_color;
u32 undo_color;
u32 next_undo_color;
Interactive_Style file_info_style;
}; };
inline u32* internal void
style_index_by_tag(Style_Main_Data *s, u32 tag){ style_copy(Style *dst, Style *src){
u32 *result = 0; *dst = *src;
switch (tag){ dst->name.str = dst->name_;
case Stag_Bar: result = &s->file_info_style.bar_color; break;
case Stag_Bar_Active: result = &s->file_info_style.bar_active_color; break;
case Stag_Base: result = &s->file_info_style.base_color; break;
case Stag_Pop1: result = &s->file_info_style.pop1_color; break;
case Stag_Pop2: result = &s->file_info_style.pop2_color; break;
case Stag_Back: result = &s->back_color; break;
case Stag_Margin: result = &s->margin_color; break;
case Stag_Margin_Hover: result = &s->margin_hover_color; break;
case Stag_Margin_Active: result = &s->margin_active_color; break;
case Stag_List_Item: result = &s->list_item_color; break;
case Stag_List_Item_Hover: result = &s->list_item_hover_color; break;
case Stag_List_Item_Active: result = &s->list_item_active_color; break;
case Stag_Cursor: result = &s->cursor_color; break;
case Stag_At_Cursor: result = &s->at_cursor_color; break;
case Stag_Highlight: result = &s->highlight_color; break;
case Stag_At_Highlight: result = &s->at_highlight_color; break;
case Stag_Mark: result = &s->mark_color; break;
case Stag_Default: result = &s->default_color; break;
case Stag_Comment: result = &s->comment_color; break;
case Stag_Keyword: result = &s->keyword_color; break;
case Stag_Str_Constant: result = &s->str_constant_color; break;
case Stag_Char_Constant: result = &s->char_constant_color; break;
case Stag_Int_Constant: result = &s->int_constant_color; break;
case Stag_Float_Constant: result = &s->float_constant_color; break;
case Stag_Bool_Constant: result = &s->bool_constant_color; break;
case Stag_Preproc: result = &s->preproc_color; break;
case Stag_Include: result = &s->include_color; break;
case Stag_Special_Character: result = &s->special_character_color; break;
case Stag_Ghost_Character: result = &s->ghost_character_color; break;
case Stag_Highlight_Junk: result = &s->highlight_junk_color; break;
case Stag_Highlight_White: result = &s->highlight_white_color; break;
case Stag_Paste: result = &s->paste_color; break;
case Stag_Undo: result = &s->undo_color; break;
case Stag_Next_Undo: result = &s->next_undo_color; break;
}
return(result);
} }
internal void
style_set_name(Style *style, String name){
i32 count = ArrayCount(style->name_);
style->name = make_string_cap(style->name_, 0, count - 1);
copy_ss(&style->name, name);
terminate_with_null(&style->name);
}
struct Style_Library{
Style styles[64];
i32 count, max;
};
#endif
// BOTTOM

View File

@ -9,41 +9,6 @@
// TOP // TOP
#include "4ed_buffer_model.h"
struct Translation_State{
u8 fill_buffer[4];
u32 fill_start_i;
u8 fill_i;
u8 fill_expected;
};
global_const Translation_State null_buffer_translating_state = {0};
enum{
TranLBH_None,
TranLBH_Rebuffer,
TranLBH_EmitAsCP,
};
struct Translation_Byte_Description{
u8 byte_class;
u8 last_byte_handler;
u8 prelim_emit_type;
};
struct Translation_Emit_Rule{
u8 byte_class;
u8 last_byte_handler;
u8 emit_type;
u32 codepoint;
u32 codepoint_length;
};
struct Translation_Emits{
Buffer_Model_Step steps[5];
u32 step_count;
};
#define ERROR_BYTE (max_u8-1) #define ERROR_BYTE (max_u8-1)
#define CONTINUATION_BYTE max_u8 #define CONTINUATION_BYTE max_u8

51
4ed_translation.h Normal file
View File

@ -0,0 +1,51 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 24.01.2018
*
* Buffer types
*
*/
// TOP
#if !defined(FRED_TRANSLATION_H)
#define FRED_TRANSLATION_H
struct Translation_State{
u8 fill_buffer[4];
u32 fill_start_i;
u8 fill_i;
u8 fill_expected;
};
global_const Translation_State null_buffer_translating_state = {0};
enum{
TranLBH_None,
TranLBH_Rebuffer,
TranLBH_EmitAsCP,
};
struct Translation_Byte_Description{
u8 byte_class;
u8 last_byte_handler;
u8 prelim_emit_type;
};
struct Translation_Emit_Rule{
u8 byte_class;
u8 last_byte_handler;
u8 emit_type;
u32 codepoint;
u32 codepoint_length;
};
struct Translation_Emits{
Buffer_Model_Step steps[5];
u32 step_count;
};
#endif
// BOTTOM

View File

@ -1,17 +1,16 @@
/* /*
* Mr. 4th Dimention - Allen Webster * Mr. 4th Dimention - Allen Webster
* *
* 06.01.2017 * 24.01.2018
* *
* Undo subsystem for 4coder * Buffer types
* *
*/ */
// TOP // TOP
// #if !defined(FRED_UNDO_H)
// Undo Basics #define FRED_UNDO_H
//
enum Edit_Type{ enum Edit_Type{
ED_NORMAL, ED_NORMAL,
@ -66,5 +65,6 @@ struct Undo_Data{
b32 current_block_normal; b32 current_block_normal;
}; };
// BOTTOM #endif
// BOTTOM

File diff suppressed because it is too large Load Diff

367
4ed_view.h Normal file
View File

@ -0,0 +1,367 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 17.07.2017
*
* File editing view for 4coder.
*
*/
// TOP
#if !defined(FRED_VIEW_H)
#define FRED_VIEW_H
struct View_Persistent{
i32 id;
Coroutine_Head *coroutine;
Event_Message message_passing_slot;
};
struct File_Viewing_Data{
Editing_File *file;
Full_Cursor temp_highlight;
i32 temp_highlight_end_pos;
b32 show_temp_highlight;
b32 show_whitespace;
b32 file_locked;
};
global File_Viewing_Data null_file_viewing_data = {0};
enum Interactive_Action{
IAct_Open,
IAct_New,
IAct_OpenOrNew,
IAct_Switch,
IAct_Kill,
IAct_Sure_To_Kill,
IAct_Sure_To_Close
};
enum Interactive_Interaction{
IInt_Sys_File_List,
IInt_Live_File_List,
IInt_Sure_To_Kill,
IInt_Sure_To_Close
};
enum View_UI{
VUI_None,
VUI_Theme,
VUI_Interactive,
VUI_Debug
};
enum Debug_Mode{
DBG_Input,
DBG_Threads_And_Memory,
DBG_View_Inspection
};
enum Color_View_Mode{
CV_Mode_Library,
CV_Mode_Font,
CV_Mode_Global_Font,
CV_Mode_Font_Editing,
CV_Mode_Global_Font_Editing,
CV_Mode_Adjusting,
};
struct Scroll_Context{
Editing_File *file;
GUI_id scroll;
View_UI mode;
};
struct Debug_Vars{
i32 mode;
i32 inspecting_view_id;
};
global_const Debug_Vars null_debug_vars = {0};
struct View_Transient{
struct View *next;
struct View *prev;
struct Panel *panel;
b32 in_use;
i32 map;
File_Viewing_Data file_data;
i32_Rect file_region_prev;
i32_Rect file_region;
i32_Rect scroll_region;
File_Edit_Positions *edit_pos;
View_UI showing_ui;
GUI_Target gui_target;
void *gui_mem;
GUI_Scroll_Vars gui_scroll;
i32 gui_max_y;
i32 list_i;
b32 hide_scrollbar;
b32 hide_file_bar;
// interactive stuff
Interactive_Interaction interaction;
Interactive_Action action;
char dest_[256];
String dest;
b32 changed_context_in_step;
// theme stuff
View *hot_file_view;
u32 *palette;
Color_View_Mode color_mode;
Face_ID font_edit_id;
Super_Color color;
b32 p4c_only;
Style_Library inspecting_styles;
b8 import_export_check[64];
i32 import_file_id;
i32 current_color_editing;
i32 color_cursor;
// misc
// TODO(allen): Can we burn line_height to the ground now?
// It's what I've always wanted!!!! :D
i32 line_height;
// TODO(allen): Do I still use mode?
Query_Set query_set;
f32 widget_height;
b32 reinit_scrolling;
Debug_Vars debug_vars;
};
struct View{
// TODO(allen): Why is this this way?
View_Persistent persistent;
View_Transient transient;
};
struct Live_Views{
View *views;
View free_sentinel;
i32 count, max;
};
struct Cursor_Limits{
f32 min, max;
f32 delta;
};
struct View_And_ID{
View *view;
i32 id;
};
enum{
GROW_FAILED,
GROW_NOT_NEEDED,
GROW_SUCCESS,
};
struct Code_Wrap_X{
f32 base_x;
f32 paren_nesting[32];
i32 paren_safe_top;
i32 paren_top;
};
global Code_Wrap_X null_wrap_x = {0};
struct Code_Wrap_State{
Cpp_Token_Array token_array;
Cpp_Token *token_ptr;
Cpp_Token *end_token;
Code_Wrap_X wrap_x;
b32 in_pp_body;
Code_Wrap_X plane_wrap_x;
i32 *line_starts;
i32 line_count;
i32 line_index;
i32 next_line_start;
f32 x;
b32 consume_newline;
Gap_Buffer_Stream stream;
i32 size;
i32 i;
Font_Pointers font;
f32 tab_indent_amount;
f32 byte_advance;
Translation_State tran;
Translation_Emits emits;
u32 J;
Buffer_Model_Step step;
Buffer_Model_Behavior behavior;
};
struct Code_Wrap_Step{
i32 position_start;
i32 position_end;
f32 start_x;
f32 final_x;
Cpp_Token *this_token;
};
struct Wrap_Indent_Pair{
i32 wrap_position;
f32 line_shift;
};
struct Potential_Wrap_Indent_Pair{
i32 wrap_position;
f32 line_shift;
f32 wrap_x;
i32 wrappable_score;
b32 adjust_top_to_this;
};
struct Wrap_Current_Shift{
f32 shift;
b32 adjust_top_to_this;
};
struct Shift_Information{
i32 start, end, amount;
};
struct Edit_Spec{
u8 *str;
Edit_Step step;
};
struct Relative_Scrolling{
f32 scroll_x, scroll_y;
f32 target_x, target_y;
};
struct Cursor_Fix_Descriptor{
b32 is_batch;
union{
struct{
Buffer_Edit *batch;
i32 batch_size;
};
struct{
i32 start, end;
i32 shift_amount;
};
};
};
struct File_Bar{
f32 pos_x, pos_y;
f32 text_shift_x, text_shift_y;
i32_Rect rect;
Face_ID font_id;
};
struct Exhaustive_File_Loop{
char front_name_[256];
char full_path_[256];
String front_name, full_path;
Absolutes absolutes;
File_Info *infos;
i32 count, r;
};
struct Exhaustive_File_Info{
File_Info *info;
String message;
b8 is_folder;
b8 name_match;
b8 is_loaded;
};
struct Style_Color_Edit{
Style_Tag target;
Style_Tag fore;
Style_Tag back;
String text;
};
struct Single_Line_Input_Step{
b8 hit_newline;
b8 hit_ctrl_newline;
b8 hit_a_character;
b8 hit_backspace;
b8 hit_esc;
b8 made_a_change;
b8 did_command;
b8 no_file_match;
};
enum Single_Line_Input_Type{
SINGLE_LINE_STRING,
SINGLE_LINE_FILE
};
struct Single_Line_Mode{
Single_Line_Input_Type type;
String *string;
Hot_Directory *hot_directory;
b32 fast_folder_select;
b32 try_to_match;
b32 case_sensitive;
};
struct View_Step_Result{
b32 animating;
b32 consume_keys;
b32 consume_esc;
};
struct Input_Process_Result{
GUI_Scroll_Vars vars;
i32_Rect region;
b32 is_animating;
b32 consumed_l;
b32 consumed_r;
b32 has_max_y_suggestion;
i32 max_y;
};
enum{
FileCreateFlag_ReadOnly = 1,
};
enum History_Mode{
hist_normal,
hist_backward,
hist_forward
};
enum Try_Kill_Result{
TryKill_CannotKill,
TryKill_NeedDialogue,
TryKill_Success
};
#endif
// BOTTOM

View File

@ -98,9 +98,8 @@ working_set_alloc(Working_Set *working_set){
dll_remove(node); dll_remove(node);
Buffer_Slot_ID id = result->id; Buffer_Slot_ID id = result->id;
*result = null_editing_file; memset(result, 0, sizeof(*result));
result->id = id; result->id = id;
//result->unique_buffer_id = ++working_set->unique_file_counter;
dll_insert(&working_set->used_sentinel, node); dll_insert(&working_set->used_sentinel, node);
result->settings.display_width = working_set->default_display_width; result->settings.display_width = working_set->default_display_width;
result->settings.minimum_base_display_width = working_set->default_minimum_base_display_width; result->settings.minimum_base_display_width = working_set->default_minimum_base_display_width;
@ -305,41 +304,39 @@ internal Editing_File*
working_set_lookup_file(Working_Set *working_set, String string){ working_set_lookup_file(Working_Set *working_set, String string){
Editing_File *file = 0; Editing_File *file = 0;
{ // TODO(allen): use the name table for this
// TODO(allen): use the name table for this for (File_Node *node = working_set->used_sentinel.next;
File_Node *node, *used_nodes; node != &working_set->used_sentinel;
used_nodes = &working_set->used_sentinel; node = node->next){
for (dll_items(node, used_nodes)){ Editing_File *nfile = (Editing_File*)node;
file = (Editing_File*)node; if (string.size == 0 || match_ss(string, nfile->unique_name.name)){
if (string.size == 0 || match_ss(string, file->unique_name.name)){ file = nfile;
break;
}
}
if (file == 0){
for (File_Node *node = working_set->used_sentinel.next;
node = &working_set->used_sentinel;
node = node->next){
Editing_File *nfile = (Editing_File*)node;
if (string.size == 0 || has_substr_s(nfile->unique_name.name, string)){
file = nfile;
break; break;
} }
} }
if (node == used_nodes) file = 0;
} }
if (!file){ return(file);
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 || has_substr_s(file->unique_name.name, string)){
break;
}
}
if (node == used_nodes) file = 0;
}
return (file);
} }
internal void internal void
touch_file(Working_Set *working_set, Editing_File *file){ touch_file(Working_Set *working_set, Editing_File *file){
if (file){ TentativeAssert(file != 0);
Assert(!file->is_dummy); Assert(!file->is_dummy);
dll_remove(&file->node); dll_remove(&file->node);
dll_insert(&working_set->used_sentinel, &file->node); dll_insert(&working_set->used_sentinel, &file->node);
}
} }

View File

@ -26,9 +26,7 @@ cl %opts% %inc% %code%\meta\4ed_test_builder.cpp /Zi /Fe%name%
popd popd
pushd %data% pushd %data%
%full_name% %scripts%\test_full_click.4is %full_name% %scripts%\*.4is
%full_name% %scripts%\test_write_4coder_awesomeness.4is
%full_name% %scripts%\test_bootstrap.4is
%full_name% %scripts%\generated\*.4is %full_name% %scripts%\generated\*.4is
popd popd

View File

@ -22,6 +22,4 @@ pushd %build%
cl %opts% %inc% %code%\meta\4ed_test_generator.cpp /Zi /Fe%name% cl %opts% %inc% %code%\meta\4ed_test_generator.cpp /Zi /Fe%name%
popd popd
pushd %scripts% %full_name% %code%
%full_name%
popd

View File

@ -583,8 +583,8 @@ internal void
standard_build(char *cdir, u32 flags, u32 arch){ standard_build(char *cdir, u32 flags, u32 arch){
fsm_generator(cdir); fsm_generator(cdir);
metagen(cdir); metagen(cdir);
//do_buildsuper(cdir, fm_str(custom_files[Custom_Default]), arch); do_buildsuper(cdir, fm_str(custom_files[Custom_Default]), arch);
do_buildsuper(cdir, fm_str(custom_files[Custom_Experiments]), arch); //do_buildsuper(cdir, fm_str(custom_files[Custom_Experiments]), arch);
//do_buildsuper(cdir, fm_str(custom_files[Custom_Casey]), arch); //do_buildsuper(cdir, fm_str(custom_files[Custom_Casey]), arch);
//do_buildsuper(cdir, fm_str(custom_files[Custom_ChronalVim]), arch); //do_buildsuper(cdir, fm_str(custom_files[Custom_ChronalVim]), arch);
build_main(cdir, true, flags, arch); build_main(cdir, true, flags, arch);

View File

@ -14,9 +14,6 @@
#define API_H "4coder_generated/app_functions.h" #define API_H "4coder_generated/app_functions.h"
#define REMAPPING_FILE "4coder_generated/remapping.h" #define REMAPPING_FILE "4coder_generated/remapping.h"
#define OS_API_H "4ed_os_custom_api.h"
#include "../4ed_defines.h" #include "../4ed_defines.h"
#include "4ed_meta_defines.h" #include "4ed_meta_defines.h"
#include "../4coder_API/version.h" #include "../4coder_API/version.h"
@ -187,7 +184,7 @@ generate_style(){
Temp temp = fm_begin_temp(); Temp temp = fm_begin_temp();
char filename_4coder[] = STYLE_FILE; char filename_4coder[] = STYLE_FILE;
char filename_4ed[] = "4ed_style.h"; char filename_4ed[] = "4ed_generated_style.h";
String out = str_alloc(10 << 20);; String out = str_alloc(10 << 20);;
@ -354,31 +351,6 @@ generate_custom_headers(){
String out = str_alloc(10 << 20); String out = str_alloc(10 << 20);
// NOTE(allen): Custom API headers // NOTE(allen): Custom API headers
i32 main_api_count = unit_custom.parse[0].item_count;
i32 os_api_count = unit_custom.parse[1].item_count;
append(&out, "struct Application_Links;\n");
for (i32 i = main_api_count; i < os_api_count; ++i){
append(&out, "#define ");
append(&out, func_4ed_names.names[i].macro);
append(&out, "(n) ");
append(&out, unit_custom.set.items[i].ret);
append(&out, " n");
append(&out, unit_custom.set.items[i].args);
append_s_char(&out, '\n');
}
for (i32 i = main_api_count; i < os_api_count; ++i){
append(&out, "typedef ");
append(&out, func_4ed_names.names[i].macro);
append_s_char(&out, '(');
append(&out, unit_custom.set.items[i].name);
append(&out, "_Function);\n");
}
fm_write_file(OS_API_H, out.str, out.size);
out.size = 0;
append(&out, "struct Application_Links;\n"); append(&out, "struct Application_Links;\n");
for (i32 i = 0; i < unit_custom.set.count; ++i){ for (i32 i = 0; i < unit_custom.set.count; ++i){
@ -401,7 +373,6 @@ generate_custom_headers(){
append(&out, "struct Application_Links{\n"); append(&out, "struct Application_Links{\n");
append(&out, "#if defined(ALLOW_DEP_4CODER)\n"); append(&out, "#if defined(ALLOW_DEP_4CODER)\n");
for (i32 i = 0; i < unit_custom.set.count; ++i){ for (i32 i = 0; i < unit_custom.set.count; ++i){
append(&out, unit_custom.set.items[i].name); append(&out, unit_custom.set.items[i].name);
@ -731,7 +702,7 @@ generate_remapping_code_and_data(){
bind(mappings, 'x', MDFR_ALT, execute_arbitrary_command); bind(mappings, 'x', MDFR_ALT, execute_arbitrary_command);
bind(mappings, 's', MDFR_ALT, show_scrollbar); bind(mappings, 'W', MDFR_ALT, show_scrollbar);
bind(mappings, 'w', MDFR_ALT, hide_scrollbar); bind(mappings, 'w', MDFR_ALT, hide_scrollbar);
bind(mappings, 'b', MDFR_ALT, toggle_filebar); bind(mappings, 'b', MDFR_ALT, toggle_filebar);
@ -824,6 +795,7 @@ generate_remapping_code_and_data(){
bind(mappings, 'q', MDFR_ALT , query_replace_selection); bind(mappings, 'q', MDFR_ALT , query_replace_selection);
bind(mappings, 'r', MDFR_CTRL, reverse_search); bind(mappings, 'r', MDFR_CTRL, reverse_search);
bind(mappings, 's', MDFR_CTRL, save); bind(mappings, 's', MDFR_CTRL, save);
bind(mappings, 's', MDFR_ALT , save_to_query);
bind(mappings, 't', MDFR_CTRL, search_identifier); bind(mappings, 't', MDFR_CTRL, search_identifier);
bind(mappings, 'T', MDFR_CTRL, list_all_locations_of_identifier); bind(mappings, 'T', MDFR_CTRL, list_all_locations_of_identifier);
bind(mappings, 'u', MDFR_CTRL, to_uppercase); bind(mappings, 'u', MDFR_CTRL, to_uppercase);
@ -930,7 +902,7 @@ generate_remapping_code_and_data(){
bind(mappings, 'x', MDFR_CTRL, execute_arbitrary_command); bind(mappings, 'x', MDFR_CTRL, execute_arbitrary_command);
bind(mappings, 's', MDFR_CTRL, show_scrollbar); bind(mappings, 'W', MDFR_CTRL, show_scrollbar);
bind(mappings, 'w', MDFR_CTRL, hide_scrollbar); bind(mappings, 'w', MDFR_CTRL, hide_scrollbar);
bind(mappings, 'b', MDFR_CTRL, toggle_filebar); bind(mappings, 'b', MDFR_CTRL, toggle_filebar);
@ -1020,6 +992,7 @@ generate_remapping_code_and_data(){
bind(mappings, 'Q', MDFR_CMND, query_replace_identifier); bind(mappings, 'Q', MDFR_CMND, query_replace_identifier);
bind(mappings, 'r', MDFR_CMND, reverse_search); bind(mappings, 'r', MDFR_CMND, reverse_search);
bind(mappings, 's', MDFR_CMND, save); bind(mappings, 's', MDFR_CMND, save);
bind(mappings, 's', MDFR_CTRL, save_to_query);
bind(mappings, 't', MDFR_CMND, search_identifier); bind(mappings, 't', MDFR_CMND, search_identifier);
bind(mappings, 'T', MDFR_CMND, list_all_locations_of_identifier); bind(mappings, 'T', MDFR_CMND, list_all_locations_of_identifier);
bind(mappings, 'u', MDFR_CMND, to_uppercase); bind(mappings, 'u', MDFR_CMND, to_uppercase);

View File

@ -223,6 +223,32 @@ require_unquoted_string(Line_Parse_Context context, i32 index, String *str_out){
return(result); return(result);
} }
internal bool32
require_unquoted_multi_string(Line_Parse_Context context, i32 start_index, String *str_out){
bool32 result = false;
if (start_index < context.words.count){
String str = context.words.strings[start_index];
if (str.str[0] != '"'){
String last_word = context.words.strings[context.words.count - 1];
char *end = last_word.str + last_word.size;
str.size = (i32)(end - str.str);
*str_out = str;
result = true;
}
else{
show_error(context,
context.words.strings[context.words.count - 1].str,
"expected a simple word (a simple word must be unquoted)");
}
}
else{
show_error(context,
context.words.strings[context.words.count - 1].str,
"expected another word");
}
return(result);
}
internal bool32 internal bool32
require_any_string(Line_Parse_Context context, i32 index, String *str_out){ require_any_string(Line_Parse_Context context, i32 index, String *str_out){
bool32 result = require_unquoted_string(context, index, str_out); bool32 result = require_unquoted_string(context, index, str_out);
@ -323,6 +349,7 @@ process_script__inner(Partition *scratch, char *name){
Simulation_Event *events = push_array(scratch, Simulation_Event, 0); Simulation_Event *events = push_array(scratch, Simulation_Event, 0);
i32 event_count = 0; i32 event_count = 0;
i32 standard_time_increment = 0;
i32 time_counter = 0; i32 time_counter = 0;
for (i32 i = 0; i < lines.count; ++i){ for (i32 i = 0; i < lines.count; ++i){
@ -378,6 +405,17 @@ process_script__inner(Partition *scratch, char *name){
} }
} }
else if (match(first_word, "basewait")){
i32 increment = 0;
if (require_integer(context, 1, &increment) &&
require_blank(context, 2)){
standard_time_increment = increment;
}
else{
return;
}
}
else if (match(first_word, "key")){ else if (match(first_word, "key")){
String key_name = {0}; String key_name = {0};
String mod_name = {0}; String mod_name = {0};
@ -407,8 +445,7 @@ process_script__inner(Partition *scratch, char *name){
i32 increment = 0; i32 increment = 0;
String string = {0}; String string = {0};
if (require_integer(context, 1, &increment) && if (require_integer(context, 1, &increment) &&
require_unquoted_string(context, 2, &string) && require_unquoted_multi_string(context, 2, &string)){
require_blank(context, 3)){
emit_type = true; emit_type = true;
type_increment = increment; type_increment = increment;
type_string = string; type_string = string;
@ -543,6 +580,7 @@ process_script__inner(Partition *scratch, char *name){
memset(new_event, 0, sizeof(*new_event)); memset(new_event, 0, sizeof(*new_event));
*new_event = event; *new_event = event;
event_count += 1; event_count += 1;
time_counter += standard_time_increment;
} }
if (emit_type){ if (emit_type){
@ -554,8 +592,11 @@ process_script__inner(Partition *scratch, char *name){
new_event->key.code = type_string.str[j]; new_event->key.code = type_string.str[j];
new_event->key.modifiers = MDFR_NONE; new_event->key.modifiers = MDFR_NONE;
event_count += 1; event_count += 1;
time_counter += type_increment; if (j + 1 < type_string.size){
time_counter += type_increment;
}
} }
time_counter += standard_time_increment;
} }
if (emit_invoke){ if (emit_invoke){
@ -584,7 +625,7 @@ process_script__inner(Partition *scratch, char *name){
} }
} }
if (count > 0){ if (count > 0){
time_counter = events[count - 1].counter_index; time_counter = events[count - 1].counter_index + standard_time_increment;
} }
end_temp_memory(invoke_temp); end_temp_memory(invoke_temp);

View File

@ -11,19 +11,143 @@
#include "4ed_defines.h" #include "4ed_defines.h"
#include "4coder_lib/4coder_string.h" #include "4coder_lib/4coder_string.h"
#include "4coder_lib/4coder_mem.h"
#include "4coder_file.h" #include "4coder_file.h"
#include <stdio.h> #include <stdio.h>
////////////////////////////////
global char hot_directory_space[4096];
global String hot_directory = {hot_directory_space, 0, sizeof(hot_directory_space)};
internal void internal void
print_usage(char *name){ init_hot_directory(char *dir){
fprintf(stdout, "usage: %s\n", name); copy(&hot_directory, dir);
replace_char(&hot_directory, '\\', '/');
if (hot_directory.str[hot_directory.size - 1] != '/'){
append(&hot_directory, "/");
}
}
internal void
set_hot_directory(String str){
copy(&hot_directory, str);
}
internal void
set_hot_directory(char *str){
copy(&hot_directory, str);
}
internal void
push_folder_hot_directory(String str){
append(&hot_directory, str);
append(&hot_directory, "/");
}
internal void
push_folder_hot_directory(char *str){
append(&hot_directory, str);
append(&hot_directory, "/");
}
internal void
pop_folder_hot_directory(void){
remove_last_folder(&hot_directory);
}
internal String
get_hot_directory(Partition *part){
String hot;
hot.str = push_array(part, char, hot_directory.size);
hot.size = hot_directory.size;
hot.memory_size = hot_directory.size;
memcpy(hot.str, hot_directory.str, hot_directory.size);
return(hot);
} }
internal FILE* internal FILE*
try_open_output(char *name){ fopen_hot_directory(Partition *scratch, char *file_name, char *flags){
FILE *out = fopen(name, "wb"); Temp_Memory temp = begin_temp_memory(scratch);
char *full_name = push_array(scratch, char, hot_directory.size);
memcpy(full_name, hot_directory.str, hot_directory.size);
i32 file_name_length = str_size(file_name);
char *full_name_file_portion = push_array(scratch, char, file_name_length);
memcpy(full_name_file_portion, file_name, file_name_length);
char *terminator = push_array(scratch, char, 1);
*terminator = 0;
FILE *result = fopen(full_name, flags);
end_temp_memory(temp);
return(result);
}
////////////////////////////////
struct Test_Node{
Test_Node *next;
String name;
};
struct Test_List{
Partition *part;
Test_Node *first;
Test_Node *last;
i32 count;
};
#define zdll_push(f,l,cptr,n) (((f) == 0)?((f) = (l) = (n)):((l)->next = (n), (l) = (n))), (*(cptr)) += 1
internal void
push_test(Test_List *list, String name){
Test_Node *node = push_array(list->part, Test_Node, 1);
node->name = make_string_cap(push_array(list->part, char, name.size), 0, name.size);
push_align(list->part, 8);
copy(&node->name, name);
zdll_push(list->first, list->last, &list->count, node);
}
internal void
push_test(Test_List *list, char *name){
push_test(list, make_string_slowly(name));
}
////////////////////////////////
global String code_root;
global String script_root;
global String sample_root;
typedef u32 Generate_Flag;
enum{
GenFlag_RebuildSamples = 1,
GenFlag_RebuildScripts = 2,
GenFlag_OutputTestNames = 4,
};
enum{
GenFlag_DoAll = GenFlag_RebuildSamples|GenFlag_RebuildScripts|GenFlag_OutputTestNames,
};
#define DoSamples(f) (((f) & GenFlag_RebuildSamples) != 0)
#define DoScripts(f) (((f) & GenFlag_RebuildScripts) != 0)
#define DoTestNames(f) (((f) & GenFlag_OutputTestNames) != 0)
internal void
print_usage(char *name){
fprintf(stdout, "usage: %s code-root-directory\n", name);
}
internal FILE*
try_open_output(Partition *scratch, char *name){
FILE *out = fopen_hot_directory(scratch, name, "wb");
if (out == 0){ if (out == 0){
fprintf(stdout, "Could not open output file %s\n", name); fprintf(stdout, "Could not open output file %s\n", name);
} }
@ -31,99 +155,299 @@ try_open_output(char *name){
} }
internal void internal void
write_open_test_file_default_bindings(FILE *out, generate_run_script(Partition *scratch, Test_List list){
char *src_name, char *dst_name){ Temp_Memory temp = begin_temp_memory(scratch);
fprintf(out,
"wait 1\n" set_hot_directory(code_root);
"key o MDFR_CTRL\n" FILE *out = try_open_output(scratch, "run_regression_tests.bat");
"wait 1\n" if (out != 0){
"type 1 %s\n" fprintf(out,
"wait 1\n" "@echo off\n"
"key key_newline MDFR_NONE\n"
"wait 1\n" "pushd ..\\4coder-non-source\\test_data\n"
"key key_space MDFR_CTRL\n" "set run_path=%%cd%%\\sample_files\n"
"wait 1\n" "set data_path=%%cd%%\\input_data\n"
"key key_page_down MDFR_CTRL\n" "popd\n"
"wait 1\n"
"key c MDFR_CTRL\n" "pushd ..\\build\n"
"wait 1\n" "set build=%%cd%%\n"
"key K MDFR_CTRL\n" "popd\n"
"wait 1\n"
"key o MDFR_CTRL\n" "pushd %%run_path%%\n");
"wait 1\n"
"key key_back MDFR_NONE\n" for (Test_Node *node = list.first;
"wait 1\n" node != 0;
"type 1 output/%s\n" node = node->next){
"wait 1\n" fprintf(out, "%%build%%\\4ed -T %%data_path%%\\%.*s\n",
"key key_newline MDFR_NONE\n" node->name.size, node->name.str);
"wait 1\n" }
"key key_space MDFR_CTRL\n"
"wait 1\n" fprintf(out, "popd\n");
"key key_page_down MDFR_CTRL\n" fclose(out);
"wait 1\n" }
"key d MDFR_CTRL\n"
"wait 1\n" end_temp_memory(temp);
"key v MDFR_CTRL\n"
"wait 1\n"
"key m MDFR_CTRL\n"
"wait 1\n"
"key key_space MDFR_CTRL\n",
src_name, dst_name);
} }
internal void internal void
generate_capacity_stresser_1(void){ write_open_test_file_default_bindings(FILE *out,
FILE *out = try_open_output("gentest_capstress1.4is"); char *src_name, char *dst_name){
if (out == 0){
return;
}
fprintf(out, "mouse_xy 20 20\n");
write_open_test_file_default_bindings(out,
"small.cpp", "small.cpp");
fprintf(out, fprintf(out,
"wait 1\n" "key o MDFR_CTRL\n"
"key g MDFR_CTRL\n" "type 1 %s\n"
"wait 1\n" "key key_newline MDFR_NONE\n"
"key 6 MDFR_NONE\n" "key o MDFR_CTRL\n"
"wait 1\n" "key key_back MDFR_NONE\n"
"key key_newline MDFR_NONE\n"); "type 1 output/\n"
"key key_esc MDFR_NONE\n"
"key s MDFR_ALT\n"
"type 1 %s\n"
"key key_newline MDFR_NONE\n",
src_name, dst_name);
}
for (i32 i = 0; i < 20; ++i){ internal String
fprintf(out, generate_token_test_sample_file(Partition *part, i32 index, i32 token_target, Generate_Flag flags){
"wait 1\n" i32 name_cap = 512;
"type 1 int\n" String sample_name = make_string_cap(push_array(part, char, name_cap), 0, name_cap);
"wait 1\n" append(&sample_name, "gentokentest");
"key key_space MDFR_NONE\n" append_int_to_str(&sample_name, index + 1);
"wait 1\n" append(&sample_name, ".cpp");
"type 1 foo%d\n" bool32 string_build_success = terminate_with_null(&sample_name);
"wait 1\n" Assert(string_build_success);
"key key_space MDFR_NONE\n"
"wait 1\n" set_hot_directory(sample_root);
"key = MDFR_NONE\n" if (DoSamples(flags)){
"wait 1\n" FILE *out = try_open_output(part, sample_name.str);
"key key_space MDFR_NONE\n" if (out != 0){
"wait 1\n" fprintf(out,
"type 1 %d;\n" "int foo(){\n"
"wait 1\n" "\n");
"key key_newline MDFR_NONE\n", i32 token_count = 6;
i, i); Assert(token_count < token_target);
for (;token_count + 10 < token_target;){
fprintf(out, "int x = 0;\n");
token_count += 5;
}
Assert(token_count < token_target);
fprintf(out, "}\n");
fclose(out);
}
else{
sample_name.str = 0;
sample_name.size = 0;
sample_name.memory_size = 0;
}
} }
fprintf(out, "exit\n"); return(sample_name);
}
fclose(out); internal void
generate_token_tests(Partition *scratch, Test_List *test_list, Generate_Flag flags){
Temp_Memory temp = begin_temp_memory(scratch);
for (i32 size = 1024, i = 0; i < 5; size <<= 1, ++i){
char test_name_space[512];
String test_name = make_fixed_width_string(test_name_space);
append(&test_name, "gentest_capstress");
append_int_to_str(&test_name, i + 1);
append(&test_name, ".4is");
bool32 string_build_success = terminate_with_null(&test_name);
Assert(string_build_success);
String sample_name = generate_token_test_sample_file(scratch, i, size, flags);
if (sample_name.str != 0){
set_hot_directory(script_root);
if (DoScripts(flags)){
FILE *out = try_open_output(scratch, test_name.str);
if (out != 0){
fprintf(out,
"mouse_xy 20 20\n"
"key P MDFR_CTRL\n"
"basewait 1\n");
write_open_test_file_default_bindings(out, sample_name.str, sample_name.str);
fprintf(out, "key key_down MDFR_CTRL\n");
for (i32 i = 0; i < 5; ++i){
fprintf(out,
"type 1 int x = 0;\n"
"key key_newline MDFR_NONE\n");
}
fprintf(out,
"key s MDFR_CTRL\n"
"exit\n"
"key Y MDFR_NONE");
fclose(out);
}
}
if (DoTestNames(flags)){
remove_extension(&test_name);
append(&test_name, "4id");
bool32 string_build_success = terminate_with_null(&test_name);
Assert(string_build_success);
push_test(test_list, test_name);
}
}
}
end_temp_memory(temp);
}
internal String
generate_dupline_test_sample_file(Partition *part, i32 line_count, bool32 always_newline, Generate_Flag flags){
i32 name_cap = 512;
String sample_name = make_string_cap(push_array(part, char, name_cap), 0, name_cap);
append(&sample_name, "genduplinetest");
append_int_to_str(&sample_name, line_count);
append(&sample_name, "_");
append_int_to_str(&sample_name, always_newline);
append(&sample_name, ".cpp");
bool32 string_build_success = terminate_with_null(&sample_name);
Assert(string_build_success);
if (DoSamples(flags)){
set_hot_directory(sample_root);
FILE *out = try_open_output(part, sample_name.str);
if (out != 0){
for (i32 i = 0; i < line_count; ++i){
fprintf(out, "abcd");
if (i + 1 < line_count || always_newline){
fprintf(out, "\n");
}
}
fclose(out);
}
}
return(sample_name);
}
internal void
generate_dupline_specific_test(Partition *scratch, Test_List *test_list, Generate_Flag flags,
i32 line_count, bool32 always_newline, bool32 read_only){
char test_name_space[512];
String test_name = make_fixed_width_string(test_name_space);
if (read_only){
append(&test_name, "gentest_dupline_readonly.4is");
}
else{
append(&test_name, "gentest_dupline");
append_int_to_str(&test_name, line_count);
append(&test_name, "_");
append_int_to_str(&test_name, always_newline);
append(&test_name, ".4is");
}
bool32 string_build_success = terminate_with_null(&test_name);
Assert(string_build_success);
String sample_name;
if (read_only){
sample_name = make_lit_string("*messages*");
}
else{
sample_name = generate_dupline_test_sample_file(scratch, line_count, always_newline, flags);
}
if (sample_name.str != 0){
set_hot_directory(script_root);
if (DoScripts(flags)){
FILE *out = try_open_output(scratch, test_name.str);
if (out != 0){
fprintf(out,
"mouse_xy 20 20\n"
"key P MDFR_CTRL\n"
"basewait 1\n");
if (read_only){
fprintf(out,
"key i MDFR_CTRL\n"
"type 1 *messages*\n"
"key key_newline MDFR_NONE\n"
"key L MDFR_CTRL\n"
"key s MDFR_CTRL\n"
"exit\n");
}
else{
write_open_test_file_default_bindings(out, sample_name.str, sample_name.str);
fprintf(out,
"key L MDFR_CTRL\n"
"key s MDFR_CTRL\n"
"exit\n");
}
fclose(out);
}
}
if (DoTestNames(flags)){
remove_extension(&test_name);
append(&test_name, "4id");
bool32 string_build_success = terminate_with_null(&test_name);
Assert(string_build_success);
push_test(test_list, test_name);
}
}
}
internal void
generate_dupline_tests(Partition *scratch, Test_List *test_list, Generate_Flag flags){
Temp_Memory temp = begin_temp_memory(scratch);
for (i32 line_count = 0; line_count < 2; ++line_count){
for (bool32 always_newline = 0; always_newline <= 1; ++always_newline){
generate_dupline_specific_test(scratch, test_list, flags,
line_count, always_newline, false);
}
}
generate_dupline_specific_test(scratch, test_list, flags, 0, false, true);
end_temp_memory(temp);
} }
int int
main(int argc, char **argv){ main(int argc, char **argv){
if (argc > 1){ if (argc != 2){
print_usage(argv[0]); print_usage(argv[0]);
exit(1); exit(1);
} }
generate_capacity_stresser_1(); // NOTE(allen): Init the hot directory
init_hot_directory(argv[1]);
// NOTE(allen): Init the partition
i32 memory_size = MB(8);
Partition part_ = make_part(malloc(memory_size), memory_size);
Partition *part = &part_;
// NOTE(allen): Get various root paths
code_root = get_hot_directory(part);
push_folder_hot_directory("test_input_scripts/generated");
script_root = get_hot_directory(part);
set_hot_directory(code_root);
pop_folder_hot_directory();
push_folder_hot_directory("4coder-non-source/test_data/sample_files");
sample_root = get_hot_directory(part);
// NOTE(allen): Setup the test list
i32 test_list_size = MB(8);
Partition test_list_part = make_part(malloc(test_list_size), test_list_size);
Test_List test_list = {0};
test_list.part = &test_list_part;
// NOTE(allen): Tests
push_test(&test_list, "test_load_FONT_COURIER_NEW_28_c.4id");
generate_token_tests(part, &test_list, GenFlag_DoAll);
//generate_token_tests(part, &test_list, GenFlag_OutputTestNames);
generate_dupline_tests(part, &test_list, GenFlag_DoAll);
//generate_dupline_tests(part, &test_list, GenFlag_OutputTestNames);
// NOTE(allen): Generate the run test script
generate_run_script(part, test_list);
return(0); return(0);
} }

View File

@ -28,7 +28,6 @@
# include "4coder_lib/4coder_mem.h" # include "4coder_lib/4coder_mem.h"
# include "4coder_API/types.h" # include "4coder_API/types.h"
# include "4ed_os_custom_api.h"
#else #else
# include "4coder_default_bindings.cpp" # include "4coder_default_bindings.cpp"

View File

@ -25,7 +25,6 @@
# include "4coder_lib/4coder_mem.h" # include "4coder_lib/4coder_mem.h"
# include "4coder_API/types.h" # include "4coder_API/types.h"
# include "4ed_os_custom_api.h"
#else #else
# include "4coder_default_bindings.cpp" # include "4coder_default_bindings.cpp"

View File

@ -36,7 +36,6 @@
# include "4coder_lib/4coder_mem.h" # include "4coder_lib/4coder_mem.h"
# include "4coder_API/types.h" # include "4coder_API/types.h"
# include "4ed_os_custom_api.h"
#else #else
# include "4coder_default_bindings.cpp" # include "4coder_default_bindings.cpp"

View File

@ -6,11 +6,15 @@ fkey_command_win[2] = {"build_site.bat" , "*site*" , false,
fkey_command_win[3] = {"build_string.bat" , "*compilation*" , true , true }; fkey_command_win[3] = {"build_string.bat" , "*compilation*" , true , true };
fkey_command_win[4] = {"echo build: x86 & build.bat /DDEV_BUILD_X86" , "*compilation*", true, true }; fkey_command_win[4] = {"echo build: x86 & build.bat /DDEV_BUILD_X86" , "*compilation*", true, true };
fkey_command_win[5] = {"build_metadata.bat" , "*compilation*" , true , true }; fkey_command_win[5] = {"build_metadata.bat" , "*compilation*" , true , true };
fkey_command_win[6] = {"run_regression_tests.bat" , "*test*" , false, false}; fkey_command_win[6] = {"run_regression_tests.bat" , "*test*" , false, true };
fkey_command_win[7] = {"build_tests.bat" , "*compilation*" , true , true }; fkey_command_win[7] = {"build_tests.bat" , "*compilation*" , true , true };
fkey_command_win[8] = {"generate_tests.bat" , "*compilation*" , true , true }; fkey_command_win[8] = {"generate_tests.bat" , "*compilation*" , true , true };
fkey_command_win[12] = {"package.bat" , "*package*" , false, true }; fkey_command_win[12] = {"package.bat" , "*package*" , false, true };
fkey_command_win[1] = {"build_tests.bat" , "*compilation*" , true , true };
fkey_command_win[2] = {"generate_tests.bat" , "*compilation*" , true , true };
fkey_command_win[3] = {"run_regression_tests.bat" , "*test*" , false, true };
fkey_command_linux[1] = {"echo build: x64 & ./build.sh", "*compilation*" , true , true }; fkey_command_linux[1] = {"echo build: x64 & ./build.sh", "*compilation*" , true , true };
fkey_command_linux[2] = {"build_site.sh" , "*site*" , false, true }; fkey_command_linux[2] = {"build_site.sh" , "*site*" , false, true };
fkey_command_linux[3] = {"build_string.sh" , "*compilation*" , true , true }; fkey_command_linux[3] = {"build_string.sh" , "*compilation*" , true , true };

View File

@ -1,16 +1,21 @@
@echo off @echo off
pushd ..\4coder-non-source\test_data pushd ..\4coder-non-source\test_data
set run_path=%cd%\sample_files set run_path=%cd%\sample_files
set data_path=%cd%\input_data set data_path=%cd%\input_data
popd popd
pushd ..\build pushd ..\build
set build=%cd% set build=%cd%
popd popd
pushd %run_path% pushd %run_path%
rem %build%\4ed -T %data_path%\test_bootstrap.4id %build%\4ed -T %data_path%\test_load_FONT_COURIER_NEW_28_c.4id
%build%\4ed -T %data_path%\gentest_capstress1.4id %build%\4ed -T %data_path%\gentest_capstress1.4id
%build%\4ed -T %data_path%\gentest_capstress2.4id
%build%\4ed -T %data_path%\gentest_capstress3.4id
%build%\4ed -T %data_path%\gentest_capstress4.4id
%build%\4ed -T %data_path%\gentest_capstress5.4id
%build%\4ed -T %data_path%\gentest_dupline0_0.4id
%build%\4ed -T %data_path%\gentest_dupline0_1.4id
%build%\4ed -T %data_path%\gentest_dupline1_0.4id
%build%\4ed -T %data_path%\gentest_dupline1_1.4id
%build%\4ed -T %data_path%\gentest_dupline_readonly.4id
popd popd

View File

@ -5,7 +5,7 @@
If you cannot find what you are looking for please contact \STYLE{code} editor@4coder.net \END with questions. If you cannot find what you are looking for please contact \STYLE{code} editor@4coder.net \END with questions.
\LINK{!http://patreon.com/mr4thdimention} Support Development \END \LINK{!http://4coder.itch.io/4coder} Get Builds and Support Development \END
\LINK{document:features} Feature List \END \LINK{document:features} Feature List \END

View File

@ -1,41 +0,0 @@
mouse_xy 20 20
wait 45
debug_number 1
key _ MDFR_CTRL
wait 5
debug_number 2
invoke test_write_4coder_awesomeness.4id
wait 30
invoke test_full_click.4id
wait 10
mouse_left_press
wait 10
mouse_xy 50 20
mouse_left_release
wait 40
key key_back MDFR_CTRL
key key_end MDFR_NONE
wait 10
key o MDFR_CTRL
wait 10
type 5 unicode.txt
wait 25
key key_newline MDFR_NONE
wait 25
type 5 hello
key key_newline MDFR_NONE
wait 60
exit
wait 60
key Y MDFR_NONE

View File

@ -1,6 +0,0 @@
mouse_left_press
wait 2
mouse_left_release
exit

View File

@ -0,0 +1,6 @@
basewait 1
key o MDFR_CTRL
type 1 FONT_COURIER_NEW_28
key key_newline MDFR_NONE
exit

View File

@ -1,6 +0,0 @@
type 2 4coder
key key_tab MDFR_NONE
wait 2
type 2 awesomeness
exit