Fixed off-by-one problem with buffer_seek_string; fixed history grouping in batch edits
This commit is contained in:
parent
316673af26
commit
f4b77f9c55
|
@ -442,7 +442,7 @@ place_begin_and_end_on_own_lines(Application_Links *app, char *begin, char *end)
|
||||||
max_adjustment += begin_str.size;
|
max_adjustment += begin_str.size;
|
||||||
Range new_pos = make_range(range.min + (i32)min_adjustment, range.max + (i32)max_adjustment);
|
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;
|
i32 mark_pos = 0;
|
||||||
view_get_cursor_pos(app, view, &cursor_pos);
|
view_get_cursor_pos(app, view, &cursor_pos);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
String_Const_u8_Array chunks = buffer_get_chunks(&cursor, gap_buffer);
|
||||||
Range range = {};
|
Range range = {};
|
||||||
if (direction == Scan_Forward){
|
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{
|
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);
|
chunks = buffer_chunks_clamp(chunks, range);
|
||||||
u64_Array jump_table = string_compute_needle_jump_table(scratch, needle, direction);
|
if (chunks.count > 0){
|
||||||
Character_Predicate dummy = {};
|
u64_Array jump_table = string_compute_needle_jump_table(scratch, needle, direction);
|
||||||
String_Match_List list = find_all_matches(scratch, 1,
|
Character_Predicate dummy = {};
|
||||||
chunks, needle, jump_table, &dummy, direction,
|
String_Match_List list = find_all_matches(scratch, 1,
|
||||||
range.min, 0);
|
chunks, needle, jump_table, &dummy, direction,
|
||||||
if (list.count == 1){
|
range.min, 0);
|
||||||
result = true;
|
if (list.count == 1){
|
||||||
*pos_out = (i32)list.first->index;
|
result = true;
|
||||||
*case_sensitive_out = (HasFlag(list.first->flags, StringMatch_CaseSensitive));
|
*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;
|
Models *models = (Models*)app->cmd_context;
|
||||||
Editing_File *file = imp_get_file(models, buffer_id);
|
Editing_File *file = imp_get_file(models, buffer_id);
|
||||||
b32 result = false;
|
b32 result = false;
|
||||||
if (file != 0 && history_is_activated(&file->state.history)){
|
if (api_check_buffer(file)){
|
||||||
History *history = &file->state.history;
|
result = edit_merge_history_range(models, file, first_index, last_index, flags);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
done:;
|
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
113
4ed_edit.cpp
113
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
|
internal void
|
||||||
file_end_file(Models *models, Editing_File *file){
|
file_end_file(Models *models, Editing_File *file){
|
||||||
if (models->hook_end_file != 0){
|
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*
|
internal Editing_File*
|
||||||
|
|
Loading…
Reference in New Issue