From c970c1c7d6b5cf85f0566ae372282f4df51b5bac Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Sat, 17 Jan 2026 08:22:32 +0100 Subject: [PATCH] UndoEdit, RedoEdit fix recursion, search buffers uses temp buffers now --- src/text_editor/buffer.cpp | 70 +++++++++++-------- .../plugin_search_open_buffers.cpp | 9 ++- 2 files changed, 43 insertions(+), 36 deletions(-) diff --git a/src/text_editor/buffer.cpp b/src/text_editor/buffer.cpp index f98b20a..15cb8fa 100644 --- a/src/text_editor/buffer.cpp +++ b/src/text_editor/buffer.cpp @@ -898,53 +898,61 @@ void SaveHistoryBeforeApplyEdits(Buffer *buffer, Array *stack, Arr API void RedoEdit(Buffer *buffer, Array *carets) { ProfileFunction(); if (buffer->no_history) return; - if (buffer->redo_stack.len <= 0) return; - HistoryEntry entry = Pop(&buffer->redo_stack); + for (int i = 0; buffer->redo_stack.len > 0; i += 1) { + HistoryEntry entry = Pop(&buffer->redo_stack); + HistoryEntry *e = SaveHistoryBeforeMergeCursor(buffer, &buffer->undo_stack, *carets); + e->time = entry.time; + SaveHistoryBeforeApplyEdits(buffer, &buffer->undo_stack, entry.edits); + ApplyEditsMultiCursor(buffer, entry.edits); - HistoryEntry *e = SaveHistoryBeforeMergeCursor(buffer, &buffer->undo_stack, *carets); - e->time = entry.time; - SaveHistoryBeforeApplyEdits(buffer, &buffer->undo_stack, entry.edits); - ApplyEditsMultiCursor(buffer, entry.edits); + Dealloc(carets); + *carets = entry.carets; - Dealloc(carets); - *carets = entry.carets; + Allocator sys_allocator = GetSystemAllocator(); + For(entry.edits) Dealloc(sys_allocator, it.string.data); + Dealloc(&entry.edits); - Allocator sys_allocator = GetSystemAllocator(); - For(entry.edits) Dealloc(sys_allocator, it.string.data); - Dealloc(&entry.edits); - - if (buffer->redo_stack.len > 0) { - HistoryEntry *next = GetLast(buffer->redo_stack); - if ((next->time - entry.time) <= UndoMergeTime) { - RedoEdit(buffer, carets); + if (buffer->redo_stack.len > 0) { + HistoryEntry *next = GetLast(buffer->redo_stack); + if ((next->time - entry.time) <= UndoMergeTime) { + continue; + } } + break; } } API void UndoEdit(Buffer *buffer, Array *carets) { ProfileFunction(); if (buffer->no_history) return; - if (buffer->undo_stack.len <= 0) return; - HistoryEntry entry = Pop(&buffer->undo_stack); - HistoryEntry *e = SaveHistoryBeforeMergeCursor(buffer, &buffer->redo_stack, *carets); - e->time = entry.time; - SaveHistoryBeforeApplyEdits(buffer, &buffer->redo_stack, entry.edits); - ApplyEditsMultiCursor(buffer, entry.edits); + static bool warning_reported; + for (int i = 0;buffer->undo_stack.len > 0; i += 1) { + HistoryEntry entry = Pop(&buffer->undo_stack); + HistoryEntry *e = SaveHistoryBeforeMergeCursor(buffer, &buffer->redo_stack, *carets); + e->time = entry.time; + SaveHistoryBeforeApplyEdits(buffer, &buffer->redo_stack, entry.edits); + ApplyEditsMultiCursor(buffer, entry.edits); - Dealloc(carets); - *carets = entry.carets; + Dealloc(carets); + *carets = entry.carets; - Allocator sys_allocator = GetSystemAllocator(); - For(entry.edits) Dealloc(sys_allocator, it.string.data); - Dealloc(&entry.edits); + Allocator sys_allocator = GetSystemAllocator(); + For(entry.edits) Dealloc(sys_allocator, it.string.data); + Dealloc(&entry.edits); - if (buffer->undo_stack.len > 0) { - HistoryEntry *next = GetLast(buffer->undo_stack); - if ((entry.time - next->time) <= UndoMergeTime) { - UndoEdit(buffer, carets); + if (i > 1000 && !warning_reported) { + ReportConsolef("WARNING: Undoing more then 1000 edits at once, optimizations is needed I think, too much memory usage?"); + warning_reported = true; } + if (buffer->undo_stack.len > 0) { + HistoryEntry *next = GetLast(buffer->undo_stack); + if ((entry.time - next->time) <= UndoMergeTime) { + continue; + } + } + break; } } diff --git a/src/text_editor/plugin_search_open_buffers.cpp b/src/text_editor/plugin_search_open_buffers.cpp index d608f6c..e342fb7 100644 --- a/src/text_editor/plugin_search_open_buffers.cpp +++ b/src/text_editor/plugin_search_open_buffers.cpp @@ -1,6 +1,6 @@ struct SearchOpenBuffersParams { String16 needle; - BufferID buffer; + ViewID view; }; void Coro_SearchOpenBuffers(mco_coro *co) { @@ -25,7 +25,7 @@ void Coro_SearchOpenBuffers(mco_coro *co) { { Scratch scratch; Array occurences = FindAll(scratch, it, param->needle); - Buffer *out_buffer = GetBuffer(param->buffer); + View *out_view = GetView(param->view); ForItem (caret, occurences) { Int pos = caret.range.min; Int line = PosToLine(it, pos); @@ -33,7 +33,7 @@ void Coro_SearchOpenBuffers(mco_coro *co) { Int column = pos - range.min; String16 line_string = GetString(it, range); String line_string8 = ToString(scratch, line_string); - RawAppendf(out_buffer, "%S ||> %S:%lld:%lld\n", line_string8, it->name, (long long)line + 1, (long long)column + 1); + Appendf(out_view, "%S ||> %S:%lld:%lld\n", line_string8, it->name, (long long)line + 1, (long long)column + 1); } } CoYield(co); @@ -48,7 +48,6 @@ void UpdateSearchOpenBuffersView() { if (active.view->prev_search_line_hash != hash) { active.view->prev_search_line_hash = hash; if (line_string.len > 0) { - // @todo: do we reintroduce history here? like in fuzzy search view Caret caret = active.view->carets[0]; SelectEntireBuffer(active.view); Replace(active.view, line_string); @@ -58,7 +57,7 @@ void UpdateSearchOpenBuffersView() { CoData *dat = CoAdd(Coro_SearchOpenBuffers); SearchOpenBuffersParams *param = AllocType(dat->arena, SearchOpenBuffersParams); param->needle = Copy16(dat->arena, line_string); - param->buffer = active.buffer->id; + param->view = active.view->id; dat->user_ctx = param; dat->dont_wait_until_resolved = true; CoResume(dat);