Generalizing the ideas of 'stop spots' and 'enclose' operations even more

This commit is contained in:
Allen Webster 2019-06-10 22:01:57 -07:00
parent 0516c94afc
commit 7e3bcf04a8
8 changed files with 516 additions and 388 deletions

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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);
}

View File

@ -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 },

View File

@ -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){
i32 result = 0;
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));
}
Scratch_Block scratch(app);
if (buffer_exists(app, buffer)){
static i32
scan(Application_Links *app, Boundary_Function_List funcs, Buffer_ID buffer, Scan_Direction direction, i32 start_pos){
i32 result = 0;
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);
}
return(result);
}
if (flags & BoundaryWhitespace){
pos[0] = scan_to_word_boundary(app, buffer, start_pos, direction,
&character_predicate_non_whitespace);
}
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;
}
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);
}
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;
}
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)
if (flags & BoundaryAlphanumeric){
pos[2] = scan_to_word_boundary(app, buffer, start_pos, direction,
&character_predicate_alpha_numeric);
}
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);
}
if (flags & BoundaryCamelCase){
pos[3] = scan_to_alpha_numeric_camel(app, buffer, start_pos, direction);
}
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));
}
result = dummy_pos;
if (direction == Scan_Forward){
for (i32 i = 0; i < ArrayCount(pos); ++i){
result = Min(result, pos[i]);
}
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);
}
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));
}

View File

@ -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);
////////////////////////////////