Fuzzy search, working dir as nullbuffer dir

This commit is contained in:
Krzosa Karol
2025-05-06 16:41:43 +02:00
parent 9ddfed92ff
commit abb2cfb1c4
12 changed files with 102 additions and 111 deletions

View File

@@ -50,7 +50,7 @@ void Command_GetCFiles(void) {
String buffer_name = GetUniqueBufferName(GetDir(main.buffer), "getcfiles");
Buffer *buffer = CreateBuffer(GetSystemAllocator(), buffer_name, 4096 * 4);
ListFilesRecursive(buffer, Command_GetDir());
ListFilesRecursive(buffer, Command_GetMainDir());
WindowOpenBufferView(main.window, buffer_name);
}
@@ -632,17 +632,6 @@ void OnCommand(Event event) {
Command_GotoNextInList(active.window, 1);
}
if (CtrlShiftPress(SDLK_RETURN)) {
Command_MoveCursorsToSide(active.view, DIR_LEFT);
Command_IdentedNewLine(active.view);
Command_Move(active.view, DIR_UP);
} else if (CtrlPress(SDLK_RETURN)) {
Command_MoveCursorsToSide(active.view, DIR_RIGHT);
Command_IdentedNewLine(active.view);
} else if (Press(SDLK_RETURN)) {
Command_IdentedNewLine(active.view);
}
if (CtrlShiftPress(SDLK_F)) {
// because using lua thing
} else if (CtrlPress(SDLK_F)) {
@@ -659,6 +648,44 @@ void OnCommand(Event event) {
}
}
if (CtrlShiftPress(SDLK_RETURN)) {
Command_MoveCursorsToSide(active.view, DIR_LEFT);
Command_IdentedNewLine(active.view);
Command_Move(active.view, DIR_UP);
} else if (CtrlPress(SDLK_RETURN)) {
Command_MoveCursorsToSide(active.view, DIR_RIGHT);
Command_IdentedNewLine(active.view);
} else if (Press(SDLK_RETURN)) {
Command_IdentedNewLine(active.view);
}
if (active.view->fuzzy_search) {
if (!ProcessIsActive(active.view->id)) {
Scratch scratch;
String16 last_line_string = GetLineStringWithoutNL(active.buffer, active.buffer->line_starts.len - 1);
if (active.view->prev_search_line != last_line_string) {
active.view->prev_search_line = last_line_string;
Array<FuzzyPair> ratings = FuzzySearchLines(scratch, active.buffer, 0, active.buffer->line_starts.len - 1, last_line_string);
Buffer *temp_buffer = CreateTempBuffer(scratch, active.buffer->cap);
For(IterateInReverse(&ratings)) {
String16 s = GetLineStringWithoutNL(active.buffer, it.index);
if (s.len == 0) continue;
RawReplaceText(temp_buffer, GetEndAsRange(temp_buffer), s);
RawReplaceText(temp_buffer, GetEndAsRange(temp_buffer), u"\n");
}
RawReplaceText(temp_buffer, GetEndAsRange(temp_buffer), last_line_string);
Caret caret = active.view->carets[0];
Command_SelectEntireBuffer(active.view);
Command_Replace(active.view, GetString(temp_buffer));
active.view->carets[0] = caret;
}
}
}
if (CtrlPress(SDLK_S)) {
SaveBuffer(active.view);
}
@@ -689,6 +716,10 @@ void OnCommand(Event event) {
Command_Eval(FetchLoadWord());
} else if (CtrlPress(SDLK_Q)) {
Command_Open(FetchLoadWord());
if (active.view->fuzzy_search) {
Range rng = GetLineRangeWithoutNL(active.buffer, active.buffer->line_starts.len - 1);
GetLast(active.window->goto_history)->caret = MakeCaret(rng.max, rng.min);
}
}
if (Press(SDLK_ESCAPE)) {
@@ -703,9 +734,6 @@ void OnCommand(Event event) {
}
}
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) {
Command_Find(main.view, GetSearchString(main.window), true);
}

View File

@@ -247,7 +247,7 @@ function MatchWindowsPath(_s)
end
if not drive then
local d = GetDir()
local d = GetMainDir()
file_path = d..'/'..file_path
end
local line, col, s = SkipLineAndColumn(s)
@@ -263,7 +263,7 @@ function MatchGitCommit(s)
if i then
s = s:sub(8)
local command = "git --no-pager show "..s
return {kind = "exec", cmd = command, working_dir = GetDir()}
return {kind = "exec", cmd = command, working_dir = GetMainDir()}
end
return nil
end
@@ -271,7 +271,7 @@ end
function MatchURL(s)
local i, j = string.find(s, "^https://")
if i then
return {kind = "exec_console", cmd = '"'..INTERNET_BROWSER..'" '..s, working_dir = GetDir()}
return {kind = "exec_console", cmd = '"'..INTERNET_BROWSER..'" '..s, working_dir = GetMainDir()}
end
return nil
end
@@ -294,7 +294,7 @@ function ApplyRules(s)
end
function CFiles()
Cmd({working_dir = GetProjectPath(), destination ="a", cmd = "dir /s/b | findstr .*\\.c"})
Cmd({working_dir = GetProjectDir(), kind ="a", cmd = "dir /s/b | findstr .*\\.c"})
end
Coroutines = {}
@@ -310,7 +310,7 @@ table.insert(OnCommandCallbacks, function (e)
if e.key == SDLK_F and e.ctrl == 1 and e.shift == 1 then
C("git grep -n "..GetLoadWord().." :/") end
if e.key == SDLK_B and e.ctrl == 1 then
Cmd { working_dir = GetProjectPath(), destination = "console", cmd = "build.bat" } end
Cmd { working_dir = GetProjectDir(), kind = "console", cmd = "build.bat" } end
end)
function OnUpdate(e)

View File

@@ -93,6 +93,7 @@ BSet Command_Open(String path) {
ActiveWindow = main.window->id;
if (IsDir(file_path)) {
Command_JumpNew(&main);
main.buffer->name = GetUniqueBufferName(file_path, "temp");
Command_Appendf(main.view, "%.*s/..\n", FmtString(file_path));
for (FileIter it = IterateFiles(scratch, file_path); IsValid(it); Advance(&it)) {
Command_Appendf(main.view, "%.*s\n", FmtString(it.absolute_path));
@@ -110,7 +111,7 @@ BSet Command_Open(String path) {
} else if (FieldString(LuaState, "kind") == "exec") {
String cmd = FieldString(LuaState, "cmd");
String working_dir = FieldString(LuaState, "working_dir");
Command_Exec(cmd, Command_GetDir());
Command_Exec(cmd, Command_GetMainDir());
} else if (FieldString(LuaState, "kind") == "exec_console") {
// this shouldn't change the focus/window/view
String cmd = FieldString(LuaState, "cmd");
@@ -132,7 +133,7 @@ BSet Command_Open(String16 path) {
int Lua_C(lua_State *L) {
String string = lua_tostring(L, 1);
lua_pop(L, 1);
Command_Exec(string, Command_GetDir());
Command_Exec(string, Command_GetMainDir());
return 0;
}
@@ -161,7 +162,7 @@ int Lua_NewBufferCMD(lua_State *L) {
String string = lua_tostring(L, 1);
lua_pop(L, 1);
String working_dir = Command_GetDir();
String working_dir = Command_GetMainDir();
BSet set = GetActiveMainSet();
Command_ExecInNewBuffer(set, string, working_dir);
return 0;
@@ -172,21 +173,23 @@ int Lua_Cmd(lua_State *L) {
defer { lua_pop(L, 1); };
lua_getfield(L, -1, "working_dir");
if (!lua_isstring(L, -1)) luaL_error(L, "expected a string for working_dir param");
String working_dir = lua_tostring(L, -1);
lua_pop(L, 1);
if (working_dir == "") {
working_dir = Command_GetMainDir();
}
lua_getfield(L, -1, "cmd");
if (!lua_isstring(L, -1)) luaL_error(L, "expected a string for cmd param");
String cmd = lua_tostring(L, -1);
lua_pop(L, 1);
lua_getfield(L, -1, "destination");
String destination = lua_tostring(L, -1);
lua_getfield(L, -1, "kind");
String kind = lua_tostring(L, -1);
lua_pop(L, 1);
BSet main = GetActiveMainSet();
if (destination == "console") {
if (kind == "console") {
BSet set = GetConsoleSet();
main.window->active_goto_list = set.view->id;
main.window->goto_list_pos = set.buffer->len;
@@ -194,6 +197,11 @@ int Lua_Cmd(lua_State *L) {
Command_BeginJump(&set);
Exec(set.view->id, true, cmd, working_dir);
Command_EndJump(set);
} else if (kind == "fuzzy") {
Command_JumpNew(&main);
Exec(main.view->id, true, cmd, working_dir);
main.view->fuzzy_search = true;
ActiveWindow = main.window->id;
} else {
Command_JumpNew(&main);
Exec(main.view->id, true, cmd, working_dir);
@@ -358,7 +366,7 @@ int Lua_GetFilename(lua_State *L) {
return 1;
}
int Lua_GetProjectPath(lua_State *L) {
int Lua_GetProjectDir(lua_State *L) {
if (LuaProjectBuffer) {
String path = ChopLastSlash(LuaProjectBuffer->name);
lua_pushlstring(L, path.data, path.len);
@@ -376,13 +384,14 @@ int Lua_FileExists(lua_State *L) {
return 1;
}
int Lua_GetWorkingDir(lua_State *L) {
lua_pushlstring(L, WorkingDir.data, WorkingDir.len);
int Lua_GetBaseDir(lua_State *L) {
String name = Command_GetBaseDir();
lua_pushlstring(L, name.data, name.len);
return 1;
}
int Lua_GetDir(lua_State *L) {
String name = Command_GetDir();
int Lua_GetMainDir(lua_State *L) {
String name = Command_GetMainDir();
lua_pushlstring(L, name.data, name.len);
return 1;
}
@@ -551,7 +560,7 @@ void ReloadLuaConfigs() {
ReloadStyle();
ReloadFont();
for (Window *it = FirstWindow; it; it = it->next) {
if (!it->visible || it->absolute_position || it->is_title_bar || it->is_search_bar) {
if (it->is_title_bar || it->is_search_bar) {
continue;
}
it->draw_scrollbar = StyleDrawScrollbar;

View File

@@ -21,10 +21,10 @@ luaL_Reg LuaFunctions[] = {
{"GetEntireBuffer", Lua_GetEntireBuffer},
{"GetClipboard", Lua_GetClipboard},
{"GetFilename", Lua_GetFilename},
{"GetProjectPath", Lua_GetProjectPath},
{"GetProjectDir", Lua_GetProjectDir},
{"FileExists", Lua_FileExists},
{"GetWorkingDir", Lua_GetWorkingDir},
{"GetDir", Lua_GetDir},
{"GetBaseDir", Lua_GetBaseDir},
{"GetMainDir", Lua_GetMainDir},
{"SplitSize", Lua_SplitSize},
{"Play", Lua_Play},
{NULL, NULL},

View File

@@ -49,13 +49,14 @@ String GetUniqueBufferName(String working_dir, String prepend_name) {
void InitScratchBuffer() {
Allocator sys_allocator = GetSystemAllocator();
Buffer *null_buffer = CreateBuffer(sys_allocator, GetUniqueBufferName(WorkingDir, "console"));
Scratch scratch;
Buffer *null_buffer = CreateBuffer(sys_allocator, GetUniqueBufferName(GetWorkingDir(scratch), "console"));
View *null_view = CreateView(null_buffer->id);
Assert(null_buffer->id == NullBufferID && null_view->id == NullViewID);
GCInfoBuffer = CreateBuffer(sys_allocator, GetUniqueBufferName(WorkingDir, "gc"));
EventBuffer = CreateBuffer(sys_allocator, GetUniqueBufferName(WorkingDir, "events"));
ScratchBuffer = CreateBuffer(sys_allocator, GetUniqueBufferName(WorkingDir, "scratch"));
GCInfoBuffer = CreateBuffer(sys_allocator, GetUniqueBufferName(Command_GetBaseDir(), "gc"));
EventBuffer = CreateBuffer(sys_allocator, GetUniqueBufferName(Command_GetBaseDir(), "events"));
ScratchBuffer = CreateBuffer(sys_allocator, GetUniqueBufferName(Command_GetBaseDir(), "scratch"));
EventBuffer->no_history = true;
GCInfoBuffer->no_history = true;
}
@@ -293,12 +294,17 @@ String GetDir(Buffer *buffer) {
return name;
}
String Command_GetDir() {
String Command_GetMainDir() {
BSet set = GetActiveMainSet();
String name = ChopLastSlash(set.buffer->name);
return name;
}
String Command_GetBaseDir() {
Buffer *buffer = GetBuffer(NullBufferID);
return ChopLastSlash(buffer->name);
}
Int ConvertUTF8ToUTF16UnixLine(String string, char16_t *buffer, Int buffer_cap) {
if (string.len == 0) {
return 0;

View File

@@ -226,7 +226,7 @@ void Windows_SetupVCVarsall(mco_coro *co) {
View *view = NULL;
{
Scratch scratch;
String working_dir = Command_GetDir();
String working_dir = Command_GetBaseDir();
String buffer_name = GetUniqueBufferName(working_dir, "vcvarsall-");
String cmd = Format(scratch, "\"%.*s\" && set", FmtString(StyleVCVarsall));
view = Command_ExecHidden(buffer_name, cmd, working_dir);
@@ -266,8 +266,6 @@ int main(int argc, char **argv)
InitArena(&Perm);
// Prototype();
WorkingDir = GetWorkingDir(Perm);
ExeDir = GetExeDir(Perm);
{
String sdl_config_path = SDL_GetPrefPath("krzosa", "text_editor");
if (sdl_config_path.len && sdl_config_path.data[sdl_config_path.len - 1] == '\\') {

View File

@@ -14,6 +14,9 @@ struct View {
// window | view
Caret main_caret_on_begin_frame;
bool update_scroll;
bool fuzzy_search;
String16 prev_search_line;
};
struct GotoCrumb {
@@ -52,7 +55,6 @@ struct Window {
bool draw_line_numbers : 1;
bool visible : 1;
bool absolute_position : 1;
bool is_title_bar : 1;
bool is_search_bar : 1;
@@ -102,9 +104,7 @@ struct BSet {
// Dont use it
Int FrameID;
String WorkingDir;
String ConfigDir;
String ExeDir;
Arena Perm;
float DPIScale = 1.0f;
@@ -122,8 +122,10 @@ void Command_Append(View *view, String16 string, bool scroll_to_end_if_cu
void Command_Append(View *view, String string, bool scroll_to_end_if_cursor_on_last_line);
Array<Edit> Command_ReplaceEx(Allocator scratch, View *view, String16 string);
void Command_ReplaceWithoutMovingCarets(View *view, Range range, String16 string);
void Command_Eval(String string);
void Command_Eval(String16 string);
void Command_Eval(String string);
void Command_Eval(String16 string);
String Command_GetMainDir();
String Command_GetBaseDir();
void Command_Copy(View *view);
void Command_Paste(View *view);

View File

@@ -16,8 +16,6 @@ void UpdateDebugBuffer() {
SDL_GetMouseState(&xmouse, &ymouse);
RawAppendf(buffer, "mouse: [%f, %f]\n", xmouse, ymouse);
RawAppendf(buffer, "C:/Work/text_editor/src/text_editor/text_editor.cpp\n");
RawAppendf(buffer, "working dir: %.*s\n", FmtString(WorkingDir));
RawAppendf(buffer, "exe dir: %.*s\n", FmtString(ExeDir));
RawAppendf(buffer, "config dir: %.*s\n", FmtString(ConfigDir));
}

View File

@@ -1,10 +1,8 @@
!!As little lua code as possible, but lua code should be powerful just in case of quick edits
- 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 |
- need a buffer for every window that will be cleared on command and replaced with new content
- buffer_list shouldn't be a thing
- Scroll the console properly
- commands for scrolling: center, cursor_at_bottom_of_screen, cursor_at_top
- Maybe instead of WorkingDir use directory of null buffer?
- automatically generating lua bindings for simple commands
--------------
buffer = make_buffer()

View File

@@ -14,7 +14,7 @@ Window *CreateSearchBar(WindowID parent_window_id) {
static int BarCount;
Allocator sys_allocator = GetSystemAllocator();
String name = Format(sys_allocator, "%.*s/searchbar%d", FmtString(WorkingDir), ++BarCount);
String name = Format(sys_allocator, "%.*s/searchbar%d", FmtString(Command_GetBaseDir()), ++BarCount);
Buffer *b = CreateBuffer(sys_allocator, name);
View *v = CreateView(b->id);
@@ -37,7 +37,7 @@ Window *CreateTitlebar(WindowID parent_window_id) {
static int TitlebarCount;
Allocator sys_allocator = GetSystemAllocator();
String name = Format(sys_allocator, "%.*s/titlebar%d", FmtString(WorkingDir), ++TitlebarCount);
String name = Format(sys_allocator, "%.*s/titlebar%d", FmtString(Command_GetBaseDir()), ++TitlebarCount);
Buffer *b = CreateBuffer(sys_allocator, name);
View *v = CreateView(b->id);
@@ -189,9 +189,8 @@ void InitWindows() {
{
Window *window = CreateWindow();
Buffer *buffer = CreateBuffer(sys_allocator, GetUniqueBufferName(WorkingDir, "test_buffer"));
Buffer *buffer = ScratchBuffer;
View *view = CreateView(buffer->id);
LoadTestBufferMessage(buffer);
window->active_view = view->id;
CreateTitlebar(window->id);
CreateSearchBar(window->id);
@@ -205,12 +204,11 @@ void InitWindows() {
Window *window = CreateWindow();
DebugWindowID = window->id;
window->draw_line_numbers = false;
window->absolute_position = true;
window->draw_scrollbar = false;
window->visible = false;
window->z = 2;
Buffer *buffer = CreateBuffer(sys_allocator, GetUniqueBufferName(WorkingDir, "debug"));
Buffer *buffer = CreateBuffer(sys_allocator, GetUniqueBufferName(Command_GetBaseDir(), "debug"));
DebugBufferID = buffer->id;
buffer->no_history = true;