Mirror system up and running -- without highlights
This commit is contained in:
parent
5ddc8e2b86
commit
031d097be7
|
@ -25,6 +25,14 @@ lock_jump_buffer(Buffer_Summary buffer){
|
||||||
lock_jump_buffer(buffer.buffer_name, buffer.buffer_name_len);
|
lock_jump_buffer(buffer.buffer_name, buffer.buffer_name_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
lock_jump_buffer(Application_Links *app, Buffer_ID buffer_id){
|
||||||
|
Buffer_Summary buffer = {};
|
||||||
|
if (get_buffer_summary(app, buffer_id, AccessAll, &buffer)){
|
||||||
|
lock_jump_buffer(buffer.buffer_name, buffer.buffer_name_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static View_Summary
|
static View_Summary
|
||||||
get_view_for_locked_jump_buffer(Application_Links *app){
|
get_view_for_locked_jump_buffer(Application_Links *app){
|
||||||
View_Summary view = {};
|
View_Summary view = {};
|
||||||
|
|
|
@ -353,7 +353,7 @@ RENDER_CALLER_SIG(default_render_caller){
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE(allen): Token highlight setup
|
// NOTE(allen): Token highlight setup
|
||||||
bool32 do_token_highlight = true;
|
bool32 do_token_highlight = false;
|
||||||
if (do_token_highlight){
|
if (do_token_highlight){
|
||||||
Theme_Color color = {};
|
Theme_Color color = {};
|
||||||
color.tag = Stag_Cursor;
|
color.tag = Stag_Cursor;
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "4coder_ui_helper.h"
|
#include "4coder_ui_helper.h"
|
||||||
#include "4coder_helper.h"
|
#include "4coder_helper.h"
|
||||||
#include "4coder_default_framework.h"
|
#include "4coder_default_framework.h"
|
||||||
|
#include "4coder_mirror.h"
|
||||||
#include "4coder_config.h"
|
#include "4coder_config.h"
|
||||||
#include "4coder_seek.h"
|
#include "4coder_seek.h"
|
||||||
#include "4coder_auto_indent.h"
|
#include "4coder_auto_indent.h"
|
||||||
|
@ -49,6 +50,7 @@
|
||||||
#include "4coder_font_helper.cpp"
|
#include "4coder_font_helper.cpp"
|
||||||
#include "4coder_config.cpp"
|
#include "4coder_config.cpp"
|
||||||
#include "4coder_default_framework.cpp"
|
#include "4coder_default_framework.cpp"
|
||||||
|
#include "4coder_mirror.cpp"
|
||||||
#include "4coder_seek.cpp"
|
#include "4coder_seek.cpp"
|
||||||
#include "4coder_base_commands.cpp"
|
#include "4coder_base_commands.cpp"
|
||||||
#include "4coder_lists.cpp"
|
#include "4coder_lists.cpp"
|
||||||
|
|
|
@ -255,7 +255,7 @@ int32_t source_name_len;
|
||||||
int32_t line_number;
|
int32_t line_number;
|
||||||
};
|
};
|
||||||
static Command_Metadata fcoder_metacmd_table[234] = {
|
static Command_Metadata fcoder_metacmd_table[234] = {
|
||||||
{ PROC_LINKS(allow_mouse, 0), "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 242 },
|
{ PROC_LINKS(allow_mouse, 0), "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 250 },
|
||||||
{ PROC_LINKS(auto_tab_line_at_cursor, 0), "auto_tab_line_at_cursor", 23, "Auto-indents the line on which the cursor sits.", 47, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 721 },
|
{ PROC_LINKS(auto_tab_line_at_cursor, 0), "auto_tab_line_at_cursor", 23, "Auto-indents the line on which the cursor sits.", 47, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 721 },
|
||||||
{ PROC_LINKS(auto_tab_range, 0), "auto_tab_range", 14, "Auto-indents the range between the cursor and the mark.", 55, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 732 },
|
{ PROC_LINKS(auto_tab_range, 0), "auto_tab_range", 14, "Auto-indents the range between the cursor and the mark.", 55, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 732 },
|
||||||
{ PROC_LINKS(auto_tab_whole_file, 0), "auto_tab_whole_file", 19, "Audo-indents the entire current buffer.", 39, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 711 },
|
{ PROC_LINKS(auto_tab_whole_file, 0), "auto_tab_whole_file", 19, "Audo-indents the entire current buffer.", 39, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 711 },
|
||||||
|
@ -265,8 +265,8 @@ static Command_Metadata fcoder_metacmd_table[234] = {
|
||||||
{ PROC_LINKS(build_in_build_panel, 0), "build_in_build_panel", 20, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*. Puts the *compilation* buffer in a panel at the footer of the current view.", 230, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 187 },
|
{ PROC_LINKS(build_in_build_panel, 0), "build_in_build_panel", 20, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*. Puts the *compilation* buffer in a panel at the footer of the current view.", 230, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 187 },
|
||||||
{ PROC_LINKS(build_search, 0), "build_search", 12, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*.", 153, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 155 },
|
{ PROC_LINKS(build_search, 0), "build_search", 12, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*.", 153, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 155 },
|
||||||
{ PROC_LINKS(center_view, 0), "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 151 },
|
{ PROC_LINKS(center_view, 0), "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 151 },
|
||||||
{ PROC_LINKS(change_active_panel, 0), "change_active_panel", 19, "Change the currently active panel, moving to the panel with the next highest view_id.", 85, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 144 },
|
{ PROC_LINKS(change_active_panel, 0), "change_active_panel", 19, "Change the currently active panel, moving to the panel with the next highest view_id.", 85, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 152 },
|
||||||
{ PROC_LINKS(change_active_panel_backwards, 0), "change_active_panel_backwards", 29, "Change the currently active panel, moving to the panel with the next lowest view_id.", 84, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 154 },
|
{ PROC_LINKS(change_active_panel_backwards, 0), "change_active_panel_backwards", 29, "Change the currently active panel, moving to the panel with the next lowest view_id.", 84, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 162 },
|
||||||
{ PROC_LINKS(change_to_build_panel, 0), "change_to_build_panel", 21, "If the special build panel is open, makes the build panel the active panel.", 75, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 209 },
|
{ PROC_LINKS(change_to_build_panel, 0), "change_to_build_panel", 21, "If the special build panel is open, makes the build panel the active panel.", 75, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 209 },
|
||||||
{ PROC_LINKS(clean_all_lines, 0), "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 444 },
|
{ PROC_LINKS(clean_all_lines, 0), "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 444 },
|
||||||
{ PROC_LINKS(click_set_cursor, 0), "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 218 },
|
{ PROC_LINKS(click_set_cursor, 0), "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 218 },
|
||||||
|
@ -331,16 +331,16 @@ static Command_Metadata fcoder_metacmd_table[234] = {
|
||||||
{ PROC_LINKS(list_all_functions_all_buffers_lister, 0), "list_all_functions_all_buffers_lister", 37, "Creates a lister of locations that look like function definitions and declarations all buffers.", 95, "w:\\4ed\\code\\4coder_function_list.cpp", 36, 338 },
|
{ PROC_LINKS(list_all_functions_all_buffers_lister, 0), "list_all_functions_all_buffers_lister", 37, "Creates a lister of locations that look like function definitions and declarations all buffers.", 95, "w:\\4ed\\code\\4coder_function_list.cpp", 36, 338 },
|
||||||
{ 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, "w:\\4ed\\code\\4coder_function_list.cpp", 36, 309 },
|
{ 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, "w:\\4ed\\code\\4coder_function_list.cpp", 36, 309 },
|
||||||
{ PROC_LINKS(list_all_functions_current_buffer_lister, 0), "list_all_functions_current_buffer_lister", 40, "Creates a lister of locations that look like function definitions and declarations in the buffer.", 97, "w:\\4ed\\code\\4coder_function_list.cpp", 36, 319 },
|
{ PROC_LINKS(list_all_functions_current_buffer_lister, 0), "list_all_functions_current_buffer_lister", 40, "Creates a lister of locations that look like function definitions and declarations in the buffer.", 97, "w:\\4ed\\code\\4coder_function_list.cpp", 36, 319 },
|
||||||
{ PROC_LINKS(list_all_locations, 0), "list_all_locations", 18, "Queries the user for a string and lists all exact case-sensitive matches found in all open buffers.", 99, "w:\\4ed\\code\\4coder_search.cpp", 29, 780 },
|
{ PROC_LINKS(list_all_locations, 0), "list_all_locations", 18, "Queries the user for a string and lists all exact case-sensitive matches found in all open buffers.", 99, "w:\\4ed\\code\\4coder_search.cpp", 29, 866 },
|
||||||
{ PROC_LINKS(list_all_locations_case_insensitive, 0), "list_all_locations_case_insensitive", 35, "Queries the user for a string and lists all exact case-insensitive matches found in all open buffers.", 101, "w:\\4ed\\code\\4coder_search.cpp", 29, 794 },
|
{ PROC_LINKS(list_all_locations_case_insensitive, 0), "list_all_locations_case_insensitive", 35, "Queries the user for a string and lists all exact case-insensitive matches found in all open buffers.", 101, "w:\\4ed\\code\\4coder_search.cpp", 29, 880 },
|
||||||
{ PROC_LINKS(list_all_locations_of_identifier, 0), "list_all_locations_of_identifier", 32, "Reads a token or word under the cursor and lists all exact case-sensitive mathces in all open buffers.", 102, "w:\\4ed\\code\\4coder_search.cpp", 29, 808 },
|
{ PROC_LINKS(list_all_locations_of_identifier, 0), "list_all_locations_of_identifier", 32, "Reads a token or word under the cursor and lists all exact case-sensitive mathces in all open buffers.", 102, "w:\\4ed\\code\\4coder_search.cpp", 29, 894 },
|
||||||
{ PROC_LINKS(list_all_locations_of_identifier_case_insensitive, 0), "list_all_locations_of_identifier_case_insensitive", 49, "Reads a token or word under the cursor and lists all exact case-insensitive mathces in all open buffers.", 104, "w:\\4ed\\code\\4coder_search.cpp", 29, 815 },
|
{ PROC_LINKS(list_all_locations_of_identifier_case_insensitive, 0), "list_all_locations_of_identifier_case_insensitive", 49, "Reads a token or word under the cursor and lists all exact case-insensitive mathces in all open buffers.", 104, "w:\\4ed\\code\\4coder_search.cpp", 29, 901 },
|
||||||
{ PROC_LINKS(list_all_locations_of_selection, 0), "list_all_locations_of_selection", 31, "Reads the string in the selected range and lists all exact case-sensitive mathces in all open buffers.", 102, "w:\\4ed\\code\\4coder_search.cpp", 29, 822 },
|
{ PROC_LINKS(list_all_locations_of_selection, 0), "list_all_locations_of_selection", 31, "Reads the string in the selected range and lists all exact case-sensitive mathces in all open buffers.", 102, "w:\\4ed\\code\\4coder_search.cpp", 29, 908 },
|
||||||
{ PROC_LINKS(list_all_locations_of_selection_case_insensitive, 0), "list_all_locations_of_selection_case_insensitive", 48, "Reads the string in the selected range and lists all exact case-insensitive mathces in all open buffers.", 104, "w:\\4ed\\code\\4coder_search.cpp", 29, 829 },
|
{ PROC_LINKS(list_all_locations_of_selection_case_insensitive, 0), "list_all_locations_of_selection_case_insensitive", 48, "Reads the string in the selected range and lists all exact case-insensitive mathces in all open buffers.", 104, "w:\\4ed\\code\\4coder_search.cpp", 29, 915 },
|
||||||
{ PROC_LINKS(list_all_locations_of_type_definition, 0), "list_all_locations_of_type_definition", 37, "Queries user for string, lists all locations of strings that appear to define a type whose name matches the input string.", 121, "w:\\4ed\\code\\4coder_search.cpp", 29, 836 },
|
{ PROC_LINKS(list_all_locations_of_type_definition, 0), "list_all_locations_of_type_definition", 37, "Queries user for string, lists all locations of strings that appear to define a type whose name matches the input string.", 121, "w:\\4ed\\code\\4coder_search.cpp", 29, 922 },
|
||||||
{ PROC_LINKS(list_all_locations_of_type_definition_of_identifier, 0), "list_all_locations_of_type_definition_of_identifier", 51, "Reads a token or word under the cursor and lists all locations of strings that appear to define a type whose name matches it.", 125, "w:\\4ed\\code\\4coder_search.cpp", 29, 847 },
|
{ PROC_LINKS(list_all_locations_of_type_definition_of_identifier, 0), "list_all_locations_of_type_definition_of_identifier", 51, "Reads a token or word under the cursor and lists all locations of strings that appear to define a type whose name matches it.", 125, "w:\\4ed\\code\\4coder_search.cpp", 29, 933 },
|
||||||
{ 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, "w:\\4ed\\code\\4coder_search.cpp", 29, 787 },
|
{ 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, "w:\\4ed\\code\\4coder_search.cpp", 29, 873 },
|
||||||
{ 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, "w:\\4ed\\code\\4coder_search.cpp", 29, 801 },
|
{ 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, "w:\\4ed\\code\\4coder_search.cpp", 29, 887 },
|
||||||
{ PROC_LINKS(lister__activate, 0), "lister__activate", 16, "A lister mode command that activates the list's action on the highlighted item.", 79, "w:\\4ed\\code\\4coder_lists.cpp", 28, 15 },
|
{ PROC_LINKS(lister__activate, 0), "lister__activate", 16, "A lister mode command that activates the list's action on the highlighted item.", 79, "w:\\4ed\\code\\4coder_lists.cpp", 28, 15 },
|
||||||
{ PROC_LINKS(lister__backspace_text_field, 0), "lister__backspace_text_field", 28, "A lister mode command that dispatches to the lister's backspace text field handler.", 83, "w:\\4ed\\code\\4coder_lists.cpp", 28, 41 },
|
{ PROC_LINKS(lister__backspace_text_field, 0), "lister__backspace_text_field", 28, "A lister mode command that dispatches to the lister's backspace text field handler.", 83, "w:\\4ed\\code\\4coder_lists.cpp", 28, 41 },
|
||||||
{ PROC_LINKS(lister__backspace_text_field__default, 0), "lister__backspace_text_field__default", 37, "A lister mode command that backspaces one character from the text field.", 72, "w:\\4ed\\code\\4coder_lists.cpp", 28, 146 },
|
{ PROC_LINKS(lister__backspace_text_field__default, 0), "lister__backspace_text_field__default", 37, "A lister mode command that backspaces one character from the text field.", 72, "w:\\4ed\\code\\4coder_lists.cpp", 28, 146 },
|
||||||
|
@ -391,8 +391,8 @@ static Command_Metadata fcoder_metacmd_table[234] = {
|
||||||
{ PROC_LINKS(open_long_braces_break, 0), "open_long_braces_break", 22, "At the cursor, insert a '{' and '}break;' separated by a blank line.", 68, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 71 },
|
{ PROC_LINKS(open_long_braces_break, 0), "open_long_braces_break", 22, "At the cursor, insert a '{' and '}break;' separated by a blank line.", 68, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 71 },
|
||||||
{ PROC_LINKS(open_long_braces_semicolon, 0), "open_long_braces_semicolon", 26, "At the cursor, insert a '{' and '};' separated by a blank line.", 63, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 63 },
|
{ PROC_LINKS(open_long_braces_semicolon, 0), "open_long_braces_semicolon", 26, "At the cursor, insert a '{' and '};' separated by a blank line.", 63, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 63 },
|
||||||
{ PROC_LINKS(open_matching_file_cpp, 0), "open_matching_file_cpp", 22, "If the current file is a *.cpp or *.h, attempts to open the corresponding *.h or *.cpp file in the other view.", 110, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1535 },
|
{ PROC_LINKS(open_matching_file_cpp, 0), "open_matching_file_cpp", 22, "If the current file is a *.cpp or *.h, attempts to open the corresponding *.h or *.cpp file in the other view.", 110, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1535 },
|
||||||
{ PROC_LINKS(open_panel_hsplit, 0), "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 173 },
|
{ PROC_LINKS(open_panel_hsplit, 0), "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 181 },
|
||||||
{ PROC_LINKS(open_panel_vsplit, 0), "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 164 },
|
{ PROC_LINKS(open_panel_vsplit, 0), "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 172 },
|
||||||
{ PROC_LINKS(page_down, 0), "page_down", 9, "Scrolls the view down one view height and moves the cursor down one view height.", 80, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 361 },
|
{ PROC_LINKS(page_down, 0), "page_down", 9, "Scrolls the view down one view height and moves the cursor down one view height.", 80, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 361 },
|
||||||
{ PROC_LINKS(page_up, 0), "page_up", 7, "Scrolls the view up one view height and moves the cursor up one view height.", 76, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 352 },
|
{ PROC_LINKS(page_up, 0), "page_up", 7, "Scrolls the view up one view height and moves the cursor up one view height.", 76, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 352 },
|
||||||
{ PROC_LINKS(paste, 0), "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "w:\\4ed\\code\\4coder_clipboard.cpp", 32, 46 },
|
{ PROC_LINKS(paste, 0), "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "w:\\4ed\\code\\4coder_clipboard.cpp", 32, 46 },
|
||||||
|
@ -409,7 +409,7 @@ static Command_Metadata fcoder_metacmd_table[234] = {
|
||||||
{ PROC_LINKS(redo, 0), "redo", 4, "Advances forward through the undo history in the buffer containing the most recent regular edit.", 96, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1715 },
|
{ PROC_LINKS(redo, 0), "redo", 4, "Advances forward through the undo history in the buffer containing the most recent regular edit.", 96, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1715 },
|
||||||
{ PROC_LINKS(redo_this_buffer, 0), "redo_this_buffer", 16, "Advances forwards through the undo history of the current buffer.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1629 },
|
{ PROC_LINKS(redo_this_buffer, 0), "redo_this_buffer", 16, "Advances forwards through the undo history of the current buffer.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1629 },
|
||||||
{ PROC_LINKS(reload_themes, 0), "reload_themes", 13, "Loads all the theme files in the theme folder, replacing duplicates with the new theme data.", 92, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1793 },
|
{ PROC_LINKS(reload_themes, 0), "reload_themes", 13, "Loads all the theme files in the theme folder, replacing duplicates with the new theme data.", 92, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1793 },
|
||||||
{ PROC_LINKS(remap_interactive, 0), "remap_interactive", 17, "Switch to a named key binding map.", 34, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 292 },
|
{ PROC_LINKS(remap_interactive, 0), "remap_interactive", 17, "Switch to a named key binding map.", 34, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 300 },
|
||||||
{ 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, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1236 },
|
{ 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, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1236 },
|
||||||
{ 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, "w:\\4ed\\code\\4coder_experiments.cpp", 34, 383 },
|
{ 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, "w:\\4ed\\code\\4coder_experiments.cpp", 34, 383 },
|
||||||
{ PROC_LINKS(reopen, 0), "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1607 },
|
{ PROC_LINKS(reopen, 0), "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1607 },
|
||||||
|
@ -449,8 +449,8 @@ static Command_Metadata fcoder_metacmd_table[234] = {
|
||||||
{ PROC_LINKS(set_bindings_default, 0), "set_bindings_default", 20, "Remap keybindings using the 'default' mapping rule.", 51, "w:\\4ed\\code\\4coder_remapping_commands.cpp", 41, 61 },
|
{ PROC_LINKS(set_bindings_default, 0), "set_bindings_default", 20, "Remap keybindings using the 'default' mapping rule.", 51, "w:\\4ed\\code\\4coder_remapping_commands.cpp", 41, 61 },
|
||||||
{ PROC_LINKS(set_bindings_mac_default, 0), "set_bindings_mac_default", 24, "Remap keybindings using the 'mac-default' mapping rule.", 55, "w:\\4ed\\code\\4coder_remapping_commands.cpp", 41, 75 },
|
{ PROC_LINKS(set_bindings_mac_default, 0), "set_bindings_mac_default", 24, "Remap keybindings using the 'mac-default' mapping rule.", 55, "w:\\4ed\\code\\4coder_remapping_commands.cpp", 41, 75 },
|
||||||
{ PROC_LINKS(set_mark, 0), "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 121 },
|
{ PROC_LINKS(set_mark, 0), "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 121 },
|
||||||
{ PROC_LINKS(set_mode_to_notepad_like, 0), "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 260 },
|
{ PROC_LINKS(set_mode_to_notepad_like, 0), "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 268 },
|
||||||
{ PROC_LINKS(set_mode_to_original, 0), "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 254 },
|
{ PROC_LINKS(set_mode_to_original, 0), "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 262 },
|
||||||
{ PROC_LINKS(setup_build_bat, 0), "setup_build_bat", 15, "Queries the user for several configuration options and initializes a new build batch script.", 92, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1498 },
|
{ PROC_LINKS(setup_build_bat, 0), "setup_build_bat", 15, "Queries the user for several configuration options and initializes a new build batch script.", 92, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1498 },
|
||||||
{ PROC_LINKS(setup_build_bat_and_sh, 0), "setup_build_bat_and_sh", 22, "Queries the user for several configuration options and initializes a new build batch script.", 92, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1510 },
|
{ PROC_LINKS(setup_build_bat_and_sh, 0), "setup_build_bat_and_sh", 22, "Queries the user for several configuration options and initializes a new build batch script.", 92, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1510 },
|
||||||
{ PROC_LINKS(setup_build_sh, 0), "setup_build_sh", 14, "Queries the user for several configuration options and initializes a new build shell script.", 92, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1504 },
|
{ PROC_LINKS(setup_build_sh, 0), "setup_build_sh", 14, "Queries the user for several configuration options and initializes a new build shell script.", 92, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1504 },
|
||||||
|
@ -460,17 +460,17 @@ static Command_Metadata fcoder_metacmd_table[234] = {
|
||||||
{ PROC_LINKS(snipe_token_or_word, 0), "snipe_token_or_word", 19, "Delete a single, whole token on or to the left of the cursor and post it to the clipboard.", 90, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1269 },
|
{ PROC_LINKS(snipe_token_or_word, 0), "snipe_token_or_word", 19, "Delete a single, whole token on or to the left of the cursor and post it to the clipboard.", 90, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1269 },
|
||||||
{ PROC_LINKS(snipe_token_or_word_right, 0), "snipe_token_or_word_right", 25, "Delete a single, whole token on or to the right of the cursor and post it to the clipboard.", 91, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1275 },
|
{ PROC_LINKS(snipe_token_or_word_right, 0), "snipe_token_or_word_right", 25, "Delete a single, whole token on or to the right of the cursor and post it to the clipboard.", 91, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1275 },
|
||||||
{ PROC_LINKS(snippet_lister, 0), "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 248 },
|
{ PROC_LINKS(snippet_lister, 0), "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 248 },
|
||||||
{ PROC_LINKS(suppress_mouse, 0), "suppress_mouse", 14, "Hides the mouse and causes all mosue input (clicks, position, wheel) to be ignored.", 83, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 236 },
|
{ PROC_LINKS(suppress_mouse, 0), "suppress_mouse", 14, "Hides the mouse and causes all mosue input (clicks, position, wheel) to be ignored.", 83, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 244 },
|
||||||
{ PROC_LINKS(swap_buffers_between_panels, 0), "swap_buffers_between_panels", 27, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1559 },
|
{ PROC_LINKS(swap_buffers_between_panels, 0), "swap_buffers_between_panels", 27, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1559 },
|
||||||
{ PROC_LINKS(to_lowercase, 0), "to_lowercase", 12, "Converts all ascii text in the range between the cursor and the mark to lowercase.", 82, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 424 },
|
{ PROC_LINKS(to_lowercase, 0), "to_lowercase", 12, "Converts all ascii text in the range between the cursor and the mark to lowercase.", 82, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 424 },
|
||||||
{ PROC_LINKS(to_uppercase, 0), "to_uppercase", 12, "Converts all ascii text in the range between the cursor and the mark to uppercase.", 82, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 404 },
|
{ PROC_LINKS(to_uppercase, 0), "to_uppercase", 12, "Converts all ascii text in the range between the cursor and the mark to uppercase.", 82, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 404 },
|
||||||
{ PROC_LINKS(toggle_filebar, 0), "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 554 },
|
{ PROC_LINKS(toggle_filebar, 0), "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 554 },
|
||||||
{ PROC_LINKS(toggle_fullscreen, 0), "toggle_fullscreen", 17, "Toggle fullscreen mode on or off. The change(s) do not take effect until the next frame.", 89, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 284 },
|
{ PROC_LINKS(toggle_fullscreen, 0), "toggle_fullscreen", 17, "Toggle fullscreen mode on or off. The change(s) do not take effect until the next frame.", 89, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 292 },
|
||||||
{ PROC_LINKS(toggle_highlight_enclosing_scopes, 0), "toggle_highlight_enclosing_scopes", 33, "In code files scopes surrounding the cursor are highlighted with distinguishing colors.", 87, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 272 },
|
{ PROC_LINKS(toggle_highlight_enclosing_scopes, 0), "toggle_highlight_enclosing_scopes", 33, "In code files scopes surrounding the cursor are highlighted with distinguishing colors.", 87, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 280 },
|
||||||
{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 266 },
|
{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 274 },
|
||||||
{ PROC_LINKS(toggle_line_wrap, 0), "toggle_line_wrap", 16, "Toggles the current buffer's line wrapping status.", 50, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 563 },
|
{ PROC_LINKS(toggle_line_wrap, 0), "toggle_line_wrap", 16, "Toggles the current buffer's line wrapping status.", 50, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 563 },
|
||||||
{ PROC_LINKS(toggle_mouse, 0), "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 248 },
|
{ PROC_LINKS(toggle_mouse, 0), "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 256 },
|
||||||
{ PROC_LINKS(toggle_paren_matching_helper, 0), "toggle_paren_matching_helper", 28, "In code files matching parentheses pairs are colored with distinguishing colors.", 80, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 278 },
|
{ PROC_LINKS(toggle_paren_matching_helper, 0), "toggle_paren_matching_helper", 28, "In code files matching parentheses pairs are colored with distinguishing colors.", 80, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 286 },
|
||||||
{ PROC_LINKS(toggle_show_whitespace, 0), "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 647 },
|
{ PROC_LINKS(toggle_show_whitespace, 0), "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 647 },
|
||||||
{ PROC_LINKS(toggle_virtual_whitespace, 0), "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 636 },
|
{ PROC_LINKS(toggle_virtual_whitespace, 0), "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 636 },
|
||||||
{ PROC_LINKS(uncomment_line, 0), "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 147 },
|
{ PROC_LINKS(uncomment_line, 0), "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 147 },
|
||||||
|
@ -478,7 +478,7 @@ static Command_Metadata fcoder_metacmd_table[234] = {
|
||||||
{ PROC_LINKS(undo_this_buffer, 0), "undo_this_buffer", 16, "Advances backwards through the undo history of the current buffer.", 66, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1617 },
|
{ PROC_LINKS(undo_this_buffer, 0), "undo_this_buffer", 16, "Advances backwards through the undo history of the current buffer.", 66, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1617 },
|
||||||
{ 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, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1549 },
|
{ 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, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1549 },
|
||||||
{ PROC_LINKS(view_jump_list_with_lister, 0), "view_jump_list_with_lister", 26, "When executed on a buffer with jumps, creates a persistent lister for all the jumps", 83, "w:\\4ed\\code\\4coder_jump_lister.cpp", 34, 108 },
|
{ PROC_LINKS(view_jump_list_with_lister, 0), "view_jump_list_with_lister", 26, "When executed on a buffer with jumps, creates a persistent lister for all the jumps", 83, "w:\\4ed\\code\\4coder_jump_lister.cpp", 34, 108 },
|
||||||
{ 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, "w:\\4ed\\code\\4coder_search.cpp", 29, 867 },
|
{ 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, "w:\\4ed\\code\\4coder_search.cpp", 29, 953 },
|
||||||
{ 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, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 744 },
|
{ 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, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 744 },
|
||||||
{ PROC_LINKS(write_block, 0), "write_block", 11, "At the cursor, insert a block comment.", 38, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 103 },
|
{ PROC_LINKS(write_block, 0), "write_block", 11, "At the cursor, insert a block comment.", 38, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 103 },
|
||||||
{ PROC_LINKS(write_character, 0), "write_character", 15, "Inserts whatever character was used to trigger this command.", 60, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 67 },
|
{ PROC_LINKS(write_character, 0), "write_character", 15, "Inserts whatever character was used to trigger this command.", 60, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 67 },
|
||||||
|
|
|
@ -613,143 +613,5 @@ OPEN_FILE_HOOK_SIG(end_file_close_jump_list){
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////
|
|
||||||
|
|
||||||
static bool32
|
|
||||||
search_buffer_edit_handler__inner(Application_Links *app, Partition *part, Buffer_ID buffer_id, int32_t start, int32_t one_past_last, String text){
|
|
||||||
Buffer_Summary buffer = get_buffer(app, buffer_id, AccessProtected);
|
|
||||||
|
|
||||||
// NOTE(allen): get the list for this buffer
|
|
||||||
Marker_List *list = get_or_make_list_for_buffer(app, part, &global_heap, buffer_id);
|
|
||||||
if (list == 0){
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE(allen): activate jumps
|
|
||||||
if (match(text, "\n")){
|
|
||||||
User_Input in = get_command_input(app);
|
|
||||||
if (in.key.modifiers[MDFR_SHIFT_INDEX]){
|
|
||||||
goto_jump_at_cursor_same_panel_sticky(app);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
goto_jump_at_cursor_sticky(app);
|
|
||||||
}
|
|
||||||
lock_jump_buffer(buffer);
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE(allen): do not allow new lines to be inserted ever
|
|
||||||
if (find_s_char(text, 0, '\n') != text.size){
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE(allen): check that the range is entirely inside an editable range
|
|
||||||
Partial_Cursor start_cursor = {};
|
|
||||||
Partial_Cursor one_past_last_cursor = {};
|
|
||||||
if (!(buffer_compute_cursor(app, &buffer, seek_pos(start), &start_cursor) &&
|
|
||||||
buffer_compute_cursor(app, &buffer, seek_pos(one_past_last), &one_past_last_cursor))){
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
if (start_cursor.line != one_past_last_cursor.line){
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t line_number = start_cursor.line;
|
|
||||||
Partial_Cursor line_start_cursor = {};
|
|
||||||
Partial_Cursor line_one_past_last_cursor = {};
|
|
||||||
String line = {};
|
|
||||||
if (!read_line(app, part, &buffer, line_number, &line, &line_start_cursor, &line_one_past_last_cursor)){
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t line_start = line_start_cursor.pos;
|
|
||||||
int32_t line_one_past_last = line_one_past_last_cursor.pos;
|
|
||||||
|
|
||||||
int32_t colon_index = find_substr(line, 0, make_lit_string(": "));
|
|
||||||
if (colon_index == line.size){
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t editable_start_from_line_start = colon_index + 2;
|
|
||||||
int32_t editable_start = line_start + editable_start_from_line_start;
|
|
||||||
int32_t editable_one_past_last = line_one_past_last;
|
|
||||||
if (!(editable_start <= start && one_past_last <= editable_one_past_last)){
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE(allen): figure out the target buffer make sure we want to edit it
|
|
||||||
int32_t list_index = get_index_exact_from_list(app, part, list, line_number);
|
|
||||||
if (list_index < 0){
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
ID_Pos_Jump_Location location = {};
|
|
||||||
if (!get_jump_from_list(app, list, list_index, &location)){
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
Buffer_Summary target_buffer = {};
|
|
||||||
if (!get_jump_buffer(app, &target_buffer, &location, AccessOpen)){
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t is_unimportant = false;
|
|
||||||
if (!buffer_get_setting(app, &target_buffer, BufferSetting_Unimportant, &is_unimportant)){
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_unimportant){
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE(allen): figure out the shift of the edit from the search buffer to the target buffer
|
|
||||||
Partial_Cursor target_pos = {};
|
|
||||||
if (!buffer_compute_cursor(app, &target_buffer, seek_pos(location.pos), &target_pos)){
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t target_line_number = target_pos.line;
|
|
||||||
Partial_Cursor target_line_start_cursor = {};
|
|
||||||
Partial_Cursor target_line_one_past_last_cursor = {};
|
|
||||||
String target_line = {};
|
|
||||||
if (!read_line(app, part, &target_buffer, target_line_number, &target_line, &target_line_start_cursor, &target_line_one_past_last_cursor)){
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
String editable_string = substr(line, editable_start_from_line_start, editable_one_past_last - editable_start);
|
|
||||||
if (!match(skip_chop_whitespace(target_line), editable_string)){
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t target_line_start = target_line_start_cursor.pos;
|
|
||||||
//int32_t target_line_one_past_last = target_line_one_past_last_cursor.pos;
|
|
||||||
|
|
||||||
String target_line_skip_whitespace = skip_whitespace(target_line);
|
|
||||||
int32_t skip_into_line_amount = (int32_t)(target_line_skip_whitespace.str - target_line.str);
|
|
||||||
|
|
||||||
int32_t target_editable_start = target_line_start + skip_into_line_amount;
|
|
||||||
int32_t edit_range_shift = target_editable_start - editable_start;
|
|
||||||
|
|
||||||
// NOTE(allen): try to apply the edits
|
|
||||||
global_history_edit_group_begin(app);
|
|
||||||
bool32 result = false;
|
|
||||||
if (buffer_replace_range(app, &target_buffer, start + edit_range_shift, one_past_last + edit_range_shift, text.str, text.size)){
|
|
||||||
if (buffer_replace_range(app, &buffer, start, one_past_last, text.str, text.size)){
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
global_history_edit_group_end(app);
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool32
|
|
||||||
search_buffer_edit_handler(Application_Links *app, Buffer_ID buffer_id, int32_t start, int32_t one_past_last, String text){
|
|
||||||
Partition *scratch = &global_part;
|
|
||||||
Temp_Memory temp = begin_temp_memory(scratch);
|
|
||||||
bool32 result = search_buffer_edit_handler__inner(app, scratch, buffer_id, start, one_past_last, text);
|
|
||||||
end_temp_memory(temp);
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
// BOTTOM
|
// BOTTOM
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,953 @@
|
||||||
|
/*
|
||||||
|
4coder_mirror.cpp - Commands and helpers for parsing jump locations from
|
||||||
|
compiler errors, sticking markers on jump locations, and jumping to them.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TOP
|
||||||
|
|
||||||
|
static Managed_Variable_ID mirror_root_loc = 0;
|
||||||
|
#define DefaultMirrorRootName "DEFAULT.mirror_root"
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_edit_handler(Application_Links *app, Buffer_ID buffer_id, int32_t start, int32_t one_past_last, String text);
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
static void
|
||||||
|
mirror__global_init(Application_Links *app){
|
||||||
|
if (mirror_root_loc == 0){
|
||||||
|
mirror_root_loc = managed_variable_create_or_get_id(app, DefaultMirrorRootName, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Managed_Object
|
||||||
|
mirror__check_scope_for_mirror(Application_Links *app, Managed_Scope scope){
|
||||||
|
Managed_Object result = 0;
|
||||||
|
Managed_Object mirror = 0;
|
||||||
|
if (managed_variable_get(app, scope, mirror_root_loc, &mirror)){
|
||||||
|
if (mirror != 0){
|
||||||
|
Managed_Object_Type object_type = managed_object_get_type(app, mirror);
|
||||||
|
if (object_type == ManagedObjectType_Memory){
|
||||||
|
result = mirror;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
managed_variable_set(app, scope, mirror_root_loc, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_init__inner(Application_Links *app, Buffer_ID buffer, Mirror_Flags flags, Managed_Object *mirror_object_out){
|
||||||
|
bool32 result = false;
|
||||||
|
Managed_Scope scope = 0;
|
||||||
|
if (buffer_get_managed_scope(app, buffer, &scope)){
|
||||||
|
Managed_Object mirror = mirror__check_scope_for_mirror(app, scope);
|
||||||
|
if (mirror == 0){
|
||||||
|
mirror = alloc_managed_memory_in_scope(app, scope, sizeof(Mirror), 1);
|
||||||
|
if (managed_variable_set(app, scope, mirror_root_loc, mirror)){
|
||||||
|
Mirror mirror_data = {};
|
||||||
|
mirror_data.mirror_buffer_id = buffer;
|
||||||
|
mirror_data.mode = MirrorMode_Constructing;
|
||||||
|
mirror_data.flags = flags;
|
||||||
|
mirror_data.mirror_scope = create_user_managed_scope(app);
|
||||||
|
*mirror_object_out = mirror;
|
||||||
|
managed_object_store_data(app, mirror, 0, 1, &mirror_data);
|
||||||
|
buffer_set_edit_handler(app, buffer, mirror_edit_handler);
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_end__inner(Application_Links *app, Managed_Object mirror){
|
||||||
|
bool32 result = false;
|
||||||
|
Managed_Scope scope = managed_object_get_containing_scope(app, mirror);
|
||||||
|
Managed_Object mirror_check = mirror__check_scope_for_mirror(app, scope);
|
||||||
|
if (mirror_check == mirror){
|
||||||
|
Mirror mirror_data = {};
|
||||||
|
if (managed_object_load_data(app, mirror, 0, 1, &mirror_data)){
|
||||||
|
destroy_user_managed_scope(app, mirror_data.mirror_scope);
|
||||||
|
buffer_set_edit_handler(app, mirror_data.mirror_buffer_id, 0);
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
managed_variable_set(app, scope, mirror_root_loc, 0);
|
||||||
|
managed_object_free(app, mirror);
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Mirror__Binary_Search_Result{
|
||||||
|
bool32 abutting;
|
||||||
|
int32_t index;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Mirror__Binary_Search_Result
|
||||||
|
mirror__binary_search_max_point_below(Marker *ranges, int32_t target, int32_t first, int32_t one_past_last){
|
||||||
|
Mirror__Binary_Search_Result result = {};
|
||||||
|
result.index = -1;
|
||||||
|
first = (first*2) - 1;
|
||||||
|
one_past_last = one_past_last*2;
|
||||||
|
for (;;){
|
||||||
|
int32_t mid = (first + one_past_last)/2;
|
||||||
|
int32_t pos = -1;
|
||||||
|
if (mid != -1){
|
||||||
|
Marker *marker = ranges + mid;
|
||||||
|
pos = marker->pos;
|
||||||
|
}
|
||||||
|
if (pos > target){
|
||||||
|
one_past_last = mid;
|
||||||
|
}
|
||||||
|
else if (pos < target){
|
||||||
|
first = mid;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
result.abutting = true;
|
||||||
|
result.index = mid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (first + 1 >= one_past_last){
|
||||||
|
result.index = first;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Mirror__Binary_Search_Result
|
||||||
|
mirror__binary_search_min_point_above(Marker *ranges, int32_t target, int32_t first, int32_t one_past_last,
|
||||||
|
int32_t fake_index, int32_t fake_pos){
|
||||||
|
Mirror__Binary_Search_Result result = {};
|
||||||
|
result.index = -1;
|
||||||
|
first = first*2;
|
||||||
|
one_past_last = (one_past_last*2) + 1;
|
||||||
|
for (;;){
|
||||||
|
int32_t mid = (first + one_past_last - 1)/2;
|
||||||
|
int32_t pos = fake_pos;
|
||||||
|
if (mid != fake_index){
|
||||||
|
Marker *marker = ranges + mid;
|
||||||
|
pos = marker->pos;
|
||||||
|
}
|
||||||
|
if (pos > target){
|
||||||
|
one_past_last = mid + 1;
|
||||||
|
}
|
||||||
|
else if (pos < target){
|
||||||
|
first = mid + 1;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
result.abutting = true;
|
||||||
|
result.index = mid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (first + 1 >= one_past_last){
|
||||||
|
result.index = first;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Mirror_Hot
|
||||||
|
mirror__hot_from_data(Application_Links *app, Arena *arena, Mirror mirror_data){
|
||||||
|
Mirror_Hot result = {};
|
||||||
|
Mirror_Hot mirror_hot = {};
|
||||||
|
mirror_hot.count = mirror_data.count;
|
||||||
|
mirror_hot.source_buffer_ids = push_array(arena, Buffer_ID, mirror_hot.count);
|
||||||
|
mirror_hot.mirror_ranges = push_array(arena, Marker, (mirror_hot.count)*2);
|
||||||
|
mirror_hot.source_ranges = push_array(arena, Managed_Object, mirror_hot.count);
|
||||||
|
if (managed_object_load_data(app, mirror_data.source_buffer_ids, 0, mirror_hot.count, mirror_hot.source_buffer_ids) &&
|
||||||
|
managed_object_load_data(app, mirror_data.mirror_ranges, 0, mirror_hot.count*2, mirror_hot.mirror_ranges) &&
|
||||||
|
managed_object_load_data(app, mirror_data.source_ranges, 0, mirror_hot.count, mirror_hot.source_ranges)){
|
||||||
|
result = mirror_hot;
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror__min_max_point_indices_not_intersecting(int32_t above_point, int32_t below_point, int32_t *range_index_out){
|
||||||
|
bool32 result = false;
|
||||||
|
if (below_point < above_point && (above_point%2) == 0 && ((below_point + 2)%2) == 1){
|
||||||
|
*range_index_out = above_point/2;
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror__min_max_point_indices_contained(int32_t above_point, int32_t below_point, int32_t *range_index_out){
|
||||||
|
bool32 result = false;
|
||||||
|
if (below_point < above_point && (above_point%2) == 1 && ((below_point + 2)%2) == 0){
|
||||||
|
*range_index_out = above_point/2;
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Mirror__Check_Range_Result{
|
||||||
|
bool32 passed_checks;
|
||||||
|
int32_t insert_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Mirror__Check_Range_Result
|
||||||
|
mirror__check_range_to_add(Application_Links *app, Arena *scratch, int32_t mirror_first, int32_t source_first, int32_t length,
|
||||||
|
Buffer_Summary *source_buffer, Buffer_Summary *mirror_buffer, Mirror_Hot *mirror_hot,
|
||||||
|
int32_t collidable_indices_first, bool32 auto_trust_text){
|
||||||
|
// check the new range for the following rules and determine the insert index
|
||||||
|
Mirror__Check_Range_Result result = {};
|
||||||
|
result.insert_index = -1;
|
||||||
|
|
||||||
|
// 1. the source range must be entirely contained in the source buffer and
|
||||||
|
// the mirror range must be entirely contained in the mirror buffer
|
||||||
|
int32_t source_one_past_last = source_first + length;
|
||||||
|
int32_t mirror_one_past_last = mirror_first + length;
|
||||||
|
if (0 <= source_first && source_one_past_last <= source_buffer->size &&
|
||||||
|
0 <= mirror_first && mirror_one_past_last <= mirror_buffer->size){
|
||||||
|
|
||||||
|
// 2. the mirror range must not overlap or abut any existing mirror ranges
|
||||||
|
bool32 independent_range = false;
|
||||||
|
if (mirror_hot->count == 0){
|
||||||
|
independent_range = true;
|
||||||
|
result.insert_index = 0;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
int32_t fake_index = mirror_hot->count*2;
|
||||||
|
int32_t fake_pos = mirror_buffer->size + 1;
|
||||||
|
Mirror__Binary_Search_Result above_point = mirror__binary_search_min_point_above(mirror_hot->mirror_ranges, mirror_first,
|
||||||
|
collidable_indices_first, mirror_hot->count,
|
||||||
|
fake_index, fake_pos);
|
||||||
|
Mirror__Binary_Search_Result below_point = {};
|
||||||
|
if (!above_point.abutting){
|
||||||
|
below_point = mirror__binary_search_max_point_below(mirror_hot->mirror_ranges, mirror_first,
|
||||||
|
collidable_indices_first, mirror_hot->count);
|
||||||
|
if (!below_point.abutting){
|
||||||
|
if (mirror__min_max_point_indices_not_intersecting(above_point.index, below_point.index, &result.insert_index)){
|
||||||
|
independent_range = true;
|
||||||
|
Assert(0 <= result.insert_index && result.insert_index <= mirror_hot->count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (independent_range){
|
||||||
|
// 3. the text in the source range must exactly match the text in the mirror range
|
||||||
|
if (auto_trust_text){
|
||||||
|
result.passed_checks = true;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
char *buffer_1 = push_array(scratch, char, length);
|
||||||
|
char *buffer_2 = push_array(scratch, char, length);
|
||||||
|
if (buffer_read_range(app, source_buffer->buffer_id, source_first, source_first + length, buffer_1)){
|
||||||
|
if (buffer_read_range(app, mirror_buffer->buffer_id, mirror_first, mirror_first + length, buffer_2)){
|
||||||
|
if (memcmp(buffer_1, buffer_2, length) == 0){
|
||||||
|
result.passed_checks = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_add_range__inner_check_optimization(Application_Links *app, Managed_Object mirror, Buffer_ID source,
|
||||||
|
int32_t mirror_first, int32_t source_first, int32_t length,
|
||||||
|
int32_t collidable_indices_first, bool32 auto_trust_text, int32_t *insert_index_out){
|
||||||
|
bool32 result = false;
|
||||||
|
if (length > 0){
|
||||||
|
Buffer_Summary source_buffer = {};
|
||||||
|
if (get_buffer_summary(app, source, AccessAll, &source_buffer)){
|
||||||
|
Managed_Scope scope = managed_object_get_containing_scope(app, mirror);
|
||||||
|
Managed_Object mirror_check = mirror__check_scope_for_mirror(app, scope);
|
||||||
|
if (mirror_check == mirror){
|
||||||
|
Mirror mirror_data = {};
|
||||||
|
if (managed_object_load_data(app, mirror, 0, 1, &mirror_data)){
|
||||||
|
Buffer_Summary mirror_buffer = {};
|
||||||
|
Buffer_ID mirror_id = mirror_data.mirror_buffer_id;
|
||||||
|
if (get_buffer_summary(app, mirror_id, AccessAll, &mirror_buffer)){
|
||||||
|
Arena arena = make_arena(app, (8 << 10));
|
||||||
|
|
||||||
|
// read mirror data into hot structure
|
||||||
|
Mirror_Hot mirror_hot = {};
|
||||||
|
mirror_hot.count = mirror_data.count;
|
||||||
|
mirror_hot.source_buffer_ids = push_array(&arena, Buffer_ID, mirror_hot.count);
|
||||||
|
mirror_hot.mirror_ranges = push_array(&arena, Marker, (mirror_hot.count)*2);
|
||||||
|
mirror_hot.source_ranges = push_array(&arena, Managed_Object, mirror_hot.count);
|
||||||
|
|
||||||
|
bool32 load_success = false;
|
||||||
|
if (mirror_hot.count == 0){
|
||||||
|
load_success = true;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
load_success = (managed_object_load_data(app, mirror_data.source_buffer_ids, 0, mirror_hot.count , mirror_hot.source_buffer_ids) &&
|
||||||
|
managed_object_load_data(app, mirror_data.mirror_ranges , 0, mirror_hot.count*2, mirror_hot.mirror_ranges ) &&
|
||||||
|
managed_object_load_data(app, mirror_data.source_ranges , 0, mirror_hot.count , mirror_hot.source_ranges ));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (load_success){
|
||||||
|
Mirror__Check_Range_Result check = mirror__check_range_to_add(app, &arena, mirror_first, source_first, length,
|
||||||
|
&source_buffer, &mirror_buffer, &mirror_hot,
|
||||||
|
collidable_indices_first, auto_trust_text);
|
||||||
|
|
||||||
|
if (check.passed_checks){
|
||||||
|
// insert the new range at the insert index
|
||||||
|
bool32 r = true;
|
||||||
|
int32_t insert_index = check.insert_index;
|
||||||
|
*insert_index_out = insert_index;
|
||||||
|
|
||||||
|
Marker mirror_range[2] = {};
|
||||||
|
mirror_range[0].pos = mirror_first;
|
||||||
|
mirror_range[0].lean_right = false;
|
||||||
|
mirror_range[1].pos = mirror_first + length;
|
||||||
|
mirror_range[1].lean_right = true;
|
||||||
|
|
||||||
|
Marker source_range[2] = {};
|
||||||
|
source_range[0].pos = source_first;
|
||||||
|
source_range[0].lean_right = false;
|
||||||
|
source_range[1].pos = source_first + length;
|
||||||
|
source_range[1].lean_right = true;
|
||||||
|
|
||||||
|
Managed_Scope scopes[3] = {};
|
||||||
|
scopes[0] = scope;
|
||||||
|
scopes[1] = mirror_data.mirror_scope;
|
||||||
|
buffer_get_managed_scope(app, source, &scopes[2]);
|
||||||
|
|
||||||
|
Managed_Scope source_sub_scope = get_managed_scope_with_multiple_dependencies(app, scopes, 3);
|
||||||
|
|
||||||
|
Managed_Object new_source_range = alloc_buffer_markers_on_buffer(app, source, 2, &source_sub_scope);
|
||||||
|
r = r && managed_object_store_data(app, new_source_range, 0, 2, &source_range);
|
||||||
|
|
||||||
|
if (mirror_data.count + 1 > mirror_data.max){
|
||||||
|
if (mirror_data.count != 0){
|
||||||
|
r = r && managed_object_free(app, mirror_data.source_buffer_ids);
|
||||||
|
r = r && managed_object_free(app, mirror_data.mirror_ranges);
|
||||||
|
r = r && managed_object_free(app, mirror_data.source_ranges);
|
||||||
|
}
|
||||||
|
|
||||||
|
Managed_Scope mirror_sub_scope = get_managed_scope_with_multiple_dependencies(app, scopes, 2);
|
||||||
|
int32_t new_max = 256;
|
||||||
|
if (new_max <= mirror_data.max){
|
||||||
|
new_max = mirror_data.max*2;
|
||||||
|
}
|
||||||
|
mirror_data.source_buffer_ids = alloc_managed_memory_in_scope(app, mirror_sub_scope, sizeof(Buffer_ID), new_max);
|
||||||
|
mirror_data.mirror_ranges = alloc_buffer_markers_on_buffer(app, mirror_id, new_max*2, &mirror_sub_scope);
|
||||||
|
mirror_data.source_ranges = alloc_managed_memory_in_scope(app, mirror_sub_scope, sizeof(Managed_Object), new_max);
|
||||||
|
|
||||||
|
mirror_data.max = new_max;
|
||||||
|
|
||||||
|
// head ranges
|
||||||
|
int32_t head_count = insert_index;
|
||||||
|
if (head_count > 0){
|
||||||
|
r = r && managed_object_store_data(app, mirror_data.source_buffer_ids, 0, head_count , mirror_hot.source_buffer_ids);
|
||||||
|
r = r && managed_object_store_data(app, mirror_data.mirror_ranges , 0, head_count*2, mirror_hot.mirror_ranges );
|
||||||
|
r = r && managed_object_store_data(app, mirror_data.source_ranges , 0, head_count , mirror_hot.source_ranges );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// tail ranges
|
||||||
|
int32_t tail_count = mirror_hot.count - insert_index;
|
||||||
|
if (tail_count > 0){
|
||||||
|
int32_t to = insert_index + 1;
|
||||||
|
int32_t from = insert_index;
|
||||||
|
r = r && managed_object_store_data(app, mirror_data.source_buffer_ids, to , tail_count , mirror_hot.source_buffer_ids + from);
|
||||||
|
r = r && managed_object_store_data(app, mirror_data.mirror_ranges , to*2, tail_count*2, mirror_hot.mirror_ranges + from*2 );
|
||||||
|
r = r && managed_object_store_data(app, mirror_data.source_ranges , to , tail_count , mirror_hot.source_ranges + from );
|
||||||
|
}
|
||||||
|
|
||||||
|
// new range
|
||||||
|
r = r && managed_object_store_data(app, mirror_data.source_buffer_ids, insert_index , 1, &source );
|
||||||
|
r = r && managed_object_store_data(app, mirror_data.mirror_ranges , insert_index*2, 2, mirror_range );
|
||||||
|
r = r && managed_object_store_data(app, mirror_data.source_ranges , insert_index , 1, &new_source_range);
|
||||||
|
|
||||||
|
mirror_data.count += 1;
|
||||||
|
|
||||||
|
managed_object_store_data(app, mirror, 0, 1, &mirror_data);
|
||||||
|
|
||||||
|
result = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
arena_release_all(&arena);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_add_range__inner(Application_Links *app, Managed_Object mirror, Buffer_ID source,
|
||||||
|
int32_t mirror_first, int32_t source_first, int32_t length){
|
||||||
|
int32_t ignore = 0;
|
||||||
|
return(mirror_add_range__inner_check_optimization(app, mirror, source, mirror_first, source_first, length, 0, false, &ignore));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_set_mode__inner(Application_Links *app, Managed_Object mirror, Mirror_Mode mode){
|
||||||
|
bool32 result = false;
|
||||||
|
Managed_Scope scope = managed_object_get_containing_scope(app, mirror);
|
||||||
|
Managed_Object mirror_check = mirror__check_scope_for_mirror(app, scope);
|
||||||
|
if (mirror_check == mirror){
|
||||||
|
Mirror mirror_data = {};
|
||||||
|
if (managed_object_load_data(app, mirror, 0, 1, &mirror_data)){
|
||||||
|
mirror_data.mode = mode;
|
||||||
|
if (managed_object_store_data(app, mirror, 0, 1, &mirror_data)){
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_get_mode__inner(Application_Links *app, Managed_Object mirror, Mirror_Mode *mode_out){
|
||||||
|
bool32 result = false;
|
||||||
|
Managed_Scope scope = managed_object_get_containing_scope(app, mirror);
|
||||||
|
Managed_Object mirror_check = mirror__check_scope_for_mirror(app, scope);
|
||||||
|
if (mirror_check == mirror){
|
||||||
|
Mirror mirror_data = {};
|
||||||
|
if (managed_object_load_data(app, mirror, 0, 1, &mirror_data)){
|
||||||
|
*mode_out = mirror_data.mode;
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_set_flags__inner(Application_Links *app, Managed_Object mirror, Mirror_Flags flags){
|
||||||
|
bool32 result = false;
|
||||||
|
Managed_Scope scope = managed_object_get_containing_scope(app, mirror);
|
||||||
|
Managed_Object mirror_check = mirror__check_scope_for_mirror(app, scope);
|
||||||
|
if (mirror_check == mirror){
|
||||||
|
Mirror mirror_data = {};
|
||||||
|
if (managed_object_load_data(app, mirror, 0, 1, &mirror_data)){
|
||||||
|
mirror_data.flags = flags;
|
||||||
|
if (managed_object_store_data(app, mirror, 0, 1, &mirror_data)){
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_get_flags__inner(Application_Links *app, Managed_Object mirror, Mirror_Flags *flags_out){
|
||||||
|
bool32 result = false;
|
||||||
|
Managed_Scope scope = managed_object_get_containing_scope(app, mirror);
|
||||||
|
Managed_Object mirror_check = mirror__check_scope_for_mirror(app, scope);
|
||||||
|
if (mirror_check == mirror){
|
||||||
|
Mirror mirror_data = {};
|
||||||
|
if (managed_object_load_data(app, mirror, 0, 1, &mirror_data)){
|
||||||
|
*flags_out = mirror_data.flags;
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_init(Application_Links *app, Buffer_ID buffer, Mirror_Flags flags, Managed_Object *mirror_object_out){
|
||||||
|
mirror__global_init(app);
|
||||||
|
return(mirror_init__inner(app, buffer, flags, mirror_object_out));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_end(Application_Links *app, Managed_Object mirror){
|
||||||
|
mirror__global_init(app);
|
||||||
|
return(mirror_end__inner(app, mirror));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_add_range(Application_Links *app, Managed_Object mirror, Buffer_ID source,
|
||||||
|
int32_t mirror_first, int32_t source_first, int32_t length){
|
||||||
|
mirror__global_init(app);
|
||||||
|
return(mirror_add_range__inner(app, mirror, source, mirror_first, source_first, length));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_set_mode(Application_Links *app, Managed_Object mirror, Mirror_Mode mode){
|
||||||
|
mirror__global_init(app);
|
||||||
|
return(mirror_set_mode__inner(app, mirror, mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_get_mode(Application_Links *app, Managed_Object mirror, Mirror_Mode *mode_out){
|
||||||
|
mirror__global_init(app);
|
||||||
|
return(mirror_get_mode__inner(app, mirror, mode_out));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_set_flags(Application_Links *app, Managed_Object mirror, Mirror_Flags flags){
|
||||||
|
mirror__global_init(app);
|
||||||
|
return(mirror_set_flags__inner(app, mirror, flags));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_get_flags(Application_Links *app, Managed_Object mirror, Mirror_Flags *flags_out){
|
||||||
|
mirror__global_init(app);
|
||||||
|
return(mirror_get_flags__inner(app, mirror, flags_out));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_buffer_create(Application_Links *app, String buffer_name, Mirror_Flags flags, Buffer_ID *mirror_buffer_id_out){
|
||||||
|
mirror__global_init(app);
|
||||||
|
bool32 result = false;
|
||||||
|
Buffer_ID new_buffer = 0;
|
||||||
|
if (!get_buffer_by_name(app, buffer_name, AccessAll, &new_buffer)){
|
||||||
|
if (new_buffer == 0){
|
||||||
|
if (create_buffer(app, buffer_name, BufferCreate_NeverAttachToFile|BufferCreate_AlwaysNew, &new_buffer)){
|
||||||
|
Managed_Object ignore_object = 0;
|
||||||
|
if (mirror_init__inner(app, new_buffer, flags, &ignore_object)){
|
||||||
|
*mirror_buffer_id_out = new_buffer;
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Managed_Scope
|
||||||
|
mirror__buffer_to_object(Application_Links *app, Buffer_ID buffer){
|
||||||
|
Managed_Object result = 0;
|
||||||
|
Managed_Scope scope = 0;
|
||||||
|
if (buffer_get_managed_scope(app, buffer, &scope)){
|
||||||
|
result = mirror__check_scope_for_mirror(app, scope);
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_buffer_end(Application_Links *app, Buffer_ID mirror){
|
||||||
|
mirror__global_init(app);
|
||||||
|
bool32 result = false;
|
||||||
|
Managed_Object mirror_object = mirror__buffer_to_object(app, mirror);
|
||||||
|
if (mirror_object != 0){
|
||||||
|
result = mirror_end__inner(app, mirror_object);
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_buffer_add_range_exact(Application_Links *app, Buffer_ID mirror, Buffer_ID source,
|
||||||
|
int32_t mirror_first, int32_t source_first, int32_t length){
|
||||||
|
mirror__global_init(app);
|
||||||
|
bool32 result = false;
|
||||||
|
Managed_Object mirror_object = mirror__buffer_to_object(app, mirror);
|
||||||
|
if (mirror_object != 0){
|
||||||
|
result = mirror_add_range__inner(app, mirror_object, source, mirror_first, source_first, length);
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t
|
||||||
|
mirror__range_loose_get_length(Application_Links *app, Buffer_ID mirror, Buffer_ID source,
|
||||||
|
int32_t mirror_first, int32_t source_first, int32_t max_length){
|
||||||
|
int32_t result = 0;
|
||||||
|
Arena arena = make_arena(app, (8 << 10));
|
||||||
|
char *buffer_1 = push_array(&arena, char, max_length);
|
||||||
|
char *buffer_2 = push_array(&arena, char, max_length);
|
||||||
|
if (buffer_read_range(app, source, source_first, source_first + max_length, buffer_1)){
|
||||||
|
if (buffer_read_range(app, mirror, mirror_first, mirror_first + max_length, buffer_2)){
|
||||||
|
for (; result < max_length;
|
||||||
|
result += 1){
|
||||||
|
if (buffer_1[result] != buffer_2[result]){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arena_release_all(&arena);
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_buffer_add_range_loose(Application_Links *app, Buffer_ID mirror, Buffer_ID source,
|
||||||
|
int32_t mirror_first, int32_t source_first, int32_t max_length){
|
||||||
|
mirror__global_init(app);
|
||||||
|
bool32 result = false;
|
||||||
|
int32_t length = mirror__range_loose_get_length(app, mirror, source, mirror_first, source_first, max_length);
|
||||||
|
if (length > 0){
|
||||||
|
Managed_Object mirror_object = mirror__buffer_to_object(app, mirror);
|
||||||
|
if (mirror_object != 0){
|
||||||
|
result = mirror_add_range__inner(app, mirror_object, source, mirror_first, source_first, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_buffer_insert_range(Application_Links *app, Buffer_ID mirror, Buffer_ID source,
|
||||||
|
int32_t mirror_insert_pos, int32_t source_first, int32_t length){
|
||||||
|
mirror__global_init(app);
|
||||||
|
bool32 result = false;
|
||||||
|
Managed_Object mirror_object = mirror__buffer_to_object(app, mirror);
|
||||||
|
if (mirror_object != 0){
|
||||||
|
Mirror_Mode mode = 0;
|
||||||
|
if (mirror_get_mode__inner(app, mirror_object, &mode)){
|
||||||
|
if (mode == MirrorMode_Constructing){
|
||||||
|
bool32 did_insert = false;
|
||||||
|
{
|
||||||
|
Arena arena = make_arena(app, (8 << 10));
|
||||||
|
char *buffer = push_array(&arena, char, length);
|
||||||
|
if (buffer_read_range(app, source, source_first, source_first + length, buffer)){
|
||||||
|
String string = make_string(buffer, length);
|
||||||
|
if (buffer_replace_range(app, mirror, mirror_insert_pos, mirror_insert_pos, string)){
|
||||||
|
did_insert = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arena_release_all(&arena);
|
||||||
|
}
|
||||||
|
if (did_insert){
|
||||||
|
result = mirror_add_range__inner(app, mirror_object, source, mirror_insert_pos, source_first, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_buffer_set_mode(Application_Links *app, Buffer_ID mirror, Mirror_Mode mode){
|
||||||
|
mirror__global_init(app);
|
||||||
|
bool32 result = false;
|
||||||
|
Managed_Object mirror_object = mirror__buffer_to_object(app, mirror);
|
||||||
|
if (mirror_object != 0){
|
||||||
|
result = mirror_set_mode__inner(app, mirror_object, mode);
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_buffer_get_mode(Application_Links *app, Buffer_ID mirror, Mirror_Mode *mode_out){
|
||||||
|
mirror__global_init(app);
|
||||||
|
bool32 result = false;
|
||||||
|
Managed_Object mirror_object = mirror__buffer_to_object(app, mirror);
|
||||||
|
if (mirror_object != 0){
|
||||||
|
result = mirror_get_mode__inner(app, mirror_object, mode_out);
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_buffer_set_flags(Application_Links *app, Buffer_ID mirror, Mirror_Flags flags){
|
||||||
|
mirror__global_init(app);
|
||||||
|
bool32 result = false;
|
||||||
|
Managed_Object mirror_object = mirror__buffer_to_object(app, mirror);
|
||||||
|
if (mirror_object != 0){
|
||||||
|
result = mirror_set_flags__inner(app, mirror_object, flags);
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_buffer_get_flags(Application_Links *app, Buffer_ID mirror, Mirror_Flags *flags_out){
|
||||||
|
mirror__global_init(app);
|
||||||
|
bool32 result = false;
|
||||||
|
Managed_Object mirror_object = mirror__buffer_to_object(app, mirror);
|
||||||
|
if (mirror_object != 0){
|
||||||
|
result = mirror_get_flags__inner(app, mirror_object, flags_out);
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_buffer_refresh(Application_Links *app, Buffer_ID mirror){
|
||||||
|
mirror__global_init(app);
|
||||||
|
bool32 result = false;
|
||||||
|
Managed_Object mirror_object = mirror__buffer_to_object(app, mirror);
|
||||||
|
if (mirror_object != 0){
|
||||||
|
// TODO(allen):
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mirror_quick_sort_mirror_ranges(Mirror_Range *ranges, int32_t first, int32_t one_past_last){
|
||||||
|
int32_t last = one_past_last - 1;
|
||||||
|
if (first < last){
|
||||||
|
int32_t pivot_mirror_first = ranges[last].mirror_first;
|
||||||
|
int32_t j = first;
|
||||||
|
for (int32_t i = first; i < last; i += 1){
|
||||||
|
int32_t mirror_first = ranges[i].mirror_first;
|
||||||
|
if (mirror_first < pivot_mirror_first){
|
||||||
|
if (j < i){
|
||||||
|
Mirror_Range t = ranges[i];
|
||||||
|
ranges[i] = ranges[j];
|
||||||
|
ranges[j] = t;
|
||||||
|
}
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Mirror_Range t = ranges[last];
|
||||||
|
ranges[last] = ranges[j];
|
||||||
|
ranges[j] = t;
|
||||||
|
}
|
||||||
|
int32_t pivot = j;
|
||||||
|
mirror_quick_sort_mirror_ranges(ranges, first, pivot);
|
||||||
|
mirror_quick_sort_mirror_ranges(ranges, pivot + 1, one_past_last);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror__check_range_array_sorting(Mirror_Range *ranges, int32_t count){
|
||||||
|
bool32 result = true;
|
||||||
|
int32_t prev_pos = -1;
|
||||||
|
for (int32_t i = 0; i < count; i += 1){
|
||||||
|
int32_t first = ranges[i].mirror_first;
|
||||||
|
int32_t one_past_last = first + ranges[i].length;
|
||||||
|
if (prev_pos < first && first <= one_past_last){
|
||||||
|
prev_pos = one_past_last;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
result = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_buffer_add_range_exact_array(Application_Links *app, Buffer_ID mirror, Mirror_Range *ranges, int32_t count){
|
||||||
|
mirror__global_init(app);
|
||||||
|
bool32 result = false;
|
||||||
|
Managed_Object mirror_object = mirror__buffer_to_object(app, mirror);
|
||||||
|
if (mirror_object != 0){
|
||||||
|
if (mirror__check_range_array_sorting(ranges, count)){
|
||||||
|
bool32 r = true;
|
||||||
|
Mirror_Range *range = ranges;
|
||||||
|
int32_t safe_to_ignore_index = 0;
|
||||||
|
for (int32_t i = 0; i < count; i += 1, range += 1){
|
||||||
|
int32_t new_range_index = 0;
|
||||||
|
if (range->length > 0){
|
||||||
|
if (!mirror_add_range__inner_check_optimization(app, mirror_object, range->source_buffer_id,
|
||||||
|
range->mirror_first, range->source_first, range->length,
|
||||||
|
safe_to_ignore_index, false, &new_range_index)){
|
||||||
|
r = false;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
safe_to_ignore_index = new_range_index + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_buffer_add_range_loose_array(Application_Links *app, Buffer_ID mirror, Mirror_Range *ranges, int32_t count){
|
||||||
|
mirror__global_init(app);
|
||||||
|
bool32 result = false;
|
||||||
|
Managed_Object mirror_object = mirror__buffer_to_object(app, mirror);
|
||||||
|
if (mirror_object != 0){
|
||||||
|
{
|
||||||
|
Mirror_Range *range = ranges;
|
||||||
|
for (int32_t i = 0; i < count; i += 1, range += 1){
|
||||||
|
range->length = mirror__range_loose_get_length(app, mirror, range->source_buffer_id, range->mirror_first, range->source_first, range->length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mirror__check_range_array_sorting(ranges, count)){
|
||||||
|
bool32 r = true;
|
||||||
|
Mirror_Range *range = ranges;
|
||||||
|
int32_t safe_to_ignore_index = 0;
|
||||||
|
for (int32_t i = 0; i < count; i += 1, range += 1){
|
||||||
|
int32_t new_range_index = 0;
|
||||||
|
if (range->length > 0){
|
||||||
|
if (!mirror_add_range__inner_check_optimization(app, mirror_object, range->source_buffer_id,
|
||||||
|
range->mirror_first, range->source_first, range->length,
|
||||||
|
safe_to_ignore_index, false, &new_range_index)){
|
||||||
|
r = false;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
safe_to_ignore_index = new_range_index + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_buffer_insert_range_array(Application_Links *app, Buffer_ID mirror, Mirror_Range *ranges, int32_t count){
|
||||||
|
mirror__global_init(app);
|
||||||
|
bool32 result = false;
|
||||||
|
Managed_Object mirror_object = mirror__buffer_to_object(app, mirror);
|
||||||
|
if (mirror_object != 0){
|
||||||
|
Mirror_Mode mode = 0;
|
||||||
|
if (mirror_get_mode__inner(app, mirror_object, &mode)){
|
||||||
|
if (mode == MirrorMode_Constructing){
|
||||||
|
if (mirror__check_range_array_sorting(ranges, count)){
|
||||||
|
bool32 r = true;
|
||||||
|
Mirror_Range *range = ranges;
|
||||||
|
int32_t safe_to_ignore_index = 0;
|
||||||
|
int32_t total_shift = 0;
|
||||||
|
Arena arena = make_arena(app, (8 << 10));
|
||||||
|
for (int32_t i = 0; i < count; i += 1, range += 1){
|
||||||
|
int32_t mirror_first = range->mirror_first + total_shift;
|
||||||
|
bool32 did_insert = false;
|
||||||
|
{
|
||||||
|
Temp_Memory_Arena temp = begin_temp_memory(&arena);
|
||||||
|
char *buffer = push_array(&arena, char, range->length);
|
||||||
|
if (buffer_read_range(app, range->source_buffer_id, range->source_first, range->source_first + range->length, buffer)){
|
||||||
|
String string = make_string(buffer, range->length);
|
||||||
|
if (buffer_replace_range(app, mirror, mirror_first, mirror_first, string)){
|
||||||
|
did_insert = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end_temp_memory(temp);
|
||||||
|
}
|
||||||
|
int32_t new_range_index = 0;
|
||||||
|
if (range->length > 0){
|
||||||
|
if (!mirror_add_range__inner_check_optimization(app, mirror_object, range->source_buffer_id,
|
||||||
|
mirror_first, range->source_first, range->length,
|
||||||
|
safe_to_ignore_index, false, &new_range_index)){
|
||||||
|
r = false;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
safe_to_ignore_index = new_range_index + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
total_shift += range->length;
|
||||||
|
}
|
||||||
|
arena_release_all(&arena);
|
||||||
|
result = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
mirror_edit_handler(Application_Links *app, Buffer_ID buffer_id, int32_t first, int32_t one_past_last, String text){
|
||||||
|
mirror__global_init(app);
|
||||||
|
bool32 result = false;
|
||||||
|
Buffer_Summary mirror_buffer = {};
|
||||||
|
if (get_buffer_summary(app, buffer_id, AccessAll, &mirror_buffer)){
|
||||||
|
Managed_Object mirror = mirror__buffer_to_object(app, buffer_id);
|
||||||
|
if (mirror != 0){
|
||||||
|
Mirror_Mode mode = 0;
|
||||||
|
if (mirror_get_mode__inner(app, mirror, &mode)){
|
||||||
|
Mirror mirror_data = {};
|
||||||
|
if (managed_object_load_data(app, mirror, 0, 1, &mirror_data)){
|
||||||
|
Arena arena = make_arena(app, (8 << 10));
|
||||||
|
|
||||||
|
Mirror_Hot mirror_hot = mirror__hot_from_data(app, &arena, mirror_data);
|
||||||
|
switch (mode){
|
||||||
|
case MirrorMode_Constructing:
|
||||||
|
{
|
||||||
|
bool32 unreflected_range = false;
|
||||||
|
if (mirror_hot.count == 0){
|
||||||
|
unreflected_range = true;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
int32_t fake_index = mirror_hot.count*2;
|
||||||
|
int32_t fake_pos = mirror_buffer.size + 1;
|
||||||
|
Mirror__Binary_Search_Result above_point = mirror__binary_search_min_point_above(mirror_hot.mirror_ranges, first,
|
||||||
|
0, mirror_hot.count,
|
||||||
|
fake_index, fake_pos);
|
||||||
|
Mirror__Binary_Search_Result below_point = mirror__binary_search_max_point_below(mirror_hot.mirror_ranges, one_past_last,
|
||||||
|
0, mirror_hot.count);
|
||||||
|
int32_t ignore = 0;
|
||||||
|
if (mirror__min_max_point_indices_not_intersecting(above_point.index, below_point.index, &ignore)){
|
||||||
|
unreflected_range = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unreflected_range){
|
||||||
|
result = buffer_replace_range(app, buffer_id, first, one_past_last, text);
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case MirrorMode_Reflecting:
|
||||||
|
{
|
||||||
|
bool32 newlines_are_jumps = ((mirror_data.flags & MirrorFlag_NewlinesAreJumps) != 0);
|
||||||
|
|
||||||
|
bool32 blocked = false;
|
||||||
|
if (newlines_are_jumps){
|
||||||
|
if (has_substr(text, make_lit_string("\n"))){
|
||||||
|
blocked = true;
|
||||||
|
}
|
||||||
|
if (match(text, "\n")){
|
||||||
|
User_Input in = get_command_input(app);
|
||||||
|
if (in.key.modifiers[MDFR_SHIFT_INDEX]){
|
||||||
|
goto_jump_at_cursor_same_panel_sticky(app);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
goto_jump_at_cursor_sticky(app);
|
||||||
|
}
|
||||||
|
lock_jump_buffer(app, buffer_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!blocked){
|
||||||
|
bool32 reflected_range = false;
|
||||||
|
int32_t range_index = 0;
|
||||||
|
if (mirror_hot.count > 0){
|
||||||
|
int32_t fake_index = mirror_hot.count*2;
|
||||||
|
int32_t fake_pos = mirror_buffer.size + 1;
|
||||||
|
Mirror__Binary_Search_Result above_point = mirror__binary_search_min_point_above(mirror_hot.mirror_ranges, first,
|
||||||
|
0, mirror_hot.count,
|
||||||
|
fake_index, fake_pos);
|
||||||
|
Mirror__Binary_Search_Result below_point = mirror__binary_search_max_point_below(mirror_hot.mirror_ranges, one_past_last,
|
||||||
|
0, mirror_hot.count);
|
||||||
|
if (mirror__min_max_point_indices_contained(above_point.index, below_point.index, &range_index)){
|
||||||
|
reflected_range = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reflected_range){
|
||||||
|
// check that the range_index is valid and get source if it is
|
||||||
|
Managed_Object source_range_object = mirror_hot.source_ranges[range_index];
|
||||||
|
if (managed_object_get_type(app, source_range_object) == ManagedObjectType_Markers){
|
||||||
|
Buffer_ID source = mirror_hot.source_buffer_ids[range_index];
|
||||||
|
Marker *mirror_range = mirror_hot.mirror_ranges + range_index*2;
|
||||||
|
Marker source_range[2];
|
||||||
|
if (managed_object_load_data(app, source_range_object, 0, 2, source_range)){
|
||||||
|
int32_t base_source_first = source_range[0].pos;
|
||||||
|
//int32_t base_source_one_past_last = source_range[1].pos;
|
||||||
|
|
||||||
|
int32_t base_mirror_first = mirror_range[0].pos;
|
||||||
|
//int32_t base_mirror_one_past_last = mirror_range[1].pos;
|
||||||
|
|
||||||
|
int32_t source_first = base_source_first + (first - base_mirror_first);
|
||||||
|
int32_t source_one_past_last = source_first + (one_past_last - first);
|
||||||
|
|
||||||
|
global_history_edit_group_begin(app);
|
||||||
|
if (buffer_replace_range(app, source, source_first, source_one_past_last, text)){
|
||||||
|
result = buffer_replace_range(app, buffer_id, first, one_past_last, text);
|
||||||
|
}
|
||||||
|
global_history_edit_group_end(app);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
|
||||||
|
arena_release_all(&arena);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// BOTTOM
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
4coder_mirror.h - Types for the mirror buffer system.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(FCODER_MIRROR_H)
|
||||||
|
#define FCODER_MIRROR_H
|
||||||
|
|
||||||
|
struct Mirror_Range{
|
||||||
|
Buffer_ID source_buffer_id;
|
||||||
|
int32_t mirror_first;
|
||||||
|
int32_t source_first;
|
||||||
|
int32_t length;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
typedef int32_t Mirror_Mode;
|
||||||
|
enum{
|
||||||
|
MirrorMode_Constructing,
|
||||||
|
MirrorMode_Reflecting,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef uint32_t Mirror_Flags;
|
||||||
|
enum{
|
||||||
|
MirrorFlag_NoHighlight = 0x0,
|
||||||
|
MirrorFlag_CharacterRangeHighlight = 0x1,
|
||||||
|
MirrorFlag_LineRangeHighlight = 0x2,
|
||||||
|
MirrorFlag_UnusedHighlight = 0x3,
|
||||||
|
MirrorFlag_HighlightMask = 0x3,
|
||||||
|
MirrorFlag_NewlinesAreJumps = 0x4,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Mirror{
|
||||||
|
Buffer_ID mirror_buffer_id;
|
||||||
|
Mirror_Mode mode;
|
||||||
|
Mirror_Flags flags;
|
||||||
|
Managed_Scope mirror_scope;
|
||||||
|
int32_t count;
|
||||||
|
int32_t max;
|
||||||
|
Managed_Object source_buffer_ids;
|
||||||
|
Managed_Object mirror_ranges;
|
||||||
|
Managed_Object source_ranges;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Mirror_Hot{
|
||||||
|
int32_t count;
|
||||||
|
Buffer_ID *source_buffer_ids;
|
||||||
|
Marker *mirror_ranges;
|
||||||
|
Managed_Object *source_ranges;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
// The primary API for mirrors.
|
||||||
|
|
||||||
|
static bool32 mirror_init(Application_Links *app, Buffer_ID buffer, Mirror_Flags flags, Managed_Object *mirror_object_out);
|
||||||
|
static bool32 mirror_end(Application_Links *app, Managed_Object mirror);
|
||||||
|
static bool32 mirror_add_range(Application_Links *app, Managed_Object mirror, Buffer_ID source,
|
||||||
|
int32_t mirror_first, int32_t source_first, int32_t length);
|
||||||
|
static bool32 mirror_set_mode(Application_Links *app, Managed_Object mirror, Mirror_Mode mode);
|
||||||
|
static bool32 mirror_get_mode(Application_Links *app, Managed_Object mirror, Mirror_Mode *mode_out);
|
||||||
|
static bool32 mirror_set_flags(Application_Links *app, Managed_Object mirror, Mirror_Flags flags);
|
||||||
|
static bool32 mirror_get_flags(Application_Links *app, Managed_Object mirror, Mirror_Flags *flags_out);
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
// Extra helpers for mirrors (all implemented on the primary API)
|
||||||
|
|
||||||
|
static bool32 mirror_buffer_create(Application_Links *app, String buffer_name, Mirror_Flags flags, Buffer_ID *mirror_buffer_id_out);
|
||||||
|
static bool32 mirror_buffer_end(Application_Links *app, Buffer_ID mirror);
|
||||||
|
static bool32 mirror_buffer_add_range_exact(Application_Links *app, Buffer_ID mirror, Buffer_ID source,
|
||||||
|
int32_t mirror_first, int32_t source_first, int32_t length);
|
||||||
|
static bool32 mirror_buffer_add_range_loose(Application_Links *app, Buffer_ID mirror, Buffer_ID source,
|
||||||
|
int32_t mirror_first, int32_t source_first, int32_t max_length);
|
||||||
|
static bool32 mirror_buffer_insert_range(Application_Links *app, Buffer_ID mirror, Buffer_ID source,
|
||||||
|
int32_t mirror_insert_pos, int32_t source_first, int32_t length);
|
||||||
|
static bool32 mirror_buffer_set_mode(Application_Links *app, Buffer_ID mirror, Mirror_Mode mode);
|
||||||
|
static bool32 mirror_buffer_get_mode(Application_Links *app, Buffer_ID mirror, Mirror_Mode *mode_out);
|
||||||
|
static bool32 mirror_buffer_set_flags(Application_Links *app, Buffer_ID mirror, Mirror_Flags flags);
|
||||||
|
static bool32 mirror_buffer_get_flags(Application_Links *app, Buffer_ID mirror, Mirror_Flags *flags_out);
|
||||||
|
|
||||||
|
static bool32 mirror_buffer_refresh(Application_Links *app, Buffer_ID mirror);
|
||||||
|
|
||||||
|
static void mirror_quick_sort_mirror_ranges(Mirror_Range *ranges, int32_t first, int32_t one_past_last);
|
||||||
|
|
||||||
|
static bool32 mirror_buffer_add_range_exact_array(Application_Links *app, Buffer_ID mirror, Mirror_Range *ranges, int32_t count);
|
||||||
|
static bool32 mirror_buffer_add_range_loose_array(Application_Links *app, Buffer_ID mirror, Mirror_Range *ranges, int32_t count);
|
||||||
|
static bool32 mirror_buffer_insert_range_array(Application_Links *app, Buffer_ID mirror, Mirror_Range *ranges, int32_t count);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TOP
|
|
@ -577,18 +577,31 @@ buffered_print_flush(Application_Links *app, Partition *part, Temp_Memory temp,
|
||||||
}
|
}
|
||||||
|
|
||||||
static char*
|
static char*
|
||||||
buffered_memory_reserve(Application_Links *app, Partition *part, Temp_Memory temp, Buffer_Summary *output_buffer,
|
buffered_memory_reserve(Application_Links *app, Partition *part, Temp_Memory temp, Buffer_Summary *output_buffer, int32_t length, bool32 *did_flush){
|
||||||
int32_t length){
|
|
||||||
char *mem = push_array(part, char, length);
|
char *mem = push_array(part, char, length);
|
||||||
|
*did_flush = false;
|
||||||
if (mem == 0){
|
if (mem == 0){
|
||||||
buffered_print_flush(app, part, temp, output_buffer);
|
buffered_print_flush(app, part, temp, output_buffer);
|
||||||
end_temp_memory(temp);
|
end_temp_memory(temp);
|
||||||
mem = push_array(part, char, length);
|
mem = push_array(part, char, length);
|
||||||
|
*did_flush = true;
|
||||||
}
|
}
|
||||||
Assert(mem != 0);
|
Assert(mem != 0);
|
||||||
return(mem);
|
return(mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char*
|
||||||
|
buffered_memory_reserve(Application_Links *app, Partition *part, Temp_Memory temp, Buffer_Summary *output_buffer, int32_t length){
|
||||||
|
bool32 ignore;
|
||||||
|
return(buffered_memory_reserve(app, part, temp, output_buffer, length, &ignore));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t
|
||||||
|
buffered_print_buffer_length(Partition *part, Temp_Memory temp){
|
||||||
|
return(part->pos - temp.pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static void
|
static void
|
||||||
buffered_print_match_jump_line(Application_Links *app, Partition *part, Temp_Memory temp, Partition *line_part, Buffer_Summary *output_buffer,
|
buffered_print_match_jump_line(Application_Links *app, Partition *part, Temp_Memory temp, Partition *line_part, Buffer_Summary *output_buffer,
|
||||||
Buffer_Summary *match_buffer, Partial_Cursor word_pos){
|
Buffer_Summary *match_buffer, Partial_Cursor word_pos){
|
||||||
|
@ -622,14 +635,16 @@ buffered_print_match_jump_line(Application_Links *app, Partition *part, Temp_Mem
|
||||||
|
|
||||||
end_temp_memory(line_temp);
|
end_temp_memory(line_temp);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
static bool32
|
static bool32
|
||||||
search_buffer_edit_handler(Application_Links *app, Buffer_ID buffer_id, int32_t start, int32_t one_past_last, String text);
|
search_buffer_edit_handler(Application_Links *app, Buffer_ID buffer_id, int32_t start, int32_t one_past_last, String text);
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
list__parameters(Application_Links *app, Heap *heap, Partition *scratch,
|
list__parameters(Application_Links *app, Heap *heap, Partition *scratch, String *strings, int32_t count,
|
||||||
String *strings, int32_t count, Search_Range_Flag match_flags,
|
Search_Range_Flag match_flags, View_Summary default_target_view){
|
||||||
View_Summary default_target_view){
|
|
||||||
// Open the search buffer
|
// Open the search buffer
|
||||||
String search_name = make_lit_string("*search*");
|
String search_name = make_lit_string("*search*");
|
||||||
Buffer_ID search_buffer_id = create_or_switch_to_buffer_by_name(app, search_name.str, search_name.size, default_target_view);
|
Buffer_ID search_buffer_id = create_or_switch_to_buffer_by_name(app, search_name.str, search_name.size, default_target_view);
|
||||||
|
@ -637,6 +652,11 @@ list__parameters(Application_Links *app, Heap *heap, Partition *scratch,
|
||||||
|
|
||||||
// Setup the search buffer for 'init' mode - the history will begin only AFTER the buffer is filled
|
// Setup the search buffer for 'init' mode - the history will begin only AFTER the buffer is filled
|
||||||
buffer_set_setting(app, &search_buffer, BufferSetting_RecordsHistory, false);
|
buffer_set_setting(app, &search_buffer, BufferSetting_RecordsHistory, false);
|
||||||
|
{
|
||||||
|
mirror_buffer_end(app, search_buffer_id);
|
||||||
|
Managed_Object ignore = 0;
|
||||||
|
mirror_init(app, search_buffer_id, MirrorFlag_CharacterRangeHighlight|MirrorFlag_NewlinesAreJumps, &ignore);
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize a generic search all buffers
|
// Initialize a generic search all buffers
|
||||||
Search_Set set = {};
|
Search_Set set = {};
|
||||||
|
@ -645,7 +665,12 @@ list__parameters(Application_Links *app, Heap *heap, Partition *scratch,
|
||||||
|
|
||||||
// List all locations into search buffer
|
// List all locations into search buffer
|
||||||
Temp_Memory all_temp = begin_temp_memory(scratch);
|
Temp_Memory all_temp = begin_temp_memory(scratch);
|
||||||
|
|
||||||
Partition line_part = part_sub_part(scratch, (4 << 10));
|
Partition line_part = part_sub_part(scratch, (4 << 10));
|
||||||
|
int32_t mirror_range_count = 0;
|
||||||
|
int32_t mirror_range_max = (1 << 10);
|
||||||
|
Mirror_Range *mirror_ranges = push_array(scratch, Mirror_Range, mirror_range_max);
|
||||||
|
|
||||||
Temp_Memory temp = begin_temp_memory(scratch);
|
Temp_Memory temp = begin_temp_memory(scratch);
|
||||||
Buffer_ID prev_match_id = 0;
|
Buffer_ID prev_match_id = 0;
|
||||||
bool32 no_matches = true;
|
bool32 no_matches = true;
|
||||||
|
@ -661,7 +686,62 @@ list__parameters(Application_Links *app, Heap *heap, Partition *scratch,
|
||||||
}
|
}
|
||||||
prev_match_id = match.buffer.buffer_id;
|
prev_match_id = match.buffer.buffer_id;
|
||||||
}
|
}
|
||||||
buffered_print_match_jump_line(app, scratch, temp, &line_part, &search_buffer, &match.buffer, word_pos);
|
|
||||||
|
char *file_name = match.buffer.buffer_name;
|
||||||
|
int32_t file_len = match.buffer.buffer_name_len;
|
||||||
|
|
||||||
|
int32_t line_num_len = int_to_str_size(word_pos.line);
|
||||||
|
int32_t column_num_len = int_to_str_size(word_pos.character);
|
||||||
|
|
||||||
|
Temp_Memory line_temp = begin_temp_memory(&line_part);
|
||||||
|
Partial_Cursor line_start_cursor = {};
|
||||||
|
Partial_Cursor line_one_past_last_cursor = {};
|
||||||
|
String full_line_str = {};
|
||||||
|
if (read_line(app, &line_part, &match.buffer, word_pos.line, &full_line_str, &line_start_cursor, &line_one_past_last_cursor)){
|
||||||
|
int32_t source_full_line_start = line_start_cursor.pos;
|
||||||
|
String line_str = skip_chop_whitespace(full_line_str);
|
||||||
|
int32_t source_line_start = source_full_line_start + (int32_t)(line_str.str - full_line_str.str);
|
||||||
|
|
||||||
|
int32_t out_pos = search_buffer.size + buffered_print_buffer_length(scratch, temp);
|
||||||
|
|
||||||
|
if (mirror_range_count == mirror_range_max){
|
||||||
|
buffered_print_flush(app, scratch, temp, &search_buffer);
|
||||||
|
mirror_buffer_add_range_exact_array(app, search_buffer_id, mirror_ranges, mirror_range_count);
|
||||||
|
mirror_range_count = 0;
|
||||||
|
Assert(out_pos == search_buffer.size);
|
||||||
|
}
|
||||||
|
bool32 flushed = false;
|
||||||
|
int32_t str_len = file_len + 1 + line_num_len + 1 + column_num_len + 1 + 1 + line_str.size + 1;
|
||||||
|
char *spare = buffered_memory_reserve(app, scratch, temp, &search_buffer, str_len, &flushed);
|
||||||
|
if (flushed){
|
||||||
|
mirror_buffer_add_range_exact_array(app, search_buffer_id, mirror_ranges, mirror_range_count);
|
||||||
|
mirror_range_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
search_buffer = get_buffer(app, search_buffer_id, AccessAll);
|
||||||
|
String out_line = make_string_cap(spare, 0, str_len);
|
||||||
|
append_ss(&out_line, make_string(file_name, file_len));
|
||||||
|
append_s_char(&out_line, ':');
|
||||||
|
append_int_to_str(&out_line, word_pos.line);
|
||||||
|
append_s_char(&out_line, ':');
|
||||||
|
append_int_to_str(&out_line, word_pos.character);
|
||||||
|
append_s_char(&out_line, ':');
|
||||||
|
append_s_char(&out_line, ' ');
|
||||||
|
int32_t mirror_range_start = out_pos + out_line.size;
|
||||||
|
append_ss(&out_line, line_str);
|
||||||
|
append_s_char(&out_line, '\n');
|
||||||
|
Assert(out_line.size == str_len);
|
||||||
|
|
||||||
|
Assert(mirror_range_count < mirror_range_max);
|
||||||
|
Mirror_Range *mirror_range = &mirror_ranges[mirror_range_count];
|
||||||
|
mirror_range_count += 1;
|
||||||
|
mirror_range->source_buffer_id = match.buffer.buffer_id;
|
||||||
|
mirror_range->mirror_first = mirror_range_start;
|
||||||
|
mirror_range->source_first = source_line_start;
|
||||||
|
mirror_range->length = line_str.size;
|
||||||
|
}
|
||||||
|
end_temp_memory(line_temp);
|
||||||
|
|
||||||
no_matches = false;
|
no_matches = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -674,15 +754,21 @@ list__parameters(Application_Links *app, Heap *heap, Partition *scratch,
|
||||||
}
|
}
|
||||||
|
|
||||||
buffered_print_flush(app, scratch, temp, &search_buffer);
|
buffered_print_flush(app, scratch, temp, &search_buffer);
|
||||||
|
mirror_buffer_add_range_exact_array(app, search_buffer_id, mirror_ranges, mirror_range_count);
|
||||||
|
mirror_range_count = 0;
|
||||||
|
|
||||||
end_temp_memory(all_temp);
|
end_temp_memory(all_temp);
|
||||||
|
|
||||||
// Lock *search* as the jump buffer
|
// Lock *search* as the jump buffer
|
||||||
lock_jump_buffer(search_name.str, search_name.size);
|
lock_jump_buffer(search_name.str, search_name.size);
|
||||||
|
|
||||||
// Setup the search buffer for 'reference editing' mode
|
// Setup the search buffer for 'reflecting' mode
|
||||||
|
mirror_buffer_set_mode(app, search_buffer_id, MirrorMode_Reflecting);
|
||||||
buffer_set_setting(app, &search_buffer, BufferSetting_ReadOnly, false);
|
buffer_set_setting(app, &search_buffer, BufferSetting_ReadOnly, false);
|
||||||
buffer_set_setting(app, &search_buffer, BufferSetting_RecordsHistory, true);
|
buffer_set_setting(app, &search_buffer, BufferSetting_RecordsHistory, true);
|
||||||
|
#if 0
|
||||||
buffer_set_edit_handler(app, search_buffer_id, search_buffer_edit_handler);
|
buffer_set_edit_handler(app, search_buffer_id, search_buffer_edit_handler);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -63,15 +63,17 @@ buffer_quick_unsort_cursors(Cursor_With_Index *positions, i32 start, i32 pivot){
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
buffer_sort_cursors(Cursor_With_Index *positions, i32 count){
|
buffer_sort_cursors(Cursor_With_Index *positions, i32 count){
|
||||||
Assert(count > 0);
|
if (count > 0){
|
||||||
buffer_quick_sort_cursors(positions, 0, count - 1);
|
buffer_quick_sort_cursors(positions, 0, count - 1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
buffer_unsort_cursors(Cursor_With_Index *positions, i32 count){
|
buffer_unsort_cursors(Cursor_With_Index *positions, i32 count){
|
||||||
Assert(count > 0);
|
if (count > 0){
|
||||||
buffer_quick_unsort_cursors(positions, 0, count - 1);
|
buffer_quick_unsort_cursors(positions, 0, count - 1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
buffer_update_cursors(Cursor_With_Index *sorted_positions, i32 count, i32 start, i32 end, i32 len, b32 lean_right){
|
buffer_update_cursors(Cursor_With_Index *sorted_positions, i32 count, i32 start, i32 end, i32 len, b32 lean_right){
|
||||||
|
|
|
@ -163,6 +163,7 @@ edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, E
|
||||||
|
|
||||||
if (cursor_count > 0 || r_cursor_count > 0){
|
if (cursor_count > 0 || r_cursor_count > 0){
|
||||||
buffer_sort_cursors( cursors, cursor_count);
|
buffer_sort_cursors( cursors, cursor_count);
|
||||||
|
buffer_sort_cursors(r_cursors, r_cursor_count);
|
||||||
if (edits.count > 1){
|
if (edits.count > 1){
|
||||||
buffer_batch_edit_update_cursors( cursors, cursor_count, edits, false);
|
buffer_batch_edit_update_cursors( cursors, cursor_count, edits, false);
|
||||||
buffer_batch_edit_update_cursors(r_cursors, r_cursor_count, edits, true);
|
buffer_batch_edit_update_cursors(r_cursors, r_cursor_count, edits, true);
|
||||||
|
@ -173,6 +174,7 @@ edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, E
|
||||||
buffer_update_cursors(r_cursors, r_cursor_count, edit.range.first, edit.range.one_past_last, edit.length, true);
|
buffer_update_cursors(r_cursors, r_cursor_count, edit.range.first, edit.range.one_past_last, edit.length, true);
|
||||||
}
|
}
|
||||||
buffer_unsort_cursors( cursors, cursor_count);
|
buffer_unsort_cursors( cursors, cursor_count);
|
||||||
|
buffer_unsort_cursors(r_cursors, r_cursor_count);
|
||||||
|
|
||||||
cursor_count = 0;
|
cursor_count = 0;
|
||||||
r_cursor_count = 0;
|
r_cursor_count = 0;
|
||||||
|
|
Loading…
Reference in New Issue