Fix BeforeEdit cursor removal, add multicursor deletion
This commit is contained in:
@@ -183,16 +183,47 @@ for (int i = 0; i < array.len; i += 1) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Simple delete
|
||||||
|
|
||||||
IterRemove(arr) {
|
IterRemove(arr) {
|
||||||
IterRemovePrepare(arr);
|
IterRemovePrepare(arr);
|
||||||
|
|
||||||
remove_item = true;
|
remove_item = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Deleting backwards
|
||||||
|
//
|
||||||
|
|
||||||
For(arr.reverse_iter()) {
|
For(arr.reverse_iter()) {
|
||||||
defer{ arr.unordered_remove(it); };
|
defer{ arr.unordered_remove(it); };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// When double looping and deleting
|
||||||
|
//
|
||||||
|
|
||||||
|
Array<Cursor *> deleted_cursors = {scratch};
|
||||||
|
ForItem(cursor, window->cursors) {
|
||||||
|
For(deleted_cursors) if (it == &cursor) goto end_of_cursor_loop;
|
||||||
|
|
||||||
|
For(window->cursors) {
|
||||||
|
if (&it == &cursor) break;
|
||||||
|
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) {
|
||||||
|
deleted_cursors.add(&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:;
|
||||||
|
}
|
||||||
|
|
||||||
|
For(deleted_cursors) window->cursors.ordered_remove(*it);
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
#define IterRemove(a) for (int i = 0; i < (a).len; i += 1)
|
#define IterRemove(a) for (int i = 0; i < (a).len; i += 1)
|
||||||
#define IterRemovePrepare(a) \
|
#define IterRemovePrepare(a) \
|
||||||
|
|||||||
@@ -247,21 +247,29 @@ Array<LayoutColumn> CalculateVisibleColumns(Arena *arena, Window &window) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BeforeEdit(Window *window) {
|
void BeforeEdit(Window *window) {
|
||||||
|
Scratch scratch;
|
||||||
// Merge cursors that overlap, this needs to be handled before any edits to
|
// Merge cursors that overlap, this needs to be handled before any edits to
|
||||||
// make sure overlapping edits won't happen.
|
// make sure overlapping edits won't happen.
|
||||||
for (int64_t cursor_i = 0; cursor_i < window->cursors.len; cursor_i += 1) {
|
// @optimize: could probably reverse the inner loop and simply unordered remove
|
||||||
Cursor &cursor = window->cursors[cursor_i];
|
Array<Cursor *> deleted_cursors = {scratch};
|
||||||
IterRemove(window->cursors) {
|
ForItem(cursor, window->cursors) {
|
||||||
IterRemovePrepare(window->cursors);
|
For(deleted_cursors) if (it == &cursor) goto end_of_cursor_loop;
|
||||||
if (&cursor == &it) continue;
|
|
||||||
|
|
||||||
if (cursor.range.max >= it.range.min && cursor.range.max <= it.range.max) {
|
For(window->cursors) {
|
||||||
remove_item = true;
|
if (&it == &cursor) break;
|
||||||
cursor.range.max = it.range.max;
|
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) {
|
||||||
|
deleted_cursors.add(&it);
|
||||||
|
cursor.range.max = Max(cursor.range.max, it.range.max);
|
||||||
|
cursor.range.min = Min(cursor.range.min, it.range.min);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
end_of_cursor_loop:;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
For(deleted_cursors) window->cursors.ordered_remove(*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AfterEdit(Window *window, Array<Edit> edits) {
|
void AfterEdit(Window *window, Array<Edit> edits) {
|
||||||
|
|||||||
@@ -312,22 +312,51 @@ int main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (IsKeyPressed(KEY_DELETE) || IsKeyPressedRepeat(KEY_DELETE)) {
|
if (IsKeyPressed(KEY_DELETE) || IsKeyPressedRepeat(KEY_DELETE)) {
|
||||||
if (IsKeyDown(KEY_LEFT_SHIFT)) {
|
// Select things to delete
|
||||||
}
|
For(focused_window->cursors) {
|
||||||
}
|
if (GetRangeSize(it.range)) continue;
|
||||||
if (IsKeyPressed(KEY_BACKSPACE) || IsKeyPressedRepeat(KEY_BACKSPACE)) {
|
if (IsKeyDown(KEY_LEFT_CONTROL)) {
|
||||||
if (IsKeyDown(KEY_LEFT_SHIFT)) {
|
int64_t pos = Seek(focused_window->buffer, it.range.min, ITERATE_FORWARD);
|
||||||
} else {
|
it = MakeCursor(it.range.min, pos);
|
||||||
BeforeEdit(focused_window);
|
} else {
|
||||||
Array<Edit> edits = {FrameArena};
|
int64_t pos = MoveRight(focused_window->buffer, it.range.min);
|
||||||
String string = {};
|
it = MakeCursor(it.range.min, pos);
|
||||||
For(focused_window->cursors) {
|
|
||||||
int64_t pos = MoveLeft(focused_window->buffer, it.range.min);
|
|
||||||
AddEdit(&edits, {pos, it.range.min}, string);
|
|
||||||
}
|
}
|
||||||
ApplyEdits(&focused_window->buffer, edits);
|
|
||||||
AfterEdit(focused_window, edits);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Merge
|
||||||
|
BeforeEdit(focused_window);
|
||||||
|
|
||||||
|
// Modify
|
||||||
|
Array<Edit> edits = {FrameArena};
|
||||||
|
String string = {};
|
||||||
|
For(focused_window->cursors) AddEdit(&edits, it.range, string);
|
||||||
|
ApplyEdits(&focused_window->buffer, edits);
|
||||||
|
AfterEdit(focused_window, edits);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_BACKSPACE) || IsKeyPressedRepeat(KEY_BACKSPACE)) {
|
||||||
|
// Select things to delete
|
||||||
|
For(focused_window->cursors) {
|
||||||
|
if (GetRangeSize(it.range)) continue;
|
||||||
|
if (IsKeyDown(KEY_LEFT_CONTROL)) {
|
||||||
|
int64_t pos = Seek(focused_window->buffer, it.range.min, ITERATE_BACKWARD);
|
||||||
|
it = MakeCursor(pos, it.range.min);
|
||||||
|
} else {
|
||||||
|
int64_t pos = MoveLeft(focused_window->buffer, it.range.min);
|
||||||
|
it = MakeCursor(pos, it.range.min);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge
|
||||||
|
BeforeEdit(focused_window);
|
||||||
|
|
||||||
|
// Modify
|
||||||
|
Array<Edit> edits = {FrameArena};
|
||||||
|
String string = {};
|
||||||
|
For(focused_window->cursors) AddEdit(&edits, it.range, string);
|
||||||
|
ApplyEdits(&focused_window->buffer, edits);
|
||||||
|
AfterEdit(focused_window, edits);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsKeyPressed(KEY_ENTER) || IsKeyPressedRepeat(KEY_ENTER)) {
|
if (IsKeyPressed(KEY_ENTER) || IsKeyPressedRepeat(KEY_ENTER)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user