Fixed off-by-one problem with buffer_seek_string; fixed history grouping in batch edits

This commit is contained in:
Allen Webster 2019-06-17 13:05:14 -07:00
parent 316673af26
commit f4b77f9c55
3 changed files with 106 additions and 80 deletions

View File

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

View File

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

View File

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