Buffer cursor work
This commit is contained in:
@@ -592,8 +592,8 @@ T Get(Array<T> &arr, int64_t i, T default_value = {}) {
|
||||
|
||||
template <class T>
|
||||
void Dealloc(Array<T> *arr) {
|
||||
if (arr->data) Dealloc(arr->allocator, arr->data);
|
||||
arr->len = arr->cap = arr->data = 0;
|
||||
if (arr->data) Dealloc(arr->allocator, &arr->data);
|
||||
arr->len = arr->cap = 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
||||
@@ -157,16 +157,28 @@ Range GetLine(Buffer &buffer, Int line) {
|
||||
}
|
||||
|
||||
Int GetLineNumber(Buffer &buffer, Int pos) {
|
||||
// @optimize: binary search
|
||||
Add(&buffer.line_starts, buffer.len);
|
||||
|
||||
// binary search
|
||||
Int low = 0;
|
||||
Int high = buffer.line_starts.len - 2;
|
||||
Int result = 0;
|
||||
for (Int i = 0; i < buffer.line_starts.len - 1; i += 1) {
|
||||
Range range = {buffer.line_starts[i], buffer.line_starts[i + 1]};
|
||||
|
||||
while (low <= high) {
|
||||
Int mid = low + (high - low) / 2;
|
||||
Range range = {buffer.line_starts[mid], buffer.line_starts[mid + 1]};
|
||||
if (pos >= range.min && pos < range.max) {
|
||||
result = i;
|
||||
result = mid;
|
||||
break;
|
||||
}
|
||||
|
||||
if (range.min < pos) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
high = mid - 1;
|
||||
}
|
||||
}
|
||||
|
||||
Pop(&buffer.line_starts);
|
||||
return result;
|
||||
}
|
||||
@@ -211,6 +223,41 @@ void ValidateLineStarts(Buffer *buffer) {
|
||||
}
|
||||
}
|
||||
|
||||
void MergeCursors(Array<Cursor> *cursors) {
|
||||
Scratch scratch;
|
||||
// Merge cursors that overlap, this needs to be handled before any edits to
|
||||
// make sure overlapping edits won't happen.
|
||||
|
||||
// @optimize @refactor: this is retarded, I hit so many array removal bugs here, without allocation please
|
||||
Array<Cursor *> deleted_cursors = {scratch};
|
||||
ForItem(cursor, *cursors) {
|
||||
if (Contains(deleted_cursors, &cursor)) goto end_of_cursor_loop;
|
||||
|
||||
For(*cursors) {
|
||||
if (&it == &cursor) continue;
|
||||
bool a = cursor.range.max >= it.range.min && cursor.range.max <= it.range.max;
|
||||
bool b = cursor.range.min >= it.range.min && cursor.range.min <= it.range.max;
|
||||
if ((a || b) && !Contains(deleted_cursors, &it)) {
|
||||
Add(&deleted_cursors, &it);
|
||||
cursor.range.max = Max(cursor.range.max, it.range.max);
|
||||
cursor.range.min = Min(cursor.range.min, it.range.min);
|
||||
break;
|
||||
}
|
||||
}
|
||||
end_of_cursor_loop:;
|
||||
}
|
||||
|
||||
Array<Cursor> new_cursors = {cursors->allocator};
|
||||
For(*cursors) {
|
||||
if (Contains(deleted_cursors, &it) == false) {
|
||||
Add(&new_cursors, it);
|
||||
}
|
||||
}
|
||||
Assert(new_cursors.len <= cursors->len);
|
||||
Dealloc(cursors);
|
||||
*cursors = new_cursors;
|
||||
}
|
||||
|
||||
void UpdateLines(Buffer *buffer, Range range, String16 string) {
|
||||
Array<Int> &ls = buffer->line_starts;
|
||||
Int min_line_number = GetLineNumber(*buffer, range.min);
|
||||
@@ -365,6 +412,7 @@ void ApplyEdits(Buffer *buffer, Array<Edit> edits) {
|
||||
edits = edits_copy;
|
||||
}
|
||||
|
||||
// @optimize:
|
||||
For(edits) _ReplaceText(buffer, it.range, it.string);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user