From e231293acfff41e91da2885c8ab49c304ae66367 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sat, 29 Feb 2020 17:21:37 -0800 Subject: [PATCH] Checking global map in isearch and query_user_general so that basic global commands still work in that context --- custom/4coder_base_commands.cpp | 47 +- custom/4coder_events.h | 7 +- custom/4coder_helper.cpp | 3287 ++++++++++++++------------- custom/generated/command_metadata.h | 74 +- 4 files changed, 1719 insertions(+), 1696 deletions(-) diff --git a/custom/4coder_base_commands.cpp b/custom/4coder_base_commands.cpp index 57438b2e..445baf33 100644 --- a/custom/4coder_base_commands.cpp +++ b/custom/4coder_base_commands.cpp @@ -898,7 +898,8 @@ isearch(Application_Links *app, Scan_Direction start_scan, i64 first_pos, } isearch__update_highlight(app, view, Ii64_size(pos, match_size)); - in = get_next_input(app, EventPropertyGroup_AnyKeyboardEvent, + in = get_next_input(app, + EventPropertyGroup_Any, EventProperty_Escape|EventProperty_ViewActivation); if (in.abort){ break; @@ -942,9 +943,6 @@ isearch(Application_Links *app, Scan_Direction start_scan, i64 first_pos, } } - // TODO(allen): how to detect if the input corresponds to - // a search or rsearch command, a scroll wheel command? - b32 do_scan_action = false; b32 do_scroll_wheel = false; Scan_Direction change_scan = scan; @@ -954,17 +952,41 @@ isearch(Application_Links *app, Scan_Direction start_scan, i64 first_pos, change_scan = Scan_Forward; do_scan_action = true; } - if (match_key_code(&in, KeyCode_PageUp) || - match_key_code(&in, KeyCode_Up)){ + else if (match_key_code(&in, KeyCode_PageUp) || + match_key_code(&in, KeyCode_Up)){ change_scan = Scan_Backward; do_scan_action = true; } - -#if 0 - if (in.command == mouse_wheel_scroll){ - do_scroll_wheel = true; + else{ + // NOTE(allen): is the user trying to execute another command? + View_Context ctx = view_current_context(app, view); + Mapping *mapping = ctx.mapping; + Command_Map *map = mapping_get_map(mapping, ctx.map_id); + Command_Binding binding = map_get_binding_recursive(mapping, map, &in.event); + if (binding.custom != 0){ + if (binding.custom == search){ + change_scan = Scan_Forward; + do_scan_action = true; + } + else if (binding.custom == reverse_search){ + change_scan = Scan_Backward; + do_scan_action = true; + } + else{ + Command_Metadata *metadata = get_command_metadata(binding.custom); + if (metadata != 0){ + if (metadata->is_ui){ + view_enqueue_command_function(app, view, binding.custom); + break; + } + } + binding.custom(app); + } + } + else{ + leave_current_input_unhandled(app); + } } -#endif } if (string_change){ @@ -1017,9 +1039,6 @@ isearch(Application_Links *app, Scan_Direction start_scan, i64 first_pos, else if (do_scroll_wheel){ mouse_wheel_scroll(app); } - else{ - leave_current_input_unhandled(app); - } } view_disable_highlight_range(app, view); diff --git a/custom/4coder_events.h b/custom/4coder_events.h index 90086bd9..72562eac 100644 --- a/custom/4coder_events.h +++ b/custom/4coder_events.h @@ -132,14 +132,17 @@ enum{ EventPropertyGroup_AnyUserInput = EventPropertyGroup_AnyKeyboardEvent| EventPropertyGroup_AnyMouseEvent, - EventPropertyGroup_Any = - EventPropertyGroup_AnyUserInput| + EventPropertyGroup_AnyCore = EventProperty_Animate| EventProperty_ViewActivation| EventProperty_AnyFile| EventProperty_Startup| EventProperty_Exit| EventProperty_Clipboard| + EventProperty_Animate, + EventPropertyGroup_Any = + EventPropertyGroup_AnyUserInput| + EventPropertyGroup_AnyCore| EventProperty_CustomFunction, }; diff --git a/custom/4coder_helper.cpp b/custom/4coder_helper.cpp index 986397e2..e079780b 100644 --- a/custom/4coder_helper.cpp +++ b/custom/4coder_helper.cpp @@ -9,6 +9,30 @@ //////////////////////////////// +function i32 +get_command_id(Custom_Command_Function *func){ + i32 result = -1; + for (i32 i = 0; i < ArrayCount(fcoder_metacmd_table); i += 1){ + if (func == fcoder_metacmd_table[i].proc){ + result = i; + break; + } + } + return(result); +} + +function Command_Metadata* +get_command_metadata(Custom_Command_Function *func){ + Command_Metadata *result = 0; + i32 id = get_command_id(func); + if (id >= 0){ + result = &fcoder_metacmd_table[id]; + } + return(result); +} + +//////////////////////////////// + internal Token_Array get_token_array_from_buffer(Application_Links *app, Buffer_ID buffer){ Token_Array result = {}; @@ -612,318 +636,318 @@ boundary_token(Application_Links *app, Buffer_ID buffer, Side side, Scan_Directi }break; case Scan_Backward: - { - result = 0; + { + result = 0; if (tokens.count > 0){ - Token_Iterator_Array it = token_iterator_pos(0, &tokens, pos); - Token *token = token_it_read(&it); -if (token->kind == TokenBaseKind_Whitespace){ - token_it_dec_non_whitespace(&it); -token = token_it_read(&it); - } + Token_Iterator_Array it = token_iterator_pos(0, &tokens, pos); + Token *token = token_it_read(&it); + if (token->kind == TokenBaseKind_Whitespace){ + token_it_dec_non_whitespace(&it); + token = token_it_read(&it); + } if (token != 0){ - if (side == Side_Min){ - if (token->pos >= pos){ - token_it_dec_non_whitespace(&it); -token = token_it_read(&it); - } + if (side == Side_Min){ + if (token->pos >= pos){ + token_it_dec_non_whitespace(&it); + token = token_it_read(&it); + } result = token->pos; - } + } else{ - if (token->pos + token->size >= pos){ - token_it_dec_non_whitespace(&it); -token = token_it_read(&it); - } + if (token->pos + token->size >= pos){ + token_it_dec_non_whitespace(&it); + token = token_it_read(&it); + } result = token->pos + token->size; - } } } - }break; - } - } - return(result); + } + }break; + } + } + return(result); } - internal i64 +internal i64 boundary_line(Application_Links *app, Buffer_ID buffer, Side side, Scan_Direction direction, i64 pos){ - i64 line_number = get_line_number_from_pos(app, buffer, pos); - i64 new_pos = get_line_side_pos(app, buffer, line_number, side); - if (direction == Scan_Backward && new_pos >= pos){ - if (line_number > 1){ - new_pos = get_line_side_pos(app, buffer, line_number - 1, side); - } - else{ - new_pos = 0; - } - } - else if (direction == Scan_Forward && new_pos <= pos){ - new_pos = get_line_side_pos(app, buffer, line_number + 1, side); - if (new_pos <= pos){ - new_pos = (i32)buffer_get_size(app, buffer); - } + i64 line_number = get_line_number_from_pos(app, buffer, pos); + i64 new_pos = get_line_side_pos(app, buffer, line_number, side); + if (direction == Scan_Backward && new_pos >= pos){ + if (line_number > 1){ + new_pos = get_line_side_pos(app, buffer, line_number - 1, side); } + else{ + new_pos = 0; + } + } + else if (direction == Scan_Forward && new_pos <= pos){ + new_pos = get_line_side_pos(app, buffer, line_number + 1, side); + if (new_pos <= pos){ + new_pos = (i32)buffer_get_size(app, buffer); + } + } return(new_pos); } - - //////////////////////////////// + +//////////////////////////////// // TODO(allen): these need a little more rewrite internal void seek_string_forward(Application_Links *app, Buffer_ID buffer, i64 pos, i64 end, String_Const_u8 needle, i64 *result){ - if (end == 0){ - end = (i32)buffer_get_size(app, buffer); - } + if (end == 0){ + end = (i32)buffer_get_size(app, buffer); + } String_Match match = {}; -match.range.first = pos; - for (;;){ - match = buffer_seek_string(app, buffer, needle, Scan_Forward, (i32)match.range.first); - if (HasFlag(match.flags, StringMatch_CaseSensitive) || - match.buffer != buffer || match.range.first >= end) break; - } - if (match.range.first < end && match.buffer == buffer){ - *result = match.range.first; -} - else{ - *result = buffer_get_size(app, buffer); - } - } - - internal void -seek_string_backward(Application_Links *app, Buffer_ID buffer, i64 pos, i64 min, String_Const_u8 needle, i64 *result){ - String_Match match = {}; match.range.first = pos; - for (;;){ - match = buffer_seek_string(app, buffer, needle, Scan_Backward, match.range.first); - if (HasFlag(match.flags, StringMatch_CaseSensitive) || - match.buffer != buffer || match.range.first < min) break; - } - if (match.range.first >= min && match.buffer == buffer){ - *result = match.range.first; + for (;;){ + match = buffer_seek_string(app, buffer, needle, Scan_Forward, (i32)match.range.first); + if (HasFlag(match.flags, StringMatch_CaseSensitive) || + match.buffer != buffer || match.range.first >= end) break; + } + if (match.range.first < end && match.buffer == buffer){ + *result = match.range.first; + } + else{ + *result = buffer_get_size(app, buffer); + } } - else{ - *result = -1; - } - } - - internal void -seek_string_insensitive_forward(Application_Links *app, Buffer_ID buffer, i64 pos, i64 end, String_Const_u8 needle, i64 *result){ - if (end == 0){ - end = (i32)buffer_get_size(app, buffer); - } - String_Match match = buffer_seek_string(app, buffer, needle, Scan_Forward, pos); - if (match.range.first < end && match.buffer == buffer){ - *result = match.range.first; - } - else{ - *result = buffer_get_size(app, buffer); - } - } - internal void +internal void +seek_string_backward(Application_Links *app, Buffer_ID buffer, i64 pos, i64 min, String_Const_u8 needle, i64 *result){ + String_Match match = {}; + match.range.first = pos; + for (;;){ + match = buffer_seek_string(app, buffer, needle, Scan_Backward, match.range.first); + if (HasFlag(match.flags, StringMatch_CaseSensitive) || + match.buffer != buffer || match.range.first < min) break; + } + if (match.range.first >= min && match.buffer == buffer){ + *result = match.range.first; + } + else{ + *result = -1; + } +} + +internal void +seek_string_insensitive_forward(Application_Links *app, Buffer_ID buffer, i64 pos, i64 end, String_Const_u8 needle, i64 *result){ + if (end == 0){ + end = (i32)buffer_get_size(app, buffer); + } + String_Match match = buffer_seek_string(app, buffer, needle, Scan_Forward, pos); + if (match.range.first < end && match.buffer == buffer){ + *result = match.range.first; + } + else{ + *result = buffer_get_size(app, buffer); + } +} + +internal void seek_string_insensitive_backward(Application_Links *app, Buffer_ID buffer, i64 pos, i64 min, String_Const_u8 needle, i64 *result){ - String_Match match = buffer_seek_string(app, buffer, needle, Scan_Backward, pos); - if (match.range.first >= min && match.buffer == buffer){ - *result = match.range.first; - } - else{ - *result = -1; + String_Match match = buffer_seek_string(app, buffer, needle, Scan_Backward, pos); + if (match.range.first >= min && match.buffer == buffer){ + *result = match.range.first; } + else{ + *result = -1; } - - internal void - seek_string(Application_Links *app, Buffer_ID buffer_id, i64 pos, i64 end, i64 min, String_Const_u8 str, i64 *result, Buffer_Seek_String_Flags flags){ - switch (flags & 3){ - case 0: - { - seek_string_forward(app, buffer_id, pos, end, str, result); - }break; +} + +internal void +seek_string(Application_Links *app, Buffer_ID buffer_id, i64 pos, i64 end, i64 min, String_Const_u8 str, i64 *result, Buffer_Seek_String_Flags flags){ + switch (flags & 3){ + case 0: + { + seek_string_forward(app, buffer_id, pos, end, str, result); + }break; case BufferSeekString_Backward: - { - seek_string_backward(app, buffer_id, pos, min, str, result); -}break; - - case BufferSeekString_CaseInsensitive: { - seek_string_insensitive_forward(app, buffer_id, pos, end, str, result); - }break; - - case BufferSeekString_Backward|BufferSeekString_CaseInsensitive: + seek_string_backward(app, buffer_id, pos, min, str, result); + }break; + + case BufferSeekString_CaseInsensitive: { - seek_string_insensitive_backward(app, buffer_id, pos, min, str, result); - }break; - } - } - - //////////////////////////////// - + seek_string_insensitive_forward(app, buffer_id, pos, end, str, result); + }break; + + case BufferSeekString_Backward|BufferSeekString_CaseInsensitive: + { + seek_string_insensitive_backward(app, buffer_id, pos, min, str, result); + }break; + } +} + +//////////////////////////////// + internal Range_i64 get_line_range_from_pos_range(Application_Links *app, Buffer_ID buffer, Range_i64 pos_range){ - Range_i64 line_range = {}; - line_range.first = get_line_number_from_pos(app, buffer, pos_range.first); - if (line_range.first != 0){ - line_range.end = get_line_number_from_pos(app, buffer, pos_range.one_past_last); -if (line_range.end == 0){ - line_range.first = 0; - } - } - return(line_range); - } - - // NOTE(allen): The end of the returned range does not include the terminating newline character of + Range_i64 line_range = {}; + line_range.first = get_line_number_from_pos(app, buffer, pos_range.first); + if (line_range.first != 0){ + line_range.end = get_line_number_from_pos(app, buffer, pos_range.one_past_last); + if (line_range.end == 0){ + line_range.first = 0; + } + } + return(line_range); +} + +// NOTE(allen): The end of the returned range does not include the terminating newline character of // the last line. internal Range_i64 get_pos_range_from_line_range(Application_Links *app, Buffer_ID buffer, Range_i64 line_range){ - Range_i64 pos_range = {}; - if (is_valid_line_range(app, buffer, line_range)){ - pos_range.first = get_line_start_pos(app, buffer, line_range.first); -pos_range.one_past_last = get_line_end_pos(app, buffer, line_range.end); - } + Range_i64 pos_range = {}; + if (is_valid_line_range(app, buffer, line_range)){ + pos_range.first = get_line_start_pos(app, buffer, line_range.first); + pos_range.one_past_last = get_line_end_pos(app, buffer, line_range.end); + } return(pos_range); +} + +internal Range_i64 +enclose_boundary(Application_Links *app, Buffer_ID buffer, Range_i64 range, + Boundary_Function *func){ + i64 new_min = func(app, buffer, Side_Min, Scan_Backward, range.min + 1); + i64 new_min_check = func(app, buffer, Side_Max, Scan_Backward, range.min + 1); + if (new_min_check <= new_min && new_min < range.min){ + range.min = new_min; } - - internal Range_i64 - enclose_boundary(Application_Links *app, Buffer_ID buffer, Range_i64 range, -Boundary_Function *func){ - i64 new_min = func(app, buffer, Side_Min, Scan_Backward, range.min + 1); - i64 new_min_check = func(app, buffer, Side_Max, Scan_Backward, range.min + 1); - if (new_min_check <= new_min && new_min < range.min){ - range.min = new_min; - } - i64 new_max = func(app, buffer, Side_Max, Scan_Forward, range.max - 1); - i64 new_max_check = func(app, buffer, Side_Min, Scan_Forward, range.max); - if (new_max_check >= new_max && new_max > range.max){ - range.max = new_max; - } - return(range); - } - - internal Range_i64 - left_enclose_boundary(Application_Links *app, Buffer_ID buffer, Range_i64 range, -Boundary_Function *func){ - i64 new_min = func(app, buffer, Side_Min, Scan_Backward, range.min + 1); - i64 new_min_check = func(app, buffer, Side_Max, Scan_Backward, range.min + 1); - if (new_min_check <= new_min && new_min < range.min){ - range.min = new_min; - } - return(range); - } - - internal Range_i64 - right_enclose_boundary(Application_Links *app, Buffer_ID buffer, Range_i64 range, -Boundary_Function *func){ - i64 new_max = func(app, buffer, Side_Max, Scan_Forward, range.max - 1); - i64 new_max_check = func(app, buffer, Side_Min, Scan_Forward, range.max - 1); -if (new_max_check >= new_max && new_max > range.max){ - range.max = new_max; - } - return(range); - } - - internal Range_i64 - enclose_non_whitespace(Application_Links *app, Buffer_ID buffer, Range_i64 range){ -return(enclose_boundary(app, buffer, range, boundary_non_whitespace)); - } - internal Range_i64 + i64 new_max = func(app, buffer, Side_Max, Scan_Forward, range.max - 1); + i64 new_max_check = func(app, buffer, Side_Min, Scan_Forward, range.max); + if (new_max_check >= new_max && new_max > range.max){ + range.max = new_max; + } + return(range); +} + +internal Range_i64 +left_enclose_boundary(Application_Links *app, Buffer_ID buffer, Range_i64 range, + Boundary_Function *func){ + i64 new_min = func(app, buffer, Side_Min, Scan_Backward, range.min + 1); + i64 new_min_check = func(app, buffer, Side_Max, Scan_Backward, range.min + 1); + if (new_min_check <= new_min && new_min < range.min){ + range.min = new_min; + } + return(range); +} + +internal Range_i64 +right_enclose_boundary(Application_Links *app, Buffer_ID buffer, Range_i64 range, + Boundary_Function *func){ + i64 new_max = func(app, buffer, Side_Max, Scan_Forward, range.max - 1); + i64 new_max_check = func(app, buffer, Side_Min, Scan_Forward, range.max - 1); + if (new_max_check >= new_max && new_max > range.max){ + range.max = new_max; + } + return(range); +} + +internal Range_i64 +enclose_non_whitespace(Application_Links *app, Buffer_ID buffer, Range_i64 range){ + return(enclose_boundary(app, buffer, range, boundary_non_whitespace)); +} +internal Range_i64 enclose_pos_non_whitespace(Application_Links *app, Buffer_ID buffer, i64 pos){ - return(enclose_boundary(app, buffer, Ii64(pos), boundary_non_whitespace)); + return(enclose_boundary(app, buffer, Ii64(pos), boundary_non_whitespace)); } internal Range_i64 - enclose_tokens(Application_Links *app, Buffer_ID buffer, Range_i64 range){ - return(enclose_boundary(app, buffer, range, boundary_token)); - } - internal Range_i64 - enclose_pos_tokens(Application_Links *app, Buffer_ID buffer, i64 pos){ -return(enclose_boundary(app, buffer, Ii64(pos), boundary_token)); - } - - internal Range_i64 - enclose_base10(Application_Links *app, Buffer_ID buffer, Range_i64 range){ - return(enclose_boundary(app, buffer, range, boundary_base10)); - } - internal Range_i64 - enclose_pos_base10(Application_Links *app, Buffer_ID buffer, i64 pos){ -return(enclose_boundary(app, buffer, Ii64(pos), boundary_base10)); - } - - internal Range_i64 - enclose_base16(Application_Links *app, Buffer_ID buffer, Range_i64 range){ - return(enclose_boundary(app, buffer, range, boundary_base16)); - } - internal Range_i64 - enclose_pos_base16(Application_Links *app, Buffer_ID buffer, i64 pos){ -return(enclose_boundary(app, buffer, Ii64(pos), boundary_base16)); - } - - internal Range_i64 - enclose_base10_colon(Application_Links *app, Buffer_ID buffer, Range_i64 range){ - return(enclose_boundary(app, buffer, range, boundary_base10_colon)); - } - internal Range_i64 - enclose_pos_base10_colon(Application_Links *app, Buffer_ID buffer, i64 pos){ - return(enclose_boundary(app, buffer, Ii64(pos), boundary_base10_colon)); +enclose_tokens(Application_Links *app, Buffer_ID buffer, Range_i64 range){ + return(enclose_boundary(app, buffer, range, boundary_token)); +} +internal Range_i64 +enclose_pos_tokens(Application_Links *app, Buffer_ID buffer, i64 pos){ + return(enclose_boundary(app, buffer, Ii64(pos), boundary_token)); } internal Range_i64 - enclose_alpha_numeric(Application_Links *app, Buffer_ID buffer, Range_i64 range){ - return(enclose_boundary(app, buffer, range, boundary_alpha_numeric)); - } - internal Range_i64 - enclose_pos_alpha_numeric(Application_Links *app, Buffer_ID buffer, i64 pos){ - return(enclose_boundary(app, buffer, Ii64(pos), boundary_alpha_numeric)); +enclose_base10(Application_Links *app, Buffer_ID buffer, Range_i64 range){ + return(enclose_boundary(app, buffer, range, boundary_base10)); +} +internal Range_i64 +enclose_pos_base10(Application_Links *app, Buffer_ID buffer, i64 pos){ + return(enclose_boundary(app, buffer, Ii64(pos), boundary_base10)); } internal Range_i64 - enclose_alpha_numeric_unicode(Application_Links *app, Buffer_ID buffer, Range_i64 range){ - return(enclose_boundary(app, buffer, range, boundary_alpha_numeric_unicode)); +enclose_base16(Application_Links *app, Buffer_ID buffer, Range_i64 range){ + return(enclose_boundary(app, buffer, range, boundary_base16)); } - internal Range_i64 - enclose_pos_alpha_numeric_unicode(Application_Links *app, Buffer_ID buffer, i64 pos){ - return(enclose_boundary(app, buffer, Ii64(pos), boundary_alpha_numeric_unicode)); - } - - internal Range_i64 - enclose_alpha_numeric_underscore(Application_Links *app, Buffer_ID buffer, Range_i64 range){ - return(enclose_boundary(app, buffer, range, boundary_alpha_numeric_underscore)); - } - internal Range_i64 - enclose_pos_alpha_numeric_underscore(Application_Links *app, Buffer_ID buffer, i64 pos){ - return(enclose_boundary(app, buffer, Ii64(pos), boundary_alpha_numeric_underscore)); - } - internal Range_i64 - right_enclose_alpha_numeric_underscore(Application_Links *app, Buffer_ID buffer, - Range_i64 range){ - return(right_enclose_boundary(app, buffer, range, boundary_alpha_numeric_underscore)); - } - +internal Range_i64 +enclose_pos_base16(Application_Links *app, Buffer_ID buffer, i64 pos){ + return(enclose_boundary(app, buffer, Ii64(pos), boundary_base16)); +} + +internal Range_i64 +enclose_base10_colon(Application_Links *app, Buffer_ID buffer, Range_i64 range){ + return(enclose_boundary(app, buffer, range, boundary_base10_colon)); +} +internal Range_i64 +enclose_pos_base10_colon(Application_Links *app, Buffer_ID buffer, i64 pos){ + return(enclose_boundary(app, buffer, Ii64(pos), boundary_base10_colon)); +} + +internal Range_i64 +enclose_alpha_numeric(Application_Links *app, Buffer_ID buffer, Range_i64 range){ + return(enclose_boundary(app, buffer, range, boundary_alpha_numeric)); +} +internal Range_i64 +enclose_pos_alpha_numeric(Application_Links *app, Buffer_ID buffer, i64 pos){ + return(enclose_boundary(app, buffer, Ii64(pos), boundary_alpha_numeric)); +} + +internal Range_i64 +enclose_alpha_numeric_unicode(Application_Links *app, Buffer_ID buffer, Range_i64 range){ + return(enclose_boundary(app, buffer, range, boundary_alpha_numeric_unicode)); +} +internal Range_i64 +enclose_pos_alpha_numeric_unicode(Application_Links *app, Buffer_ID buffer, i64 pos){ + return(enclose_boundary(app, buffer, Ii64(pos), boundary_alpha_numeric_unicode)); +} + +internal Range_i64 +enclose_alpha_numeric_underscore(Application_Links *app, Buffer_ID buffer, Range_i64 range){ + return(enclose_boundary(app, buffer, range, boundary_alpha_numeric_underscore)); +} +internal Range_i64 +enclose_pos_alpha_numeric_underscore(Application_Links *app, Buffer_ID buffer, i64 pos){ + return(enclose_boundary(app, buffer, Ii64(pos), boundary_alpha_numeric_underscore)); +} +internal Range_i64 +right_enclose_alpha_numeric_underscore(Application_Links *app, Buffer_ID buffer, + Range_i64 range){ + return(right_enclose_boundary(app, buffer, range, boundary_alpha_numeric_underscore)); +} + internal Range_i64 enclose_alpha_numeric_underscore_utf8(Application_Links *app, Buffer_ID buffer, Range_i64 range){ -return(enclose_boundary(app, buffer, range, boundary_alpha_numeric_underscore_utf8)); + return(enclose_boundary(app, buffer, range, boundary_alpha_numeric_underscore_utf8)); } internal Range_i64 - enclose_pos_alpha_numeric_underscore_utf8(Application_Links *app, Buffer_ID buffer, i64 pos){ -return(enclose_boundary(app, buffer, Ii64(pos), boundary_alpha_numeric_underscore_utf8)); - } - internal Range_i64 - right_enclose_alpha_numeric_underscore_utf8(Application_Links *app, Buffer_ID buffer, - Range_i64 range){ -return(right_enclose_boundary(app, buffer, range, boundary_alpha_numeric_underscore_utf8)); - } +enclose_pos_alpha_numeric_underscore_utf8(Application_Links *app, Buffer_ID buffer, i64 pos){ + return(enclose_boundary(app, buffer, Ii64(pos), boundary_alpha_numeric_underscore_utf8)); +} +internal Range_i64 +right_enclose_alpha_numeric_underscore_utf8(Application_Links *app, Buffer_ID buffer, + Range_i64 range){ + return(right_enclose_boundary(app, buffer, range, boundary_alpha_numeric_underscore_utf8)); +} - internal Range_i64 +internal Range_i64 enclose_alpha_numeric_camel(Application_Links *app, Buffer_ID buffer, Range_i64 range){ -return(enclose_boundary(app, buffer, range, boundary_alpha_numeric_camel)); + return(enclose_boundary(app, buffer, range, boundary_alpha_numeric_camel)); } internal Range_i64 enclose_pos_alpha_numeric_camel(Application_Links *app, Buffer_ID buffer, i64 pos){ -return(enclose_boundary(app, buffer, Ii64(pos), boundary_alpha_numeric_camel)); + return(enclose_boundary(app, buffer, Ii64(pos), boundary_alpha_numeric_camel)); } internal Range_i64 enclose_pos_inside_quotes(Application_Links *app, Buffer_ID buffer, i64 pos){ - return(enclose_boundary(app, buffer, Ii64(pos), boundary_inside_quotes)); + return(enclose_boundary(app, buffer, Ii64(pos), boundary_inside_quotes)); } internal Range_i64 @@ -932,1544 +956,1521 @@ enclose_whole_lines(Application_Links *app, Buffer_ID buffer, Range_i64 range){ } internal Range_i64 enclose_pos_whole_lines(Application_Links *app, Buffer_ID buffer, i64 pos){ - return(enclose_boundary(app, buffer, Ii64(pos), boundary_line)); - } - - //////////////////////////////// - - internal Range_i64 - get_snipe_range(Application_Links *app, Boundary_Function_List funcs, Buffer_ID buffer, i64 pos, Scan_Direction direction){ - Range_i64 result = {}; - i64 buffer_size = buffer_get_size(app, buffer); + return(enclose_boundary(app, buffer, Ii64(pos), boundary_line)); +} + +//////////////////////////////// + +internal Range_i64 +get_snipe_range(Application_Links *app, Boundary_Function_List funcs, Buffer_ID buffer, i64 pos, Scan_Direction direction){ + Range_i64 result = {}; + i64 buffer_size = buffer_get_size(app, buffer); i64 pos0 = pos; i64 pos1 = scan(app, funcs, buffer, direction, pos0); -if (0 <= pos1 && pos1 <= buffer_size){ -i64 pos2 = scan(app, funcs, buffer, flip_direction(direction), pos1); - if (0 <= pos2 && pos2 <= buffer_size){ -if (direction == Scan_Backward){ - pos2 = clamp_bot(pos2, pos0); - } -else{ - pos2 = clamp_top(pos2, pos0); - } - result = Ii64(pos1, pos2); - } - } - return(result); - } - - internal Range_i64 - get_snipe_range(Application_Links *app, Boundary_Function *func, Buffer_ID buffer, i64 pos, Scan_Direction direction){ - Scratch_Block scratch(app); - return(get_snipe_range(app, push_boundary_list(scratch, func), buffer, pos, direction)); + if (0 <= pos1 && pos1 <= buffer_size){ + i64 pos2 = scan(app, funcs, buffer, flip_direction(direction), pos1); + if (0 <= pos2 && pos2 <= buffer_size){ + if (direction == Scan_Backward){ + pos2 = clamp_bot(pos2, pos0); + } + else{ + pos2 = clamp_top(pos2, pos0); + } + result = Ii64(pos1, pos2); } - - //////////////////////////////// + } + return(result); +} + +internal Range_i64 +get_snipe_range(Application_Links *app, Boundary_Function *func, Buffer_ID buffer, i64 pos, Scan_Direction direction){ + Scratch_Block scratch(app); + return(get_snipe_range(app, push_boundary_list(scratch, func), buffer, pos, direction)); +} + +//////////////////////////////// internal String_Const_u8 push_buffer_range(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range){ - String_Const_u8 result = {}; - i64 length = range_size(range); + String_Const_u8 result = {}; + i64 length = range_size(range); if (length > 0){ - Temp_Memory restore_point = begin_temp(arena); - u8 *memory = push_array(arena, u8, length); - if (buffer_read_range(app, buffer, range, memory)){ - result = SCu8(memory, length); - } - else{ - end_temp(restore_point); -} -} -return(result); + Temp_Memory restore_point = begin_temp(arena); + u8 *memory = push_array(arena, u8, length); + if (buffer_read_range(app, buffer, range, memory)){ + result = SCu8(memory, length); + } + else{ + end_temp(restore_point); + } + } + return(result); } internal String_Const_u8 - push_token_lexeme(Application_Links *app, Arena *arena, Buffer_ID buffer, Token *token){ - return(push_buffer_range(app, arena, buffer, Ii64(token))); - } - - internal String_Const_u8 - push_buffer_line(Application_Links *app, Arena *arena, Buffer_ID buffer, i64 line_number){ - return(push_buffer_range(app, arena, buffer, get_line_pos_range(app, buffer, line_number))); +push_token_lexeme(Application_Links *app, Arena *arena, Buffer_ID buffer, Token *token){ + return(push_buffer_range(app, arena, buffer, Ii64(token))); } internal String_Const_u8 - push_whole_buffer(Application_Links *app, Arena *arena, Buffer_ID buffer){ +push_buffer_line(Application_Links *app, Arena *arena, Buffer_ID buffer, i64 line_number){ + return(push_buffer_range(app, arena, buffer, get_line_pos_range(app, buffer, line_number))); +} + +internal String_Const_u8 +push_whole_buffer(Application_Links *app, Arena *arena, Buffer_ID buffer){ return(push_buffer_range(app, arena, buffer, buffer_range(app, buffer))); - } - - internal String_Const_u8 - push_view_range_string(Application_Links *app, Arena *arena, View_ID view){ - Buffer_ID buffer = view_get_buffer(app, view, Access_ReadVisible); - return(push_buffer_range(app, arena, buffer, get_view_range(app, view))); - } +} - internal String_Const_u8 - push_view_range_string(Application_Links *app, Arena *arena){ - View_ID view = get_active_view(app, Access_Always); -return(push_view_range_string(app, arena, view)); +internal String_Const_u8 +push_view_range_string(Application_Links *app, Arena *arena, View_ID view){ + Buffer_ID buffer = view_get_buffer(app, view, Access_ReadVisible); + return(push_buffer_range(app, arena, buffer, get_view_range(app, view))); +} + +internal String_Const_u8 +push_view_range_string(Application_Links *app, Arena *arena){ + View_ID view = get_active_view(app, Access_Always); + return(push_view_range_string(app, arena, view)); } internal String_Const_u8 push_enclose_range_at_pos(Application_Links *app, Arena *arena, Buffer_ID buffer, i64 pos, Enclose_Function *enclose){ - Range_i64 range = enclose(app, buffer, Ii64(pos)); + Range_i64 range = enclose(app, buffer, Ii64(pos)); return(push_buffer_range(app, arena, buffer, range)); - } +} //////////////////////////////// - - internal String_Const_u8 - token_it_lexeme(Application_Links *app, Arena *arena, Token_Iterator_Array *it){ - String_Const_u8 result = {}; - Token *token = token_it_read(it); -if (token != 0){ + +internal String_Const_u8 +token_it_lexeme(Application_Links *app, Arena *arena, Token_Iterator_Array *it){ + String_Const_u8 result = {}; + Token *token = token_it_read(it); + if (token != 0){ result = push_token_lexeme(app, arena, (Buffer_ID)it->user_id, token); - } -return(result); + } + return(result); } internal b32 token_it_check_and_get_lexeme(Application_Links *app, Arena *arena, Token_Iterator_Array *it, Token_Base_Kind kind, String_Const_u8 *lexeme_out){ - Token *token = token_it_read(it); + Token *token = token_it_read(it); b32 result = {}; if (token != 0 && token->kind == kind){ - result = true; - *lexeme_out = push_token_lexeme(app, arena, (Buffer_ID)it->user_id, token); + result = true; + *lexeme_out = push_token_lexeme(app, arena, (Buffer_ID)it->user_id, token); } -return(result); - } + return(result); +} - internal String_Const_u8 - token_it_lexeme(Application_Links *app, Arena *arena, Token_Iterator_List *it){ +internal String_Const_u8 +token_it_lexeme(Application_Links *app, Arena *arena, Token_Iterator_List *it){ String_Const_u8 result = {}; Token *token = token_it_read(it); -if (token != 0){ -result = push_token_lexeme(app, arena, (Buffer_ID)it->user_id, token); -} -return(result); + if (token != 0){ + result = push_token_lexeme(app, arena, (Buffer_ID)it->user_id, token); } - - internal b32 - token_it_check_and_get_lexeme(Application_Links *app, Arena *arena, Token_Iterator_List *it, Token_Base_Kind kind, String_Const_u8 *lexeme_out){ + return(result); +} + +internal b32 +token_it_check_and_get_lexeme(Application_Links *app, Arena *arena, Token_Iterator_List *it, Token_Base_Kind kind, String_Const_u8 *lexeme_out){ Token *token = token_it_read(it); b32 result = {}; if (token != 0 && token->kind == kind){ - result = true; - *lexeme_out = push_token_lexeme(app, arena, (Buffer_ID)it->user_id, token); - } - return(result); - } - - //////////////////////////////// - - internal b32 -buffer_has_name_with_star(Application_Links *app, Buffer_ID buffer){ - Scratch_Block scratch(app); -String_Const_u8 str = push_buffer_unique_name(app, scratch, buffer); - return(str.size > 0 && str.str[0] == '*'); + result = true; + *lexeme_out = push_token_lexeme(app, arena, (Buffer_ID)it->user_id, token); } - - internal u8 - buffer_get_char(Application_Links *app, Buffer_ID buffer_id, i64 pos){ - i64 buffer_size = buffer_get_size(app, buffer_id); - u8 result = ' '; - if (0 <= pos && pos < buffer_size){ + return(result); +} + +//////////////////////////////// + +internal b32 +buffer_has_name_with_star(Application_Links *app, Buffer_ID buffer){ + Scratch_Block scratch(app); + String_Const_u8 str = push_buffer_unique_name(app, scratch, buffer); + return(str.size > 0 && str.str[0] == '*'); +} + +internal u8 +buffer_get_char(Application_Links *app, Buffer_ID buffer_id, i64 pos){ + i64 buffer_size = buffer_get_size(app, buffer_id); + u8 result = ' '; + if (0 <= pos && pos < buffer_size){ buffer_read_range(app, buffer_id, Ii64(pos, pos + 1), &result); - } - return(result); + } + return(result); } internal b32 - line_is_valid_and_blank(Application_Links *app, Buffer_ID buffer, i64 line_number){ -b32 result = false; -if (is_valid_line(app, buffer, line_number)){ -Scratch_Block scratch(app); - String_Const_u8 line = push_buffer_line(app, scratch, buffer, line_number); - result = true; - for (u64 i = 0; i < line.size; i += 1){ - if (!character_is_whitespace(line.str[i])){ - result = false; - break; -} +line_is_valid_and_blank(Application_Links *app, Buffer_ID buffer, i64 line_number){ + b32 result = false; + if (is_valid_line(app, buffer, line_number)){ + Scratch_Block scratch(app); + String_Const_u8 line = push_buffer_line(app, scratch, buffer, line_number); + result = true; + for (u64 i = 0; i < line.size; i += 1){ + if (!character_is_whitespace(line.str[i])){ + result = false; + break; + } + } } - } - return(result); - } + return(result); +} - //////////////////////////////// - - internal i64 - get_pos_past_lead_whitespace_from_line_number(Application_Links *app, Buffer_ID buffer, i64 line_number){ +//////////////////////////////// + +internal i64 +get_pos_past_lead_whitespace_from_line_number(Application_Links *app, Buffer_ID buffer, i64 line_number){ Scratch_Block scratch(app); Range_i64 line_range = get_line_pos_range(app, buffer, line_number); -String_Const_u8 line = push_buffer_range(app, scratch, buffer, line_range); - i64 result = line_range.end; - for (u64 i = 0; i < line.size; i += 1){ - if (!character_is_whitespace(line.str[i])){ - result = line_range.start + i; -break; + String_Const_u8 line = push_buffer_range(app, scratch, buffer, line_range); + i64 result = line_range.end; + for (u64 i = 0; i < line.size; i += 1){ + if (!character_is_whitespace(line.str[i])){ + result = line_range.start + i; + break; } - } - return(result); - } - - internal i64 - get_pos_past_lead_whitespace(Application_Links *app, Buffer_ID buffer, i64 pos){ - i64 line_number = get_line_number_from_pos(app, buffer, pos); -i64 result = get_pos_past_lead_whitespace_from_line_number(app, buffer, line_number); -result = clamp_bot(pos, result); - return(result); - } - - internal void - move_past_lead_whitespace(Application_Links *app, View_ID view, Buffer_ID buffer){ - i64 pos = view_get_cursor_pos(app, view); - i64 new_pos = get_pos_past_lead_whitespace(app, buffer, pos); -view_set_cursor_and_preferred_x(app, view, seek_pos(new_pos)); - } - - internal void - move_past_lead_whitespace(Application_Links *app, View_ID view){ -Buffer_ID buffer = view_get_buffer(app, view, Access_ReadVisible); - move_past_lead_whitespace(app, view, buffer); } - -internal b32 -line_is_blank(Application_Links *app, Buffer_ID buffer, i64 line_number){ - Scratch_Block scratch(app); - String_Const_u8 line = push_buffer_line(app, scratch, buffer, line_number); - b32 is_blank = true; -for (u64 i = 0; i < line.size; i += 1){ - if (!character_is_whitespace(line.str[i])){ - is_blank = false; - break; - } - } - return(is_blank); - } - - internal i64 -get_line_number_of__whitespace_status_line(Application_Links *app, Buffer_ID buffer, Scan_Direction direction, i64 line_number_start, b32 get_blank_line){ -i64 line_count = buffer_get_line_count(app, buffer); - i64 line_number = line_number_start + direction; - for (;1 <= line_number && line_number <= line_count; line_number += direction){ -b32 is_blank = line_is_blank(app, buffer, line_number); -if (is_blank == get_blank_line){ - break; - } - } - line_number = clamp(1, line_number, line_count); - return(line_number); - } - - internal i64 - get_line_number_of_non_blank_line(Application_Links *app, Buffer_ID buffer, Scan_Direction direction, i64 line_number_start){ - return(get_line_number_of__whitespace_status_line(app, buffer, direction, line_number_start, false)); + return(result); } internal i64 - get_line_number_of_blank_line(Application_Links *app, Buffer_ID buffer, Scan_Direction direction, i64 line_number_start){ - return(get_line_number_of__whitespace_status_line(app, buffer, direction, line_number_start, true)); - } - - internal i64 - get_pos_of_blank_line(Application_Links *app, Buffer_ID buffer, Scan_Direction direction, i64 pos_start){ - i64 line_number_start = get_line_number_from_pos(app, buffer, pos_start); - i64 blank_line = get_line_number_of_blank_line(app, buffer, direction, line_number_start); - i64 pos = get_line_start_pos(app, buffer, blank_line); +get_pos_past_lead_whitespace(Application_Links *app, Buffer_ID buffer, i64 pos){ + i64 line_number = get_line_number_from_pos(app, buffer, pos); + i64 result = get_pos_past_lead_whitespace_from_line_number(app, buffer, line_number); + result = clamp_bot(pos, result); + return(result); +} + +internal void +move_past_lead_whitespace(Application_Links *app, View_ID view, Buffer_ID buffer){ + i64 pos = view_get_cursor_pos(app, view); + i64 new_pos = get_pos_past_lead_whitespace(app, buffer, pos); + view_set_cursor_and_preferred_x(app, view, seek_pos(new_pos)); +} + +internal void +move_past_lead_whitespace(Application_Links *app, View_ID view){ + Buffer_ID buffer = view_get_buffer(app, view, Access_ReadVisible); + move_past_lead_whitespace(app, view, buffer); +} + +internal b32 +line_is_blank(Application_Links *app, Buffer_ID buffer, i64 line_number){ + Scratch_Block scratch(app); + String_Const_u8 line = push_buffer_line(app, scratch, buffer, line_number); + b32 is_blank = true; + for (u64 i = 0; i < line.size; i += 1){ + if (!character_is_whitespace(line.str[i])){ + is_blank = false; + break; + } + } + return(is_blank); +} + +internal i64 +get_line_number_of__whitespace_status_line(Application_Links *app, Buffer_ID buffer, Scan_Direction direction, i64 line_number_start, b32 get_blank_line){ + i64 line_count = buffer_get_line_count(app, buffer); + i64 line_number = line_number_start + direction; + for (;1 <= line_number && line_number <= line_count; line_number += direction){ + b32 is_blank = line_is_blank(app, buffer, line_number); + if (is_blank == get_blank_line){ + break; + } + } + line_number = clamp(1, line_number, line_count); + return(line_number); +} + +internal i64 +get_line_number_of_non_blank_line(Application_Links *app, Buffer_ID buffer, Scan_Direction direction, i64 line_number_start){ + return(get_line_number_of__whitespace_status_line(app, buffer, direction, line_number_start, false)); +} + +internal i64 +get_line_number_of_blank_line(Application_Links *app, Buffer_ID buffer, Scan_Direction direction, i64 line_number_start){ + return(get_line_number_of__whitespace_status_line(app, buffer, direction, line_number_start, true)); +} + +internal i64 +get_pos_of_blank_line(Application_Links *app, Buffer_ID buffer, Scan_Direction direction, i64 pos_start){ + i64 line_number_start = get_line_number_from_pos(app, buffer, pos_start); + i64 blank_line = get_line_number_of_blank_line(app, buffer, direction, line_number_start); + i64 pos = get_line_start_pos(app, buffer, blank_line); return(pos); } - internal i64 - get_line_number_of_blank_line_grouped(Application_Links *app, Buffer_ID buffer, Scan_Direction direction, i64 line_number_start){ - i64 line_number = line_number_start; +internal i64 +get_line_number_of_blank_line_grouped(Application_Links *app, Buffer_ID buffer, Scan_Direction direction, i64 line_number_start){ + i64 line_number = line_number_start; if (line_is_blank(app, buffer, line_number)){ - line_number = get_line_number_of_non_blank_line(app, buffer, direction, line_number); - } + line_number = get_line_number_of_non_blank_line(app, buffer, direction, line_number); + } line_number = get_line_number_of_blank_line(app, buffer, direction, line_number); return(line_number); - } - - internal i64 - get_pos_of_blank_line_grouped(Application_Links *app, Buffer_ID buffer, Scan_Direction direction, i64 pos_start){ -i64 line_number_start = get_line_number_from_pos(app, buffer, pos_start); - i64 blank_line = get_line_number_of_blank_line_grouped(app, buffer, direction, line_number_start); - i64 pos = get_line_start_pos(app, buffer, blank_line); - return(pos); - } - - internal Indent_Info - get_indent_info_range(Application_Links *app, Buffer_ID buffer, Range_i64 range, i32 tab_width){ - Scratch_Block scratch(app); - String_Const_u8 s = push_buffer_range(app, scratch, buffer, range); +} - Indent_Info info = {}; -info.first_char_pos = range.end; +internal i64 +get_pos_of_blank_line_grouped(Application_Links *app, Buffer_ID buffer, Scan_Direction direction, i64 pos_start){ + i64 line_number_start = get_line_number_from_pos(app, buffer, pos_start); + i64 blank_line = get_line_number_of_blank_line_grouped(app, buffer, direction, line_number_start); + i64 pos = get_line_start_pos(app, buffer, blank_line); + return(pos); +} + +internal Indent_Info +get_indent_info_range(Application_Links *app, Buffer_ID buffer, Range_i64 range, i32 tab_width){ + Scratch_Block scratch(app); + String_Const_u8 s = push_buffer_range(app, scratch, buffer, range); + + Indent_Info info = {}; + info.first_char_pos = range.end; info.is_blank = true; info.all_space = true; - - for (u64 i = 0; i < s.size; i += 1){ - u8 c = s.str[i]; - if (!character_is_whitespace(c)){ - info.is_blank = false; - info.all_space = false; -info.first_char_pos = range.start + (i64)i; - break; + + for (u64 i = 0; i < s.size; i += 1){ + u8 c = s.str[i]; + if (!character_is_whitespace(c)){ + info.is_blank = false; + info.all_space = false; + info.first_char_pos = range.start + (i64)i; + break; + } + if (c == ' '){ + info.indent_pos += 1; + } + else{ + info.all_space = false; + } + if (c == '\t'){ + info.indent_pos += tab_width; + } } - if (c == ' '){ - info.indent_pos += 1; - } - else{ -info.all_space = false; -} -if (c == '\t'){ - info.indent_pos += tab_width; - } - } return(info); - } - - internal Indent_Info - get_indent_info_line_number_and_start(Application_Links *app, Buffer_ID buffer, i64 line_number, i64 line_start, i32 tab_width){ - i64 end = get_line_side_pos(app, buffer, line_number, Side_Max); -return(get_indent_info_range(app, buffer, Ii64(line_start, end), tab_width)); - } - - //////////////////////////////// - - internal History_Group - history_group_begin(Application_Links *app, Buffer_ID buffer){ - History_Group group = {}; - group.app = app; - group.buffer = buffer; - group.first = buffer_history_get_current_state_index(app, buffer); - group.first += 1; - return(group); - } - - internal void - history_group_end(History_Group group){ - History_Record_Index last = buffer_history_get_current_state_index(group.app, group.buffer); - if (group.first < last){ - buffer_history_merge_record_range(group.app, group.buffer, group.first, last, RecordMergeFlag_StateInRange_MoveStateForward); } + +internal Indent_Info +get_indent_info_line_number_and_start(Application_Links *app, Buffer_ID buffer, i64 line_number, i64 line_start, i32 tab_width){ + i64 end = get_line_side_pos(app, buffer, line_number, Side_Max); + return(get_indent_info_range(app, buffer, Ii64(line_start, end), tab_width)); +} + +//////////////////////////////// + +internal History_Group +history_group_begin(Application_Links *app, Buffer_ID buffer){ + History_Group group = {}; + group.app = app; + group.buffer = buffer; + group.first = buffer_history_get_current_state_index(app, buffer); + group.first += 1; + return(group); +} + +internal void +history_group_end(History_Group group){ + History_Record_Index last = buffer_history_get_current_state_index(group.app, group.buffer); + if (group.first < last){ + buffer_history_merge_record_range(group.app, group.buffer, group.first, last, RecordMergeFlag_StateInRange_MoveStateForward); + } } //////////////////////////////// internal void - replace_in_range(Application_Links *app, Buffer_ID buffer, Range_i64 range, String_Const_u8 needle, String_Const_u8 string){ +replace_in_range(Application_Links *app, Buffer_ID buffer, Range_i64 range, String_Const_u8 needle, String_Const_u8 string){ // TODO(allen): rewrite History_Group group = history_group_begin(app, buffer); i64 pos = range.min - 1; i64 new_pos = 0; - seek_string_forward(app, buffer, pos, range.end, needle, &new_pos); - i64 shift = replace_range_shift(needle.size, string.size); - for (; new_pos + (i64)needle.size <= range.end;){ - Range_i64 needle_range = Ii64(new_pos, new_pos + (i32)needle.size); - buffer_replace_range(app, buffer, needle_range, string); - range.end += shift; -pos = new_pos + (i32)string.size - 1; - seek_string_forward(app, buffer, pos, range.end, needle, &new_pos); - } - history_group_end(group); + seek_string_forward(app, buffer, pos, range.end, needle, &new_pos); + i64 shift = replace_range_shift(needle.size, string.size); + for (; new_pos + (i64)needle.size <= range.end;){ + Range_i64 needle_range = Ii64(new_pos, new_pos + (i32)needle.size); + buffer_replace_range(app, buffer, needle_range, string); + range.end += shift; + pos = new_pos + (i32)string.size - 1; + seek_string_forward(app, buffer, pos, range.end, needle, &new_pos); + } + history_group_end(group); } - - internal Range_i64 - swap_lines(Application_Links *app, Buffer_ID buffer, i64 line_1, i64 line_2){ -Range_i64 result = {}; -i64 line_count = buffer_get_line_count(app, buffer); - if (1 <= line_1 && line_2 <= line_count){ - Range_i64 range_1 = get_line_pos_range(app, buffer, line_1); - Range_i64 range_2 = get_line_pos_range(app, buffer, line_2); - - Scratch_Block scratch(app); - - String_Const_u8 text_1 = push_buffer_range(app, scratch, buffer, range_1); + +internal Range_i64 +swap_lines(Application_Links *app, Buffer_ID buffer, i64 line_1, i64 line_2){ + Range_i64 result = {}; + i64 line_count = buffer_get_line_count(app, buffer); + if (1 <= line_1 && line_2 <= line_count){ + Range_i64 range_1 = get_line_pos_range(app, buffer, line_1); + Range_i64 range_2 = get_line_pos_range(app, buffer, line_2); + + Scratch_Block scratch(app); + + String_Const_u8 text_1 = push_buffer_range(app, scratch, buffer, range_1); String_Const_u8 text_2 = push_buffer_range(app, scratch, buffer, range_2); History_Group group = history_group_begin(app, buffer); - buffer_replace_range(app, buffer, range_2, text_1); -buffer_replace_range(app, buffer, range_1, text_2); - history_group_end(group); - -i64 shift = replace_range_shift(range_1, text_2.size); - result.min = range_1.min; -result.max = range_2.min + shift; - } - return(result); -} - - internal i64 - move_line(Application_Links *app, Buffer_ID buffer, i64 line_number, Scan_Direction direction){ - i64 line_1 = 0; - i64 line_2 = 0; - if (direction == Scan_Forward){ - line_1 = line_number; -line_2 = line_number + 1; - } - else{ - line_1 = line_number - 1; - line_2 = line_number; - } - Range_i64 line_starts = swap_lines(app, buffer, line_1, line_2); - i64 result = 0; - if (line_starts.min < line_starts.max){ - if (direction == Scan_Forward){ - result = line_starts.max; - } - else{ - result = line_starts.min; - } - } - else{ - result = get_line_side_pos(app, buffer, line_number, Side_Min); - } - return(result); - } + buffer_replace_range(app, buffer, range_2, text_1); + buffer_replace_range(app, buffer, range_1, text_2); + history_group_end(group); - internal void - clear_buffer(Application_Links *app, Buffer_ID buffer){ - buffer_replace_range(app, buffer, buffer_range(app, buffer), string_u8_litexpr("")); - } - - //////////////////////////////// - - internal String_Match_List - find_all_matches_all_buffers(Application_Links *app, Arena *arena, String_Const_u8_Array match_patterns, String_Match_Flag must_have_flags, String_Match_Flag must_not_have_flags){ - String_Match_List all_matches = {}; -for (Buffer_ID buffer = get_buffer_next(app, 0, Access_Always); - buffer != 0; - buffer = get_buffer_next(app, buffer, Access_Always)){ -String_Match_List buffer_matches = {}; - for (i32 i = 0; i < match_patterns.count; i += 1){ - Range_i64 range = buffer_range(app, buffer); - String_Match_List pattern_matches = buffer_find_all_matches(app, arena, buffer, i, range, match_patterns.vals[i], - &character_predicate_alpha_numeric_underscore_utf8, Scan_Forward); - string_match_list_filter_flags(&pattern_matches, must_have_flags, must_not_have_flags); -if (pattern_matches.count > 0){ -if (buffer_matches.count == 0){ - buffer_matches = pattern_matches; - } - else{ -buffer_matches = string_match_list_merge_front_to_back(&buffer_matches, &pattern_matches); -} -} -} -all_matches = string_match_list_join(&all_matches, &buffer_matches); - } - return(all_matches); + i64 shift = replace_range_shift(range_1, text_2.size); + result.min = range_1.min; + result.max = range_2.min + shift; } - - internal String_Match_List - find_all_matches_all_buffers(Application_Links *app, Arena *arena, String_Const_u8 pattern, String_Match_Flag must_have_flags, String_Match_Flag must_not_have_flags){ - String_Const_u8_Array array = {&pattern, 1}; - return(find_all_matches_all_buffers(app, arena, array, must_have_flags, must_not_have_flags)); - } + return(result); +} + +internal i64 +move_line(Application_Links *app, Buffer_ID buffer, i64 line_number, Scan_Direction direction){ + i64 line_1 = 0; + i64 line_2 = 0; + if (direction == Scan_Forward){ + line_1 = line_number; + line_2 = line_number + 1; + } + else{ + line_1 = line_number - 1; + line_2 = line_number; + } + Range_i64 line_starts = swap_lines(app, buffer, line_1, line_2); + i64 result = 0; + if (line_starts.min < line_starts.max){ + if (direction == Scan_Forward){ + result = line_starts.max; + } + else{ + result = line_starts.min; + } + } + else{ + result = get_line_side_pos(app, buffer, line_number, Side_Min); + } + return(result); +} + +internal void +clear_buffer(Application_Links *app, Buffer_ID buffer){ + buffer_replace_range(app, buffer, buffer_range(app, buffer), string_u8_litexpr("")); +} //////////////////////////////// - - internal b32 - is_modified(User_Input *input){ - return(is_modified(&input->event)); - } - - internal String_Const_u8 - to_writable(User_Input *in){ - return(to_writable(&in->event)); - } - - internal b32 - has_modifier(User_Input *in, Key_Code key_code){ - b32 result = false; - Input_Modifier_Set *mods = get_modifiers(&in->event); - if (mods != 0){ - result = has_modifier(mods, key_code); + +internal String_Match_List +find_all_matches_all_buffers(Application_Links *app, Arena *arena, String_Const_u8_Array match_patterns, String_Match_Flag must_have_flags, String_Match_Flag must_not_have_flags){ + String_Match_List all_matches = {}; + for (Buffer_ID buffer = get_buffer_next(app, 0, Access_Always); + buffer != 0; + buffer = get_buffer_next(app, buffer, Access_Always)){ + String_Match_List buffer_matches = {}; + for (i32 i = 0; i < match_patterns.count; i += 1){ + Range_i64 range = buffer_range(app, buffer); + String_Match_List pattern_matches = buffer_find_all_matches(app, arena, buffer, i, range, match_patterns.vals[i], + &character_predicate_alpha_numeric_underscore_utf8, Scan_Forward); + string_match_list_filter_flags(&pattern_matches, must_have_flags, must_not_have_flags); + if (pattern_matches.count > 0){ + if (buffer_matches.count == 0){ + buffer_matches = pattern_matches; + } + else{ + buffer_matches = string_match_list_merge_front_to_back(&buffer_matches, &pattern_matches); + } + } } - return(result); - } - - internal b32 - match_key_code(User_Input *in, Key_Code key_code){ - return(match_key_code(&in->event, key_code)); + all_matches = string_match_list_join(&all_matches, &buffer_matches); } - + return(all_matches); +} + +internal String_Match_List +find_all_matches_all_buffers(Application_Links *app, Arena *arena, String_Const_u8 pattern, String_Match_Flag must_have_flags, String_Match_Flag must_not_have_flags){ + String_Const_u8_Array array = {&pattern, 1}; + return(find_all_matches_all_buffers(app, arena, array, must_have_flags, must_not_have_flags)); +} + +//////////////////////////////// + +internal b32 +is_modified(User_Input *input){ + return(is_modified(&input->event)); +} + +internal String_Const_u8 +to_writable(User_Input *in){ + return(to_writable(&in->event)); +} + +internal b32 +has_modifier(User_Input *in, Key_Code key_code){ + b32 result = false; + Input_Modifier_Set *mods = get_modifiers(&in->event); + if (mods != 0){ + result = has_modifier(mods, key_code); + } + return(result); +} + +internal b32 +match_key_code(User_Input *in, Key_Code key_code){ + return(match_key_code(&in->event, key_code)); +} + internal b32 match_core_code(User_Input *in, Key_Code core_code){ -return(match_core_code(&in->event, core_code)); + return(match_core_code(&in->event, core_code)); } internal String_Const_u8 backspace_utf8(String_Const_u8 string){ - if (string.size > 0){ -u64 i = string.size - 1; - for (; i > 0; --i){ - if (string.str[i] <= 0x7F || string.str[i] >= 0xC0){ - break; - } - } - string.size = i; + if (string.size > 0){ + u64 i = string.size - 1; + for (; i > 0; --i){ + if (string.str[i] <= 0x7F || string.str[i] >= 0xC0){ + break; + } + } + string.size = i; } return(string); - } - - //////////////////////////////// - -Query_Bar_Group::Query_Bar_Group(Application_Links *app){ - this->app = app; - this->view = get_active_view(app, Access_Always); -} - -Query_Bar_Group::Query_Bar_Group(Application_Links *app, View_ID view){ - this->app = app; - this->view = view; -} - -Query_Bar_Group::~Query_Bar_Group(){ -clear_all_query_bars(this->app, this->view); - } - - internal b32 - query_user_general(Application_Links *app, Query_Bar *bar, b32 force_number, String_Const_u8 init_string){ -// NOTE(allen|a3.4.4): It will not cause an *error* if we continue on after failing to. -// start a query bar, but it will be unusual behavior from the point of view of the - // user, if this command starts intercepting input even though no prompt is shown. -// This will only happen if you have a lot of bars open already or if the current view - // doesn't support query bars. - if (start_query_bar(app, bar, 0) == 0){ - return(false); - } - - if (init_string.size > 0){ - String_u8 string = Su8(bar->string.str, bar->string.size, bar->string_capacity); - string_append(&string, init_string); - bar->string.size = string.string.size; - } - - b32 success = true; - - for (;;){ - // NOTE(allen|a3.4.4): This call will block until the user does one of the input -// types specified in the flags. The first set of flags are inputs you'd like to - // intercept that you don't want to abort on. The second set are inputs that - // you'd like to cause the command to abort. If an event satisfies both flags, it -// is treated as an abort. - User_Input in = get_next_input(app, EventPropertyGroup_AnyKeyboardEvent, - EventProperty_Escape|EventProperty_MouseButton); - - // NOTE(allen|a3.4.4): The responsible thing to do on abort is to end the command - // without waiting on get_next_input again. -if (in.abort){ -success = false; - break; - } - - Scratch_Block scratch(app); - b32 good_insert = false; -String_Const_u8 insert_string = to_writable(&in); - if (insert_string.str != 0 && insert_string.size > 0){ - insert_string = string_replace(scratch, insert_string, - string_u8_litexpr("\n"), - string_u8_litexpr("")); - insert_string = string_replace(scratch, insert_string, - string_u8_litexpr("\t"), - string_u8_litexpr("")); - if (force_number){ -if (string_is_integer(insert_string, 10)){ - good_insert = true; - } - } - else{ - good_insert = true; - } -} - -// NOTE(allen|a3.4.4): All we have to do to update the query bar is edit our - // local Query_Bar struct! This is handy because it means our Query_Bar - // is always correct for typical use without extra work updating the bar. - if (in.event.kind == InputEventKind_KeyStroke && - (in.event.key.code == KeyCode_Return || in.event.key.code == KeyCode_Tab)){ - break; - } - else if (in.event.kind == InputEventKind_KeyStroke && - in.event.key.code == KeyCode_Backspace){ - bar->string = backspace_utf8(bar->string); - } - else if (good_insert){ - String_u8 string = Su8(bar->string.str, bar->string.size, bar->string_capacity); - string_append(&string, insert_string); - bar->string.size = string.string.size; - } - else{ - leave_current_input_unhandled(app); - } - } - - return(success); - } - - internal b32 - query_user_string(Application_Links *app, Query_Bar *bar){ - return(query_user_general(app, bar, false, string_u8_empty)); - } - - internal b32 - query_user_number(Application_Links *app, Query_Bar *bar){ -return(query_user_general(app, bar, true, string_u8_empty)); - } - - internal b32 - query_user_number(Application_Links *app, Query_Bar *bar, i32 x){ - Scratch_Block scratch(app); - String_Const_u8 string = push_u8_stringf(scratch, "%d", x); - return(query_user_general(app, bar, true, string)); - } - - //////////////////////////////// - - internal Buffer_Identifier - buffer_identifier(char *str, i32 len){ - Buffer_Identifier identifier; - identifier.name = str; - identifier.name_len = len; - identifier.id = 0; - return(identifier); - } - - internal Buffer_Identifier - buffer_identifier(String_Const_u8 str){ - return(buffer_identifier((char*)str.str, (i32)str.size)); - } - - internal Buffer_Identifier - buffer_identifier(Buffer_ID id){ - Buffer_Identifier identifier; - identifier.name = 0; -identifier.name_len = 0; -identifier.id = id; -return(identifier); - } - - internal Buffer_ID - buffer_identifier_to_id(Application_Links *app, Buffer_Identifier identifier){ -Buffer_ID id = 0; - if (identifier.id != 0){ -id = identifier.id; - } - else{ - String_Const_u8 name = SCu8(identifier.name, identifier.name_len); - id = get_buffer_by_name(app, name, Access_Always); - if (id == 0){ - id = get_buffer_by_file_name(app, name, Access_Always); - } - } - return(id); - } - - internal Buffer_ID - buffer_identifier_to_id_create_out_buffer(Application_Links *app, Buffer_Identifier buffer_id){ - Buffer_ID result = 0; - if (buffer_id.name != 0 && buffer_id.name_len > 0){ - String_Const_u8 buffer_name = SCu8(buffer_id.name, buffer_id.name_len); - Buffer_ID buffer_attach_id = get_buffer_by_name(app, buffer_name, Access_Always); - if (buffer_attach_id != 0){ - result = buffer_attach_id; - } -else{ -buffer_attach_id = create_buffer(app, buffer_name, BufferCreate_AlwaysNew|BufferCreate_NeverAttachToFile); -if (buffer_attach_id != 0){ -buffer_set_setting(app, buffer_attach_id, BufferSetting_ReadOnly, true); - buffer_set_setting(app, buffer_attach_id, BufferSetting_Unimportant, true); - result = buffer_attach_id; -} -} -} -else{ -result = buffer_id.id; - } - return(result); - } - - //////////////////////////////// - - function void -place_begin_and_end_on_own_lines(Application_Links *app, char *begin, char *end){ - View_ID view = get_active_view(app, Access_ReadWriteVisible); - Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible); - - Range_i64 range = get_view_range(app, view); - Range_i64 lines = get_line_range_from_pos_range(app, buffer, range); - range = get_pos_range_from_line_range(app, buffer, lines); - -Scratch_Block scratch(app); - - b32 min_line_blank = line_is_valid_and_blank(app, buffer, lines.min); - b32 max_line_blank = line_is_valid_and_blank(app, buffer, lines.max); - - if ((lines.min < lines.max) || (!min_line_blank)){ - String_Const_u8 begin_str = {}; - String_Const_u8 end_str = {}; - - i64 min_adjustment = 0; - i64 max_adjustment = 0; - - if (min_line_blank){ - begin_str = push_u8_stringf(scratch, "\n%s", begin); - min_adjustment += 1; - } - else{ - begin_str = push_u8_stringf(scratch, "%s\n", begin); - } - if (max_line_blank){ -end_str = push_u8_stringf(scratch, "%s\n", end); - } - else{ - end_str = push_u8_stringf(scratch, "\n%s", end); - max_adjustment += 1; -} - -max_adjustment += begin_str.size; -Range_i64 new_pos = Ii64(range.min + min_adjustment, range.max + max_adjustment); - - History_Group group = history_group_begin(app, buffer); - buffer_replace_range(app, buffer, Ii64(range.min), begin_str); - buffer_replace_range(app, buffer, Ii64(range.max + begin_str.size), end_str); - history_group_end(group); - - set_view_range(app, view, new_pos); - } - else{ - String_Const_u8 str = push_u8_stringf(scratch, "%s\n\n%s", begin, end); - buffer_replace_range(app, buffer, range, str); - i64 center_pos = range.min + cstring_length(begin) + 1; - view_set_cursor_and_preferred_x(app, view, seek_pos(center_pos)); - view_set_mark(app, view, seek_pos(center_pos)); - } - } - - //////////////////////////////// - - function Face_ID - get_view_face_id(Application_Links *app, View_ID view){ - Buffer_ID buffer = view_get_buffer(app, view, Access_Always); - return(get_face_id(app, buffer)); - } - - function Face_Metrics - get_view_face_metrics(Application_Links *app, View_ID view){ - Face_ID face = get_view_face_id(app, view); - return(get_face_metrics(app, face)); - } - - function f32 - get_view_line_height(Application_Links *app, View_ID view){ - Face_Metrics metrics = get_view_face_metrics(app, view); - return(metrics.line_height); - } - -internal View_ID - open_view(Application_Links *app, View_ID view_location, View_Split_Position position){ - View_ID result = 0; - if (view_location != 0 && view_exists(app, view_location)){ - Panel_ID panel_id = view_get_panel(app, view_location); - if (panel_id != 0){ - Dimension split = (position == ViewSplit_Left || - position == ViewSplit_Right)?Dimension_X:Dimension_Y; - Side side = (position == ViewSplit_Left || - position == ViewSplit_Top)?Side_Min:Side_Max; - if (panel_split(app, panel_id, split)){ - Panel_ID new_panel_id = panel_get_child(app, panel_id, side); - if (new_panel_id != 0){ -View_ID new_view_id = panel_get_view(app, new_panel_id, - Access_Always); - if (new_view_id != 0){ - result = new_view_id; - } - } -} -} -} -return(result); -} - -internal View_ID -get_first_view_with_buffer(Application_Links *app, Buffer_ID buffer_id){ - View_ID result = {}; - if (buffer_id != 0){ -for (View_ID test = get_view_next(app, 0, Access_Always); -test != 0; - test = get_view_next(app, test, Access_Always)){ - Buffer_ID test_buffer = view_get_buffer(app, test, Access_Always); - if (test_buffer == buffer_id){ - result = test; - break; - } - } - } - return(result); - } - - internal b32 -open_file(Application_Links *app, Buffer_ID *buffer_out, String_Const_u8 file_name, b32 background, b32 never_new){ - b32 result = false; -Buffer_ID buffer = get_buffer_by_name(app, file_name, Access_ReadVisible); - b32 exists = buffer_exists(app, buffer); - if (!exists){ - Buffer_Create_Flag flags = 0; - if (background){ - flags |= BufferCreate_Background; - } - if (never_new){ - flags |= BufferCreate_NeverNew; - } - buffer = create_buffer(app, file_name, flags); - exists = buffer_exists(app, buffer); - } - if (exists){ - if (buffer_out != 0){ - *buffer_out = buffer; - } - result = true; - } - return(result); - } - -internal b32 -view_open_file(Application_Links *app, View_ID view, String_Const_u8 file_name, b32 never_new){ - b32 result = false; - if (view != 0){ - Buffer_ID buffer = 0; - if (open_file(app, &buffer, file_name, false, never_new)){ - view_set_buffer(app, view, buffer, 0); - result = true; - } -} - return(result); -} - -internal void -view_disable_highlight_range(Application_Links *app, View_ID view){ - Managed_Scope scope = view_get_managed_scope(app, view); - Managed_Object *highlight = scope_attachment(app, scope, view_highlight_range, Managed_Object); - if (*highlight != 0){ - managed_object_free(app, *highlight); - } - managed_scope_attachment_erase(app, scope, view_highlight_range); -managed_scope_attachment_erase(app, scope, view_highlight_buffer); - } - - internal void - view_set_highlight_range(Application_Links *app, View_ID view, Range_i64 range){ - view_disable_highlight_range(app, view); - - Buffer_ID buffer = view_get_buffer(app, view, Access_Always); - Managed_Scope scope = view_get_managed_scope(app, view); - Managed_Object *highlight = scope_attachment(app, scope, view_highlight_range, Managed_Object); - *highlight = alloc_buffer_markers_on_buffer(app, buffer, 2, &scope); -Marker markers[2] = {}; -markers[0].pos = range.min; - markers[1].pos = range.max; - managed_object_store_data(app, *highlight, 0, 2, markers); - Buffer_ID *highlight_buffer = scope_attachment(app, scope, view_highlight_buffer, Buffer_ID); - *highlight_buffer = buffer; -} - - function void - view_look_at_region(Application_Links *app, View_ID view, i64 major_pos, i64 minor_pos){ - Range_i64 range = Ii64(major_pos, minor_pos); - b32 bottom_major = false; - if (major_pos == range.max){ - bottom_major = true; -} - -Buffer_Cursor top = view_compute_cursor(app, view, seek_pos(range.min)); - if (top.line > 0){ - Buffer_Cursor bottom = view_compute_cursor(app, view, seek_pos(range.max)); - if (bottom.line > 0){ - Rect_f32 region = view_get_buffer_region(app, view); - f32 view_height = rect_height(region); -f32 skirt_height = view_height*.1f; - Range_f32 acceptable_y = If32(skirt_height, view_height*.9f); - - f32 target_height = view_line_y_difference(app, view, bottom.line + 1, top.line); - -f32 line_height = get_view_line_height(app, view); - if (target_height + 2*line_height > view_height){ - i64 major_line = bottom.line; - if (range.min == major_pos){ - major_line = top.line; - } - - Buffer_Scroll scroll = view_get_buffer_scroll(app, view); - scroll.target.line_number = major_line; - scroll.target.pixel_shift.y = -skirt_height; - view_set_buffer_scroll(app, view, scroll, SetBufferScroll_SnapCursorIntoView); - } -else{ - Buffer_Scroll scroll = view_get_buffer_scroll(app, view); - Vec2_f32 top_p = view_relative_xy_of_pos(app, view, scroll.position.line_number, range.min); - top_p -= scroll.position.pixel_shift; -if (top_p.y < acceptable_y.min){ - scroll.target.line_number = top.line; - scroll.target.pixel_shift.y = -skirt_height; - view_set_buffer_scroll(app, view, scroll, SetBufferScroll_NoCursorChange); - } - else{ - Vec2_f32 bot_p = view_relative_xy_of_pos(app, view, scroll.position.line_number, range.max); - bot_p -= scroll.position.pixel_shift; - if (bot_p.y > acceptable_y.max){ - scroll.target.line_number = bottom.line; - scroll.target.pixel_shift.y = skirt_height - view_height; - view_set_buffer_scroll(app, view, scroll, SetBufferScroll_NoCursorChange); - } - } - } -} - } - } - - function void - view_look_at_region(Application_Links *app, View_ID view, Range_i64 range){ - view_look_at_region(app, view, range.min, range.max); - } - - //////////////////////////////// - - function Buffer_ID - get_buffer_next_looped(Application_Links *app, Buffer_ID buffer, Access_Flag access){ - buffer = get_buffer_next(app, buffer, access); - if (buffer == 0){ -buffer = get_buffer_next(app, 0, access); - } - return(buffer); - } - - //////////////////////////////// - - internal View_ID - get_next_view_looped_all_panels(Application_Links *app, View_ID view_id, Access_Flag access){ -view_id = get_view_next(app, view_id, access); - if (view_id == 0){ - view_id = get_view_next(app, 0, access); -} - return(view_id); - } - - internal View_ID - get_prev_view_looped_all_panels(Application_Links *app, View_ID view_id, Access_Flag access){ - view_id = get_view_prev(app, view_id, access); - if (view_id == 0){ - view_id = get_view_prev(app, 0, access); - } - return(view_id); - } - - //////////////////////////////// - - internal Buffer_Kill_Result - try_buffer_kill(Application_Links *app, Buffer_ID buffer, View_ID gui_view_id, Buffer_Kill_Flag flags){ - Buffer_Kill_Result result = buffer_kill(app, buffer, flags); - if (result == BufferKillResult_Dirty){ - if (do_buffer_kill_user_check(app, buffer, gui_view_id)){ - result = buffer_kill(app, buffer, BufferKill_AlwaysKill); -} - } - return(result); - } - - //////////////////////////////// - - internal String_Const_u8 -get_query_string(Application_Links *app, char *query_str, u8 *string_space, i32 space_size){ - Query_Bar_Group group(app); -Query_Bar bar = {}; -bar.prompt = SCu8((u8*)query_str); -bar.string = SCu8(string_space, (u64)0); -bar.string_capacity = space_size; -if (!query_user_string(app, &bar)){ - bar.string.size = 0; - } - return(bar.string); - } - -internal Token* - get_token_from_pos(Application_Links *app, Token_Array *array, u64 pos){ - Token *result = 0; - if (array->count > 0){ - i64 index = token_index_from_pos(array, pos); -result = array->tokens + index; -} -return(result); -} - -internal Token* -get_token_from_pos(Application_Links *app, Buffer_ID buffer, u64 pos){ - Token_Array array = get_token_array_from_buffer(app, buffer); -return(get_token_from_pos(app, &array, pos)); -} - -internal String_Const_u8 - push_token_or_word_under_pos(Application_Links *app, Arena *arena, Buffer_ID buffer, u64 pos){ - String_Const_u8 result = {}; -Token *token = get_token_from_pos(app, buffer, pos); -if (token != 0 && token->size > 0 && token->kind != TokenBaseKind_Whitespace){ - Range_i64 range = Ii64(token); - result = push_buffer_range(app, arena, buffer, range); - } - return(result); -} - - internal String_Const_u8 - push_token_or_word_under_active_cursor(Application_Links *app, Arena *arena){ - View_ID view = get_active_view(app, Access_Always); - Buffer_ID buffer = view_get_buffer(app, view, Access_Always); - i64 pos = view_get_cursor_pos(app, view); -return(push_token_or_word_under_pos(app, arena, buffer, pos)); - } - - //////////////////////////////// - - internal b32 -file_exists(Application_Links *app, String_Const_u8 file_name){ - Scratch_Block scratch(app); - File_Attributes attributes = system_quick_file_attributes(scratch, file_name); -return(attributes.last_write_time > 0); - } - - internal b32 - file_exists_and_is_file(Application_Links *app, String_Const_u8 file_name){ - Scratch_Block scratch(app); -File_Attributes attributes = system_quick_file_attributes(scratch, file_name); - return(attributes.last_write_time > 0 && !HasFlag(attributes.flags, FileAttribute_IsDirectory)); - } - - internal b32 - file_exists_and_is_folder(Application_Links *app, String_Const_u8 file_name){ - Scratch_Block scratch(app); -File_Attributes attributes = system_quick_file_attributes(scratch, file_name); - return(attributes.last_write_time > 0 && HasFlag(attributes.flags, FileAttribute_IsDirectory)); - } - -internal Data - dump_file_handle(Arena *arena, FILE *file){ -Data result = {}; - if (file != 0){ - fseek(file, 0, SEEK_END); - u64 size = ftell(file); - char *mem = push_array(arena, char, size); - if (mem != 0){ - fseek(file, 0, SEEK_SET); - fread(mem, 1, (size_t)size, file); - result = make_data(mem, size); - } - } - return(result); - } - -internal String_Const_u8 -push_file_search_up_path(Application_Links *app, Arena *arena, String_Const_u8 start_path, String_Const_u8 file_name){ -String_Const_u8 result = {}; -String_Const_u8 path = start_path; -for (;path.size > 0;){ - Temp_Memory temp = begin_temp(arena); - if (character_is_slash(string_get_character(path, path.size - 1))){ - path = string_chop(path, 1); - } - String_Const_u8 full_path = push_u8_stringf(arena, "%.*s/%.*s", - string_expand(path), -string_expand(file_name)); - if (file_exists(app, full_path)){ - result = full_path; - break; - } - path = string_remove_last_folder(path); - end_temp(temp); - } - return(result); - } - - internal FILE* - open_file_try_current_path_then_binary_path(Application_Links *app, char *file_name){ - FILE *file = fopen(file_name, "rb"); - if (file == 0){ -Scratch_Block scratch(app); - List_String_Const_u8 list = {}; - string_list_push(scratch, &list, system_get_path(scratch, SystemPath_Binary)); - string_list_push_overlap(scratch, &list, '/', SCu8(file_name)); - String_Const_u8 str = string_list_flatten(scratch, list, StringFill_NullTerminate); -file = fopen((char*)str.str, "rb"); -} -return(file); -} - -internal FILE* -open_file(Arena *scratch, String_Const_u8 name){ -Temp_Memory temp = begin_temp(scratch); - String_Const_u8 name_copy = push_string_copy(scratch, name); - FILE *file = fopen((char*)name_copy.str, "rb"); - end_temp(temp); - return(file); - } - - internal File_Name_Data - dump_file(Arena *arena, String_Const_u8 file_name){ -File_Name_Data result = {}; - FILE *file = open_file(arena, file_name); -if (file != 0){ - result.file_name = file_name; - result.data = dump_file_handle(arena, file); -fclose(file); - } -return(result); - } - - internal File_Name_Data - dump_file_search_up_path(Application_Links *app, Arena *arena, String_Const_u8 path, String_Const_u8 file_name){ - File_Name_Data result = {}; - String_Const_u8 full_path = push_file_search_up_path(app, arena, path, file_name); - if (full_path.size > 0){ - result = dump_file(arena, full_path); -} -return(result); -} - -internal void -sort_pairs_by_key__quick(Sort_Pair_i32 *pairs, i32 first, i32 one_past_last){ - i32 dif = one_past_last - first; - if (dif >= 2){ - i32 pivot = one_past_last - 1; - Sort_Pair_i32 pivot_pair = pairs[pivot]; - i32 j = first; - b32 interleave = false; - for (i32 i = first; i < pivot; i += 1){ - Sort_Pair_i32 pair = pairs[i]; - if (pair.key < pivot_pair.key){ - pairs[i] = pairs[j]; - pairs[j] = pair; - j += 1; -} - else if (pair.key == pivot_pair.key){ - if (interleave){ - pairs[i] = pairs[j]; - pairs[j] = pair; - j += 1; - } - interleave = !interleave; - } - } - pairs[pivot] = pairs[j]; - pairs[j] = pivot_pair; - sort_pairs_by_key__quick(pairs, first, j); - sort_pairs_by_key__quick(pairs, j + 1, one_past_last); - } - } - - internal void - sort_pairs_by_key(Sort_Pair_i32 *pairs, i32 count){ - sort_pairs_by_key__quick(pairs, 0, count); - } - - internal Range_i32_Array - get_ranges_of_duplicate_keys(Arena *arena, i32 *keys, i32 stride, i32 count){ - Range_i32_Array result = {}; - result.ranges = push_array(arena, Range_i32, count); -u8 *ptr = (u8*)keys; - i32 start_i = 0; - for (i32 i = 1; i <= count; i += 1){ - b32 is_end = false; - if (i == count){ - is_end = true; - } - else if (*(i32*)(ptr + i*stride) != *(i32*)(ptr + start_i*stride)){ - is_end = true; - } - if (is_end){ - Range_i32 *new_range = &result.ranges[result.count++]; - new_range->first = start_i; -new_range->one_past_last = i; - start_i = i; - } - } - pop_array(arena, Range_i32, count - result.count); - return(result); - } - - internal void - no_mark_snap_to_cursor(Application_Links *app, Managed_Scope view_scope){ - b32 *snap_to_cursor = scope_attachment(app, view_scope, view_snap_mark_to_cursor, b32); - *snap_to_cursor = false; - } - - internal void - no_mark_snap_to_cursor(Application_Links *app, View_ID view_id){ - Managed_Scope scope = view_get_managed_scope(app, view_id); - no_mark_snap_to_cursor(app, scope); - } - - internal void - no_mark_snap_to_cursor_if_shift(Application_Links *app, View_ID view_id){ - Scratch_Block scratch(app); - Input_Modifier_Set mods = system_get_keyboard_modifiers(scratch); - if (has_modifier(&mods, KeyCode_Shift)){ -no_mark_snap_to_cursor(app, view_id); - } - } - - internal b32 - view_has_highlighted_range(Application_Links *app, View_ID view){ -b32 result = false; - if (fcoder_mode == FCoderMode_NotepadLike){ - i64 pos = view_get_cursor_pos(app, view); -i64 mark = view_get_mark_pos(app, view); -result = (pos != mark); -} -return(result); -} - -internal b32 - if_view_has_highlighted_range_delete_range(Application_Links *app, View_ID view_id){ - b32 result = false; - if (view_has_highlighted_range(app, view_id)){ - Range_i64 range = get_view_range(app, view_id); - Buffer_ID buffer = view_get_buffer(app, view_id, Access_ReadWriteVisible); - buffer_replace_range(app, buffer, range, string_u8_litexpr("")); - result = true; - } - return(result); - } - - internal void - begin_notepad_mode(Application_Links *app){ - fcoder_mode = FCoderMode_NotepadLike; -for (View_ID view = get_view_next(app, 0, Access_Always); - view != 0; -view = get_view_next(app, view, Access_Always)){ - i64 pos = view_get_cursor_pos(app, view); - view_set_mark(app, view, seek_pos(pos)); -} } //////////////////////////////// - internal void +Query_Bar_Group::Query_Bar_Group(Application_Links *app){ + this->app = app; + this->view = get_active_view(app, Access_Always); +} + +Query_Bar_Group::Query_Bar_Group(Application_Links *app, View_ID view){ + this->app = app; + this->view = view; +} + +Query_Bar_Group::~Query_Bar_Group(){ + clear_all_query_bars(this->app, this->view); +} + +internal b32 +query_user_general(Application_Links *app, Query_Bar *bar, b32 force_number, String_Const_u8 init_string){ + if (start_query_bar(app, bar, 0) == 0){ + return(false); + } + + if (init_string.size > 0){ + String_u8 string = Su8(bar->string.str, bar->string.size, bar->string_capacity); + string_append(&string, init_string); + bar->string.size = string.string.size; + } + + b32 success = true; + for (;;){ + User_Input in = get_next_input(app, EventPropertyGroup_Any, + EventProperty_Escape|EventProperty_MouseButton); + if (in.abort){ + success = false; + break; + } + + Scratch_Block scratch(app); + b32 good_insert = false; + String_Const_u8 insert_string = to_writable(&in); + if (insert_string.str != 0 && insert_string.size > 0){ + insert_string = string_replace(scratch, insert_string, + string_u8_litexpr("\n"), + string_u8_litexpr("")); + insert_string = string_replace(scratch, insert_string, + string_u8_litexpr("\t"), + string_u8_litexpr("")); + if (force_number){ + if (string_is_integer(insert_string, 10)){ + good_insert = true; + } + } + else{ + good_insert = true; + } + } + + if (in.event.kind == InputEventKind_KeyStroke && + (in.event.key.code == KeyCode_Return || in.event.key.code == KeyCode_Tab)){ + break; + } + else if (in.event.kind == InputEventKind_KeyStroke && + in.event.key.code == KeyCode_Backspace){ + bar->string = backspace_utf8(bar->string); + } + else if (good_insert){ + String_u8 string = Su8(bar->string.str, bar->string.size, bar->string_capacity); + string_append(&string, insert_string); + bar->string.size = string.string.size; + } + else{ + // NOTE(allen): is the user trying to execute another command? + View_ID view = get_this_ctx_view(app, Access_Always); + View_Context ctx = view_current_context(app, view); + Mapping *mapping = ctx.mapping; + Command_Map *map = mapping_get_map(mapping, ctx.map_id); + Command_Binding binding = map_get_binding_recursive(mapping, map, &in.event); + if (binding.custom != 0){ + Command_Metadata *metadata = get_command_metadata(binding.custom); + if (metadata != 0){ + if (metadata->is_ui){ + view_enqueue_command_function(app, view, binding.custom); + break; + } + } + binding.custom(app); + } + else{ + leave_current_input_unhandled(app); + } + } + } + + return(success); +} + +internal b32 +query_user_string(Application_Links *app, Query_Bar *bar){ + return(query_user_general(app, bar, false, string_u8_empty)); +} + +internal b32 +query_user_number(Application_Links *app, Query_Bar *bar){ + return(query_user_general(app, bar, true, string_u8_empty)); +} + +internal b32 +query_user_number(Application_Links *app, Query_Bar *bar, i32 x){ + Scratch_Block scratch(app); + String_Const_u8 string = push_u8_stringf(scratch, "%d", x); + return(query_user_general(app, bar, true, string)); +} + +//////////////////////////////// + +internal Buffer_Identifier +buffer_identifier(char *str, i32 len){ + Buffer_Identifier identifier; + identifier.name = str; + identifier.name_len = len; + identifier.id = 0; + return(identifier); +} + +internal Buffer_Identifier +buffer_identifier(String_Const_u8 str){ + return(buffer_identifier((char*)str.str, (i32)str.size)); +} + +internal Buffer_Identifier +buffer_identifier(Buffer_ID id){ + Buffer_Identifier identifier; + identifier.name = 0; + identifier.name_len = 0; + identifier.id = id; + return(identifier); +} + +internal Buffer_ID +buffer_identifier_to_id(Application_Links *app, Buffer_Identifier identifier){ + Buffer_ID id = 0; + if (identifier.id != 0){ + id = identifier.id; + } + else{ + String_Const_u8 name = SCu8(identifier.name, identifier.name_len); + id = get_buffer_by_name(app, name, Access_Always); + if (id == 0){ + id = get_buffer_by_file_name(app, name, Access_Always); + } + } + return(id); +} + +internal Buffer_ID +buffer_identifier_to_id_create_out_buffer(Application_Links *app, Buffer_Identifier buffer_id){ + Buffer_ID result = 0; + if (buffer_id.name != 0 && buffer_id.name_len > 0){ + String_Const_u8 buffer_name = SCu8(buffer_id.name, buffer_id.name_len); + Buffer_ID buffer_attach_id = get_buffer_by_name(app, buffer_name, Access_Always); + if (buffer_attach_id != 0){ + result = buffer_attach_id; + } + else{ + buffer_attach_id = create_buffer(app, buffer_name, BufferCreate_AlwaysNew|BufferCreate_NeverAttachToFile); + if (buffer_attach_id != 0){ + buffer_set_setting(app, buffer_attach_id, BufferSetting_ReadOnly, true); + buffer_set_setting(app, buffer_attach_id, BufferSetting_Unimportant, true); + result = buffer_attach_id; + } + } + } + else{ + result = buffer_id.id; + } + return(result); +} + +//////////////////////////////// + +function void +place_begin_and_end_on_own_lines(Application_Links *app, char *begin, char *end){ + View_ID view = get_active_view(app, Access_ReadWriteVisible); + Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible); + + Range_i64 range = get_view_range(app, view); + Range_i64 lines = get_line_range_from_pos_range(app, buffer, range); + range = get_pos_range_from_line_range(app, buffer, lines); + + Scratch_Block scratch(app); + + b32 min_line_blank = line_is_valid_and_blank(app, buffer, lines.min); + b32 max_line_blank = line_is_valid_and_blank(app, buffer, lines.max); + + if ((lines.min < lines.max) || (!min_line_blank)){ + String_Const_u8 begin_str = {}; + String_Const_u8 end_str = {}; + + i64 min_adjustment = 0; + i64 max_adjustment = 0; + + if (min_line_blank){ + begin_str = push_u8_stringf(scratch, "\n%s", begin); + min_adjustment += 1; + } + else{ + begin_str = push_u8_stringf(scratch, "%s\n", begin); + } + if (max_line_blank){ + end_str = push_u8_stringf(scratch, "%s\n", end); + } + else{ + end_str = push_u8_stringf(scratch, "\n%s", end); + max_adjustment += 1; + } + + max_adjustment += begin_str.size; + Range_i64 new_pos = Ii64(range.min + min_adjustment, range.max + max_adjustment); + + History_Group group = history_group_begin(app, buffer); + buffer_replace_range(app, buffer, Ii64(range.min), begin_str); + buffer_replace_range(app, buffer, Ii64(range.max + begin_str.size), end_str); + history_group_end(group); + + set_view_range(app, view, new_pos); + } + else{ + String_Const_u8 str = push_u8_stringf(scratch, "%s\n\n%s", begin, end); + buffer_replace_range(app, buffer, range, str); + i64 center_pos = range.min + cstring_length(begin) + 1; + view_set_cursor_and_preferred_x(app, view, seek_pos(center_pos)); + view_set_mark(app, view, seek_pos(center_pos)); + } +} + +//////////////////////////////// + +function Face_ID +get_view_face_id(Application_Links *app, View_ID view){ + Buffer_ID buffer = view_get_buffer(app, view, Access_Always); + return(get_face_id(app, buffer)); +} + +function Face_Metrics +get_view_face_metrics(Application_Links *app, View_ID view){ + Face_ID face = get_view_face_id(app, view); + return(get_face_metrics(app, face)); +} + +function f32 +get_view_line_height(Application_Links *app, View_ID view){ + Face_Metrics metrics = get_view_face_metrics(app, view); + return(metrics.line_height); +} + +internal View_ID +open_view(Application_Links *app, View_ID view_location, View_Split_Position position){ + View_ID result = 0; + if (view_location != 0 && view_exists(app, view_location)){ + Panel_ID panel_id = view_get_panel(app, view_location); + if (panel_id != 0){ + Dimension split = (position == ViewSplit_Left || + position == ViewSplit_Right)?Dimension_X:Dimension_Y; + Side side = (position == ViewSplit_Left || + position == ViewSplit_Top)?Side_Min:Side_Max; + if (panel_split(app, panel_id, split)){ + Panel_ID new_panel_id = panel_get_child(app, panel_id, side); + if (new_panel_id != 0){ + View_ID new_view_id = panel_get_view(app, new_panel_id, + Access_Always); + if (new_view_id != 0){ + result = new_view_id; + } + } + } + } + } + return(result); +} + +internal View_ID +get_first_view_with_buffer(Application_Links *app, Buffer_ID buffer_id){ + View_ID result = {}; + if (buffer_id != 0){ + for (View_ID test = get_view_next(app, 0, Access_Always); + test != 0; + test = get_view_next(app, test, Access_Always)){ + Buffer_ID test_buffer = view_get_buffer(app, test, Access_Always); + if (test_buffer == buffer_id){ + result = test; + break; + } + } + } + return(result); +} + +internal b32 +open_file(Application_Links *app, Buffer_ID *buffer_out, String_Const_u8 file_name, b32 background, b32 never_new){ + b32 result = false; + Buffer_ID buffer = get_buffer_by_name(app, file_name, Access_ReadVisible); + b32 exists = buffer_exists(app, buffer); + if (!exists){ + Buffer_Create_Flag flags = 0; + if (background){ + flags |= BufferCreate_Background; + } + if (never_new){ + flags |= BufferCreate_NeverNew; + } + buffer = create_buffer(app, file_name, flags); + exists = buffer_exists(app, buffer); + } + if (exists){ + if (buffer_out != 0){ + *buffer_out = buffer; + } + result = true; + } + return(result); +} + +internal b32 +view_open_file(Application_Links *app, View_ID view, String_Const_u8 file_name, b32 never_new){ + b32 result = false; + if (view != 0){ + Buffer_ID buffer = 0; + if (open_file(app, &buffer, file_name, false, never_new)){ + view_set_buffer(app, view, buffer, 0); + result = true; + } + } + return(result); +} + +internal void +view_disable_highlight_range(Application_Links *app, View_ID view){ + Managed_Scope scope = view_get_managed_scope(app, view); + Managed_Object *highlight = scope_attachment(app, scope, view_highlight_range, Managed_Object); + if (*highlight != 0){ + managed_object_free(app, *highlight); + } + managed_scope_attachment_erase(app, scope, view_highlight_range); + managed_scope_attachment_erase(app, scope, view_highlight_buffer); +} + +internal void +view_set_highlight_range(Application_Links *app, View_ID view, Range_i64 range){ + view_disable_highlight_range(app, view); + + Buffer_ID buffer = view_get_buffer(app, view, Access_Always); + Managed_Scope scope = view_get_managed_scope(app, view); + Managed_Object *highlight = scope_attachment(app, scope, view_highlight_range, Managed_Object); + *highlight = alloc_buffer_markers_on_buffer(app, buffer, 2, &scope); + Marker markers[2] = {}; + markers[0].pos = range.min; + markers[1].pos = range.max; + managed_object_store_data(app, *highlight, 0, 2, markers); + Buffer_ID *highlight_buffer = scope_attachment(app, scope, view_highlight_buffer, Buffer_ID); + *highlight_buffer = buffer; +} + +function void +view_look_at_region(Application_Links *app, View_ID view, i64 major_pos, i64 minor_pos){ + Range_i64 range = Ii64(major_pos, minor_pos); + b32 bottom_major = false; + if (major_pos == range.max){ + bottom_major = true; + } + + Buffer_Cursor top = view_compute_cursor(app, view, seek_pos(range.min)); + if (top.line > 0){ + Buffer_Cursor bottom = view_compute_cursor(app, view, seek_pos(range.max)); + if (bottom.line > 0){ + Rect_f32 region = view_get_buffer_region(app, view); + f32 view_height = rect_height(region); + f32 skirt_height = view_height*.1f; + Range_f32 acceptable_y = If32(skirt_height, view_height*.9f); + + f32 target_height = view_line_y_difference(app, view, bottom.line + 1, top.line); + + f32 line_height = get_view_line_height(app, view); + if (target_height + 2*line_height > view_height){ + i64 major_line = bottom.line; + if (range.min == major_pos){ + major_line = top.line; + } + + Buffer_Scroll scroll = view_get_buffer_scroll(app, view); + scroll.target.line_number = major_line; + scroll.target.pixel_shift.y = -skirt_height; + view_set_buffer_scroll(app, view, scroll, SetBufferScroll_SnapCursorIntoView); + } + else{ + Buffer_Scroll scroll = view_get_buffer_scroll(app, view); + Vec2_f32 top_p = view_relative_xy_of_pos(app, view, scroll.position.line_number, range.min); + top_p -= scroll.position.pixel_shift; + if (top_p.y < acceptable_y.min){ + scroll.target.line_number = top.line; + scroll.target.pixel_shift.y = -skirt_height; + view_set_buffer_scroll(app, view, scroll, SetBufferScroll_NoCursorChange); + } + else{ + Vec2_f32 bot_p = view_relative_xy_of_pos(app, view, scroll.position.line_number, range.max); + bot_p -= scroll.position.pixel_shift; + if (bot_p.y > acceptable_y.max){ + scroll.target.line_number = bottom.line; + scroll.target.pixel_shift.y = skirt_height - view_height; + view_set_buffer_scroll(app, view, scroll, SetBufferScroll_NoCursorChange); + } + } + } + } + } +} + +function void +view_look_at_region(Application_Links *app, View_ID view, Range_i64 range){ + view_look_at_region(app, view, range.min, range.max); +} + +//////////////////////////////// + +function Buffer_ID +get_buffer_next_looped(Application_Links *app, Buffer_ID buffer, Access_Flag access){ + buffer = get_buffer_next(app, buffer, access); + if (buffer == 0){ + buffer = get_buffer_next(app, 0, access); + } + return(buffer); +} + +//////////////////////////////// + +internal View_ID +get_next_view_looped_all_panels(Application_Links *app, View_ID view_id, Access_Flag access){ + view_id = get_view_next(app, view_id, access); + if (view_id == 0){ + view_id = get_view_next(app, 0, access); + } + return(view_id); +} + +internal View_ID +get_prev_view_looped_all_panels(Application_Links *app, View_ID view_id, Access_Flag access){ + view_id = get_view_prev(app, view_id, access); + if (view_id == 0){ + view_id = get_view_prev(app, 0, access); + } + return(view_id); +} + +//////////////////////////////// + +internal Buffer_Kill_Result +try_buffer_kill(Application_Links *app, Buffer_ID buffer, View_ID gui_view_id, Buffer_Kill_Flag flags){ + Buffer_Kill_Result result = buffer_kill(app, buffer, flags); + if (result == BufferKillResult_Dirty){ + if (do_buffer_kill_user_check(app, buffer, gui_view_id)){ + result = buffer_kill(app, buffer, BufferKill_AlwaysKill); + } + } + return(result); +} + +//////////////////////////////// + +internal String_Const_u8 +get_query_string(Application_Links *app, char *query_str, u8 *string_space, i32 space_size){ + Query_Bar_Group group(app); + Query_Bar bar = {}; + bar.prompt = SCu8((u8*)query_str); + bar.string = SCu8(string_space, (u64)0); + bar.string_capacity = space_size; + if (!query_user_string(app, &bar)){ + bar.string.size = 0; + } + return(bar.string); +} + +internal Token* +get_token_from_pos(Application_Links *app, Token_Array *array, u64 pos){ + Token *result = 0; + if (array->count > 0){ + i64 index = token_index_from_pos(array, pos); + result = array->tokens + index; + } + return(result); +} + +internal Token* +get_token_from_pos(Application_Links *app, Buffer_ID buffer, u64 pos){ + Token_Array array = get_token_array_from_buffer(app, buffer); + return(get_token_from_pos(app, &array, pos)); +} + +internal String_Const_u8 +push_token_or_word_under_pos(Application_Links *app, Arena *arena, Buffer_ID buffer, u64 pos){ + String_Const_u8 result = {}; + Token *token = get_token_from_pos(app, buffer, pos); + if (token != 0 && token->size > 0 && token->kind != TokenBaseKind_Whitespace){ + Range_i64 range = Ii64(token); + result = push_buffer_range(app, arena, buffer, range); + } + return(result); +} + +internal String_Const_u8 +push_token_or_word_under_active_cursor(Application_Links *app, Arena *arena){ + View_ID view = get_active_view(app, Access_Always); + Buffer_ID buffer = view_get_buffer(app, view, Access_Always); + i64 pos = view_get_cursor_pos(app, view); + return(push_token_or_word_under_pos(app, arena, buffer, pos)); +} + +//////////////////////////////// + +internal b32 +file_exists(Application_Links *app, String_Const_u8 file_name){ + Scratch_Block scratch(app); + File_Attributes attributes = system_quick_file_attributes(scratch, file_name); + return(attributes.last_write_time > 0); +} + +internal b32 +file_exists_and_is_file(Application_Links *app, String_Const_u8 file_name){ + Scratch_Block scratch(app); + File_Attributes attributes = system_quick_file_attributes(scratch, file_name); + return(attributes.last_write_time > 0 && !HasFlag(attributes.flags, FileAttribute_IsDirectory)); +} + +internal b32 +file_exists_and_is_folder(Application_Links *app, String_Const_u8 file_name){ + Scratch_Block scratch(app); + File_Attributes attributes = system_quick_file_attributes(scratch, file_name); + return(attributes.last_write_time > 0 && HasFlag(attributes.flags, FileAttribute_IsDirectory)); +} + +internal Data +dump_file_handle(Arena *arena, FILE *file){ + Data result = {}; + if (file != 0){ + fseek(file, 0, SEEK_END); + u64 size = ftell(file); + char *mem = push_array(arena, char, size); + if (mem != 0){ + fseek(file, 0, SEEK_SET); + fread(mem, 1, (size_t)size, file); + result = make_data(mem, size); + } + } + return(result); +} + +internal String_Const_u8 +push_file_search_up_path(Application_Links *app, Arena *arena, String_Const_u8 start_path, String_Const_u8 file_name){ + String_Const_u8 result = {}; + String_Const_u8 path = start_path; + for (;path.size > 0;){ + Temp_Memory temp = begin_temp(arena); + if (character_is_slash(string_get_character(path, path.size - 1))){ + path = string_chop(path, 1); + } + String_Const_u8 full_path = push_u8_stringf(arena, "%.*s/%.*s", + string_expand(path), + string_expand(file_name)); + if (file_exists(app, full_path)){ + result = full_path; + break; + } + path = string_remove_last_folder(path); + end_temp(temp); + } + return(result); +} + +internal FILE* +open_file_try_current_path_then_binary_path(Application_Links *app, char *file_name){ + FILE *file = fopen(file_name, "rb"); + if (file == 0){ + Scratch_Block scratch(app); + List_String_Const_u8 list = {}; + string_list_push(scratch, &list, system_get_path(scratch, SystemPath_Binary)); + string_list_push_overlap(scratch, &list, '/', SCu8(file_name)); + String_Const_u8 str = string_list_flatten(scratch, list, StringFill_NullTerminate); + file = fopen((char*)str.str, "rb"); + } + return(file); +} + +internal FILE* +open_file(Arena *scratch, String_Const_u8 name){ + Temp_Memory temp = begin_temp(scratch); + String_Const_u8 name_copy = push_string_copy(scratch, name); + FILE *file = fopen((char*)name_copy.str, "rb"); + end_temp(temp); + return(file); +} + +internal File_Name_Data +dump_file(Arena *arena, String_Const_u8 file_name){ + File_Name_Data result = {}; + FILE *file = open_file(arena, file_name); + if (file != 0){ + result.file_name = file_name; + result.data = dump_file_handle(arena, file); + fclose(file); + } + return(result); +} + +internal File_Name_Data +dump_file_search_up_path(Application_Links *app, Arena *arena, String_Const_u8 path, String_Const_u8 file_name){ + File_Name_Data result = {}; + String_Const_u8 full_path = push_file_search_up_path(app, arena, path, file_name); + if (full_path.size > 0){ + result = dump_file(arena, full_path); + } + return(result); +} + +internal void +sort_pairs_by_key__quick(Sort_Pair_i32 *pairs, i32 first, i32 one_past_last){ + i32 dif = one_past_last - first; + if (dif >= 2){ + i32 pivot = one_past_last - 1; + Sort_Pair_i32 pivot_pair = pairs[pivot]; + i32 j = first; + b32 interleave = false; + for (i32 i = first; i < pivot; i += 1){ + Sort_Pair_i32 pair = pairs[i]; + if (pair.key < pivot_pair.key){ + pairs[i] = pairs[j]; + pairs[j] = pair; + j += 1; + } + else if (pair.key == pivot_pair.key){ + if (interleave){ + pairs[i] = pairs[j]; + pairs[j] = pair; + j += 1; + } + interleave = !interleave; + } + } + pairs[pivot] = pairs[j]; + pairs[j] = pivot_pair; + sort_pairs_by_key__quick(pairs, first, j); + sort_pairs_by_key__quick(pairs, j + 1, one_past_last); + } +} + +internal void +sort_pairs_by_key(Sort_Pair_i32 *pairs, i32 count){ + sort_pairs_by_key__quick(pairs, 0, count); +} + +internal Range_i32_Array +get_ranges_of_duplicate_keys(Arena *arena, i32 *keys, i32 stride, i32 count){ + Range_i32_Array result = {}; + result.ranges = push_array(arena, Range_i32, count); + u8 *ptr = (u8*)keys; + i32 start_i = 0; + for (i32 i = 1; i <= count; i += 1){ + b32 is_end = false; + if (i == count){ + is_end = true; + } + else if (*(i32*)(ptr + i*stride) != *(i32*)(ptr + start_i*stride)){ + is_end = true; + } + if (is_end){ + Range_i32 *new_range = &result.ranges[result.count++]; + new_range->first = start_i; + new_range->one_past_last = i; + start_i = i; + } + } + pop_array(arena, Range_i32, count - result.count); + return(result); +} + +internal void +no_mark_snap_to_cursor(Application_Links *app, Managed_Scope view_scope){ + b32 *snap_to_cursor = scope_attachment(app, view_scope, view_snap_mark_to_cursor, b32); + *snap_to_cursor = false; +} + +internal void +no_mark_snap_to_cursor(Application_Links *app, View_ID view_id){ + Managed_Scope scope = view_get_managed_scope(app, view_id); + no_mark_snap_to_cursor(app, scope); +} + +internal void +no_mark_snap_to_cursor_if_shift(Application_Links *app, View_ID view_id){ + Scratch_Block scratch(app); + Input_Modifier_Set mods = system_get_keyboard_modifiers(scratch); + if (has_modifier(&mods, KeyCode_Shift)){ + no_mark_snap_to_cursor(app, view_id); + } +} + +internal b32 +view_has_highlighted_range(Application_Links *app, View_ID view){ + b32 result = false; + if (fcoder_mode == FCoderMode_NotepadLike){ + i64 pos = view_get_cursor_pos(app, view); + i64 mark = view_get_mark_pos(app, view); + result = (pos != mark); + } + return(result); +} + +internal b32 +if_view_has_highlighted_range_delete_range(Application_Links *app, View_ID view_id){ + b32 result = false; + if (view_has_highlighted_range(app, view_id)){ + Range_i64 range = get_view_range(app, view_id); + Buffer_ID buffer = view_get_buffer(app, view_id, Access_ReadWriteVisible); + buffer_replace_range(app, buffer, range, string_u8_litexpr("")); + result = true; + } + return(result); +} + +internal void +begin_notepad_mode(Application_Links *app){ + fcoder_mode = FCoderMode_NotepadLike; + for (View_ID view = get_view_next(app, 0, Access_Always); + view != 0; + view = get_view_next(app, view, Access_Always)){ + i64 pos = view_get_cursor_pos(app, view); + view_set_mark(app, view, seek_pos(pos)); + } +} + +//////////////////////////////// + +internal void seek_pos_of_textual_line(Application_Links *app, Side side){ - View_ID view = get_active_view(app, Access_ReadVisible); + View_ID view = get_active_view(app, Access_ReadVisible); Buffer_ID buffer = view_get_buffer(app, view, Access_ReadVisible); i64 pos = view_get_cursor_pos(app, view); -i64 new_pos = get_line_side_pos_from_pos(app, buffer, pos, side); + i64 new_pos = get_line_side_pos_from_pos(app, buffer, pos, side); view_set_cursor_and_preferred_x(app, view, seek_pos(new_pos)); - no_mark_snap_to_cursor_if_shift(app, view); - } + no_mark_snap_to_cursor_if_shift(app, view); +} internal void seek_pos_of_visual_line(Application_Links *app, Side side){ - View_ID view = get_active_view(app, Access_ReadVisible); + View_ID view = get_active_view(app, Access_ReadVisible); i64 pos = view_get_cursor_pos(app, view); Buffer_Cursor cursor = view_compute_cursor(app, view, seek_pos(pos)); - Vec2_f32 p = view_relative_xy_of_pos(app, view, cursor.line, pos); - p.x = (side == Side_Min)?(0.f):(max_f32); -i64 new_pos = view_pos_at_relative_xy(app, view, cursor.line, p); - view_set_cursor_and_preferred_x(app, view, seek_pos(new_pos)); - no_mark_snap_to_cursor_if_shift(app, view); - } - - CUSTOM_COMMAND_SIG(seek_beginning_of_textual_line) - CUSTOM_DOC("Seeks the cursor to the beginning of the line across all text.") + Vec2_f32 p = view_relative_xy_of_pos(app, view, cursor.line, pos); + p.x = (side == Side_Min)?(0.f):(max_f32); + i64 new_pos = view_pos_at_relative_xy(app, view, cursor.line, p); + view_set_cursor_and_preferred_x(app, view, seek_pos(new_pos)); + no_mark_snap_to_cursor_if_shift(app, view); +} + +CUSTOM_COMMAND_SIG(seek_beginning_of_textual_line) +CUSTOM_DOC("Seeks the cursor to the beginning of the line across all text.") { seek_pos_of_textual_line(app, Side_Min); - } +} - CUSTOM_COMMAND_SIG(seek_end_of_textual_line) +CUSTOM_COMMAND_SIG(seek_end_of_textual_line) CUSTOM_DOC("Seeks the cursor to the end of the line across all text.") - { - seek_pos_of_textual_line(app, Side_Max); - } - - CUSTOM_COMMAND_SIG(seek_beginning_of_line) - CUSTOM_DOC("Seeks the cursor to the beginning of the visual line.") +{ + seek_pos_of_textual_line(app, Side_Max); +} + +CUSTOM_COMMAND_SIG(seek_beginning_of_line) +CUSTOM_DOC("Seeks the cursor to the beginning of the visual line.") { seek_pos_of_visual_line(app, Side_Min); - } - - CUSTOM_COMMAND_SIG(seek_end_of_line) - CUSTOM_DOC("Seeks the cursor to the end of the visual line.") - { - seek_pos_of_visual_line(app, Side_Max); - } - - CUSTOM_COMMAND_SIG(goto_beginning_of_file) - CUSTOM_DOC("Sets the cursor to the beginning of the file.") +} + +CUSTOM_COMMAND_SIG(seek_end_of_line) +CUSTOM_DOC("Seeks the cursor to the end of the visual line.") { -View_ID view = get_active_view(app, Access_ReadVisible); -view_set_cursor_and_preferred_x(app, view, seek_pos(0)); + seek_pos_of_visual_line(app, Side_Max); +} + +CUSTOM_COMMAND_SIG(goto_beginning_of_file) +CUSTOM_DOC("Sets the cursor to the beginning of the file.") +{ + View_ID view = get_active_view(app, Access_ReadVisible); + view_set_cursor_and_preferred_x(app, view, seek_pos(0)); no_mark_snap_to_cursor_if_shift(app, view); - } - - CUSTOM_COMMAND_SIG(goto_end_of_file) - CUSTOM_DOC("Sets the cursor to the end of the file.") - { - View_ID view = get_active_view(app, Access_ReadVisible); - Buffer_ID buffer_id = view_get_buffer(app, view, Access_ReadVisible); - i32 size = (i32)buffer_get_size(app, buffer_id); - view_set_cursor_and_preferred_x(app, view, seek_pos(size)); -no_mark_snap_to_cursor_if_shift(app, view); - } - - //////////////////////////////// - - internal b32 -view_set_split(Application_Links *app, View_ID view, View_Split_Kind kind, f32 t){ - b32 result = false; - if (view != 0){ - Panel_ID panel_id = view_get_panel(app, view); - if (panel_id != 0){ - Panel_ID parent_panel_id = panel_get_parent(app, panel_id); -if (parent_panel_id != 0){ - Panel_ID min_child_id = panel_get_child(app, parent_panel_id, Side_Min); - if (min_child_id != 0){ - b32 panel_is_min = (min_child_id == panel_id); -Panel_Split_Kind panel_kind = ((kind == ViewSplitKind_Ratio)? - (panel_is_min?PanelSplitKind_Ratio_Min:PanelSplitKind_Ratio_Max): -(panel_is_min?PanelSplitKind_FixedPixels_Min:PanelSplitKind_FixedPixels_Max)); - result = panel_set_split(app, parent_panel_id, panel_kind, t); - } } + +CUSTOM_COMMAND_SIG(goto_end_of_file) +CUSTOM_DOC("Sets the cursor to the end of the file.") +{ + View_ID view = get_active_view(app, Access_ReadVisible); + Buffer_ID buffer_id = view_get_buffer(app, view, Access_ReadVisible); + i32 size = (i32)buffer_get_size(app, buffer_id); + view_set_cursor_and_preferred_x(app, view, seek_pos(size)); + no_mark_snap_to_cursor_if_shift(app, view); } -} -return(result); - } + +//////////////////////////////// internal b32 - view_set_split_proportion(Application_Links *app, View_ID view, f32 t){ -return(view_set_split(app, view, ViewSplitKind_Ratio, t)); +view_set_split(Application_Links *app, View_ID view, View_Split_Kind kind, f32 t){ + b32 result = false; + if (view != 0){ + Panel_ID panel_id = view_get_panel(app, view); + if (panel_id != 0){ + Panel_ID parent_panel_id = panel_get_parent(app, panel_id); + if (parent_panel_id != 0){ + Panel_ID min_child_id = panel_get_child(app, parent_panel_id, Side_Min); + if (min_child_id != 0){ + b32 panel_is_min = (min_child_id == panel_id); + Panel_Split_Kind panel_kind = ((kind == ViewSplitKind_Ratio)? + (panel_is_min?PanelSplitKind_Ratio_Min:PanelSplitKind_Ratio_Max): + (panel_is_min?PanelSplitKind_FixedPixels_Min:PanelSplitKind_FixedPixels_Max)); + result = panel_set_split(app, parent_panel_id, panel_kind, t); + } + } + } } - - internal b32 + return(result); +} + +internal b32 +view_set_split_proportion(Application_Links *app, View_ID view, f32 t){ + return(view_set_split(app, view, ViewSplitKind_Ratio, t)); +} + +internal b32 view_set_split_pixel_size(Application_Links *app, View_ID view, i32 t){ return(view_set_split(app, view, ViewSplitKind_FixedPixels, (f32)t)); - } - - //////////////////////////////// +} + +//////////////////////////////// internal Record_Info get_single_record(Application_Links *app, Buffer_ID buffer_id, History_Record_Index index){ -Record_Info record = buffer_history_get_record_info(app, buffer_id, index); - if (record.error == RecordError_NoError && record.kind == RecordKind_Group){ - record = buffer_history_get_group_sub_record(app, buffer_id, index, record.group_count - 1); + Record_Info record = buffer_history_get_record_info(app, buffer_id, index); + if (record.error == RecordError_NoError && record.kind == RecordKind_Group){ + record = buffer_history_get_group_sub_record(app, buffer_id, index, record.group_count - 1); } return(record); - } - - //////////////////////////////// - - function Nest_Delimiter_Kind - get_nest_delimiter_kind(Token_Base_Kind kind, Find_Nest_Flag flags){ +} + +//////////////////////////////// + +function Nest_Delimiter_Kind +get_nest_delimiter_kind(Token_Base_Kind kind, Find_Nest_Flag flags){ Nest_Delimiter_Kind result = NestDelim_None; switch (kind){ - case TokenBaseKind_ScopeOpen: - { - if (HasFlag(flags, FindNest_Scope)){ - result = NestDelim_Open; + case TokenBaseKind_ScopeOpen: + { + if (HasFlag(flags, FindNest_Scope)){ + result = NestDelim_Open; + } + }break; + case TokenBaseKind_ScopeClose: + { + if (HasFlag(flags, FindNest_Scope)){ + result = NestDelim_Close; + } + }break; + case TokenBaseKind_ParentheticalOpen: + { + if (HasFlag(flags, FindNest_Paren)){ + result = NestDelim_Open; + } + }break; + case TokenBaseKind_ParentheticalClose: + { + if (HasFlag(flags, FindNest_Paren)){ + result = NestDelim_Close; + } + }break; } - }break; -case TokenBaseKind_ScopeClose: -{ -if (HasFlag(flags, FindNest_Scope)){ -result = NestDelim_Close; -} -}break; -case TokenBaseKind_ParentheticalOpen: -{ -if (HasFlag(flags, FindNest_Paren)){ -result = NestDelim_Open; -} -}break; -case TokenBaseKind_ParentheticalClose: -{ -if (HasFlag(flags, FindNest_Paren)){ -result = NestDelim_Close; -} -}break; -} -return(result); + return(result); } function b32 find_nest_side(Application_Links *app, Buffer_ID buffer, i64 pos, -Find_Nest_Flag flags, Scan_Direction scan, Nest_Delimiter_Kind delim, -Range_i64 *out){ -b32 result = false; - - b32 balanced = HasFlag(flags, FindNest_Balanced); + Find_Nest_Flag flags, Scan_Direction scan, Nest_Delimiter_Kind delim, + Range_i64 *out){ + b32 result = false; + + b32 balanced = HasFlag(flags, FindNest_Balanced); if (balanced){ - if ((delim == NestDelim_Open && scan == Scan_Forward) || - (delim == NestDelim_Close && scan == Scan_Backward)){ - balanced = false; + if ((delim == NestDelim_Open && scan == Scan_Forward) || + (delim == NestDelim_Close && scan == Scan_Backward)){ + balanced = false; + } } -} Managed_Scope scope = buffer_get_managed_scope(app, buffer); Token_Array *tokens = scope_attachment(app, scope, attachment_tokens, Token_Array); -if (tokens != 0 && tokens->count > 0){ -Token_Iterator_Array it = token_iterator_pos(0, tokens, pos); -i32 level = 0; -for (;;){ -Token *token = token_it_read(&it); -Nest_Delimiter_Kind token_delim = get_nest_delimiter_kind(token->kind, flags); - -if (level == 0 && token_delim == delim){ -*out = Ii64_size(token->pos, token->size); -result = true; -break; -} - -if (balanced && token_delim != NestDelim_None){ -level += (token_delim == delim)?-1:1; -} - -b32 good = false; -if (scan == Scan_Forward){ -good = token_it_inc(&it); - } -else{ -good = token_it_dec(&it); - } -if (!good){ - break; - } - } - } - - return(result); -} - - function b32 -find_nest_side(Application_Links *app, Buffer_ID buffer, i64 pos, -Find_Nest_Flag flags, Scan_Direction scan, Nest_Delimiter_Kind delim, - i64 *out){ -Range_i64 range = {}; - b32 result = find_nest_side(app, buffer, pos, flags, scan, delim, &range); -if (result){ - if (HasFlag(flags, FindNest_EndOfToken)){ - *out = range.end; - } - else{ - *out = range.start; - } - } - return(result); - } - - function b32 - find_surrounding_nest(Application_Links *app, Buffer_ID buffer, i64 pos, - Find_Nest_Flag flags, Range_i64 *out){ -b32 result = false; - Range_i64 range = {}; - if (find_nest_side(app, buffer, pos - 1, flags|FindNest_Balanced, -Scan_Backward, NestDelim_Open, &range.start) && - find_nest_side(app, buffer, pos, flags|FindNest_Balanced|FindNest_EndOfToken, - Scan_Forward, NestDelim_Close, &range.end)){ - *out = range; - result = true; - } - return(result); - } - - function void - select_scope(Application_Links *app, View_ID view, Range_i64 range){ - view_set_cursor_and_preferred_x(app, view, seek_pos(range.first)); - view_set_mark(app, view, seek_pos(range.end)); - view_look_at_region(app, view, range.first, range.end); - no_mark_snap_to_cursor(app, view); - } - - //////////////////////////////// - - function Line_Ending_Kind -guess_line_ending_kind_from_buffer(Application_Links *app, Buffer_ID buffer){ - u64 size = buffer_get_size(app, buffer); - size = clamp_top(size, KB(8)); - Scratch_Block scratch(app); - String_Const_u8 string = push_buffer_range(app, scratch, buffer, Ii64(0, size)); - return(string_guess_line_ending_kind(string)); - } - - //////////////////////////////// - - function i32 - get_command_id(Custom_Command_Function *func){ - i32 result = -1; - for (i32 i = 0; i < ArrayCount(fcoder_metacmd_table); i += 1){ - if (func == fcoder_metacmd_table[i].proc){ -result = i; - break; - } - } - return(result); + if (tokens != 0 && tokens->count > 0){ + Token_Iterator_Array it = token_iterator_pos(0, tokens, pos); + i32 level = 0; + for (;;){ + Token *token = token_it_read(&it); + Nest_Delimiter_Kind token_delim = get_nest_delimiter_kind(token->kind, flags); + + if (level == 0 && token_delim == delim){ + *out = Ii64_size(token->pos, token->size); + result = true; + break; } - function Command_Metadata* - get_command_metadata(Custom_Command_Function *func){ -Command_Metadata *result = 0; - i32 id = get_command_id(func); - if (id >= 0){ - result = &fcoder_metacmd_table[id]; - } - return(result); - } - - //////////////////////////////// - - // TODO(allen): REWRITE THIS EXACTLY HOW YOU WANT IT --- start --- - - internal Child_Process_Set_Target_Flags - flags_system_command(Command_Line_Interface_Flag flags){ - Child_Process_Set_Target_Flags set_buffer_flags = 0; - if (!HasFlag(flags, CLI_OverlapWithConflict)){ - set_buffer_flags |= ChildProcessSet_FailIfBufferAlreadyAttachedToAProcess; - } -if (HasFlag(flags, CLI_CursorAtEnd)){ - set_buffer_flags |= ChildProcessSet_CursorAtEnd; -} -return(set_buffer_flags); + if (balanced && token_delim != NestDelim_None){ + level += (token_delim == delim)?-1:1; + } + + b32 good = false; + if (scan == Scan_Forward){ + good = token_it_inc(&it); + } + else{ + good = token_it_dec(&it); + } + if (!good){ + break; + } + } } - internal b32 - set_buffer_system_command(Application_Links *app, Child_Process_ID process, Buffer_ID buffer, Command_Line_Interface_Flag flags){ - b32 result = false; -Child_Process_Set_Target_Flags set_buffer_flags = flags_system_command(flags); - if (child_process_set_target_buffer(app, process, buffer, set_buffer_flags)){ - clear_buffer(app, buffer); - if (HasFlag(flags, CLI_SendEndSignal)){ - buffer_send_end_signal(app, buffer); - } -result = true; + return(result); } -return(result); + +function b32 +find_nest_side(Application_Links *app, Buffer_ID buffer, i64 pos, + Find_Nest_Flag flags, Scan_Direction scan, Nest_Delimiter_Kind delim, + i64 *out){ + Range_i64 range = {}; + b32 result = find_nest_side(app, buffer, pos, flags, scan, delim, &range); + if (result){ + if (HasFlag(flags, FindNest_EndOfToken)){ + *out = range.end; + } + else{ + *out = range.start; + } + } + return(result); +} + +function b32 +find_surrounding_nest(Application_Links *app, Buffer_ID buffer, i64 pos, + Find_Nest_Flag flags, Range_i64 *out){ + b32 result = false; + Range_i64 range = {}; + if (find_nest_side(app, buffer, pos - 1, flags|FindNest_Balanced, + Scan_Backward, NestDelim_Open, &range.start) && + find_nest_side(app, buffer, pos, flags|FindNest_Balanced|FindNest_EndOfToken, + Scan_Forward, NestDelim_Close, &range.end)){ + *out = range; + result = true; + } + return(result); +} + +function void +select_scope(Application_Links *app, View_ID view, Range_i64 range){ + view_set_cursor_and_preferred_x(app, view, seek_pos(range.first)); + view_set_mark(app, view, seek_pos(range.end)); + view_look_at_region(app, view, range.first, range.end); + no_mark_snap_to_cursor(app, view); +} + +//////////////////////////////// + +function Line_Ending_Kind +guess_line_ending_kind_from_buffer(Application_Links *app, Buffer_ID buffer){ + u64 size = buffer_get_size(app, buffer); + size = clamp_top(size, KB(8)); + Scratch_Block scratch(app); + String_Const_u8 string = push_buffer_range(app, scratch, buffer, Ii64(0, size)); + return(string_guess_line_ending_kind(string)); +} + +//////////////////////////////// + +// TODO(allen): REWRITE THIS EXACTLY HOW YOU WANT IT --- start --- + +internal Child_Process_Set_Target_Flags +flags_system_command(Command_Line_Interface_Flag flags){ + Child_Process_Set_Target_Flags set_buffer_flags = 0; + if (!HasFlag(flags, CLI_OverlapWithConflict)){ + set_buffer_flags |= ChildProcessSet_FailIfBufferAlreadyAttachedToAProcess; + } + if (HasFlag(flags, CLI_CursorAtEnd)){ + set_buffer_flags |= ChildProcessSet_CursorAtEnd; + } + return(set_buffer_flags); +} + +internal b32 +set_buffer_system_command(Application_Links *app, Child_Process_ID process, Buffer_ID buffer, Command_Line_Interface_Flag flags){ + b32 result = false; + Child_Process_Set_Target_Flags set_buffer_flags = flags_system_command(flags); + if (child_process_set_target_buffer(app, process, buffer, set_buffer_flags)){ + clear_buffer(app, buffer); + if (HasFlag(flags, CLI_SendEndSignal)){ + buffer_send_end_signal(app, buffer); + } + result = true; + } + return(result); } internal b32 exec_system_command(Application_Links *app, View_ID view, Buffer_Identifier buffer_id, - String_Const_u8 path, String_Const_u8 command, Command_Line_Interface_Flag flags){ + String_Const_u8 path, String_Const_u8 command, Command_Line_Interface_Flag flags){ b32 result = false; -Child_Process_ID child_process_id = create_child_process(app, path, command); - if (child_process_id != 0){ -result = true; -Buffer_ID buffer_attach_id = buffer_identifier_to_id_create_out_buffer(app, buffer_id); - if (buffer_attach_id != 0){ - if (set_buffer_system_command(app, child_process_id, buffer_attach_id, flags)){ - if (view != 0){ - view_set_buffer(app, view, buffer_attach_id, 0); - view_set_cursor(app, view, seek_pos(0)); - } - } - } - } - return(result); - } + Child_Process_ID child_process_id = create_child_process(app, path, command); + if (child_process_id != 0){ + result = true; + Buffer_ID buffer_attach_id = buffer_identifier_to_id_create_out_buffer(app, buffer_id); + if (buffer_attach_id != 0){ + if (set_buffer_system_command(app, child_process_id, buffer_attach_id, flags)){ + if (view != 0){ + view_set_buffer(app, view, buffer_attach_id, 0); + view_set_cursor(app, view, seek_pos(0)); + } + } + } + } + return(result); +} - // TODO(allen): --- end --- +// TODO(allen): --- end --- // BOTTOM diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index b3e93833..8ef9e353 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -293,22 +293,22 @@ static Command_Metadata fcoder_metacmd_table[237] = { { PROC_LINKS(custom_api_documentation, 0), true, "custom_api_documentation", 24, "Prompts the user to select a Custom API item then loads a doc buffer for that item", 82, "W:\\4ed\\code\\custom\\4coder_docs.cpp", 34, 175 }, { PROC_LINKS(cut, 0), false, "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "W:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 116 }, { PROC_LINKS(decrease_face_size, 0), false, "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 738 }, -{ PROC_LINKS(default_file_externally_modified, 0), false, "default_file_externally_modified", 32, "Notes the external modification of attached files by printing a message.", 72, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1880 }, +{ PROC_LINKS(default_file_externally_modified, 0), false, "default_file_externally_modified", 32, "Notes the external modification of attached files by printing a message.", 72, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1899 }, { PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "W:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 7 }, { PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "W:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 23 }, { PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "W:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 51 }, { PROC_LINKS(delete_alpha_numeric_boundary, 0), false, "delete_alpha_numeric_boundary", 29, "Delete characters between the cursor position and the first alphanumeric boundary to the right.", 95, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 162 }, { PROC_LINKS(delete_char, 0), false, "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 79 }, { PROC_LINKS(delete_current_scope, 0), false, "delete_current_scope", 20, "Deletes the braces surrounding the currently selected scope. Leaves the contents within the scope.", 99, "W:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 112 }, -{ PROC_LINKS(delete_file_query, 0), false, "delete_file_query", 17, "Deletes the file of the current buffer if 4coder has the appropriate access rights. Will ask the user for confirmation first.", 125, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1306 }, -{ PROC_LINKS(delete_line, 0), false, "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1478 }, +{ PROC_LINKS(delete_file_query, 0), false, "delete_file_query", 17, "Deletes the file of the current buffer if 4coder has the appropriate access rights. Will ask the user for confirmation first.", 125, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1325 }, +{ PROC_LINKS(delete_line, 0), false, "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1497 }, { PROC_LINKS(delete_range, 0), false, "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 134 }, -{ PROC_LINKS(duplicate_line, 0), false, "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1464 }, +{ PROC_LINKS(duplicate_line, 0), false, "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1483 }, { PROC_LINKS(execute_any_cli, 0), false, "execute_any_cli", 15, "Queries for an output buffer name and system command, runs the system command as a CLI and prints the output to the specified buffer.", 133, "W:\\4ed\\code\\custom\\4coder_cli_command.cpp", 41, 22 }, { PROC_LINKS(execute_previous_cli, 0), false, "execute_previous_cli", 20, "If the command execute_any_cli has already been used, this will execute a CLI reusing the most recent buffer name and command.", 126, "W:\\4ed\\code\\custom\\4coder_cli_command.cpp", 41, 7 }, { PROC_LINKS(exit_4coder, 0), false, "exit_4coder", 11, "Attempts to close 4coder.", 25, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 825 }, -{ PROC_LINKS(goto_beginning_of_file, 0), false, "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "W:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2201 }, -{ PROC_LINKS(goto_end_of_file, 0), false, "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "W:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2209 }, +{ PROC_LINKS(goto_beginning_of_file, 0), false, "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "W:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2226 }, +{ PROC_LINKS(goto_end_of_file, 0), false, "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "W:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2234 }, { PROC_LINKS(goto_first_jump, 0), false, "goto_first_jump", 15, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "W:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 525 }, { PROC_LINKS(goto_first_jump_same_panel_sticky, 0), false, "goto_first_jump_same_panel_sticky", 33, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer and views the buffer in the panel where the jump list was.", 153, "W:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 542 }, { PROC_LINKS(goto_jump_at_cursor, 0), false, "goto_jump_at_cursor", 19, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "W:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 348 }, @@ -334,7 +334,7 @@ static Command_Metadata fcoder_metacmd_table[237] = { { PROC_LINKS(keyboard_macro_finish_recording, 0), false, "keyboard_macro_finish_recording", 31, "Stop macro recording, do nothing if macro recording is not already started", 74, "W:\\4ed\\code\\custom\\4coder_keyboard_macro.cpp", 44, 54 }, { PROC_LINKS(keyboard_macro_replay, 0), false, "keyboard_macro_replay", 21, "Replay the most recently recorded keyboard macro", 48, "W:\\4ed\\code\\custom\\4coder_keyboard_macro.cpp", 44, 77 }, { PROC_LINKS(keyboard_macro_start_recording, 0), false, "keyboard_macro_start_recording", 30, "Start macro recording, do nothing if macro recording is already started", 71, "W:\\4ed\\code\\custom\\4coder_keyboard_macro.cpp", 44, 41 }, -{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1624 }, +{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1643 }, { PROC_LINKS(kill_tutorial, 0), false, "kill_tutorial", 13, "If there is an active tutorial, kill it.", 40, "W:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 9 }, { PROC_LINKS(left_adjust_view, 0), false, "left_adjust_view", 16, "Sets the left size of the view near the x position of the cursor.", 65, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 211 }, { PROC_LINKS(list_all_functions_all_buffers, 0), false, "list_all_functions_all_buffers", 30, "Creates a jump list of lines from all buffers that appear to define or declare functions.", 89, "W:\\4ed\\code\\custom\\4coder_function_list.cpp", 43, 295 }, @@ -355,7 +355,7 @@ static Command_Metadata fcoder_metacmd_table[237] = { { PROC_LINKS(load_theme_current_buffer, 0), false, "load_theme_current_buffer", 25, "Parse the current buffer as a theme file and add the theme to the theme list. If the buffer has a .4coder postfix in it's name, it is removed when the name is saved.", 165, "W:\\4ed\\code\\custom\\4coder_config.cpp", 36, 1627 }, { PROC_LINKS(load_themes_default_folder, 0), false, "load_themes_default_folder", 26, "Loads all the theme files in the default theme folder.", 54, "W:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 457 }, { PROC_LINKS(load_themes_hot_directory, 0), false, "load_themes_hot_directory", 25, "Loads all the theme files in the current hot directory.", 55, "W:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 469 }, -{ PROC_LINKS(make_directory_query, 0), false, "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1418 }, +{ PROC_LINKS(make_directory_query, 0), false, "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1437 }, { PROC_LINKS(miblo_decrement_basic, 0), false, "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "W:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 44 }, { PROC_LINKS(miblo_decrement_time_stamp, 0), false, "miblo_decrement_time_stamp", 26, "Decrement a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss", 81, "W:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 237 }, { PROC_LINKS(miblo_decrement_time_stamp_minute, 0), false, "miblo_decrement_time_stamp_minute", 33, "Decrement a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "W:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 249 }, @@ -376,8 +376,8 @@ static Command_Metadata fcoder_metacmd_table[237] = { { PROC_LINKS(move_left_token_boundary, 0), false, "move_left_token_boundary", 24, "Seek left for the next beginning of a token.", 44, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 486 }, { PROC_LINKS(move_left_whitespace_boundary, 0), false, "move_left_whitespace_boundary", 29, "Seek left for the next boundary between whitespace and non-whitespace.", 70, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 471 }, { PROC_LINKS(move_left_whitespace_or_token_boundary, 0), false, "move_left_whitespace_or_token_boundary", 38, "Seek left for the next end of a token or boundary between whitespace and non-whitespace.", 88, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 500 }, -{ PROC_LINKS(move_line_down, 0), false, "move_line_down", 14, "Swaps the line under the cursor with the line below it, and moves the cursor down with it.", 90, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1458 }, -{ PROC_LINKS(move_line_up, 0), false, "move_line_up", 12, "Swaps the line under the cursor with the line above it, and moves the cursor up with it.", 88, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1452 }, +{ PROC_LINKS(move_line_down, 0), false, "move_line_down", 14, "Swaps the line under the cursor with the line below it, and moves the cursor down with it.", 90, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1477 }, +{ PROC_LINKS(move_line_up, 0), false, "move_line_up", 12, "Swaps the line under the cursor with the line above it, and moves the cursor up with it.", 88, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1471 }, { PROC_LINKS(move_right, 0), false, "move_right", 10, "Moves the cursor one character to the right.", 44, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 445 }, { PROC_LINKS(move_right_alpha_numeric_boundary, 0), false, "move_right_alpha_numeric_boundary", 33, "Seek right for boundary between alphanumeric characters and non-alphanumeric characters.", 88, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 507 }, { PROC_LINKS(move_right_alpha_numeric_or_camel_boundary, 0), false, "move_right_alpha_numeric_or_camel_boundary", 42, "Seek right for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 107, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 521 }, @@ -393,12 +393,12 @@ static Command_Metadata fcoder_metacmd_table[237] = { { PROC_LINKS(multi_paste_interactive_quick, 0), false, "multi_paste_interactive_quick", 29, "Paste multiple lines from the clipboard history, controlled by inputing the number of lines to paste", 100, "W:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 373 }, { PROC_LINKS(open_all_code, 0), false, "open_all_code", 13, "Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.", 164, "W:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 849 }, { PROC_LINKS(open_all_code_recursive, 0), false, "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "W:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 855 }, -{ PROC_LINKS(open_file_in_quotes, 0), false, "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1543 }, -{ PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1874 }, +{ PROC_LINKS(open_file_in_quotes, 0), false, "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1562 }, +{ PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1893 }, { PROC_LINKS(open_long_braces, 0), false, "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "W:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 46 }, { PROC_LINKS(open_long_braces_break, 0), false, "open_long_braces_break", 22, "At the cursor, insert a '{' and '}break;' separated by a blank line.", 68, "W:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 62 }, { PROC_LINKS(open_long_braces_semicolon, 0), false, "open_long_braces_semicolon", 26, "At the cursor, insert a '{' and '};' separated by a blank line.", 63, "W:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 54 }, -{ PROC_LINKS(open_matching_file_cpp, 0), false, "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\\custom\\4coder_base_commands.cpp", 43, 1575 }, +{ PROC_LINKS(open_matching_file_cpp, 0), false, "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\\custom\\4coder_base_commands.cpp", 43, 1594 }, { PROC_LINKS(open_panel_hsplit, 0), false, "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "W:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 310 }, { PROC_LINKS(open_panel_vsplit, 0), false, "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "W:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 300 }, { PROC_LINKS(page_down, 0), false, "page_down", 9, "Scrolls the view down one view height and moves the cursor down one view height.", 80, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 372 }, @@ -415,27 +415,27 @@ static Command_Metadata fcoder_metacmd_table[237] = { { PROC_LINKS(project_command_lister, 0), false, "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "W:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1290 }, { PROC_LINKS(project_fkey_command, 0), false, "project_fkey_command", 20, "Run an 'fkey command' configured in a project.4coder file. Determines the index of the 'fkey command' by which function key or numeric key was pressed to trigger the command.", 175, "W:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 871 }, { PROC_LINKS(project_go_to_root_directory, 0), false, "project_go_to_root_directory", 28, "Changes 4coder's hot directory to the root directory of the currently loaded project. With no loaded project nothing hapepns.", 125, "W:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 897 }, -{ PROC_LINKS(query_replace, 0), false, "query_replace", 13, "Queries the user for two strings, and incrementally replaces every occurence of the first string with the second string.", 120, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1234 }, -{ PROC_LINKS(query_replace_identifier, 0), false, "query_replace_identifier", 24, "Queries the user for a string, and incrementally replace every occurence of the word or token found at the cursor with the specified string.", 140, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1255 }, -{ PROC_LINKS(query_replace_selection, 0), false, "query_replace_selection", 23, "Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string.", 141, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1271 }, -{ PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1713 }, -{ PROC_LINKS(redo_all_buffers, 0), false, "redo_all_buffers", 16, "Advances forward through the undo history in the buffer containing the most recent regular edit.", 96, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1798 }, -{ PROC_LINKS(rename_file_query, 0), false, "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\\custom\\4coder_base_commands.cpp", 43, 1383 }, -{ PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1642 }, -{ PROC_LINKS(replace_in_all_buffers, 0), false, "replace_in_all_buffers", 22, "Queries the user for a needle and string. Replaces all occurences of needle with string in all editable buffers.", 112, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1144 }, -{ PROC_LINKS(replace_in_buffer, 0), false, "replace_in_buffer", 17, "Queries the user for a needle and string. Replaces all occurences of needle with string in the active buffer.", 109, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1135 }, -{ PROC_LINKS(replace_in_range, 0), false, "replace_in_range", 16, "Queries the user for a needle and string. Replaces all occurences of needle with string in the range between cursor and the mark in the active buffer.", 150, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1126 }, -{ PROC_LINKS(reverse_search, 0), false, "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1067 }, -{ PROC_LINKS(reverse_search_identifier, 0), false, "reverse_search_identifier", 25, "Begins an incremental search up through the current buffer for the word or token under the cursor.", 98, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1079 }, -{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1632 }, +{ PROC_LINKS(query_replace, 0), false, "query_replace", 13, "Queries the user for two strings, and incrementally replaces every occurence of the first string with the second string.", 120, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1253 }, +{ PROC_LINKS(query_replace_identifier, 0), false, "query_replace_identifier", 24, "Queries the user for a string, and incrementally replace every occurence of the word or token found at the cursor with the specified string.", 140, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1274 }, +{ PROC_LINKS(query_replace_selection, 0), false, "query_replace_selection", 23, "Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string.", 141, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1290 }, +{ PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1732 }, +{ PROC_LINKS(redo_all_buffers, 0), false, "redo_all_buffers", 16, "Advances forward through the undo history in the buffer containing the most recent regular edit.", 96, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1817 }, +{ PROC_LINKS(rename_file_query, 0), false, "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\\custom\\4coder_base_commands.cpp", 43, 1402 }, +{ PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1661 }, +{ PROC_LINKS(replace_in_all_buffers, 0), false, "replace_in_all_buffers", 22, "Queries the user for a needle and string. Replaces all occurences of needle with string in all editable buffers.", 112, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1163 }, +{ PROC_LINKS(replace_in_buffer, 0), false, "replace_in_buffer", 17, "Queries the user for a needle and string. Replaces all occurences of needle with string in the active buffer.", 109, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1154 }, +{ PROC_LINKS(replace_in_range, 0), false, "replace_in_range", 16, "Queries the user for a needle and string. Replaces all occurences of needle with string in the range between cursor and the mark in the active buffer.", 150, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1145 }, +{ PROC_LINKS(reverse_search, 0), false, "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1086 }, +{ PROC_LINKS(reverse_search_identifier, 0), false, "reverse_search_identifier", 25, "Begins an incremental search up through the current buffer for the word or token under the cursor.", 98, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1098 }, +{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1651 }, { PROC_LINKS(save_all_dirty_buffers, 0), false, "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "W:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 382 }, -{ PROC_LINKS(save_to_query, 0), false, "save_to_query", 13, "Queries the user for a file name and saves the contents of the current buffer, altering the buffer's name too.", 110, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1350 }, -{ PROC_LINKS(search, 0), false, "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1061 }, -{ PROC_LINKS(search_identifier, 0), false, "search_identifier", 17, "Begins an incremental search down through the current buffer for the word or token under the cursor.", 100, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1073 }, -{ PROC_LINKS(seek_beginning_of_line, 0), false, "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "W:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2189 }, -{ PROC_LINKS(seek_beginning_of_textual_line, 0), false, "seek_beginning_of_textual_line", 30, "Seeks the cursor to the beginning of the line across all text.", 62, "W:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2177 }, -{ PROC_LINKS(seek_end_of_line, 0), false, "seek_end_of_line", 16, "Seeks the cursor to the end of the visual line.", 47, "W:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2195 }, -{ PROC_LINKS(seek_end_of_textual_line, 0), false, "seek_end_of_textual_line", 24, "Seeks the cursor to the end of the line across all text.", 56, "W:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2183 }, +{ PROC_LINKS(save_to_query, 0), false, "save_to_query", 13, "Queries the user for a file name and saves the contents of the current buffer, altering the buffer's name too.", 110, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1369 }, +{ PROC_LINKS(search, 0), false, "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1080 }, +{ PROC_LINKS(search_identifier, 0), false, "search_identifier", 17, "Begins an incremental search down through the current buffer for the word or token under the cursor.", 100, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1092 }, +{ PROC_LINKS(seek_beginning_of_line, 0), false, "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "W:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2214 }, +{ PROC_LINKS(seek_beginning_of_textual_line, 0), false, "seek_beginning_of_textual_line", 30, "Seeks the cursor to the beginning of the line across all text.", 62, "W:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2202 }, +{ PROC_LINKS(seek_end_of_line, 0), false, "seek_end_of_line", 16, "Seeks the cursor to the end of the visual line.", 47, "W:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2220 }, +{ PROC_LINKS(seek_end_of_textual_line, 0), false, "seek_end_of_textual_line", 24, "Seeks the cursor to the end of the line across all text.", 56, "W:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2208 }, { PROC_LINKS(select_all, 0), false, "select_all", 10, "Puts the cursor at the top of the file, and the mark at the bottom of the file.", 79, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 537 }, { PROC_LINKS(select_next_scope_absolute, 0), false, "select_next_scope_absolute", 26, "Finds the first scope started by '{' after the cursor and puts the cursor and mark on the '{' and '}'.", 102, "W:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 57 }, { PROC_LINKS(select_next_scope_after_current, 0), false, "select_next_scope_after_current", 31, "If a scope is selected, find first scope that starts after the selected scope. Otherwise find the first scope that starts after the cursor.", 139, "W:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 66 }, @@ -463,7 +463,7 @@ static Command_Metadata fcoder_metacmd_table[237] = { { PROC_LINKS(snipe_forward_whitespace_or_token_boundary, 0), false, "snipe_forward_whitespace_or_token_boundary", 42, "Delete a single, whole token on or to the right of the cursor and post it to the clipboard.", 91, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 187 }, { PROC_LINKS(snippet_lister, 0), true, "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "W:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 237 }, { PROC_LINKS(suppress_mouse, 0), false, "suppress_mouse", 14, "Hides the mouse and causes all mosue input (clicks, position, wheel) to be ignored.", 83, "W:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 403 }, -{ PROC_LINKS(swap_panels, 0), false, "swap_panels", 11, "Swaps the active panel with it's sibling.", 41, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1600 }, +{ PROC_LINKS(swap_panels, 0), false, "swap_panels", 11, "Swaps the active panel with it's sibling.", 41, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1619 }, { PROC_LINKS(theme_lister, 0), true, "theme_lister", 12, "Opens an interactive list of all registered themes.", 51, "W:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 785 }, { PROC_LINKS(to_lowercase, 0), false, "to_lowercase", 12, "Converts all ascii text in the range between the cursor and the mark to lowercase.", 82, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 563 }, { PROC_LINKS(to_uppercase, 0), false, "to_uppercase", 12, "Converts all ascii text in the range between the cursor and the mark to uppercase.", 82, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 550 }, @@ -481,9 +481,9 @@ static Command_Metadata fcoder_metacmd_table[237] = { { PROC_LINKS(tutorial_maximize, 0), false, "tutorial_maximize", 17, "Expand the tutorial window", 26, "W:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 20 }, { PROC_LINKS(tutorial_minimize, 0), false, "tutorial_minimize", 17, "Shrink the tutorial window", 26, "W:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 34 }, { PROC_LINKS(uncomment_line, 0), false, "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "W:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 137 }, -{ PROC_LINKS(undo, 0), false, "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1700 }, -{ PROC_LINKS(undo_all_buffers, 0), false, "undo_all_buffers", 16, "Advances backward through the undo history in the buffer containing the most recent regular edit.", 97, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1727 }, -{ PROC_LINKS(view_buffer_other_panel, 0), false, "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\\custom\\4coder_base_commands.cpp", 43, 1588 }, +{ PROC_LINKS(undo, 0), false, "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1719 }, +{ PROC_LINKS(undo_all_buffers, 0), false, "undo_all_buffers", 16, "Advances backward through the undo history in the buffer containing the most recent regular edit.", 97, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1746 }, +{ PROC_LINKS(view_buffer_other_panel, 0), false, "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\\custom\\4coder_base_commands.cpp", 43, 1607 }, { PROC_LINKS(view_jump_list_with_lister, 0), false, "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\\custom\\4coder_jump_lister.cpp", 41, 59 }, { PROC_LINKS(word_complete, 0), false, "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\\custom\\4coder_search.cpp", 36, 395 }, { PROC_LINKS(word_complete_drop_down, 0), false, "word_complete_drop_down", 23, "Word complete with drop down menu.", 34, "W:\\4ed\\code\\custom\\4coder_search.cpp", 36, 642 },