New hook design

This commit is contained in:
Krzosa Karol
2026-01-09 08:23:48 +01:00
parent de06ea05cc
commit 005a22a93d
11 changed files with 211 additions and 192 deletions

View File

@@ -167,7 +167,7 @@ void UIMessagef(const char *fmt, ...) {
NextActiveWindowID = main.window->id;
RawAppendf(main.buffer, "\n %S\n :Close\n", string);
main.view->carets[0] = FindNext(main.buffer, u":Close", MakeCaret(0));
AddHook(&main.view->hooks, "Close", "escape | enter", [](){
AddCommand(&main.view->hooks, "Close", "escape | enter", [](HookParam param){
BSet active = GetBSet(ActiveWindowID);
Close(active.buffer->id);
});
@@ -223,7 +223,7 @@ void CenterView(WindowID window) {
}
}
void CMD_CenterView() {
void CMD_CenterView(HookParam param) {
CenterView(PrimaryWindowID);
} RegisterCommand(CMD_CenterView, "");
@@ -336,7 +336,7 @@ void ApplyFormattingTool(Buffer *buffer, String tool) {
}
}
void CMD_FormatSelection() {
void CMD_FormatSelection(HookParam param) {
Scratch scratch;
BSet primary = GetBSet(PrimaryWindowID);
@@ -482,7 +482,7 @@ BSet ExecBuild(String cmd) {
return build;
}
void CMD_SaveAll() {
void CMD_SaveAll(HookParam param) {
For(Buffers) {
// NOTE: file_mod_time is only set when buffer got read or written to disk already so should be saved
if (it->file_mod_time && it->dirty) {
@@ -491,8 +491,8 @@ void CMD_SaveAll() {
}
} RegisterCommand(CMD_SaveAll, "ctrl-shift-s");
void CMD_Build() {
CMD_SaveAll();
void CMD_Build(HookParam param) {
CMD_SaveAll({});
#if OS_WINDOWS
ExecBuild("build.bat");
#else
@@ -502,12 +502,12 @@ void CMD_Build() {
main.window->visible = true;
} RegisterCommand(CMD_Build, "f1", "Run build.sh or build.bat in working directory, output is printed in a popup console and a special build buffer");
void CMD_GotoNextInList() {
void CMD_GotoNextInList(HookParam param) {
BSet main = GetBSet(PrimaryWindowID);
GotoNextInList(main.window, 1);
} RegisterCommand(CMD_GotoNextInList, "ctrl-e", "For example: when jumping from build panel to build error, a jump point is setup, user can click this button to go over to the next compiler error");
void CMD_GotoPrevInList() {
void CMD_GotoPrevInList(HookParam param) {
BSet main = GetBSet(PrimaryWindowID);
GotoNextInList(main.window, -1);
} RegisterCommand(CMD_GotoPrevInList, "alt-e", "For example: when jumping from build panel to build error, a jump point is setup, user can click this button to go over to the previous compiler error");
@@ -586,8 +586,8 @@ void Set(String string) {
return;
}
CommandData *cmd = NULL;
For (CommandFunctions) {
Hook *cmd = NULL;
For (GlobalHooks) {
if (it.name == name) {
cmd = ⁢
break;
@@ -778,11 +778,11 @@ BSet Open(Window *window, String path, ResolveOpenMeta meta, bool set_active = t
Buffer *buffer = GetBuffer(view->active_buffer);
if (o.line != -1) {
if (o.col == -1) o.col = 1;
Int pos = XYToPos(buffer, {o.col - 1, o.line - 1});
view->carets[0] = MakeCaret(pos);
Int pos = XYToPos(buffer, {o.col - 1, o.line - 1});
SelectRange(view, MakeCaret(pos));
}
}
CMD_CenterView();
CenterView(window->id);
} else if (o.kind == OpenKind_Exec) {
if (set_active) {
NextActiveWindowID = set.window->id;
@@ -817,23 +817,23 @@ BSet Open(String16 path, ResolveOpenMeta meta) {
return Open(string, meta);
}
void CMD_Save() {
void CMD_Save(HookParam param) {
BSet active = GetBSet(PrimaryWindowID);
SaveBuffer(active.buffer);
} RegisterCommand(CMD_Save, "ctrl-s", "Save buffer currently open in the last primary window");
void CMD_Reopen() {
void CMD_Reopen(HookParam param) {
BSet main = GetBSet(PrimaryWindowID);
ReopenBuffer(main.buffer);
NextActiveWindowID = main.window->id;
} RegisterCommand(CMD_Reopen, "");
void CMD_New() {
void CMD_New(HookParam param) {
BSet main = GetBSet(PrimaryWindowID);
New(main.window, "");
} RegisterCommand(CMD_New, "ctrl-n", "Open a new buffer with automatically generated name, use :Rename");
void CMD_ToggleFullscreen() {
void CMD_ToggleFullscreen(HookParam param) {
if (IsInFullscreen) {
SDL_SetWindowSize(SDLWindow, FullScreenSizeX, FullScreenSizeY);
SDL_SetWindowPosition(SDLWindow, FullScreenPositionX, FullScreenPositionY);
@@ -850,7 +850,7 @@ void CMD_ToggleFullscreen() {
IsInFullscreen = !IsInFullscreen;
} RegisterCommand(CMD_ToggleFullscreen, "f11");
void CMD_SetWorkDirHere() {
void CMD_SetWorkDirHere(HookParam param) {
BSet main = GetBSet(PrimaryWindowID);
SetWorkDirHere(GetDir(main.buffer));
} RegisterCommand(CMD_SetWorkDirHere, "", "Sets work directory to the directory of the current buffer, it also renames couple special buffers to make them accomodate the new WorkDir");
@@ -907,22 +907,27 @@ void OpenCode(String dir) {
CoResume(data);
}
void CMD_OpenCode() {
void CMD_OpenCode(HookParam param) {
OpenCode(WorkDir);
} RegisterCommand(CMD_OpenCode, "", "Open all code files in current WorkDir, the code files are determined through NonCodePatterns_EndsWith config variable list");
void CMD_KillProcess() {
void CMD_KillProcess(HookParam param) {
BSet main = GetBSet(PrimaryWindowID);
KillProcess(main.view);
} RegisterCommand(CMD_KillProcess, "", "Kill process in the last active primary window");
void CMD_CloseWindow() {
void CMD_CloseWindow(HookParam param) {
Close(PrimaryWindowID);
} RegisterCommand(CMD_CloseWindow, "", "Close the last active primary window");
void AddHook(Array<CommandData> *arr, String name, String binding, Function *function) {
CommandData n = {name, binding, function, "Not listing hooks anywhere currently", ParseKeyCached(binding)};
Add(arr, n);
void AddCommand(Array<Hook> *arr, String name, String binding, HookFunction *function) {
Hook hook = {};
hook.name = name;
hook.binding = binding;
hook.function = function;
hook.trigger = ParseKeyCached(binding);
hook.docs = "Not listing hooks anywhere currently, maybe should change!!";
Add(arr, hook);
}
void Coro_Rename(mco_coro *co) {
@@ -934,8 +939,8 @@ void Coro_Rename(mco_coro *co) {
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";});
AddCommand(&main.view->hooks, "Rename", "enter", [](HookParam param){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Rename";});
AddCommand(&main.view->hooks, "Cancel", "escape", [](HookParam param){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Cancel";});
String result = "Cancel";
for (;;) {
if (main.window->active_view != main.view->id || (main.window->id != PrimaryWindowID && main.window->id != ActiveWindowID) || main.window->close) {
@@ -964,7 +969,7 @@ void Coro_Rename(mco_coro *co) {
}
}
void CMD_Rename() {
void CMD_Rename(HookParam param) {
CoRemove("Coro_Rename");
CoData *data = CoAdd(Coro_Rename);
CoResume(data);
@@ -980,9 +985,9 @@ String Coro_YesNoCancel(mco_coro *co, BSet main, String question) {
)==", question);
main.view->carets[0] = FindNext(main.buffer, u":Yes", MakeCaret(0));
main.view->carets[0].range.min = main.view->carets[0].range.max;
AddHook(&main.view->hooks, "Yes", "enter", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Yes";});
AddHook(&main.view->hooks, "No", "", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "No";});
AddHook(&main.view->hooks, "Cancel", "escape", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Cancel";});
AddCommand(&main.view->hooks, "Yes", "enter", [](HookParam param){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Yes";});
AddCommand(&main.view->hooks, "No", "", [](HookParam param){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "No";});
AddCommand(&main.view->hooks, "Cancel", "escape", [](HookParam param){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Cancel";});
String result = "Cancel";
for (;;) {
if (main.window->active_view != main.view->id || (main.window->id != PrimaryWindowID && main.window->id != ActiveWindowID) || main.window->close) {
@@ -1040,13 +1045,13 @@ void Coro_Close(mco_coro *co) {
} ElseInvalidCodepath();
}
void CMD_Close() {
void CMD_Close(HookParam param) {
CoRemove("Coro_Close");
CoData *data = CoAdd(Coro_Close);
CoResume(data);
} RegisterCommand(CMD_Close, "ctrl-w", "Close open view in the last active primary window");
void CMD_DeleteFile() {
void CMD_DeleteFile(HookParam param) {
BSet main = GetBSet(PrimaryWindowID);
String buffer_name = main.buffer->name;
DeleteFile(main.buffer->name);
@@ -1094,13 +1099,13 @@ void Coro_Quit(mco_coro *co) {
}
}
void CMD_Quit() {
void CMD_Quit(HookParam param) {
CoRemove("Coro_Quit");
CoData *data = CoAdd(Coro_Quit);
CoResume(data);
} RegisterCommand(CMD_Quit, "", "Ask user which files he would like to save and exit");
} RegisterHook(CMD_Quit, HookKind_AppQuit, "", "Ask user which files he would like to save and exit");
void CMD_QuitWithoutSaving() {
void CMD_QuitWithoutSaving(HookParam param) {
AppIsRunning = false;
} RegisterCommand(CMD_QuitWithoutSaving, "", "Self explanatory");
@@ -1108,72 +1113,72 @@ void Coro_CloseAll(mco_coro *co) {
Coro_CloseAllEx(co);
}
void CMD_CloseAll() {
void CMD_CloseAll(HookParam param) {
CoRemove("Coro_CloseAll");
CoData *data = CoAdd(Coro_CloseAll);
CoResume(data);
} RegisterCommand(CMD_CloseAll, "", "Ask user which files to save and close all open normal views and buffers");
void CMD_JumpPrev() {
void CMD_JumpPrev(HookParam param) {
BSet main = GetBSet(PrimaryWindowID);
JumpToLastValidView(main.window);
NextActiveWindowID = main.window->id;
} RegisterCommand(CMD_JumpPrev, "ctrl-tab", "Go to the previous open view in primary window");
void CMD_Prev() {
void CMD_Prev(HookParam param) {
BSet main = GetBSet(PrimaryWindowID);
main.window->skip_checkpoint = true;
JumpBack(main.window);
NextActiveWindowID = main.window->id;
} RegisterCommand(CMD_Prev, "alt-q | mousex1", "Go to previous position (either previous view that was open or caret position) in the primary window");
void CMD_Next() {
void CMD_Next(HookParam param) {
BSet main = GetBSet(PrimaryWindowID);
main.window->skip_checkpoint = true;
JumpForward(main.window);
NextActiveWindowID = main.window->id;
} RegisterCommand(CMD_Next, "alt-shift-q | mousex2", "Go to next position, after backtracking, in the primary window");
void CMD_OpenUpFolder() {
void CMD_OpenUpFolder(HookParam param) {
BSet main = GetBSet(PrimaryWindowID);
String name = ChopLastSlash(main.buffer->name);
Open(name);
} RegisterCommand(CMD_OpenUpFolder, "ctrl-o", "Open current's file directory or up directory in other cases");
void CMD_EncloseLine() {
void CMD_EncloseLine(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
EncloseLine(active.view);
} RegisterCommand(CMD_EncloseLine, "ctrl-l", "Select the entire line on which your caret is placed");
void CMD_SelectAll() {
void CMD_SelectAll(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
SelectEntireBuffer(active.view);
active.view->update_scroll = false;
} RegisterCommand(CMD_SelectAll, "ctrl-a", "Select the entire buffer");
void CMD_Redo() {
void CMD_Redo(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
RedoEdit(active.buffer, &active.view->carets);
} RegisterCommand(CMD_Redo, "ctrl-shift-z", "Redo after undoing changes to the buffer");
void CMD_Undo() {
void CMD_Undo(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
UndoEdit(active.buffer, &active.view->carets);
} RegisterCommand(CMD_Undo, "ctrl-z", "Undo last change you made to the buffer");
void CMD_MakeFontLarger() {
void CMD_MakeFontLarger(HookParam param) {
FontSize += 1;
ReloadFont(PathToFont, (U32)FontSize);
} RegisterCommand(CMD_MakeFontLarger, "ctrl-equals", "Increase the font size");
void CMD_MakeFontSmaller() {
void CMD_MakeFontSmaller(HookParam param) {
if (FontSize > 4) {
FontSize -= 1;
ReloadFont(PathToFont, (U32)FontSize);
}
} RegisterCommand(CMD_MakeFontSmaller, "ctrl-minus", "Decrease the font size");
void CMD_OpenLoadWord() {
void CMD_OpenLoadWord(HookParam param) {
Scratch scratch;
BSet active = GetBSet(ActiveWindowID);
String16 load_word = FetchLoadWord(active.view);
@@ -1184,210 +1189,210 @@ void CMD_OpenLoadWord() {
Open(load_word);
} RegisterCommand(CMD_OpenLoadWord, "ctrl-q | f12", "Open a link under the caret (file link, url, command) or open the selection");
void CMD_KillSelectedLines() {
void CMD_KillSelectedLines(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
KillSelectedLines(active.view);
} RegisterCommand(CMD_KillSelectedLines, "ctrl-shift-k");
void CMD_IndentSelectedLines() {
void CMD_IndentSelectedLines(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
IndentSelectedLines(active.view);
} RegisterCommand(CMD_IndentSelectedLines, "ctrl-rightbracket | tab");
void CMD_DedentSelectedLines() {
void CMD_DedentSelectedLines(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
IndentSelectedLines(active.view, true);
} RegisterCommand(CMD_DedentSelectedLines, "ctrl-leftbracket | shift-tab");
void CMD_DuplicateLineDown() {
void CMD_DuplicateLineDown(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
DuplicateLine(active.view, DIR_DOWN);
} RegisterCommand(CMD_DuplicateLineDown, "ctrl-alt-down");
void CMD_CreateCursorDown() {
void CMD_CreateCursorDown(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
CreateCursorVertical(active.view, DIR_DOWN);
} RegisterCommand(CMD_CreateCursorDown, "alt-shift-down");
void CMD_SelectDownToEmptyLine() {
void CMD_SelectDownToEmptyLine(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_DOWN, CTRL_PRESSED, SHIFT_PRESS);
} RegisterCommand(CMD_SelectDownToEmptyLine, "ctrl-shift-down");
void CMD_MoveLineDown() {
void CMD_MoveLineDown(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCaretsLine(active.view, DIR_DOWN);
} RegisterCommand(CMD_MoveLineDown, "alt-down");
void CMD_MoveDownToEmptyLine() {
void CMD_MoveDownToEmptyLine(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_DOWN, CTRL_PRESSED);
} RegisterCommand(CMD_MoveDownToEmptyLine, "ctrl-down");
void CMD_SelectDown() {
void CMD_SelectDown(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_DOWN, false, SHIFT_PRESS);
} RegisterCommand(CMD_SelectDown, "shift-down");
void CMD_MoveDown() {
void CMD_MoveDown(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_DOWN);
} RegisterCommand(CMD_MoveDown, "down");
void CMD_DuplicateLineUp() {
void CMD_DuplicateLineUp(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
DuplicateLine(active.view, DIR_UP);
} RegisterCommand(CMD_DuplicateLineUp, "ctrl-alt-up");
void CMD_CreateCursorUp() {
void CMD_CreateCursorUp(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
CreateCursorVertical(active.view, DIR_UP);
} RegisterCommand(CMD_CreateCursorUp, "alt-shift-up");
void CMD_SelectUpToEmptyLine() {
void CMD_SelectUpToEmptyLine(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_UP, CTRL_PRESSED, SHIFT_PRESS);
} RegisterCommand(CMD_SelectUpToEmptyLine, "ctrl-shift-up");
void CMD_MoveLineUp() {
void CMD_MoveLineUp(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCaretsLine(active.view, DIR_UP);
} RegisterCommand(CMD_MoveLineUp, "alt-up");
void CMD_MoveUpToEmptyLine() {
void CMD_MoveUpToEmptyLine(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_UP, CTRL_PRESSED);
} RegisterCommand(CMD_MoveUpToEmptyLine, "ctrl-up");
void CMD_SelectUp() {
void CMD_SelectUp(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_UP, false, SHIFT_PRESS);
} RegisterCommand(CMD_SelectUp, "shift-up");
void CMD_MoveUp() {
void CMD_MoveUp(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_UP);
} RegisterCommand(CMD_MoveUp, "up");
void CMD_BoundarySelectLeft() {
void CMD_BoundarySelectLeft(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_LEFT, CTRL_PRESSED, SHIFT_PRESS);
} RegisterCommand(CMD_BoundarySelectLeft, "ctrl-shift-left");
void CMD_BoundaryMoveLeft() {
void CMD_BoundaryMoveLeft(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_LEFT, CTRL_PRESSED);
} RegisterCommand(CMD_BoundaryMoveLeft, "ctrl-left");
void CMD_SelectLeft() {
void CMD_SelectLeft(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_LEFT, false, SHIFT_PRESS);
} RegisterCommand(CMD_SelectLeft, "shift-left");
void CMD_FocusLeftWindow() {
void CMD_FocusLeftWindow(HookParam param) {
NextActiveWindowID = SwitchWindow(DIR_LEFT)->id;
} RegisterCommand(CMD_FocusLeftWindow, "alt-left");
void CMD_MoveLeft() {
void CMD_MoveLeft(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_LEFT);
} RegisterCommand(CMD_MoveLeft, "left");
void CMD_BoundarySelectRight() {
void CMD_BoundarySelectRight(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_RIGHT, CTRL_PRESSED, SHIFT_PRESS);
} RegisterCommand(CMD_BoundarySelectRight, "ctrl-shift-right");
void CMD_BoundaryMoveRight() {
void CMD_BoundaryMoveRight(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_RIGHT, CTRL_PRESSED);
} RegisterCommand(CMD_BoundaryMoveRight, "ctrl-right");
void CMD_SelectRight() {
void CMD_SelectRight(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_RIGHT, false, SHIFT_PRESS);
} RegisterCommand(CMD_SelectRight, "shift-right");
void CMD_FocusRightWindow() {
void CMD_FocusRightWindow(HookParam param) {
NextActiveWindowID = SwitchWindow(DIR_RIGHT)->id;
} RegisterCommand(CMD_FocusRightWindow, "alt-right");
void CMD_MoveRight() {
void CMD_MoveRight(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCarets(active.view, DIR_RIGHT);
} RegisterCommand(CMD_MoveRight, "right");
void CMD_MoveUpAPage() {
void CMD_MoveUpAPage(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCursorByPageSize(active.window, DIR_UP);
} RegisterCommand(CMD_MoveUpAPage, "pageup");
void CMD_SelectUpPage() {
void CMD_SelectUpPage(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCursorByPageSize(active.window, DIR_UP, SHIFT_PRESS);
} RegisterCommand(CMD_SelectUpPage, "shift-pageup");
void CMD_MoveToStart() {
void CMD_MoveToStart(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
SelectRange(active.view, MakeRange(0));
} RegisterCommand(CMD_MoveToStart, "ctrl-pageup");
void CMD_SelectDownPage() {
void CMD_SelectDownPage(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCursorByPageSize(active.window, DIR_DOWN, SHIFT_PRESS);
} RegisterCommand(CMD_SelectDownPage, "shift-pagedown");
void CMD_MoveToEnd() {
void CMD_MoveToEnd(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
SelectRange(active.view, MakeRange(active.buffer->len));
} RegisterCommand(CMD_MoveToEnd, "ctrl-pagedown");
void CMD_MoveDownPage() {
void CMD_MoveDownPage(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCursorByPageSize(active.window, DIR_DOWN);
} RegisterCommand(CMD_MoveDownPage, "pagedown");
void CMD_SelectToLineStart() {
void CMD_SelectToLineStart(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCursorToSide(active.view, DIR_LEFT, SHIFT_PRESS);
} RegisterCommand(CMD_SelectToLineStart, "shift-home");
void CMD_MoveToLineStart() {
void CMD_MoveToLineStart(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCursorToSide(active.view, DIR_LEFT);
} RegisterCommand(CMD_MoveToLineStart, "home");
void CMD_MoveToLineEnd() {
void CMD_MoveToLineEnd(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCursorToSide(active.view, DIR_RIGHT);
} RegisterCommand(CMD_MoveToLineEnd, "end");
void CMD_SelectToLineEnd() {
void CMD_SelectToLineEnd(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
MoveCursorToSide(active.view, DIR_RIGHT, SHIFT_PRESS);
} RegisterCommand(CMD_SelectToLineEnd, "shift-end");
void CMD_DeleteCharacter() {
void CMD_DeleteCharacter(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
Delete(active.view, DIR_LEFT);
} RegisterCommand(CMD_DeleteCharacter, "shift-backspace | backspace");
void CMD_DeleteBoundary() {
void CMD_DeleteBoundary(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
Delete(active.view, DIR_LEFT, SHIFT_PRESS);
} RegisterCommand(CMD_DeleteBoundary, "ctrl-backspace");
void CMD_DeleteForward() {
void CMD_DeleteForward(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
Delete(active.view, DIR_RIGHT);
} RegisterCommand(CMD_DeleteForward, "shift-delete | delete");
void CMD_DeleteForwardBoundary() {
void CMD_DeleteForwardBoundary(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
Delete(active.view, DIR_RIGHT, SHIFT_PRESS);
} RegisterCommand(CMD_DeleteForwardBoundary, "ctrl-delete");
void CMD_InsertNewLineUp() {
void CMD_InsertNewLineUp(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
SaveCaretHistoryBeforeBeginEdit(active.buffer, active.view->carets);
MoveCursorToSide(active.view, DIR_LEFT);
@@ -1395,19 +1400,19 @@ void CMD_InsertNewLineUp() {
MoveCarets(active.view, DIR_UP);
} RegisterCommand(CMD_InsertNewLineUp, "ctrl-shift-enter");
void CMD_InsertNewLineDown() {
void CMD_InsertNewLineDown(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
SaveCaretHistoryBeforeBeginEdit(active.buffer, active.view->carets);
MoveCursorToSide(active.view, DIR_RIGHT);
IndentedNewLine(active.view);
} RegisterCommand(CMD_InsertNewLineDown, "ctrl-enter");
void CMD_NewLine() {
void CMD_NewLine(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
IndentedNewLine(active.view);
} RegisterCommand(CMD_NewLine, "enter | shift-enter");
void CMD_CreateCaretOnNextFind() {
void CMD_CreateCaretOnNextFind(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
String16 string = GetString(active.buffer, active.view->carets[0].range);
Caret caret = FindNext(active.buffer, string, active.view->carets[0]);
@@ -1415,17 +1420,17 @@ void CMD_CreateCaretOnNextFind() {
MergeCarets(active.buffer, &active.view->carets);
} RegisterCommand(CMD_CreateCaretOnNextFind, "ctrl-d");
void CMD_FocusWindow1() {
void CMD_FocusWindow1(HookParam param) {
NextActiveWindowID = GetOverlappingWindow({0,0}, GetWindow(ActiveWindowID))->id;
} RegisterCommand(CMD_FocusWindow1, "ctrl-1");
void CMD_FocusWindow2() {
void CMD_FocusWindow2(HookParam param) {
Window *first = GetOverlappingWindow({0,0}, GetWindow(ActiveWindowID));
Vec2I p = GetSideOfWindow(first, DIR_RIGHT);
NextActiveWindowID = GetOverlappingWindow(p, GetWindow(ActiveWindowID))->id;
} RegisterCommand(CMD_FocusWindow2, "ctrl-2");
void CMD_FocusWindow3() {
void CMD_FocusWindow3(HookParam param) {
Window *first = GetOverlappingWindow({0,0});
if (first) {
Window *second = GetOverlappingWindow(GetSideOfWindow(first, DIR_RIGHT));
@@ -1438,11 +1443,11 @@ void CMD_FocusWindow3() {
}
} RegisterCommand(CMD_FocusWindow3, "ctrl-3");
void CMD_NewWindow() {
void CMD_NewWindow(HookParam param) {
CreateWind();
} RegisterCommand(CMD_NewWindow, "ctrl-backslash");
void CMD_ClearCarets() {
void CMD_ClearCarets(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
active.view->carets.len = 1;
active.view->carets[0] = MakeCaret(GetFront(active.view->carets[0]));
@@ -1474,7 +1479,7 @@ void GenerateConfig(View *view) {
Appendf(view, "// :Set %S %x\n", it.name, it.color->value);
} ElseInvalidCodepath();
}
For (CommandFunctions) {
For (GlobalHooks) {
Appendf(view, "// :Set %S '%S'\n", it.name, it.binding);
}
}

View File

@@ -87,17 +87,17 @@ void ClipboardPaste(View *view) {
EndEdit(buffer, &edits, &view->carets, KILL_SELECTION);
}
void CMD_Paste() {
void CMD_Paste(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
ClipboardPaste(active.view);
} RegisterCommand(CMD_Paste, "ctrl-v");
void CMD_Copy() {
void CMD_Copy(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
ClipboardCopy(active.view);
} RegisterCommand(CMD_Copy, "ctrl-c");
void CMD_Cut() {
void CMD_Cut(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
SaveCaretHistoryBeforeBeginEdit(active.buffer, active.view->carets);
ClipboardCopy(active.view);

View File

@@ -284,12 +284,12 @@ void TestParser() {
}
} RegisterFunction(&TestFunctions, TestParser);
void CMD_OpenConfig() {
void CMD_OpenConfig(HookParam param) {
Buffer *buffer = GetBuffer(GlobalConfigBufferID);
Open(buffer->name);
} RegisterCommand(CMD_OpenConfig, "", "Open the global config file");
void CMD_OpenConfigOptions() {
void CMD_OpenConfigOptions(HookParam param) {
BSet main = GetBSet(PrimaryWindowID);
JumpTempBuffer(&main);
NextActiveWindowID = main.window->id;
@@ -303,7 +303,7 @@ void CMD_OpenConfigOptions() {
default: InvalidCodepath();
}
}
For (CommandFunctions) {
For (GlobalHooks) {
RawAppendf(main.buffer, "\n:Set %-50S '%S'", it.name, it.binding);
}
} RegisterCommand(CMD_OpenConfigOptions, "", "List available variables and associated documentation inside the command window");
@@ -334,7 +334,7 @@ void EvalCommandsLineByLine(BSet set) {
NextActiveWindowID = save_next;
}
void CMD_EvalCommandsLineByLine() {
void CMD_EvalCommandsLineByLine(HookParam param) {
BSet set = GetBSet(PrimaryWindowID);
EvalCommandsLineByLine(set);
} RegisterCommand(CMD_EvalCommandsLineByLine, "", "Goes line by line over a buffer and evaluates every line as a command, ignores empty or lines starting with '//'");

View File

@@ -92,8 +92,7 @@ String Intern(InternTable *table, String string) {
// optimize worst offenders (like event text)
InternTable GlobalInternTable;
Function *LastExecutedManualCommand;
Array<CommandData> CommandFunctions;
Array<Hook> GlobalHooks;
Array<FunctionData> TestFunctions;
Array<Variable> Variables;

View File

@@ -17,7 +17,8 @@ Alternatively you can open with your keyboard - ctrl-q / f12, try that also!
Navigate to next parts of the guide by executing them like these commands you just played
with:
guide_big_picture.txt
guide_project.txt
guide_bindings_and_config.txt
:GuideBigPicture
:GuideNavigation
:GuideProjects
:GuideBindings
:GuideConfig

View File

@@ -400,19 +400,17 @@ void OnCommand(Event event) {
For (active.view->hooks) {
if (it.trigger && MatchEvent(it.trigger, &event)) {
ProfileScopeEx(it.name);
it.function();
LastExecutedManualCommand = it.function;
it.function({});
executed = true;
break;
}
}
if (executed == false) {
For (CommandFunctions) {
For (GlobalHooks) {
if (it.trigger && MatchEvent(it.trigger, &event)) {
ProfileScopeEx(it.name);
it.function();
LastExecutedManualCommand = it.function;
it.function(HookParam{});
}
}
}
@@ -427,7 +425,12 @@ void OnCommand(Event event) {
}
if (event.kind == EVENT_QUIT) {
CMD_Quit();
For (GlobalHooks) {
if (it.kind == HookKind_AppQuit) {
ProfileScopeEx(it.name);
it.function({});
}
}
}
IF_DEBUG(AssertRanges(main.view->carets));
@@ -439,14 +442,14 @@ void EvalCommand(String command) {
For (active.view->hooks) {
if (it.name == command) {
ProfileScopeEx(it.name);
it.function();
it.function({});
return;
}
}
For (CommandFunctions) {
For (GlobalHooks) {
if (it.name == command) {
ProfileScopeEx(it.name);
it.function();
it.function({});
return;
}
}
@@ -880,7 +883,7 @@ int main(int argc, char **argv)
InitWindows();
InitOS(ReportWarningf);
For (CommandFunctions) {
For (GlobalHooks) {
if (it.binding.len != 0) {
it.trigger = ParseKeyCached(it.binding);
}
@@ -905,6 +908,16 @@ int main(int argc, char **argv)
co_data->dont_wait_until_resolved = true;
CoResume(co_data);
#endif
{
For (GlobalHooks) {
if (it.kind == HookKind_AppInit) {
ProfileScopeEx(it.name);
it.function({});
}
}
}
#if OS_WASM
emscripten_set_main_loop(MainLoop, 0, 1);
#else

View File

@@ -62,9 +62,9 @@ enum HookKind {
HookKind_AppInit,
HookKind_AppUpdate,
HookKind_AppExit,
HookKind_AppQuit,
HookKind_Binding,
HookKind_Command,
HookKind_BeforeLayoutWindow,
HookKind_HandleLayoutWindow,
@@ -88,32 +88,18 @@ enum HookKind {
// Global hooks, per (window, view, buffer) hooks
struct HookParam {
struct Hook *hook;
Buffer *buffer;
View *view;
Window *window;
};
typedef void HookFunction(HookParam *param);
typedef void HookFunction(HookParam param);
struct Hook {
HookKind kind;
String name;
String doc;
String docs;
HookFunction *function;
// HookKind_Binding
String binding;
struct Trigger *trigger;
};
struct CommandData {
String name;
String binding;
Function *function;
String doc;
struct Trigger *trigger;
};
enum ViewKind {
ViewKind_Normal,
ViewKind_FuzzySearch,
@@ -132,7 +118,7 @@ struct View {
bool update_scroll;
String hook_cmd;
Array<CommandData> hooks;
Array<Hook> hooks;
uint64_t prev_search_line_hash;
struct {
unsigned close : 1;
@@ -312,8 +298,27 @@ struct ResolvedOpen {
bool existing_buffer;
};
struct Register_Command { Register_Command(Array<CommandData> *fucs, Function *function, String name, String binding, String doc = "") { if (StartsWith(name, "CMD_")) name = Skip(name, sizeof("CMD_") - 1); Add(fucs, {name, binding, function, doc}); } };
#define RegisterCommand(name, ...) Register_Command RC__##name(&CommandFunctions, name, #name, __VA_ARGS__)
void AddCommand(Array<Hook> *arr, String name, String binding, HookFunction *function);
#define RegisterCommand(name, ...) Register_Command RC__##name(&GlobalHooks, HookKind_Command, name, #name, __VA_ARGS__)
#define RegisterHook(name, kind, bindings, docs) Register_Command RC__##name(&GlobalHooks, kind, name, #name, bindings, docs)
struct Register_Command {
Register_Command(Array<Hook> *funcs, HookKind kind, HookFunction *function, String name, String binding, String docs = "") {
int64_t pos = 0;
if (Seek(name, "_", &pos, 0)) {
name = Skip(name, pos + 1);
}
Hook hook = {};
hook.kind = kind;
hook.name = name;
hook.binding = binding;
hook.function = function;
hook.docs = docs;
Reserve(funcs, 512);
Add(funcs, hook);
}
};
#define RegisterFunction(functions, name) Register_Function RF__##name(functions, #name, name)
struct Register_Function {
Register_Function(Array<FunctionData> *functions, String name, Function *f) {
int64_t pos = 0;
@@ -323,8 +328,6 @@ struct Register_Function {
Add(functions, {name, f});
}
};
#define RegisterFunction(functions, name) Register_Function RF__##name(functions, #name, name)
void AddHook(Array<CommandData> *arr, String name, String binding, Function *function);
constexpr int DIR_RIGHT = 0;
constexpr int DIR_LEFT = 1;

View File

@@ -27,7 +27,7 @@ void BuildWindowLayout(Rect2I *rect, Int wx, Int wy) {
n->document_rect = n->total_rect = CutBottom(rect, barsize);
}
void CMD_ShowBuildWindow() {
void CMD_ShowBuildWindow(HookParam param) {
BSet main = GetBSet(BuildWindowID);
if (ActiveWindowID != BuildWindowID) {
main.window->visible = true;

View File

@@ -1,34 +1,34 @@
void CMD_ShowCommands() {
if (ActiveWindowID == CommandWindowID && LastExecutedManualCommand == CMD_ShowCommands) {
NextActiveWindowID = PrimaryWindowID;
return;
}
ProfileFunction();
void CMD_ShowCommands(HookParam param) {
// @todo: maybe redo this, similar behavior but use View stored information
// if (ActiveWindowID == CommandWindowID && LastExecutedManualCommand == CMD_ShowCommands) {
// NextActiveWindowID = PrimaryWindowID;
// return;
// }
BSet command_bar = GetBSet(CommandWindowID);
command_bar.window->visible = true;
NextActiveWindowID = command_bar.window->id;
ResetBuffer(command_bar.buffer);
For (CommandFunctions) {
For (GlobalHooks) {
if (it.name == "OpenCommand") {
continue;
}
// RawAppendf(command_bar.buffer, "\n:%-30S <|| :Set %-30S '%-30S'", it.name, it.name, it.binding);
RawAppendf(command_bar.buffer, "\n:%-30S <|| ", it.name);
if (it.doc.len) {
RawAppendf(command_bar.buffer, "%S", it.doc);
if (it.docs.len) {
RawAppendf(command_bar.buffer, "%S", it.docs);
}
}
command_bar.view->update_scroll = true;
SelectRange(command_bar.view, GetBufferBeginAsRange(command_bar.buffer));
} RegisterCommand(CMD_ShowCommands, "ctrl-shift-p", "List available commands and their documentation inside the command window");
void CMD_ShowDebugBufferList() {
if (ActiveWindowID == CommandWindowID && LastExecutedManualCommand == CMD_ShowDebugBufferList) {
NextActiveWindowID = PrimaryWindowID;
return;
}
ProfileFunction();
void CMD_ShowDebugBufferList(HookParam param) {
// @todo: maybe redo this, similar behavior but use View stored information
// if (ActiveWindowID == CommandWindowID && LastExecutedManualCommand == CMD_ShowDebugBufferList) {
// NextActiveWindowID = PrimaryWindowID;
// return;
// }
BSet command_bar = GetBSet(CommandWindowID);
command_bar.window->visible = true;
@@ -45,13 +45,12 @@ void CMD_ShowDebugBufferList() {
SelectRange(command_bar.view, GetBufferBeginAsRange(command_bar.buffer));
} RegisterCommand(CMD_ShowDebugBufferList, "ctrl-shift-alt-p", "Show full list of buffers, including the special ones that normally just clutter list");
void CMD_ShowBufferList() {
if (ActiveWindowID == CommandWindowID && LastExecutedManualCommand == CMD_ShowBufferList) {
NextActiveWindowID = PrimaryWindowID;
return;
}
ProfileFunction();
void CMD_ShowBufferList(HookParam param) {
// @todo: maybe redo this, similar behavior but use View stored information
// if (ActiveWindowID == CommandWindowID && LastExecutedManualCommand == CMD_ShowBufferList) {
// NextActiveWindowID = PrimaryWindowID;
// return;
// }
BSet command_bar = GetBSet(CommandWindowID);
command_bar.window->visible = true;
NextActiveWindowID = command_bar.window->id;
@@ -68,12 +67,11 @@ void CMD_ShowBufferList() {
} RegisterCommand(CMD_ShowBufferList, "ctrl-p", "List open buffers inside the command window that you can fuzzy search over");
void OpenCommand(BSet active) {
ProfileFunction();
String16 string = FetchFuzzyViewLoadLine(active.view);
Open(string);
}
void CMD_CommandWindowOpen() {
void CMD_CommandWindowOpen(HookParam param) {
BSet active = GetBSet(ActiveWindowID);
BSet main = GetBSet(PrimaryWindowID);
NextActiveWindowID = main.window->id;
@@ -220,8 +218,8 @@ void Coro_ReplaceAll(mco_coro *co) {
Caret field_seek = FindNext(main.buffer, u"for::", MakeCaret(0));
main.view->carets[0] = FindNext(main.buffer, string, field_seek);
AddHook(&main.view->hooks, "Submit", "enter", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Submit";});
AddHook(&main.view->hooks, "Cancel", "escape", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Cancel";});
AddCommand(&main.view->hooks, "Submit", "enter", [](HookParam param){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Submit";});
AddCommand(&main.view->hooks, "Cancel", "escape", [](HookParam param){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Cancel";});
String result = "Cancel";
for (;;) {
@@ -249,12 +247,12 @@ void Coro_ReplaceAll(mco_coro *co) {
{
JumpTempBuffer(&main);
NextActiveWindowID = main.window->id;
RawAppendf(main.buffer, ":Submit (enter) :Cancel (escape)\nString to replace with::%S", string8);
RawAppendf(main.buffer, ":Submit (enter) :Cancel (escape)\nString to replace with::%S", ToString(CoCurr->arena, needle));
Caret field_seek = FindNext(main.buffer, u"with::", MakeCaret(0));
main.view->carets[0] = FindNext(main.buffer, string, field_seek);
AddHook(&main.view->hooks, "Submit", "enter", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Submit";});
AddHook(&main.view->hooks, "Cancel", "escape", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Cancel";});
main.view->carets[0] = MakeCaret(main.buffer->len, field_seek.range.max);
AddCommand(&main.view->hooks, "Submit", "enter", [](HookParam param){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Submit";});
AddCommand(&main.view->hooks, "Cancel", "escape", [](HookParam param){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Cancel";});
String result = "Cancel";
for (;;) {
if (main.window->active_view != main.view->id || (main.window->id != PrimaryWindowID && main.window->id != ActiveWindowID) || main.window->close) {
@@ -291,11 +289,11 @@ void Coro_ReplaceAll(mco_coro *co) {
}
}
void CMD_ReplaceAll() {
void CMD_ReplaceAll(HookParam param) {
CoRemove("Coro_ReplaceAll");
CoData *data = CoAdd(Coro_ReplaceAll);
CoResume(data);
} RegisterCommand(CMD_ReplaceAll, "", "Search and replace over the entire project, you need to select a text with format like this 'FindAnd@>ReplaceWith' and executing the command will change all occurences of FindAnd to ReplaceWith");
} RegisterCommand(CMD_ReplaceAll, "ctrl-shift-r", "Search and replace over the entire project, you need to select a text with format like this 'FindAnd@>ReplaceWith' and executing the command will change all occurences of FindAnd to ReplaceWith");
void FuzzySearchViewUpdate() {
ProfileFunction();
@@ -351,7 +349,7 @@ void FuzzySearchViewUpdate() {
}
}
void CMD_SearchProject() {
void CMD_SearchProject(HookParam param) {
BSet main = GetBSet(PrimaryWindowID);
String16 string = {};
if (main.view->carets.len == 1 && GetSize(main.view->carets[0]) > 0) {
@@ -363,7 +361,7 @@ void CMD_SearchProject() {
View *view = WindowOpenBufferView(main.window, search_project_buffer->name);
view->special = true;
view->kind = ViewKind_ActiveSearch;
AddHook(&view->hooks, "Open", "ctrl-q | enter | f12", CMD_CommandWindowOpen);
AddCommand(&view->hooks, "Open", "ctrl-q | enter | f12", CMD_CommandWindowOpen);
SelectRange(view, GetLineRangeWithoutNL(search_project_buffer, 0));
if (string.len) {
Replace(view, string);
@@ -373,7 +371,7 @@ void CMD_SearchProject() {
void SetFuzzy(View *view) {
view->kind = ViewKind_FuzzySearch;
AddHook(&view->hooks, "Open", "ctrl-q | enter | f12", CMD_CommandWindowOpen);
AddCommand(&view->hooks, "Open", "ctrl-q | enter | f12", CMD_CommandWindowOpen);
}
void CommandWindowInit() {

View File

@@ -79,7 +79,7 @@ void DebugWindowUpdate() {
RawAppendf(set.buffer, "int temp = %d\n", main.buffer->temp);
}
void CMD_ToggleDebug() {
void CMD_ToggleDebug(HookParam param) {
Window *window = GetWindow(DebugWindowID);
window->visible = !window->visible;
} RegisterCommand(CMD_ToggleDebug, "ctrl-0", "Open a floating window that might become useful for debugging");

View File

@@ -1,4 +1,4 @@
void CMD_Search() {
void CMD_Search(HookParam param) {
BSet main = GetBSet(ActiveWindowID);
String16 string = {};
if (main.view->carets.len == 1 && GetSize(main.view->carets[0]) > 0) {
@@ -23,23 +23,23 @@ void SearchWindowFindNext(bool forward = true) {
CenterView(PrimaryWindowID);
}
void CMD_SearchNextInSearch() {
void CMD_SearchNextInSearch(HookParam param) {
SearchWindowFindNext(true);
}
void CMD_SearchPrevInSearch() {
void CMD_SearchPrevInSearch(HookParam param) {
SearchWindowFindNext(false);
}
void CMD_SearchNext() {
void CMD_SearchNext(HookParam param) {
SearchWindowFindNext(true);
} RegisterCommand(CMD_SearchNext, "f3", "Go to the next occurence of the search window needle");
void CMD_SearchPrev() {
void CMD_SearchPrev(HookParam param) {
SearchWindowFindNext(false);
} RegisterCommand(CMD_SearchPrev, "shift-f3", "Go to the previous occurence of the search window needle");
void CMD_SearchAll() {
void CMD_SearchAll(HookParam param) {
BSet main = GetBSet(PrimaryWindowID);
BSet set = GetBSet(SearchWindowID);
String16 needle = GetString(set.buffer, GetRange(set.buffer));
@@ -47,11 +47,11 @@ void CMD_SearchAll() {
set.window->visible = false;
} RegisterCommand(CMD_SearchAll, "alt-f3", "Use the search window needle and seek all the possible occurences in current buffer");
void CMD_ToggleCaseSensitiveSearch() {
void CMD_ToggleCaseSensitiveSearch(HookParam param) {
SearchCaseSensitive = !SearchCaseSensitive;
} RegisterCommand(CMD_ToggleCaseSensitiveSearch, "alt-c", "Text editor wide search toggle, should apply to most search things");
void CMD_ToggleSearchWordBoundary() {
void CMD_ToggleSearchWordBoundary(HookParam param) {
SearchWordBoundary = !SearchWordBoundary;
} RegisterCommand(CMD_ToggleSearchWordBoundary, "alt-w", "Text editor wide search toggle, should apply to most search things");
@@ -96,7 +96,7 @@ void SearchWindowInit() {
window->visible = false;
window->lose_visibility_on_escape = true;
window->jump_history = false;
AddHook(&view->hooks, "SearchAll", "alt-enter", CMD_SearchAll);
AddHook(&view->hooks, "SearchPrevInSearch", "shift-enter", CMD_SearchPrevInSearch);
AddHook(&view->hooks, "SearchNextInSearch", "enter", CMD_SearchNextInSearch);
AddCommand(&view->hooks, "SearchAll", "alt-enter", CMD_SearchAll);
AddCommand(&view->hooks, "SearchPrevInSearch", "shift-enter", CMD_SearchPrevInSearch);
AddCommand(&view->hooks, "SearchNextInSearch", "enter", CMD_SearchNextInSearch);
}