Fix redo off by one error

This commit is contained in:
Peter Slattery 2025-07-07 14:06:38 -07:00
parent 1c9fd3e16f
commit 051b5068e5
1 changed files with 119 additions and 119 deletions

View File

@ -11,12 +11,12 @@ write_text(Application_Links *app, String_Const_u8 insert){
if (insert.str != 0 && insert.size > 0){ if (insert.str != 0 && insert.size > 0){
View_ID view = get_active_view(app, Access_ReadWriteVisible); View_ID view = get_active_view(app, Access_ReadWriteVisible);
if_view_has_highlighted_range_delete_range(app, view); if_view_has_highlighted_range_delete_range(app, view);
i64 pos = view_get_cursor_pos(app, view); i64 pos = view_get_cursor_pos(app, view);
pos = view_get_character_legal_pos_from_pos(app, view, pos); pos = view_get_character_legal_pos_from_pos(app, view, pos);
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible); Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
// NOTE(allen): consecutive inserts merge logic // NOTE(allen): consecutive inserts merge logic
History_Record_Index first_index = buffer_history_get_current_state_index(app, buffer); History_Record_Index first_index = buffer_history_get_current_state_index(app, buffer);
b32 do_merge = false; b32 do_merge = false;
@ -39,16 +39,16 @@ write_text(Application_Links *app, String_Const_u8 insert){
} }
} }
} }
// NOTE(allen): perform the edit // NOTE(allen): perform the edit
b32 edit_success = buffer_replace_range(app, buffer, Ii64(pos), insert); b32 edit_success = buffer_replace_range(app, buffer, Ii64(pos), insert);
// NOTE(allen): finish merging records if necessary // NOTE(allen): finish merging records if necessary
if (do_merge){ if (do_merge){
History_Record_Index last_index = buffer_history_get_current_state_index(app, buffer); History_Record_Index last_index = buffer_history_get_current_state_index(app, buffer);
buffer_history_merge_record_range(app, buffer, first_index, last_index, RecordMergeFlag_StateInRange_MoveStateForward); buffer_history_merge_record_range(app, buffer, first_index, last_index, RecordMergeFlag_StateInRange_MoveStateForward);
} }
// NOTE(allen): finish updating the cursor // NOTE(allen): finish updating the cursor
if (edit_success){ if (edit_success){
view_set_cursor_and_preferred_x(app, view, seek_pos(pos + insert.size)); view_set_cursor_and_preferred_x(app, view, seek_pos(pos + insert.size));
@ -160,7 +160,7 @@ CUSTOM_DOC("Delete characters between the cursor position and the first alphanum
} }
function i64 function i64
get_boundary_token_or_whitespace(Application_Links *app, Buffer_ID buffer, get_boundary_token_or_whitespace(Application_Links *app, Buffer_ID buffer,
Side side, Scan_Direction direction, i64 pos) Side side, Scan_Direction direction, i64 pos)
{ {
// NOTE(PS): originally this was F4_Boundary_TokenAndWhitespace // NOTE(PS): originally this was F4_Boundary_TokenAndWhitespace
@ -176,12 +176,12 @@ get_boundary_token_or_whitespace(Application_Links *app, Buffer_ID buffer,
{ {
Token_Iterator_Array it = token_iterator_pos(0, &tokens, pos); Token_Iterator_Array it = token_iterator_pos(0, &tokens, pos);
Token *token = token_it_read(&it); Token *token = token_it_read(&it);
if(token == 0) if(token == 0)
{ {
break; break;
} }
// NOTE(rjf): Comments/Strings // NOTE(rjf): Comments/Strings
if(token->kind == TokenBaseKind_Comment || if(token->kind == TokenBaseKind_Comment ||
token->kind == TokenBaseKind_LiteralString) token->kind == TokenBaseKind_LiteralString)
@ -189,7 +189,7 @@ get_boundary_token_or_whitespace(Application_Links *app, Buffer_ID buffer,
result = boundary_non_whitespace(app, buffer, side, direction, pos); result = boundary_non_whitespace(app, buffer, side, direction, pos);
break; break;
} }
// NOTE(rjf): All other cases. // NOTE(rjf): All other cases.
else else
{ {
@ -198,10 +198,10 @@ get_boundary_token_or_whitespace(Application_Links *app, Buffer_ID buffer,
// token_it_inc_non_whitespace(&it); // token_it_inc_non_whitespace(&it);
// token = token_it_read(&it); // token = token_it_read(&it);
} }
if (side == Side_Max){ if (side == Side_Max){
result = token->pos + token->size; result = token->pos + token->size;
token_it_inc_all(&it); token_it_inc_all(&it);
Token *ws = token_it_read(&it); Token *ws = token_it_read(&it);
if(ws != 0 && ws->kind == TokenBaseKind_Whitespace && if(ws != 0 && ws->kind == TokenBaseKind_Whitespace &&
@ -221,32 +221,32 @@ get_boundary_token_or_whitespace(Application_Links *app, Buffer_ID buffer,
} }
} }
} }
} }
}break; }break;
case Scan_Backward: case Scan_Backward:
{ {
result = 0; result = 0;
if (tokens.count > 0){ if (tokens.count > 0){
Token_Iterator_Array it = token_iterator_pos(0, &tokens, pos); Token_Iterator_Array it = token_iterator_pos(0, &tokens, pos);
Token *token = token_it_read(&it); Token *token = token_it_read(&it);
Token_Iterator_Array it2 = it; Token_Iterator_Array it2 = it;
token_it_dec_non_whitespace(&it2); token_it_dec_non_whitespace(&it2);
Token *token2 = token_it_read(&it2); Token *token2 = token_it_read(&it2);
// NOTE(rjf): Comments/Strings // NOTE(rjf): Comments/Strings
if(token->kind == TokenBaseKind_Comment || if(token->kind == TokenBaseKind_Comment ||
token->kind == TokenBaseKind_LiteralString || token->kind == TokenBaseKind_LiteralString ||
(token2 && (token2 &&
token2->kind == TokenBaseKind_Comment || token2->kind == TokenBaseKind_Comment ||
token2->kind == TokenBaseKind_LiteralString)) token2->kind == TokenBaseKind_LiteralString))
{ {
result = boundary_non_whitespace(app, buffer, side, direction, pos); result = boundary_non_whitespace(app, buffer, side, direction, pos);
break; break;
} }
if (token->kind == TokenBaseKind_Whitespace){ if (token->kind == TokenBaseKind_Whitespace){
token_it_dec_non_whitespace(&it); token_it_dec_non_whitespace(&it);
token = token_it_read(&it); token = token_it_read(&it);
@ -724,7 +724,7 @@ clean_all_lines_buffer(Application_Links *app, Buffer_ID buffer, Clean_All_Lines
Scratch_Block scratch(app); Scratch_Block scratch(app);
Batch_Edit *batch_first = 0; Batch_Edit *batch_first = 0;
Batch_Edit *batch_last = 0; Batch_Edit *batch_last = 0;
i64 line_count = buffer_get_line_count(app, buffer); i64 line_count = buffer_get_line_count(app, buffer);
for (i64 line_number = 1; line_number <= line_count; line_number += 1){ for (i64 line_number = 1; line_number <= line_count; line_number += 1){
i64 line_start = get_line_side_pos(app, buffer, line_number, Side_Min); i64 line_start = get_line_side_pos(app, buffer, line_number, Side_Min);
@ -759,11 +759,11 @@ clean_all_lines_buffer(Application_Links *app, Buffer_ID buffer, Clean_All_Lines
break; break;
} }
} }
if (mode == CleanAllLinesMode_RemoveBlankLines || start_offset > 0){ if (mode == CleanAllLinesMode_RemoveBlankLines || start_offset > 0){
i64 start = start_offset + line_start; i64 start = start_offset + line_start;
i64 end = end_offset + line_start; i64 end = end_offset + line_start;
Batch_Edit *batch = push_array(scratch, Batch_Edit, 1); Batch_Edit *batch = push_array(scratch, Batch_Edit, 1);
sll_queue_push(batch_first, batch_last, batch); sll_queue_push(batch_first, batch_last, batch);
batch->edit.text = SCu8(); batch->edit.text = SCu8();
@ -772,7 +772,7 @@ clean_all_lines_buffer(Application_Links *app, Buffer_ID buffer, Clean_All_Lines
} }
} }
} }
if (batch_first != 0){ if (batch_first != 0){
buffer_batch_edit(app, buffer, batch_first); buffer_batch_edit(app, buffer, batch_first);
} }
@ -865,7 +865,7 @@ CUSTOM_DOC("Set face size of the face used by the current buffer.")
Buffer_ID buffer = view_get_buffer(app, view, Access_Always); Buffer_ID buffer = view_get_buffer(app, view, Access_Always);
Face_ID face_id = get_face_id(app, buffer); Face_ID face_id = get_face_id(app, buffer);
Face_Description description = get_face_description(app, face_id); Face_Description description = get_face_description(app, face_id);
Query_Bar_Group group(app); Query_Bar_Group group(app);
u8 string_space[256]; u8 string_space[256];
Query_Bar bar = {}; Query_Bar bar = {};
@ -906,7 +906,7 @@ CUSTOM_DOC("Set face size of the face used by the current buffer; if any other b
View_ID view = get_active_view(app, Access_Always); View_ID view = get_active_view(app, Access_Always);
Buffer_ID buffer = view_get_buffer(app, view, Access_Always); Buffer_ID buffer = view_get_buffer(app, view, Access_Always);
Face_ID face_id = get_face_id(app, buffer); Face_ID face_id = get_face_id(app, buffer);
b32 is_shared = false; b32 is_shared = false;
for (Buffer_ID buf_it = get_buffer_next(app, 0, Access_Always); for (Buffer_ID buf_it = get_buffer_next(app, 0, Access_Always);
buf_it != 0; buf_it != 0;
@ -919,7 +919,7 @@ CUSTOM_DOC("Set face size of the face used by the current buffer; if any other b
is_shared = true; is_shared = true;
} }
} }
if (is_shared){ if (is_shared){
Face_Description description = get_face_description(app, face_id); Face_Description description = get_face_description(app, face_id);
face_id = try_create_new_face(app, &description); face_id = try_create_new_face(app, &description);
@ -927,7 +927,7 @@ CUSTOM_DOC("Set face size of the face used by the current buffer; if any other b
buffer_set_face(app, buffer, face_id); buffer_set_face(app, buffer, face_id);
} }
} }
set_face_size(app); set_face_size(app);
} }
@ -1019,35 +1019,35 @@ isearch(Application_Links *app, Scan_Direction start_scan, i64 first_pos,
if (!buffer_exists(app, buffer)){ if (!buffer_exists(app, buffer)){
return; return;
} }
i64 buffer_size = buffer_get_size(app, buffer); i64 buffer_size = buffer_get_size(app, buffer);
Query_Bar_Group group(app); Query_Bar_Group group(app);
Query_Bar bar = {}; Query_Bar bar = {};
if (start_query_bar(app, &bar, 0) == 0){ if (start_query_bar(app, &bar, 0) == 0){
return; return;
} }
Vec2_f32 old_margin = {}; Vec2_f32 old_margin = {};
Vec2_f32 old_push_in = {}; Vec2_f32 old_push_in = {};
view_get_camera_bounds(app, view, &old_margin, &old_push_in); view_get_camera_bounds(app, view, &old_margin, &old_push_in);
Vec2_f32 margin = old_margin; Vec2_f32 margin = old_margin;
margin.y = clamp_bot(200.f, margin.y); margin.y = clamp_bot(200.f, margin.y);
view_set_camera_bounds(app, view, margin, old_push_in); view_set_camera_bounds(app, view, margin, old_push_in);
Scan_Direction scan = start_scan; Scan_Direction scan = start_scan;
i64 pos = first_pos; i64 pos = first_pos;
u8 bar_string_space[256]; u8 bar_string_space[256];
bar.string = SCu8(bar_string_space, query_init.size); bar.string = SCu8(bar_string_space, query_init.size);
block_copy(bar.string.str, query_init.str, query_init.size); block_copy(bar.string.str, query_init.str, query_init.size);
String_Const_u8 isearch_str = string_u8_litexpr("I-Search: "); String_Const_u8 isearch_str = string_u8_litexpr("I-Search: ");
String_Const_u8 rsearch_str = string_u8_litexpr("Reverse-I-Search: "); String_Const_u8 rsearch_str = string_u8_litexpr("Reverse-I-Search: ");
u64 match_size = bar.string.size; u64 match_size = bar.string.size;
User_Input in = {}; User_Input in = {};
for (;;){ for (;;){
switch (scan){ switch (scan){
@ -1061,14 +1061,14 @@ isearch(Application_Links *app, Scan_Direction start_scan, i64 first_pos,
}break; }break;
} }
isearch__update_highlight(app, view, Ii64_size(pos, match_size)); isearch__update_highlight(app, view, Ii64_size(pos, match_size));
in = get_next_input(app, EventPropertyGroup_Any, EventProperty_Escape); in = get_next_input(app, EventPropertyGroup_Any, EventProperty_Escape);
if (in.abort){ if (in.abort){
break; break;
} }
String_Const_u8 string = to_writable(&in); String_Const_u8 string = to_writable(&in);
b32 string_change = false; b32 string_change = false;
if (match_key_code(&in, KeyCode_Return) || if (match_key_code(&in, KeyCode_Return) ||
match_key_code(&in, KeyCode_Tab)){ match_key_code(&in, KeyCode_Tab)){
@ -1104,7 +1104,7 @@ isearch(Application_Links *app, Scan_Direction start_scan, i64 first_pos,
} }
} }
} }
b32 do_scan_action = false; b32 do_scan_action = false;
b32 do_scroll_wheel = false; b32 do_scroll_wheel = false;
Scan_Direction change_scan = scan; Scan_Direction change_scan = scan;
@ -1150,7 +1150,7 @@ isearch(Application_Links *app, Scan_Direction start_scan, i64 first_pos,
} }
} }
} }
if (string_change){ if (string_change){
switch (scan){ switch (scan){
case Scan_Forward: case Scan_Forward:
@ -1162,7 +1162,7 @@ isearch(Application_Links *app, Scan_Direction start_scan, i64 first_pos,
match_size = bar.string.size; match_size = bar.string.size;
} }
}break; }break;
case Scan_Backward: case Scan_Backward:
{ {
i64 new_pos = 0; i64 new_pos = 0;
@ -1186,7 +1186,7 @@ isearch(Application_Links *app, Scan_Direction start_scan, i64 first_pos,
match_size = bar.string.size; match_size = bar.string.size;
} }
}break; }break;
case Scan_Backward: case Scan_Backward:
{ {
i64 new_pos = 0; i64 new_pos = 0;
@ -1202,9 +1202,9 @@ isearch(Application_Links *app, Scan_Direction start_scan, i64 first_pos,
mouse_wheel_scroll(app); mouse_wheel_scroll(app);
} }
} }
view_disable_highlight_range(app, view); view_disable_highlight_range(app, view);
if (in.abort){ if (in.abort){
u64 size = bar.string.size; u64 size = bar.string.size;
size = clamp_top(size, sizeof(previous_isearch_query) - 1); size = clamp_top(size, sizeof(previous_isearch_query) - 1);
@ -1212,7 +1212,7 @@ isearch(Application_Links *app, Scan_Direction start_scan, i64 first_pos,
previous_isearch_query[size] = 0; previous_isearch_query[size] = 0;
view_set_cursor_and_preferred_x(app, view, seek_pos(first_pos)); view_set_cursor_and_preferred_x(app, view, seek_pos(first_pos));
} }
view_set_camera_bounds(app, view, old_margin, old_push_in); view_set_camera_bounds(app, view, old_margin, old_push_in);
} }
@ -1278,13 +1278,13 @@ query_user_replace_pair(Application_Links *app, Arena *arena){
replace->prompt = string_u8_litexpr("Replace: "); replace->prompt = string_u8_litexpr("Replace: ");
replace->string = SCu8(replace_space, (u64)0); replace->string = SCu8(replace_space, (u64)0);
replace->string_capacity = KB(1); replace->string_capacity = KB(1);
Query_Bar *with = push_array(arena, Query_Bar, 1); Query_Bar *with = push_array(arena, Query_Bar, 1);
u8 *with_space = push_array(arena, u8, KB(1)); u8 *with_space = push_array(arena, u8, KB(1));
with->prompt = string_u8_litexpr("With: "); with->prompt = string_u8_litexpr("With: ");
with->string = SCu8(with_space, (u64)0); with->string = SCu8(with_space, (u64)0);
with->string_capacity = KB(1); with->string_capacity = KB(1);
String_Pair result = {}; String_Pair result = {};
if (query_user_string(app, replace) && replace->string.size != 0 && query_user_string(app, with)){ if (query_user_string(app, replace) && replace->string.size != 0 && query_user_string(app, with)){
result.valid = true; result.valid = true;
@ -1328,7 +1328,7 @@ CUSTOM_COMMAND_SIG(replace_in_all_buffers)
CUSTOM_DOC("Queries the user for a needle and string. Replaces all occurences of needle with string in all editable buffers.") CUSTOM_DOC("Queries the user for a needle and string. Replaces all occurences of needle with string in all editable buffers.")
{ {
global_history_edit_group_begin(app); global_history_edit_group_begin(app);
Scratch_Block scratch(app); Scratch_Block scratch(app);
Query_Bar_Group group(app); Query_Bar_Group group(app);
String_Pair pair = query_user_replace_pair(app, scratch); String_Pair pair = query_user_replace_pair(app, scratch);
@ -1338,7 +1338,7 @@ CUSTOM_DOC("Queries the user for a needle and string. Replaces all occurences of
Range_i64 range = buffer_range(app, buffer); Range_i64 range = buffer_range(app, buffer);
replace_in_range(app, buffer, range, pair.a, pair.b); replace_in_range(app, buffer, range, pair.a, pair.b);
} }
global_history_edit_group_end(app); global_history_edit_group_end(app);
} }
@ -1346,17 +1346,17 @@ function void
query_replace_base(Application_Links *app, View_ID view, Buffer_ID buffer_id, i64 pos, String_Const_u8 r, String_Const_u8 w){ query_replace_base(Application_Links *app, View_ID view, Buffer_ID buffer_id, i64 pos, String_Const_u8 r, String_Const_u8 w){
i64 new_pos = 0; i64 new_pos = 0;
seek_string_forward(app, buffer_id, pos - 1, 0, r, &new_pos); seek_string_forward(app, buffer_id, pos - 1, 0, r, &new_pos);
User_Input in = {}; User_Input in = {};
for (;;){ for (;;){
Range_i64 match = Ii64(new_pos, new_pos + r.size); Range_i64 match = Ii64(new_pos, new_pos + r.size);
isearch__update_highlight(app, view, match); isearch__update_highlight(app, view, match);
in = get_next_input(app, EventProperty_AnyKey, EventProperty_MouseButton); in = get_next_input(app, EventProperty_AnyKey, EventProperty_MouseButton);
if (in.abort || match_key_code(&in, KeyCode_Escape) || !is_unmodified_key(&in.event)){ if (in.abort || match_key_code(&in, KeyCode_Escape) || !is_unmodified_key(&in.event)){
break; break;
} }
i64 size = buffer_get_size(app, buffer_id); i64 size = buffer_get_size(app, buffer_id);
if (match.max <= size && if (match.max <= size &&
(match_key_code(&in, KeyCode_Y) || (match_key_code(&in, KeyCode_Y) ||
@ -1368,16 +1368,16 @@ query_replace_base(Application_Links *app, View_ID view, Buffer_ID buffer_id, i6
else{ else{
pos = match.max; pos = match.max;
} }
seek_string_forward(app, buffer_id, pos, 0, r, &new_pos); seek_string_forward(app, buffer_id, pos, 0, r, &new_pos);
} }
view_disable_highlight_range(app, view); view_disable_highlight_range(app, view);
if (in.abort){ if (in.abort){
return; return;
} }
view_set_cursor_and_preferred_x(app, view, seek_pos(pos)); view_set_cursor_and_preferred_x(app, view, seek_pos(pos));
} }
@ -1387,29 +1387,29 @@ query_replace_parameter(Application_Links *app, String_Const_u8 replace_str, i64
Query_Bar replace = {}; Query_Bar replace = {};
replace.prompt = string_u8_litexpr("Replace: "); replace.prompt = string_u8_litexpr("Replace: ");
replace.string = replace_str; replace.string = replace_str;
if (add_replace_query_bar){ if (add_replace_query_bar){
start_query_bar(app, &replace, 0); start_query_bar(app, &replace, 0);
} }
Query_Bar with = {}; Query_Bar with = {};
u8 with_space[1024]; u8 with_space[1024];
with.prompt = string_u8_litexpr("With: "); with.prompt = string_u8_litexpr("With: ");
with.string = SCu8(with_space, (u64)0); with.string = SCu8(with_space, (u64)0);
with.string_capacity = sizeof(with_space); with.string_capacity = sizeof(with_space);
if (query_user_string(app, &with)){ if (query_user_string(app, &with)){
String_Const_u8 r = replace.string; String_Const_u8 r = replace.string;
String_Const_u8 w = with.string; String_Const_u8 w = with.string;
View_ID view = get_active_view(app, Access_ReadVisible); View_ID view = get_active_view(app, Access_ReadVisible);
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadVisible); Buffer_ID buffer = view_get_buffer(app, view, Access_ReadVisible);
i64 pos = start_pos; i64 pos = start_pos;
Query_Bar bar = {}; Query_Bar bar = {};
bar.prompt = string_u8_litexpr("Replace? (y)es, (n)ext, (esc)\n"); bar.prompt = string_u8_litexpr("Replace? (y)es, (n)ext, (esc)\n");
start_query_bar(app, &bar, 0); start_query_bar(app, &bar, 0);
query_replace_base(app, view, buffer, pos, r, w); query_replace_base(app, view, buffer, pos, r, w);
} }
} }
@ -1475,7 +1475,7 @@ CUSTOM_DOC("Read from the top of the point stack and jump there; if already ther
if (view != 0){ if (view != 0){
Buffer_ID buffer = view_get_buffer(app, view, Access_Always); Buffer_ID buffer = view_get_buffer(app, view, Access_Always);
i64 pos = view_get_cursor_pos(app, view); i64 pos = view_get_cursor_pos(app, view);
for (;;){ for (;;){
Buffer_ID stack_buffer = 0; Buffer_ID stack_buffer = 0;
i64 stack_pos = 0; i64 stack_pos = 0;
@ -1540,14 +1540,14 @@ CUSTOM_DOC("Deletes the file of the current buffer if 4coder has the appropriate
delete_file_base(app, file_name, buffer); delete_file_base(app, file_name, buffer);
cancelled = true; cancelled = true;
}break; }break;
case KeyCode_Shift: case KeyCode_Shift:
case KeyCode_Control: case KeyCode_Control:
case KeyCode_Alt: case KeyCode_Alt:
case KeyCode_Command: case KeyCode_Command:
case KeyCode_CapsLock: case KeyCode_CapsLock:
{}break; {}break;
default: default:
{ {
cancelled = true; cancelled = true;
@ -1564,11 +1564,11 @@ CUSTOM_DOC("Queries the user for a file name and saves the contents of the curre
{ {
View_ID view = get_active_view(app, Access_Always); View_ID view = get_active_view(app, Access_Always);
Buffer_ID buffer = view_get_buffer(app, view, Access_Always); Buffer_ID buffer = view_get_buffer(app, view, Access_Always);
Scratch_Block scratch(app); Scratch_Block scratch(app);
Query_Bar_Group group(app); Query_Bar_Group group(app);
String_Const_u8 buffer_name = push_buffer_unique_name(app, scratch, buffer); String_Const_u8 buffer_name = push_buffer_unique_name(app, scratch, buffer);
// Query the user // Query the user
u8 name_space[4096]; u8 name_space[4096];
Query_Bar bar = {}; Query_Bar bar = {};
@ -1597,9 +1597,9 @@ CUSTOM_DOC("Queries the user for a new name and renames the file of the current
{ {
View_ID view = get_active_view(app, Access_Always); View_ID view = get_active_view(app, Access_Always);
Buffer_ID buffer = view_get_buffer(app, view, Access_Always); Buffer_ID buffer = view_get_buffer(app, view, Access_Always);
Scratch_Block scratch(app); Scratch_Block scratch(app);
String_Const_u8 file_name = push_buffer_file_name(app, scratch, buffer); String_Const_u8 file_name = push_buffer_file_name(app, scratch, buffer);
if (file_name.size > 0){ if (file_name.size > 0){
// Query the user // Query the user
@ -1631,9 +1631,9 @@ CUSTOM_COMMAND_SIG(make_directory_query)
CUSTOM_DOC("Queries the user for a name and creates a new directory with the given name.") CUSTOM_DOC("Queries the user for a name and creates a new directory with the given name.")
{ {
Scratch_Block scratch(app); Scratch_Block scratch(app);
String_Const_u8 hot = push_hot_directory(app, scratch); String_Const_u8 hot = push_hot_directory(app, scratch);
// Query the user // Query the user
Query_Bar_Group group(app); Query_Bar_Group group(app);
u8 name_space[4096]; u8 name_space[4096];
@ -1641,10 +1641,10 @@ CUSTOM_DOC("Queries the user for a name and creates a new directory with the giv
bar.prompt = push_u8_stringf(scratch, "Make directory at '%.*s': ", string_expand(hot)); bar.prompt = push_u8_stringf(scratch, "Make directory at '%.*s': ", string_expand(hot));
bar.string = SCu8(name_space, (u64)0); bar.string = SCu8(name_space, (u64)0);
bar.string_capacity = sizeof(name_space); bar.string_capacity = sizeof(name_space);
if (!query_user_string(app, &bar)) return; if (!query_user_string(app, &bar)) return;
if (bar.string.size == 0) return; if (bar.string.size == 0) return;
String_Const_u8 cmd = push_u8_stringf(scratch, "mkdir %.*s", string_expand(bar.string)); String_Const_u8 cmd = push_u8_stringf(scratch, "mkdir %.*s", string_expand(bar.string));
exec_system_command(app, 0, buffer_identifier(0), hot, cmd, 0); exec_system_command(app, 0, buffer_identifier(0), hot, cmd, 0);
} }
@ -1715,19 +1715,19 @@ CUSTOM_DOC("Deletes all text from the cursor to the end of the line")
i64 line_number = get_line_number_from_pos(app, buffer, pos); i64 line_number = get_line_number_from_pos(app, buffer, pos);
Range_Cursor line_range = get_line_range(app, buffer, line_number); Range_Cursor line_range = get_line_range(app, buffer, line_number);
Range_i64 delete_range = {}; Range_i64 delete_range = {};
if (line_range.start.line != 0 && line_range.end.line != 0) if (line_range.start.line != 0 && line_range.end.line != 0)
{ {
delete_range = Ii64(pos, line_range.end.pos); delete_range = Ii64(pos, line_range.end.pos);
} }
if (range_size(delete_range) == 0) if (range_size(delete_range) == 0)
{ {
delete_range.end += 1; delete_range.end += 1;
i32 buffer_size = (i32)buffer_get_size(app, buffer); i32 buffer_size = (i32)buffer_get_size(app, buffer);
delete_range.end = clamp_top(delete_range.end, buffer_size); delete_range.end = clamp_top(delete_range.end, buffer_size);
} }
buffer_replace_range(app, buffer, delete_range, string_u8_litexpr("")); buffer_replace_range(app, buffer, delete_range, string_u8_litexpr(""));
} }
@ -1740,22 +1740,22 @@ CUSTOM_DOC("Reads a filename from surrounding '\"' characters and attempts to op
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadVisible); Buffer_ID buffer = view_get_buffer(app, view, Access_ReadVisible);
if (buffer_exists(app, buffer)){ if (buffer_exists(app, buffer)){
Scratch_Block scratch(app); Scratch_Block scratch(app);
i64 pos = view_get_cursor_pos(app, view); i64 pos = view_get_cursor_pos(app, view);
Range_i64 range = enclose_pos_inside_quotes(app, buffer, pos); Range_i64 range = enclose_pos_inside_quotes(app, buffer, pos);
String_Const_u8 quoted_name = push_buffer_range(app, scratch, buffer, range); String_Const_u8 quoted_name = push_buffer_range(app, scratch, buffer, range);
String_Const_u8 file_name = push_buffer_file_name(app, scratch, buffer); String_Const_u8 file_name = push_buffer_file_name(app, scratch, buffer);
String_Const_u8 path = string_remove_last_folder(file_name); String_Const_u8 path = string_remove_last_folder(file_name);
if (character_is_slash(string_get_character(path, path.size - 1))){ if (character_is_slash(string_get_character(path, path.size - 1))){
path = string_chop(path, 1); path = string_chop(path, 1);
} }
String_Const_u8 new_file_name = push_u8_stringf(scratch, "%.*s/%.*s", string_expand(path), string_expand(quoted_name)); String_Const_u8 new_file_name = push_u8_stringf(scratch, "%.*s/%.*s", string_expand(path), string_expand(quoted_name));
view = get_next_view_looped_primary_panels(app, view, Access_Always); view = get_next_view_looped_primary_panels(app, view, Access_Always);
if (view != 0){ if (view != 0){
if (view_open_file(app, view, new_file_name, true)){ if (view_open_file(app, view, new_file_name, true)){
@ -1792,7 +1792,7 @@ get_cpp_matching_file(Application_Links *app, Buffer_ID buffer, Buffer_ID *buffe
new_extensions[0] = string_u8_litexpr("cpp"); new_extensions[0] = string_u8_litexpr("cpp");
new_extensions_count = 1; new_extensions_count = 1;
} }
String_Const_u8 file_without_extension = string_file_without_extension(file_name); String_Const_u8 file_without_extension = string_file_without_extension(file_name);
for (i32 i = 0; i < new_extensions_count; i += 1){ for (i32 i = 0; i < new_extensions_count; i += 1){
Temp_Memory temp = begin_temp(scratch); Temp_Memory temp = begin_temp(scratch);
@ -1804,7 +1804,7 @@ get_cpp_matching_file(Application_Links *app, Buffer_ID buffer, Buffer_ID *buffe
} }
end_temp(temp); end_temp(temp);
} }
if (!result && new_extensions_count > 0){ if (!result && new_extensions_count > 0){
String_Const_u8 new_file_name = push_u8_stringf(scratch, "%.*s.%.*s", string_expand(file_without_extension), string_expand(new_extensions[0])); String_Const_u8 new_file_name = push_u8_stringf(scratch, "%.*s.%.*s", string_expand(file_without_extension), string_expand(new_extensions[0]));
if (open_file(app, buffer_out, new_file_name, false, false)){ if (open_file(app, buffer_out, new_file_name, false, false)){
@ -1812,7 +1812,7 @@ get_cpp_matching_file(Application_Links *app, Buffer_ID buffer, Buffer_ID *buffe
} }
} }
} }
return(result); return(result);
} }
@ -1850,15 +1850,15 @@ CUSTOM_DOC("Swaps the active panel with it's sibling.")
for (;parent != 0;){ for (;parent != 0;){
Panel_ID child_1 = panel_get_child(app, parent, Side_Min); Panel_ID child_1 = panel_get_child(app, parent, Side_Min);
Panel_ID child_2 = panel_get_child(app, parent, Side_Max); Panel_ID child_2 = panel_get_child(app, parent, Side_Max);
View_ID view_1 = panel_get_view(app, child_1, Access_Always); View_ID view_1 = panel_get_view(app, child_1, Access_Always);
View_ID view_2 = panel_get_view(app, child_2, Access_Always); View_ID view_2 = panel_get_view(app, child_2, Access_Always);
if (!view_get_is_passive(app, view_1) && !view_get_is_passive(app, view_2)){ if (!view_get_is_passive(app, view_1) && !view_get_is_passive(app, view_2)){
panel_swap_children(app, parent); panel_swap_children(app, parent);
break; break;
} }
parent = panel_get_parent(app, parent); parent = panel_get_parent(app, parent);
} }
} }
@ -1997,12 +1997,12 @@ CUSTOM_DOC("Advances backwards through the undo history of the current buffer.")
View_ID view = get_active_view(app, Access_ReadWriteVisible); View_ID view = get_active_view(app, Access_ReadWriteVisible);
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible); Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
undo__flush_fades(app, buffer); undo__flush_fades(app, buffer);
History_Record_Index current = buffer_history_get_current_state_index(app, buffer); History_Record_Index current = buffer_history_get_current_state_index(app, buffer);
if (current > 0){ if (current > 0){
Record_Info record = buffer_history_get_record_info(app, buffer, current); Record_Info record = buffer_history_get_record_info(app, buffer, current);
i64 new_position = record_get_new_cursor_position_undo(app, buffer, current, record); i64 new_position = record_get_new_cursor_position_undo(app, buffer, current, record);
b32 do_immedite_undo = true; b32 do_immedite_undo = true;
f32 undo_fade_time = 0.33f; f32 undo_fade_time = 0.33f;
b32 enable_undo_fade_out = def_get_config_b32(vars_save_string_lit("enable_undo_fade_out")); b32 enable_undo_fade_out = def_get_config_b32(vars_save_string_lit("enable_undo_fade_out"));
@ -2029,7 +2029,7 @@ CUSTOM_DOC("Advances backwards through the undo history of the current buffer.")
} }
} }
} }
if (do_immedite_undo){ if (do_immedite_undo){
buffer_history_set_current_state_index(app, buffer, current - 1); buffer_history_set_current_state_index(app, buffer, current - 1);
if (record.single_string_backward.size > 0){ if (record.single_string_backward.size > 0){
@ -2038,7 +2038,7 @@ CUSTOM_DOC("Advances backwards through the undo history of the current buffer.")
buffer_post_fade(app, buffer, undo_fade_time, range, color); buffer_post_fade(app, buffer, undo_fade_time, range, color);
} }
} }
view_set_cursor_and_preferred_x(app, view, seek_pos(new_position)); view_set_cursor_and_preferred_x(app, view, seek_pos(new_position));
} }
} }
@ -2049,22 +2049,22 @@ CUSTOM_DOC("Advances forwards through the undo history of the current buffer.")
View_ID view = get_active_view(app, Access_ReadWriteVisible); View_ID view = get_active_view(app, Access_ReadWriteVisible);
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible); Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
undo__flush_fades(app, buffer); undo__flush_fades(app, buffer);
History_Record_Index current = buffer_history_get_current_state_index(app, buffer); History_Record_Index current = buffer_history_get_current_state_index(app, buffer);
History_Record_Index max_index = buffer_history_get_max_record_index(app, buffer); History_Record_Index max_index = buffer_history_get_max_record_index(app, buffer);
if (current < max_index){ if (current < max_index){
Record_Info record = buffer_history_get_record_info(app, buffer, current); Record_Info record = buffer_history_get_record_info(app, buffer, current+1);
i64 new_position = record_get_new_cursor_position_redo(app, buffer, current + 1, record); i64 new_position = record_get_new_cursor_position_redo(app, buffer, current + 1, record);
buffer_history_set_current_state_index(app, buffer, current + 1); buffer_history_set_current_state_index(app, buffer, current + 1);
if (record.single_string_forward.size > 0){ if (record.single_string_forward.size > 0){
Range_i64 range = Ii64_size(record.single_first, record.single_string_forward.size); Range_i64 range = Ii64_size(record.single_first, record.single_string_forward.size);
ARGB_Color color = fcolor_resolve(fcolor_id(defcolor_undo)); ARGB_Color color = fcolor_resolve(fcolor_id(defcolor_undo));
f32 undo_fade_time = 0.33f; f32 undo_fade_time = 0.33f;
buffer_post_fade(app, buffer, undo_fade_time, range, color); buffer_post_fade(app, buffer, undo_fade_time, range, color);
} }
view_set_cursor_and_preferred_x(app, view, seek_pos(new_position)); view_set_cursor_and_preferred_x(app, view, seek_pos(new_position));
} }
} }
@ -2077,7 +2077,7 @@ CUSTOM_DOC("Advances backward through the undo history in the buffer containing
Buffer_ID first_buffer_match = 0; Buffer_ID first_buffer_match = 0;
Buffer_ID last_buffer_match = 0; Buffer_ID last_buffer_match = 0;
i32 match_count = 0; i32 match_count = 0;
{ {
for (Buffer_ID buffer = get_buffer_next(app, 0, Access_Always); for (Buffer_ID buffer = get_buffer_next(app, 0, Access_Always);
buffer != 0; buffer != 0;
@ -2098,11 +2098,11 @@ CUSTOM_DOC("Advances backward through the undo history in the buffer containing
} }
} }
} }
Buffer_ID *match_buffers = push_array(scratch, Buffer_ID, match_count); Buffer_ID *match_buffers = push_array(scratch, Buffer_ID, match_count);
i64 *new_positions = push_array(scratch, i64, match_count); i64 *new_positions = push_array(scratch, i64, match_count);
match_count = 0; match_count = 0;
if (highest_edit_number != -1){ if (highest_edit_number != -1){
for (Buffer_ID buffer = first_buffer_match; for (Buffer_ID buffer = first_buffer_match;
buffer != 0; buffer != 0;
@ -2136,7 +2136,7 @@ CUSTOM_DOC("Advances backward through the undo history in the buffer containing
} }
} }
} }
view_buffer_set(app, match_buffers, new_positions, match_count); view_buffer_set(app, match_buffers, new_positions, match_count);
} }
@ -2144,12 +2144,12 @@ CUSTOM_COMMAND_SIG(redo_all_buffers)
CUSTOM_DOC("Advances forward through the undo history in the buffer containing the most recent regular edit.") CUSTOM_DOC("Advances forward through the undo history in the buffer containing the most recent regular edit.")
{ {
Scratch_Block scratch(app); Scratch_Block scratch(app);
i32 lowest_edit_number = 0x7FFFFFFF; i32 lowest_edit_number = 0x7FFFFFFF;
Buffer_ID first_buffer_match = 0; Buffer_ID first_buffer_match = 0;
Buffer_ID last_buffer_match = 0; Buffer_ID last_buffer_match = 0;
i32 match_count = 0; i32 match_count = 0;
{ {
for (Buffer_ID buffer = get_buffer_next(app, 0, Access_Always); for (Buffer_ID buffer = get_buffer_next(app, 0, Access_Always);
buffer != 0; buffer != 0;
@ -2171,11 +2171,11 @@ CUSTOM_DOC("Advances forward through the undo history in the buffer containing t
} }
} }
} }
Buffer_ID *match_buffers = push_array(scratch, Buffer_ID, match_count); Buffer_ID *match_buffers = push_array(scratch, Buffer_ID, match_count);
i64 *new_positions = push_array(scratch, i64, match_count); i64 *new_positions = push_array(scratch, i64, match_count);
match_count = 0; match_count = 0;
if (lowest_edit_number != -1){ if (lowest_edit_number != -1){
for (Buffer_ID buffer = first_buffer_match; for (Buffer_ID buffer = first_buffer_match;
buffer != 0; buffer != 0;
@ -2210,7 +2210,7 @@ CUSTOM_DOC("Advances forward through the undo history in the buffer containing t
} }
} }
} }
view_buffer_set(app, match_buffers, new_positions, match_count); view_buffer_set(app, match_buffers, new_positions, match_count);
} }
@ -2259,10 +2259,10 @@ reindent_line(Application_Links *app, Buffer_ID buffer, i64 line, i64 indent_del
{ {
Scratch_Block scratch(app); Scratch_Block scratch(app);
View_ID view = get_active_view(app, Access_ReadWriteVisible); View_ID view = get_active_view(app, Access_ReadWriteVisible);
String_Const_u8 line_string = push_buffer_line(app, scratch, buffer, line); String_Const_u8 line_string = push_buffer_line(app, scratch, buffer, line);
i64 line_start_pos = get_line_start_pos(app, buffer, line); i64 line_start_pos = get_line_start_pos(app, buffer, line);
Range_i64 line_indent_range = Ii64(0, 0); Range_i64 line_indent_range = Ii64(0, 0);
i64 tabs_at_beginning = 0; i64 tabs_at_beginning = 0;
i64 spaces_at_beginning = 0; i64 spaces_at_beginning = 0;
@ -2282,7 +2282,7 @@ reindent_line(Application_Links *app, Buffer_ID buffer, i64 line, i64 indent_del
break; break;
} }
} }
// NOTE(PS): This is in the event that we are unindenting a line that // NOTE(PS): This is in the event that we are unindenting a line that
// is JUST tabs or spaces - rather than unindenting nothing // is JUST tabs or spaces - rather than unindenting nothing
// and then reindenting the proper amount, this should cause // and then reindenting the proper amount, this should cause
@ -2294,7 +2294,7 @@ reindent_line(Application_Links *app, Buffer_ID buffer, i64 line, i64 indent_del
line_indent_range.max = line_string.size; line_indent_range.max = line_string.size;
place_cursor_at_end = true; place_cursor_at_end = true;
} }
// NOTE(rjf): Indent lines. // NOTE(rjf): Indent lines.
{ {
Range_i64 indent_range = Range_i64 indent_range =
@ -2302,13 +2302,13 @@ reindent_line(Application_Links *app, Buffer_ID buffer, i64 line, i64 indent_del
line_indent_range.min + line_start_pos, line_indent_range.min + line_start_pos,
line_indent_range.max + line_start_pos, line_indent_range.max + line_start_pos,
}; };
i64 indent_width = (i64)def_get_config_u64(app, vars_save_string_lit("indent_width")); i64 indent_width = (i64)def_get_config_u64(app, vars_save_string_lit("indent_width"));
b32 indent_with_tabs = def_get_config_b32(vars_save_string_lit("indent_with_tabs")); b32 indent_with_tabs = def_get_config_b32(vars_save_string_lit("indent_with_tabs"));
i64 spaces_per_indent_level = indent_width; i64 spaces_per_indent_level = indent_width;
i64 indent_level = spaces_at_beginning / spaces_per_indent_level + tabs_at_beginning; i64 indent_level = spaces_at_beginning / spaces_per_indent_level + tabs_at_beginning;
i64 new_indent_level = indent_level + indent_delta; i64 new_indent_level = indent_level + indent_delta;
String_Const_u8 indent_string; String_Const_u8 indent_string;
if (indent_with_tabs) { if (indent_with_tabs) {
indent_string = str8_lit("\t"); indent_string = str8_lit("\t");
@ -2320,18 +2320,18 @@ reindent_line(Application_Links *app, Buffer_ID buffer, i64 line, i64 indent_del
{ {
buffer_replace_range(app, buffer, Ii64(line_start_pos), indent_string); buffer_replace_range(app, buffer, Ii64(line_start_pos), indent_string);
} }
if (place_cursor_at_end) if (place_cursor_at_end)
{ {
// update line_string now that we've edited the line // update line_string now that we've edited the line
line_string = push_buffer_line(app, scratch, buffer, line); line_string = push_buffer_line(app, scratch, buffer, line);
line_start_pos = get_line_start_pos(app, buffer, line); line_start_pos = get_line_start_pos(app, buffer, line);
i64 line_end_pos = line_start_pos + line_string.size; i64 line_end_pos = line_start_pos + line_string.size;
view_set_cursor(app, view, seek_pos(line_end_pos)); view_set_cursor(app, view, seek_pos(line_end_pos));
} }
} }
} }
internal void internal void
@ -2405,7 +2405,7 @@ adjust_cursor_and_mark_for_indentation(Application_Links *app, View_ID view, i64
break; break;
} }
} }
view_set_cursor(app, view, seek_pos(new_pos)); view_set_cursor(app, view, seek_pos(new_pos));
view_set_mark(app, view, seek_pos(new_pos)); view_set_mark(app, view, seek_pos(new_pos));
} }
@ -2447,7 +2447,7 @@ CUSTOM_COMMAND_SIG(unindent_range)
CUSTOM_COMMAND_SIG(indent_or_autocomplete) CUSTOM_COMMAND_SIG(indent_or_autocomplete)
{ {
Scratch_Block scratch(app); Scratch_Block scratch(app);
View_ID view = get_active_view(app, Access_ReadVisible); View_ID view = get_active_view(app, Access_ReadVisible);
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible); Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
if (buffer != 0) if (buffer != 0)
@ -2492,7 +2492,7 @@ CUSTOM_COMMAND_SIG(input_enter_behavior)
} }
else else
{ {
leave_current_input_unhandled(app); leave_current_input_unhandled(app);
} }
} }