From 70858fdec5044a9dbbbda34f3360146ece80259b Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Mon, 12 May 2025 17:12:37 +0200 Subject: [PATCH] ListCode, fix unique buffer opening an existing file on disk --- data/init.lua | 39 +++++++++++++- src/text_editor/commands.cpp | 74 +++++++++++++-------------- src/text_editor/commands_bindings.cpp | 3 +- src/text_editor/generated.cpp | 39 +++++++++++++- src/text_editor/lua_api.cpp | 13 +++++ src/text_editor/lua_api_generated.cpp | 2 +- src/text_editor/management.cpp | 2 +- 7 files changed, 128 insertions(+), 44 deletions(-) diff --git a/data/init.lua b/data/init.lua index dd0b8c3..07ae061 100644 --- a/data/init.lua +++ b/data/init.lua @@ -251,13 +251,16 @@ function MatchExec(s, meta) return {kind = "skip"} end -OnOpenMatchers = { +BuiltinOnOpenMatchers = { MatchWindowsPath, MatchGitCommit, MatchURL, + MatchGotoBuild, + MatchExec, } +OnOpenMatchers = BuiltinOnOpenMatchers function OnOpen(path, meta) for i = #OnOpenMatchers,1,-1 do @@ -319,4 +322,38 @@ function OnSave(buffer_id) if Style.ClangFormatOnSave and (name:match(".c$") or name:match(".h$") or name:match(".cpp$") or name:match(".hpp$")) then ApplyClangFormat(buffer_id) end +end + +function IsCodeExclude(s, meta) + if s:match("/.git$") or s:match("\\.git$") or + s:match(".exe$") or + s:match(".bin$") or + s:match(".obj$") or + s:match(".o$") or + s:match(".lib$") or + s:match(".ilk$") or + s:match(".cache$") or + s:match(".exp$") or + s:match(".pdb$") or + s:match("/external/") or s:match("\\external\\") + then + return false + end + return true +end + +BuiltinIsCodeMatchers = { + IsCodeExclude, +} +IsCodeMatchers = BuiltinIsCodeMatchers + +function IsCode(path, meta) + for i = #IsCodeMatchers,1,-1 do + rule = IsCodeMatchers[i] + result = rule(path, meta) + if result then + return result + end + end + return false end \ No newline at end of file diff --git a/src/text_editor/commands.cpp b/src/text_editor/commands.cpp index e3e45b6..5798f90 100644 --- a/src/text_editor/commands.cpp +++ b/src/text_editor/commands.cpp @@ -40,10 +40,12 @@ void GotoForward(Window *window) { UpdateScroll(window, true); } -void JumpGarbageBuffer(BSet *set) { +void JumpGarbageBuffer(BSet *set, String buffer_name = "") { CheckpointBeforeGoto(set->window); - String current_dir = ChopLastSlash(set->buffer->name); - String buffer_name = GetUniqueBufferName(current_dir, "temp"); + if (buffer_name.len == 0) { + String current_dir = ChopLastSlash(set->buffer->name); + buffer_name = GetUniqueBufferName(current_dir, "temp"); + } set->view = WindowOpenBufferView(set->window, buffer_name); set->buffer = GetBuffer(set->view->active_buffer); set->buffer->garbage = true; @@ -140,28 +142,6 @@ void ReplaceWithoutMovingCarets(Buffer *buffer, Range range, String16 string) { view->carets = carets; } -void ListFilesRecursive(Buffer *buffer, String filename) { - Scratch scratch(buffer->line_starts.allocator); - for (FileIter it = IterateFiles(scratch, filename); IsValid(it); Advance(&it)) { - if (it.filename == ".git") { - continue; - } - if (it.is_directory) { - ListFilesRecursive(buffer, it.absolute_path); - } else { - bool good = EndsWith(it.filename, ".c") || - EndsWith(it.filename, ".h") || - EndsWith(it.filename, ".cpp") || - EndsWith(it.filename, ".hpp") || - EndsWith(it.filename, ".bat"); - if (!good) { - continue; - } - RawAppendf(buffer, "%.*s\n", FmtString(it.absolute_path)); - } - } -} - // @todo: revamp interface since it scrolls ALL VIEWS??? or maybe not?? void Command_Append(View *view, String16 string, bool scroll_to_end_if_cursor_on_last_line) { Scratch scratch; @@ -611,6 +591,7 @@ void TrimTrailingWhitespace(Buffer *buffer, bool trim_lines_with_caret = false) EndEdit(buffer, &edits, &view->carets, !KILL_SELECTION); view->update_scroll = false; } + int Lua_TrimTrailingWhitespace(lua_State *L) { lua_Integer buffer_id = luaL_checkinteger(L, 1); int trim_lines_with_caret = lua_toboolean(L, 2); @@ -651,6 +632,7 @@ void ConvertLineEndingsToLF(Buffer *buffer, bool trim_lines_with_caret = false) EndEdit(buffer, &edits, &view->carets, !KILL_SELECTION); view->update_scroll = false; } + int Lua_ConvertLineEndingsToLF(lua_State *L) { lua_Integer buffer_id = luaL_checkinteger(L, 1); int trim_lines_with_caret = lua_toboolean(L, 2); @@ -1038,7 +1020,6 @@ int Lua_NewDir(lua_State *L) { return 0; } - void Command_ToggleFullscreen() { if (IsInFullscreen) { SDL_SetWindowSize(SDLWindow, FullScreenSizeX, FullScreenSizeY); @@ -1055,23 +1036,39 @@ void Command_ToggleFullscreen() { IsInFullscreen = !IsInFullscreen; } + int Lua_ToggleFullscreen(lua_State *L) { Command_ToggleFullscreen(); return 0; } -void Command_GetCFiles(void) { - BSet main = GetActiveMainSet(); - - Scratch scratch; - String buffer_name = GetUniqueBufferName(GetDir(main.buffer), "getcfiles"); - - Buffer *buffer = CreateBuffer(GetSystemAllocator(), buffer_name, 4096 * 4); - ListFilesRecursive(buffer, Command_GetMainDir()); - WindowOpenBufferView(main.window, buffer_name); +void ListFilesRecursive(Buffer *buffer, String filename) { + Scratch scratch(buffer->line_starts.allocator); + for (FileIter it = IterateFiles(scratch, filename); IsValid(it); Advance(&it)) { + if (it.filename == ".git") { + continue; + } + if (it.is_directory) { + ListFilesRecursive(buffer, it.absolute_path); + } else { + bool good = CallIsCode(it.absolute_path); + if (!good) { + continue; + } + RawAppendf(buffer, "%.*s\n", FmtString(it.absolute_path)); + } + } } -int Lua_GetCFiles(lua_State *L) { - Command_GetCFiles(); + +void Command_ListCode(void) { + BSet main = GetActiveMainSet(); + JumpGarbageBuffer(&main); + ListFilesRecursive(main.buffer, WorkDir); + main.view->fuzzy_search = true; +} + +int Lua_ListCode(lua_State *L) { + Command_ListCode(); return 0; } @@ -1106,8 +1103,7 @@ BSet Command_Open(Window *window, String path, String meta, bool set_active = tr ActiveWindow = set.window->id; } if (IsDir(ores.file_path)) { - JumpGarbageBuffer(&set); - set.buffer->name = GetUniqueBufferName(ores.file_path, "temp"); + JumpGarbageBuffer(&set, GetUniqueBufferName(ores.file_path, "dir")); Command_Appendf(set.view, "..\n", FmtString(ores.file_path)); for (FileIter it = IterateFiles(scratch, ores.file_path); IsValid(it); Advance(&it)) { Command_Appendf(set.view, "%.*s\n", FmtString(it.filename)); diff --git a/src/text_editor/commands_bindings.cpp b/src/text_editor/commands_bindings.cpp index 1e578fc..f7b3405 100644 --- a/src/text_editor/commands_bindings.cpp +++ b/src/text_editor/commands_bindings.cpp @@ -285,7 +285,8 @@ void OnCommand(Event event) { if (CtrlPress(SDLK_P)) { - void Command_ListBuffers(); + Command_ListCode(); + } else if (CtrlAltPress(SDLK_P)) { Command_ListBuffers(); } diff --git a/src/text_editor/generated.cpp b/src/text_editor/generated.cpp index 0be6b8a..cbced8c 100644 --- a/src/text_editor/generated.cpp +++ b/src/text_editor/generated.cpp @@ -321,13 +321,16 @@ function MatchExec(s, meta) return {kind = "skip"} end -OnOpenMatchers = { +BuiltinOnOpenMatchers = { MatchWindowsPath, MatchGitCommit, MatchURL, + MatchGotoBuild, + MatchExec, } +OnOpenMatchers = BuiltinOnOpenMatchers function OnOpen(path, meta) for i = #OnOpenMatchers,1,-1 do @@ -390,6 +393,40 @@ function OnSave(buffer_id) ApplyClangFormat(buffer_id) end end + +function IsCodeExclude(s, meta) + if s:match("/.git$") or s:match("\\.git$") or + s:match(".exe$") or + s:match(".bin$") or + s:match(".obj$") or + s:match(".o$") or + s:match(".lib$") or + s:match(".ilk$") or + s:match(".cache$") or + s:match(".exp$") or + s:match(".pdb$") or + s:match("/external/") or s:match("\\external\\") + then + return false + end + return true +end + +BuiltinIsCodeMatchers = { + IsCodeExclude, +} +IsCodeMatchers = BuiltinIsCodeMatchers + +function IsCode(path, meta) + for i = #IsCodeMatchers,1,-1 do + rule = IsCodeMatchers[i] + result = rule(path, meta) + if result then + return result + end + end + return false +end )=="; void ReloadStyle() { ColorText = GetColor("Text", ColorText); diff --git a/src/text_editor/lua_api.cpp b/src/text_editor/lua_api.cpp index 4749f2f..d6fceb6 100644 --- a/src/text_editor/lua_api.cpp +++ b/src/text_editor/lua_api.cpp @@ -318,6 +318,19 @@ OnOpenResult CallOnOpen(String path, String meta) { return result; } +bool CallIsCode(String path, String meta = "") { + lua_getglobal(LuaState, "IsCode"); + lua_pushlstring(LuaState, path.data, path.len); + lua_pushlstring(LuaState, meta.data, meta.len); + if (!CallLuaFunc("IsCode", 2, 1)) { + return false; + } + + bool result = lua_toboolean(LuaState, -1); + lua_pop(LuaState, 1); + return result; +} + void CallOnSave(BufferID buffer_id) { lua_getglobal(LuaState, "OnSave"); lua_pushinteger(LuaState, buffer_id.id); diff --git a/src/text_editor/lua_api_generated.cpp b/src/text_editor/lua_api_generated.cpp index 7c7e4c7..550fef2 100644 --- a/src/text_editor/lua_api_generated.cpp +++ b/src/text_editor/lua_api_generated.cpp @@ -21,7 +21,7 @@ luaL_Reg LuaFunctions[] = { {"New", Lua_New}, {"NewDir", Lua_NewDir}, {"ToggleFullscreen", Lua_ToggleFullscreen}, - {"GetCFiles", Lua_GetCFiles}, + {"ListCode", Lua_ListCode}, {"C", Lua_C}, {"Open", Lua_Open}, {"Cmd", Lua_Cmd}, diff --git a/src/text_editor/management.cpp b/src/text_editor/management.cpp index d520d3a..baae48c 100644 --- a/src/text_editor/management.cpp +++ b/src/text_editor/management.cpp @@ -58,7 +58,7 @@ String GetUniqueBufferName(String working_dir, String prepend_name) { buffer_name = Format(scratch, "%.*s/%.*s%d.log", FmtString(working_dir), FmtString(prepend_name), i); buffer_name = GetAbsolutePath(scratch, buffer_name); Buffer *exists = FindBuffer(buffer_name); - if (!exists) { + if (!exists && !FileExists(buffer_name)) { break; } }