From 7e3bcf04a8a984ac24ac17c811f762f300fa5983 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Mon, 10 Jun 2019 22:01:57 -0700 Subject: [PATCH] Generalizing the ideas of 'stop spots' and 'enclose' operations even more --- 4coder_api_transition_30_31.h | 9 + 4coder_api_transition_30_31_helpers.cpp | 57 ++- 4coder_base_commands.cpp | 76 ++-- 4coder_base_types.cpp | 15 + 4coder_default_hooks.cpp | 32 +- 4coder_generated/command_metadata.h | 182 ++++----- 4coder_helper.cpp | 514 +++++++++++++----------- 4coder_helper.h | 19 +- 8 files changed, 516 insertions(+), 388 deletions(-) diff --git a/4coder_api_transition_30_31.h b/4coder_api_transition_30_31.h index ea513c04..ab399a62 100644 --- a/4coder_api_transition_30_31.h +++ b/4coder_api_transition_30_31.h @@ -103,6 +103,15 @@ STRUCT View_Summary{ GUI_Scroll_Vars scroll_vars; }; +/* DOC(A Seek_Boundary_Flag field specifies a set of "boundary" types used in seeks for the beginning or end of different types of words.) */ +typedef u32 Seek_Boundary_Flag; +enum{ + BoundaryWhitespace = 0x1, + BoundaryToken = 0x2, + BoundaryAlphanumeric = 0x4, + BoundaryCamelCase = 0x8 +}; + #endif // BOTTOM diff --git a/4coder_api_transition_30_31_helpers.cpp b/4coder_api_transition_30_31_helpers.cpp index 7c59e5a6..55cefbce 100644 --- a/4coder_api_transition_30_31_helpers.cpp +++ b/4coder_api_transition_30_31_helpers.cpp @@ -198,48 +198,46 @@ buffer_seek_whitespace_down(Application_Links *app, Buffer_Summary *buffer, i32 static i32 buffer_seek_whitespace_right(Application_Links *app, Buffer_Summary *buffer, i32 pos){ - return(buffer==0?0:scan_to_word_boundary(app, buffer->buffer_id, pos, - Scan_Forward, &character_predicate_non_whitespace)); + return(buffer==0?0:scan(app, boundary_non_whitespace, buffer->buffer_id, Scan_Forward, pos)); } static i32 buffer_seek_whitespace_left(Application_Links *app, Buffer_Summary *buffer, i32 pos){ - return(buffer==0?0:scan_to_word_boundary(app, buffer->buffer_id, pos, - Scan_Backward, &character_predicate_non_whitespace)); + return(buffer==0?0:scan(app, boundary_non_whitespace, buffer->buffer_id, Scan_Backward, pos)); } static i32 buffer_seek_alphanumeric_right(Application_Links *app, Buffer_Summary *buffer, i32 pos){ - return(buffer==0?0:scan_to_word_boundary(app, buffer->buffer_id, pos, - Scan_Forward, &character_predicate_alpha_numeric)); + return(buffer==0?0:scan(app, boundary_alpha_numeric, buffer->buffer_id, Scan_Forward, pos)); } static i32 buffer_seek_alphanumeric_left(Application_Links *app, Buffer_Summary *buffer, i32 pos){ - return(buffer==0?0:scan_to_word_boundary(app, buffer->buffer_id, pos, - Scan_Backward, &character_predicate_alpha_numeric)); + return(buffer==0?0:scan(app, boundary_alpha_numeric, buffer->buffer_id, Scan_Backward, pos)); } static i32 buffer_seek_alphanumeric_or_underscore_right(Application_Links *app, Buffer_Summary *buffer, i32 pos){ - return(buffer==0?0:scan_to_word_boundary(app, buffer->buffer_id, pos, Scan_Forward, - &character_predicate_alpha_numeric_underscore)); + return(buffer==0?0:scan(app, boundary_alpha_numeric_underscore, buffer->buffer_id, + Scan_Forward, pos)); } static i32 buffer_seek_alphanumeric_or_underscore_left(Application_Links *app, Buffer_Summary *buffer, i32 pos){ - return(buffer==0?0:scan_to_word_boundary(app, buffer->buffer_id, pos, Scan_Backward, - &character_predicate_alpha_numeric_underscore)); + return(buffer==0?0:scan(app, boundary_alpha_numeric_underscore, buffer->buffer_id, + Scan_Backward, pos)); } static i32 buffer_seek_alphanumeric_or_camel_right(Application_Links *app, Buffer_Summary *buffer, i32 pos){ - return(buffer==0?0:scan_to_alpha_numeric_camel_forward(app, buffer->buffer_id, pos)); + return(buffer==0?0:scan(app, boundary_alpha_numeric_camel, buffer->buffer_id, + Scan_Forward, pos)); } static i32 buffer_seek_alphanumeric_or_camel_left(Application_Links *app, Buffer_Summary *buffer, i32 pos){ - return(buffer==0?0:scan_to_alpha_numeric_camel_backward(app, buffer->buffer_id, pos)); + return(buffer==0?0:scan(app, boundary_alpha_numeric_camel, buffer->buffer_id, + Scan_Backward, pos)); } static i32 @@ -315,7 +313,7 @@ read_identifier_at_pos(Application_Links *app, Buffer_Summary *buffer, i32 pos, String result = {}; if (buffer != 0){ Scratch_Block scratch(app); - Range range = pos_range_enclose_alpha_numeric_underscore(app, buffer->buffer_id, make_range(pos)); + Range range = enclose_alpha_numeric_underscore(app, buffer->buffer_id, make_range(pos)); String_Const_u8 string = push_buffer_range(app, scratch, buffer->buffer_id, range); if (range_out != 0){ *range_out = range; @@ -328,9 +326,33 @@ read_identifier_at_pos(Application_Links *app, Buffer_Summary *buffer, i32 pos, return(result); } +internal Boundary_Function_List +boundary_list_from_old_flags(Arena *arena, Seek_Boundary_Flag flags){ + Boundary_Function_List list = {}; + if (HasFlag(flags, BoundaryWhitespace)){ + push_boundary(arena, &list, boundary_non_whitespace); + } + if (HasFlag(flags, BoundaryToken)){ + push_boundary(arena, &list, boundary_token); + } + if (HasFlag(flags, BoundaryAlphanumeric)){ + push_boundary(arena, &list, boundary_alpha_numeric); + } + if (HasFlag(flags, BoundaryCamelCase)){ + push_boundary(arena, &list, boundary_alpha_numeric_camel); + } + return(list); +} + static i32 buffer_boundary_seek(Application_Links *app, Buffer_Summary *buffer, i32 start_pos, i32 dir, Seek_Boundary_Flag flags){ - return(buffer==0?0:scan_to_word_boundary(app, buffer->buffer_id, start_pos, dir, flags)); + i32 result = 0; + if (buffer != 0){ + Scratch_Block scratch(app); + result = scan(app, boundary_list_from_old_flags(scratch, flags), + buffer->buffer_id, dir, start_pos); + } + return(result); } static void @@ -995,7 +1017,8 @@ view_get_line_number(Application_Links *app, View_ID view, i32 pos){ static void current_view_boundary_seek_set_pos(Application_Links *app, Scan_Direction direction, u32 flags){ - current_view_move_to_word_boundary(app, direction, flags); + Scratch_Block scratch(app); + current_view_scan_move(app, direction, boundary_list_from_old_flags(scratch, flags)); } #endif diff --git a/4coder_base_commands.cpp b/4coder_base_commands.cpp index 190197b2..1cc97fe7 100644 --- a/4coder_base_commands.cpp +++ b/4coder_base_commands.cpp @@ -167,14 +167,14 @@ CUSTOM_DOC("Deletes the text in the range between the cursor and the mark.") } static void -current_view_boundary_delete(Application_Links *app, Scan_Direction direction, Seek_Boundary_Flag flags){ +current_view_boundary_delete(Application_Links *app, Scan_Direction direction, Boundary_Function_List funcs){ View_ID view = 0; get_active_view(app, AccessOpen, &view); Buffer_ID buffer = 0; view_get_buffer(app, view, AccessOpen, &buffer); Range range = {}; view_get_cursor_pos(app, view, &range.first); - range.one_past_last = scan_to_word_boundary(app, buffer, range.first, direction, flags); + range.one_past_last = scan(app, funcs, buffer, direction, range.first); range = rectify(range); buffer_replace_range(app, buffer, range, string_u8_litexpr("")); } @@ -182,40 +182,48 @@ current_view_boundary_delete(Application_Links *app, Scan_Direction direction, S CUSTOM_COMMAND_SIG(backspace_alpha_numeric_boundary) CUSTOM_DOC("Delete characters between the cursor position and the first alphanumeric boundary to the left.") { - current_view_boundary_delete(app, Scan_Backward, BoundaryAlphanumeric); + Scratch_Block scratch(app); + current_view_boundary_delete(app, Scan_Backward, + push_boundary_list(scratch, boundary_alpha_numeric)); } CUSTOM_COMMAND_SIG(delete_alpha_numeric_boundary) CUSTOM_DOC("Delete characters between the cursor position and the first alphanumeric boundary to the right.") { - current_view_boundary_delete(app, Scan_Forward, BoundaryAlphanumeric); + Scratch_Block scratch(app); + current_view_boundary_delete(app, Scan_Forward, + push_boundary_list(scratch, boundary_alpha_numeric)); } #define backspace_word backspace_alpha_numeric_boundary #define delete_word delete_alpha_numeric_boundary static void -current_view_snipe_delete(Application_Links *app, Scan_Direction direction, Seek_Boundary_Flag flags){ +current_view_snipe_delete(Application_Links *app, Scan_Direction direction, Boundary_Function_List funcs){ View_ID view = 0; get_active_view(app, AccessOpen, &view); Buffer_ID buffer = 0; view_get_buffer(app, view, AccessOpen, &buffer); i32 pos = 0; view_get_cursor_pos(app, view, &pos); - Range range = get_snipe_range(app, buffer, pos, direction, flags); + Range range = get_snipe_range(app, funcs, buffer, pos, direction); buffer_replace_range(app, buffer, range, string_u8_litexpr("")); } CUSTOM_COMMAND_SIG(snipe_backward_whitespace_or_token_boundary) CUSTOM_DOC("Delete a single, whole token on or to the left of the cursor and post it to the clipboard.") { - current_view_snipe_delete(app, Scan_Backward, BoundaryToken|BoundaryWhitespace); + Scratch_Block scratch(app); + current_view_snipe_delete(app, Scan_Backward, + push_boundary_list(scratch, boundary_token, boundary_non_whitespace)); } CUSTOM_COMMAND_SIG(snipe_forward_whitespace_or_token_boundary) CUSTOM_DOC("Delete a single, whole token on or to the right of the cursor and post it to the clipboard.") { - current_view_snipe_delete(app, Scan_Forward, BoundaryToken|BoundaryWhitespace); + Scratch_Block scratch(app); + current_view_snipe_delete(app, Scan_Forward, + push_boundary_list(scratch, boundary_token, boundary_non_whitespace)); } #define snipe_token_or_word snipe_backward_whitespace_or_token_boundary @@ -554,14 +562,14 @@ CUSTOM_DOC("Moves the cursor one character to the right.") } static void -current_view_move_to_word_boundary(Application_Links *app, Scan_Direction direction, u32 flags){ +current_view_scan_move(Application_Links *app, Scan_Direction direction, Boundary_Function_List funcs){ View_ID view = 0; get_active_view(app, AccessProtected, &view); Buffer_ID buffer = 0; view_get_buffer(app, view, AccessProtected, &buffer); i32 cursor_pos = 0; view_get_cursor_pos(app, view, &cursor_pos); - i32 pos = scan_to_word_boundary(app, buffer, cursor_pos, direction, flags); + i32 pos = scan(app, funcs, buffer, direction, cursor_pos); view_set_cursor(app, view, seek_pos(pos), true); no_mark_snap_to_cursor_if_shift(app, view); } @@ -569,61 +577,81 @@ current_view_move_to_word_boundary(Application_Links *app, Scan_Direction direct CUSTOM_COMMAND_SIG(move_right_whitespace_boundary) CUSTOM_DOC("Seek right for the next boundary between whitespace and non-whitespace.") { - current_view_move_to_word_boundary(app, Scan_Forward, BoundaryWhitespace); + Scratch_Block scratch(app); + current_view_scan_move(app, Scan_Forward, + push_boundary_list(scratch, boundary_non_whitespace)); } CUSTOM_COMMAND_SIG(move_left_whitespace_boundary) CUSTOM_DOC("Seek left for the next boundary between whitespace and non-whitespace.") { - current_view_move_to_word_boundary(app, Scan_Backward, BoundaryWhitespace); + Scratch_Block scratch(app); + current_view_scan_move(app, Scan_Backward, + push_boundary_list(scratch, boundary_non_whitespace)); } CUSTOM_COMMAND_SIG(move_right_token_boundary) CUSTOM_DOC("Seek right for the next end of a token.") { - current_view_move_to_word_boundary(app, Scan_Forward, BoundaryToken); + Scratch_Block scratch(app); + current_view_scan_move(app, Scan_Forward, + push_boundary_list(scratch, boundary_token)); } CUSTOM_COMMAND_SIG(move_left_token_boundary) CUSTOM_DOC("Seek left for the next beginning of a token.") { - current_view_move_to_word_boundary(app, Scan_Backward, BoundaryToken); + Scratch_Block scratch(app); + current_view_scan_move(app, Scan_Backward, + push_boundary_list(scratch, boundary_token)); } CUSTOM_COMMAND_SIG(move_right_whitespace_or_token_boundary) CUSTOM_DOC("Seek right for the next end of a token or boundary between whitespace and non-whitespace.") { - current_view_move_to_word_boundary(app, Scan_Forward, BoundaryToken|BoundaryWhitespace); + Scratch_Block scratch(app); + current_view_scan_move(app, Scan_Forward, + push_boundary_list(scratch, boundary_token, boundary_non_whitespace)); } CUSTOM_COMMAND_SIG(move_left_whitespace_or_token_boundary) CUSTOM_DOC("Seek left for the next end of a token or boundary between whitespace and non-whitespace.") { - current_view_move_to_word_boundary(app, Scan_Backward, BoundaryToken|BoundaryWhitespace); + Scratch_Block scratch(app); + current_view_scan_move(app, Scan_Backward, + push_boundary_list(scratch, boundary_token, boundary_non_whitespace)); } CUSTOM_COMMAND_SIG(move_right_alpha_numeric_boundary) CUSTOM_DOC("Seek right for boundary between alphanumeric characters and non-alphanumeric characters.") { - current_view_move_to_word_boundary(app, Scan_Forward, BoundaryAlphanumeric); + Scratch_Block scratch(app); + current_view_scan_move(app, Scan_Forward, + push_boundary_list(scratch, boundary_alpha_numeric)); } CUSTOM_COMMAND_SIG(move_left_alpha_numeric_boundary) CUSTOM_DOC("Seek left for boundary between alphanumeric characters and non-alphanumeric characters.") { - current_view_move_to_word_boundary(app, Scan_Backward, BoundaryAlphanumeric); + Scratch_Block scratch(app); + current_view_scan_move(app, Scan_Backward, + push_boundary_list(scratch, boundary_alpha_numeric)); } CUSTOM_COMMAND_SIG(move_right_alpha_numeric_or_camel_boundary) CUSTOM_DOC("Seek right for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.") { - current_view_move_to_word_boundary(app, Scan_Forward, BoundaryAlphanumeric|BoundaryCamelCase); + Scratch_Block scratch(app); + current_view_scan_move(app, Scan_Forward, + push_boundary_list(scratch, boundary_alpha_numeric_camel)); } CUSTOM_COMMAND_SIG(move_left_alpha_numeric_or_camel_boundary) CUSTOM_DOC("Seek left for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.") { - current_view_move_to_word_boundary(app, Scan_Backward, BoundaryAlphanumeric|BoundaryCamelCase); + Scratch_Block scratch(app); + current_view_scan_move(app, Scan_Backward, + push_boundary_list(scratch, boundary_alpha_numeric_camel)); } #define seek_whitespace_right move_right_whitespace_boundary @@ -1219,7 +1247,8 @@ CUSTOM_DOC("Begins an incremental search down through the current buffer for the i32 pos = 0; view_get_cursor_pos(app, view, &pos); Scratch_Block scratch(app); - String_Const_u8 query = push_alpha_numeric_underscore_word_at_pos(app, scratch, buffer_id, pos); + String_Const_u8 query = push_enclose_range_at_pos(app, scratch, buffer_id, pos, + enclose_alpha_numeric_underscore); isearch(app, false, query, true); } @@ -1233,7 +1262,8 @@ CUSTOM_DOC("Begins an incremental search up through the current buffer for the w i32 pos = 0; view_get_cursor_pos(app, view, &pos); Scratch_Block scratch(app); - String_Const_u8 query = push_alpha_numeric_underscore_word_at_pos(app, scratch, buffer_id, pos); + String_Const_u8 query = push_enclose_range_at_pos(app, scratch, buffer_id, pos, + enclose_alpha_numeric_underscore); isearch(app, true, query, true); } @@ -1392,7 +1422,7 @@ CUSTOM_DOC("Queries the user for a string, and incrementally replace every occur i32 pos = 0; view_get_cursor_pos(app, view, &pos); Scratch_Block scratch(app); - Range range = pos_range_enclose_alpha_numeric_underscore(app, buffer, make_range(pos)); + Range range = enclose_alpha_numeric_underscore(app, buffer, make_range(pos)); String_Const_u8 replace = push_buffer_range(app, scratch, buffer, range); if (replace.size != 0){ query_replace_parameter(app, replace, range.min, true); diff --git a/4coder_base_types.cpp b/4coder_base_types.cpp index 00b4f7f1..9fd5cd47 100644 --- a/4coder_base_types.cpp +++ b/4coder_base_types.cpp @@ -2009,6 +2009,21 @@ flip_direction(Scan_Direction direction){ return(direction); } +internal Side +flip_side(Side side){ + switch (side){ + case Side_Min: + { + side = Side_Max; + }break; + case Side_Max: + { + side = Side_Min; + }break; + } + return(side); +} + //////////////////////////////// #if defined(Migrating__Arena) diff --git a/4coder_default_hooks.cpp b/4coder_default_hooks.cpp index 4b990344..90c71fce 100644 --- a/4coder_default_hooks.cpp +++ b/4coder_default_hooks.cpp @@ -383,8 +383,7 @@ default_buffer_render_caller(Application_Links *app, Frame_Info frame_info, View get_active_view(app, AccessAll, &active_view); b32 is_active_view = (active_view == view_id); - Arena *scratch = context_get_arena(app); - Temp_Memory major_temp = begin_temp(scratch); + Scratch_Block scratch(app); static Managed_Scope render_scope = 0; if (render_scope == 0){ @@ -694,23 +693,19 @@ default_buffer_render_caller(Application_Links *app, Frame_Info frame_info, View if (do_token_highlight){ int_color token_color = 0x5000EE00; - u32 token_flags = BoundaryToken|BoundaryWhitespace; - i32 pos0 = cursor_pos; - i32 pos1 = scan_to_word_boundary(app, buffer_id, pos0, Scan_Backward , token_flags); - if (pos1 >= 0){ - i32 pos2 = scan_to_word_boundary(app, buffer_id, pos1, Scan_Forward, token_flags); - i32 buffer_size = 0; - buffer_get_size(app, buffer_id, &buffer_size); - if (pos2 <= buffer_size){ - Managed_Object token_highlight = alloc_buffer_markers_on_buffer(app, buffer_id, 2, &render_scope); - Marker range_markers[2] = {}; - range_markers[0].pos = pos1; - range_markers[1].pos = pos2; - managed_object_store_data(app, token_highlight, 0, 2, range_markers); - Marker_Visual visual = create_marker_visual(app, token_highlight); - marker_visual_set_effect(app, visual, VisualType_CharacterHighlightRanges, token_color, Stag_At_Highlight, 0); - } + Temp_Memory temp = begin_temp(scratch); + Boundary_Function_List funcs = push_boundary_list(scratch, boundary_token, boundary_non_whitespace); + Range snipe_range = get_snipe_range(app, funcs, buffer_id, cursor_pos, Scan_Backward); + if (range_size(snipe_range) > 0){ + Managed_Object token_highlight = alloc_buffer_markers_on_buffer(app, buffer_id, 2, &render_scope); + Marker range_markers[2] = {}; + range_markers[0].pos = snipe_range.min; + range_markers[1].pos = snipe_range.max; + managed_object_store_data(app, token_highlight, 0, 2, range_markers); + Marker_Visual visual = create_marker_visual(app, token_highlight); + marker_visual_set_effect(app, visual, VisualType_CharacterHighlightRanges, token_color, Stag_At_Highlight, 0); } + end_temp(temp); } // NOTE(allen): Matching enclosure highlight setup @@ -805,7 +800,6 @@ default_buffer_render_caller(Application_Links *app, Frame_Info frame_info, View animate_in_n_milliseconds(app, 1000); } - end_temp(major_temp); managed_scope_clear_self_all_dependent_scopes(app, render_scope); } diff --git a/4coder_generated/command_metadata.h b/4coder_generated/command_metadata.h index 19289e37..c0df6c94 100644 --- a/4coder_generated/command_metadata.h +++ b/4coder_generated/command_metadata.h @@ -284,93 +284,93 @@ static Command_Metadata fcoder_metacmd_table[234] = { { PROC_LINKS(cursor_mark_swap, 0), "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 145 }, { PROC_LINKS(delete_range, 0), "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 158 }, { PROC_LINKS(backspace_alpha_numeric_boundary, 0), "backspace_alpha_numeric_boundary", 32, "Delete characters between the cursor position and the first alphanumeric boundary to the left.", 94, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 182 }, -{ PROC_LINKS(delete_alpha_numeric_boundary, 0), "delete_alpha_numeric_boundary", 29, "Delete characters between the cursor position and the first alphanumeric boundary to the right.", 95, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 188 }, -{ PROC_LINKS(snipe_backward_whitespace_or_token_boundary, 0), "snipe_backward_whitespace_or_token_boundary", 43, "Delete a single, whole token on or to the left of the cursor and post it to the clipboard.", 90, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 209 }, -{ PROC_LINKS(snipe_forward_whitespace_or_token_boundary, 0), "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\\4coder_base_commands.cpp", 36, 215 }, -{ PROC_LINKS(center_view, 0), "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 226 }, -{ PROC_LINKS(left_adjust_view, 0), "left_adjust_view", 16, "Sets the left size of the view near the x position of the cursor.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 244 }, -{ PROC_LINKS(click_set_cursor_and_mark, 0), "click_set_cursor_and_mark", 25, "Sets the cursor position and mark to the mouse position.", 56, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 269 }, -{ PROC_LINKS(click_set_cursor, 0), "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 288 }, -{ PROC_LINKS(click_set_cursor_if_lbutton, 0), "click_set_cursor_if_lbutton", 27, "If the mouse left button is pressed, sets the cursor position to the mouse position.", 84, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 305 }, -{ PROC_LINKS(click_set_mark, 0), "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 324 }, -{ PROC_LINKS(mouse_wheel_scroll, 0), "mouse_wheel_scroll", 18, "Reads the scroll wheel value from the mouse state and scrolls accordingly.", 74, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 341 }, -{ PROC_LINKS(move_up, 0), "move_up", 7, "Moves the cursor up one line.", 29, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 417 }, -{ PROC_LINKS(move_down, 0), "move_down", 9, "Moves the cursor down one line.", 31, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 423 }, -{ PROC_LINKS(move_up_10, 0), "move_up_10", 10, "Moves the cursor up ten lines.", 30, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 429 }, -{ PROC_LINKS(move_down_10, 0), "move_down_10", 12, "Moves the cursor down ten lines.", 32, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 435 }, -{ PROC_LINKS(move_down_textual, 0), "move_down_textual", 17, "Moves down to the next line of actual text, regardless of line wrapping.", 72, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 441 }, -{ PROC_LINKS(page_up, 0), "page_up", 7, "Scrolls the view up one view height and moves the cursor up one view height.", 76, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 455 }, -{ PROC_LINKS(page_down, 0), "page_down", 9, "Scrolls the view down one view height and moves the cursor down one view height.", 80, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 464 }, -{ PROC_LINKS(move_up_to_blank_line, 0), "move_up_to_blank_line", 21, "Seeks the cursor up to the next blank line.", 43, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 499 }, -{ PROC_LINKS(move_down_to_blank_line, 0), "move_down_to_blank_line", 23, "Seeks the cursor down to the next blank line.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 505 }, -{ PROC_LINKS(move_up_to_blank_line_end, 0), "move_up_to_blank_line_end", 25, "Seeks the cursor up to the next blank line and places it at the end of the line.", 80, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 511 }, -{ PROC_LINKS(move_down_to_blank_line_end, 0), "move_down_to_blank_line_end", 27, "Seeks the cursor down to the next blank line and places it at the end of the line.", 82, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 517 }, -{ PROC_LINKS(move_left, 0), "move_left", 9, "Moves the cursor one character to the left.", 43, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 528 }, -{ PROC_LINKS(move_right, 0), "move_right", 10, "Moves the cursor one character to the right.", 44, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 542 }, -{ PROC_LINKS(move_right_whitespace_boundary, 0), "move_right_whitespace_boundary", 30, "Seek right for the next boundary between whitespace and non-whitespace.", 71, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 569 }, -{ PROC_LINKS(move_left_whitespace_boundary, 0), "move_left_whitespace_boundary", 29, "Seek left for the next boundary between whitespace and non-whitespace.", 70, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 575 }, -{ PROC_LINKS(move_right_token_boundary, 0), "move_right_token_boundary", 25, "Seek right for the next end of a token.", 39, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 581 }, -{ PROC_LINKS(move_left_token_boundary, 0), "move_left_token_boundary", 24, "Seek left for the next beginning of a token.", 44, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 587 }, -{ PROC_LINKS(move_right_whitespace_or_token_boundary, 0), "move_right_whitespace_or_token_boundary", 39, "Seek right for the next end of a token or boundary between whitespace and non-whitespace.", 89, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 593 }, -{ PROC_LINKS(move_left_whitespace_or_token_boundary, 0), "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\\4coder_base_commands.cpp", 36, 599 }, -{ PROC_LINKS(move_right_alpha_numeric_boundary, 0), "move_right_alpha_numeric_boundary", 33, "Seek right for boundary between alphanumeric characters and non-alphanumeric characters.", 88, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 605 }, -{ PROC_LINKS(move_left_alpha_numeric_boundary, 0), "move_left_alpha_numeric_boundary", 32, "Seek left for boundary between alphanumeric characters and non-alphanumeric characters.", 87, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 611 }, -{ PROC_LINKS(move_right_alpha_numeric_or_camel_boundary, 0), "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\\4coder_base_commands.cpp", 36, 617 }, -{ PROC_LINKS(move_left_alpha_numeric_or_camel_boundary, 0), "move_left_alpha_numeric_or_camel_boundary", 41, "Seek left for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 106, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 623 }, -{ PROC_LINKS(select_all, 0), "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\\4coder_base_commands.cpp", 36, 642 }, -{ PROC_LINKS(to_uppercase, 0), "to_uppercase", 12, "Converts all ascii text in the range between the cursor and the mark to uppercase.", 82, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 658 }, -{ PROC_LINKS(to_lowercase, 0), "to_lowercase", 12, "Converts all ascii text in the range between the cursor and the mark to lowercase.", 82, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 678 }, -{ PROC_LINKS(clean_all_lines, 0), "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 698 }, -{ PROC_LINKS(basic_change_active_panel, 0), "basic_change_active_panel", 25, "Change the currently active panel, moving to the panel with the next highest view_id. Will not skipe the build panel if it is open.", 132, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 768 }, -{ PROC_LINKS(close_panel, 0), "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 777 }, -{ PROC_LINKS(show_scrollbar, 0), "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 787 }, -{ PROC_LINKS(hide_scrollbar, 0), "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 795 }, -{ PROC_LINKS(show_filebar, 0), "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 803 }, -{ PROC_LINKS(hide_filebar, 0), "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 811 }, -{ PROC_LINKS(toggle_filebar, 0), "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 819 }, -{ PROC_LINKS(toggle_line_wrap, 0), "toggle_line_wrap", 16, "Toggles the current buffer's line wrapping status.", 50, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 829 }, -{ PROC_LINKS(toggle_fps_meter, 0), "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 841 }, -{ PROC_LINKS(increase_line_wrap, 0), "increase_line_wrap", 18, "Increases the current buffer's width for line wrapping.", 55, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 847 }, -{ PROC_LINKS(decrease_line_wrap, 0), "decrease_line_wrap", 18, "Decrases the current buffer's width for line wrapping.", 54, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 859 }, -{ PROC_LINKS(increase_face_size, 0), "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 871 }, -{ PROC_LINKS(decrease_face_size, 0), "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 885 }, -{ PROC_LINKS(mouse_wheel_change_face_size, 0), "mouse_wheel_change_face_size", 28, "Reads the state of the mouse wheel and uses it to either increase or decrease the face size.", 92, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 899 }, -{ PROC_LINKS(toggle_virtual_whitespace, 0), "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 916 }, -{ PROC_LINKS(toggle_show_whitespace, 0), "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 928 }, -{ PROC_LINKS(toggle_line_numbers, 0), "toggle_line_numbers", 19, "Toggles the left margin line numbers.", 37, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 938 }, -{ PROC_LINKS(eol_dosify, 0), "eol_dosify", 10, "Puts the buffer in DOS line ending mode.", 40, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 944 }, -{ PROC_LINKS(eol_nixify, 0), "eol_nixify", 10, "Puts the buffer in NIX line ending mode.", 40, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 954 }, -{ PROC_LINKS(exit_4coder, 0), "exit_4coder", 11, "Attempts to close 4coder.", 25, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 964 }, -{ PROC_LINKS(goto_line, 0), "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 972 }, -{ PROC_LINKS(search, 0), "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1200 }, -{ PROC_LINKS(reverse_search, 0), "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1206 }, -{ PROC_LINKS(search_identifier, 0), "search_identifier", 17, "Begins an incremental search down through the current buffer for the word or token under the cursor.", 100, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1212 }, -{ PROC_LINKS(reverse_search_identifier, 0), "reverse_search_identifier", 25, "Begins an incremental search up through the current buffer for the word or token under the cursor.", 98, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1226 }, -{ PROC_LINKS(replace_in_range, 0), "replace_in_range", 16, "Queries the user for two strings, and replaces all occurences of the first string in the range between the cursor and the mark with the second string.", 150, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1240 }, -{ PROC_LINKS(query_replace, 0), "query_replace", 13, "Queries the user for two strings, and incrementally replaces every occurence of the first string with the second string.", 120, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1361 }, -{ PROC_LINKS(query_replace_identifier, 0), "query_replace_identifier", 24, "Queries the user for a string, and incrementally replace every occurence of the word or token found at the cursor with the specified string.", 140, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1384 }, -{ PROC_LINKS(query_replace_selection, 0), "query_replace_selection", 23, "Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string.", 141, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1403 }, -{ PROC_LINKS(save_all_dirty_buffers, 0), "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1447 }, -{ PROC_LINKS(delete_file_query, 0), "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\\4coder_base_commands.cpp", 36, 1472 }, -{ PROC_LINKS(save_to_query, 0), "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\\4coder_base_commands.cpp", 36, 1512 }, -{ PROC_LINKS(rename_file_query, 0), "rename_file_query", 17, "Queries the user for a new name and renames the file of the current buffer, altering the buffer's name too.", 107, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1550 }, -{ PROC_LINKS(make_directory_query, 0), "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1593 }, -{ PROC_LINKS(move_line_up, 0), "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\\4coder_base_commands.cpp", 36, 1616 }, -{ PROC_LINKS(move_line_down, 0), "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\\4coder_base_commands.cpp", 36, 1681 }, -{ PROC_LINKS(duplicate_line, 0), "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1703 }, -{ PROC_LINKS(delete_line, 0), "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1721 }, -{ PROC_LINKS(open_file_in_quotes, 0), "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1813 }, -{ PROC_LINKS(open_matching_file_cpp, 0), "open_matching_file_cpp", 22, "If the current file is a *.cpp or *.h, attempts to open the corresponding *.h or *.cpp file in the other view.", 110, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1851 }, -{ PROC_LINKS(view_buffer_other_panel, 0), "view_buffer_other_panel", 23, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1866 }, -{ PROC_LINKS(swap_buffers_between_panels, 0), "swap_buffers_between_panels", 27, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1881 }, -{ PROC_LINKS(kill_buffer, 0), "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1926 }, -{ PROC_LINKS(save, 0), "save", 4, "Saves the current buffer.", 25, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1936 }, -{ PROC_LINKS(reopen, 0), "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1950 }, -{ PROC_LINKS(undo, 0), "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 2014 }, -{ PROC_LINKS(redo, 0), "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 2030 }, -{ PROC_LINKS(undo_all_buffers, 0), "undo_all_buffers", 16, "Advances backward through the undo history in the buffer containing the most recent regular edit.", 97, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 2048 }, -{ PROC_LINKS(redo_all_buffers, 0), "redo_all_buffers", 16, "Advances forward through the undo history in the buffer containing the most recent regular edit.", 96, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 2127 }, -{ PROC_LINKS(open_in_other, 0), "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 2237 }, +{ PROC_LINKS(delete_alpha_numeric_boundary, 0), "delete_alpha_numeric_boundary", 29, "Delete characters between the cursor position and the first alphanumeric boundary to the right.", 95, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 190 }, +{ PROC_LINKS(snipe_backward_whitespace_or_token_boundary, 0), "snipe_backward_whitespace_or_token_boundary", 43, "Delete a single, whole token on or to the left of the cursor and post it to the clipboard.", 90, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 213 }, +{ PROC_LINKS(snipe_forward_whitespace_or_token_boundary, 0), "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\\4coder_base_commands.cpp", 36, 221 }, +{ PROC_LINKS(center_view, 0), "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 234 }, +{ PROC_LINKS(left_adjust_view, 0), "left_adjust_view", 16, "Sets the left size of the view near the x position of the cursor.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 252 }, +{ PROC_LINKS(click_set_cursor_and_mark, 0), "click_set_cursor_and_mark", 25, "Sets the cursor position and mark to the mouse position.", 56, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 277 }, +{ PROC_LINKS(click_set_cursor, 0), "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 296 }, +{ PROC_LINKS(click_set_cursor_if_lbutton, 0), "click_set_cursor_if_lbutton", 27, "If the mouse left button is pressed, sets the cursor position to the mouse position.", 84, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 313 }, +{ PROC_LINKS(click_set_mark, 0), "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 332 }, +{ PROC_LINKS(mouse_wheel_scroll, 0), "mouse_wheel_scroll", 18, "Reads the scroll wheel value from the mouse state and scrolls accordingly.", 74, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 349 }, +{ PROC_LINKS(move_up, 0), "move_up", 7, "Moves the cursor up one line.", 29, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 425 }, +{ PROC_LINKS(move_down, 0), "move_down", 9, "Moves the cursor down one line.", 31, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 431 }, +{ PROC_LINKS(move_up_10, 0), "move_up_10", 10, "Moves the cursor up ten lines.", 30, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 437 }, +{ PROC_LINKS(move_down_10, 0), "move_down_10", 12, "Moves the cursor down ten lines.", 32, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 443 }, +{ PROC_LINKS(move_down_textual, 0), "move_down_textual", 17, "Moves down to the next line of actual text, regardless of line wrapping.", 72, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 449 }, +{ PROC_LINKS(page_up, 0), "page_up", 7, "Scrolls the view up one view height and moves the cursor up one view height.", 76, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 463 }, +{ PROC_LINKS(page_down, 0), "page_down", 9, "Scrolls the view down one view height and moves the cursor down one view height.", 80, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 472 }, +{ PROC_LINKS(move_up_to_blank_line, 0), "move_up_to_blank_line", 21, "Seeks the cursor up to the next blank line.", 43, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 507 }, +{ PROC_LINKS(move_down_to_blank_line, 0), "move_down_to_blank_line", 23, "Seeks the cursor down to the next blank line.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 513 }, +{ PROC_LINKS(move_up_to_blank_line_end, 0), "move_up_to_blank_line_end", 25, "Seeks the cursor up to the next blank line and places it at the end of the line.", 80, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 519 }, +{ PROC_LINKS(move_down_to_blank_line_end, 0), "move_down_to_blank_line_end", 27, "Seeks the cursor down to the next blank line and places it at the end of the line.", 82, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 525 }, +{ PROC_LINKS(move_left, 0), "move_left", 9, "Moves the cursor one character to the left.", 43, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 536 }, +{ PROC_LINKS(move_right, 0), "move_right", 10, "Moves the cursor one character to the right.", 44, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 550 }, +{ PROC_LINKS(move_right_whitespace_boundary, 0), "move_right_whitespace_boundary", 30, "Seek right for the next boundary between whitespace and non-whitespace.", 71, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 577 }, +{ PROC_LINKS(move_left_whitespace_boundary, 0), "move_left_whitespace_boundary", 29, "Seek left for the next boundary between whitespace and non-whitespace.", 70, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 585 }, +{ PROC_LINKS(move_right_token_boundary, 0), "move_right_token_boundary", 25, "Seek right for the next end of a token.", 39, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 593 }, +{ PROC_LINKS(move_left_token_boundary, 0), "move_left_token_boundary", 24, "Seek left for the next beginning of a token.", 44, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 601 }, +{ PROC_LINKS(move_right_whitespace_or_token_boundary, 0), "move_right_whitespace_or_token_boundary", 39, "Seek right for the next end of a token or boundary between whitespace and non-whitespace.", 89, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 609 }, +{ PROC_LINKS(move_left_whitespace_or_token_boundary, 0), "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\\4coder_base_commands.cpp", 36, 617 }, +{ PROC_LINKS(move_right_alpha_numeric_boundary, 0), "move_right_alpha_numeric_boundary", 33, "Seek right for boundary between alphanumeric characters and non-alphanumeric characters.", 88, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 625 }, +{ PROC_LINKS(move_left_alpha_numeric_boundary, 0), "move_left_alpha_numeric_boundary", 32, "Seek left for boundary between alphanumeric characters and non-alphanumeric characters.", 87, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 633 }, +{ PROC_LINKS(move_right_alpha_numeric_or_camel_boundary, 0), "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\\4coder_base_commands.cpp", 36, 641 }, +{ PROC_LINKS(move_left_alpha_numeric_or_camel_boundary, 0), "move_left_alpha_numeric_or_camel_boundary", 41, "Seek left for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 106, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 649 }, +{ PROC_LINKS(select_all, 0), "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\\4coder_base_commands.cpp", 36, 670 }, +{ PROC_LINKS(to_uppercase, 0), "to_uppercase", 12, "Converts all ascii text in the range between the cursor and the mark to uppercase.", 82, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 686 }, +{ PROC_LINKS(to_lowercase, 0), "to_lowercase", 12, "Converts all ascii text in the range between the cursor and the mark to lowercase.", 82, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 706 }, +{ PROC_LINKS(clean_all_lines, 0), "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 726 }, +{ PROC_LINKS(basic_change_active_panel, 0), "basic_change_active_panel", 25, "Change the currently active panel, moving to the panel with the next highest view_id. Will not skipe the build panel if it is open.", 132, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 796 }, +{ PROC_LINKS(close_panel, 0), "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 805 }, +{ PROC_LINKS(show_scrollbar, 0), "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 815 }, +{ PROC_LINKS(hide_scrollbar, 0), "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 823 }, +{ PROC_LINKS(show_filebar, 0), "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 831 }, +{ PROC_LINKS(hide_filebar, 0), "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 839 }, +{ PROC_LINKS(toggle_filebar, 0), "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 847 }, +{ PROC_LINKS(toggle_line_wrap, 0), "toggle_line_wrap", 16, "Toggles the current buffer's line wrapping status.", 50, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 857 }, +{ PROC_LINKS(toggle_fps_meter, 0), "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 869 }, +{ PROC_LINKS(increase_line_wrap, 0), "increase_line_wrap", 18, "Increases the current buffer's width for line wrapping.", 55, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 875 }, +{ PROC_LINKS(decrease_line_wrap, 0), "decrease_line_wrap", 18, "Decrases the current buffer's width for line wrapping.", 54, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 887 }, +{ PROC_LINKS(increase_face_size, 0), "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 899 }, +{ PROC_LINKS(decrease_face_size, 0), "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 913 }, +{ PROC_LINKS(mouse_wheel_change_face_size, 0), "mouse_wheel_change_face_size", 28, "Reads the state of the mouse wheel and uses it to either increase or decrease the face size.", 92, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 927 }, +{ PROC_LINKS(toggle_virtual_whitespace, 0), "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 944 }, +{ PROC_LINKS(toggle_show_whitespace, 0), "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 956 }, +{ PROC_LINKS(toggle_line_numbers, 0), "toggle_line_numbers", 19, "Toggles the left margin line numbers.", 37, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 966 }, +{ PROC_LINKS(eol_dosify, 0), "eol_dosify", 10, "Puts the buffer in DOS line ending mode.", 40, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 972 }, +{ PROC_LINKS(eol_nixify, 0), "eol_nixify", 10, "Puts the buffer in NIX line ending mode.", 40, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 982 }, +{ PROC_LINKS(exit_4coder, 0), "exit_4coder", 11, "Attempts to close 4coder.", 25, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 992 }, +{ PROC_LINKS(goto_line, 0), "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1000 }, +{ PROC_LINKS(search, 0), "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1228 }, +{ PROC_LINKS(reverse_search, 0), "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1234 }, +{ PROC_LINKS(search_identifier, 0), "search_identifier", 17, "Begins an incremental search down through the current buffer for the word or token under the cursor.", 100, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1240 }, +{ PROC_LINKS(reverse_search_identifier, 0), "reverse_search_identifier", 25, "Begins an incremental search up through the current buffer for the word or token under the cursor.", 98, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1255 }, +{ PROC_LINKS(replace_in_range, 0), "replace_in_range", 16, "Queries the user for two strings, and replaces all occurences of the first string in the range between the cursor and the mark with the second string.", 150, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1270 }, +{ PROC_LINKS(query_replace, 0), "query_replace", 13, "Queries the user for two strings, and incrementally replaces every occurence of the first string with the second string.", 120, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1391 }, +{ PROC_LINKS(query_replace_identifier, 0), "query_replace_identifier", 24, "Queries the user for a string, and incrementally replace every occurence of the word or token found at the cursor with the specified string.", 140, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1414 }, +{ PROC_LINKS(query_replace_selection, 0), "query_replace_selection", 23, "Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string.", 141, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1433 }, +{ PROC_LINKS(save_all_dirty_buffers, 0), "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1477 }, +{ PROC_LINKS(delete_file_query, 0), "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\\4coder_base_commands.cpp", 36, 1502 }, +{ PROC_LINKS(save_to_query, 0), "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\\4coder_base_commands.cpp", 36, 1542 }, +{ PROC_LINKS(rename_file_query, 0), "rename_file_query", 17, "Queries the user for a new name and renames the file of the current buffer, altering the buffer's name too.", 107, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1580 }, +{ PROC_LINKS(make_directory_query, 0), "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1623 }, +{ PROC_LINKS(move_line_up, 0), "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\\4coder_base_commands.cpp", 36, 1646 }, +{ PROC_LINKS(move_line_down, 0), "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\\4coder_base_commands.cpp", 36, 1711 }, +{ PROC_LINKS(duplicate_line, 0), "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1733 }, +{ PROC_LINKS(delete_line, 0), "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1751 }, +{ PROC_LINKS(open_file_in_quotes, 0), "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1843 }, +{ PROC_LINKS(open_matching_file_cpp, 0), "open_matching_file_cpp", 22, "If the current file is a *.cpp or *.h, attempts to open the corresponding *.h or *.cpp file in the other view.", 110, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1881 }, +{ PROC_LINKS(view_buffer_other_panel, 0), "view_buffer_other_panel", 23, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1896 }, +{ PROC_LINKS(swap_buffers_between_panels, 0), "swap_buffers_between_panels", 27, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1911 }, +{ PROC_LINKS(kill_buffer, 0), "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1956 }, +{ PROC_LINKS(save, 0), "save", 4, "Saves the current buffer.", 25, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1966 }, +{ PROC_LINKS(reopen, 0), "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1980 }, +{ PROC_LINKS(undo, 0), "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 2044 }, +{ PROC_LINKS(redo, 0), "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 2060 }, +{ PROC_LINKS(undo_all_buffers, 0), "undo_all_buffers", 16, "Advances backward through the undo history in the buffer containing the most recent regular edit.", 97, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 2078 }, +{ PROC_LINKS(redo_all_buffers, 0), "redo_all_buffers", 16, "Advances forward through the undo history in the buffer containing the most recent regular edit.", 96, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 2157 }, +{ PROC_LINKS(open_in_other, 0), "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 2267 }, { PROC_LINKS(lister__quit, 0), "lister__quit", 12, "A lister mode command that quits the list without executing any actions.", 72, "w:\\4ed\\code\\4coder_lists.cpp", 28, 8 }, { PROC_LINKS(lister__activate, 0), "lister__activate", 16, "A lister mode command that activates the list's action on the highlighted item.", 79, "w:\\4ed\\code\\4coder_lists.cpp", 28, 16 }, { PROC_LINKS(lister__write_character, 0), "lister__write_character", 23, "A lister mode command that dispatches to the lister's write character handler.", 78, "w:\\4ed\\code\\4coder_lists.cpp", 28, 32 }, @@ -394,10 +394,10 @@ static Command_Metadata fcoder_metacmd_table[234] = { { PROC_LINKS(interactive_new, 0), "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\4coder_lists.cpp", 28, 885 }, { PROC_LINKS(interactive_open, 0), "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\4coder_lists.cpp", 28, 919 }, { PROC_LINKS(command_lister, 0), "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "w:\\4ed\\code\\4coder_lists.cpp", 28, 1004 }, -{ PROC_LINKS(auto_tab_whole_file, 0), "auto_tab_whole_file", 19, "Audo-indents the entire current buffer.", 39, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 606 }, -{ PROC_LINKS(auto_tab_line_at_cursor, 0), "auto_tab_line_at_cursor", 23, "Auto-indents the line on which the cursor sits.", 47, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 619 }, -{ PROC_LINKS(auto_tab_range, 0), "auto_tab_range", 14, "Auto-indents the range between the cursor and the mark.", 55, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 633 }, -{ PROC_LINKS(write_and_auto_tab, 0), "write_and_auto_tab", 18, "Inserts a character and auto-indents the line on which the cursor sits.", 71, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 646 }, +{ PROC_LINKS(auto_tab_whole_file, 0), "auto_tab_whole_file", 19, "Audo-indents the entire current buffer.", 39, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 608 }, +{ PROC_LINKS(auto_tab_line_at_cursor, 0), "auto_tab_line_at_cursor", 23, "Auto-indents the line on which the cursor sits.", 47, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 621 }, +{ PROC_LINKS(auto_tab_range, 0), "auto_tab_range", 14, "Auto-indents the range between the cursor and the mark.", 55, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 635 }, +{ PROC_LINKS(write_and_auto_tab, 0), "write_and_auto_tab", 18, "Inserts a character and auto-indents the line on which the cursor sits.", 71, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 648 }, { PROC_LINKS(list_all_locations, 0), "list_all_locations", 18, "Queries the user for a string and lists all exact case-sensitive matches found in all open buffers.", 99, "w:\\4ed\\code\\4coder_search.cpp", 29, 723 }, { PROC_LINKS(list_all_substring_locations, 0), "list_all_substring_locations", 28, "Queries the user for a string and lists all case-sensitive substring matches found in all open buffers.", 103, "w:\\4ed\\code\\4coder_search.cpp", 29, 730 }, { PROC_LINKS(list_all_locations_case_insensitive, 0), "list_all_locations_case_insensitive", 35, "Queries the user for a string and lists all exact case-insensitive matches found in all open buffers.", 101, "w:\\4ed\\code\\4coder_search.cpp", 29, 737 }, diff --git a/4coder_helper.cpp b/4coder_helper.cpp index afcf110f..a099f721 100644 --- a/4coder_helper.cpp +++ b/4coder_helper.cpp @@ -622,187 +622,257 @@ buffer_get_all_tokens(Application_Links *app, Arena *arena, Buffer_ID buffer_id) //////////////////////////////// static i32 -scan_to_word_boundary(Application_Links *app, Buffer_ID buffer, i32 pos, - Scan_Direction direction, Character_Predicate *predicate){ +scan_any_boundary(Application_Links *app, Boundary_Function *func, Buffer_ID buffer, Scan_Direction direction, i32 pos){ + i32 a = func(app, buffer, Side_Min, direction, pos); + i32 b = func(app, buffer, Side_Max, direction, pos); i32 result = 0; - switch (direction){ - case Scan_Backward: - { - result = buffer_seek_character_class_change_0_1(app, buffer, predicate, Scan_Backward, pos); - }break; - case Scan_Forward: - { - result = buffer_seek_character_class_change_1_0(app, buffer, predicate, Scan_Forward, pos); - }break; - } - return(result); -} - -static i32 -scan_to_alpha_numeric_camel_forward(Application_Links *app, Buffer_ID buffer, i32 pos){ - i32 an_pos = scan_to_word_boundary(app, buffer, pos, - Scan_Forward, &character_predicate_alpha_numeric); - i32 an_left_pos = scan_to_word_boundary(app, buffer, an_pos, - Scan_Backward, &character_predicate_alpha_numeric); - i32 cap_pos = 0; - buffer_seek_character_class(app, buffer, &character_predicate_uppercase, - Scan_Forward, pos, &cap_pos); - if (cap_pos == an_left_pos){ - buffer_seek_character_class(app, buffer, &character_predicate_uppercase, - Scan_Forward, cap_pos, &cap_pos); - } - return(Min(an_pos, cap_pos)); -} - -static i32 -scan_to_alpha_numeric_camel_backward(Application_Links *app, Buffer_ID buffer, i32 pos){ - i32 an_pos = scan_to_word_boundary(app, buffer, pos, - Scan_Backward, &character_predicate_alpha_numeric); - i32 cap_pos = 0; - buffer_seek_character_class(app, buffer, &character_predicate_uppercase, - Scan_Backward, pos, &cap_pos); - return(Max(cap_pos, an_pos)); -} - -static i32 -scan_to_alpha_numeric_camel(Application_Links *app, Buffer_ID buffer, i32 pos, Scan_Direction direction){ - i32 result = 0; - switch (direction){ - case Scan_Forward: - { - result = scan_to_alpha_numeric_camel_forward(app, buffer, pos); - }break; - case Scan_Backward: - { - result = scan_to_alpha_numeric_camel_backward(app, buffer, pos); - }break; - } - return(result); -} - -static i32 -scan_to_token_forward(Cpp_Token_Array tokens, i32 pos, i32 buffer_size){ - if (tokens.count > 0){ - Cpp_Token *token = get_first_token_from_pos(tokens, pos); - if (token != 0){ - pos = token->start + token->size; - } - else{ - pos = buffer_size; - } + if (direction == Scan_Forward){ + result = Min(a, b); } else{ - pos = buffer_size; - } - return(pos); -} - -static i32 -scan_to_token_backward(Cpp_Token_Array tokens, i32 pos){ - if (tokens.count > 0){ - Cpp_Token *token = get_first_token_from_pos(tokens, pos); - if (token == 0){ - token = tokens.tokens + tokens.count - 1; - pos = token->start; - } - else{ - if (token->start < pos){ - pos = token->start; - } - else{ - if (token > tokens.tokens){ - pos = (token - 1)->start; - } - else{ - pos = 0; - } - } - } - } - else{ - pos = 0; - } - return(pos); -} - -static i32 -scan_to_token(Cpp_Token_Array tokens, i32 pos, i32 buffer_size, Scan_Direction direction){ - i32 result = 0; - switch (direction){ - case Scan_Forward: - { - result = scan_to_token_forward(tokens, pos, buffer_size); - }break; - case Scan_Backward: - { - result = scan_to_token_backward(tokens, pos); - }break; + result = Max(a, b); } return(result); } static i32 -scan_to_word_boundary(Application_Links *app, Buffer_ID buffer, i32 start_pos, - Scan_Direction direction, Seek_Boundary_Flag flags){ +scan(Application_Links *app, Boundary_Function *func, Buffer_ID buffer, Scan_Direction direction, i32 pos){ + Side side = (direction == Scan_Forward)?(Side_Max):(Side_Min); + return(func(app, buffer, side, direction, pos)); +} + +static i32 +scan(Application_Links *app, Boundary_Function_List funcs, Buffer_ID buffer, Scan_Direction direction, i32 start_pos){ i32 result = 0; - - Scratch_Block scratch(app); - if (buffer_exists(app, buffer)){ + if (direction == Scan_Forward){ i32 size = 0; buffer_get_size(app, buffer, &size); - - i32 dummy_pos = -1; - if (direction == Scan_Forward){ - dummy_pos = size + 1; + result = size + 1; + for (Boundary_Function_Node *node = funcs.first; + node != 0; + node = node->next){ + i32 pos = scan(app, node->func, buffer, direction, start_pos); + result = Min(result, pos); } - - i32 pos[4]; - for (i32 i = 0; i < ArrayCount(pos); ++i){ - pos[i] = dummy_pos; + } + else{ + result = -1; + for (Boundary_Function_Node *node = funcs.first; + node != 0; + node = node->next){ + i32 pos = scan(app, node->func, buffer, direction, start_pos); + result = Max(result, pos); } - start_pos = clamp(0, start_pos, size); - - if (flags & BoundaryWhitespace){ - pos[0] = scan_to_word_boundary(app, buffer, start_pos, direction, - &character_predicate_non_whitespace); + } + return(result); +} + +static void +push_boundary(Arena *arena, Boundary_Function_List *list, Boundary_Function *func){ + Boundary_Function_Node *node = push_array(arena, Boundary_Function_Node, 1); + sll_queue_push(list->first, list->last, node); + list->count += 1; + node->func = func; +} + +static Boundary_Function_List +push_boundary_list__innerv(Arena *arena, va_list args){ + Boundary_Function_List list = {}; + for (;;){ + Boundary_Function *func = va_arg(args, Boundary_Function*); + if (func == 0){ + break; } - - if (flags & BoundaryToken){ - if (buffer_tokens_are_ready(app, buffer)){ - Cpp_Token_Array array = buffer_get_all_tokens(app, scratch, buffer); - pos[1] = scan_to_token(array, start_pos, size, direction); - } - else{ - pos[1] = scan_to_word_boundary(app, buffer, start_pos, direction, - &character_predicate_non_whitespace); - } + push_boundary(arena, &list, func); + } + return(list); +} +static Boundary_Function_List +push_boundary_list__inner(Arena *arena, ...){ + va_list args; + va_start(args, arena); + Boundary_Function_List result = push_boundary_list__innerv(arena, args); + va_end(args); + return(result); +} +#define push_boundary_list(a,...) push_boundary_list__inner((a), __VA_ARGS__, 0) + +static i32 +boundary_predicate(Application_Links *app, Buffer_ID buffer, Side side, Scan_Direction direction, i32 pos, Character_Predicate *predicate){ + i32 result = 0; + switch (side){ + case Side_Min: + { + result = buffer_seek_character_class_change_0_1(app, buffer, predicate, direction, pos); + }break; + case Side_Max: + { + result = buffer_seek_character_class_change_1_0(app, buffer, predicate, direction, pos); + }break; + } + return(result); +} + +static i32 +boundary_non_whitespace(Application_Links *app, Buffer_ID buffer, Side side, Scan_Direction direction, i32 pos){ + return(boundary_predicate(app, buffer, side, direction, pos, &character_predicate_non_whitespace)); +} + +static i32 +boundary_alpha_numeric(Application_Links *app, Buffer_ID buffer, Side side, Scan_Direction direction, i32 pos){ + return(boundary_predicate(app, buffer, side, direction, pos, &character_predicate_alpha_numeric)); +} + +static i32 +boundary_alpha_numeric_underscore(Application_Links *app, Buffer_ID buffer, Side side, Scan_Direction direction, i32 pos){ + return(boundary_predicate(app, buffer, side, direction, pos, + &character_predicate_alpha_numeric_underscore)); +} + +static i32 +boundary_alpha_numeric_camel(Application_Links *app, Buffer_ID buffer, Side side, Scan_Direction direction, i32 pos){ + i32 an_pos = boundary_alpha_numeric(app, buffer, side, direction, pos); + i32 cap_pos = 0; + buffer_seek_character_class(app, buffer, &character_predicate_uppercase, + direction, pos, &cap_pos); + if (side == Side_Max){ + i32 an_left_pos = boundary_alpha_numeric(app, buffer, flip_side(side), + flip_direction(direction), an_pos); + if (cap_pos == an_left_pos){ + buffer_seek_character_class(app, buffer, &character_predicate_uppercase, + direction, cap_pos, &cap_pos); } - - if (flags & BoundaryAlphanumeric){ - pos[2] = scan_to_word_boundary(app, buffer, start_pos, direction, - &character_predicate_alpha_numeric); - } - - if (flags & BoundaryCamelCase){ - pos[3] = scan_to_alpha_numeric_camel(app, buffer, start_pos, direction); - } - - result = dummy_pos; - if (direction == Scan_Forward){ - for (i32 i = 0; i < ArrayCount(pos); ++i){ - result = Min(result, pos[i]); - } - } - else{ - for (i32 i = 0; i < ArrayCount(pos); ++i){ - result = Max(result, pos[i]); - } + } + i32 result = 0; + if (direction == Scan_Backward){ + result = Max(an_pos, cap_pos); + } + else{ + result = Min(an_pos, cap_pos); + } + return(result); +} + +static i32 +boundary_token(Application_Links *app, Buffer_ID buffer, Side side, Scan_Direction direction, i32 pos){ + i32 result = 0; + if (!buffer_tokens_are_ready(app, buffer)){ + result = boundary_non_whitespace(app, buffer, side, direction, pos); + } + else{ + Cpp_Token *first_token = 0; + Cpp_Token *last_token = 0; + buffer_get_token_range(app, buffer, &first_token, &last_token); + Cpp_Token_Array tokens = {first_token, (i32)(last_token - first_token)}; + switch (direction){ + case Scan_Forward: + { + i32 buffer_size = 0; + buffer_get_size(app, buffer, &buffer_size); + if (tokens.count > 0){ + Cpp_Token *token = get_first_token_from_pos(tokens, pos); + if (token != 0){ + if (side == Side_Max){ + result = token->start + token->size; + } + else{ + if (token->start > pos){ + result = token->start; + } + else{ + token += 1; + if (token < tokens.tokens + tokens.count){ + result = token->start; + } + else{ + result = buffer_size; + } + } + } + } + else{ + result = buffer_size; + } + } + else{ + result = buffer_size; + } + }break; + + case Scan_Backward: + { + if (tokens.count > 0){ + Cpp_Token *token = get_first_token_from_pos(tokens, pos); + if (side == Side_Min){ + if (token == 0){ + token = tokens.tokens + tokens.count - 1; + result = token->start; + } + else{ + if (token->start < pos){ + result = token->start; + } + else{ + token -= 1; + if (token >= tokens.tokens){ + result = token->start; + } + else{ + result = 0; + } + } + } + } + else{ + if (token == 0){ + token = tokens.tokens + tokens.count - 1; + result = token->start + token->size; + } + else{ + token -= 1; + if (token >= tokens.tokens && token->start + token->size == pos){ + token -= 1; + } + if (token >= tokens.tokens){ + result = token->start + token->size; + } + else{ + result = 0; + } + } + } + } + else{ + result = 0; + } + }break; } } return(result); } +static i32 +boundary_line(Application_Links *app, Buffer_ID buffer, Side side, Scan_Direction direction, i32 pos){ + i32 line_number = get_line_number_from_pos(app, buffer, pos); + i32 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){ + buffer_get_size(app, buffer, &new_pos); + } + } + return(new_pos); +} + //////////////////////////////// static Range @@ -830,68 +900,62 @@ get_pos_range_from_line_range(Application_Links *app, Buffer_ID buffer, Range li return(pos_range); } +static Range +enclose_boundary(Application_Links *app, Buffer_ID buffer, Range range, Boundary_Function *func){ + i32 new_min = func(app, buffer, Side_Min, Scan_Backward, range.min + 1); + i32 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; + } + i32 new_max = func(app, buffer, Side_Max, Scan_Forward, range.max - 1); + i32 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); +} + +static Range +enclose_non_whitespace(Application_Links *app, Buffer_ID buffer, Range range){ + return(enclose_boundary(app, buffer, range, boundary_non_whitespace)); +} + +static Range +enclose_tokens(Application_Links *app, Buffer_ID buffer, Range range){ + return(enclose_boundary(app, buffer, range, boundary_token)); +} + +static Range +enclose_alpha_numeric(Application_Links *app, Buffer_ID buffer, Range range){ + return(enclose_boundary(app, buffer, range, boundary_alpha_numeric)); +} + +static Range +enclose_alpha_numeric_underscore(Application_Links *app, Buffer_ID buffer, Range range){ + return(enclose_boundary(app, buffer, range, boundary_alpha_numeric_underscore)); +} + +static Range +enclose_alpha_numeric_camel(Application_Links *app, Buffer_ID buffer, Range range){ + return(enclose_boundary(app, buffer, range, boundary_alpha_numeric_camel)); +} + static Range pos_range_enclose_whole_lines(Application_Links *app, Buffer_ID buffer, Range range){ - Range line_range = get_line_range_from_pos_range(app, buffer, range); - return(get_pos_range_from_line_range(app, buffer, line_range)); + return(enclose_boundary(app, buffer, range, boundary_line)); } -static Range -pos_range_enclose_whole_tokens(Application_Links *app, Cpp_Token_Array tokens, Range range){ - if (range_size(range) > 0){ - if (tokens.count > 0){ - Cpp_Token *first_token = get_first_token_from_pos(tokens, range.first); - if (first_token != 0 && first_token->start < range.first){ - range.first = first_token->start; - } - Cpp_Token *last_token = get_first_token_from_pos(tokens, range.one_past_last - 1); - if (last_token != 0 && last_token->start < range.one_past_last){ - range.one_past_last = last_token->start + last_token->size; - } - } - } - return(range); -} +//////////////////////////////// static Range -pos_range_enclose__within_delimiter_class(Application_Links *app, Buffer_ID buffer, Range range, Character_Predicate *predicate){ - i32 new_pos = 0; - if (buffer_seek_character_class(app, buffer, predicate, Scan_Backward, range.min + 1, &new_pos)){ - range.first = new_pos + 1; - } - if (buffer_seek_character_class(app, buffer, predicate, Scan_Forward, range.max - 1, &new_pos)){ - range.one_past_last = new_pos; - } - return(range); -} - -static Range -pos_range_enclose_non_whitespace(Application_Links *app, Buffer_ID buffer, Range range){ - return(pos_range_enclose__within_delimiter_class(app, buffer, range, - &character_predicate_whitespace)); -} - -static Range -pos_range_enclose_alpha_numeric(Application_Links *app, Buffer_ID buffer, Range range){ - Character_Predicate negative = character_predicate_not(&character_predicate_alpha_numeric); - return(pos_range_enclose__within_delimiter_class(app, buffer, range, &negative)); -} - -static Range -pos_range_enclose_alpha_numeric_underscore(Application_Links *app, Buffer_ID buffer, Range range){ - Character_Predicate negative = character_predicate_not(&character_predicate_alpha_numeric_underscore); - return(pos_range_enclose__within_delimiter_class(app, buffer, range, &negative)); -} - -static Range -get_snipe_range(Application_Links *app, Buffer_ID buffer, i32 pos, Scan_Direction direction, Seek_Boundary_Flag flags){ +get_snipe_range(Application_Links *app, Boundary_Function_List funcs, Buffer_ID buffer, i32 pos, Scan_Direction direction){ Range result = {}; i32 buffer_size = 0; buffer_get_size(app, buffer, &buffer_size); i32 pos0 = pos; - i32 pos1 = scan_to_word_boundary(app, buffer, pos0, direction, flags); + i32 pos1 = scan(app, funcs, buffer, direction, pos0); if (0 <= pos1 && pos1 <= buffer_size){ - i32 pos2 = scan_to_word_boundary(app, buffer, pos1, flip_direction(direction), flags); + i32 pos2 = scan(app, funcs, buffer, flip_direction(direction), pos1); if (0 <= pos2 && pos2 <= buffer_size){ if (direction == Scan_Backward){ pos2 = clamp_bot(pos2, pos0); @@ -905,6 +969,12 @@ get_snipe_range(Application_Links *app, Buffer_ID buffer, i32 pos, Scan_Directio return(result); } +static Range +get_snipe_range(Application_Links *app, Boundary_Function *func, Buffer_ID buffer, i32 pos, Scan_Direction direction){ + Scratch_Block scratch(app); + return(get_snipe_range(app, push_boundary_list(scratch, func), buffer, pos, direction)); +} + //////////////////////////////// static String_Const_u8 @@ -959,26 +1029,8 @@ push_string_in_view_range(Application_Links *app, Arena *arena, View_ID view){ } static String_Const_u8 -push_non_whitespace_word_at_pos(Application_Links *app, Arena *arena, Buffer_ID buffer, i32 pos){ - Range range = pos_range_enclose_non_whitespace(app, buffer, make_range(pos)); - return(push_buffer_range(app, arena, buffer, range)); -} - -static String_Const_u8 -push_alpha_numeric_word_at_pos(Application_Links *app, Arena *arena, Buffer_ID buffer, i32 pos){ - Range range = pos_range_enclose_alpha_numeric(app, buffer, make_range(pos)); - return(push_buffer_range(app, arena, buffer, range)); -} - -static String_Const_u8 -push_alpha_numeric_underscore_word_at_pos(Application_Links *app, Arena *arena, Buffer_ID buffer, i32 pos){ - Range range = pos_range_enclose_alpha_numeric_underscore(app, buffer, make_range(pos)); - return(push_buffer_range(app, arena, buffer, range)); -} - -static String_Const_u8 -push_token_at_pos(Application_Links *app, Arena *arena, Buffer_ID buffer, Cpp_Token_Array tokens, i32 pos){ - Range range = pos_range_enclose_whole_tokens(app, tokens, make_range(pos)); +push_enclose_range_at_pos(Application_Links *app, Arena *arena, Buffer_ID buffer, i32 pos, Enclose_Function *enclose){ + Range range = enclose(app, buffer, make_range(pos)); return(push_buffer_range(app, arena, buffer, range)); } diff --git a/4coder_helper.h b/4coder_helper.h index 64659897..d185163d 100644 --- a/4coder_helper.h +++ b/4coder_helper.h @@ -105,14 +105,19 @@ global Character_Predicate character_predicate_utf8_byte = { { 255, 255, 255, 255, 255, 255, 255, 255, } }; -/* DOC(A Seek_Boundary_Flag field specifies a set of "boundary" types used in seeks for the beginning or end of different types of words.) */ -typedef u32 Seek_Boundary_Flag; -enum{ - BoundaryWhitespace = 0x1, - BoundaryToken = 0x2, - BoundaryAlphanumeric = 0x4, - BoundaryCamelCase = 0x8 +typedef i32 Boundary_Function(Application_Links *app, Buffer_ID buffer, Side side, Scan_Direction direction, i32 pos); + +struct Boundary_Function_Node{ + Boundary_Function_Node *next; + Boundary_Function *func; }; +struct Boundary_Function_List{ + Boundary_Function_Node *first; + Boundary_Function_Node *last; + i32 count; +}; + +typedef Range Enclose_Function(Application_Links *app, Buffer_ID buffer, Range range); ////////////////////////////////