Trying to add undo
This commit is contained in:
@@ -225,7 +225,7 @@ void MergeSort(int64_t Count, Edit *First, Edit *Temp) {
|
||||
}
|
||||
}
|
||||
|
||||
void ApplyEdits(Buffer *buffer, Array<Edit> edits) {
|
||||
void _ApplyEdits(Buffer *buffer, Array<Edit> edits) {
|
||||
Scratch scratch((Arena *)buffer->allocator.object);
|
||||
Assert(buffer->data[0]);
|
||||
Assert(buffer->allocator.proc);
|
||||
|
||||
@@ -101,7 +101,7 @@ void EventRecording_SimulateGetCharPressed(Window *focused_window) {
|
||||
For(focused_window->cursors) {
|
||||
AddEdit(&edits, it.range, string);
|
||||
}
|
||||
ApplyEdits(&focused_window->buffer, edits);
|
||||
ApplyEdits(focused_window, edits);
|
||||
AfterEdit(focused_window, edits);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,16 @@ struct Layout {
|
||||
Vec2 buffer_world_pixel_size;
|
||||
};
|
||||
|
||||
struct HistoryEntry {
|
||||
Array<Cursor> cursors;
|
||||
Array<Edit> edits;
|
||||
};
|
||||
|
||||
struct History {
|
||||
Array<HistoryEntry> entries;
|
||||
int debug_edit_phase;
|
||||
};
|
||||
|
||||
struct Window {
|
||||
Font font;
|
||||
float font_size;
|
||||
@@ -25,6 +35,7 @@ struct Window {
|
||||
Cursor main_cursor_begin_frame;
|
||||
Array<Cursor> cursors;
|
||||
Buffer buffer;
|
||||
History history;
|
||||
|
||||
Arena layout_arena;
|
||||
Layout layout;
|
||||
@@ -246,7 +257,7 @@ Array<LayoutColumn> CalculateVisibleColumns(Arena *arena, Window &window) {
|
||||
return r;
|
||||
}
|
||||
|
||||
void BeforeEdit(Window *window) {
|
||||
void MergeCursors(Window *window) {
|
||||
Scratch scratch;
|
||||
// Merge cursors that overlap, this needs to be handled before any edits to
|
||||
// make sure overlapping edits won't happen.
|
||||
@@ -280,7 +291,67 @@ void BeforeEdit(Window *window) {
|
||||
window->cursors = new_cursors;
|
||||
}
|
||||
|
||||
void UndoEdit(Window *window) {
|
||||
if (window->history.entries.len <= 0) return;
|
||||
|
||||
HistoryEntry entry = window->history.entries.pop();
|
||||
_ApplyEdits(&window->buffer, entry.edits);
|
||||
|
||||
window->cursors.dealloc();
|
||||
window->cursors = entry.cursors;
|
||||
|
||||
Allocator sys_allocator = GetSystemAllocator();
|
||||
For(entry.edits) Dealloc(sys_allocator, &it.string.data);
|
||||
entry.edits.dealloc();
|
||||
|
||||
// Generate layout
|
||||
Clear(&window->layout_arena);
|
||||
window->layout = CalculateLayout(&window->layout_arena, window->buffer, window->font, window->font_size, window->font_spacing);
|
||||
}
|
||||
|
||||
void BeforeEdit(Window *window) {
|
||||
Assert(window->history.debug_edit_phase == 0);
|
||||
window->history.debug_edit_phase += 1;
|
||||
|
||||
{
|
||||
History &h = window->history;
|
||||
HistoryEntry *entry = h.entries.alloc();
|
||||
Allocator sys_allocator = GetSystemAllocator();
|
||||
Assert(window->cursors.len);
|
||||
entry->cursors = window->cursors.tight_copy(sys_allocator);
|
||||
}
|
||||
|
||||
MergeCursors(window);
|
||||
}
|
||||
|
||||
void ApplyEdits(Window *window, Array<Edit> edits) {
|
||||
Assert(window->history.debug_edit_phase == 1);
|
||||
window->history.debug_edit_phase += 1;
|
||||
|
||||
{
|
||||
HistoryEntry *entry = window->history.entries.last();
|
||||
Allocator sys_allocator = GetSystemAllocator();
|
||||
entry->edits = edits.tight_copy(sys_allocator);
|
||||
For(entry->edits) {
|
||||
// Need to compile reverse edits
|
||||
Range new_range = {it.range.min, it.range.min + it.string.len};
|
||||
String string = GetString(window->buffer, it.range);
|
||||
it.string = Copy(sys_allocator, string);
|
||||
it.range = new_range;
|
||||
}
|
||||
}
|
||||
|
||||
_ApplyEdits(&window->buffer, edits);
|
||||
}
|
||||
|
||||
void AfterEdit(Window *window, Array<Edit> edits) {
|
||||
Assert(window->history.debug_edit_phase == 2);
|
||||
window->history.debug_edit_phase -= 2;
|
||||
|
||||
HistoryEntry *entry = window->history.entries.last();
|
||||
Assert(entry->cursors.len);
|
||||
Assert(entry->edits.len);
|
||||
|
||||
// Offset all cursors by edits
|
||||
ForItem(edit, edits) {
|
||||
int64_t remove_size = GetRangeSize(edit.range);
|
||||
@@ -308,6 +379,7 @@ void AfterEdit(Window *window, Array<Edit> edits) {
|
||||
// Make sure all cursors are in range
|
||||
For(window->cursors) it.range = Clamp(window->buffer, it.range);
|
||||
|
||||
// Generate layout
|
||||
Clear(&window->layout_arena);
|
||||
window->layout = CalculateLayout(&window->layout_arena, window->buffer, window->font, window->font_size, window->font_spacing);
|
||||
}
|
||||
|
||||
@@ -63,27 +63,26 @@ int main() {
|
||||
window.font_size = font_size;
|
||||
window.font_spacing;
|
||||
InitArena(&window.layout_arena);
|
||||
|
||||
InitBuffer(GetSystemAllocator(), &window.buffer);
|
||||
if (1) {
|
||||
// Array<Edit> edits = {FrameArena};
|
||||
// AddEdit(&edits, GetEnd(window.buffer), Format(FrameArena, "line number: 1"));
|
||||
// ApplyEdits(&window.buffer, edits);
|
||||
for (int i = 0; i < 50; i += 1) {
|
||||
Array<Edit> edits = {FrameArena};
|
||||
AddEdit(&edits, GetEnd(window.buffer), Format(FrameArena, "line number: %d\n", i));
|
||||
ApplyEdits(&window.buffer, edits);
|
||||
}
|
||||
}
|
||||
|
||||
window.cursors.allocator = GetSystemAllocator();
|
||||
window.cursors.add({});
|
||||
AfterEdit(&window, {});
|
||||
|
||||
if (1) {
|
||||
for (int i = 0; i < 50; i += 1) {
|
||||
BeforeEdit(&window);
|
||||
Array<Edit> edits = {FrameArena};
|
||||
AddEdit(&edits, GetEnd(window.buffer), Format(FrameArena, "line number: %d\n", i));
|
||||
ApplyEdits(&window, edits);
|
||||
AfterEdit(&window, edits);
|
||||
}
|
||||
}
|
||||
|
||||
*window.cursors.last() = {};
|
||||
windows.add(window);
|
||||
}
|
||||
|
||||
// EnableEventWaiting();
|
||||
int64_t frame = -1;
|
||||
InitEventRecording();
|
||||
while (!WindowShouldClose()) {
|
||||
For(windows) {
|
||||
@@ -91,6 +90,9 @@ int main() {
|
||||
it.main_cursor_begin_frame = it.cursors[0];
|
||||
}
|
||||
|
||||
frame += 1;
|
||||
Dbg("%lld", (long long)frame);
|
||||
|
||||
UpdateEventRecording();
|
||||
|
||||
{
|
||||
@@ -100,7 +102,7 @@ int main() {
|
||||
focused_window->scroll.y -= mouse_wheel;
|
||||
focused_window->scroll.y = ClampBottom(focused_window->scroll.y, 0.f);
|
||||
|
||||
BeforeEdit(focused_window); // Merge cursors
|
||||
MergeCursors(focused_window);
|
||||
if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_A)) {
|
||||
focused_window->cursors.clear();
|
||||
focused_window->cursors.add(MakeCursor(0, focused_window->buffer.len));
|
||||
@@ -167,7 +169,7 @@ int main() {
|
||||
cursors_to_add.add({front, front});
|
||||
}
|
||||
For(cursors_to_add) focused_window->cursors.add(it);
|
||||
BeforeEdit(focused_window); // Merge cursors
|
||||
MergeCursors(focused_window);
|
||||
} 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};
|
||||
@@ -177,7 +179,7 @@ int main() {
|
||||
String string = GetString(focused_window->buffer, line.range);
|
||||
AddEdit(&edits, {line.range.max, line.range.max}, string);
|
||||
}
|
||||
ApplyEdits(&focused_window->buffer, edits);
|
||||
ApplyEdits(focused_window, edits);
|
||||
AfterEdit(focused_window, edits);
|
||||
For(focused_window->cursors) {
|
||||
it.range.max = it.range.min = MoveDown(focused_window->buffer, it.range.min);
|
||||
@@ -204,7 +206,7 @@ int main() {
|
||||
cursors_to_add.add({front, front});
|
||||
}
|
||||
For(cursors_to_add) focused_window->cursors.add(it);
|
||||
BeforeEdit(focused_window); // Merge cursors
|
||||
MergeCursors(focused_window);
|
||||
} 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};
|
||||
@@ -214,7 +216,7 @@ int main() {
|
||||
String string = GetString(focused_window->buffer, line.range);
|
||||
AddEdit(&edits, {line.range.min, line.range.min}, string);
|
||||
}
|
||||
ApplyEdits(&focused_window->buffer, edits);
|
||||
ApplyEdits(focused_window, edits);
|
||||
AfterEdit(focused_window, edits);
|
||||
For(focused_window->cursors) {
|
||||
it.range.max = it.range.min = MoveUp(focused_window->buffer, it.range.min);
|
||||
@@ -240,7 +242,7 @@ int main() {
|
||||
if (Seek(to_seek, needle, &found_index, SeekFlag_IgnoreCase)) {
|
||||
found_index += cursor.range.max;
|
||||
focused_window->cursors.add(MakeCursor(found_index + needle.len, found_index));
|
||||
BeforeEdit(focused_window); // Merge cursors
|
||||
MergeCursors(focused_window);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,7 +290,7 @@ int main() {
|
||||
For(focused_window->cursors) {
|
||||
AddEdit(&edits, it.range, string);
|
||||
}
|
||||
ApplyEdits(&focused_window->buffer, edits);
|
||||
ApplyEdits(focused_window, edits);
|
||||
AfterEdit(focused_window, edits);
|
||||
}
|
||||
if (IsKeyDown(KEY_LEFT_CONTROL) && (IsKeyPressed(KEY_X) || IsKeyPressedRepeat(KEY_X))) {
|
||||
@@ -310,10 +312,14 @@ int main() {
|
||||
}
|
||||
String to_save = Merge(FrameArena, strings, "\n");
|
||||
SetClipboardText(to_save.data);
|
||||
ApplyEdits(&focused_window->buffer, edits);
|
||||
ApplyEdits(focused_window, edits);
|
||||
AfterEdit(focused_window, edits);
|
||||
}
|
||||
|
||||
if (IsKeyDown(KEY_LEFT_CONTROL) && (IsKeyPressed(KEY_Z) || IsKeyPressedRepeat(KEY_Z))) {
|
||||
UndoEdit(focused_window);
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_DELETE) || IsKeyPressedRepeat(KEY_DELETE)) {
|
||||
// Select things to delete
|
||||
For(focused_window->cursors) {
|
||||
@@ -334,7 +340,7 @@ int main() {
|
||||
Array<Edit> edits = {FrameArena};
|
||||
String string = {};
|
||||
For(focused_window->cursors) AddEdit(&edits, it.range, string);
|
||||
ApplyEdits(&focused_window->buffer, edits);
|
||||
ApplyEdits(focused_window, edits);
|
||||
AfterEdit(focused_window, edits);
|
||||
}
|
||||
|
||||
@@ -358,7 +364,7 @@ int main() {
|
||||
Array<Edit> edits = {FrameArena};
|
||||
String string = {};
|
||||
For(focused_window->cursors) AddEdit(&edits, it.range, string);
|
||||
ApplyEdits(&focused_window->buffer, edits);
|
||||
ApplyEdits(focused_window, edits);
|
||||
AfterEdit(focused_window, edits);
|
||||
}
|
||||
|
||||
@@ -366,7 +372,7 @@ int main() {
|
||||
BeforeEdit(focused_window);
|
||||
Array<Edit> edits = {FrameArena};
|
||||
For(focused_window->cursors) AddEdit(&edits, it.range, " ");
|
||||
ApplyEdits(&focused_window->buffer, edits);
|
||||
ApplyEdits(focused_window, edits);
|
||||
AfterEdit(focused_window, edits);
|
||||
}
|
||||
|
||||
@@ -382,7 +388,7 @@ int main() {
|
||||
BeforeEdit(focused_window);
|
||||
Array<Edit> edits = {FrameArena};
|
||||
For(focused_window->cursors) AddEdit(&edits, it.range, "\n");
|
||||
ApplyEdits(&focused_window->buffer, edits);
|
||||
ApplyEdits(focused_window, edits);
|
||||
AfterEdit(focused_window, edits);
|
||||
}
|
||||
|
||||
@@ -402,7 +408,7 @@ int main() {
|
||||
For(focused_window->cursors) {
|
||||
AddEdit(&edits, it.range, string);
|
||||
}
|
||||
ApplyEdits(&focused_window->buffer, edits);
|
||||
ApplyEdits(focused_window, edits);
|
||||
AfterEdit(focused_window, edits);
|
||||
}
|
||||
EventRecording_SimulateGetCharPressed(focused_window);
|
||||
@@ -457,7 +463,7 @@ int main() {
|
||||
window.cursors.clear();
|
||||
}
|
||||
window.cursors.add({col->pos, col->pos});
|
||||
BeforeEdit(&window); // Merge cursors
|
||||
MergeCursors(&window);
|
||||
window.mouse_selecting = true;
|
||||
}
|
||||
|
||||
@@ -572,6 +578,14 @@ int main() {
|
||||
|
||||
Dbg_Draw();
|
||||
EventRecording_Draw();
|
||||
|
||||
Window *focused_window = &windows[0];
|
||||
if (focused_window->mouse_selecting || EventPlaying) {
|
||||
DisableEventWaiting();
|
||||
} else {
|
||||
EnableEventWaiting();
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user