From f4b77f9c55bd9283002ae8ea405fd3d0626fb2d9 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Mon, 17 Jun 2019 13:05:14 -0700 Subject: [PATCH] Fixed off-by-one problem with buffer_seek_string; fixed history grouping in batch edits --- 4coder_scope_commands.cpp | 2 +- 4ed_api_implementation.cpp | 71 ++++++++--------------- 4ed_edit.cpp | 113 +++++++++++++++++++++++++++---------- 3 files changed, 106 insertions(+), 80 deletions(-) diff --git a/4coder_scope_commands.cpp b/4coder_scope_commands.cpp index 0541ff0a..674f8cce 100644 --- a/4coder_scope_commands.cpp +++ b/4coder_scope_commands.cpp @@ -442,7 +442,7 @@ place_begin_and_end_on_own_lines(Application_Links *app, char *begin, char *end) max_adjustment += begin_str.size; Range new_pos = make_range(range.min + (i32)min_adjustment, range.max + (i32)max_adjustment); - i32 cursor_pos = 0; + i32 cursor_pos = 0; i32 mark_pos = 0; view_get_cursor_pos(app, view, &cursor_pos); diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index e206e73e..2df2328e 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -472,21 +472,30 @@ Buffer_Seek_String(Application_Links *app, Buffer_ID buffer, String_Const_u8 nee String_Const_u8_Array chunks = buffer_get_chunks(&cursor, gap_buffer); Range range = {}; if (direction == Scan_Forward){ - range = make_range(start_pos, size); + i32 adjusted_pos = start_pos + 1; + start_pos = clamp_top(adjusted_pos, size); + range = make_range(adjusted_pos, size); } else{ - range = make_range(0, start_pos); + i32 adjusted_pos = start_pos - 1; + start_pos = clamp_bot(0, adjusted_pos); + range = make_range(0, adjusted_pos); } chunks = buffer_chunks_clamp(chunks, range); - u64_Array jump_table = string_compute_needle_jump_table(scratch, needle, direction); - Character_Predicate dummy = {}; - String_Match_List list = find_all_matches(scratch, 1, - chunks, needle, jump_table, &dummy, direction, - range.min, 0); - if (list.count == 1){ - result = true; - *pos_out = (i32)list.first->index; - *case_sensitive_out = (HasFlag(list.first->flags, StringMatch_CaseSensitive)); + if (chunks.count > 0){ + u64_Array jump_table = string_compute_needle_jump_table(scratch, needle, direction); + Character_Predicate dummy = {}; + String_Match_List list = find_all_matches(scratch, 1, + chunks, needle, jump_table, &dummy, direction, + range.min, 0); + if (list.count == 1){ + result = true; + *pos_out = (i32)list.first->index; + *case_sensitive_out = (HasFlag(list.first->flags, StringMatch_CaseSensitive)); + } + } + else{ + *pos_out = start_pos; } } } @@ -3289,45 +3298,9 @@ Buffer_History_Merge_Record_Range(Application_Links *app, Buffer_ID buffer_id, H Models *models = (Models*)app->cmd_context; Editing_File *file = imp_get_file(models, buffer_id); b32 result = false; - if (file != 0 && history_is_activated(&file->state.history)){ - History *history = &file->state.history; - i32 max_index = history_get_record_count(history); - first_index = clamp_bot(1, first_index); - if (first_index <= last_index && last_index <= max_index){ - i32 current_index = file->state.current_record_index; - if (first_index <= current_index && current_index < last_index){ - System_Functions *system = models->system; - u32 in_range_handler = flags & bitmask_2; - switch (in_range_handler){ - case RecordMergeFlag_StateInRange_MoveStateForward: - { - edit_change_current_history_state(system, models, file, last_index); - current_index = last_index; - }break; - - case RecordMergeFlag_StateInRange_MoveStateBackward: - { - edit_change_current_history_state(system, models, file, first_index); - current_index = first_index; - }break; - - case RecordMergeFlag_StateInRange_ErrorOut: - { - goto done; - }break; - } - } - if (first_index < last_index){ - history_merge_records(&models->mem.arena, &models->mem.heap, history, first_index, last_index); - } - if (current_index >= last_index){ - current_index -= (last_index - first_index); - } - file->state.current_record_index = current_index; - result = true; - } + if (api_check_buffer(file)){ + result = edit_merge_history_range(models, file, first_index, last_index, flags); } - done:; return(result); } diff --git a/4ed_edit.cpp b/4ed_edit.cpp index 6335c9aa..5f83cfd0 100644 --- a/4ed_edit.cpp +++ b/4ed_edit.cpp @@ -313,36 +313,6 @@ edit_single(System_Functions *system, Models *models, Editing_File *file, Range } } -internal b32 -edit_batch(System_Functions *system, Models *models, Editing_File *file, char *str, Buffer_Edit *edits, i32 edit_count, Edit_Behaviors behaviors){ - b32 result = true; - if (edit_count > 0){ - global_history_adjust_edit_grouping_counter(&models->global_history, 1); - - Buffer_Edit *edit_in = edits; - Buffer_Edit *one_past_last = edits + edit_count; - i32 shift = 0; - for (;edit_in < one_past_last; edit_in += 1){ - String_Const_u8 insert_string = SCu8(str + edit_in->str_start, edit_in->len); - Range edit_range = make_range(edit_in->start, edit_in->end); - edit_range.first += shift; - edit_range.one_past_last += shift; - i32 size = buffer_size(&file->state.buffer); - if (0 <= edit_range.first && edit_range.first <= edit_range.one_past_last && edit_range.one_past_last <= size){ - edit_single(system, models, file, edit_range, insert_string, behaviors); - shift += replace_range_compute_shift(edit_range, (i32)insert_string.size); - } - else{ - result = false; - break; - } - } - - global_history_adjust_edit_grouping_counter(&models->global_history, -1); - } - return(result); -} - internal void file_end_file(Models *models, Editing_File *file){ if (models->hook_end_file != 0){ @@ -451,6 +421,89 @@ edit_change_current_history_state(System_Functions *system, Models *models, Edit } } +internal b32 +edit_merge_history_range(Models *models, Editing_File *file, History_Record_Index first_index, History_Record_Index last_index, Record_Merge_Flag flags){ + b32 result = false; + History *history = &file->state.history; + if (history_is_activated(history)){ + i32 max_index = history_get_record_count(history); + first_index = clamp_bot(1, first_index); + if (first_index <= last_index && last_index <= max_index){ + if (first_index < last_index){ + i32 current_index = file->state.current_record_index; + if (first_index <= current_index && current_index < last_index){ + System_Functions *system = models->system; + u32 in_range_handler = (flags & bitmask_2); + switch (in_range_handler){ + case RecordMergeFlag_StateInRange_MoveStateForward: + { + edit_change_current_history_state(system, models, file, last_index); + current_index = last_index; + }break; + + case RecordMergeFlag_StateInRange_MoveStateBackward: + { + edit_change_current_history_state(system, models, file, first_index); + current_index = first_index; + }break; + + case RecordMergeFlag_StateInRange_ErrorOut: + { + goto done; + }break; + } + } + history_merge_records(&models->mem.arena, &models->mem.heap, history, first_index, last_index); + if (current_index >= last_index){ + current_index -= (last_index - first_index); + } + file->state.current_record_index = current_index; + } + result = true; + } + } + done:; + return(result); +} + +internal b32 +edit_batch(System_Functions *system, Models *models, Editing_File *file, char *str, Buffer_Edit *edits, i32 edit_count, Edit_Behaviors behaviors){ + b32 result = true; + if (edit_count > 0){ + History_Record_Index start_index = 0; + if (history_is_activated(&file->state.history)){ + start_index = history_get_record_count(&file->state.history); + } + + Buffer_Edit *edit_in = edits; + Buffer_Edit *one_past_last = edits + edit_count; + i32 shift = 0; + for (;edit_in < one_past_last; edit_in += 1){ + String_Const_u8 insert_string = SCu8(str + edit_in->str_start, edit_in->len); + Range edit_range = make_range(edit_in->start, edit_in->end); + edit_range.first += shift; + edit_range.one_past_last += shift; + i32 size = buffer_size(&file->state.buffer); + if (0 <= edit_range.first && edit_range.first <= edit_range.one_past_last && edit_range.one_past_last <= size){ + edit_single(system, models, file, edit_range, insert_string, behaviors); + shift += replace_range_compute_shift(edit_range, (i32)insert_string.size); + } + else{ + result = false; + break; + } + } + + if (history_is_activated(&file->state.history)){ + History_Record_Index last_index = history_get_record_count(&file->state.history); + if (start_index + 1 < last_index){ + edit_merge_history_range(models, file, start_index + 1, last_index, RecordMergeFlag_StateInRange_ErrorOut); + } + } + } + return(result); +} + //////////////////////////////// internal Editing_File*