Expanding go to next in list functionality

This commit is contained in:
Krzosa Karol
2026-01-02 15:21:33 +01:00
parent bedc2b15e2
commit 9730aa944d
7 changed files with 104 additions and 53 deletions

View File

@@ -1,6 +1,14 @@
! What precise workflow do I need for me to be viable to use this?
! From a user (novice) point of view, how does it look like?
Use session 4
- ":OpenAt C:/Work"
- :OpenCodeAt C:/Work
- :SetWorkDirAt C:/Work or :Set WorkDir "." ? or :Set WorkDir "C:/text_editor"
- Maybe some convention for commands that accept arguments?
- Delete file command
- :Close Fuzzy search exact match doesn't match with Close
- Make a fuzzy command !> grep and fuzzy over it??? (doesn't seem very useful for grep)
- Make the equivalent of SearchProject but for cmds like !@git grep -n "@>"
- Add Bool variable

View File

@@ -42,7 +42,7 @@ void JumpTempBuffer(BSet *set, String buffer_name) {
set->buffer->temp = true;
}
void MouseLoadWord(Event event, String meta = "") {
void MouseLoadWord(Event event, ResolveOpenMeta meta = ResolveOpenMeta_Normal) {
Vec2I mouse = MouseVec2I();
BSet active = GetBSet(ActiveWindowID);
@@ -327,20 +327,29 @@ 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);
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);
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);
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);
line = Trim(line);
MergeCarets(buffer_goto, &view_goto->carets);
IF_DEBUG(AssertRanges(view_goto->carets));
@@ -348,11 +357,22 @@ void GotoNextInList(Window *window, Int line_offset = 1) {
continue;
}
BSet set = Open(line, "dont_error");
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;
}
@@ -460,12 +480,12 @@ bool IsOpenBoundary(char c) {
return result;
}
ResolvedOpen ResolveOpen(Allocator alo, String path, String meta) {
ResolvedOpen ResolveOpen(Allocator alo, String path, ResolveOpenMeta meta) {
ResolvedOpen result = {};
path = Trim(path);
// Editor command
{
if(!(ResolveOpenMeta_DontExec & meta)) {
if (StartsWith(path, ":")) {
result.kind = OpenKind_Command;
path = Skip(path, 1);
@@ -481,7 +501,7 @@ ResolvedOpen ResolveOpen(Allocator alo, String path, String meta) {
}
// Shell
{
if (!(ResolveOpenMeta_DontExec & meta)) {
if (StartsWith(path, "!!")) {
result.kind = OpenKind_BackgroundExec;
result.path = Skip(path, 2);
@@ -495,7 +515,7 @@ ResolvedOpen ResolveOpen(Allocator alo, String path, String meta) {
}
// Web
{
if (!(ResolveOpenMeta_DontExec & meta)) {
if (StartsWith(path, "https://") || StartsWith(path, "http://")) {
result.path = Format(alo, "%S %S", InternetBrowser, path);
result.kind = OpenKind_BackgroundExec;
@@ -504,7 +524,7 @@ ResolvedOpen ResolveOpen(Allocator alo, String path, String meta) {
}
// Commit
{
if (!(ResolveOpenMeta_DontExec & meta)) {
if (StartsWith(path, "commit ")) {
path = Skip(path, 7);
result.path = Format(alo, "git --no-pager show %S", path);
@@ -586,7 +606,7 @@ ResolvedOpen ResolveOpen(Allocator alo, String path, String meta) {
}
if (meta == "dont_error") {
if (meta & ResolveOpenMeta_DontError) {
result.path = path;
result.kind = OpenKind_Skip;
return result;
@@ -595,7 +615,7 @@ ResolvedOpen ResolveOpen(Allocator alo, String path, String meta) {
return result;
}
BSet Open(Window *window, String path, String meta, bool set_active = true) {
BSet Open(Window *window, String path, ResolveOpenMeta meta, bool set_active = true) {
Scratch scratch;
BSet set = GetBSet(window);
ResolvedOpen o = ResolveOpen(scratch, path, meta);
@@ -643,13 +663,13 @@ BSet Open(Window *window, String path, String meta, bool set_active = true) {
return GetBSet(window);
}
BSet Open(String path, String meta) {
BSet Open(String path, ResolveOpenMeta meta) {
BSet main = GetBSet(LastActiveLayoutWindowID);
main = Open(main.window, path, meta);
return main;
}
BSet Open(String16 path, String meta) {
BSet Open(String16 path, ResolveOpenMeta meta) {
Scratch scratch;
String string = ToString(scratch, path);
return Open(string, meta);
@@ -996,10 +1016,16 @@ void CMD_MakeFontSmaller() {
}
} RegisterCommand(CMD_MakeFontSmaller, "ctrl-minus");
void CMD_Open() {
void CMD_OpenLoadWord() {
Scratch scratch;
BSet active = GetBSet(ActiveWindowID);
Open(FetchLoadWord(active.view));
} RegisterCommand(CMD_Open, "ctrl-q");
String16 load_word = FetchLoadWord(active.view);
// String load_word = ToString(scratch, load_word16);
Window *window = GetWindow(LastActiveLayoutWindowID);
window->active_goto_list = active.view->id;
window->goto_list_pos = active.view->carets[0].range.min;
Open(load_word);
} RegisterCommand(CMD_OpenLoadWord, "ctrl-q");
void CMD_KillSelectedLines() {
BSet active = GetBSet(ActiveWindowID);
@@ -1452,19 +1478,19 @@ void CMD_EvalCommandsLineByLine() {
EvalCommandsLineByLine(set);
} RegisterCommand(CMD_EvalCommandsLineByLine, "");
void GenerateConfig(Buffer *buffer) {
void GenerateConfig(View *view) {
For (Variables) {
if (it.type == VariableType_String) {
RawAppendf(buffer, "// :Set %S '%S'\n", it.name, *it.string);
Appendf(view, "// :Set %S '%S'\n", it.name, *it.string);
} else if (it.type == VariableType_Int) {
RawAppendf(buffer, "// :Set %S '%lld'\n", it.name, (long long)*it.i);
Appendf(view, "// :Set %S '%lld'\n", it.name, (long long)*it.i);
} else if (it.type == VariableType_Float) {
RawAppendf(buffer, "// :Set %S '%f'\n", it.name, *it.f);
Appendf(view, "// :Set %S '%f'\n", it.name, *it.f);
} else if (it.type == VariableType_Color) {
RawAppendf(buffer, "// :Set %S %x\n", it.name, it.color->value);
Appendf(view, "// :Set %S %x\n", it.name, it.color->value);
} ElseInvalidCodepath();
}
For (CommandFunctions) {
RawAppendf(buffer, "// :Set %S '%S'\n", it.name, it.binding);
Appendf(view, "// :Set %S '%S'\n", it.name, it.binding);
}
}

View File

@@ -160,6 +160,6 @@ RegisterVariable(String, VCVarsall, "C:/Program Files/Microsoft Visual Studio/20
RegisterVariable(Float, UndoMergeTime, 0.3);
RegisterVariable(Float, JumpHistoryMergeTime, 0.3);
RegisterVariable(String, InternetBrowser, "firefox");
RegisterVariable(String, NonCodePatterns_EndsWith, ".git/|.obj|.o|.pdb|.exe|.ilk|.ttf|.ico|.gif|.jpg|.png|.spall");
RegisterVariable(String, NonCodePatterns_EndsWith, ".git/|.obj|.o|.pdb|.exe|.ilk|.ttf|.ico|.gif|.jpg|.png|.spall|.dll|.so|.a|.lib");
RegisterVariable(Int, TrimTrailingWhitespace, 1);
RegisterVariable(Int, FormatCode, 0);

View File

@@ -904,7 +904,7 @@ int main(int argc, char **argv)
Buffer *buffer = GetBuffer(view->active_buffer);
bool file_exists = buffer->file_mod_time != 0;
if (!file_exists) {
GenerateConfig(buffer);
GenerateConfig(view);
} else {
EvalCommandsLineByLine({window, view, buffer});
}

View File

@@ -75,8 +75,6 @@ float DPIScale = 1.0f;
void AfterEdit(View *view, Array<Edit> edits);
Scroller ComputeScrollerRect(Window *window);
BSet Open(String path, String meta = "");
BSet Open(String16 path, String meta = "");
void UpdateScroll(Window *window, bool update_caret_scrolling);
String GetMainDir();
@@ -187,13 +185,23 @@ enum OpenKind {
OpenKind_Command,
};
typedef uint32_t ResolveOpenMeta;
enum {
ResolveOpenMeta_Normal = 0,
ResolveOpenMeta_DontError = 2,
ResolveOpenMeta_DontExec = 4, // dont error +
};
struct ResolvedOpen {
OpenKind kind;
String path;
Int line, col;
bool existing_buffer;
};
ResolvedOpen ResolveOpen(Allocator scratch, String path, String meta);
ResolvedOpen ResolveOpen(Allocator scratch, String path, ResolveOpenMeta meta);
BSet Open(String path, ResolveOpenMeta meta = ResolveOpenMeta_Normal);
BSet Open(String16 path, ResolveOpenMeta meta = ResolveOpenMeta_Normal);
void CenterView(WindowID window);
void TrimWhitespace(Buffer *buffer, bool trim_lines_with_caret = false);
void ApplyFormattingTool(Buffer *buffer, String tool);

View File

@@ -114,6 +114,26 @@ String16 FetchLoadWord(View *view) {
return string;
}
String16 FetchFuzzyViewLoadLine(View *view) {
Buffer *buffer = GetBuffer(view->active_buffer);
Range range = view->carets[0].range;
String16 string = GetString(buffer, range);
if (GetSize(range) == 0) {
Int line = PosToLine(buffer, range.min);
if (line == 0) {
line = ClampTop(1ll, buffer->line_starts.len - 1ll);
}
string = GetLineStringWithoutNL(buffer, line);
Int idx = 0;
String16 delim = u"|::|";
if (Seek(string, delim, &idx, SeekFlag_None)) {
string = Skip(string, idx + delim.len);
}
}
return string;
}
void IdentedNewLine(View *view) {
Buffer *buffer = GetBuffer(view->active_buffer);
Scratch scratch;

View File

@@ -49,10 +49,6 @@ void CMD_ShowBufferList() {
NextActiveWindowID = command_bar.window->id;
ResetBuffer(command_bar.buffer);
For (Buffers) {
if (it->special || it->temp) {
if (it->id != NullBufferID && it->id != BuildBufferID) continue;
}
RawAppendf(command_bar.buffer, "\n%S", it->name);
}
command_bar.view->update_scroll = true;
@@ -61,22 +57,7 @@ void CMD_ShowBufferList() {
void OpenCommand(BSet active) {
ProfileFunction();
Range range = active.view->carets[0].range;
String16 string = FetchLoadWord(active.view);
if (GetSize(range) == 0) {
Int line = PosToLine(active.buffer, range.min);
if (line == 0) {
line = ClampTop(1ll, active.buffer->line_starts.len - 1ll);
}
string = GetLineStringWithoutNL(active.buffer, line);
Int idx = 0;
String16 delim = u"|::|";
if (Seek(string, delim, &idx, SeekFlag_None)) {
string = Skip(string, idx + delim.len);
}
}
String16 string = FetchFuzzyViewLoadLine(active.view);
Open(string);
}
@@ -84,7 +65,12 @@ void CMD_CommandWindowOpen() {
BSet active = GetBSet(ActiveWindowID);
BSet main = GetBSet(LastActiveLayoutWindowID);
NextActiveWindowID = main.window->id;
OpenCommand(active);
String16 string = FetchFuzzyViewLoadLine(active.view);
// if (active.view->kind == ViewKind_ActiveSearch) {
main.window->active_goto_list = active.view->id;
main.window->goto_list_pos = active.view->carets[0].range.min;
// }
Open(string);
}
void CommandWindowLayout(Rect2I *rect, Int wx, Int wy) {
@@ -169,7 +155,7 @@ void Coro_SearchProject(mco_coro *co) {
Int line = PosToLine(it, pos);
String16 line_string = GetLineStringWithoutNL(it, line);
String line_string8 = ToString(scratch, line_string);
RawAppendf(out_buffer, "%-150S |::| %S:%lld\n", line_string8, it->name, (long long)line + 1);
RawAppendf(out_buffer, "%S |::| %S:%lld\n", line_string8, it->name, (long long)line + 1);
}
}
CoYield(co);
@@ -210,6 +196,7 @@ void FuzzySearchViewUpdate() {
active.view->prev_search_line_hash = hash;
if (line_string.len > 0) {
// @todo: do we reintroduce history here?
Caret caret = active.view->carets[0];
SelectEntireBuffer(active.view);
Replace(active.view, line_string);
Append(active.view, "\n", false);
@@ -222,6 +209,8 @@ void FuzzySearchViewUpdate() {
dat->user_ctx = param;
dat->dont_wait_until_resolved = true;
CoResume(dat);
active.view->carets[0] = caret;
}
}
} else if (active.view->kind == ViewKind_FuzzySearch) {