Adding commands, BeforeEdit AfterEdit

This commit is contained in:
Krzosa Karol
2024-06-25 07:29:28 +02:00
parent 84f0b65fa9
commit 7ef502f3b0
2 changed files with 95 additions and 27 deletions

View File

@@ -103,7 +103,26 @@ int64_t MoveUp(Buffer &buffer, int64_t pos) {
return new_pos;
}
void UpdateCursorsAfterEdit(Window *window, Array<Edit> edits) {
void BeforeEdit(Window *window) {
// Merge cursors that overlap, this needs to be handled before any edits to
// make sure overlapping edits won't happen.
for (int64_t cursor_i = 0; cursor_i < window->cursors.len; cursor_i += 1) {
Cursor &cursor = window->cursors[cursor_i];
IterRemove(window->cursors) {
IterRemovePrepare(window->cursors);
if (&cursor == &it) continue;
if (cursor.range.max >= it.range.min && cursor.range.max <= it.range.max) {
remove_item = true;
cursor.range.max = it.range.max;
break;
}
}
}
}
void AfterEdit(Window *window, Array<Edit> edits) {
// First offset all cursors by edits
ForItem(edit, edits) {
int64_t remove_size = GetRangeSize(edit.range);
int64_t insert_size = edit.string.len;
@@ -194,7 +213,13 @@ int main() {
if (IsKeyPressed(KEY_LEFT) || IsKeyPressedRepeat(KEY_LEFT)) {
For(focused_window->cursors) {
if (IsKeyDown(KEY_LEFT_CONTROL)) {
it.range.max = it.range.min = Seek(focused_window->buffer, it.range.min, ITERATE_BACKWARD);
if (IsKeyDown(KEY_LEFT_SHIFT)) {
int64_t front = GetFront(it);
front = Seek(focused_window->buffer, front, ITERATE_BACKWARD);
it = ChangeFront(it, front);
} else {
it.range.max = it.range.min = Seek(focused_window->buffer, it.range.min, ITERATE_BACKWARD);
}
} else {
if (IsKeyDown(KEY_LEFT_SHIFT)) {
int64_t front = GetFront(it);
@@ -213,7 +238,13 @@ int main() {
if (IsKeyPressed(KEY_RIGHT) || IsKeyPressedRepeat(KEY_RIGHT)) {
For(focused_window->cursors) {
if (IsKeyDown(KEY_LEFT_CONTROL)) {
it.range.max = it.range.min = Seek(focused_window->buffer, it.range.min, ITERATE_FORWARD);
if (IsKeyDown(KEY_LEFT_SHIFT)) {
int64_t front = GetFront(it);
front = Seek(focused_window->buffer, front, ITERATE_FORWARD);
it = ChangeFront(it, front);
} else {
it.range.max = it.range.min = Seek(focused_window->buffer, it.range.min, ITERATE_FORWARD);
}
} else {
if (IsKeyDown(KEY_LEFT_SHIFT)) {
int64_t front = GetFront(it);
@@ -230,45 +261,75 @@ int main() {
}
}
if (IsKeyPressed(KEY_DOWN) || IsKeyPressedRepeat(KEY_DOWN)) {
For(focused_window->cursors) {
if (IsKeyDown(KEY_LEFT_SHIFT)) {
if (IsKeyDown(KEY_LEFT_SHIFT) && IsKeyDown(KEY_LEFT_ALT)) { // Default in VSCode seems to be Ctrl + Alt + down
For(focused_window->cursors) {
int64_t front = GetFront(it);
front = MoveDown(focused_window->buffer, front);
focused_window->cursors.add({front, front});
}
} else if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyDown(KEY_LEFT_ALT)) { // Default in VSCode seems to be Shift + Alt + down
BeforeEdit(focused_window);
Array<Edit> edits = {FrameArena};
For(focused_window->cursors) {
int64_t front = GetFront(it);
Line line = FindLine(focused_window->buffer, front);
String string = GetString(focused_window->buffer, {line.range.min, line.range.max + 1});
AddEdit(&edits, {line.range.max + 1, line.range.max + 1}, string);
}
ApplyEdits(&focused_window->buffer, edits);
AfterEdit(focused_window, edits);
For(focused_window->cursors) {
it.range.max = it.range.min = MoveDown(focused_window->buffer, it.range.min);
}
} else if (IsKeyDown(KEY_LEFT_SHIFT)) {
For(focused_window->cursors) {
int64_t front = GetFront(it);
front = MoveDown(focused_window->buffer, front);
it = ChangeFront(it, front);
} else {
}
} else {
For(focused_window->cursors) {
it.range.max = it.range.min = MoveDown(focused_window->buffer, it.range.min);
}
}
}
if (IsKeyPressed(KEY_UP) || IsKeyPressedRepeat(KEY_UP)) {
For(focused_window->cursors) {
if (IsKeyDown(KEY_LEFT_SHIFT)) {
if (IsKeyDown(KEY_LEFT_SHIFT) && IsKeyDown(KEY_LEFT_ALT)) { // Default in VSCode seems to be Ctrl + Alt + up
For(focused_window->cursors) {
int64_t front = GetFront(it);
front = MoveUp(focused_window->buffer, front);
focused_window->cursors.add({front, front});
}
} else if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyDown(KEY_LEFT_ALT)) { // Default in VSCode seems to be Shift + Alt + up
BeforeEdit(focused_window);
Array<Edit> edits = {FrameArena};
For(focused_window->cursors) {
int64_t front = GetFront(it);
Line line = FindLine(focused_window->buffer, front);
String string = GetString(focused_window->buffer, {line.range.min, line.range.max + 1});
AddEdit(&edits, {line.range.min, line.range.min}, string);
}
ApplyEdits(&focused_window->buffer, edits);
AfterEdit(focused_window, edits);
For(focused_window->cursors) {
it.range.max = it.range.min = MoveUp(focused_window->buffer, it.range.min);
}
} else if (IsKeyDown(KEY_LEFT_SHIFT)) {
For(focused_window->cursors) {
int64_t front = GetFront(it);
front = MoveUp(focused_window->buffer, front);
it = ChangeFront(it, front);
} else {
}
} else {
For(focused_window->cursors) {
it.range.max = it.range.min = MoveUp(focused_window->buffer, it.range.min);
}
}
}
// Merge cursors that overlap, this needs to be handled before any edits to
// make sure overlapping edits won't happen.
for (int64_t cursor_i = 0; cursor_i < focused_window->cursors.len; cursor_i += 1) {
Cursor &cursor = focused_window->cursors[cursor_i];
IterRemove(focused_window->cursors) {
IterRemovePrepare(focused_window->cursors);
if (&cursor == &it) continue;
if (cursor.range.max >= it.range.min && cursor.range.max <= it.range.max) {
remove_item = true;
cursor.range.max = it.range.max;
break;
}
}
}
if (IsKeyPressed(KEY_BACKSPACE) || IsKeyPressedRepeat(KEY_BACKSPACE)) {
BeforeEdit(focused_window);
Array<Edit> edits = {FrameArena};
String string = {};
For(focused_window->cursors) {
@@ -276,7 +337,7 @@ int main() {
AddEdit(&edits, {pos, it.range.min}, string);
}
ApplyEdits(&focused_window->buffer, edits);
UpdateCursorsAfterEdit(focused_window, edits);
AfterEdit(focused_window, edits);
}
// Handle user input
@@ -290,12 +351,13 @@ int main() {
string = {(char *)utf8.out_str, (int64_t)utf8.len};
}
BeforeEdit(focused_window);
Array<Edit> edits = {FrameArena};
For(focused_window->cursors) {
AddEdit(&edits, it.range, string);
}
ApplyEdits(&focused_window->buffer, edits);
UpdateCursorsAfterEdit(focused_window, edits);
AfterEdit(focused_window, edits);
}
}