Compare commits

...

2 Commits

Author SHA1 Message Date
krzosa
97ba82ab7d Better Rename 2025-12-29 12:26:03 +01:00
krzosa
cde431549c :Prev :Next, CatchAll 2025-12-29 12:02:08 +01:00
6 changed files with 80 additions and 45 deletions

View File

@@ -2,12 +2,13 @@
- From a user (novice) point of view, how does it look like? - From a user (novice) point of view, how does it look like?
Debug session: Debug session:
- Should highlight main buffer when clicking on status?
- Report errorf - use coroutine dialogs - Report errorf - use coroutine dialogs
- Replace in render layer also - Replace in render layer also
Use session 1: Use session 1:
- OpenCommand in command window freezes the app - OpenCommand in command window freezes the app
- :Rename command that will ask - :Rename command that will ask the user
New UI Session New UI Session
- Cleanup String16/String with Open and EvalCommands after lua refactor - Cleanup String16/String with Open and EvalCommands after lua refactor

View File

@@ -164,7 +164,11 @@ void UIMessagef(const char *fmt, ...) {
BSet main = GetBSet(LastActiveLayoutWindowID); BSet main = GetBSet(LastActiveLayoutWindowID);
JumpTempBuffer(&main); JumpTempBuffer(&main);
NextActiveWindowID = main.window->id; NextActiveWindowID = main.window->id;
RawAppendf(main.buffer, "\n %S\n", string); RawAppendf(main.buffer, "\n %S\n :Close\n", string);
AddHook(&main.view->hooks, "Close", "escape", [](){
BSet active = GetBSet(ActiveWindowID);
Close(active.buffer->id);
});
} }
void ReportErrorf(const char *fmt, ...) { void ReportErrorf(const char *fmt, ...) {
@@ -705,7 +709,48 @@ void AddHook(Array<CommandData> *arr, String name, String binding, Function *fun
Add(arr, n); Add(arr, n);
} }
// @todo: rename to temp buffer? but there is already a thing like that... void Coro_Rename(mco_coro *co) {
BSet main = GetBSet(LastActiveLayoutWindowID);
Buffer *buffer = main.buffer;
JumpTempBuffer(&main);
NextActiveWindowID = main.window->id;
RawAppendf(main.buffer, "Rename and click enter to submit: [%S]\n :Rename :Cancel", buffer->name);
main.view->carets[0] = FindNext(main.buffer, u"]", MakeCaret(0));
main.view->carets[0].range.max = main.view->carets[0].range.min;
AddHook(&main.view->hooks, "Rename", "enter", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Rename";});
AddHook(&main.view->hooks, "Cancel", "escape", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Cancel";});
String result = "Cancel";
for (;;) {
if (main.window->active_view != main.view->id || (main.window->id != LastActiveLayoutWindowID && main.window->id != ActiveWindowID) || main.window->close) {
break;
}
if (main.view->hook_cmd != "") {
result = main.view->hook_cmd;
break;
}
CoYield(co);
}
Close(main.buffer->id);
if (result == "Rename") {
Caret a = FindNext(main.buffer, u"[", MakeCaret(-1));
Caret b = FindNext(main.buffer, u"]", MakeCaret(-1));
if (a.range.min == -1 || b.range.max == -1) {
ReportErrorf("Failed to extract the name for the Rename operation from the buffer");
return;
}
String16 string16 = GetString(main.buffer, {a.range.max + 1, b.range.max});
String string = ToString(CoCurr->arena, string16);
buffer->name = Intern(&GlobalInternTable, string);
}
}
void Command_Rename() {
CoAdd(Coro_Rename);
} RegisterCommand(Command_Rename, "");
String Coro_YesNoCancel(mco_coro *co, BSet main, String question) { String Coro_YesNoCancel(mco_coro *co, BSet main, String question) {
JumpTempBuffer(&main); JumpTempBuffer(&main);
NextActiveWindowID = main.window->id; NextActiveWindowID = main.window->id;
@@ -834,17 +879,17 @@ void Command_CloseAll() {
CoAdd(Coro_CloseAll); CoAdd(Coro_CloseAll);
} RegisterCommand(Command_CloseAll, ""); } RegisterCommand(Command_CloseAll, "");
void Command_JumpBack() { void Command_Prev() {
BSet main = GetBSet(LastActiveLayoutWindowID); BSet main = GetBSet(LastActiveLayoutWindowID);
main.window->skip_checkpoint = true; main.window->skip_checkpoint = true;
JumpBack(main.window); JumpBack(main.window);
} RegisterCommand(Command_JumpBack, "alt-q | mousex1"); } RegisterCommand(Command_Prev, "alt-q | mousex1");
void Command_JumpForward() { void Command_Next() {
BSet main = GetBSet(LastActiveLayoutWindowID); BSet main = GetBSet(LastActiveLayoutWindowID);
main.window->skip_checkpoint = true; main.window->skip_checkpoint = true;
JumpForward(main.window); JumpForward(main.window);
} RegisterCommand(Command_JumpForward, "alt-shift-q | mousex2"); } RegisterCommand(Command_Next, "alt-shift-q | mousex2");
void Command_OpenUpFolder() { void Command_OpenUpFolder() {
BSet main = GetBSet(LastActiveLayoutWindowID); BSet main = GetBSet(LastActiveLayoutWindowID);

View File

@@ -12,6 +12,7 @@ enum TriggerKind {
TriggerKind_Key, TriggerKind_Key,
TriggerKind_Mouse, TriggerKind_Mouse,
TriggerKind_Binary, TriggerKind_Binary,
TriggerKind_CatchAll,
}; };
struct Trigger { struct Trigger {
@@ -140,20 +141,31 @@ Trigger *ParseKeyChord(Lexer *lex) {
return left; return left;
} }
Trigger *ParseKeyExpr(Lexer *lex) { Trigger *ParseKeyOr(Lexer *lex) {
Trigger *left = ParseKeyChord(lex); Trigger *left = ParseKeyChord(lex);
EatWhitespace(lex); EatWhitespace(lex);
while (At(lex) == '|') { while (At(lex) == '|') {
Advance(lex); Advance(lex);
left = TriggerBinary(lex, left, ParseKeyExpr(lex), '|'); left = TriggerBinary(lex, left, ParseKeyOr(lex), '|');
EatWhitespace(lex); EatWhitespace(lex);
} }
return left; return left;
} }
Trigger *ParseKeyCatchAll(Lexer *lex) {
String string = AsString(lex);
if (string == "catch_all") {
Trigger *result = AllocType(lex->allocator, Trigger);
result->kind = TriggerKind_CatchAll;
return result;
} else {
return ParseKeyOr(lex);
}
}
Trigger *ParseKey(Allocator allocator, String key, char *debug_name) { Trigger *ParseKey(Allocator allocator, String key, char *debug_name) {
Lexer lex = {allocator, key.data, key.data, key.data + key.len, debug_name}; Lexer lex = {allocator, key.data, key.data, key.data + key.len, debug_name};
Trigger *result = ParseKeyExpr(&lex); Trigger *result = ParseKeyCatchAll(&lex);
return result; return result;
} }
@@ -201,6 +213,10 @@ bool MatchEvent(Trigger *trigger, Event *event) {
ok = MatchEvent(trigger->right, event); ok = MatchEvent(trigger->right, event);
if (ok) return ok; if (ok) return ok;
} ElseInvalidCodepath(); } ElseInvalidCodepath();
} else if (trigger->kind == TriggerKind_CatchAll) {
if (event->kind == EVENT_MOUSE_LEFT || event->kind == EVENT_MOUSE_RIGHT || event->kind == EVENT_MOUSE_MIDDLE || event->kind == EVENT_MOUSE_X1 || event->kind == EVENT_MOUSE_X2 || event->kind == EVENT_KEY_PRESS || event->kind == EVENT_TEXT_INPUT) {
return true;
}
} else { } else {
return false; return false;
} }
@@ -212,7 +228,7 @@ void TestParser() {
{ {
char *cmd = "ctrl-b"; char *cmd = "ctrl-b";
Lexer base_lex = {scratch, cmd, cmd, cmd + strlen(cmd), "keybinding"}; Lexer base_lex = {scratch, cmd, cmd, cmd + strlen(cmd), "keybinding"};
Trigger *trigger = ParseKeyExpr(&base_lex); Trigger *trigger = ParseKeyCatchAll(&base_lex);
Assert(trigger->kind == TriggerKind_Key); Assert(trigger->kind == TriggerKind_Key);
Assert(trigger->key == SDLK_B); Assert(trigger->key == SDLK_B);
Assert(trigger->ctrl); Assert(trigger->ctrl);
@@ -222,7 +238,7 @@ void TestParser() {
{ {
char *cmd = "ctrl-b shift-ctrl-a"; char *cmd = "ctrl-b shift-ctrl-a";
Lexer base_lex = {scratch, cmd, cmd, cmd + strlen(cmd), "keybinding"}; Lexer base_lex = {scratch, cmd, cmd, cmd + strlen(cmd), "keybinding"};
Trigger *trigger = ParseKeyExpr(&base_lex); Trigger *trigger = ParseKeyCatchAll(&base_lex);
Assert(trigger->kind == TriggerKind_Binary); Assert(trigger->kind == TriggerKind_Binary);
Assert(trigger->key == ' '); Assert(trigger->key == ' ');
Assert(trigger->left->kind == TriggerKind_Key); Assert(trigger->left->kind == TriggerKind_Key);
@@ -238,7 +254,7 @@ void TestParser() {
{ {
char *cmd = "ctrl-b shift-ctrl-a | ctrl-c | ctrl-d"; char *cmd = "ctrl-b shift-ctrl-a | ctrl-c | ctrl-d";
Lexer base_lex = {scratch, cmd, cmd, cmd + strlen(cmd), "keybinding"}; Lexer base_lex = {scratch, cmd, cmd, cmd + strlen(cmd), "keybinding"};
Trigger *trigger = ParseKeyExpr(&base_lex); Trigger *trigger = ParseKeyCatchAll(&base_lex);
Assert(trigger->kind == TriggerKind_Binary); Assert(trigger->kind == TriggerKind_Binary);
Assert(trigger->key == '|'); Assert(trigger->key == '|');

View File

@@ -282,18 +282,12 @@ void OnCommand(Event event) {
} }
} }
if (Ctrl() && Shift() && Mouse(RIGHT)) { if (Ctrl() && Mouse(RIGHT)) {
} else if (Alt() && Ctrl() && Mouse(RIGHT)) {
} else if (Ctrl() && Mouse(RIGHT)) {
} else if (Alt() && Mouse(RIGHT)) {
} else if (Mouse(RIGHT)) {
Vec2I mouse = MouseVec2I(); Vec2I mouse = MouseVec2I();
BSet active = GetBSet(ActiveWindowID); BSet active = GetBSet(ActiveWindowID);
bool mouse_in_document = AreOverlapping(mouse, active.window->document_rect); bool mouse_in_document = AreOverlapping(mouse, active.window->document_rect);
if (mouse_in_document) { if (mouse_in_document) {
Int p = ScreenSpaceToBufferPos(active.window, active.view, active.buffer, mouse); Int p = ScreenSpaceToBufferPos(active.window, active.view, active.buffer, mouse);
Int saved_front = -1; Int saved_front = -1;
IterRemove(active.view->carets) { IterRemove(active.view->carets) {
@@ -315,6 +309,8 @@ void OnCommand(Event event) {
SaveStringInClipboard(string); SaveStringInClipboard(string);
} }
} }
} else if (Mouse(RIGHT)) {
MouseLoadWord(event);
} }
if (Ctrl() && Mouse(LEFT)) { if (Ctrl() && Mouse(LEFT)) {

View File

@@ -178,7 +178,6 @@ struct Register_Variable {
void AddHook(Array<CommandData> *arr, String name, String binding, Function *function); void AddHook(Array<CommandData> *arr, String name, String binding, Function *function);
enum OpenKind { enum OpenKind {
OpenKind_Invalid, OpenKind_Invalid,
OpenKind_Skip, OpenKind_Skip,

View File

@@ -14,28 +14,6 @@ void StatusWindowInit() {
window->layout = false; window->layout = false;
window->jump_history = false; window->jump_history = false;
window->lose_focus_on_escape = true; window->lose_focus_on_escape = true;
AddHook(&view->hooks, "Rename", "ctrl-r", [](){
BSet active = GetBSet(ActiveWindowID);
BSet last = GetBSet(LastActiveLayoutWindowID);
String16 buffer_string = GetString(active.buffer);
Range replace_range = {0, active.buffer->len};
bool found_separator = Seek(buffer_string, u" |", &replace_range.max);
if (!found_separator) {
ReportErrorf("Failed to :Rename, didn't find '|' separator");
return;
}
Scratch scratch;
String16 buffer_name = GetString(active.buffer, replace_range);
String buffer_name8 = ToString(scratch, buffer_name);
ResolvedOpen o = ResolveOpen(scratch, buffer_name8, "dont_error");
if (o.kind != OpenKind_Skip) {
ReportErrorf("%S already exists, either on disk as file or as buffer", buffer_name8);
return;
}
last.buffer->name = Intern(&GlobalInternTable, o.path);
});
} }
void StatusWindowLayout(Rect2I *rect, Int wx, Int wy) { void StatusWindowLayout(Rect2I *rect, Int wx, Int wy) {
@@ -101,7 +79,7 @@ void StatusWindowUpdate() {
// add separator at the end of buffer // add separator at the end of buffer
if (!found_separator) { if (!found_separator) {
SelectRange(title.view, GetBufferEndAsRange(title.buffer)); SelectRange(title.view, GetBufferEndAsRange(title.buffer));
ReplaceEx(scratch, title.view, u" | :Rename"); ReplaceEx(scratch, title.view, u" | :Prev :Next");
} }
// replace data up to separator with filename and stuff // replace data up to separator with filename and stuff