Improving SearchEverything, yield happens per character basis, no stalls, or multiple small buffers slowing down search
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user