Improving SearchEverything, yield happens per character basis, no stalls, or multiple small buffers slowing down search

This commit is contained in:
Krzosa Karol
2026-02-05 09:20:40 +01:00
parent 3ab6639afb
commit 36d39f9417
2 changed files with 62 additions and 23 deletions

View File

@@ -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

View File

@@ -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<Caret> 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);
// :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 = pos - range.min;
Int column = i - 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);
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;
}
}
}
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);