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;
|
||||
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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
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
|
||||
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*
|
||||
|
|
Loading…
Reference in New Issue