From a00f8acd9a6171beea7fe4051fa49121c7199976 Mon Sep 17 00:00:00 2001 From: krzosa Date: Wed, 30 Apr 2025 09:34:54 +0200 Subject: [PATCH] Get info for lua commands on buffer, ctrl shift Q thing, packaging --- .gitignore | 21 ++++++----- build_file.cpp | 10 ++++- src/basic/string16.cpp | 30 ++++----------- src/text_editor/commands.cpp | 10 ++++- src/text_editor/commands_bindings.cpp | 54 +++++++++++++-------------- src/text_editor/generated.cpp | 4 +- src/text_editor/lua_api.cpp | 34 ++++++++++++++++- src/text_editor/lua_api_generated.cpp | 4 ++ src/text_editor/management.cpp | 1 + src/text_editor/todo.txt | 6 +-- src/text_editor/window.cpp | 2 +- 11 files changed, 108 insertions(+), 68 deletions(-) diff --git a/.gitignore b/.gitignore index 4adc1e7..5b64b26 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,12 @@ -x64/Debug -x64/Release -.vs/ - -src/external/SDL/ -build/ -*.rdbg -*.spall -*.sublime-workspace \ No newline at end of file +x64/Debug +x64/Release +.vs/ + +src/external/SDL/ +build/ +package/ +*.rdbg +*.spall +*.sublime-workspace +te.exe +te.pdb \ No newline at end of file diff --git a/build_file.cpp b/build_file.cpp index 0071dfa..8281178 100644 --- a/build_file.cpp +++ b/build_file.cpp @@ -165,6 +165,12 @@ int CompileTextEditor() { Run("rc icon.rc"); } result += Run(cmd); + if (result == 0) { + OS_MakeDir("../package"); + OS_CopyFile("../build/te.exe", "../package/te.exe", true); + OS_CopyFile("../build/te.pdb", "../package/te.pdb", true); + } + return result; } @@ -422,7 +428,9 @@ function IsLoadWord(w) w == string.byte('_') or w == string.byte('.') or w == string.byte('-') or - w == string.byte(',') + w == string.byte(',') or + w == string.byte('"') or + w == string.byte("'") if not result then result = not (IsSymbol(w) or IsWhitespace(w)) end diff --git a/src/basic/string16.cpp b/src/basic/string16.cpp index 3a288a7..2bac1dc 100644 --- a/src/basic/string16.cpp +++ b/src/basic/string16.cpp @@ -136,6 +136,13 @@ bool Seek(String16 string, String16 find, int64_t *index_out = NULL, SeekFlag fl return result; } +String16 CutLastSlash(String16 *s) { + String16 result = *s; + Seek(*s, u"/", &s->len, SeekFlag_MatchFindLast); + result = Skip(result, s->len); + return result; +} + String16 ChopLastSlash(String16 s) { String16 result = s; Seek(s, u"/", &result.len, SeekFlag_MatchFindLast); @@ -297,26 +304,3 @@ String16 SkipWhitespace(String16 *string) { } return begin; } - -String16 Format16V(Allocator allocator, const char16_t *data, va_list args1) { - va_list args2; - va_copy(args2, args1); - int64_t len = vswprintf(0, 0, (wchar_t *)data, args2); // @todo: check this type - va_end(args2); - - char16_t *result = (char16_t *)AllocSize(allocator, sizeof(char16_t) * (len + 1)); - vswprintf((wchar_t *)result, (int)(len + 1), (wchar_t *)data, args1); // @todo: check this type - String16 res = {result, len}; - return res; -} - -#define STRING16_FORMAT(allocator, data, result) \ - va_list args1; \ - va_start(args1, data); \ - String16 result = Format16V(allocator, data, args1); \ - va_end(args1) - -String16 Format16(Allocator allocator, const char16_t *data, ...) { - STRING16_FORMAT(allocator, data, result); - return result; -} \ No newline at end of file diff --git a/src/text_editor/commands.cpp b/src/text_editor/commands.cpp index bab04e6..a941c74 100644 --- a/src/text_editor/commands.cpp +++ b/src/text_editor/commands.cpp @@ -99,7 +99,7 @@ void Command_ListBuffers() { Command_SelectRangeOneCursor(new_view, {}); } -void MouseLoadWord(Event event) { +void MouseLoadWord(Event event, bool cut_path) { Vec2I mouse = MouseVec2I(); BSet active = GetActiveSet(); @@ -110,6 +110,14 @@ void MouseLoadWord(Event event) { 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); + Scratch scratch; + if (cut_path) { + string = NormalizePath(scratch, string); + String16 right_part = CutLastSlash(&string); + if (right_part.len > 1 && right_part.data[1] == u'+') { + CutLastSlash(&string); + } + } active.view->carets.len = 1; active.view->carets[0] = MakeCaret(p); diff --git a/src/text_editor/commands_bindings.cpp b/src/text_editor/commands_bindings.cpp index dd7cbf8..0f6e6ba 100644 --- a/src/text_editor/commands_bindings.cpp +++ b/src/text_editor/commands_bindings.cpp @@ -175,13 +175,11 @@ void OnCommand(Event event) { } } - // @todo: maybe move some of this stuff to window command ??? - // for now let's leave it because we are relaying on global state - // - maybe just do the check if active window is matching the DocumentSelected window - // - if scrollbar selected then don't invoke window command - if (Ctrl() && Mouse(LEFT)) { - MouseLoadWord(event); - } else if (Mouse(LEFT)) { // CTRL SHIFT + if (Shift() && Ctrl() && Mouse(LEFT)) { + MouseLoadWord(event, true); + } else if (Ctrl() && Mouse(LEFT)) { + MouseLoadWord(event, false); + } else if (Mouse(LEFT)) { // Uses Alt and shift Vec2I mouse = MouseVec2I(); { Assert(ScrollbarSelected.id == -1); @@ -282,6 +280,7 @@ void OnCommand(Event event) { if (window) ActiveWindow = window->id; } + BSet main = GetActiveMainSet(); BSet active = GetActiveSet(); Int buffer_change_id = active.buffer->change_id; @@ -392,11 +391,11 @@ void OnCommand(Event event) { } if (CtrlShiftPress(SDLK_TAB)) { - GotoForward(GetActiveMainSet().window); + GotoForward(main.window); } else if (ShiftPress(SDLK_TAB)) { Command_IndentSelectedLines(active.view, SHIFT_PRESSED); } else if (CtrlPress(SDLK_TAB)) { - GotoBackward(GetActiveMainSet().window); + GotoBackward(main.window); } else if (Press(SDLK_TAB)) { Command_IndentSelectedLines(active.view); } @@ -433,13 +432,11 @@ void OnCommand(Event event) { if (ShiftPress(SDLK_F3)) { Scratch scratch; - BSet main = GetActiveMainSet(); String16 search_string = GetSearchString(main.window); Caret caret = FindPrev(main.buffer, search_string, main.view->carets[0]); Command_SelectRangeOneCursor(main.view, caret); } else if (Press(SDLK_F3)) { Scratch scratch; - BSet main = GetActiveMainSet(); String16 search_string = GetSearchString(main.window); Caret caret = FindNext(main.buffer, search_string, main.view->carets[0]); Command_SelectRangeOneCursor(main.view, caret); @@ -464,7 +461,6 @@ void OnCommand(Event event) { if (CtrlPress(SDLK_F)) { if (!active.window->is_search_bar) { - BSet main = GetActiveMainSet(); BSet search = GetBSet(main.window->search_bar_window); String16 string = GetString(main.buffer, main.view->carets[0].range); if (string.len) { @@ -482,9 +478,7 @@ void OnCommand(Event event) { } if (CtrlPress(SDLK_PERIOD)) { - BSet main = GetActiveMainSet(); - String name = ChopLastSlash(main.buffer->name); - Open(name); + Open(ChopLastSlash(main.buffer->name)); } if (CtrlPress(SDLK_T)) { @@ -496,13 +490,19 @@ void OnCommand(Event event) { } - // if (CtrlShiftPress(SDLK_W)) { - // GotoForward(GetActiveMainSet().window); - // } else if (CtrlPress(SDLK_W)) { - // GotoBackward(GetActiveMainSet().window); - // } + if (CtrlShiftPress(SDLK_Q)) { + Scratch scratch; + Caret caret = active.view->carets[0]; + Range range = caret.range; + if (GetSize(caret.range) == 0) range = EncloseLoadWord(active.buffer, GetFront(caret)); + String16 string = NormalizePath(scratch, GetString(active.buffer, range)); + String16 right_part = CutLastSlash(&string); + if (right_part.len > 1 && right_part.data[1] == u'+') { + CutLastSlash(&string); + } - if (CtrlPress(SDLK_Q)) { + Open(string); + } else if (CtrlPress(SDLK_Q)) { Caret caret = active.view->carets[0]; Range range = caret.range; if (GetSize(caret.range) == 0) range = EncloseLoadWord(active.buffer, GetFront(caret)); @@ -513,21 +513,21 @@ void OnCommand(Event event) { if (Press(SDLK_ESCAPE)) { if (active.window->is_search_bar) { - ActiveWindow = GetActiveMainSet().window->id; + ActiveWindow = main.window->id; active.window->visible = 0; } else if (active.window->deactivate_on_escape) { - ActiveWindow = GetActiveMainSet().window->id; + ActiveWindow = main.window->id; } else { active.view->carets.len = 1; active.view->carets[0] = MakeCaret(GetFront(active.view->carets[0])); } } + if (active.window->is_title_bar && buffer_change_id != active.buffer->change_id) { + } + if (active.window->is_search_bar && buffer_change_id != active.buffer->change_id) { - BSet main = GetActiveMainSet(); - String16 search_string = GetSearchString(main.window); - Caret caret = FindNext(main.buffer, search_string, main.view->carets[0]); - Command_SelectRangeOneCursor(main.view, caret); + Command_Find(main.view, GetSearchString(main.window), true); } MergeCarets(active.buffer, &active.view->carets); diff --git a/src/text_editor/generated.cpp b/src/text_editor/generated.cpp index 7789237..7583af4 100644 --- a/src/text_editor/generated.cpp +++ b/src/text_editor/generated.cpp @@ -312,7 +312,9 @@ function IsLoadWord(w) w == string.byte('_') or w == string.byte('.') or w == string.byte('-') or - w == string.byte(',') + w == string.byte(',') or + w == string.byte('"') or + w == string.byte("'") if not result then result = not (IsSymbol(w) or IsWhitespace(w)) end diff --git a/src/text_editor/lua_api.cpp b/src/text_editor/lua_api.cpp index 5d2d8e1..27d13cd 100644 --- a/src/text_editor/lua_api.cpp +++ b/src/text_editor/lua_api.cpp @@ -195,7 +195,7 @@ int Lua_Open(lua_State *L) { int Lua_SetProjectFile(lua_State *L) { String name = luaL_checkstring(L, 1); lua_pop(L, 1); - LuaProjectBuffer = BufferOpenFile(name); + LuaProjectBuffer = BufferOpenFile(name); LuaProjectBuffer->user_change_id = -1; return 0; } @@ -296,6 +296,38 @@ int Lua_Rename(lua_State *L) { return 0; } +int Lua_GetSelection(lua_State *L) { + Scratch scratch; + BSet main = GetActiveMainSet(); + String16 string16 = GetString(main.buffer, main.view->carets[0].range); + String string = ToString(scratch, string16); + lua_pushlstring(L, string.data, string.len); + return 1; +} + +int Lua_GetEntireBuffer(lua_State *L) { + Scratch scratch; + BSet main = GetActiveMainSet(); + String16 string16 = GetString(main.buffer); + String string = ToString(scratch, string16); + lua_pushlstring(L, string.data, string.len); + return 1; +} + +int Lua_GetClipboard(lua_State *L) { + Scratch scratch; + BSet main = GetActiveMainSet(); + String string = ToString(scratch, SavedClipboardString); + lua_pushlstring(L, string.data, string.len); + return 1; +} + +int Lua_GetFilename(lua_State *L) { + BSet main = GetActiveMainSet(); + lua_pushlstring(L, main.buffer->name.data, main.buffer->name.len); + return 1; +} + static void HookLuaForceExit(lua_State *L, lua_Debug *debug) { SDL_PumpEvents(); int numkeys = 0; diff --git a/src/text_editor/lua_api_generated.cpp b/src/text_editor/lua_api_generated.cpp index 89f3c9b..50956fb 100644 --- a/src/text_editor/lua_api_generated.cpp +++ b/src/text_editor/lua_api_generated.cpp @@ -19,6 +19,10 @@ luaL_Reg LuaFunctions[] = { {"GetActiveMainWindowBufferDir", Lua_GetActiveMainWindowBufferDir}, {"Ls", Lua_Ls}, {"Rename", Lua_Rename}, + {"GetSelection", Lua_GetSelection}, + {"GetEntireBuffer", Lua_GetEntireBuffer}, + {"GetClipboard", Lua_GetClipboard}, + {"GetFilename", Lua_GetFilename}, {"Play", Lua_Play}, {NULL, NULL}, }; diff --git a/src/text_editor/management.cpp b/src/text_editor/management.cpp index 19a8c4b..8da4823 100644 --- a/src/text_editor/management.cpp +++ b/src/text_editor/management.cpp @@ -333,6 +333,7 @@ Buffer *BufferOpenFile(String path) { String buffer_name = GetUniqueBufferName(scratch, path, "+dir-"); buffer = CreateBuffer(sys_allocator, buffer_name, 4096 * 2); + RawAppendf(buffer, "..\n"); for (FileIter it = IterateFiles(scratch, path); IsValid(it); Advance(&it)) { RawAppendf(buffer, "%.*s\n", FmtString(it.filename)); } diff --git a/src/text_editor/todo.txt b/src/text_editor/todo.txt index a0f50cd..928b2fa 100644 --- a/src/text_editor/todo.txt +++ b/src/text_editor/todo.txt @@ -1,4 +1,4 @@ -- maybe we could allow user to change window titles which would make them special in some way. +- maybe we could allow user to change window titles which would make them special in some way. A:/text_editor/+test_buffer:1:1:ADE | - dump text editor state to file, restore state - help menu popup when for example in process buffer, on tile bar buffer and stuff like that @@ -7,10 +7,8 @@ - proper lister - adding items to directory should create files on save - it should ask the user (syntax: dir/ | file) -- ask user if he really wants to quit even though he has an unsaved buffer - popup window -- test the code editor: try writing in it, try browsing in it, create test tooling +- ask user if he really wants to quit even though he has an unsaved buffer - popup window | we could just show ForceClose() in the titlebar - Find matches using grep, change things in that buffer then apply those changes to all items - - need a way to pipe the buffer content as input into command, then it would be easy - group history entries so the you can rollback through multiple ones at once and not waste time on skipping whitespace trimming or deleting every character diff --git a/src/text_editor/window.cpp b/src/text_editor/window.cpp index a851b83..4341534 100644 --- a/src/text_editor/window.cpp +++ b/src/text_editor/window.cpp @@ -217,7 +217,7 @@ void InitWindows() { Window *window = CreateWindow(); WindowID window_id = window->id; window->is_column = true; - Buffer *buffer = CreateBuffer(sys_allocator, BuffCWD("+test_buffer")); + Buffer *buffer = CreateBuffer(sys_allocator, BuffCWD("test_buffer")); View *view = CreateView(buffer->id); LoadTestBufferMessage(buffer); window->active_view = view->id;