From 36d39f941753b5b854f3cf9901e0dbedf409b6d5 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Thu, 5 Feb 2026 09:20:40 +0100 Subject: [PATCH] Improving SearchEverything, yield happens per character basis, no stalls, or multiple small buffers slowing down search --- src/text_editor/globals.cpp | 16 ++--- .../plugin_search_open_buffers.cpp | 69 +++++++++++++++---- 2 files changed, 62 insertions(+), 23 deletions(-) diff --git a/src/text_editor/globals.cpp b/src/text_editor/globals.cpp index 79b31eb..b4da7e7 100644 --- a/src/text_editor/globals.cpp +++ b/src/text_editor/globals.cpp @@ -182,14 +182,14 @@ RegisterVariable(String, ConfigFolder, ""); RegisterVariable(String, ProjectFolder, ""); // PLUGIN_BUILD_WINDOW -RegisterVariable(String, Build1OnWindows, "build.bat slow"); -RegisterVariable(String, Build1OnUnix, "sh build.sh slow"); -RegisterVariable(String, Build2OnWindows, "build.bat"); -RegisterVariable(String, Build2OnUnix, "sh build.sh"); -RegisterVariable(String, Build3OnWindows, "build.bat release"); -RegisterVariable(String, Build3OnUnix, "sh build.sh release"); -RegisterVariable(String, Build4OnWindows, "build.bat release"); -RegisterVariable(String, Build4OnUnix, "sh build.sh release"); +RegisterVariable(String, Build1OnWindows, "build.bat"); +RegisterVariable(String, Build1OnUnix, "sh build.sh"); +RegisterVariable(String, Build2OnWindows, "build.bat release"); +RegisterVariable(String, Build2OnUnix, "sh build.sh release"); +RegisterVariable(String, Build3OnWindows, "build.bat slow"); +RegisterVariable(String, Build3OnUnix, "sh build.sh slow"); +RegisterVariable(String, Build4OnWindows, "build.bat"); +RegisterVariable(String, Build4OnUnix, "sh build.sh"); // PLUGIN_LOAD_VCVARS diff --git a/src/text_editor/plugin_search_open_buffers.cpp b/src/text_editor/plugin_search_open_buffers.cpp index f2630c6..ec93b26 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; - ViewID view; + BufferID buffer; }; void Coro_SearchOpenBuffers(mco_coro *co) { @@ -12,6 +12,15 @@ void Coro_SearchOpenBuffers(mco_coro *co) { Add(&buffers, it->id); } + SeekFlag flag = SearchCaseSensitive ? SeekFlag_None : SeekFlag_IgnoreCase; + if (SearchWordBoundary) { + flag |= SeekFlag_WordBoundary; + } + bool ignore_case = flag & SeekFlag_IgnoreCase ? true : false; + bool word_boundary = flag & SeekFlag_WordBoundary; + Int max_iters_per_yield = 50000; + Int yield_iters = 0; + ForItem (id, buffers) { Buffer *it = GetBuffer(id, NULL); if (it == NULL || it->special || it->temp || it->dont_try_to_save_in_bulk_ops) { @@ -23,21 +32,51 @@ void Coro_SearchOpenBuffers(mco_coro *co) { } #endif - { - Scratch scratch; - Array occurences = FindAll(scratch, it, param->needle); - View *out_view = GetView(param->view); - ForItem (caret, occurences) { - Int pos = caret.range.min; - Int line = PosToLine(it, pos); - Range range = GetLineRangeWithoutNL(it, line); - Int column = pos - range.min; - String16 line_string = GetString(it, range); - String line_string8 = ToString(scratch, line_string); - Appendf(out_view, "%S ||> %S:%lld:%lld\n", line_string8, it->name, (long long)line + 1, (long long)column + 1); + // :Seek + Buffer *out_buffer = GetBuffer(param->buffer); + String16 find = param->needle; + String16 string = GetString(it); + for (int64_t i = 0; i < string.len; i++) { + String16 substring = GetSlice(string, i, i + find.len); + if (AreEqual(substring, find, ignore_case)) { + bool ok_boundary = true; + if (word_boundary) { + String16 left = GetSlice(string, i - 1, i); + String16 right = GetSlice(string, i + find.len, i + find.len + 1); + if (left.len != 0 && !IsNonWord(left.data[0])) { + ok_boundary = false; + } + if (right.len != 0 && !IsNonWord(right.data[0])) { + ok_boundary = false; + } + } + if (ok_boundary) { + Int line = PosToLine(it, i); + Range range = GetLineRangeWithoutNL(it, line); + Int column = i - range.min; + String16 line_string = GetString(it, range); + U8 *pos = ctx->arena.start; + String line_string8 = ToString(ctx->arena, line_string); + RawAppendf(out_buffer, "%S ||> %S:%lld:%lld\n", line_string8, it->name, (long long)line + 1, (long long)column + 1); + Unwind(&ctx->arena, pos); + } + } + + yield_iters += 1; + if (yield_iters > max_iters_per_yield) { + Yield(co); + yield_iters = 0; + out_buffer = GetBuffer(param->buffer, NULL); + if (out_buffer == NULL) { + return; + } + Buffer *it = GetBuffer(id, NULL); + if (it == NULL) { + goto skip_buffer; + } } } - Yield(co); + skip_buffer:; } } @@ -60,7 +99,7 @@ void UpdateSearchOpenBuffersView() { CCtx *dat = AddCoroutine(Coro_SearchOpenBuffers); SearchOpenBuffersParams *param = AllocType(dat->arena, SearchOpenBuffersParams); param->needle = Copy16(dat->arena, line_string); - param->view = active.view->id; + param->buffer = active.buffer->id; dat->user_ctx = param; dat->dont_wait_until_resolved = true; ResumeCoroutine(dat);