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>
|
template <class T>
|
||||||
void Dealloc(Array<T> *arr) {
|
void Dealloc(Array<T> *arr) {
|
||||||
if (arr->data) Dealloc(arr->allocator, arr->data);
|
if (arr->data) Dealloc(arr->allocator, &arr->data);
|
||||||
arr->len = arr->cap = arr->data = 0;
|
arr->len = arr->cap = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|||||||
@@ -157,16 +157,28 @@ Range GetLine(Buffer &buffer, Int line) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Int GetLineNumber(Buffer &buffer, Int pos) {
|
Int GetLineNumber(Buffer &buffer, Int pos) {
|
||||||
// @optimize: binary search
|
|
||||||
Add(&buffer.line_starts, buffer.len);
|
Add(&buffer.line_starts, buffer.len);
|
||||||
|
|
||||||
|
// binary search
|
||||||
|
Int low = 0;
|
||||||
|
Int high = buffer.line_starts.len - 2;
|
||||||
Int result = 0;
|
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) {
|
if (pos >= range.min && pos < range.max) {
|
||||||
result = i;
|
result = mid;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (range.min < pos) {
|
||||||
|
low = mid + 1;
|
||||||
|
} else {
|
||||||
|
high = mid - 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Pop(&buffer.line_starts);
|
Pop(&buffer.line_starts);
|
||||||
return result;
|
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) {
|
void UpdateLines(Buffer *buffer, Range range, String16 string) {
|
||||||
Array<Int> &ls = buffer->line_starts;
|
Array<Int> &ls = buffer->line_starts;
|
||||||
Int min_line_number = GetLineNumber(*buffer, range.min);
|
Int min_line_number = GetLineNumber(*buffer, range.min);
|
||||||
@@ -365,6 +412,7 @@ void ApplyEdits(Buffer *buffer, Array<Edit> edits) {
|
|||||||
edits = edits_copy;
|
edits = edits_copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @optimize:
|
||||||
For(edits) _ReplaceText(buffer, it.range, it.string);
|
For(edits) _ReplaceText(buffer, it.range, it.string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user