From e52450a3df0cc924db77079f6c164c7fb35b3fc1 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Sat, 17 Jan 2026 10:26:39 +0100 Subject: [PATCH] Big UI cleanup --- src/text_editor/commands.cpp | 175 +++++++----------- src/text_editor/fuzzy_search_view.cpp | 2 +- src/text_editor/globals.cpp | 7 + src/text_editor/plugin_build_window.cpp | 4 +- src/text_editor/plugin_project_management.cpp | 2 +- src/text_editor/plugin_remedybg.cpp | 2 +- .../plugin_search_open_buffers.cpp | 2 +- src/text_editor/plugin_search_window.cpp | 6 +- src/text_editor/text_editor.cpp | 7 + src/text_editor/text_editor.h | 13 +- 10 files changed, 99 insertions(+), 121 deletions(-) diff --git a/src/text_editor/commands.cpp b/src/text_editor/commands.cpp index dfd847f..88322b5 100644 --- a/src/text_editor/commands.cpp +++ b/src/text_editor/commands.cpp @@ -1,12 +1,4 @@ -BSet GetConsoleSet() { - BSet result = {}; - result.window = GetWindow(NullWindowID); - result.view = GetView(NullViewID); - result.buffer = GetBuffer(NullBufferID); - return result; -} - -String GetDir(Buffer *buffer) { +String GetBufferDirectory(Buffer *buffer) { #if PLUGIN_DIRECTORY_NAVIGATION if (buffer->is_dir) { return buffer->name; @@ -16,14 +8,14 @@ String GetDir(Buffer *buffer) { return result; } -String GetMainDir() { +String GetPrimaryDirectory() { BSet main = GetBSet(PrimaryWindowID); - return GetDir(main.buffer); + return GetBufferDirectory(main.buffer); } void JumpTempBuffer(BSet *set, String buffer_name) { if (buffer_name.len == 0) { - buffer_name = GetUniqueBufferName(GetDir(set->buffer), "temp"); + buffer_name = GetUniqueBufferName(GetBufferDirectory(set->buffer), "temp"); } set->view = WindowOpenBufferView(set->window, buffer_name); set->buffer = GetBuffer(set->view->active_buffer); @@ -136,7 +128,7 @@ void UIMessagef(const char *fmt, ...) { NextActiveWindowID = main.window->id; RawAppendf(main.buffer, "\n %S\n :Close\n", string); main.view->carets[0] = FindNext(main.buffer, u":Close", MakeCaret(0)); - AddCommand(&main.view->commands, "Close", "escape | enter", [](){ + AddCommand(&main.view->commands, "Close", EnterOrEscapeKeySet, [](){ BSet active = GetBSet(ActiveWindowID); Close(active.buffer->id); }); @@ -217,7 +209,7 @@ void TrimWhitespace(Buffer *buffer, bool trim_lines_with_caret) { void ApplyFormattingTool(Buffer *buffer, String tool) { Scratch scratch; String string = AllocCharString(scratch, buffer); - ExecResult exec_result = ExecAndWait(scratch, tool, GetDir(buffer), string); + ExecResult exec_result = ExecAndWait(scratch, tool, GetBufferDirectory(buffer), string); String16 string16 = {exec_result.buffer->str, exec_result.buffer->len}; if (exec_result.exit_code == 0) { ReplaceWithoutMovingCarets(buffer, GetRange(buffer), string16); @@ -244,7 +236,7 @@ void CMD_FormatSelection() { MergeCarets(primary.buffer, &primary.view->carets); For (primary.view->carets) { String input_string = ToString(scratch, GetString(primary.buffer, it.range)); - ExecResult exec_result = ExecAndWait(scratch, tool, GetDir(primary.buffer), input_string); + ExecResult exec_result = ExecAndWait(scratch, tool, GetBufferDirectory(primary.buffer), input_string); String16 string16 = {exec_result.buffer->str, exec_result.buffer->len}; AddEdit(&edits, it.range, string16); } @@ -256,7 +248,7 @@ void New(Window *window, String name = "") { Buffer *buffer = GetBuffer(view->active_buffer); Scratch scratch; - String dir = GetDir(buffer); + String dir = GetBufferDirectory(buffer); if (name != "") { if (!IsAbsolute(name)) { name = Format(scratch, "%S/%S", dir, name); @@ -409,7 +401,7 @@ ResolvedOpen ResolveOpen(Allocator alo, String path, ResolveOpenMeta meta) { result.kind = OpenKind_Goto; return result; } else { - String rel_path = Format(alo, "%S/%S", GetMainDir(), path); + String rel_path = Format(alo, "%S/%S", GetPrimaryDirectory(), path); existing_buffer = GetBuffer(rel_path, NULL); if (existing_buffer || FileExists(rel_path)) { result.existing_buffer = existing_buffer; @@ -457,10 +449,10 @@ BSet Open(Window *window, String path, ResolveOpenMeta meta, bool set_active = t NextActiveWindowID = set.window->id; } JumpTempBuffer(&set); - Exec(set.view->id, false, o.path, GetMainDir()); + Exec(set.view->id, false, o.path, GetPrimaryDirectory()); } else if (o.kind == OpenKind_BackgroundExec) { // this shouldn't change the focus/window/view - Exec(NullViewID, false, o.path, GetMainDir()); + Exec(NullViewID, false, o.path, GetPrimaryDirectory()); } else if (o.kind == OpenKind_Command) { EvalCommand(o.path); } @@ -535,7 +527,7 @@ void CMD_KillProcess() { KillProcess(main.view); } RegisterCommand(CMD_KillProcess, "", "Kill process in the last active primary window"); -void AddCommand(Array *arr, String name, String binding, CMDFunction *function) { +void AddCommand(Array *arr, String name, Trigger *trigger, CMDFunction *function) { IterRemove(*arr) { IterRemovePrepare(*arr); if (it.name == name) { @@ -544,50 +536,56 @@ void AddCommand(Array *arr, String name, String binding, CMDFunction *f } Command cmd = {}; cmd.name = name; - cmd.binding = binding; cmd.function = function; - cmd.trigger = ParseKeyCached(binding); + cmd.trigger = trigger; cmd.docs = "Not listing commands attached to things anywhere currently, maybe should change?"; Add(arr, cmd); } -void Coro_Rename(mco_coro *co) { - BSet main = GetBSet(PrimaryWindowID); - Buffer *buffer = main.buffer; - JumpTempBuffer(&main); - NextActiveWindowID = main.window->id; - RawAppendf(main.buffer, "Rename and click enter to submit: [%S]\n :Rename :Cancel", buffer->name); - - main.view->carets[0] = FindNext(main.buffer, u"]", MakeCaret(0)); - main.view->carets[0].range.max = main.view->carets[0].range.min; - AddCommand(&main.view->commands, "Rename", "enter", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Rename";}); - AddCommand(&main.view->commands, "Cancel", "escape", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Cancel";}); - String result = "Cancel"; +UIAction WaitForUIAction(mco_coro *co, BSet main) { + UIAction result = UIAction_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; + if (main.view->ui_action != UIAction_Null) { + result = main.view->ui_action; break; } CoYield(co); } Close(main.buffer->id); + return result; +} +#define AddUIAction(VIEW,NAME,TRIGGER,ACTION) AddCommand(&((VIEW)->commands),(NAME),(TRIGGER),[](){BSet active = GetBSet(ActiveWindowID); active.view->ui_action = (ACTION);}) - if (result == "Rename") { - Caret a = FindNext(main.buffer, u"[", MakeCaret(-1)); - Caret b = FindNext(main.buffer, u"]", MakeCaret(-1)); - if (a.range.min == -1 || b.range.max == -1) { - ReportErrorf("Failed to extract the name for the Rename operation from the buffer"); - return; - } - String16 string16 = GetString(main.buffer, {a.range.max + 1, b.range.max}); - String string = ToString(CoCurr->arena, string16); - buffer->name = Intern(&GlobalInternTable, string); +void Coro_Rename(mco_coro *co) { + BSet main = GetBSet(PrimaryWindowID); + Buffer *original_buffer = main.buffer; + JumpTempBuffer(&main); + NextActiveWindowID = main.window->id; + RawAppendf(main.buffer, "Rename and click enter to submit: [%S]\n :Rename :Cancel", original_buffer->name); + + main.view->carets[0] = FindNext(main.buffer, u"]", MakeCaret(0)); + main.view->carets[0].range.max = main.view->carets[0].range.min; + AddUIAction(main.view, "Rename", EnterKey, UIAction_Yes); + AddUIAction(main.view, "Cancel", EscapeKey, UIAction_Cancel); + UIAction action = WaitForUIAction(co, main); + if (action != UIAction_Yes) { + return; } + + Caret a = FindNext(main.buffer, u"[", MakeCaret(-1)); + Caret b = FindNext(main.buffer, u"]", MakeCaret(-1)); + if (a.range.min == -1 || b.range.max == -1) { + ReportErrorf("Failed to extract the name for the Rename operation from the buffer"); + return; + } + String16 string16 = GetString(main.buffer, {a.range.max + 1, b.range.max}); + String string = ToString(CoCurr->arena, string16); + original_buffer->name = Intern(&GlobalInternTable, string); } void CMD_Rename() { @@ -596,7 +594,7 @@ void CMD_Rename() { CoResume(data); } RegisterCommand(CMD_Rename, "", "Opens a UI asking for a new name of a buffer open in the last active primary window"); -String Coro_YesNoCancel(mco_coro *co, BSet main, String question) { +UIAction Coro_YesNoCancel(mco_coro *co, BSet main, String question) { JumpTempBuffer(&main); NextActiveWindowID = main.window->id; RawAppendf(main.buffer, R"==( @@ -606,24 +604,11 @@ String Coro_YesNoCancel(mco_coro *co, BSet main, String question) { )==", question); main.view->carets[0] = FindNext(main.buffer, u":Yes", MakeCaret(0)); main.view->carets[0].range.min = main.view->carets[0].range.max; - AddCommand(&main.view->commands, "Yes", "enter", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Yes";}); - AddCommand(&main.view->commands, "No", "", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "No";}); - AddCommand(&main.view->commands, "Cancel", "escape", [](){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); - return result; + AddUIAction(main.view, "Yes", EnterKey, UIAction_Yes); + AddUIAction(main.view, "No", NULL, UIAction_No); + AddUIAction(main.view, "Cancel", EscapeKey, UIAction_Cancel); + UIAction ui_action = WaitForUIAction(co, main); + return ui_action; } void Coro_Close(mco_coro *co) { @@ -655,13 +640,13 @@ void Coro_Close(mco_coro *co) { } String question = Format(CoCurr->arena, "Do you want to save [%S] before closing?", main.buffer->name); - String result = Coro_YesNoCancel(co, main, question); - if (result == "Yes") { + UIAction ui_action = Coro_YesNoCancel(co, main, question); + if (ui_action == UIAction_Yes) { SaveBuffer(main.buffer); Close(main.buffer->id); - } else if (result == "No") { + } else if (ui_action == UIAction_No) { Close(main.buffer->id); - } else if (result == "Cancel") { + } else if (ui_action == UIAction_Cancel) { return; } ElseInvalidCodepath(); } @@ -697,12 +682,12 @@ String Coro_CloseAllEx(mco_coro *co) { } String question = Format(CoCurr->arena, "Do you want to save [%S] before closing?", it->name); - String result = Coro_YesNoCancel(co, main, question); + UIAction ui_action = Coro_YesNoCancel(co, main, question); it = GetBuffer(id, NULL); - if (it && result == "Yes") { + if (it && ui_action == UIAction_Yes) { SaveBuffer(it); - } else if (result == "No") { - } else if (result == "Cancel") { + } else if (ui_action == UIAction_No) { + } else if (ui_action == UIAction_Cancel) { return "Cancel"; } ElseInvalidCodepath(); } @@ -749,24 +734,10 @@ void Coro_ReplaceAll(mco_coro *co) { Caret field_seek = BaseFindNext(main.buffer, u"for::", MakeCaret(0), SeekFlag_None); main.view->carets[0] = MakeCaret(main.buffer->len, field_seek.range.max); - AddCommand(&main.view->commands, "Submit", "enter", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Submit";}); - AddCommand(&main.view->commands, "Cancel", "escape", [](){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") { + AddUIAction(main.view, "Submit", EnterKey, UIAction_Yes); + AddUIAction(main.view, "Cancel", EscapeKey, UIAction_Cancel); + UIAction action = WaitForUIAction(co, main); + if (action == UIAction_Cancel) { return; } @@ -782,24 +753,10 @@ void Coro_ReplaceAll(mco_coro *co) { Caret field_seek = BaseFindNext(main.buffer, u"with::", MakeCaret(0), SeekFlag_None); main.view->carets[0] = MakeCaret(main.buffer->len, field_seek.range.max); - AddCommand(&main.view->commands, "Submit", "enter", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Submit";}); - AddCommand(&main.view->commands, "Cancel", "escape", [](){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") { + AddUIAction(main.view, "Submit", EnterKey, UIAction_Yes); + AddUIAction(main.view, "Cancel", EscapeKey, UIAction_Cancel); + UIAction action = WaitForUIAction(co, main); + if (action == UIAction_Cancel) { return; } diff --git a/src/text_editor/fuzzy_search_view.cpp b/src/text_editor/fuzzy_search_view.cpp index f429273..a037c00 100644 --- a/src/text_editor/fuzzy_search_view.cpp +++ b/src/text_editor/fuzzy_search_view.cpp @@ -124,7 +124,7 @@ void UpdateFuzzySearchView() { } void SetFuzzy(View *view) { - AddCommand(&view->commands, "Open", "ctrl-q | enter | f12", [](){ + AddCommand(&view->commands, "Open", OpenKeySet, [](){ BSet active = GetBSet(ActiveWindowID); BSet main = GetBSet(PrimaryWindowID); NextActiveWindowID = main.window->id; diff --git a/src/text_editor/globals.cpp b/src/text_editor/globals.cpp index a321664..e3871b8 100644 --- a/src/text_editor/globals.cpp +++ b/src/text_editor/globals.cpp @@ -39,6 +39,13 @@ WindowID NullWindowID; BufferID SearchBufferID; #endif +Trigger *EscapeKey; +Trigger *EnterKey; +Trigger *OpenKeySet; +Trigger *EnterOrEscapeKeySet; +Trigger *AltEnterKeySet; +Trigger *ShiftEnterKeySet; + WindowID NextActiveWindowID; WindowID ActiveWindowID; WindowID PrimaryWindowID; diff --git a/src/text_editor/plugin_build_window.cpp b/src/text_editor/plugin_build_window.cpp index eaafc47..a25574f 100644 --- a/src/text_editor/plugin_build_window.cpp +++ b/src/text_editor/plugin_build_window.cpp @@ -61,10 +61,10 @@ void CMD_RunFile() { if (OS_WINDOWS) { String cmd = Format(scratch, "cl %S -Fe:cfile.exe /Zi /FC /nologo /WX /W3 /wd4200 /wd4334 /diagnostics:column && cfile.exe", primary.buffer->name); - ExecBuild(cmd, GetDir(primary.buffer)); + ExecBuild(cmd, GetBufferDirectory(primary.buffer)); } else { String cmd = Format(scratch, "bash <name); - ExecBuild(cmd, GetDir(primary.buffer)); + ExecBuild(cmd, GetBufferDirectory(primary.buffer)); } build.window->visible = true; } RegisterCommand(CMD_RunFile, "", "Run and build current file, currently only C/C++ supported"); diff --git a/src/text_editor/plugin_project_management.cpp b/src/text_editor/plugin_project_management.cpp index 8cfd6bc..0ff3ccc 100644 --- a/src/text_editor/plugin_project_management.cpp +++ b/src/text_editor/plugin_project_management.cpp @@ -11,7 +11,7 @@ void SetProjectDirectory(String dir) { void CMD_SetProjectDirectoryHere() { BSet main = GetBSet(PrimaryWindowID); - SetProjectDirectory(GetDir(main.buffer)); + SetProjectDirectory(GetBufferDirectory(main.buffer)); } RegisterCommand(CMD_SetProjectDirectoryHere, "", "Sets work directory to the directory of the current buffer, it also renames couple special buffers to make them accomodate the new ProjectDirectory"); void Coro_OpenCode(mco_coro *co) { diff --git a/src/text_editor/plugin_remedybg.cpp b/src/text_editor/plugin_remedybg.cpp index 8baf42d..85fd7a4 100644 --- a/src/text_editor/plugin_remedybg.cpp +++ b/src/text_editor/plugin_remedybg.cpp @@ -2109,7 +2109,7 @@ bool RDBG_InitConnection() { Scratch scratch; String session_name = Format(scratch, "te%llu", GetTimeNanos()); String remedy_string = Format(scratch, "%S --servername %S", RemedyBGPath, session_name); - Exec(NullViewID, true, remedy_string, GetMainDir()); + Exec(NullViewID, true, remedy_string, GetPrimaryDirectory()); MemoryZero(&RDBG_Ctx, sizeof(RDBG_Ctx)); RDBG_Ctx.cmd.data = command_buf; RDBG_Ctx.cmd.capacity = sizeof(command_buf); diff --git a/src/text_editor/plugin_search_open_buffers.cpp b/src/text_editor/plugin_search_open_buffers.cpp index e342fb7..3079812 100644 --- a/src/text_editor/plugin_search_open_buffers.cpp +++ b/src/text_editor/plugin_search_open_buffers.cpp @@ -76,7 +76,7 @@ void CMD_SearchOpenBuffers() { NextActiveWindowID = main.window->id; JumpTempBuffer(&main); - AddCommand(&main.view->commands, "Open", "ctrl-q | enter | f12", []() { + AddCommand(&main.view->commands, "Open", OpenKeySet, []() { BSet active = GetBSet(ActiveWindowID); BSet main = GetBSet(PrimaryWindowID); NextActiveWindowID = main.window->id; diff --git a/src/text_editor/plugin_search_window.cpp b/src/text_editor/plugin_search_window.cpp index 4c019f9..0490ee2 100644 --- a/src/text_editor/plugin_search_window.cpp +++ b/src/text_editor/plugin_search_window.cpp @@ -73,9 +73,9 @@ void InitSearchWindow() { window->visible = false; window->lose_visibility_on_escape = true; window->jump_history = false; - AddCommand(&view->commands, "SearchAll", "alt-enter", CMD_SearchAll); - AddCommand(&view->commands, "SearchPrevInSearch", "shift-enter", CMD_SearchPrevInSearch); - AddCommand(&view->commands, "SearchNextInSearch", "enter", CMD_SearchNextInSearch); + AddCommand(&view->commands, "SearchAll", AltEnterKeySet, CMD_SearchAll); + AddCommand(&view->commands, "SearchPrevInSearch", ShiftEnterKeySet, CMD_SearchPrevInSearch); + AddCommand(&view->commands, "SearchNextInSearch", EnterKey, CMD_SearchNextInSearch); } void LayoutSearchWindow(Rect2I *rect, int16_t wx, int16_t wy) { diff --git a/src/text_editor/text_editor.cpp b/src/text_editor/text_editor.cpp index 18ecee6..6d759d2 100644 --- a/src/text_editor/text_editor.cpp +++ b/src/text_editor/text_editor.cpp @@ -974,6 +974,13 @@ int main(int argc, char **argv) it.trigger = ParseKeyCached(it.binding); } } + EnterKey = ParseKeyCached("enter"); + EscapeKey = ParseKeyCached("escape"); + OpenKeySet = ParseKeyCached("ctrl-q | enter | f12"); + EnterOrEscapeKeySet = ParseKeyCached("escape | enter"); + AltEnterKeySet = ParseKeyCached("alt-enter"); + ShiftEnterKeySet = ParseKeyCached("shift-enter"); + #if PLUGIN_CONFIG { diff --git a/src/text_editor/text_editor.h b/src/text_editor/text_editor.h index 6a76971..e9e7a10 100644 --- a/src/text_editor/text_editor.h +++ b/src/text_editor/text_editor.h @@ -30,10 +30,17 @@ struct Command { String name; String docs; CMDFunction *function; - String binding; + String binding; // DONT USE, only for ParseKeyCached struct Trigger *trigger; }; +enum UIAction { + UIAction_Null, + UIAction_Cancel, + UIAction_Yes, + UIAction_No, +}; + struct Buffer { BufferID id; String name; @@ -79,7 +86,7 @@ struct View { Caret main_caret_on_begin_frame; bool update_scroll; - String hook_cmd; + UIAction ui_action; Array commands; Function *update_hook; uint64_t prev_search_line_hash; @@ -264,7 +271,7 @@ struct ResolvedOpen { bool existing_buffer; }; -void AddCommand(Array *arr, String name, String binding, CMDFunction *function); +void AddCommand(Array *arr, String name, struct Trigger *trigger, CMDFunction *function); #define RegisterCommand(name, ...) Register_Command RC__##name(&GlobalCommands, name, #name, __VA_ARGS__) struct Register_Command { Register_Command(Array *funcs, CMDFunction *function, String name, String binding, String docs = "") {