diff --git a/src/text_editor/buffer.cpp b/src/text_editor/buffer.cpp index 12cdf3a..f9127c9 100644 --- a/src/text_editor/buffer.cpp +++ b/src/text_editor/buffer.cpp @@ -1557,7 +1557,7 @@ void SaveBuffer(Buffer *buffer) { } } -String GetBufferDirectory(Buffer *buffer) { +String GetDirectory(Buffer *buffer) { #if PLUGIN_DIRECTORY_NAVIGATION if (buffer->is_dir) { return buffer->name; diff --git a/src/text_editor/commands.cpp b/src/text_editor/commands.cpp index 04fee36..83e4de7 100644 --- a/src/text_editor/commands.cpp +++ b/src/text_editor/commands.cpp @@ -178,7 +178,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, GetBufferDirectory(buffer), string); + ExecResult exec_result = ExecAndWait(scratch, tool, GetDirectory(buffer), string); String16 string16 = {exec_result.buffer->str, exec_result.buffer->len}; if (exec_result.exit_code == 0) { ReplaceWithoutMovingCarets(buffer, GetRange(buffer), string16); @@ -205,7 +205,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, GetBufferDirectory(primary.buffer), input_string); + ExecResult exec_result = ExecAndWait(scratch, tool, GetDirectory(primary.buffer), input_string); String16 string16 = {exec_result.buffer->str, exec_result.buffer->len}; AddEdit(&edits, it.range, string16); } @@ -217,7 +217,7 @@ void New(Window *window, String name = "") { Buffer *buffer = GetBuffer(view->active_buffer); Scratch scratch; - String dir = GetBufferDirectory(buffer); + String dir = GetDirectory(buffer); if (name != "") { if (!IsAbsolute(name)) { name = Format(scratch, "%S/%S", dir, name); @@ -315,7 +315,7 @@ void CO_Close(mco_coro *co) { } String question = Format(CoCurr->arena, "Do you want to save [%S] before closing?", main.buffer->name); - UIAction ui_action = ShowYesNoCancelUI(co, main, question); + UIAction ui_action = QueryUserYesNoCancel(co, main, question); if (ui_action == UIAction_Yes) { SaveBuffer(main.buffer); Close(main.buffer->id); @@ -351,7 +351,7 @@ UIAction ShowCloseAllUI(mco_coro *co) { } String question = Format(CoCurr->arena, "Do you want to save [%S] before closing?", it->name); - UIAction ui_action = ShowYesNoCancelUI(co, main, question); + UIAction ui_action = QueryUserYesNoCancel(co, main, question); it = GetBuffer(id, NULL); if (it && ui_action == UIAction_Yes) { SaveBuffer(it); @@ -458,4 +458,9 @@ void CMD_ToggleFullscreen() { SDL_SetWindowPosition(SDLWindow, 0, 0); } IsInFullscreen = !IsInFullscreen; -} RegisterCommand(CMD_ToggleFullscreen, "f11", "switches between the fullscreen and non-fulscreen mode"); +} RegisterCommand(CMD_ToggleFullscreen, "f11", "Switches between the fullscreen and non-fulscreen mode"); + +void CMD_OpenLogs() { + Buffer *buffer = GetBuffer(NullBufferID); + Open(buffer->name); +} RegisterCommand(CMD_OpenLogs, "", "Opens the text editor logs"); \ No newline at end of file diff --git a/src/text_editor/plugin_build_window.cpp b/src/text_editor/plugin_build_window.cpp index 76c250a..3556fba 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, GetBufferDirectory(primary.buffer)); + ExecBuild(cmd, GetDirectory(primary.buffer)); } else { String cmd = Format(scratch, "bash <name); - ExecBuild(cmd, GetBufferDirectory(primary.buffer)); + ExecBuild(cmd, GetDirectory(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 264c0c4..63f5fc8 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(GetBufferDirectory(main.buffer)); + SetProjectDirectory(GetDirectory(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 CO_OpenCode(mco_coro *co) { diff --git a/src/text_editor/text_editor.h b/src/text_editor/text_editor.h index 3f64296..01c0bcc 100644 --- a/src/text_editor/text_editor.h +++ b/src/text_editor/text_editor.h @@ -41,6 +41,32 @@ enum UIAction { UIAction_No, }; +enum OpenKind { + OpenKind_Invalid, + OpenKind_Skip, + OpenKind_Exec, + OpenKind_BackgroundExec, + OpenKind_Goto, + OpenKind_Command, +#if PLUGIN_CONFIG + OpenKind_Set, +#endif +}; + +typedef uint32_t ResolveOpenMeta; +enum { + ResolveOpenMeta_Normal = 0, + ResolveOpenMeta_DontError = 2, + ResolveOpenMeta_DontExec = 4, // dont error + +}; + +struct ResolvedOpen { + OpenKind kind; + String path; + Int line, col; + bool existing_buffer; +}; + struct Buffer { BufferID id; String name; @@ -125,6 +151,8 @@ struct Window { ViewID active_goto_list; Int goto_list_pos; + String ui_query_file; + void (*after_resolve_open_hook)(Window *window, ResolvedOpen *resolved); Array commands; struct { uint32_t draw_scrollbar : 1; @@ -245,32 +273,6 @@ struct Register_Variable { type name = __VA_ARGS__; \ Register_Variable var_##name(&Variables, VariableType_##type, #name, &name) -enum OpenKind { - OpenKind_Invalid, - OpenKind_Skip, - OpenKind_Exec, - OpenKind_BackgroundExec, - OpenKind_Goto, - OpenKind_Command, -#if PLUGIN_CONFIG - OpenKind_Set, -#endif -}; - -typedef uint32_t ResolveOpenMeta; -enum { - ResolveOpenMeta_Normal = 0, - ResolveOpenMeta_DontError = 2, - ResolveOpenMeta_DontExec = 4, // dont error + -}; - -struct ResolvedOpen { - OpenKind kind; - String path; - Int line, col; - bool existing_buffer; -}; - void AddCommand(Array *arr, String name, struct Trigger *trigger, CMDFunction *function); struct Register_Command { Register_Command(Array *funcs, CMDFunction *function, String name, String binding, String docs = "") { @@ -330,7 +332,7 @@ View *CreateView(BufferID active_buffer); void EvalCommand(String command); void EvalCommand(String16 command); Rect2I GetVisibleCells(Window *window); -ResolvedOpen ResolveOpen(Allocator scratch, String path, ResolveOpenMeta meta); +ResolvedOpen ResolveOpen(Allocator scratch, Window *window, String path, ResolveOpenMeta meta); BSet Open(String path, ResolveOpenMeta meta = ResolveOpenMeta_Normal); BSet Open(String16 path, ResolveOpenMeta meta = ResolveOpenMeta_Normal); void CenterView(WindowID window); diff --git a/src/text_editor/ui.cpp b/src/text_editor/ui.cpp index 0517df7..601af34 100644 --- a/src/text_editor/ui.cpp +++ b/src/text_editor/ui.cpp @@ -1,6 +1,6 @@ void JumpTempBuffer(BSet *set, String buffer_name) { if (buffer_name.len == 0) { - buffer_name = GetUniqueBufferName(GetBufferDirectory(set->buffer), "temp"); + buffer_name = GetUniqueBufferName(GetDirectory(set->buffer), "temp"); } set->view = WindowOpenBufferView(set->window, buffer_name); set->buffer = GetBuffer(set->view->active_buffer); @@ -41,7 +41,7 @@ UIAction WaitForUIAction(mco_coro *co, BSet main) { return result; } -UIAction ShowYesNoCancelUI(mco_coro *co, BSet main, String question) { +UIAction QueryUserYesNoCancel(mco_coro *co, BSet main, String question) { JumpTempBuffer(&main); NextActiveWindowID = main.window->id; RawAppendf(main.buffer, R"==( @@ -72,11 +72,53 @@ void ShowUIMessagef(const char *fmt, ...) { }); } +void DetectUserFileCallback(Window *window, ResolvedOpen *resolved) { + if (resolved->kind == OpenKind_Goto) { + if (IsFile(resolved->path)) { + resolved->kind = OpenKind_Skip; + window->ui_query_file = Intern(&GlobalInternTable, resolved->path); + window->after_resolve_open_hook = NULL; + } + } +} + +String16 QueryUserString(mco_coro *co, String ask) { + BSet main = GetBSet(PrimaryWindowID); + Buffer *original_buffer = main.buffer; + JumpTempBuffer(&main); + NextActiveWindowID = main.window->id; + RawAppendf(main.buffer, R"==( + (Enter) :Submit :Cancel (Escape) + +%S +================================================ +>)==", ask); + + main.view->carets[0] = MakeCaret(GetBufferEnd(main.buffer)); + AddUIAction(main.view, "Submit", EnterKey, UIAction_Yes); + AddUIAction(main.view, "Cancel", EscapeKey, UIAction_Cancel); + UIAction action = WaitForUIAction(co, main); + if (action != UIAction_Yes) { + return u""; + } + + Caret a = FindNext(main.buffer, u">", MakeCaret(-1)); + if (a.range.min == -1) { + ReportErrorf("You changed the format of the UI buffer, I was looking for the '>' but can't find it, can't proceed"); + return u""; + } + + a.range.min = a.range.max + 1; + a.range.max = GetBufferEnd(main.buffer); + return GetString(main.buffer, a.range); +} + String QueryUserFile(mco_coro *co) { -// @todo: how to make it so that it doesn't open the file? #if PLUGIN_DIRECTORY_NAVIGATION - Open(GetPrimaryDirectory()); Window *window = GetWindow(PrimaryWindowID); + ViewID original_view = window->active_view; + Open(GetPrimaryDirectory()); + window->after_resolve_open_hook = DetectUserFileCallback; String filename = ""; for (;;) { BSet main = GetBSet(window); @@ -84,25 +126,34 @@ String QueryUserFile(mco_coro *co) { break; } - if (!main.buffer->is_dir) { - filename = main.buffer->name; + if (window->after_resolve_open_hook == NULL) { break; } CoYield(co); } - return filename; + window->active_view = original_view; + return window->ui_query_file; #else - // Just simple query - // @todo: do we want to split like this? The plugin is maybe leaking too much? - // @todo: String QueryUserString(mco_coro *co) + String16 string16 = QueryUserString(co, "Please input the path to the desired file"); + String result = ""; + { + Scratch scratch; + String i = ToString(scratch, string16); + result = Intern(&GlobalInternTable, i); + } + return result; #endif - return "todo"; } void CO_TestQueryFile(mco_coro *co) { - String file = QueryUserFile(co); - ReportConsolef("%S", file); + //String file = QueryUserFile(co); + String16 file16 = QueryUserString(co, "Input some kind of a string PLEASE!"); + { + Scratch scratch; + String file = ToString(scratch, file16); + ReportConsolef("%S", file); + } } RegisterCoroutineCommand(CO_TestQueryFile, "", ""); void MouseLoadWord(Event event, ResolveOpenMeta meta = ResolveOpenMeta_Normal) { @@ -124,68 +175,59 @@ void MouseLoadWord(Event event, ResolveOpenMeta meta = ResolveOpenMeta_Normal) { } } -ResolvedOpen ResolveOpen(Allocator alo, String path, ResolveOpenMeta meta) { +ResolvedOpen ResolveOpen(Allocator alo, Window *window, String path, ResolveOpenMeta meta) { ResolvedOpen result = {}; path = Trim(path); + bool exec = !(ResolveOpenMeta_DontExec & meta); - // Editor command - if(!(ResolveOpenMeta_DontExec & meta)) { - if (StartsWith(path, ":")) { #if PLUGIN_CONFIG - if (StartsWith(path, ":Set ")) { - result.kind = OpenKind_Set; - result.path = Skip(path, 5); - return result; - } + if (exec && result.kind == OpenKind_Invalid && StartsWith(path, ":Set ")) { + result.kind = OpenKind_Set; + result.path = Skip(path, 5); + } #endif - result.kind = OpenKind_Command; - path = Skip(path, 1); - result.path.data = path.data; - for (Int i = 0; i < path.len; i += 1) { - if (IsNonWord(path.data[i])) { - break; - } - result.path.len += 1; + // :Command + if (exec && result.kind == OpenKind_Invalid && StartsWith(path, ":")) { + result.kind = OpenKind_Command; + path = Skip(path, 1); + result.path.data = path.data; + for (Int i = 0; i < path.len; i += 1) { + if (IsNonWord(path.data[i])) { + break; } - return result; + result.path.len += 1; } } - // Shell - if (!(ResolveOpenMeta_DontExec & meta)) { - if (StartsWith(path, "!!")) { - result.kind = OpenKind_BackgroundExec; - result.path = Skip(path, 2); - return result; - } - if (StartsWith(path, "!")) { - result.kind = OpenKind_Exec; - result.path = Skip(path, 1); - return result; - } + // !!exec_hidden + if (exec && result.kind == OpenKind_Invalid && StartsWith(path, "!!")) { + result.kind = OpenKind_BackgroundExec; + result.path = Skip(path, 2); } - // Web - if (!(ResolveOpenMeta_DontExec & meta)) { - if (StartsWith(path, "https://") || StartsWith(path, "http://")) { - result.path = Format(alo, "%S %S", InternetBrowser, path); - result.kind = OpenKind_BackgroundExec; - return result; - } + // !exec + if (exec && result.kind == OpenKind_Invalid && StartsWith(path, "!")) { + result.kind = OpenKind_Exec; + result.path = Skip(path, 1); } - // Commit - if (!(ResolveOpenMeta_DontExec & meta)) { - if (StartsWith(path, "commit ")) { - path = Skip(path, 7); - result.path = Format(alo, "git --no-pager show %S", path); - result.kind = OpenKind_Exec; - return result; - } + // https://web + bool web = StartsWith(path, "https://") || StartsWith(path, "http://"); + if (exec && result.kind == OpenKind_Invalid && web) { + result.path = Format(alo, "%S %S", InternetBrowser, path); + result.kind = OpenKind_BackgroundExec; } - { + // commit 3kc09as92 + if (exec && result.kind == OpenKind_Invalid && StartsWith(path, "commit ")) { + path = Skip(path, 7); + result.path = Format(alo, "git --no-pager show %S", path); + result.kind = OpenKind_Exec; + } + + // c:/filename:32:12 + if (result.kind == OpenKind_Invalid) { String p = NormalizePath(alo, path); if (p.len == 2 && IsAlphabetic(ToLowerCase(At(p, 0))) && At(p, 1) == ':') { p = Format(alo, "%S/", p); @@ -225,34 +267,35 @@ ResolvedOpen ResolveOpen(Allocator alo, String path, ResolveOpenMeta meta) { } Buffer *existing_buffer = GetBuffer(path, NULL); - if (existing_buffer != NULL) { + if (result.kind == OpenKind_Invalid && existing_buffer != NULL) { result.path = path; result.kind = OpenKind_Goto; result.existing_buffer = true; - return result; } - if (is_absolute && FileExists(path)) { + if (result.kind == OpenKind_Invalid && is_absolute && FileExists(path)) { result.path = path; result.kind = OpenKind_Goto; - return result; - } else { - String rel_path = Format(alo, "%S/%S", GetPrimaryDirectory(), path); + } + + if (result.kind == OpenKind_Invalid) { + String rel_path = Format(alo, "%S/%S", GetDirectory(window), path); existing_buffer = GetBuffer(rel_path, NULL); if (existing_buffer || FileExists(rel_path)) { result.existing_buffer = existing_buffer; result.path = rel_path; result.kind = OpenKind_Goto; - return result; } } - } - if (meta & ResolveOpenMeta_DontError) { + if (result.kind == OpenKind_Invalid && (meta & ResolveOpenMeta_DontError)) { result.path = path; result.kind = OpenKind_Skip; - return result; + } + + if (window->after_resolve_open_hook) { + window->after_resolve_open_hook(window, &result); } return result; @@ -261,7 +304,7 @@ ResolvedOpen ResolveOpen(Allocator alo, String path, ResolveOpenMeta meta) { BSet Open(Window *window, String path, ResolveOpenMeta meta, bool set_active = true) { Scratch scratch; BSet set = GetBSet(window); - ResolvedOpen o = ResolveOpen(scratch, path, meta); + ResolvedOpen o = ResolveOpen(scratch, window, path, meta); if (o.kind == OpenKind_Goto) { if (set_active) { NextActiveWindowID = set.window->id; @@ -274,8 +317,8 @@ BSet Open(Window *window, String path, ResolveOpenMeta meta, bool set_active = t } Buffer *buffer = GetBuffer(view->active_buffer); - if (o.line != -1) { - if (o.col == -1) o.col = 1; + if (o.line != 0) { + if (o.col == 0) o.col = 1; Int pos = XYToPos(buffer, {o.col - 1, o.line - 1}); SelectRange(view, MakeCaret(pos)); } diff --git a/src/text_editor/window.cpp b/src/text_editor/window.cpp index ad19dce..3205dfe 100644 --- a/src/text_editor/window.cpp +++ b/src/text_editor/window.cpp @@ -393,7 +393,12 @@ BSet GetBSet(WindowID window_id) { String GetPrimaryDirectory() { BSet main = GetBSet(PrimaryWindowID); - return GetBufferDirectory(main.buffer); + return GetDirectory(main.buffer); +} + +String GetDirectory(Window *window) { + BSet main = GetBSet(PrimaryWindowID); + return GetDirectory(main.buffer); } void MoveCursorByPageSize(Window *window, int direction, bool shift = false) {