Continuing hook refactor

This commit is contained in:
Krzosa Karol
2026-01-09 23:02:22 +01:00
parent 57c179970e
commit 0dd4641044
6 changed files with 242 additions and 238 deletions

View File

@@ -1477,3 +1477,152 @@ void CMD_ClearCarets(HookParam param) {
}
}
} RegisterCommand(CMD_ClearCarets, "escape", "Clear all carets and reset to 1 caret, also do some windowing stuff that closes things on escape");
void Coro_ReplaceAll(mco_coro *co) {
BSet main = GetBSet(PrimaryWindowID);
String16 string = FetchLoadWord(main.view);
String string8 = ToString(CoCurr->arena, string);
String16 needle = {};
String16 replace = {};
{
JumpTempBuffer(&main);
NextActiveWindowID = main.window->id;
RawAppendf(main.buffer, ":Submit (enter) :Cancel (escape)\nString to search for::%S", string8);
Caret field_seek = FindNext(main.buffer, u"for::", MakeCaret(0));
main.view->carets[0] = FindNext(main.buffer, string, field_seek);
AddCommand(&main.view->hooks, "Submit", "enter", [](HookParam param){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Submit";});
AddCommand(&main.view->hooks, "Cancel", "escape", [](HookParam param){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Cancel";});
String result = "Cancel";
for (;;) {
if (main.window->active_view != main.view->id || (main.window->id != PrimaryWindowID && main.window->id != ActiveWindowID) || main.window->close) {
break;
}
if (main.view->hook_cmd != "") {
result = main.view->hook_cmd;
break;
}
CoYield(co);
}
Close(main.buffer->id);
if (result == "Cancel") {
return;
}
field_seek = FindNext(main.buffer, u"for::", MakeCaret(0));
Range range = {field_seek.range.max, main.buffer->len};
needle = GetString(main.buffer, range);
}
{
JumpTempBuffer(&main);
NextActiveWindowID = main.window->id;
RawAppendf(main.buffer, ":Submit (enter) :Cancel (escape)\nString to replace with::%S", ToString(CoCurr->arena, needle));
Caret field_seek = FindNext(main.buffer, u"with::", MakeCaret(0));
main.view->carets[0] = MakeCaret(main.buffer->len, field_seek.range.max);
AddCommand(&main.view->hooks, "Submit", "enter", [](HookParam param){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Submit";});
AddCommand(&main.view->hooks, "Cancel", "escape", [](HookParam param){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Cancel";});
String result = "Cancel";
for (;;) {
if (main.window->active_view != main.view->id || (main.window->id != PrimaryWindowID && main.window->id != ActiveWindowID) || main.window->close) {
break;
}
if (main.view->hook_cmd != "") {
result = main.view->hook_cmd;
break;
}
CoYield(co);
}
Close(main.buffer->id);
if (result == "Cancel") {
return;
}
field_seek = FindNext(main.buffer, u"with::", MakeCaret(0));
Range range = {field_seek.range.max, main.buffer->len};
replace = GetString(main.buffer, range);
}
ForItem (buffer, Buffers) {
if (buffer->special || buffer->is_dir || buffer->temp || buffer->dont_try_to_save_in_bulk_ops) {
continue;
}
View *view = OpenBufferView(buffer->name);
if (SelectAllOccurences(view, needle)) {
Replace(view, replace);
}
}
}
void CMD_ReplaceAll(HookParam param) {
CoRemove("Coro_ReplaceAll");
CoData *data = CoAdd(Coro_ReplaceAll);
CoResume(data);
} RegisterCommand(CMD_ReplaceAll, "ctrl-shift-r", "Search and replace over the entire project, you need to select a text with format like this 'FindAnd@>ReplaceWith' and executing the command will change all occurences of FindAnd to ReplaceWith");
void UpdateSearchProjectView(HookParam param) {
Scratch scratch;
BSet active = GetBSet(ActiveWindowID);
String16 line_string = GetLineStringWithoutNL(active.buffer, 0);
uint64_t hash = HashBytes(line_string.data, line_string.len * sizeof(char16_t));
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);
Append(active.view, "\n", false);
CoRemove("Coro_SearchProject");
CoData *dat = CoAdd(Coro_SearchProject);
SearchProjectParams *param = AllocType(dat->arena, SearchProjectParams);
param->needle = Copy16(dat->arena, line_string);
param->buffer = active.buffer->id;
dat->user_ctx = param;
dat->dont_wait_until_resolved = true;
CoResume(dat);
active.view->carets[0] = caret;
}
}
}
void CMD_SearchProject(HookParam param) {
BSet main = GetBSet(PrimaryWindowID);
String16 string = {};
if (main.view->carets.len == 1 && GetSize(main.view->carets[0]) > 0) {
string = GetString(main.buffer, main.view->carets[0].range);
}
NextActiveWindowID = main.window->id;
Buffer *search_project_buffer = GetBuffer(SearchProjectBufferID);
View *view = WindowOpenBufferView(main.window, search_project_buffer->name);
view->special = true;
view->kind = ViewKind_ActiveSearch;
AddCommand(&view->hooks, "Open", "ctrl-q | enter | f12", [](HookParam param) {
BSet active = GetBSet(ActiveWindowID);
BSet main = GetBSet(PrimaryWindowID);
NextActiveWindowID = main.window->id;
String16 string = FetchFuzzyViewLoadLine(active.view);
main.window->active_goto_list = active.view->id;
main.window->goto_list_pos = active.view->carets[0].range.min;
Open(string);
});
AddHook(&view->hooks, HookKind_AppUpdate, "UpdateSearchProjectView", "", UpdateSearchProjectView);
SelectRange(view, GetLineRangeWithoutNL(search_project_buffer, 0));
if (string.len) {
Replace(view, string);
SelectEntireBuffer(view);
}
} RegisterCommand(CMD_SearchProject, "ctrl-shift-f", "Interactive search over the entire project in a new buffer view");

View File

@@ -4,8 +4,7 @@
// the appropriate handles. This happens in this case when git grep calls
// 'less' program which errors out and doesn't print anything
// @todo: maybe I should ask someone smarter about this!
void UpdateProcesses() {
ProfileFunction();
void UpdateProcesses(HookParam param) {
IterRemove(ActiveProcesses) {
IterRemovePrepare(ActiveProcesses);
Scratch scratch;
@@ -20,7 +19,7 @@ void UpdateProcesses() {
remove_item = true;
}
}
}
} RegisterHook(UpdateProcesses, HookKind_AppUpdate, "", "Polls all the processes and outputs the results to corresponding views");
void Exec(ViewID view, bool scroll_to_end, String cmd, String working_dir) {
Process process = SpawnProcess(cmd, working_dir, {}, ProcessEnviroment);

View File

@@ -20,9 +20,9 @@
#include "buffer.cpp"
#include "view.cpp"
#include "window.cpp"
#include "window_status.cpp"
#include "window_command.cpp"
#include "window_debug.cpp"
#include "window_status.cpp"
#include "window_search.cpp"
#include "window_build.cpp"
#include "process.cpp"
@@ -583,15 +583,23 @@ void Update(Event event) {
OnCommand(event);
For (GlobalHooks) {
{
BSet set = GetBSet(ActiveWindowID);
For (set.view->hooks) {
if (it.kind == HookKind_AppUpdate) {
ProfileScopeEx(it.name);
it.function(HookParam{});
}
}
FuzzySearchViewUpdate();
UpdateProcesses();
For (GlobalHooks) {
if (it.kind == HookKind_AppUpdate) {
ProfileScopeEx(it.name);
it.function(HookParam{});
}
}
}
CoUpdate(&event);
For(IterateInReverse(&order)) {
@@ -886,7 +894,7 @@ int main(int argc, char **argv)
InitBuffers();
InitRender();
ReloadFont(PathToFont, (U32)FontSize);
InitWindows();
CreateWind();
InitOS(ReportWarningf);
For (GlobalHooks) {

View File

@@ -369,8 +369,6 @@ BSet Open(String16 path, ResolveOpenMeta meta = ResolveOpenMeta_Normal);
void CenterView(WindowID window);
void TrimWhitespace(Buffer *buffer, bool trim_lines_with_caret = false);
void JumpTempBuffer(BSet *set, String buffer_name = "");
void CommandWindowLayout(Rect2I *rect, Int wx, Int wy);
void CommandWindowInit();
View *FindView(BufferID buffer_id, View *default_view = NULL);
bool operator==(BufferID a, BufferID b) { return a.id == b.id; }

View File

@@ -114,11 +114,6 @@ View *WindowOpenBufferView(Window *new_parent_window, String name) {
return result;
}
void InitWindows() {
CreateWind();
CommandWindowInit();
}
void CalcNiceties(Window *n) {
float scrollbar_size = (10.f * DPIScale);
float line_numbers_size = (float)n->font->char_spacing * 10.f;
@@ -157,8 +152,6 @@ void LayoutWindows(int16_t wx, int16_t wy) {
}
}
CommandWindowLayout(&screen_rect, wx, wy);
// Column layout
Int c = 0;
double size = WindowCalcEvenResizerValue(wx, &c);

View File

@@ -71,26 +71,41 @@ void OpenCommand(BSet active) {
Open(string);
}
void CMD_CommandWindowOpen(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
BSet main = GetBSet(PrimaryWindowID);
NextActiveWindowID = main.window->id;
String16 string = FetchFuzzyViewLoadLine(active.view);
if (active.view->kind == ViewKind_ActiveSearch) {
main.window->active_goto_list = active.view->id;
main.window->goto_list_pos = active.view->carets[0].range.min;
}
Open(string);
}
struct SearchProjectParams {
String16 needle;
BufferID buffer;
};
void CommandWindowLayout(Rect2I *rect, Int wx, Int wy) {
Window *n = GetWindow(CommandWindowID);
Rect2I copy_rect = *rect;
if (!n->visible) {
rect = &copy_rect;
void Coro_SearchProject(mco_coro *co) {
SearchProjectParams *param = (SearchProjectParams *)CoCurr->user_ctx;
Array<BufferID> buffers = {CoCurr->arena};
For (Buffers) {
Add(&buffers, it->id);
}
ForItem (id, buffers) {
Buffer *it = GetBuffer(id, NULL);
if (it == NULL || it->special || it->is_dir || it->temp || it->dont_try_to_save_in_bulk_ops) {
continue;
}
{
Scratch scratch;
Array<Caret> occurences = FindAll(scratch, it, param->needle);
Buffer *out_buffer = GetBuffer(param->buffer);
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);
RawAppendf(out_buffer, "%S ||> %S:%lld:%lld\n", line_string8, it->name, (long long)line + 1, (long long)column + 1);
}
}
CoYield(co);
}
Int barsize = Clamp((Int)n->font->line_spacing*10, (Int)0, (Int)wx - 100);
n->document_rect = n->total_rect = CutBottom(rect, barsize);
}
float NewFuzzyRate(String16 s, String16 p) {
@@ -167,164 +182,9 @@ Array<FuzzyPair> FuzzySearchLines(Allocator allocator, Buffer *buffer, Int line_
return ratings;
}
struct SearchProjectParams {
String16 needle;
BufferID buffer;
};
void Coro_SearchProject(mco_coro *co) {
SearchProjectParams *param = (SearchProjectParams *)CoCurr->user_ctx;
Array<BufferID> buffers = {CoCurr->arena};
For (Buffers) {
Add(&buffers, it->id);
}
ForItem (id, buffers) {
Buffer *it = GetBuffer(id, NULL);
if (it == NULL || it->special || it->is_dir || it->temp || it->dont_try_to_save_in_bulk_ops) {
continue;
}
{
void UpdateFuzzySearchView(HookParam param) {
Scratch scratch;
Array<Caret> occurences = FindAll(scratch, it, param->needle);
Buffer *out_buffer = GetBuffer(param->buffer);
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);
RawAppendf(out_buffer, "%S ||> %S:%lld:%lld\n", line_string8, it->name, (long long)line + 1, (long long)column + 1);
}
}
CoYield(co);
}
}
void Coro_ReplaceAll(mco_coro *co) {
BSet main = GetBSet(PrimaryWindowID);
String16 string = FetchLoadWord(main.view);
String string8 = ToString(CoCurr->arena, string);
String16 needle = {};
String16 replace = {};
{
JumpTempBuffer(&main);
NextActiveWindowID = main.window->id;
RawAppendf(main.buffer, ":Submit (enter) :Cancel (escape)\nString to search for::%S", string8);
Caret field_seek = FindNext(main.buffer, u"for::", MakeCaret(0));
main.view->carets[0] = FindNext(main.buffer, string, field_seek);
AddCommand(&main.view->hooks, "Submit", "enter", [](HookParam param){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Submit";});
AddCommand(&main.view->hooks, "Cancel", "escape", [](HookParam param){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Cancel";});
String result = "Cancel";
for (;;) {
if (main.window->active_view != main.view->id || (main.window->id != PrimaryWindowID && main.window->id != ActiveWindowID) || main.window->close) {
break;
}
if (main.view->hook_cmd != "") {
result = main.view->hook_cmd;
break;
}
CoYield(co);
}
Close(main.buffer->id);
if (result == "Cancel") {
return;
}
field_seek = FindNext(main.buffer, u"for::", MakeCaret(0));
Range range = {field_seek.range.max, main.buffer->len};
needle = GetString(main.buffer, range);
}
{
JumpTempBuffer(&main);
NextActiveWindowID = main.window->id;
RawAppendf(main.buffer, ":Submit (enter) :Cancel (escape)\nString to replace with::%S", ToString(CoCurr->arena, needle));
Caret field_seek = FindNext(main.buffer, u"with::", MakeCaret(0));
main.view->carets[0] = MakeCaret(main.buffer->len, field_seek.range.max);
AddCommand(&main.view->hooks, "Submit", "enter", [](HookParam param){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Submit";});
AddCommand(&main.view->hooks, "Cancel", "escape", [](HookParam param){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Cancel";});
String result = "Cancel";
for (;;) {
if (main.window->active_view != main.view->id || (main.window->id != PrimaryWindowID && main.window->id != ActiveWindowID) || main.window->close) {
break;
}
if (main.view->hook_cmd != "") {
result = main.view->hook_cmd;
break;
}
CoYield(co);
}
Close(main.buffer->id);
if (result == "Cancel") {
return;
}
field_seek = FindNext(main.buffer, u"with::", MakeCaret(0));
Range range = {field_seek.range.max, main.buffer->len};
replace = GetString(main.buffer, range);
}
ForItem (buffer, Buffers) {
if (buffer->special || buffer->is_dir || buffer->temp || buffer->dont_try_to_save_in_bulk_ops) {
continue;
}
View *view = OpenBufferView(buffer->name);
if (SelectAllOccurences(view, needle)) {
Replace(view, replace);
}
}
}
void CMD_ReplaceAll(HookParam param) {
CoRemove("Coro_ReplaceAll");
CoData *data = CoAdd(Coro_ReplaceAll);
CoResume(data);
} RegisterCommand(CMD_ReplaceAll, "ctrl-shift-r", "Search and replace over the entire project, you need to select a text with format like this 'FindAnd@>ReplaceWith' and executing the command will change all occurences of FindAnd to ReplaceWith");
void FuzzySearchViewUpdate() {
ProfileFunction();
BSet active = GetBSet(ActiveWindowID);
if (active.view->kind == ViewKind_ActiveSearch) {
Scratch scratch;
String16 line_string = GetLineStringWithoutNL(active.buffer, 0);
uint64_t hash = HashBytes(line_string.data, line_string.len * sizeof(char16_t));
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?
Caret caret = active.view->carets[0];
SelectEntireBuffer(active.view);
Replace(active.view, line_string);
Append(active.view, "\n", false);
CoRemove("Coro_SearchProject");
CoData *dat = CoAdd(Coro_SearchProject);
SearchProjectParams *param = AllocType(dat->arena, SearchProjectParams);
param->needle = Copy16(dat->arena, line_string);
param->buffer = active.buffer->id;
dat->user_ctx = param;
dat->dont_wait_until_resolved = true;
CoResume(dat);
active.view->carets[0] = caret;
}
}
} else if (active.view->kind == ViewKind_FuzzySearch) {
Scratch scratch;
String16 line_string = GetLineStringWithoutNL(active.buffer, 0);
uint64_t hash = HashBytes(line_string.data, line_string.len * sizeof(char16_t));
if (active.view->prev_search_line_hash != hash) {
@@ -346,35 +206,31 @@ void FuzzySearchViewUpdate() {
Replace(active.view, GetString(scratch_buff));
active.view->carets[0] = caret;
}
}
}
void CMD_SearchProject(HookParam param) {
BSet main = GetBSet(PrimaryWindowID);
String16 string = {};
if (main.view->carets.len == 1 && GetSize(main.view->carets[0]) > 0) {
string = GetString(main.buffer, main.view->carets[0].range);
}
NextActiveWindowID = main.window->id;
Buffer *search_project_buffer = GetBuffer(SearchProjectBufferID);
View *view = WindowOpenBufferView(main.window, search_project_buffer->name);
view->special = true;
view->kind = ViewKind_ActiveSearch;
AddCommand(&view->hooks, "Open", "ctrl-q | enter | f12", CMD_CommandWindowOpen);
SelectRange(view, GetLineRangeWithoutNL(search_project_buffer, 0));
if (string.len) {
Replace(view, string);
SelectEntireBuffer(view);
}
} RegisterCommand(CMD_SearchProject, "ctrl-shift-f", "Interactive search over the entire project in a new buffer view");
void SetFuzzy(View *view) {
view->kind = ViewKind_FuzzySearch;
AddCommand(&view->hooks, "Open", "ctrl-q | enter | f12", CMD_CommandWindowOpen);
AddCommand(&view->hooks, "Open", "ctrl-q | enter | f12", [](HookParam){
BSet active = GetBSet(ActiveWindowID);
BSet main = GetBSet(PrimaryWindowID);
NextActiveWindowID = main.window->id;
String16 string = FetchFuzzyViewLoadLine(active.view);
Open(string);
});
AddHook(&view->hooks, HookKind_AppUpdate, "UpdateFuzzySearchView", "", UpdateFuzzySearchView);
}
void CommandWindowInit() {
void LayoutCommandWindow(HookParam param) {
auto p = param.layout;
Rect2I copy_rect = *p.rect;
if (!p.window->visible) {
p.rect = &copy_rect;
}
Int barsize = Clamp((Int)p.window->font->line_spacing*10, (Int)0, (Int)p.wx - 100);
p.window->document_rect = p.window->total_rect = CutBottom(p.rect, barsize);
}
void InitCommandWindow(HookParam param) {
Window *window = CreateWind();
CommandWindowID = window->id;
Buffer *buffer = CreateBuffer(SysAllocator, GetUniqueBufferName(WorkDir, "command_bar"));
@@ -393,4 +249,5 @@ void CommandWindowInit() {
window->sync_visibility_with_focus = true;
window->lose_focus_on_escape = true;
window->jump_history = false;
}
AddHook(&window->hooks, HookKind_LayoutWindow, "LayoutCommandWindow", "", LayoutCommandWindow);
} RegisterHook(InitCommandWindow, HookKind_AppInit, "", "Init command window");