From dc3861adfef9468d74b033439ddbb6f82fb3450d Mon Sep 17 00:00:00 2001 From: krzosa Date: Wed, 30 Apr 2025 21:38:21 +0200 Subject: [PATCH] Lua_GetProjectPath, SDLK_Period --- build_file.cpp | 38 ---------------------- data/te.lua_project | 6 ---- src/basic/basic.h | 8 +++++ src/text_editor/buffer.cpp | 19 +++++------ src/text_editor/commands.cpp | 9 +++-- src/text_editor/commands_bindings.cpp | 7 +++- src/text_editor/generated.cpp | 38 ---------------------- src/text_editor/lua_api.cpp | 10 ++++++ src/text_editor/lua_api_generated.cpp | 1 + src/text_editor/text_editor.cpp | 1 + src/text_editor/todo.txt | 21 ++++++------ te.lua_project | 47 +++++++++++++++++++++++++++ 12 files changed, 96 insertions(+), 109 deletions(-) delete mode 100644 data/te.lua_project create mode 100644 te.lua_project diff --git a/build_file.cpp b/build_file.cpp index 8281178..10b66d0 100644 --- a/build_file.cpp +++ b/build_file.cpp @@ -401,42 +401,6 @@ function ApplyRules(s) return nil end -function IsWhitespace(w) - local result = w == string.byte('\n') or - w == string.byte(' ') or - w == string.byte('\t') or - w == string.byte('\v') or - w == string.byte('\r') - return result -end - -function IsSymbol(w) - local result = (w >= string.byte('!') and w <= string.byte('/')) or - (w >= string.byte(':') and w <= string.byte('@')) or - (w >= string.byte('[') and w <= string.byte('`')) or - (w >= string.byte('{') and w <= string.byte('~')) - return result -end - -function IsLoadWord(w) - local result = w == string.byte('(') or - w == string.byte(')') or - w == string.byte('/') or - w == string.byte('\\') or - w == string.byte(':') or - w == string.byte('+') or - w == string.byte('_') or - w == string.byte('.') or - w == string.byte('-') or - w == string.byte(',') or - w == string.byte('"') or - w == string.byte("'") - if not result then - result = not (IsSymbol(w) or IsWhitespace(w)) - end - return result -end - Coroutines = {} function AddCo(f) local i = #Coroutines + 1 @@ -463,8 +427,6 @@ table.insert(OnCommandCallbacks, function (e) C("git grep -n "..GetLoadWord().." :/") end if e.key == SDLK_L and e.ctrl == 1 then Eval(GetLoadWord()) end - if e.key == SDLK_B and e.ctrl == 1 then - C(GetLoadWord()) end end) -- REMEBER: AS LITTLE ACTUAL CODE AS POSSIBLE IN LUA diff --git a/data/te.lua_project b/data/te.lua_project deleted file mode 100644 index f2eb37b..0000000 --- a/data/te.lua_project +++ /dev/null @@ -1,6 +0,0 @@ -function OnCommandTE(e) - if e.key == SDLK_B and e.ctrl == 1 then - C("cd D:/dev/text_editor && build.bat") end -end - -table.insert(OnCommandCallbacks, OnCommandTE) \ No newline at end of file diff --git a/src/basic/basic.h b/src/basic/basic.h index 9a7c5fb..6b6344c 100644 --- a/src/basic/basic.h +++ b/src/basic/basic.h @@ -810,6 +810,7 @@ String ToString(Allocator allocator, char16_t *wstring); String16 ToString16(Allocator allocator, String string); char16_t *ToWidechar(Allocator allocator, String string); void NormalizePathInPlace(String s); +String CutLastSlash(String *s); String ChopLastSlash(String s); String ChopLastPeriod(String s); String SkipToLastSlash(String s); @@ -1480,6 +1481,13 @@ Array Split(Allocator allocator, String string, String delimiter) { return result; } +String CutLastSlash(String *s) { + String result = *s; + Seek(*s, "/", &s->len, SeekFlag_MatchFindLast); + result = Skip(result, s->len); + return result; +} + String ChopLastSlash(String s) { String result = s; Seek(s, "/", &result.len, SeekFlag_MatchFindLast); diff --git a/src/text_editor/buffer.cpp b/src/text_editor/buffer.cpp index 1847c9f..4d175d2 100644 --- a/src/text_editor/buffer.cpp +++ b/src/text_editor/buffer.cpp @@ -290,19 +290,18 @@ Int GetWordEnd(Buffer *buffer, Int pos) { return pos; } -bool CallIsLoadWord(char16_t w); -// bool IsLoadWord(char16_t w) { -// bool result = w == u'(' || w == u')' || w == u'/' || w == u'\\' || w == u':' || w == u'+' || w == u'_' || w == u'.' || w == u'-' || w == u','; -// if (!result) { -// result = !(IsSymbol(w) || IsWhitespace(w)); -// } -// return result; -// } +bool IsLoadWord(char16_t w) { + bool result = w == u'(' || w == u')' || w == u'/' || w == u'\\' || w == u':' || w == u'+' || w == u'_' || w == u'.' || w == u'-' || w == u','; + if (!result) { + result = !(IsSymbol(w) || IsWhitespace(w)); + } + return result; +} Int GetLoadWordStart(Buffer *buffer, Int pos) { pos = Clamp(pos, (Int)0, buffer->len); for (Int i = pos - 1; i >= 0; i -= 1) { - if (!CallIsLoadWord(buffer->str[i])) break; + if (!IsLoadWord(buffer->str[i])) break; pos = i; } return pos; @@ -316,7 +315,7 @@ Int GetLoadWordEnd(Buffer *buffer, Int pos) { // too early and we cannot establish the proper range // semantics - proper max is one past last index if (!(i < buffer->len)) break; - if (!CallIsLoadWord(buffer->str[i])) break; + if (!IsLoadWord(buffer->str[i])) break; } return pos; } diff --git a/src/text_editor/commands.cpp b/src/text_editor/commands.cpp index a941c74..2364425 100644 --- a/src/text_editor/commands.cpp +++ b/src/text_editor/commands.cpp @@ -17,10 +17,8 @@ void ToggleFullscreen() { void CheckpointBeforeGoto(Window *window, View *view) { Buffer *buffer = GetBuffer(view->active_buffer); - // if (buffer->gc == false) { - Add(&window->goto_history, {buffer->id, view->carets[0]}); - window->goto_redo.len = 0; - // } + Add(&window->goto_history, {buffer->id, view->carets[0]}); + window->goto_redo.len = 0; } void CheckpointBeforeGoto(Window *window) { @@ -83,7 +81,8 @@ void Command_ListBuffers() { Scratch scratch; Array strings = {scratch}; For(Buffers) { - String string = Format(scratch, "%.*s id=%d", FmtString(it.o->name), (int)it.id); + Buffer *buffer = GetBuffer(it); + String string = Format(scratch, "%.*s", FmtString(buffer->name)); Add(&strings, string); } String result = Merge(scratch, strings, "\n"); diff --git a/src/text_editor/commands_bindings.cpp b/src/text_editor/commands_bindings.cpp index 0f6e6ba..85edd74 100644 --- a/src/text_editor/commands_bindings.cpp +++ b/src/text_editor/commands_bindings.cpp @@ -478,7 +478,12 @@ void OnCommand(Event event) { } if (CtrlPress(SDLK_PERIOD)) { - Open(ChopLastSlash(main.buffer->name)); + String string = main.buffer->name; + String right_part = CutLastSlash(&string); + if (StartsWith(right_part, "/+")) { + CutLastSlash(&string); + } + Open(string); } if (CtrlPress(SDLK_T)) { diff --git a/src/text_editor/generated.cpp b/src/text_editor/generated.cpp index 7583af4..83cf8c9 100644 --- a/src/text_editor/generated.cpp +++ b/src/text_editor/generated.cpp @@ -285,42 +285,6 @@ function ApplyRules(s) return nil end -function IsWhitespace(w) - local result = w == string.byte('\n') or - w == string.byte(' ') or - w == string.byte('\t') or - w == string.byte('\v') or - w == string.byte('\r') - return result -end - -function IsSymbol(w) - local result = (w >= string.byte('!') and w <= string.byte('/')) or - (w >= string.byte(':') and w <= string.byte('@')) or - (w >= string.byte('[') and w <= string.byte('`')) or - (w >= string.byte('{') and w <= string.byte('~')) - return result -end - -function IsLoadWord(w) - local result = w == string.byte('(') or - w == string.byte(')') or - w == string.byte('/') or - w == string.byte('\\') or - w == string.byte(':') or - w == string.byte('+') or - w == string.byte('_') or - w == string.byte('.') or - w == string.byte('-') or - w == string.byte(',') or - w == string.byte('"') or - w == string.byte("'") - if not result then - result = not (IsSymbol(w) or IsWhitespace(w)) - end - return result -end - Coroutines = {} function AddCo(f) local i = #Coroutines + 1 @@ -347,8 +311,6 @@ table.insert(OnCommandCallbacks, function (e) C("git grep -n "..GetLoadWord().." :/") end if e.key == SDLK_L and e.ctrl == 1 then Eval(GetLoadWord()) end - if e.key == SDLK_B and e.ctrl == 1 then - C(GetLoadWord()) end end) -- REMEBER: AS LITTLE ACTUAL CODE AS POSSIBLE IN LUA diff --git a/src/text_editor/lua_api.cpp b/src/text_editor/lua_api.cpp index 27d13cd..842bc47 100644 --- a/src/text_editor/lua_api.cpp +++ b/src/text_editor/lua_api.cpp @@ -328,6 +328,16 @@ int Lua_GetFilename(lua_State *L) { return 1; } +int Lua_GetProjectPath(lua_State *L) { + if (LuaProjectBuffer) { + String path = ChopLastSlash(LuaProjectBuffer->name); + lua_pushlstring(L, path.data, path.len); + } else { + lua_pushlstring(L, "no config", 9); + } + 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 50956fb..401c54f 100644 --- a/src/text_editor/lua_api_generated.cpp +++ b/src/text_editor/lua_api_generated.cpp @@ -23,6 +23,7 @@ luaL_Reg LuaFunctions[] = { {"GetEntireBuffer", Lua_GetEntireBuffer}, {"GetClipboard", Lua_GetClipboard}, {"GetFilename", Lua_GetFilename}, + {"GetProjectPath", Lua_GetProjectPath}, {"Play", Lua_Play}, {NULL, NULL}, }; diff --git a/src/text_editor/text_editor.cpp b/src/text_editor/text_editor.cpp index 69e5684..c5127ee 100644 --- a/src/text_editor/text_editor.cpp +++ b/src/text_editor/text_editor.cpp @@ -50,6 +50,7 @@ int FullScreenPositionX, FullScreenPositionY; #include "coroutines.cpp" #include "test.cpp" #include "prototype.cpp" + void FillEventWithBasicData(Event *event) { SDL_Keymod mod = SDL_GetModState(); event->shift = (mod & SDL_KMOD_SHIFT) != 0; diff --git a/src/text_editor/todo.txt b/src/text_editor/todo.txt index 928b2fa..5a8370e 100644 --- a/src/text_editor/todo.txt +++ b/src/text_editor/todo.txt @@ -1,5 +1,14 @@ +- When moving last line alt + arrow key it moves it into upper line, super annoying - 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 | +-------------- +buffer = make_buffer() +buffer.append(list_files("src/basic")) +activate_buffer +-------------- + +- maybe most of the bindings should be in lua, but actual code in C +- LoadWord, EncloseWord configurable? - 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 - shift click inside selection should move the selection @@ -10,27 +19,17 @@ - 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 - 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 - - +- Search and replace - some split selection commands - - A lister which is going to show project without the full path and sorted by recency - - word complete - Search all buffers in 10X style, incrementally searched results popping up on every key press (maybe we need coroutine library in C so this is easier?) - To implement that I think it would be best to load all files into memory -- Search and replace - - kill view - killing all views for buffer ejects buffer (maybe also introduce kill buffer) - ask if you want to close without saving on exit - ask if you want to create new file? - -- Lua_New - Cmd should reuse the window which already has the build - escapeing multiple cursor after ctrl + d should put the cursor where it was (probably will need to swap secondary and primary cursor for new cursor - -- when do we regen directory buffers? - - draw indentation levels like in sublime (those lines) - we render chars one by one so seems relatively easy to figure out if whitespace belongs to beginning of line (make sure to add max value like 40 because of big files) - code sections, visual demarkation if beginning of line has a very specific text + goto next / goto prev section hotkey! - change size of command window because it's wacky diff --git a/te.lua_project b/te.lua_project new file mode 100644 index 0000000..9f73541 --- /dev/null +++ b/te.lua_project @@ -0,0 +1,47 @@ +function OnCommandTE(e) + if e.key == SDLK_B and e.ctrl == 1 then + local cmd = "cd "..GetProjectPath().." && build.bat" + C(cmd) + end +end + +function MatchProject(s) + if s:sub(1,1) == '"' then + s = s:sub(2) + end + + local s, file_path, drive = SkipPath(s) + if not file_path then + return nil + end + if drive ~= nil then + return nil + end + + local line, col, s = SkipLineAndColumn(s) + + local fp = GetActiveMainWindowBufferDir().."/"..file_path + if FileExists(fp) then + return {kind = "text", file_path = fp, line = line, col = col} + end + + local fp = GetProjectPath().."/src/"..file_path + if FileExists(fp) then + return {kind = "text", file_path = fp, line = line, col = col} + end + + local fp = GetProjectPath().."/"..file_path + if FileExists(fp) then + return {kind = "text", file_path = fp, line = line, col = col} + end + + return nil +end + +function MatchGrep(s) + return {kind = "exec", cmd = "git grep -n "..GetLoadWord().." :/", working_dir = GetProjectPath()} +end + +table.insert(OnCommandCallbacks, OnCommandTE) +table.insert(Rules, 1, MatchGrep) +table.insert(Rules, MatchProject) \ No newline at end of file