Commands and keybindings

This commit is contained in:
Krzosa Karol
2025-12-16 23:07:16 +01:00
parent 5e7acd4a20
commit 29002c965c
10 changed files with 630 additions and 549 deletions

View File

@@ -38,6 +38,9 @@ Commands TODO:
- Special: non editable, hotkeys don't work etc. - Special: non editable, hotkeys don't work etc.
- I'M SETTING ACTIVE WINDOW AFTER COMMAND!!! DO WE CONTINUE WITH THIS? - I'M SETTING ACTIVE WINDOW AFTER COMMAND!!! DO WE CONTINUE WITH THIS?
- CONSIDER AUTOMATING: CheckpointBeforeGoto
- GotoBackward how to handle that in case we want to automate and create on every move?
## Hooks and bindings ## Hooks and bindings
``` ```
@@ -50,7 +53,8 @@ struct Hook {
void Command_New() { void Command_New() {
... ...
} RegisterCommand(Command_New, "ctrl-n"); } RegisterCommand(Command_New, "ctrl-n", NOT_VISIBLE_IN_LISTING);
// How do we handle Command_Delete variations????
void Hook_FormatOnSave() { void Hook_FormatOnSave() {
} RegisterHook(Hook_FormatOnSave, "onsave"); } RegisterHook(Hook_FormatOnSave, "onsave");

View File

@@ -93,6 +93,16 @@ API Int GetBack(Caret caret) {
return result; return result;
} }
API Int GetMax(Caret caret) {
Int result = Max(caret.pos[0], caret.pos[1]);
return result;
}
API Int GetMin(Caret caret) {
Int result = Min(caret.pos[0], caret.pos[1]);
return result;
}
API Caret MakeCaret(Int pos) { API Caret MakeCaret(Int pos) {
Caret result = {}; Caret result = {};
result.range.min = result.range.max = pos; result.range.min = result.range.max = pos;
@@ -1223,7 +1233,7 @@ API Buffer *CreateTempBuffer(Allocator allocator, Int size = 4096) {
return result; return result;
} }
void RunBufferTest() { void RunBufferTest(void *param) {
{ {
Scratch scratch; Scratch scratch;
Buffer buffer = {}; Buffer buffer = {};

View File

@@ -818,7 +818,7 @@ Caret FindPrev(Buffer *buffer, String16 needle, Caret caret) {
} }
Caret FindNext(Buffer *buffer, String16 needle, Caret caret) { Caret FindNext(Buffer *buffer, String16 needle, Caret caret) {
Int pos = GetFront(caret); Int pos = GetMax(caret);
String16 medium = GetString(buffer, {pos, INT64_MAX}); String16 medium = GetString(buffer, {pos, INT64_MAX});
Caret result = caret; Caret result = caret;
@@ -1077,40 +1077,39 @@ void SetProjectFile(Buffer *buffer) {
LuaProjectBuffer->user_change_id = -1; LuaProjectBuffer->user_change_id = -1;
} }
String16 FetchLoadWord(void) { String16 FetchLoadWord(BSet set) {
BSet active = GetBSet(ActiveWindowID); Caret caret = set.view->carets[0];
Caret caret = active.view->carets[0];
Range range = caret.range; Range range = caret.range;
if (GetSize(caret.range) == 0) range = EncloseLoadWord(active.buffer, GetFront(caret)); if (GetSize(caret.range) == 0) range = EncloseLoadWord(set.buffer, GetFront(caret));
String16 string = GetString(active.buffer, range); String16 string = GetString(set.buffer, range);
return string; return string;
} }
void Command_Save() { void Command_Save(CommandContext *ctx) {
BSet active = GetBSet(LastActiveLayoutWindowID); BSet active = GetBSet(LastActiveLayoutWindowID);
SaveBuffer(active.buffer); SaveBuffer(active.buffer);
} RegisterCommand(Command_Save); } RegisterCommand(Command_Save, "ctrl-s");
void Command_SaveAll() { void Command_SaveAll(CommandContext *ctx) {
For(Buffers) { For(Buffers) {
if (it->file_mod_time) { if (it->file_mod_time) {
SaveBuffer(it); SaveBuffer(it);
} }
} }
} RegisterCommand(Command_SaveAll); } RegisterCommand(Command_SaveAll, "ctrl-shift-s");
void Command_Reopen() { void Command_Reopen(CommandContext *ctx) {
BSet main = GetBSet(LastActiveLayoutWindowID); BSet main = GetBSet(LastActiveLayoutWindowID);
ReopenBuffer(main.buffer); ReopenBuffer(main.buffer);
ActiveWindowID = main.window->id; ActiveWindowID = main.window->id;
} RegisterCommand(Command_Reopen); } RegisterCommand(Command_Reopen, "");
void Command_New() { void Command_New(CommandContext *ctx) {
BSet main = GetBSet(LastActiveLayoutWindowID); BSet main = GetBSet(LastActiveLayoutWindowID);
New(main.window, ""); New(main.window, "");
} RegisterCommand(Command_New); } RegisterCommand(Command_New, "ctrl-n");
void Command_ToggleFullscreen() { void Command_ToggleFullscreen(CommandContext *ctx) {
if (IsInFullscreen) { if (IsInFullscreen) {
SDL_SetWindowSize(SDLWindow, FullScreenSizeX, FullScreenSizeY); SDL_SetWindowSize(SDLWindow, FullScreenSizeX, FullScreenSizeY);
SDL_SetWindowPosition(SDLWindow, FullScreenPositionX, FullScreenPositionY); SDL_SetWindowPosition(SDLWindow, FullScreenPositionX, FullScreenPositionY);
@@ -1125,18 +1124,18 @@ void Command_ToggleFullscreen() {
} }
IsInFullscreen = !IsInFullscreen; IsInFullscreen = !IsInFullscreen;
} RegisterCommand(Command_ToggleFullscreen); } RegisterCommand(Command_ToggleFullscreen, "f11");
void Command_ListCode() { void Command_ListCode(CommandContext *ctx) {
BSet main = GetBSet(LastActiveLayoutWindowID); BSet main = GetBSet(LastActiveLayoutWindowID);
JumpGarbageBuffer(&main); JumpGarbageBuffer(&main);
ListFilesRecursive(main.buffer, WorkDir); ListFilesRecursive(main.buffer, WorkDir);
main.view->fuzzy_search = true; main.view->fuzzy_search = true;
main.view->update_scroll = true; main.view->update_scroll = true;
SelectRange(main.view, GetBufferEndAsRange(main.buffer)); SelectRange(main.view, GetBufferEndAsRange(main.buffer));
} RegisterCommand(Command_ListCode); } RegisterCommand(Command_ListCode, "");
void Command_ShowBufferList() { void Command_ShowBufferList(CommandContext *ctx) {
BSet command_bar = GetBSet(CommandBarWindowID); BSet command_bar = GetBSet(CommandBarWindowID);
command_bar.window->visible = true; command_bar.window->visible = true;
command_bar.window->eval_command = false; command_bar.window->eval_command = false;
@@ -1147,22 +1146,9 @@ void Command_ShowBufferList() {
} }
command_bar.view->update_scroll = true; command_bar.view->update_scroll = true;
SelectRange(command_bar.view, GetBufferEndAsRange(command_bar.buffer)); SelectRange(command_bar.view, GetBufferEndAsRange(command_bar.buffer));
} RegisterCommand(Command_ShowBufferList); } RegisterCommand(Command_ShowBufferList, "ctrl-p");
void Command_ShowCommandList() { void Command_ListViews(CommandContext *ctx) {
BSet command_bar = GetBSet(CommandBarWindowID);
command_bar.window->visible = true;
command_bar.window->eval_command = false;
ActiveWindowID = command_bar.window->id;
ResetBuffer(command_bar.buffer);
For(LuaFunctions) {
Appendf(command_bar.view, "%S()\n ", it.name);
}
command_bar.view->update_scroll = true;
SelectRange(command_bar.view, GetBufferEndAsRange(command_bar.buffer));
} RegisterCommand(Command_ShowCommandList);
void Command_ListViews() {
BSet command_bar = GetBSet(CommandBarWindowID); BSet command_bar = GetBSet(CommandBarWindowID);
command_bar.window->visible = true; command_bar.window->visible = true;
command_bar.window->eval_command = false; command_bar.window->eval_command = false;
@@ -1175,14 +1161,14 @@ void Command_ListViews() {
command_bar.view->fuzzy_search = true; command_bar.view->fuzzy_search = true;
command_bar.view->update_scroll = true; command_bar.view->update_scroll = true;
SelectRange(command_bar.view, GetBufferEndAsRange(command_bar.buffer)); SelectRange(command_bar.view, GetBufferEndAsRange(command_bar.buffer));
} RegisterCommand(Command_ListViews); } RegisterCommand(Command_ListViews, "");
void Command_SetProjectFile() { void Command_SetProjectFile(CommandContext *ctx) {
BSet main = GetBSet(LastActiveLayoutWindowID); BSet main = GetBSet(LastActiveLayoutWindowID);
SetProjectFile(main.buffer); SetProjectFile(main.buffer);
} RegisterCommand(Command_SetProjectFile); } RegisterCommand(Command_SetProjectFile, "");
void Command_SetWorkDir() { void Command_SetWorkDir(CommandContext *ctx) {
String dir = lua_tostring(LuaState, -1); String dir = lua_tostring(LuaState, -1);
if (dir.len == 0) { if (dir.len == 0) {
BSet main = GetBSet(LastActiveLayoutWindowID); BSet main = GetBSet(LastActiveLayoutWindowID);
@@ -1190,29 +1176,29 @@ void Command_SetWorkDir() {
} else { } else {
WorkDir = dir; WorkDir = dir;
} }
} } RegisterCommand(Command_SetWorkDir, "");
void Command_SetProject() { void Command_SetProject(CommandContext *ctx) {
Command_SetWorkDir(); Command_SetWorkDir(ctx);
Command_SetProjectFile(); Command_SetProjectFile(ctx);
} RegisterCommand(Command_SetProject); } RegisterCommand(Command_SetProject, "");
void Command_ToggleDebug() { void Command_ToggleDebug(CommandContext *ctx) {
Window *window = GetWindow(DebugWindowID); Window *window = GetWindow(DebugWindowID);
window->visible = !window->visible; window->visible = !window->visible;
} RegisterCommand(Command_ToggleDebug); } RegisterCommand(Command_ToggleDebug, "ctrl-0");
void Command_KillProcess() { void Command_KillProcess(CommandContext *ctx) {
BSet main = GetBSet(LastActiveLayoutWindowID); BSet main = GetBSet(LastActiveLayoutWindowID);
KillProcess(main.view); KillProcess(main.view);
} RegisterCommand(Command_KillProcess); } RegisterCommand(Command_KillProcess, "");
void Command_KillWindow() { void Command_KillWindow(CommandContext *ctx) {
BSet main = GetBSet(LastActiveLayoutWindowID); BSet main = GetBSet(LastActiveLayoutWindowID);
main.window->kill = true; main.window->kill = true;
} RegisterCommand(Command_KillWindow); } RegisterCommand(Command_KillWindow, "ctrl-w");
void Command_ShowCommands() { void Command_ShowCommands(CommandContext *ctx) {
BSet command_bar = GetBSet(CommandBarWindowID); BSet command_bar = GetBSet(CommandBarWindowID);
command_bar.window->visible = true; command_bar.window->visible = true;
command_bar.window->eval_command = true; command_bar.window->eval_command = true;
@@ -1223,4 +1209,402 @@ void Command_ShowCommands() {
} }
command_bar.view->update_scroll = true; command_bar.view->update_scroll = true;
SelectRange(command_bar.view, GetBufferEndAsRange(command_bar.buffer)); SelectRange(command_bar.view, GetBufferEndAsRange(command_bar.buffer));
} RegisterCommand(Command_ShowCommands); } RegisterCommand(Command_ShowCommands, "ctrl-shift-p");
void Command_ShowLuaFunctions(CommandContext *ctx) {
BSet command_bar = GetBSet(CommandBarWindowID);
command_bar.window->visible = true;
command_bar.window->eval_command = false;
ActiveWindowID = command_bar.window->id;
ResetBuffer(command_bar.buffer);
For(LuaFunctions) {
Appendf(command_bar.view, "%S()\n ", it.name);
}
command_bar.view->update_scroll = true;
SelectRange(command_bar.view, GetBufferEndAsRange(command_bar.buffer));
} RegisterCommand(Command_ShowLuaFunctions, "");
void Command_GotoBackward(CommandContext *ctx) {
BSet main = GetBSet(LastActiveLayoutWindowID);
GotoBackward(main.window);
} RegisterCommand(Command_GotoBackward, "alt-q | mousex1");
void Command_GotoForward(CommandContext *ctx) {
BSet main = GetBSet(LastActiveLayoutWindowID);
GotoForward(main.window);
} RegisterCommand(Command_GotoForward, "mousex2");
void Command_OpenUpFolder(CommandContext *ctx) {
BSet main = GetBSet(LastActiveLayoutWindowID);
String name = ChopLastSlash(main.buffer->name);
if (EndsWith(main.buffer->name, "dirlisting")) {
name = ChopLastSlash(name);
}
Open(name);
} RegisterCommand(Command_OpenUpFolder, "ctrl-period");
void Command_EncloseLine(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
EncloseLine(active.view);
} RegisterCommand(Command_EncloseLine, "ctrl-l");
void Command_SelectAll(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
SelectEntireBuffer(active.view);
active.view->update_scroll = false;
} RegisterCommand(Command_SelectAll, "ctrl-a");
void Command_Redo(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
RedoEdit(active.buffer, &active.view->carets);
} RegisterCommand(Command_Redo, "ctrl-shift-z");
void Command_Undo(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
UndoEdit(active.buffer, &active.view->carets);
} RegisterCommand(Command_Undo, "ctrl-z");
void Command_MakeFontLarger(CommandContext *ctx) {
StyleFontSize += 1;
ReloadFont(StyleFont, (U32)StyleFontSize);
} RegisterCommand(Command_MakeFontLarger, "ctrl-equals");
void Command_MakeFontSmaller(CommandContext *ctx) {
if (StyleFontSize > 4) {
StyleFontSize -= 1;
ReloadFont(StyleFont, (U32)StyleFontSize);
}
} RegisterCommand(Command_MakeFontSmaller, "ctrl-minus");
void Command_Search(CommandContext *ctx) {
Window *window = GetWindow(SearchBarWindowID);
window->visible = !window->visible;
} RegisterCommand(Command_Search, "ctrl-f");
void EvalCommand(CommandContext *ctx, String command) {
For (CommandFunctions) {
if (it.name == command) {
it.function(ctx);
break;
}
}
}
void EvalCommand(CommandContext *ctx, String16 command) {
Scratch scratch;
EvalCommand(ctx, ToString(scratch, command));
}
void FuzzySearchOpen(CommandContext *ctx, BSet active) {
Range range = active.view->carets[0].range;
String16 string = FetchLoadWord(active);
if (GetSize(range) == 0) {
Int line = PosToLine(active.buffer, range.min);
if ((active.buffer->line_starts.len - 1) == line) {
line = ClampBottom(0ll, line - 1ll);
}
string = GetLineStringWithoutNL(active.buffer, line);
Int idx = 0;
if (Seek(string, u"||", &idx)) {
string = Skip(string, idx + 3);
}
}
if (active.window->eval_command) {
BSet main = GetBSet(LastActiveLayoutWindowID);
ActiveWindowID = main.window->id;
EvalCommand(ctx, string);
} else {
Open(string);
}
}
void Command_Open(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
if (active.view->fuzzy_search) {
FuzzySearchOpen(ctx, active);
} else {
BSet active = GetBSet(LastActiveLayoutWindowID);
Open(FetchLoadWord(active));
}
} RegisterCommand(Command_Open, "ctrl-q");
void Command_KillSelectedLines(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
KillSelectedLines(active.view);
} RegisterCommand(Command_KillSelectedLines, "ctrl-shift-k");
void Command_IndentSelectedLines(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
Event event = *OnCommandEvent;
bool left = false;
if (Press(SDLK_LEFTBRACKET) || ShiftPress(SDLK_TAB)) {
left = true;
}
IndentSelectedLines(active.view, left);
} RegisterCommand(Command_IndentSelectedLines, "ctrl-leftbracket | ctrl-rightbracket | tab | shift-tab");
void Command_DuplicateLineDown(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
DuplicateLine(active.view, DIR_DOWN);
} RegisterCommand(Command_DuplicateLineDown, "ctrl-alt-down");
void Command_CreateCursorDown(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
CreateCursorVertical(active.view, DIR_DOWN);
} RegisterCommand(Command_CreateCursorDown, "alt-shift-down");
void Command_SelectDownToEmptyLine(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_DOWN, CTRL_PRESSED, SHIFT_PRESS);
} RegisterCommand(Command_SelectDownToEmptyLine, "ctrl-shift-down");
void Command_MoveLineDown(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCaretsLine(active.view, DIR_DOWN);
} RegisterCommand(Command_MoveLineDown, "alt-down");
void Command_MoveDownToEmptyLine(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_DOWN, CTRL_PRESSED);
} RegisterCommand(Command_MoveDownToEmptyLine, "ctrl-down");
void Command_SelectDown(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_DOWN, false, SHIFT_PRESS);
} RegisterCommand(Command_SelectDown, "shift-down");
void Command_MoveDown(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_DOWN);
} RegisterCommand(Command_MoveDown, "down");
void Command_DuplicateLineUp(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
DuplicateLine(active.view, DIR_UP);
} RegisterCommand(Command_DuplicateLineUp, "ctrl-alt-up");
void Command_CreateCursorUp(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
CreateCursorVertical(active.view, DIR_UP);
} RegisterCommand(Command_CreateCursorUp, "alt-shift-up");
void Command_SelectUpToEmptyLine(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_UP, CTRL_PRESSED, SHIFT_PRESS);
} RegisterCommand(Command_SelectUpToEmptyLine, "ctrl-shift-up");
void Command_MoveLineUp(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCaretsLine(active.view, DIR_UP);
} RegisterCommand(Command_MoveLineUp, "alt-up");
void Command_MoveUpToEmptyLine(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_UP, CTRL_PRESSED);
} RegisterCommand(Command_MoveUpToEmptyLine, "ctrl-up");
void Command_SelectUp(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_UP, false, SHIFT_PRESS);
} RegisterCommand(Command_SelectUp, "shift-up");
void Command_MoveUp(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_UP);
} RegisterCommand(Command_MoveUp, "up");
void Command_BoundarySelectLeft(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_LEFT, CTRL_PRESSED, SHIFT_PRESS);
} RegisterCommand(Command_BoundarySelectLeft, "ctrl-shift-left");
void Command_BoundaryMoveLeft(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_LEFT, CTRL_PRESSED);
} RegisterCommand(Command_BoundaryMoveLeft, "ctrl-left");
void Command_SelectLeft(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_LEFT, false, SHIFT_PRESS);
} RegisterCommand(Command_SelectLeft, "shift-left");
void Command_FocusLeftWindow(CommandContext *ctx) {
ActiveWindowID = SwitchWindow(DIR_LEFT)->id;
} RegisterCommand(Command_FocusLeftWindow, "alt-left");
void Command_MoveLeft(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_LEFT);
} RegisterCommand(Command_MoveLeft, "left");
void Command_BoundarySelectRight(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_RIGHT, CTRL_PRESSED, SHIFT_PRESS);
} RegisterCommand(Command_BoundarySelectRight, "ctrl-shift-right");
void Command_BoundaryMoveRight(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_RIGHT, CTRL_PRESSED);
} RegisterCommand(Command_BoundaryMoveRight, "ctrl-right");
void Command_SelectRight(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_RIGHT, false, SHIFT_PRESS);
} RegisterCommand(Command_SelectRight, "shift-right");
void Command_FocusRightWindow(CommandContext *ctx) {
ActiveWindowID = SwitchWindow(DIR_RIGHT)->id;
} RegisterCommand(Command_FocusRightWindow, "alt-right");
void Command_MoveRight(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_RIGHT);
} RegisterCommand(Command_MoveRight, "right");
void Command_MoveUpAPage(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCursorByPageSize(active.window, DIR_UP, SHIFT_PRESS);
} RegisterCommand(Command_MoveUpAPage, "pageup");
void Command_SelectDownPage(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCursorByPageSize(active.window, DIR_DOWN, SHIFT_PRESS);
} RegisterCommand(Command_SelectDownPage, "shift-pagedown");
void Command_MoveToEnd(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
SelectRange(active.view, MakeRange(active.buffer->len));
} RegisterCommand(Command_MoveToEnd, "pagedown");
void Command_MoveDownPage(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
SelectRange(active.view, MakeRange(active.buffer->len));
} RegisterCommand(Command_MoveDownPage, "ctrl-pagedown");
void Command_SelectUpPage(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCursorByPageSize(active.window, DIR_UP, SHIFT_PRESS);
} RegisterCommand(Command_SelectUpPage, "shift-pageup");
void Command_MoveToStart(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
SelectRange(active.view, MakeRange(0));
} RegisterCommand(Command_MoveToStart, "ctrl-pageup");
void Command_MoveUpPage(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCursorByPageSize(active.window, DIR_UP);
} RegisterCommand(Command_MoveUpPage, "pageup");
void Command_SelectToLineStart(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCursorToSide(active.view, DIR_LEFT, SHIFT_PRESS);
} RegisterCommand(Command_SelectToLineStart, "shift-home");
void Command_MoveToLineStart(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCursorToSide(active.view, DIR_LEFT);
} RegisterCommand(Command_MoveToLineStart, "home");
void Command_MoveToLineEnd(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCursorToSide(active.view, DIR_RIGHT);
} RegisterCommand(Command_MoveToLineEnd, "end");
void Command_SelectToLineEnd(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCursorToSide(active.view, DIR_RIGHT, SHIFT_PRESS);
} RegisterCommand(Command_SelectToLineEnd, "shift-end");
void Command_Delete(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
Delete(active.view, DIR_LEFT);
} RegisterCommand(Command_Delete, "backspace");
void Command_DeleteBoundary(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
Delete(active.view, DIR_LEFT, SHIFT_PRESS);
} RegisterCommand(Command_DeleteBoundary, "ctrl-backspace");
void Command_DeleteForward(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
Delete(active.view, DIR_RIGHT);
} RegisterCommand(Command_DeleteForward, "delete");
void Command_DeleteForwardBoundary(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
Delete(active.view, DIR_RIGHT, SHIFT_PRESS);
} RegisterCommand(Command_DeleteForwardBoundary, "ctrl-delete");
void Command_InsertNewLineUp(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCursorToSide(active.view, DIR_LEFT);
IdentedNewLine(active.view);
MoveCarets(active.view, DIR_UP);
} RegisterCommand(Command_InsertNewLineUp, "ctrl-shift-enter");
void Command_InsertNewLineDown(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
MoveCursorToSide(active.view, DIR_RIGHT);
IdentedNewLine(active.view);
} RegisterCommand(Command_InsertNewLineDown, "ctrl-enter");
void Command_SelectFuzzySearchEntry(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
if (active.view->fuzzy_search) {
FuzzySearchOpen(ctx, active);
ctx->out_skip_rem_cmds = true;
}
} RegisterCommand(Command_SelectFuzzySearchEntry, "enter");
void Command_NewLine(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
IdentedNewLine(active.view);
} RegisterCommand(Command_NewLine, "enter");
void Command_CreateCaretOnNextFind(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
String16 string = GetString(active.buffer, active.view->carets[0].range);
Caret caret = FindNext(active.buffer, string, active.view->carets[0]);
Insert(&active.view->carets, caret, 0);
MergeCarets(active.buffer, &active.view->carets);
} RegisterCommand(Command_CreateCaretOnNextFind, "ctrl-d");
void Command_FocusWindow1(CommandContext *ctx) {
ActiveWindowID = GetOverlappingWindow({0,0}, GetWindow(ActiveWindowID))->id;
} RegisterCommand(Command_FocusWindow1, "ctrl-1");
void Command_FocusWindow2(CommandContext *ctx) {
Window *first = GetOverlappingWindow({0,0}, GetWindow(ActiveWindowID));
Vec2I p = GetSideOfWindow(first, DIR_RIGHT);
ActiveWindowID = GetOverlappingWindow(p, GetWindow(ActiveWindowID))->id;
} RegisterCommand(Command_FocusWindow2, "ctrl-2");
void Command_FocusWindow3(CommandContext *ctx) {
Window *first = GetOverlappingWindow({0,0});
if (first) {
Window *second = GetOverlappingWindow(GetSideOfWindow(first, DIR_RIGHT));
if (second) {
Window *third = GetOverlappingWindow(GetSideOfWindow(second, DIR_RIGHT));
if (third) {
ActiveWindowID = third->id;
}
}
}
} RegisterCommand(Command_FocusWindow3, "ctrl-3");
void Command_ClearCarets(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
active.view->carets.len = 1;
active.view->carets[0] = MakeCaret(GetFront(active.view->carets[0]));
// @todo: move to hook post command???
if (active.window->lose_focus_on_escape && active.window->id == ActiveWindowID) {
if (active.window->layout) {
//
} else {
ActiveWindowID = LastActiveLayoutWindowID;
}
}
} RegisterCommand(Command_ClearCarets, "escape");

View File

@@ -46,44 +46,6 @@ void UpdateScroll(Window *window, bool update_caret_scrolling) {
} }
} }
void EvalCommand(String command) {
For (CommandFunctions) {
if (it.name == command) {
it.function();
break;
}
}
}
void EvalCommand(String16 command) {
Scratch scratch;
EvalCommand(ToString(scratch, command));
}
void FuzzySearchOpen(BSet active) {
Range range = active.view->carets[0].range;
String16 string = FetchLoadWord();
if (GetSize(range) == 0) {
Int line = PosToLine(active.buffer, range.min);
if ((active.buffer->line_starts.len - 1) == line) {
line = ClampBottom(0ll, line - 1ll);
}
string = GetLineStringWithoutNL(active.buffer, line);
Int idx = 0;
if (Seek(string, u"||", &idx)) {
string = Skip(string, idx + 3);
}
}
if (active.window->eval_command) {
BSet main = GetBSet(LastActiveLayoutWindowID);
ActiveWindowID = main.window->id;
EvalCommand(string);
} else {
Open(string);
}
}
void OnCommand(Event event) { void OnCommand(Event event) {
ProfileFunction(); ProfileFunction();
// //
@@ -304,227 +266,28 @@ void OnCommand(Event event) {
} }
} }
if (Mouse(X2)) { BSet main = GetBSet(LastActiveLayoutWindowID);
BSet main = GetBSet(LastActiveLayoutWindowID); BSet active = GetBSet(ActiveWindowID);
GotoForward(main.window); Int buffer_change_id = active.buffer->change_id;
} CommandContext ctx = {};
if (Mouse(X1)) { For (CommandFunctions) {
BSet main = GetBSet(LastActiveLayoutWindowID); if (it.trigger && MatchEvent(it.trigger, &event)) {
GotoBackward(main.window); it.function(&ctx);
} MergeCarets(active.buffer, &active.view->carets);
IF_DEBUG(AssertRanges(active.view->carets));
if (CtrlPress(SDLK_W)) { if (ctx.out_skip_rem_cmds) {
Command_KillWindow(); return;
}
if (CtrlAltPress(SDLK_P)) {
} else if (CtrlShiftPress(SDLK_P)) {
Command_ShowCommands();
} else if (CtrlPress(SDLK_P)) {
Command_ShowBufferList();
}
if (CtrlPress(SDLK_0)) {
Command_ToggleDebug();
}
if (CtrlPress(SDLK_1)) {
ActiveWindowID = GetOverlappingWindow({0,0}, GetWindow(ActiveWindowID))->id;
}
if (CtrlPress(SDLK_2)) {
Window *first = GetOverlappingWindow({0,0}, GetWindow(ActiveWindowID));
Vec2I p = GetSideOfWindow(first, DIR_RIGHT);
ActiveWindowID = GetOverlappingWindow(p, GetWindow(ActiveWindowID))->id;
}
if (CtrlPress(SDLK_3)) {
Window *first = GetOverlappingWindow({0,0});
if (first) {
Window *second = GetOverlappingWindow(GetSideOfWindow(first, DIR_RIGHT));
if (second) {
Window *third = GetOverlappingWindow(GetSideOfWindow(second, DIR_RIGHT));
if (third) {
ActiveWindowID = third->id;
}
} }
} }
} }
BSet main = GetBSet(LastActiveLayoutWindowID); // @todo: do we need the context for commands, maybe skip cmds should be global?
BSet active = GetBSet(ActiveWindowID); // @todo: hook drop file
Int buffer_change_id = active.buffer->change_id;
bool skip = CallOnCommand(&event);
if (skip) {
// :OnCommandEnding
MergeCarets(active.buffer, &active.view->carets);
IF_DEBUG(AssertRanges(active.view->carets));
return;
}
if (active.view->fuzzy_search) {
if (Press(SDLK_RETURN)) {
FuzzySearchOpen(active);
// :OnCommandEnding
MergeCarets(active.buffer, &active.view->carets);
IF_DEBUG(AssertRanges(active.view->carets));
return;
}
}
if (event.kind == EVENT_DROP_FILE) { if (event.kind == EVENT_DROP_FILE) {
WindowOpenBufferView(active.window, event.text); WindowOpenBufferView(active.window, event.text);
} }
if (Press(SDLK_DOWN) || Press(SDLK_RIGHT) || Press(SDLK_LEFT) || Press(SDLK_UP)) { // @todo: hook on textinput
CheckpointBeforeGoto(active.window);
}
if (CtrlAltPress(SDLK_DOWN)) {
DuplicateLine(active.view, DIR_DOWN);
} else if (AltShiftPress(SDLK_DOWN)) {
CreateCursorVertical(active.view, DIR_DOWN);
} else if (CtrlShiftPress(SDLK_DOWN)) {
MoveCarets(active.view, DIR_DOWN, CTRL_PRESSED, SHIFT_PRESS);
} else if (AltPress(SDLK_DOWN)) {
MoveCaretsLine(active.view, DIR_DOWN);
} else if (CtrlPress(SDLK_DOWN)) {
MoveCarets(active.view, DIR_DOWN, CTRL_PRESSED);
} else if (ShiftPress(SDLK_DOWN)) {
MoveCarets(active.view, DIR_DOWN, false, SHIFT_PRESS);
} else if (Press(SDLK_DOWN)) {
MoveCarets(active.view, DIR_DOWN);
}
if (CtrlAltPress(SDLK_UP)) {
DuplicateLine(active.view, DIR_UP);
} else if (AltShiftPress(SDLK_UP)) {
CreateCursorVertical(active.view, DIR_UP);
} else if (CtrlShiftPress(SDLK_UP)) {
MoveCarets(active.view, DIR_UP, CTRL_PRESSED, SHIFT_PRESS);
} else if (AltPress(SDLK_UP)) {
MoveCaretsLine(active.view, DIR_UP);
} else if (CtrlPress(SDLK_UP)) {
MoveCarets(active.view, DIR_UP, CTRL_PRESSED);
} else if (ShiftPress(SDLK_UP)) {
MoveCarets(active.view, DIR_UP, false, SHIFT_PRESS);
} else if (Press(SDLK_UP)) {
MoveCarets(active.view, DIR_UP);
}
if (CtrlShiftPress(SDLK_LEFT)) {
MoveCarets(active.view, DIR_LEFT, CTRL_PRESSED, SHIFT_PRESS);
} else if (CtrlPress(SDLK_LEFT)) {
MoveCarets(active.view, DIR_LEFT, CTRL_PRESSED);
} else if (ShiftPress(SDLK_LEFT)) {
MoveCarets(active.view, DIR_LEFT, false, SHIFT_PRESS);
} else if (AltPress(SDLK_LEFT)) {
ActiveWindowID = SwitchWindow(DIR_LEFT)->id;
} else if (Press(SDLK_LEFT)) {
MoveCarets(active.view, DIR_LEFT);
}
if (CtrlShiftPress(SDLK_RIGHT)) {
MoveCarets(active.view, DIR_RIGHT, CTRL_PRESSED, SHIFT_PRESS);
} else if (CtrlPress(SDLK_RIGHT)) {
MoveCarets(active.view, DIR_RIGHT, CTRL_PRESSED);
} else if (ShiftPress(SDLK_RIGHT)) {
MoveCarets(active.view, DIR_RIGHT, false, SHIFT_PRESS);
} else if (AltPress(SDLK_RIGHT)) {
ActiveWindowID = SwitchWindow(DIR_RIGHT)->id;
} else if (Press(SDLK_RIGHT)) {
MoveCarets(active.view, DIR_RIGHT);
}
if (CtrlShiftPress(SDLK_Z)) {
RedoEdit(active.buffer, &active.view->carets);
} else if (CtrlPress(SDLK_Z)) {
UndoEdit(active.buffer, &active.view->carets);
}
if (CtrlPress(SDLK_C)) {
ClipboardCopy(active.view);
} else if (CtrlPress(SDLK_V)) {
ClipboardPaste(active.view);
} else if (CtrlPress(SDLK_X)) {
SaveCaretHistoryBeforeBeginEdit(active.buffer, active.view->carets);
ClipboardCopy(active.view);
Replace(active.view, u"");
}
if (CtrlPress(SDLK_A)) {
SelectEntireBuffer(active.view);
active.view->update_scroll = false;
}
if (ShiftPress(SDLK_PAGEUP)) {
CheckpointBeforeGoto(active.window);
MoveCursorByPageSize(active.window, DIR_UP, SHIFT_PRESS);
} else if (CtrlPress(SDLK_PAGEUP)) {
CheckpointBeforeGoto(active.window);
SelectRange(active.view, MakeRange(0));
} else if (Press(SDLK_PAGEUP)) {
CheckpointBeforeGoto(active.window);
MoveCursorByPageSize(active.window, DIR_UP);
}
if (ShiftPress(SDLK_PAGEDOWN)) {
CheckpointBeforeGoto(active.window);
MoveCursorByPageSize(active.window, DIR_DOWN, SHIFT_PRESS);
} else if (CtrlPress(SDLK_PAGEDOWN)) {
CheckpointBeforeGoto(active.window);
SelectRange(active.view, MakeRange(active.buffer->len));
} else if (Press(SDLK_PAGEDOWN)) {
CheckpointBeforeGoto(active.window);
MoveCursorByPageSize(active.window, DIR_DOWN);
}
if (ShiftPress(SDLK_HOME)) {
CheckpointBeforeGoto(active.window);
MoveCursorToSide(active.view, DIR_LEFT, SHIFT_PRESS);
} else if (Press(SDLK_HOME)) {
CheckpointBeforeGoto(active.window);
MoveCursorToSide(active.view, DIR_LEFT);
}
if (ShiftPress(SDLK_END)) {
CheckpointBeforeGoto(active.window);
MoveCursorToSide(active.view, DIR_RIGHT, SHIFT_PRESS);
} else if (Press(SDLK_END)) {
CheckpointBeforeGoto(active.window);
MoveCursorToSide(active.view, DIR_RIGHT);
}
if (CtrlShiftPress(SDLK_TAB)) {
} else if (ShiftPress(SDLK_TAB)) {
IndentSelectedLines(active.view, SHIFT_PRESS);
} else if (CtrlPress(SDLK_TAB)) {
} else if (Press(SDLK_TAB)) {
IndentSelectedLines(active.view);
}
if (CtrlPress(SDLK_LEFTBRACKET)) {
IndentSelectedLines(active.view, SHIFT_PRESS);
}
if (CtrlPress(SDLK_RIGHTBRACKET)) {
IndentSelectedLines(active.view);
}
if (CtrlShiftPress(SDLK_K)) {
KillSelectedLines(active.view);
}
if (CtrlPress(SDLK_BACKSPACE)) {
Delete(active.view, DIR_LEFT, CTRL_PRESSED);
} else if (Press(SDLK_BACKSPACE)) {
Delete(active.view, DIR_LEFT);
}
if (CtrlPress(SDLK_DELETE)) {
Delete(active.view, DIR_RIGHT, CTRL_PRESSED);
} else if (Press(SDLK_DELETE)) {
Delete(active.view, DIR_RIGHT);
}
if (event.kind == EVENT_TEXT_INPUT) { if (event.kind == EVENT_TEXT_INPUT) {
Scratch scratch; Scratch scratch;
String string = event.text; String string = event.text;
@@ -532,41 +295,8 @@ void OnCommand(Event event) {
Replace(active.view, string16); Replace(active.view, string16);
} }
if (CtrlPress(SDLK_D)) { // @todo: hook PostCommand?
CheckpointBeforeGoto(active.window); // @todo: Detect if edited
String16 string = GetString(active.buffer, active.view->carets[0].range);
Caret caret = FindNext(active.buffer, string, active.view->carets[0]);
Insert(&active.view->carets, caret, 0);
MergeCarets(active.buffer, &active.view->carets);
}
if (CtrlPress(SDLK_EQUALS)) {
StyleFontSize += 1;
ReloadFont(StyleFont, (U32)StyleFontSize);
}
if (CtrlPress(SDLK_MINUS)) {
if (StyleFontSize > 4) {
StyleFontSize -= 1;
ReloadFont(StyleFont, (U32)StyleFontSize);
}
}
if (CtrlPress(SDLK_E)) {
} else if (AltPress(SDLK_E)) {
}
if (CtrlShiftPress(SDLK_RETURN)) {
MoveCursorToSide(active.view, DIR_LEFT);
IdentedNewLine(active.view);
MoveCarets(active.view, DIR_UP);
} else if (CtrlPress(SDLK_RETURN)) {
MoveCursorToSide(active.view, DIR_RIGHT);
IdentedNewLine(active.view);
} else if (Press(SDLK_RETURN)) {
IdentedNewLine(active.view);
}
if (active.view->fuzzy_search) { if (active.view->fuzzy_search) {
if (!ProcessIsActive(active.view->id)) { if (!ProcessIsActive(active.view->id)) {
Scratch scratch; Scratch scratch;
@@ -593,64 +323,6 @@ void OnCommand(Event event) {
} }
} }
if (CtrlPress(SDLK_F)) {
Window *window = GetWindow(SearchBarWindowID);
window->visible = !window->visible;
}
if (CtrlPress(SDLK_S)) {
SaveBuffer(active.buffer);
}
if (CtrlPress(SDLK_PERIOD)) {
String name = ChopLastSlash(main.buffer->name);
if (EndsWith(main.buffer->name, "dirlisting")) {
name = ChopLastSlash(name);
}
Open(name);
}
if (CtrlShiftPress(SDLK_L)) {
EncloseSpace(active.view);
} else if (CtrlPress(SDLK_L)) {
EncloseLine(active.view);
}
if (CtrlShiftPress(SDLK_G)) {
} else if (CtrlPress(SDLK_G)) {
}
if (AltPress(SDLK_Q)) {
GotoBackward(main.window);
}
if (CtrlPress(SDLK_Q)) {
if (active.view->fuzzy_search) {
FuzzySearchOpen(active);
// :OnCommandEnding
MergeCarets(active.buffer, &active.view->carets);
IF_DEBUG(AssertRanges(active.view->carets));
return;
} else {
Open(FetchLoadWord());
}
}
if (Press(SDLK_ESCAPE)) {
active.view->carets.len = 1;
active.view->carets[0] = MakeCaret(GetFront(active.view->carets[0]));
if (active.window->lose_focus_on_escape && active.window->id == ActiveWindowID) {
if (active.window->layout) {
//
} else {
ActiveWindowID = LastActiveLayoutWindowID;
}
}
}
// :OnCommandEnding // :OnCommandEnding
MergeCarets(active.buffer, &active.view->carets); MergeCarets(active.buffer, &active.view->carets);
IF_DEBUG(AssertRanges(active.view->carets)); IF_DEBUG(AssertRanges(active.view->carets));

View File

@@ -86,3 +86,20 @@ void ClipboardPaste(View *view) {
} }
EndEdit(buffer, &edits, &view->carets, KILL_SELECTION); EndEdit(buffer, &edits, &view->carets, KILL_SELECTION);
} }
void Command_Paste(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
ClipboardPaste(active.view);
} RegisterCommand(Command_Paste, "ctrl-v");
void Command_Copy(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
ClipboardCopy(active.view);
} RegisterCommand(Command_Copy, "ctrl-c");
void Command_Cut(CommandContext *ctx) {
BSet active = GetBSet(ActiveWindowID);
SaveCaretHistoryBeforeBeginEdit(active.buffer, active.view->carets);
ClipboardCopy(active.view);
Replace(active.view, u"");
} RegisterCommand(Command_Cut, "ctrl-x");

View File

@@ -260,87 +260,91 @@ const char *SDLKeycodeToName(SDL_Keycode keycode) {
} }
} }
SDL_Keycode NameToSDLKeycode(String name) { struct { String string; EventKind value; } MouseConversionTable[] = {
if (name == "enter") return SDLK_RETURN; {"mousex1", EVENT_MOUSE_X1},
if (name == "escape") return SDLK_ESCAPE; {"mousex2", EVENT_MOUSE_X2},
if (name == "backspace") return SDLK_BACKSPACE; {"mouseleft", EVENT_MOUSE_LEFT},
if (name == "tab") return SDLK_TAB; {"mouseright", EVENT_MOUSE_RIGHT},
if (name == "space") return SDLK_SPACE; {"mousemiddle", EVENT_MOUSE_MIDDLE},
if (name == "-") return SDLK_MINUS; };
if (name == ".") return SDLK_PERIOD;
if (name == "/") return SDLK_SLASH;
if (name == "0") return SDLK_0;
if (name == "1") return SDLK_1;
if (name == "2") return SDLK_2;
if (name == "3") return SDLK_3;
if (name == "4") return SDLK_4;
if (name == "5") return SDLK_5;
if (name == "6") return SDLK_6;
if (name == "7") return SDLK_7;
if (name == "8") return SDLK_8;
if (name == "9") return SDLK_9;
if (name == ":") return SDLK_COLON;
if (name == ";") return SDLK_SEMICOLON;
if (name == "<") return SDLK_LESS;
if (name == "=") return SDLK_EQUALS;
if (name == ">") return SDLK_GREATER;
if (name == "?") return SDLK_QUESTION;
if (name == "[") return SDLK_LEFTBRACKET;
if (name == "\\") return SDLK_BACKSLASH;
if (name == "]") return SDLK_RIGHTBRACKET;
if (name == "`") return SDLK_GRAVE;
if (name == "a") return SDLK_A;
if (name == "b") return SDLK_B;
if (name == "c") return SDLK_C;
if (name == "d") return SDLK_D;
if (name == "e") return SDLK_E;
if (name == "f") return SDLK_F;
if (name == "g") return SDLK_G;
if (name == "h") return SDLK_H;
if (name == "i") return SDLK_I;
if (name == "j") return SDLK_J;
if (name == "k") return SDLK_K;
if (name == "l") return SDLK_L;
if (name == "m") return SDLK_M;
if (name == "n") return SDLK_N;
if (name == "o") return SDLK_O;
if (name == "p") return SDLK_P;
if (name == "q") return SDLK_Q;
if (name == "r") return SDLK_R;
if (name == "s") return SDLK_S;
if (name == "t") return SDLK_T;
if (name == "u") return SDLK_U;
if (name == "v") return SDLK_V;
if (name == "w") return SDLK_W;
if (name == "x") return SDLK_X;
if (name == "y") return SDLK_Y;
if (name == "z") return SDLK_Z;
if (name == "delete") return SDLK_DELETE;
if (name == "capslock") return SDLK_CAPSLOCK;
if (name == "f1") return SDLK_F1;
if (name == "f2") return SDLK_F2;
if (name == "f3") return SDLK_F3;
if (name == "f4") return SDLK_F4;
if (name == "f5") return SDLK_F5;
if (name == "f6") return SDLK_F6;
if (name == "f7") return SDLK_F7;
if (name == "f8") return SDLK_F8;
if (name == "f9") return SDLK_F9;
if (name == "f10") return SDLK_F10;
if (name == "f11") return SDLK_F11;
if (name == "f12") return SDLK_F12;
if (name == "insert") return SDLK_INSERT;
if (name == "home") return SDLK_HOME;
if (name == "pageup") return SDLK_PAGEUP;
if (name == "end") return SDLK_END;
if (name == "pagedown") return SDLK_PAGEDOWN;
if (name == "right") return SDLK_RIGHT;
if (name == "left") return SDLK_LEFT;
if (name == "down") return SDLK_DOWN;
if (name == "up") return SDLK_UP;
return 0;
}
struct { String string; SDL_Keycode value; } SDLKeycodeConversionTable[] = {
{"enter", SDLK_RETURN},
{"escape", SDLK_ESCAPE},
{"backspace", SDLK_BACKSPACE},
{"tab", SDLK_TAB},
{"space", SDLK_SPACE},
{"minus", SDLK_MINUS},
{"period", SDLK_PERIOD},
{"slash", SDLK_SLASH},
{"0", SDLK_0},
{"1", SDLK_1},
{"2", SDLK_2},
{"3", SDLK_3},
{"4", SDLK_4},
{"5", SDLK_5},
{"6", SDLK_6},
{"7", SDLK_7},
{"8", SDLK_8},
{"9", SDLK_9},
{"semicolon", SDLK_SEMICOLON},
{"less", SDLK_LESS},
{"equals", SDLK_EQUALS},
{"greater", SDLK_GREATER},
{"leftbracket", SDLK_LEFTBRACKET},
{"backslash", SDLK_BACKSLASH},
{"rightbracket", SDLK_RIGHTBRACKET},
{"grave", SDLK_GRAVE},
{"a", SDLK_A},
{"b", SDLK_B},
{"c", SDLK_C},
{"d", SDLK_D},
{"e", SDLK_E},
{"f", SDLK_F},
{"g", SDLK_G},
{"h", SDLK_H},
{"i", SDLK_I},
{"j", SDLK_J},
{"k", SDLK_K},
{"l", SDLK_L},
{"m", SDLK_M},
{"n", SDLK_N},
{"o", SDLK_O},
{"p", SDLK_P},
{"q", SDLK_Q},
{"r", SDLK_R},
{"s", SDLK_S},
{"t", SDLK_T},
{"u", SDLK_U},
{"v", SDLK_V},
{"w", SDLK_W},
{"x", SDLK_X},
{"y", SDLK_Y},
{"z", SDLK_Z},
{"delete", SDLK_DELETE},
{"capslock", SDLK_CAPSLOCK},
{"f1", SDLK_F1},
{"f2", SDLK_F2},
{"f3", SDLK_F3},
{"f4", SDLK_F4},
{"f5", SDLK_F5},
{"f6", SDLK_F6},
{"f7", SDLK_F7},
{"f8", SDLK_F8},
{"f9", SDLK_F9},
{"f10", SDLK_F10},
{"f11", SDLK_F11},
{"f12", SDLK_F12},
{"insert", SDLK_INSERT},
{"home", SDLK_HOME},
{"pageup", SDLK_PAGEUP},
{"end", SDLK_END},
{"pagedown", SDLK_PAGEDOWN},
{"right", SDLK_RIGHT},
{"left", SDLK_LEFT},
{"down", SDLK_DOWN},
{"up", SDLK_UP},
};
void FillEventWithBasicData(Event *event) { void FillEventWithBasicData(Event *event) {
SDL_Keymod mod = SDL_GetModState(); SDL_Keymod mod = SDL_GetModState();

View File

@@ -50,6 +50,8 @@ String WorkDir;
RandomSeed UniqueBufferNameSeed = {}; RandomSeed UniqueBufferNameSeed = {};
Array<Event> EventPlayback; Array<Event> EventPlayback;
lua_State *LuaState = NULL; lua_State *LuaState = NULL;
BlockArena Perm;
Event *OnCommandEvent;
// clipboard // clipboard
BlockArena ClipboardArena; BlockArena ClipboardArena;
@@ -181,12 +183,18 @@ void ReloadStyle() {
StyleUndoMergeTimeout = GetStyleFloat("UndoMergeTimeout", StyleUndoMergeTimeout); StyleUndoMergeTimeout = GetStyleFloat("UndoMergeTimeout", StyleUndoMergeTimeout);
} }
typedef void Function(void); struct CommandContext {
bool out_skip_rem_cmds;
};
typedef void Function(void *param);
typedef void CommandFunction(CommandContext *ctx);
typedef int LuaFunction(lua_State *state); typedef int LuaFunction(lua_State *state);
struct FunctionData { String name; Function *function; }; struct FunctionData { String name; Function *function; };
struct LuaFunctionData { String name; LuaFunction *function; }; struct LuaFunctionData { String name; LuaFunction *function; };
struct CommandData { String name; String binding; CommandFunction *function; struct Trigger *trigger; };
Array<FunctionData> CommandFunctions; Array<CommandData> CommandFunctions;
Array<LuaFunctionData> LuaFunctions; Array<LuaFunctionData> LuaFunctions;
Array<FunctionData> TestFunctions; Array<FunctionData> TestFunctions;
@@ -200,9 +208,10 @@ struct Register_Function {
} }
}; };
#define RegisterFunction(functions, name) Register_Function RF__##name(functions, #name, name) #define RegisterFunction(functions, name) Register_Function RF__##name(functions, #name, name)
#define RegisterCommand(name) RegisterFunction(&CommandFunctions, name)
struct Register_Lua { Register_Lua(LuaFunction *function, String name) { if (StartsWith(name, "Lua_")) name = Skip(name, 4); Add(&LuaFunctions, {name, function}); } }; struct Register_Lua { Register_Lua(LuaFunction *function, String name) { if (StartsWith(name, "Lua_")) name = Skip(name, 4); Add(&LuaFunctions, {name, function}); } };
#define RegisterLua(NAME) Register_Lua CONCAT(COMMAND, __COUNTER__)(NAME, #NAME) struct Register_Command { Register_Command(CommandFunction *function, String name, String binding) { if (StartsWith(name, "Command_")) name = Skip(name, 8); Add(&CommandFunctions, {name, binding, function}); } };
#define RegisterLua(NAME) Register_Lua RL_##NAME(NAME, #NAME)
#define RegisterCommand(name, binding) Register_Command RC__##name(name, #name, binding)
const int DIR_RIGHT = 0; const int DIR_RIGHT = 0;
const int DIR_LEFT = 1; const int DIR_LEFT = 1;

View File

@@ -110,26 +110,6 @@ int Lua_GetMainDir(lua_State *L) {
return 1; return 1;
} RegisterLua(Lua_GetMainDir); } RegisterLua(Lua_GetMainDir);
int Lua_KillProcess(lua_State *L) {
Command_KillProcess();
return 0;
} RegisterLua(Lua_KillProcess);
int Lua_KillWindow(lua_State *L) {
Command_KillWindow();
return 0;
} RegisterLua(Lua_KillWindow);
int Lua_SetProjectFile(lua_State *L) {
Command_SetProjectFile();
return 0;
} RegisterLua(Lua_SetProjectFile);
int Lua_SetWorkDir(lua_State *L) {
Command_SetWorkDir();
return 0;
} RegisterLua(Lua_SetWorkDir);
int Lua_ListCommands(lua_State *L) { int Lua_ListCommands(lua_State *L) {
BSet main = GetBSet(LastActiveLayoutWindowID); BSet main = GetBSet(LastActiveLayoutWindowID);
BeginJump(&main); BeginJump(&main);
@@ -166,11 +146,6 @@ int Lua_Eval(lua_State *L) {
return 0; return 0;
} RegisterLua(Lua_Eval); } RegisterLua(Lua_Eval);
int Lua_ListViews(lua_State *L) {
Command_ListViews();
return 0;
} RegisterLua(Lua_ListViews);
int Lua_ApplyClangFormat(lua_State *L) { int Lua_ApplyClangFormat(lua_State *L) {
lua_Integer buffer_id = luaL_checkinteger(L, 1); lua_Integer buffer_id = luaL_checkinteger(L, 1);
lua_pop(L, 1); lua_pop(L, 1);
@@ -197,21 +172,6 @@ int Lua_ConvertLineEndingsToLF(lua_State *L) {
return 0; return 0;
} RegisterLua(Lua_ConvertLineEndingsToLF); } RegisterLua(Lua_ConvertLineEndingsToLF);
int Lua_Save(lua_State *L) {
Command_Save();
return 0;
} RegisterLua(Lua_Save);
int Lua_SaveAll(lua_State *L) {
Command_SaveAll();
return 0;
} RegisterLua(Lua_SaveAll);
int Lua_Reopen(lua_State *L) {
Command_Reopen();
return 0;
} RegisterLua(Lua_Reopen);
int Lua_New(lua_State *L) { int Lua_New(lua_State *L) {
String name = lua_tostring(L, 1); String name = lua_tostring(L, 1);
lua_pop(L, 1); lua_pop(L, 1);
@@ -228,16 +188,6 @@ int Lua_NewDir(lua_State *L) {
return 0; return 0;
} RegisterLua(Lua_NewDir); } RegisterLua(Lua_NewDir);
int Lua_ToggleFullscreen(lua_State *L) {
Command_ToggleFullscreen();
return 0;
} RegisterLua(Lua_ToggleFullscreen);
int Lua_ListCode(lua_State *L) {
Command_ListCode();
return 0;
} RegisterLua(Lua_ListCode);
int Lua_C(lua_State *L) { int Lua_C(lua_State *L) {
String string = lua_tostring(L, 1); String string = lua_tostring(L, 1);
lua_pop(L, 1); lua_pop(L, 1);

View File

@@ -10,6 +10,7 @@ struct Lexer {
enum TriggerKind { enum TriggerKind {
TriggerKind_Error, TriggerKind_Error,
TriggerKind_Key, TriggerKind_Key,
TriggerKind_Mouse,
TriggerKind_Binary, TriggerKind_Binary,
}; };
@@ -19,6 +20,7 @@ struct Trigger {
Trigger *right; Trigger *right;
SDL_Keycode key; SDL_Keycode key;
struct { struct {
EventKind event_kind : 8;
U32 ctrl : 1; U32 ctrl : 1;
U32 alt : 1; U32 alt : 1;
U32 shift : 1; U32 shift : 1;
@@ -89,13 +91,29 @@ Trigger *ParseKeyAtom(Lexer *lex) {
Advance(lex); Advance(lex);
} }
String a = {start, lex->at - start}; String a = {start, lex->at - start};
result->key = NameToSDLKeycode(a); Advance(lex);
if (result->key == 0) {
bool found = false;
for (int i = 0; !found && i < Lengthof(MouseConversionTable); i += 1) {
if (a == MouseConversionTable[i].string) {
result->event_kind = MouseConversionTable[i].value;
result->kind = TriggerKind_Mouse;
found = true;
}
}
for (int i = 0; !found && i < Lengthof(SDLKeycodeConversionTable); i += 1) {
if (a == SDLKeycodeConversionTable[i].string) {
result->key = SDLKeycodeConversionTable[i].value;
found = true;
}
}
if (!found) {
result->kind = TriggerKind_Error; result->kind = TriggerKind_Error;
ReportErrorf("%s:%d:%d: Failed to parse key trigger, unexpected identifier: '%S'", lex->name, lex->line, lex->column, result->key); ReportErrorf("%s:%d:%d: Failed to parse key trigger, unexpected identifier: '%d'", lex->name, lex->line, lex->column, result->key);
return result; return result;
} }
Advance(lex);
} else { } else {
result->kind = TriggerKind_Error; result->kind = TriggerKind_Error;
ReportErrorf("%s:%d:%d: Failed to parse key trigger, unexpected character: '%c'", lex->name, lex->line, lex->column, At(lex)); ReportErrorf("%s:%d:%d: Failed to parse key trigger, unexpected character: '%c'", lex->name, lex->line, lex->column, At(lex));
@@ -122,26 +140,32 @@ Trigger *ParseKeyChord(Lexer *lex) {
return left; return left;
} }
Trigger *ParseKeyOr(Lexer *lex) { Trigger *ParseKeyExpr(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, ParseKeyOr(lex), '|'); left = TriggerBinary(lex, left, ParseKeyExpr(lex), '|');
EatWhitespace(lex); EatWhitespace(lex);
} }
return left; return left;
} }
bool MatchEvent(Trigger *trigger, Event *event) { Trigger *ParseKey(Allocator allocator, String key, char *debug_name) {
if (event->kind != EVENT_KEY_PRESS) { Lexer lex = {allocator, key.data, key.data, key.data + key.len, debug_name};
return false; Trigger *result = ParseKeyExpr(&lex);
} return result;
}
bool MatchEvent(Trigger *trigger, Event *event) {
if (trigger->kind == TriggerKind_Key) { if (trigger->kind == TriggerKind_Key) {
if (trigger->key == event->key && trigger->ctrl == event->ctrl && trigger->alt == event->alt && trigger->shift == event->shift) { if (trigger->key == event->key && trigger->ctrl == event->ctrl && trigger->alt == event->alt && trigger->shift == event->shift) {
return true; return true;
} }
} else if (trigger->kind == TriggerKind_Mouse) {
if (trigger->event_kind == event->kind) {
return true;
}
} else if (trigger->kind == TriggerKind_Binary) { } else if (trigger->kind == TriggerKind_Binary) {
if (trigger->key == ' ') { if (trigger->key == ' ') {
return false; return false;
@@ -157,12 +181,12 @@ bool MatchEvent(Trigger *trigger, Event *event) {
return false; return false;
} }
void TestParser() { void TestParser(void *param) {
Scratch scratch; Scratch scratch;
{ {
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 = ParseKeyOr(&base_lex); Trigger *trigger = ParseKeyExpr(&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);
@@ -172,7 +196,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 = ParseKeyOr(&base_lex); Trigger *trigger = ParseKeyExpr(&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);
@@ -188,7 +212,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 = ParseKeyOr(&base_lex); Trigger *trigger = ParseKeyExpr(&base_lex);
Assert(trigger->kind == TriggerKind_Binary); Assert(trigger->kind == TriggerKind_Binary);
Assert(trigger->key == '|'); Assert(trigger->key == '|');

View File

@@ -135,7 +135,9 @@ void Update(Event event) {
view->update_scroll = true; view->update_scroll = true;
} }
OnCommandEvent = &event;
OnCommand(event); OnCommand(event);
OnCommandEvent = NULL;
UpdateProcesses(); UpdateProcesses();
CoUpdate(&event); CoUpdate(&event);
ReloadLuaConfigs(); ReloadLuaConfigs();
@@ -253,7 +255,7 @@ int main(int argc, char **argv)
if (1) { if (1) {
RunArenaTest(); RunArenaTest();
For (TestFunctions) { For (TestFunctions) {
it.function(); it.function(NULL);
} }
// ReportErrorf("Testing DONE\n"); // ReportErrorf("Testing DONE\n");
@@ -262,11 +264,11 @@ int main(int argc, char **argv)
#if !OS_WINDOWS #if !OS_WINDOWS
for (int i = 0; environ[i]; i += 1) { for (int i = 0; environ[i]; i += 1) {
Add(&Enviroment, Copy(GetSystemAllocator(), environ[i])); Add(&Enviroment, Copy(Perm, environ[i]));
} }
#endif #endif
WorkDir = GetWorkingDir(SysAllocator); WorkDir = GetWorkingDir(Perm);
{ {
String sdl_config_path = SDL_GetPrefPath("krzosa", "text_editor"); String sdl_config_path = SDL_GetPrefPath("krzosa", "text_editor");
if (sdl_config_path.len && sdl_config_path.data[sdl_config_path.len - 1] == '\\') { if (sdl_config_path.len && sdl_config_path.data[sdl_config_path.len - 1] == '\\') {
@@ -275,7 +277,7 @@ int main(int argc, char **argv)
if (sdl_config_path.len && sdl_config_path.data[sdl_config_path.len - 1] == '/') { if (sdl_config_path.len && sdl_config_path.data[sdl_config_path.len - 1] == '/') {
sdl_config_path = Chop(sdl_config_path, 1); // chop '/' sdl_config_path = Chop(sdl_config_path, 1); // chop '/'
} }
ConfigDir = NormalizePath(SysAllocator, sdl_config_path); ConfigDir = NormalizePath(Perm, sdl_config_path);
SDL_free(sdl_config_path.data); SDL_free(sdl_config_path.data);
} }
@@ -352,6 +354,11 @@ int main(int argc, char **argv)
InitWindows(); InitWindows();
InitOS(ReportWarningf); InitOS(ReportWarningf);
For (CommandFunctions) {
if (it.binding.len != 0) {
it.trigger = ParseKey(Perm, it.binding, it.name.data);
}
}
for (int i = 1; i < argc; i += 1) { for (int i = 1; i < argc; i += 1) {
String it = argv[i]; String it = argv[i];