diff --git a/custom/4coder_clipboard.cpp b/custom/4coder_clipboard.cpp index 9bfd0a18..20e29b29 100644 --- a/custom/4coder_clipboard.cpp +++ b/custom/4coder_clipboard.cpp @@ -45,8 +45,8 @@ CUSTOM_DOC("At the cursor, insert the text at the top of the clipboard.") if_view_has_highlighted_range_delete_range(app, view); Managed_Scope scope = view_get_managed_scope(app, view); - Rewrite_Type *rewrite = scope_attachment(app, scope, view_next_rewrite_loc, Rewrite_Type); - *rewrite = Rewrite_Paste; + Rewrite_Type *next_rewrite = scope_attachment(app, scope, view_next_rewrite_loc, Rewrite_Type); + *next_rewrite = Rewrite_Paste; i32 *paste_index = scope_attachment(app, scope, view_paste_index_loc, i32); *paste_index = 0; @@ -81,11 +81,11 @@ CUSTOM_DOC("If the previous command was paste or paste_next, replaces the paste Managed_Scope scope = view_get_managed_scope(app, view); no_mark_snap_to_cursor(app, scope); - Rewrite_Type *next_rewrite = scope_attachment(app, scope, view_next_rewrite_loc, Rewrite_Type); - *next_rewrite = Rewrite_Paste; - Rewrite_Type *rewrite = scope_attachment(app, scope, view_next_rewrite_loc, Rewrite_Type); if (*rewrite == Rewrite_Paste){ + Rewrite_Type *next_rewrite = scope_attachment(app, scope, view_next_rewrite_loc, Rewrite_Type); + *next_rewrite = Rewrite_Paste; + i32 *paste_index_ptr = scope_attachment(app, scope, view_paste_index_loc, i32); i32 paste_index = (*paste_index_ptr) + 1; *paste_index_ptr = paste_index; diff --git a/custom/4coder_default_hooks.cpp b/custom/4coder_default_hooks.cpp index 3975f208..d191f78c 100644 --- a/custom/4coder_default_hooks.cpp +++ b/custom/4coder_default_hooks.cpp @@ -76,7 +76,7 @@ get_enclosure_ranges(Application_Links *app, Arena *arena, Buffer_ID buffer, i64 array.ranges = push_array(arena, Range_i64, max); for (;;){ Range_i64 range = {}; - if (find_scope_range(app, buffer, pos, &range, flags)){ + if (find_surrounding_nest(app, buffer, pos, flags, &range)){ array.ranges[array.count] = range; array.count += 1; pos = range.first; @@ -390,7 +390,7 @@ default_buffer_render_caller(Application_Links *app, Frame_Info frame_info, View colors[i] = Stag_Back_Cycle_1 + i; } draw_enclosures(app, text_layout_id, buffer, - cursor_pos, FindScope_Scope, RangeHighlightKind_LineHighlight, + cursor_pos, FindNest_Scope, RangeHighlightKind_LineHighlight, colors, 0, color_count); } @@ -435,7 +435,7 @@ default_buffer_render_caller(Application_Links *app, Frame_Info frame_info, View colors[i] = Stag_Text_Cycle_1 + i; } draw_enclosures(app, text_layout_id, buffer, - cursor_pos, FindScope_Paren, RangeHighlightKind_CharacterHighlight, + cursor_pos, FindNest_Paren, RangeHighlightKind_CharacterHighlight, 0, colors, color_count); } diff --git a/custom/4coder_helper.cpp b/custom/4coder_helper.cpp index 6c7dd9ea..6d1ad8cf 100644 --- a/custom/4coder_helper.cpp +++ b/custom/4coder_helper.cpp @@ -1694,6 +1694,63 @@ buffer_identifier_to_id_create_out_buffer(Application_Links *app, Buffer_Identif //////////////////////////////// +function void +place_begin_and_end_on_own_lines(Application_Links *app, char *begin, char *end){ + View_ID view = get_active_view(app, AccessOpen); + Buffer_ID buffer = view_get_buffer(app, view, AccessOpen); + + Range_i64 range = get_view_range(app, view); + Range_i64 lines = get_line_range_from_pos_range(app, buffer, range); + range = get_pos_range_from_line_range(app, buffer, lines); + + Scratch_Block scratch(app); + + b32 min_line_blank = line_is_valid_and_blank(app, buffer, lines.min); + b32 max_line_blank = line_is_valid_and_blank(app, buffer, lines.max); + + if ((lines.min < lines.max) || (!min_line_blank)){ + String_Const_u8 begin_str = {}; + String_Const_u8 end_str = {}; + + i64 min_adjustment = 0; + i64 max_adjustment = 0; + + if (min_line_blank){ + begin_str = push_u8_stringf(scratch, "\n%s", begin); + min_adjustment += 1; + } + else{ + begin_str = push_u8_stringf(scratch, "%s\n", begin); + } + if (max_line_blank){ + end_str = push_u8_stringf(scratch, "%s\n", end); + } + else{ + end_str = push_u8_stringf(scratch, "\n%s", end); + max_adjustment += 1; + } + + max_adjustment += begin_str.size; + Range_i64 new_pos = Ii64(range.min + min_adjustment, range.max + max_adjustment); + + History_Group group = history_group_begin(app, buffer); + buffer_replace_range(app, buffer, Ii64(range.min), begin_str); + buffer_replace_range(app, buffer, Ii64(range.max + begin_str.size), end_str); + history_group_end(group); + + set_view_range(app, view, new_pos); + } + else{ + String_Const_u8 str = push_u8_stringf(scratch, "%s\n\n%s", begin, end); + buffer_replace_range(app, buffer, range, str); + i64 center_pos = range.min + cstring_length(begin) + 1; + view_set_cursor_and_preferred_x(app, view, seek_pos(center_pos)); + view_set_mark(app, view, seek_pos(center_pos)); + } +} + +//////////////////////////////// + internal View_ID open_view(Application_Links *app, View_ID view_location, View_Split_Position position){ View_ID result = 0; @@ -1798,6 +1855,59 @@ view_set_highlight_range(Application_Links *app, View_ID view, Range_i64 range){ *highlight_buffer = buffer; } +function void +view_look_at_region(Application_Links *app, View_ID view, i64 major_pos, i64 minor_pos){ + Range_i64 range = Ii64(major_pos, minor_pos); + b32 bottom_major = false; + if (major_pos == range.max){ + bottom_major = true; + } + + Buffer_Cursor top = view_compute_cursor(app, view, seek_pos(range.min)); + if (top.line > 0){ + Buffer_Cursor bottom = view_compute_cursor(app, view, seek_pos(range.max)); + if (bottom.line > 0){ + Rect_f32 region = view_get_buffer_region(app, view); + f32 view_height = rect_height(region); + f32 skirt_height = view_height*.1f; + Interval_f32 acceptable_y = If32(skirt_height, view_height*.9f); + + f32 target_height = view_line_y_difference(app, view, bottom.line, top.line); + + if (target_height > view_height){ + i64 major_line = bottom.line; + if (range.min == major_pos){ + major_line = top.line; + } + + Buffer_Scroll scroll = view_get_buffer_scroll(app, view); + scroll.target.line_number = major_line; + scroll.target.pixel_shift.y = -skirt_height; + view_set_buffer_scroll(app, view, scroll); + } + else{ + Buffer_Scroll scroll = view_get_buffer_scroll(app, view); + Vec2_f32 top_p = view_relative_xy_of_pos(app, view, scroll.position.line_number, range.min); + top_p -= scroll.position.pixel_shift; + if (top_p.y < acceptable_y.min){ + scroll.target.line_number = top.line; + scroll.target.pixel_shift.y = -skirt_height; + view_set_buffer_scroll(app, view, scroll); + } + else{ + Vec2_f32 bot_p = view_relative_xy_of_pos(app, view, scroll.position.line_number, range.max); + bot_p -= scroll.position.pixel_shift; + if (bot_p.y > acceptable_y.max){ + scroll.target.line_number = bottom.line; + scroll.target.pixel_shift.y = skirt_height - view_height; + view_set_buffer_scroll(app, view, scroll); + } + } + } + } + } +} + //////////////////////////////// internal View_ID diff --git a/custom/4coder_scope_commands.cpp b/custom/4coder_scope_commands.cpp index 5666f865..d063bfd6 100644 --- a/custom/4coder_scope_commands.cpp +++ b/custom/4coder_scope_commands.cpp @@ -5,317 +5,124 @@ // TOP function Nest_Delimiter_Kind -get_nest_delimiter_kind(Token_Base_Kind kind, Find_Scope_Flag flags){ - Nest_Delimiter_Kind result = NestDelimiterKind_None; +get_nest_delimiter_kind(Token_Base_Kind kind, Find_Nest_Flag flags){ + Nest_Delimiter_Kind result = NestDelim_None; switch (kind){ case TokenBaseKind_ScopeOpen: { - if (HasFlag(flags, FindScope_Scope)){ - result = NestDelimiterKind_Open; + if (HasFlag(flags, FindNest_Scope)){ + result = NestDelim_Open; } }break; case TokenBaseKind_ScopeClose: { - if (HasFlag(flags, FindScope_Scope)){ - result = NestDelimiterKind_Close; + if (HasFlag(flags, FindNest_Scope)){ + result = NestDelim_Close; } }break; case TokenBaseKind_ParentheticalOpen: { - if (HasFlag(flags, FindScope_Paren)){ - result = NestDelimiterKind_Open; + if (HasFlag(flags, FindNest_Paren)){ + result = NestDelim_Open; } }break; case TokenBaseKind_ParentheticalClose: { - if (HasFlag(flags, FindScope_Paren)){ - result = NestDelimiterKind_Close; + if (HasFlag(flags, FindNest_Paren)){ + result = NestDelim_Close; } }break; } return(result); } -static b32 -find_scope_top(Application_Links *app, Buffer_ID buffer, i64 start_pos, u32 flags, i64 *end_pos_out){ - b32 success = false; - Token_Array array = get_token_array_from_buffer(app, buffer); - if (array.tokens != 0){ - i64 position = start_pos; - i64 token_index = token_index_from_pos(&array, start_pos); - Token_Iterator_Array it = token_iterator_index(buffer, &array, token_index); - b32 good_status = true; - if (HasFlag(flags, FindScope_Parent)){ - good_status = token_it_dec(&it); - } - i32 nest_level = 0; - for (;good_status;){ - Token *token = token_it_read(&it); - Nest_Delimiter_Kind delim = get_nest_delimiter_kind(token->kind, flags); - switch (delim){ - case NestDelimiterKind_Open: - { - if (nest_level == 0){ - success = true; - position = token->pos; - if (HasFlag(flags, FindScope_EndOfToken)){ - position += token->size; - } - goto finished; - } - else{ - --nest_level; - } - }break; - case NestDelimiterKind_Close: - { - ++nest_level; - }break; - } - good_status = token_it_dec(&it); - } - finished:; - *end_pos_out = position; - } - return(success); -} - -static b32 -find_scope_bottom(Application_Links *app, Buffer_ID buffer, i64 start_pos, u32 flags, i64 *end_pos_out){ - b32 success = false; - Token_Array array = get_token_array_from_buffer(app, buffer); - if (array.tokens != 0){ - i64 position = start_pos; - i64 token_index = token_index_from_pos(&array, start_pos); - Token_Iterator_Array it = token_iterator_index(buffer, &array, token_index); - token_it_inc(&it); - if (HasFlag(flags, FindScope_Parent)){ - token_it_dec(&it); - } - b32 good_status = true; - i32 nest_level = 0; - for (;good_status;){ - Token *token = token_it_read(&it); - Nest_Delimiter_Kind delim = get_nest_delimiter_kind(token->kind, flags); - switch (delim){ - case NestDelimiterKind_Open: - { - ++nest_level; - }break; - case NestDelimiterKind_Close: - { - if (nest_level == 0){ - success = true; - position = token->pos; - if (HasFlag(flags, FindScope_EndOfToken)){ - position += token->size; - } - goto finished; - } - else{ - --nest_level; - } - }break; - } - good_status = token_it_inc(&it); - } - finished:; - *end_pos_out = position; - } - return(success); -} - -static b32 -find_next_scope(Application_Links *app, Buffer_ID buffer, i64 start_pos, u32 flags, i64 *end_pos_out){ - b32 success = false; - Token_Array array = get_token_array_from_buffer(app, buffer); - if (array.tokens != 0){ - i64 position = start_pos; - i64 token_index = token_index_from_pos(&array, start_pos); - Token_Iterator_Array it = token_iterator_index(buffer, &array, token_index); - token_it_inc(&it); - if (HasFlag(flags, FindScope_NextSibling)){ - b32 good_status = true; - i32 nest_level = 1; - for (;good_status;){ - Token *token = token_it_read(&it); - Nest_Delimiter_Kind delim = get_nest_delimiter_kind(token->kind, flags); - switch (delim){ - case NestDelimiterKind_Open: - { - if (nest_level == 0){ - success = true; - position = token->pos; - if (HasFlag(flags, FindScope_EndOfToken)){ - position += token->size; - } - goto finished; - } - else{ - ++nest_level; - } - }break; - case NestDelimiterKind_Close: - { - --nest_level; - if (nest_level == -1){ - position = start_pos; - goto finished; - } - }break; - } - good_status = token_it_inc(&it); - } - } - else{ - b32 good_status = true; - for (;good_status;){ - Token *token = token_it_read(&it); - Nest_Delimiter_Kind delim = get_nest_delimiter_kind(token->kind, flags); - if (delim == NestDelimiterKind_Open){ - success = true; - position = token->pos; - if (flags & FindScope_EndOfToken){ - position += token->size; - } - goto finished; - } - good_status = token_it_inc(&it); - } - } - finished:; - *end_pos_out = position; - } - return(success); -} - -static b32 -find_prev_scope(Application_Links *app, Buffer_ID buffer, i64 start_pos, u32 flags, i64 *end_pos_out){ - b32 success = false; - Token_Array array = get_token_array_from_buffer(app, buffer); - if (array.tokens != 0){ - i64 position = start_pos; - i64 token_index = token_index_from_pos(&array, start_pos); - Token_Iterator_Array it = token_iterator_index(buffer, &array, token_index); - if (HasFlag(flags, FindScope_NextSibling)){ - b32 status_good = token_it_dec(&it); - i32 nest_level = -1; - for (;status_good;){ - Token *token = token_it_read(&it); - Nest_Delimiter_Kind delim = get_nest_delimiter_kind(token->kind, flags); - switch (delim){ - case NestDelimiterKind_Open: - { - if (nest_level == -1){ - position = start_pos; - goto finished; - } - else if (nest_level == 0){ - success = true; - position = token->pos; - if (HasFlag(flags, FindScope_EndOfToken)){ - position += token->size; - } - goto finished; - } - else{ - --nest_level; - } - }break; - case NestDelimiterKind_Close: - { - ++nest_level; - }break; - } - status_good = token_it_dec(&it); - } - } - else{ - b32 status_good = token_it_dec(&it); - for (;status_good;){ - Token *token = token_it_read(&it); - Nest_Delimiter_Kind delim = get_nest_delimiter_kind(token->kind, flags); - if (delim == NestDelimiterKind_Open){ - success = true; - position = token->pos; - if (HasFlag(flags, FindScope_EndOfToken)){ - position += token->size; - } - goto finished; - } - status_good = token_it_dec(&it); - } - } - finished:; - *end_pos_out = position; - } - return(success); -} - -static b32 -find_scope_range(Application_Links *app, Buffer_ID buffer, i64 start_pos, Range_i64 *range_out, u32 flags){ +function b32 +find_nest_side(Application_Links *app, Buffer_ID buffer, i64 pos, + Find_Nest_Flag flags, Scan_Direction scan, Nest_Delimiter_Kind delim, + Range_i64 *out){ b32 result = false; + + b32 balanced = HasFlag(flags, FindNest_Balanced); + if (balanced){ + if ((delim == NestDelim_Open && scan == Scan_Forward) || + (delim == NestDelim_Close && scan == Scan_Backward)){ + balanced = false; + } + } + + Managed_Scope scope = buffer_get_managed_scope(app, buffer); + Token_Array *tokens = scope_attachment(app, scope, attachment_tokens, Token_Array); + if (tokens != 0 && tokens->count > 0){ + Token_Iterator_Array it = token_iterator_pos(0, tokens, pos); + i32 level = 0; + for (;;){ + Token *token = token_it_read(&it); + Nest_Delimiter_Kind token_delim = get_nest_delimiter_kind(token->kind, flags); + + if (level == 0 && token_delim == delim){ + *out = Ii64_size(token->pos, token->size); + result = true; + break; + } + + if (balanced && token_delim != NestDelim_None){ + level += (token_delim == delim)?-1:1; + } + + b32 good = false; + if (scan == Scan_Forward){ + good = token_it_inc(&it); + } + else{ + good = token_it_dec(&it); + } + if (!good){ + break; + } + } + } + + return(result); +} + +function b32 +find_nest_side(Application_Links *app, Buffer_ID buffer, i64 pos, + Find_Nest_Flag flags, Scan_Direction scan, Nest_Delimiter_Kind delim, + i64 *out){ Range_i64 range = {}; - if (find_scope_top(app, buffer, start_pos, FindScope_Parent|flags, &range.start)){ - if (find_scope_bottom(app, buffer, start_pos, FindScope_Parent|FindScope_EndOfToken|flags, &range.end)){ - *range_out = range; - result = true; + b32 result = find_nest_side(app, buffer, pos, flags, scan, delim, &range); + if (result){ + if (HasFlag(flags, FindNest_EndOfToken)){ + *out = range.end; + } + else{ + *out = range.start; } } return(result); } -static void -view_set_to_region(Application_Links *app, View_ID view, i64 major_pos, i64 minor_pos){ - Range_i64 range = Ii64(major_pos, minor_pos); - b32 bottom_major = false; - if (major_pos == range.max){ - bottom_major = true; - } - - Buffer_Cursor top = view_compute_cursor(app, view, seek_pos(range.min)); - if (top.line > 0){ - Buffer_Cursor bottom = view_compute_cursor(app, view, seek_pos(range.max)); - if (bottom.line > 0){ - Rect_f32 region = view_get_buffer_region(app, view); - f32 view_height = rect_height(region); - f32 skirt_height = view_height*.1f; - Interval_f32 acceptable_y = If32(skirt_height, view_height*.9f); - - f32 target_height = view_line_y_difference(app, view, bottom.line, top.line); - - if (target_height > view_height){ - i64 major_line = bottom.line; - if (range.min == major_pos){ - major_line = top.line; - } - - Buffer_Scroll scroll = view_get_buffer_scroll(app, view); - scroll.target.line_number = major_line; - scroll.target.pixel_shift.y = -skirt_height; - view_set_buffer_scroll(app, view, scroll); - } - else{ - Buffer_Scroll scroll = view_get_buffer_scroll(app, view); - Vec2_f32 top_p = view_relative_xy_of_pos(app, view, scroll.position.line_number, range.min); - top_p -= scroll.position.pixel_shift; - if (top_p.y < acceptable_y.min){ - scroll.target.line_number = top.line; - scroll.target.pixel_shift.y = -skirt_height; - view_set_buffer_scroll(app, view, scroll); - } - else{ - Vec2_f32 bot_p = view_relative_xy_of_pos(app, view, scroll.position.line_number, range.max); - bot_p -= scroll.position.pixel_shift; - if (bot_p.y > acceptable_y.max){ - scroll.target.line_number = bottom.line; - scroll.target.pixel_shift.y = skirt_height - view_height; - view_set_buffer_scroll(app, view, scroll); - } - } - } - } +function b32 +find_surrounding_nest(Application_Links *app, Buffer_ID buffer, i64 pos, + Find_Nest_Flag flags, Range_i64 *out){ + b32 result = false; + Range_i64 range = {}; + if (find_nest_side(app, buffer, pos - 1, flags|FindNest_Balanced, + Scan_Backward, NestDelim_Open, &range.start) && + find_nest_side(app, buffer, pos, flags|FindNest_Balanced|FindNest_EndOfToken, + Scan_Forward, NestDelim_Close, &range.end)){ + *out = range; + result = true; } + return(result); +} + +function void +select_scope(Application_Links *app, View_ID view, Range_i64 range){ + view_set_cursor_and_preferred_x(app, view, seek_pos(range.first)); + view_set_mark(app, view, seek_pos(range.end)); + view_look_at_region(app, view, range.first, range.end); + no_mark_snap_to_cursor(app, view); } CUSTOM_COMMAND_SIG(select_surrounding_scope) @@ -325,11 +132,8 @@ CUSTOM_DOC("Finds the scope enclosed by '{' '}' surrounding the cursor and puts Buffer_ID buffer = view_get_buffer(app, view, AccessProtected); i64 pos = view_get_cursor_pos(app, view); Range_i64 range = {}; - if (find_scope_range(app, buffer, pos, &range, FindScope_Scope)){ - view_set_cursor_and_preferred_x(app, view, seek_pos(range.first)); - view_set_mark(app, view, seek_pos(range.end)); - view_set_to_region(app, view, range.first, range.end); - no_mark_snap_to_cursor(app, view); + if (find_surrounding_nest(app, buffer, pos, FindNest_Scope, &range)){ + select_scope(app, view, range); } } @@ -339,16 +143,14 @@ CUSTOM_DOC("Finds the first scope started by '{' after the cursor and puts the c View_ID view = get_active_view(app, AccessProtected); Buffer_ID buffer = view_get_buffer(app, view, AccessProtected); i64 pos = view_get_cursor_pos(app, view); - i64 start_pos = pos; - i64 top = 0; - i64 bottom = 0; - if (find_next_scope(app, buffer, start_pos, FindScope_Scope, &top)){ - if (find_scope_bottom(app, buffer, top, FindScope_EndOfToken|FindScope_Scope, &bottom)){ - view_set_cursor_and_preferred_x(app, view, seek_pos(top)); - view_set_mark(app, view, seek_pos(bottom)); - view_set_to_region(app, view, top, bottom); - no_mark_snap_to_cursor(app, view); - } + Find_Nest_Flag flags = FindNest_Scope; + Range_i64 range = {}; + if (find_nest_side(app, buffer, pos + 1, + flags, Scan_Forward, NestDelim_Open, &range) && + find_nest_side(app, buffer, range.end, + flags|FindNest_Balanced|FindNest_EndOfToken, Scan_Forward, + NestDelim_Close, &range.end)){ + select_scope(app, view, range); } } @@ -358,71 +160,14 @@ CUSTOM_DOC("Finds the first scope started by '{' before the cursor and puts the View_ID view = get_active_view(app, AccessProtected); Buffer_ID buffer = view_get_buffer(app, view, AccessProtected); i64 pos = view_get_cursor_pos(app, view); - i64 start_pos = pos; - i64 top = 0; - i64 bottom = 0; - if (find_prev_scope(app, buffer, start_pos, FindScope_Scope, &top)){ - if (find_scope_bottom(app, buffer, top, FindScope_EndOfToken|FindScope_Scope, &bottom)){ - view_set_cursor_and_preferred_x(app, view, seek_pos(top)); - view_set_mark(app, view, seek_pos(bottom)); - view_set_to_region(app, view, top, bottom); - no_mark_snap_to_cursor(app, view); - } - } -} - -static void -place_begin_and_end_on_own_lines(Application_Links *app, char *begin, char *end){ - View_ID view = get_active_view(app, AccessOpen); - Buffer_ID buffer = view_get_buffer(app, view, AccessOpen); - - Range_i64 range = get_view_range(app, view); - Range_i64 lines = get_line_range_from_pos_range(app, buffer, range); - range = get_pos_range_from_line_range(app, buffer, lines); - - Scratch_Block scratch(app); - - b32 min_line_blank = line_is_valid_and_blank(app, buffer, lines.min); - b32 max_line_blank = line_is_valid_and_blank(app, buffer, lines.max); - - if ((lines.min < lines.max) || (!min_line_blank)){ - String_Const_u8 begin_str = {}; - String_Const_u8 end_str = {}; - - i64 min_adjustment = 0; - i64 max_adjustment = 0; - - if (min_line_blank){ - begin_str = push_u8_stringf(scratch, "\n%s", begin); - min_adjustment += 1; - } - else{ - begin_str = push_u8_stringf(scratch, "%s\n", begin); - } - if (max_line_blank){ - end_str = push_u8_stringf(scratch, "%s\n", end); - } - else{ - end_str = push_u8_stringf(scratch, "\n%s", end); - max_adjustment += 1; - } - - max_adjustment += begin_str.size; - Range_i64 new_pos = Ii64(range.min + min_adjustment, range.max + max_adjustment); - - History_Group group = history_group_begin(app, buffer); - buffer_replace_range(app, buffer, Ii64(range.min), begin_str); - buffer_replace_range(app, buffer, Ii64(range.max + begin_str.size), end_str); - history_group_end(group); - - set_view_range(app, view, new_pos); - } - else{ - String_Const_u8 str = push_u8_stringf(scratch, "%s\n\n%s", begin, end); - buffer_replace_range(app, buffer, range, str); - i64 center_pos = range.min + cstring_length(begin) + 1; - view_set_cursor_and_preferred_x(app, view, seek_pos(center_pos)); - view_set_mark(app, view, seek_pos(center_pos)); + Find_Nest_Flag flags = FindNest_Scope; + Range_i64 range = {}; + if (find_nest_side(app, buffer, pos - 1, + flags, Scan_Backward, NestDelim_Open, &range) && + find_nest_side(app, buffer, range.end, + flags|FindNest_Balanced|FindNest_EndOfToken, Scan_Forward, + NestDelim_Close, &range.end)){ + select_scope(app, view, range); } } diff --git a/custom/4coder_scope_commands.h b/custom/4coder_scope_commands.h index 62064784..19114796 100644 --- a/custom/4coder_scope_commands.h +++ b/custom/4coder_scope_commands.h @@ -9,18 +9,17 @@ typedef i32 Nest_Delimiter_Kind; enum{ - NestDelimiterKind_None = 0, - NestDelimiterKind_Open = 1, - NestDelimiterKind_Close = 2, + NestDelim_None = 0, + NestDelim_Open = 1, + NestDelim_Close = 2, }; -typedef u32 Find_Scope_Flag; +typedef u32 Find_Nest_Flag; enum{ - FindScope_Parent = 1, - FindScope_NextSibling = 2, - FindScope_EndOfToken = 4, - FindScope_Scope = 8, - FindScope_Paren = 16, + FindNest_Scope = 1, + FindNest_Paren = 2, + FindNest_EndOfToken = 4, + FindNest_Balanced = 8, }; #endif diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index 8962d628..83448666 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -248,12 +248,12 @@ i32 line_number; }; static Command_Metadata fcoder_metacmd_table[226] = { { PROC_LINKS(set_bindings_mac_default, 0), "set_bindings_mac_default", 24, "Remap keybindings using the 'mac-default' mapping rule.", 55, "w:\\4ed\\code\\custom\\4coder_remapping_commands.cpp", 48, 62 }, -{ PROC_LINKS(seek_beginning_of_textual_line, 0), "seek_beginning_of_textual_line", 30, "Seeks the cursor to the beginning of the line across all text.", 62, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2123 }, -{ PROC_LINKS(seek_end_of_textual_line, 0), "seek_end_of_textual_line", 24, "Seeks the cursor to the end of the line across all text.", 56, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2129 }, -{ PROC_LINKS(seek_beginning_of_line, 0), "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2135 }, -{ PROC_LINKS(seek_end_of_line, 0), "seek_end_of_line", 16, "Seeks the cursor to the end of the visual line.", 47, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2141 }, -{ PROC_LINKS(goto_beginning_of_file, 0), "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2147 }, -{ PROC_LINKS(goto_end_of_file, 0), "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2155 }, +{ PROC_LINKS(seek_beginning_of_textual_line, 0), "seek_beginning_of_textual_line", 30, "Seeks the cursor to the beginning of the line across all text.", 62, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2233 }, +{ PROC_LINKS(seek_end_of_textual_line, 0), "seek_end_of_textual_line", 24, "Seeks the cursor to the end of the line across all text.", 56, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2239 }, +{ PROC_LINKS(seek_beginning_of_line, 0), "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2245 }, +{ PROC_LINKS(seek_end_of_line, 0), "seek_end_of_line", 16, "Seeks the cursor to the end of the visual line.", 47, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2251 }, +{ PROC_LINKS(goto_beginning_of_file, 0), "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2257 }, +{ PROC_LINKS(goto_end_of_file, 0), "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2265 }, { PROC_LINKS(change_active_panel, 0), "change_active_panel", 19, "Change the currently active panel, moving to the panel with the next highest view_id.", 85, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 196 }, { PROC_LINKS(change_active_panel_backwards, 0), "change_active_panel_backwards", 29, "Change the currently active panel, moving to the panel with the next lowest view_id.", 84, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 206 }, { PROC_LINKS(open_panel_vsplit, 0), "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 216 }, @@ -447,11 +447,11 @@ static Command_Metadata fcoder_metacmd_table[226] = { { PROC_LINKS(list_all_functions_current_buffer_lister, 0), "list_all_functions_current_buffer_lister", 40, "Creates a lister of locations that look like function definitions and declarations in the buffer.", 97, "w:\\4ed\\code\\custom\\4coder_function_list.cpp", 43, 277 }, { PROC_LINKS(list_all_functions_all_buffers, 0), "list_all_functions_all_buffers", 30, "Creates a jump list of lines from all buffers that appear to define or declare functions.", 89, "w:\\4ed\\code\\custom\\4coder_function_list.cpp", 43, 289 }, { PROC_LINKS(list_all_functions_all_buffers_lister, 0), "list_all_functions_all_buffers_lister", 37, "Creates a lister of locations that look like function definitions and declarations all buffers.", 95, "w:\\4ed\\code\\custom\\4coder_function_list.cpp", 43, 295 }, -{ PROC_LINKS(select_surrounding_scope, 0), "select_surrounding_scope", 24, "Finds the scope enclosed by '{' '}' surrounding the cursor and puts the cursor and mark on the '{' and '}'.", 107, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 321 }, -{ PROC_LINKS(select_next_scope_absolute, 0), "select_next_scope_absolute", 26, "Finds the first scope started by '{' after the cursor and puts the cursor and mark on the '{' and '}'.", 102, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 336 }, -{ PROC_LINKS(select_prev_scope_absolute, 0), "select_prev_scope_absolute", 26, "Finds the first scope started by '{' before the cursor and puts the cursor and mark on the '{' and '}'.", 103, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 355 }, -{ PROC_LINKS(place_in_scope, 0), "place_in_scope", 14, "Wraps the code contained in the range between cursor and mark with a new curly brace scope.", 91, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 429 }, -{ PROC_LINKS(delete_current_scope, 0), "delete_current_scope", 20, "Deletes the braces surrounding the currently selected scope. Leaves the contents within the scope.", 99, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 435 }, +{ PROC_LINKS(select_surrounding_scope, 0), "select_surrounding_scope", 24, "Finds the scope enclosed by '{' '}' surrounding the cursor and puts the cursor and mark on the '{' and '}'.", 107, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 128 }, +{ PROC_LINKS(select_next_scope_absolute, 0), "select_next_scope_absolute", 26, "Finds the first scope started by '{' after the cursor and puts the cursor and mark on the '{' and '}'.", 102, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 140 }, +{ PROC_LINKS(select_prev_scope_absolute, 0), "select_prev_scope_absolute", 26, "Finds the first scope started by '{' before the cursor and puts the cursor and mark on the '{' and '}'.", 103, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 157 }, +{ PROC_LINKS(place_in_scope, 0), "place_in_scope", 14, "Wraps the code contained in the range between cursor and mark with a new curly brace scope.", 91, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 174 }, +{ PROC_LINKS(delete_current_scope, 0), "delete_current_scope", 20, "Deletes the braces surrounding the currently selected scope. Leaves the contents within the scope.", 99, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 180 }, { PROC_LINKS(open_long_braces, 0), "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 46 }, { PROC_LINKS(open_long_braces_semicolon, 0), "open_long_braces_semicolon", 26, "At the cursor, insert a '{' and '};' separated by a blank line.", 63, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 54 }, { PROC_LINKS(open_long_braces_break, 0), "open_long_braces_break", 22, "At the cursor, insert a '{' and '}break;' separated by a blank line.", 68, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 62 },