diff --git a/src/text_editor/commands.cpp b/src/text_editor/commands.cpp index 671864b..b6a2e57 100644 --- a/src/text_editor/commands.cpp +++ b/src/text_editor/commands.cpp @@ -1,16 +1,3 @@ -BSet GetBSet(Window *window) { - BSet set = {window}; - set.view = GetView(set.window->active_view); - set.buffer = GetBuffer(set.view->active_buffer); - return set; -} - -BSet GetBSet(WindowID window_id) { - Window *window = GetWindow(window_id); - BSet result = GetBSet(window); - return result; -} - BSet GetConsoleSet() { BSet result = {}; result.window = GetWindow(NullWindowID); @@ -43,25 +30,6 @@ void JumpTempBuffer(BSet *set, String buffer_name) { set->buffer->temp = true; } -void MouseLoadWord(Event event, ResolveOpenMeta meta = ResolveOpenMeta_Normal) { - Vec2I mouse = MouseVec2I(); - BSet active = GetBSet(ActiveWindowID); - - bool mouse_in_document = AreOverlapping(mouse, active.window->document_rect); - if (mouse_in_document) { - Int p = ScreenSpaceToBufferPosErrorOutOfBounds(active.window, active.view, active.buffer, mouse); - if (p != -1) { - Range enclose = EncloseLoadWord(active.buffer, p); - if (InBounds(active.view->carets[0].range, p)) enclose = active.view->carets[0].range; - String16 string = GetString(active.buffer, enclose); - - active.view->carets.len = 1; - active.view->carets[0] = MakeCaret(p); - Open(string, meta); - } - } -} - View *GetViewForFixingWhenBufferCommand(Buffer *buffer, bool *is_active = NULL) { View *view = NULL; if (is_active) { @@ -91,33 +59,6 @@ View *GetViewForFixingWhenBufferCommand(Buffer *buffer, bool *is_active = NULL) return view; } -void MoveCursorByPageSize(Window *window, int direction, bool shift = false) { - Assert(direction == DIR_UP || direction == DIR_DOWN); - BSet set = GetBSet(window); - - Rect2I visible_cells_rect = GetVisibleCells(window); - Int y = GetSize(visible_cells_rect).y - 2; - if (direction == DIR_UP) y = -y; - - For(set.view->carets) { - XY xy = PosToXY(set.buffer, GetFront(it)); - if (direction == DIR_DOWN && xy.line == set.buffer->line_starts.len - 1) { - Range line_range = GetLineRange(set.buffer, xy.line); - xy.col = line_range.max - line_range.min; - } else if (direction == DIR_UP && xy.line == 0) { - xy.col = 0; - } - xy.line += y; - - Int pos = XYToPos(set.buffer, xy); - if (shift) { - it = SetFront(it, pos); - } else { - it = MakeCaret(pos); - } - } -} - void ReplaceWithoutMovingCarets(Buffer *buffer, Range range, String16 string) { View *view = GetViewForFixingWhenBufferCommand(buffer); Array carets = Copy(GetSystemAllocator(), view->carets); @@ -273,38 +214,6 @@ void TrimWhitespace(Buffer *buffer, bool trim_lines_with_caret) { view->update_scroll = false; } -void ConvertLineEndingsToLF(Buffer *buffer, bool trim_lines_with_caret = false) { - Scratch scratch; - - bool is_active_view = false; - View *view = GetViewForFixingWhenBufferCommand(buffer, &is_active_view); - if (!is_active_view && !trim_lines_with_caret) { - trim_lines_with_caret = true; - } - - Array edits = BeginEdit(scratch, buffer, view->carets); - MergeCarets(buffer, &view->carets); - - Array lines_to_skip_triming = {}; - if (!trim_lines_with_caret) { - lines_to_skip_triming = GetSelectedLinesSorted(scratch, view); - } - - for (Int i = 0; i < buffer->line_starts.len; i += 1) { - Int range_index = FindRangeByPos(&lines_to_skip_triming, i); - if (range_index != -1) continue; - - Range range = GetLineRangeWithoutNL(buffer, i); - char16_t cr = GetChar(buffer, range.max - 1); - char16_t lf = GetChar(buffer, range.max); - if (cr == u'\r' && lf == u'\n') { - AddEdit(&edits, {range.max - 1, range.max}, u""); - } - } - EndEdit(buffer, &edits, &view->carets, !KILL_SELECTION); - view->update_scroll = false; -} - void ApplyFormattingTool(Buffer *buffer, String tool) { Scratch scratch; String string = AllocCharString(scratch, buffer); @@ -342,63 +251,6 @@ void CMD_FormatSelection() { EndEdit(primary.buffer, &edits, &primary.view->carets, KILL_SELECTION); } RegisterCommand(CMD_FormatSelection, ""); -void GotoNextInList(Window *window, Int line_offset = 1) { - Assert(line_offset == 1 || line_offset == -1); - View *active_view = GetView(window->active_view); - - View *view_goto = GetView(window->active_goto_list); - window->active_view = view_goto->id; - - Buffer *buffer_goto = GetBuffer(view_goto->active_buffer); - int64_t pos = window->goto_list_pos; - Int line = PosToLine(buffer_goto, pos); - - bool opened = false; - for (Int i = line + line_offset; i >= 0 && i < buffer_goto->line_starts.len; i += line_offset) { - Range line_range = GetLineRangeWithoutNL(buffer_goto, i); - String16 line = GetString(buffer_goto, line_range); - - { - Int idx = 0; - String16 delim = u"||>"; - if (Seek(line, delim, &idx, SeekFlag_None)) { - line = Skip(line, idx + delim.len); - } - } - - view_goto->carets[0] = MakeCaret(line_range.min); - window->goto_list_pos = line_range.min; - line = Trim(line); - - MergeCarets(buffer_goto, &view_goto->carets); - IF_DEBUG(AssertRanges(view_goto->carets)); - if (line.len == 0) { - continue; - } - - Buffer *active_view_buffer = GetBuffer(active_view->active_buffer); - Int p = active_view->carets[0].range.min; - Int active_view_line = PosToLine(active_view_buffer, p); - - BSet set = Open(line, ResolveOpenMeta_DontError | ResolveOpenMeta_DontExec); - if (set.window == NULL) { - continue; - } - - if (set.view == active_view) { - Int new_line = PosToLine(set.buffer, set.view->carets[0].range.min); - if (active_view_line == new_line) { - continue; - } - } - - opened = true; - break; - } - - if (!opened) window->active_view = active_view->id; -} - void New(Window *window, String name = "") { View *view = GetView(window->active_view); Buffer *buffer = GetBuffer(view->active_buffer); @@ -416,25 +268,6 @@ void New(Window *window, String name = "") { WindowOpenBufferView(window, name); } -void NewDir(Window *window, String name = "") { - View *view = GetView(window->active_view); - Buffer *buffer = GetBuffer(view->active_buffer); - - Scratch scratch; - String dir = GetDir(buffer); - if (name != "") { - if (!IsAbsolute(name)) { - name = Format(scratch, "%S/%S", dir, name); - } - name = GetAbsolutePath(scratch, name); - } else { - name = GetUniqueBufferName(dir, "new"); - } - - MakeDir(name); - Open(name); -} - void CMD_SaveAll() { For(Buffers) { // NOTE: file_mod_time is only set when buffer got read or written to disk already so should be saved @@ -444,6 +277,25 @@ void CMD_SaveAll() { } } RegisterCommand(CMD_SaveAll, "ctrl-shift-s"); +void MouseLoadWord(Event event, ResolveOpenMeta meta = ResolveOpenMeta_Normal) { + Vec2I mouse = MouseVec2I(); + BSet active = GetBSet(ActiveWindowID); + + bool mouse_in_document = AreOverlapping(mouse, active.window->document_rect); + if (mouse_in_document) { + Int p = ScreenSpaceToBufferPosErrorOutOfBounds(active.window, active.view, active.buffer, mouse); + if (p != -1) { + Range enclose = EncloseLoadWord(active.buffer, p); + if (InBounds(active.view->carets[0].range, p)) enclose = active.view->carets[0].range; + String16 string = GetString(active.buffer, enclose); + + active.view->carets.len = 1; + active.view->carets[0] = MakeCaret(p); + Open(string, meta); + } + } +} + ResolvedOpen ResolveOpen(Allocator alo, String path, ResolveOpenMeta meta) { ResolvedOpen result = {}; path = Trim(path); @@ -451,11 +303,13 @@ ResolvedOpen ResolveOpen(Allocator alo, String path, ResolveOpenMeta 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; } +#endif result.kind = OpenKind_Command; path = Skip(path, 1); @@ -555,18 +409,6 @@ ResolvedOpen ResolveOpen(Allocator alo, String path, ResolveOpenMeta meta) { result.kind = OpenKind_Goto; return result; } else { - -#if PLUGIN_PROJECT_MANAGEMENT - String workspace_path = Format(alo, "%S/%S", ProjectDirectory, path); - bool existing_buffer = GetBuffer(workspace_path, NULL); - if (existing_buffer || FileExists(workspace_path)) { - result.existing_buffer = existing_buffer; - result.path = workspace_path; - result.kind = OpenKind_Goto; - return result; - } -#endif - String rel_path = Format(alo, "%S/%S", GetMainDir(), path); existing_buffer = GetBuffer(rel_path, NULL); if (existing_buffer || FileExists(rel_path)) { @@ -621,9 +463,13 @@ BSet Open(Window *window, String path, ResolveOpenMeta meta, bool set_active = t Exec(NullViewID, false, o.path, GetMainDir()); } else if (o.kind == OpenKind_Command) { EvalCommand(o.path); - } else if (o.kind == OpenKind_Set) { + } +#if PLUGIN_CONFIG + else if (o.kind == OpenKind_Set) { Set(o.path); - } else if (o.kind == OpenKind_Skip) { + } +#endif + else if (o.kind == OpenKind_Skip) { return {}; } else { ReportErrorf("Failed to open: %S", path); @@ -644,6 +490,13 @@ BSet Open(String16 path, ResolveOpenMeta meta) { return Open(string, meta); } +void CMD_OpenLoadWord() { + Scratch scratch; + BSet active = GetBSet(ActiveWindowID); + String16 load_word = FetchLoadWord(active.view); + Open(load_word); +} RegisterCommand(CMD_OpenLoadWord, "ctrl-q | f12", "Open a link under the caret (file link, url, command) or open the selection"); + void CMD_Save() { BSet active = GetBSet(PrimaryWindowID); SaveBuffer(active.buffer); @@ -876,13 +729,6 @@ void CMD_MakeFontSmaller() { } } RegisterCommand(CMD_MakeFontSmaller, "ctrl-minus", "Decrease the font size"); -void CMD_OpenLoadWord() { - Scratch scratch; - BSet active = GetBSet(ActiveWindowID); - String16 load_word = FetchLoadWord(active.view); - Open(load_word); -} RegisterCommand(CMD_OpenLoadWord, "ctrl-q | f12", "Open a link under the caret (file link, url, command) or open the selection"); - void Coro_ReplaceAll(mco_coro *co) { BSet main = GetBSet(PrimaryWindowID); String16 string = FetchLoadWord(main.view); @@ -978,59 +824,3 @@ void CMD_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 Coro_OpenCode(mco_coro *co) { - Array patterns = SplitWhitespace(CoCurr->arena, OpenCodePatterns); - Array exclude_patterns = SplitWhitespace(CoCurr->arena, OpenCodeExcludePatterns); - Array dirs = {CoCurr->arena}; - String *param_dir = (String *)CoCurr->user_ctx; - Add(&dirs, *param_dir); - for (int diri = 0; diri < dirs.len; diri += 1) { - for (FileIter it = IterateFiles(CoCurr->arena, dirs[diri]); IsValid(it); Advance(&it)) { - bool should_open = true; - if (!it.is_directory) { - should_open = false; - ForItem (ending, patterns) { - if (EndsWith(it.absolute_path, ending)) { - should_open = true; - break; - } - } - } - - ForItem (ending, exclude_patterns) { - if (EndsWith(it.absolute_path, ending)) { - should_open = false; - break; - } - } - - if (!should_open) { - continue; - } - - - if (it.is_directory) { - Add(&dirs, it.absolute_path); - } else { - BufferOpenFile(it.absolute_path); - } - - CoYield(co); - } - } -} - -void OpenCode(String dir) { - CoRemove("Coro_OpenCode"); - CoData *data = CoAdd(Coro_OpenCode); - String *string_param = AllocType(data->arena, String); - *string_param = Copy(data->arena, dir); - data->user_ctx = string_param; - data->dont_wait_until_resolved = true; - CoResume(data); -} - -void CMD_OpenCode() { - OpenCode(ProjectDirectory); -} RegisterCommand(CMD_OpenCode, "", "Open all code files in current ProjectDirectory, the code files are determined through NonCodePatterns_EndsWith config variable list"); diff --git a/src/text_editor/config.cpp b/src/text_editor/config.cpp index fdab9b0..ec4705a 100644 --- a/src/text_editor/config.cpp +++ b/src/text_editor/config.cpp @@ -283,162 +283,3 @@ void TestParser() { Assert(!ok); } } RegisterFunction(&TestFunctions, TestParser); - -void CMD_OpenConfig() { - Buffer *buffer = GetBuffer(GlobalConfigBufferID); - Open(buffer->name); -} RegisterCommand(CMD_OpenConfig, "", "Open the global config file"); - -void CMD_OpenConfigOptions() { - BSet main = GetBSet(PrimaryWindowID); - JumpTempBuffer(&main); - NextActiveWindowID = main.window->id; - For (Variables) { - RawAppendf(main.buffer, "\n:Set %-50S ", it.name); - switch(it.type) { - case VariableType_Color: RawAppendf(main.buffer, "%x", it.color->value); break; - case VariableType_String: RawAppendf(main.buffer, "'%S'", *it.string); break; - case VariableType_Int: RawAppendf(main.buffer, "%lld", (long long)*it.i); break; - case VariableType_Float: RawAppendf(main.buffer, "%f", *it.f); break; - default: InvalidCodepath(); - } - } - For (GlobalCommands) { - RawAppendf(main.buffer, "\n:Set %-50S '%S'", it.name, it.binding); - } -} RegisterCommand(CMD_OpenConfigOptions, "", "List available variables and associated documentation inside the command window"); - -void EvalCommandsLineByLine(BSet set) { - WindowID save_last = PrimaryWindowID; - WindowID save_active = ActiveWindowID; - WindowID save_next = NextActiveWindowID; - Caret save_caret = set.view->carets[0]; - ActiveWindowID = set.window->id; - PrimaryWindowID = set.window->id; - NextActiveWindowID = set.window->id; - for (Int i = 0; i < set.buffer->line_starts.len; i += 1) { - Range range = GetLineRangeWithoutNL(set.buffer, i); - String16 string = GetString(set.buffer, range); - string = Trim(string); - if (string.len == 0) { - continue; - } - if (StartsWith(string, u"//")) { - continue; - } - Open(string); - } - set.view->carets[0] = save_caret; - PrimaryWindowID = save_last; - ActiveWindowID = save_active; - NextActiveWindowID = save_next; -} - -void CMD_EvalCommandsLineByLine() { - BSet set = GetBSet(PrimaryWindowID); - EvalCommandsLineByLine(set); -} RegisterCommand(CMD_EvalCommandsLineByLine, "", "Goes line by line over a buffer and evaluates every line as a command, ignores empty or lines starting with '//'"); - -BufferID LoadConfig(String config_path) { - ReportConsolef("Loading config %S...", config_path); - Window *window = GetWindow(NullWindowID); - View *view = WindowOpenBufferView(window, config_path); - Buffer *buffer = GetBuffer(view->active_buffer); - buffer->special = true; - EvalCommandsLineByLine({window, view, buffer}); - if (window->active_view == view->id) { - window->active_view = NullViewID; - } - return buffer->id; -} - - -#define ExpectP(x, ...) \ - if (!(x)) { \ - ReportErrorf("Failed to parse '" __FUNCTION__ "' command, " __VA_ARGS__); \ - return; \ - } - -void Set(String string) { - String name = SkipIdent(&string); - ExpectP(name.len != 0, "expected a variable name, instead got '%S'", string); - - Variable *var = NULL; - For (Variables) { - if (name == it.name) { - var = ⁢ - break; - } - } - - if (var) { - SkipWhitespace(&string); - if (var->type == VariableType_String) { - char c = At(string, 0); - ExpectP(c == u'"' || c == u'\'', "Expected string to follow the command name, instead got %S", string); - string = Skip(string, 1); - String quote = SkipUntil(&string, {&c, 1}); - ExpectP(At(string, 0) == c, ":Set %S , unclosed quote", name); - ReportConsolef(":Set %S %c%S%c", name, c, quote, c); - *var->string = Intern(&GlobalInternTable, quote); - } else if (var->type == VariableType_Int) { - ExpectP(IsDigit(At(string, 0)), "Expected an integer to follow the command name, instead got: %S", string); - Int number = SkipInt(&string); - ReportConsolef(":Set %S %lld", name, number); - *var->i = number; - } else if (var->type == VariableType_Float) { - ExpectP(IsDigit(At(string, 0)), "Expected float to follow the command name, instead got: %S", string); - Float number = SkipFloat(&string); - ReportConsolef(":Set %S %f", name, number); - *var->f = number; - } else if (var->type == VariableType_Color) { - ExpectP(IsHexDigit(At(string, 0)), "Expected hex integer to follow the command name, instead got: %S", string); - String begin = {string.data, 0}; - while (IsHexDigit(At(string, 0))) { - string = Skip(string, 1); - begin.len += 1; - } - ReportConsolef(":Set %S %S", name, begin); - var->color->value = (uint32_t)strtoll(begin.data, NULL, 16); - } ElseInvalidCodepath(); - - - if (name == "FontSize" || name == "PathToFont") { - ReloadFont(PathToFont, (U32)FontSize); - } - -#if PLUGIN_PROJECT_MANAGEMENT - if (name == "ProjectDirectory") { - SetProjectDirectory(*var->string); - } -#endif - return; - } - - Command *cmd = NULL; - For (GlobalCommands) { - if (it.name == name) { - cmd = ⁢ - break; - } - } - - if (cmd) { - SkipWhitespace(&string); - char c = At(string, 0); - ExpectP(c == u'"' || c == u'\'', "Expected string to follow the command name, instead got %S", string); - string = Skip(string, 1); - String quote = SkipUntil(&string, {&c, 1}); - ExpectP(At(string, 0) == c, "Failed to parse command, unclose quote"); - quote = Intern(&GlobalInternTable, quote); - ReportConsolef(":Set %S %c%S%c", name, c, quote, c); - Trigger *trigger = ParseKeyCached(quote); - if (trigger) { - cmd->binding = quote; - cmd->trigger = trigger; - } - return; - } - - ReportErrorf("Failed to :Set, no such variable found: %S", name); -} diff --git a/src/text_editor/globals.cpp b/src/text_editor/globals.cpp index f30c4f0..a321664 100644 --- a/src/text_editor/globals.cpp +++ b/src/text_editor/globals.cpp @@ -39,8 +39,6 @@ WindowID NullWindowID; BufferID SearchBufferID; #endif -BufferID GlobalConfigBufferID; - WindowID NextActiveWindowID; WindowID ActiveWindowID; WindowID PrimaryWindowID; diff --git a/src/text_editor/plugin_config.cpp b/src/text_editor/plugin_config.cpp new file mode 100644 index 0000000..1846e83 --- /dev/null +++ b/src/text_editor/plugin_config.cpp @@ -0,0 +1,163 @@ +#if PLUGIN_CONFIG +BufferID GlobalConfigBufferID; + +void CMD_OpenConfig() { + Buffer *buffer = GetBuffer(GlobalConfigBufferID); + Open(buffer->name); +} RegisterCommand(CMD_OpenConfig, "", "Open the global config file"); + +void CMD_OpenConfigOptions() { + BSet main = GetBSet(PrimaryWindowID); + JumpTempBuffer(&main); + NextActiveWindowID = main.window->id; + For (Variables) { + RawAppendf(main.buffer, "\n:Set %-50S ", it.name); + switch(it.type) { + case VariableType_Color: RawAppendf(main.buffer, "%x", it.color->value); break; + case VariableType_String: RawAppendf(main.buffer, "'%S'", *it.string); break; + case VariableType_Int: RawAppendf(main.buffer, "%lld", (long long)*it.i); break; + case VariableType_Float: RawAppendf(main.buffer, "%f", *it.f); break; + default: InvalidCodepath(); + } + } + For (GlobalCommands) { + RawAppendf(main.buffer, "\n:Set %-50S '%S'", it.name, it.binding); + } +} RegisterCommand(CMD_OpenConfigOptions, "", "List available variables and associated documentation inside the command window"); + +void EvalCommandsLineByLine(BSet set) { + WindowID save_last = PrimaryWindowID; + WindowID save_active = ActiveWindowID; + WindowID save_next = NextActiveWindowID; + Caret save_caret = set.view->carets[0]; + ActiveWindowID = set.window->id; + PrimaryWindowID = set.window->id; + NextActiveWindowID = set.window->id; + for (Int i = 0; i < set.buffer->line_starts.len; i += 1) { + Range range = GetLineRangeWithoutNL(set.buffer, i); + String16 string = GetString(set.buffer, range); + string = Trim(string); + if (string.len == 0) { + continue; + } + if (StartsWith(string, u"//")) { + continue; + } + Open(string); + } + set.view->carets[0] = save_caret; + PrimaryWindowID = save_last; + ActiveWindowID = save_active; + NextActiveWindowID = save_next; +} + +void CMD_EvalCommandsLineByLine() { + BSet set = GetBSet(PrimaryWindowID); + EvalCommandsLineByLine(set); +} RegisterCommand(CMD_EvalCommandsLineByLine, "", "Goes line by line over a buffer and evaluates every line as a command, ignores empty or lines starting with '//'"); + +BufferID LoadConfig(String config_path) { + ReportConsolef("Loading config %S...", config_path); + Window *window = GetWindow(NullWindowID); + View *view = WindowOpenBufferView(window, config_path); + Buffer *buffer = GetBuffer(view->active_buffer); + buffer->special = true; + EvalCommandsLineByLine({window, view, buffer}); + if (window->active_view == view->id) { + window->active_view = NullViewID; + } + return buffer->id; +} + + +#define ExpectP(x, ...) \ + if (!(x)) { \ + ReportErrorf("Failed to parse '" __FUNCTION__ "' command, " __VA_ARGS__); \ + return; \ + } + +void Set(String string) { + String name = SkipIdent(&string); + ExpectP(name.len != 0, "expected a variable name, instead got '%S'", string); + + Variable *var = NULL; + For (Variables) { + if (name == it.name) { + var = ⁢ + break; + } + } + + if (var) { + SkipWhitespace(&string); + if (var->type == VariableType_String) { + char c = At(string, 0); + ExpectP(c == u'"' || c == u'\'', "Expected string to follow the command name, instead got %S", string); + string = Skip(string, 1); + String quote = SkipUntil(&string, {&c, 1}); + ExpectP(At(string, 0) == c, ":Set %S , unclosed quote", name); + ReportConsolef(":Set %S %c%S%c", name, c, quote, c); + *var->string = Intern(&GlobalInternTable, quote); + } else if (var->type == VariableType_Int) { + ExpectP(IsDigit(At(string, 0)), "Expected an integer to follow the command name, instead got: %S", string); + Int number = SkipInt(&string); + ReportConsolef(":Set %S %lld", name, number); + *var->i = number; + } else if (var->type == VariableType_Float) { + ExpectP(IsDigit(At(string, 0)), "Expected float to follow the command name, instead got: %S", string); + Float number = SkipFloat(&string); + ReportConsolef(":Set %S %f", name, number); + *var->f = number; + } else if (var->type == VariableType_Color) { + ExpectP(IsHexDigit(At(string, 0)), "Expected hex integer to follow the command name, instead got: %S", string); + String begin = {string.data, 0}; + while (IsHexDigit(At(string, 0))) { + string = Skip(string, 1); + begin.len += 1; + } + ReportConsolef(":Set %S %S", name, begin); + var->color->value = (uint32_t)strtoll(begin.data, NULL, 16); + } ElseInvalidCodepath(); + + + if (name == "FontSize" || name == "PathToFont") { + ReloadFont(PathToFont, (U32)FontSize); + } + +#if PLUGIN_PROJECT_MANAGEMENT + if (name == "ProjectDirectory") { + SetProjectDirectory(*var->string); + } +#endif + return; + } + + Command *cmd = NULL; + For (GlobalCommands) { + if (it.name == name) { + cmd = ⁢ + break; + } + } + + if (cmd) { + SkipWhitespace(&string); + char c = At(string, 0); + ExpectP(c == u'"' || c == u'\'', "Expected string to follow the command name, instead got %S", string); + string = Skip(string, 1); + String quote = SkipUntil(&string, {&c, 1}); + ExpectP(At(string, 0) == c, "Failed to parse command, unclose quote"); + quote = Intern(&GlobalInternTable, quote); + ReportConsolef(":Set %S %c%S%c", name, c, quote, c); + Trigger *trigger = ParseKeyCached(quote); + if (trigger) { + cmd->binding = quote; + cmd->trigger = trigger; + } + return; + } + + ReportErrorf("Failed to :Set, no such variable found: %S", name); +} + +#endif \ No newline at end of file diff --git a/src/text_editor/plugin_config.h b/src/text_editor/plugin_config.h new file mode 100644 index 0000000..3f89921 --- /dev/null +++ b/src/text_editor/plugin_config.h @@ -0,0 +1,3 @@ +#if PLUGIN_CONFIG +void Set(String string); +#endif \ No newline at end of file diff --git a/src/text_editor/plugin_project_management.cpp b/src/text_editor/plugin_project_management.cpp index 9d0507c..8cfd6bc 100644 --- a/src/text_editor/plugin_project_management.cpp +++ b/src/text_editor/plugin_project_management.cpp @@ -13,3 +13,59 @@ void CMD_SetProjectDirectoryHere() { BSet main = GetBSet(PrimaryWindowID); SetProjectDirectory(GetDir(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) { + Array patterns = SplitWhitespace(CoCurr->arena, OpenCodePatterns); + Array exclude_patterns = SplitWhitespace(CoCurr->arena, OpenCodeExcludePatterns); + Array dirs = {CoCurr->arena}; + String *param_dir = (String *)CoCurr->user_ctx; + Add(&dirs, *param_dir); + for (int diri = 0; diri < dirs.len; diri += 1) { + for (FileIter it = IterateFiles(CoCurr->arena, dirs[diri]); IsValid(it); Advance(&it)) { + bool should_open = true; + if (!it.is_directory) { + should_open = false; + ForItem (ending, patterns) { + if (EndsWith(it.absolute_path, ending)) { + should_open = true; + break; + } + } + } + + ForItem (ending, exclude_patterns) { + if (EndsWith(it.absolute_path, ending)) { + should_open = false; + break; + } + } + + if (!should_open) { + continue; + } + + + if (it.is_directory) { + Add(&dirs, it.absolute_path); + } else { + BufferOpenFile(it.absolute_path); + } + + CoYield(co); + } + } +} + +void OpenCode(String dir) { + CoRemove("Coro_OpenCode"); + CoData *data = CoAdd(Coro_OpenCode); + String *string_param = AllocType(data->arena, String); + *string_param = Copy(data->arena, dir); + data->user_ctx = string_param; + data->dont_wait_until_resolved = true; + CoResume(data); +} + +void CMD_OpenCode() { + OpenCode(ProjectDirectory); +} RegisterCommand(CMD_OpenCode, "", "Open all code files in current ProjectDirectory, the code files are determined through NonCodePatterns_EndsWith config variable list"); diff --git a/src/text_editor/plugin_remedybg.cpp b/src/text_editor/plugin_remedybg.cpp index 5726c7b..8baf42d 100644 --- a/src/text_editor/plugin_remedybg.cpp +++ b/src/text_editor/plugin_remedybg.cpp @@ -1,3 +1,4 @@ +#if PLUGIN_REMEDYBG #define RDBG_MAX_SERVERNAME_LEN 64 typedef uint8_t rdbg_Bool; @@ -2252,3 +2253,5 @@ void QuitDebugger() { ExitDebugger(&RDBG_Ctx, &res); CloseConnection(&RDBG_Ctx); } + +#endif \ No newline at end of file diff --git a/src/text_editor/text_editor.cpp b/src/text_editor/text_editor.cpp index ec26df7..261867b 100644 --- a/src/text_editor/text_editor.cpp +++ b/src/text_editor/text_editor.cpp @@ -15,7 +15,7 @@ #include "render/font.cpp" #include "render/opengl.cpp" -#define PLUGIN_REMEDYBG 1 +#define PLUGIN_CONFIG 1 #define PLUGIN_SEARCH_WINDOW 1 #define PLUGIN_PROJECT_MANAGEMENT 1 #define PLUGIN_WINDOW_MANAGEMENT 1 @@ -30,12 +30,14 @@ #define PLUGIN_DEBUG_WINDOW 1 #define PLUGIN_RECORD_GC 1 #define PLUGIN_RECORD_EVENTS 1 -#define PLUGIN_LOAD_VCVARS OS_WINDOWS #define PLUGIN_DIRECTORY_NAVIGATION 1 +#define PLUGIN_LOAD_VCVARS OS_WINDOWS +#define PLUGIN_REMEDYBG OS_WINDOWS #include "plugin_directory_navigation.h" #include "plugin_search_window.h" #include "plugin_project_management.h" +#include "plugin_config.h" #include "text_editor.h" #include "globals.cpp" #include "coroutines.cpp" @@ -51,6 +53,7 @@ #include "scratch.cpp" #include "draw.cpp" #include "test/tests.cpp" +#include "plugin_config.cpp" #include "plugin_window_management.cpp" #include "plugin_directory_navigation.cpp" #include "plugin_search_open_buffers.cpp" @@ -979,15 +982,21 @@ int main(int argc, char **argv) } } - Scratch scratch; - GlobalConfigBufferID = LoadConfig(Format(scratch, "%S/config.te", ConfigDir)); +#if PLUGIN_CONFIG + { + Scratch scratch; + GlobalConfigBufferID = LoadConfig(Format(scratch, "%S/config.te", ConfigDir)); + } +#endif for (int i = 1; i < argc; i += 1) { String it = argv[i]; + +#if PLUGIN_CONFIG if (EndsWith(it, ".te")) { LoadConfig(it); - } else { - Open(argv[i]); } +#endif + Open(argv[i]); } if (Testing) InitTests(); diff --git a/src/text_editor/text_editor.h b/src/text_editor/text_editor.h index 5708889..6a76971 100644 --- a/src/text_editor/text_editor.h +++ b/src/text_editor/text_editor.h @@ -245,7 +245,9 @@ enum OpenKind { OpenKind_BackgroundExec, OpenKind_Goto, OpenKind_Command, +#if PLUGIN_CONFIG OpenKind_Set, +#endif }; typedef uint32_t ResolveOpenMeta; diff --git a/src/text_editor/window.cpp b/src/text_editor/window.cpp index 6dbb4cc..ebeab0d 100644 --- a/src/text_editor/window.cpp +++ b/src/text_editor/window.cpp @@ -260,6 +260,63 @@ void JumpForward(Window *window) { } } +void GotoNextInList(Window *window, Int line_offset = 1) { + Assert(line_offset == 1 || line_offset == -1); + View *active_view = GetView(window->active_view); + + View *view_goto = GetView(window->active_goto_list); + window->active_view = view_goto->id; + + Buffer *buffer_goto = GetBuffer(view_goto->active_buffer); + int64_t pos = window->goto_list_pos; + Int line = PosToLine(buffer_goto, pos); + + bool opened = false; + for (Int i = line + line_offset; i >= 0 && i < buffer_goto->line_starts.len; i += line_offset) { + Range line_range = GetLineRangeWithoutNL(buffer_goto, i); + String16 line = GetString(buffer_goto, line_range); + + { + Int idx = 0; + String16 delim = u"||>"; + if (Seek(line, delim, &idx, SeekFlag_None)) { + line = Skip(line, idx + delim.len); + } + } + + view_goto->carets[0] = MakeCaret(line_range.min); + window->goto_list_pos = line_range.min; + line = Trim(line); + + MergeCarets(buffer_goto, &view_goto->carets); + IF_DEBUG(AssertRanges(view_goto->carets)); + if (line.len == 0) { + continue; + } + + Buffer *active_view_buffer = GetBuffer(active_view->active_buffer); + Int p = active_view->carets[0].range.min; + Int active_view_line = PosToLine(active_view_buffer, p); + + BSet set = Open(line, ResolveOpenMeta_DontError | ResolveOpenMeta_DontExec); + if (set.window == NULL) { + continue; + } + + if (set.view == active_view) { + Int new_line = PosToLine(set.buffer, set.view->carets[0].range.min); + if (active_view_line == new_line) { + continue; + } + } + + opened = true; + break; + } + + if (!opened) window->active_view = active_view->id; +} + void UpdateScroll(Window *window, bool update_caret_scrolling) { ProfileFunction(); BSet set = GetBSet(window); @@ -320,3 +377,44 @@ void CenterView(WindowID window) { set.view->scroll.y = (xy.line) * set.window->font->line_spacing - (size.y / 2); } } + +BSet GetBSet(Window *window) { + BSet set = {window}; + set.view = GetView(set.window->active_view); + set.buffer = GetBuffer(set.view->active_buffer); + return set; +} + +BSet GetBSet(WindowID window_id) { + Window *window = GetWindow(window_id); + BSet result = GetBSet(window); + return result; +} + + +void MoveCursorByPageSize(Window *window, int direction, bool shift = false) { + Assert(direction == DIR_UP || direction == DIR_DOWN); + BSet set = GetBSet(window); + + Rect2I visible_cells_rect = GetVisibleCells(window); + Int y = GetSize(visible_cells_rect).y - 2; + if (direction == DIR_UP) y = -y; + + For(set.view->carets) { + XY xy = PosToXY(set.buffer, GetFront(it)); + if (direction == DIR_DOWN && xy.line == set.buffer->line_starts.len - 1) { + Range line_range = GetLineRange(set.buffer, xy.line); + xy.col = line_range.max - line_range.min; + } else if (direction == DIR_UP && xy.line == 0) { + xy.col = 0; + } + xy.line += y; + + Int pos = XYToPos(set.buffer, xy); + if (shift) { + it = SetFront(it, pos); + } else { + it = MakeCaret(pos); + } + } +}