Big UI cleanup
This commit is contained in:
+59
-102
@@ -1,12 +1,4 @@
|
||||
BSet GetConsoleSet() {
|
||||
BSet result = {};
|
||||
result.window = GetWindow(NullWindowID);
|
||||
result.view = GetView(NullViewID);
|
||||
result.buffer = GetBuffer(NullBufferID);
|
||||
return result;
|
||||
}
|
||||
|
||||
String GetDir(Buffer *buffer) {
|
||||
String GetBufferDirectory(Buffer *buffer) {
|
||||
#if PLUGIN_DIRECTORY_NAVIGATION
|
||||
if (buffer->is_dir) {
|
||||
return buffer->name;
|
||||
@@ -16,14 +8,14 @@ String GetDir(Buffer *buffer) {
|
||||
return result;
|
||||
}
|
||||
|
||||
String GetMainDir() {
|
||||
String GetPrimaryDirectory() {
|
||||
BSet main = GetBSet(PrimaryWindowID);
|
||||
return GetDir(main.buffer);
|
||||
return GetBufferDirectory(main.buffer);
|
||||
}
|
||||
|
||||
void JumpTempBuffer(BSet *set, String buffer_name) {
|
||||
if (buffer_name.len == 0) {
|
||||
buffer_name = GetUniqueBufferName(GetDir(set->buffer), "temp");
|
||||
buffer_name = GetUniqueBufferName(GetBufferDirectory(set->buffer), "temp");
|
||||
}
|
||||
set->view = WindowOpenBufferView(set->window, buffer_name);
|
||||
set->buffer = GetBuffer(set->view->active_buffer);
|
||||
@@ -136,7 +128,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));
|
||||
AddCommand(&main.view->commands, "Close", "escape | enter", [](){
|
||||
AddCommand(&main.view->commands, "Close", EnterOrEscapeKeySet, [](){
|
||||
BSet active = GetBSet(ActiveWindowID);
|
||||
Close(active.buffer->id);
|
||||
});
|
||||
@@ -217,7 +209,7 @@ void TrimWhitespace(Buffer *buffer, bool trim_lines_with_caret) {
|
||||
void ApplyFormattingTool(Buffer *buffer, String tool) {
|
||||
Scratch scratch;
|
||||
String string = AllocCharString(scratch, buffer);
|
||||
ExecResult exec_result = ExecAndWait(scratch, tool, GetDir(buffer), string);
|
||||
ExecResult exec_result = ExecAndWait(scratch, tool, GetBufferDirectory(buffer), string);
|
||||
String16 string16 = {exec_result.buffer->str, exec_result.buffer->len};
|
||||
if (exec_result.exit_code == 0) {
|
||||
ReplaceWithoutMovingCarets(buffer, GetRange(buffer), string16);
|
||||
@@ -244,7 +236,7 @@ void CMD_FormatSelection() {
|
||||
MergeCarets(primary.buffer, &primary.view->carets);
|
||||
For (primary.view->carets) {
|
||||
String input_string = ToString(scratch, GetString(primary.buffer, it.range));
|
||||
ExecResult exec_result = ExecAndWait(scratch, tool, GetDir(primary.buffer), input_string);
|
||||
ExecResult exec_result = ExecAndWait(scratch, tool, GetBufferDirectory(primary.buffer), input_string);
|
||||
String16 string16 = {exec_result.buffer->str, exec_result.buffer->len};
|
||||
AddEdit(&edits, it.range, string16);
|
||||
}
|
||||
@@ -256,7 +248,7 @@ void New(Window *window, String name = "") {
|
||||
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||
|
||||
Scratch scratch;
|
||||
String dir = GetDir(buffer);
|
||||
String dir = GetBufferDirectory(buffer);
|
||||
if (name != "") {
|
||||
if (!IsAbsolute(name)) {
|
||||
name = Format(scratch, "%S/%S", dir, name);
|
||||
@@ -409,7 +401,7 @@ ResolvedOpen ResolveOpen(Allocator alo, String path, ResolveOpenMeta meta) {
|
||||
result.kind = OpenKind_Goto;
|
||||
return result;
|
||||
} else {
|
||||
String rel_path = Format(alo, "%S/%S", GetMainDir(), path);
|
||||
String rel_path = Format(alo, "%S/%S", GetPrimaryDirectory(), path);
|
||||
existing_buffer = GetBuffer(rel_path, NULL);
|
||||
if (existing_buffer || FileExists(rel_path)) {
|
||||
result.existing_buffer = existing_buffer;
|
||||
@@ -457,10 +449,10 @@ BSet Open(Window *window, String path, ResolveOpenMeta meta, bool set_active = t
|
||||
NextActiveWindowID = set.window->id;
|
||||
}
|
||||
JumpTempBuffer(&set);
|
||||
Exec(set.view->id, false, o.path, GetMainDir());
|
||||
Exec(set.view->id, false, o.path, GetPrimaryDirectory());
|
||||
} else if (o.kind == OpenKind_BackgroundExec) {
|
||||
// this shouldn't change the focus/window/view
|
||||
Exec(NullViewID, false, o.path, GetMainDir());
|
||||
Exec(NullViewID, false, o.path, GetPrimaryDirectory());
|
||||
} else if (o.kind == OpenKind_Command) {
|
||||
EvalCommand(o.path);
|
||||
}
|
||||
@@ -535,7 +527,7 @@ void CMD_KillProcess() {
|
||||
KillProcess(main.view);
|
||||
} RegisterCommand(CMD_KillProcess, "", "Kill process in the last active primary window");
|
||||
|
||||
void AddCommand(Array<Command> *arr, String name, String binding, CMDFunction *function) {
|
||||
void AddCommand(Array<Command> *arr, String name, Trigger *trigger, CMDFunction *function) {
|
||||
IterRemove(*arr) {
|
||||
IterRemovePrepare(*arr);
|
||||
if (it.name == name) {
|
||||
@@ -544,40 +536,47 @@ void AddCommand(Array<Command> *arr, String name, String binding, CMDFunction *f
|
||||
}
|
||||
Command cmd = {};
|
||||
cmd.name = name;
|
||||
cmd.binding = binding;
|
||||
cmd.function = function;
|
||||
cmd.trigger = ParseKeyCached(binding);
|
||||
cmd.trigger = trigger;
|
||||
cmd.docs = "Not listing commands attached to things anywhere currently, maybe should change?";
|
||||
Add(arr, cmd);
|
||||
}
|
||||
|
||||
void Coro_Rename(mco_coro *co) {
|
||||
BSet main = GetBSet(PrimaryWindowID);
|
||||
Buffer *buffer = main.buffer;
|
||||
JumpTempBuffer(&main);
|
||||
NextActiveWindowID = main.window->id;
|
||||
RawAppendf(main.buffer, "Rename and click enter to submit: [%S]\n :Rename :Cancel", buffer->name);
|
||||
|
||||
main.view->carets[0] = FindNext(main.buffer, u"]", MakeCaret(0));
|
||||
main.view->carets[0].range.max = main.view->carets[0].range.min;
|
||||
AddCommand(&main.view->commands, "Rename", "enter", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Rename";});
|
||||
AddCommand(&main.view->commands, "Cancel", "escape", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Cancel";});
|
||||
String result = "Cancel";
|
||||
UIAction WaitForUIAction(mco_coro *co, BSet main) {
|
||||
UIAction result = UIAction_Cancel;
|
||||
for (;;) {
|
||||
if (main.window->active_view != main.view->id || (main.window->id != PrimaryWindowID && main.window->id != ActiveWindowID) || main.window->close) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (main.view->hook_cmd != "") {
|
||||
result = main.view->hook_cmd;
|
||||
if (main.view->ui_action != UIAction_Null) {
|
||||
result = main.view->ui_action;
|
||||
break;
|
||||
}
|
||||
|
||||
CoYield(co);
|
||||
}
|
||||
Close(main.buffer->id);
|
||||
return result;
|
||||
}
|
||||
#define AddUIAction(VIEW,NAME,TRIGGER,ACTION) AddCommand(&((VIEW)->commands),(NAME),(TRIGGER),[](){BSet active = GetBSet(ActiveWindowID); active.view->ui_action = (ACTION);})
|
||||
|
||||
void Coro_Rename(mco_coro *co) {
|
||||
BSet main = GetBSet(PrimaryWindowID);
|
||||
Buffer *original_buffer = main.buffer;
|
||||
JumpTempBuffer(&main);
|
||||
NextActiveWindowID = main.window->id;
|
||||
RawAppendf(main.buffer, "Rename and click enter to submit: [%S]\n :Rename :Cancel", original_buffer->name);
|
||||
|
||||
main.view->carets[0] = FindNext(main.buffer, u"]", MakeCaret(0));
|
||||
main.view->carets[0].range.max = main.view->carets[0].range.min;
|
||||
AddUIAction(main.view, "Rename", EnterKey, UIAction_Yes);
|
||||
AddUIAction(main.view, "Cancel", EscapeKey, UIAction_Cancel);
|
||||
UIAction action = WaitForUIAction(co, main);
|
||||
if (action != UIAction_Yes) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (result == "Rename") {
|
||||
Caret a = FindNext(main.buffer, u"[", MakeCaret(-1));
|
||||
Caret b = FindNext(main.buffer, u"]", MakeCaret(-1));
|
||||
if (a.range.min == -1 || b.range.max == -1) {
|
||||
@@ -586,8 +585,7 @@ void Coro_Rename(mco_coro *co) {
|
||||
}
|
||||
String16 string16 = GetString(main.buffer, {a.range.max + 1, b.range.max});
|
||||
String string = ToString(CoCurr->arena, string16);
|
||||
buffer->name = Intern(&GlobalInternTable, string);
|
||||
}
|
||||
original_buffer->name = Intern(&GlobalInternTable, string);
|
||||
}
|
||||
|
||||
void CMD_Rename() {
|
||||
@@ -596,7 +594,7 @@ void CMD_Rename() {
|
||||
CoResume(data);
|
||||
} RegisterCommand(CMD_Rename, "", "Opens a UI asking for a new name of a buffer open in the last active primary window");
|
||||
|
||||
String Coro_YesNoCancel(mco_coro *co, BSet main, String question) {
|
||||
UIAction Coro_YesNoCancel(mco_coro *co, BSet main, String question) {
|
||||
JumpTempBuffer(&main);
|
||||
NextActiveWindowID = main.window->id;
|
||||
RawAppendf(main.buffer, R"==(
|
||||
@@ -606,24 +604,11 @@ 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;
|
||||
AddCommand(&main.view->commands, "Yes", "enter", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Yes";});
|
||||
AddCommand(&main.view->commands, "No", "", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "No";});
|
||||
AddCommand(&main.view->commands, "Cancel", "escape", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Cancel";});
|
||||
String result = "Cancel";
|
||||
for (;;) {
|
||||
if (main.window->active_view != main.view->id || (main.window->id != PrimaryWindowID && main.window->id != ActiveWindowID) || main.window->close) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (main.view->hook_cmd != "") {
|
||||
result = main.view->hook_cmd;
|
||||
break;
|
||||
}
|
||||
|
||||
CoYield(co);
|
||||
}
|
||||
Close(main.buffer->id);
|
||||
return result;
|
||||
AddUIAction(main.view, "Yes", EnterKey, UIAction_Yes);
|
||||
AddUIAction(main.view, "No", NULL, UIAction_No);
|
||||
AddUIAction(main.view, "Cancel", EscapeKey, UIAction_Cancel);
|
||||
UIAction ui_action = WaitForUIAction(co, main);
|
||||
return ui_action;
|
||||
}
|
||||
|
||||
void Coro_Close(mco_coro *co) {
|
||||
@@ -655,13 +640,13 @@ void Coro_Close(mco_coro *co) {
|
||||
}
|
||||
|
||||
String question = Format(CoCurr->arena, "Do you want to save [%S] before closing?", main.buffer->name);
|
||||
String result = Coro_YesNoCancel(co, main, question);
|
||||
if (result == "Yes") {
|
||||
UIAction ui_action = Coro_YesNoCancel(co, main, question);
|
||||
if (ui_action == UIAction_Yes) {
|
||||
SaveBuffer(main.buffer);
|
||||
Close(main.buffer->id);
|
||||
} else if (result == "No") {
|
||||
} else if (ui_action == UIAction_No) {
|
||||
Close(main.buffer->id);
|
||||
} else if (result == "Cancel") {
|
||||
} else if (ui_action == UIAction_Cancel) {
|
||||
return;
|
||||
} ElseInvalidCodepath();
|
||||
}
|
||||
@@ -697,12 +682,12 @@ String Coro_CloseAllEx(mco_coro *co) {
|
||||
}
|
||||
|
||||
String question = Format(CoCurr->arena, "Do you want to save [%S] before closing?", it->name);
|
||||
String result = Coro_YesNoCancel(co, main, question);
|
||||
UIAction ui_action = Coro_YesNoCancel(co, main, question);
|
||||
it = GetBuffer(id, NULL);
|
||||
if (it && result == "Yes") {
|
||||
if (it && ui_action == UIAction_Yes) {
|
||||
SaveBuffer(it);
|
||||
} else if (result == "No") {
|
||||
} else if (result == "Cancel") {
|
||||
} else if (ui_action == UIAction_No) {
|
||||
} else if (ui_action == UIAction_Cancel) {
|
||||
return "Cancel";
|
||||
} ElseInvalidCodepath();
|
||||
}
|
||||
@@ -749,24 +734,10 @@ void Coro_ReplaceAll(mco_coro *co) {
|
||||
|
||||
Caret field_seek = BaseFindNext(main.buffer, u"for::", MakeCaret(0), SeekFlag_None);
|
||||
main.view->carets[0] = MakeCaret(main.buffer->len, field_seek.range.max);
|
||||
AddCommand(&main.view->commands, "Submit", "enter", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Submit";});
|
||||
AddCommand(&main.view->commands, "Cancel", "escape", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Cancel";});
|
||||
|
||||
String result = "Cancel";
|
||||
for (;;) {
|
||||
if (main.window->active_view != main.view->id || (main.window->id != PrimaryWindowID && main.window->id != ActiveWindowID) || main.window->close) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (main.view->hook_cmd != "") {
|
||||
result = main.view->hook_cmd;
|
||||
break;
|
||||
}
|
||||
|
||||
CoYield(co);
|
||||
}
|
||||
Close(main.buffer->id);
|
||||
if (result == "Cancel") {
|
||||
AddUIAction(main.view, "Submit", EnterKey, UIAction_Yes);
|
||||
AddUIAction(main.view, "Cancel", EscapeKey, UIAction_Cancel);
|
||||
UIAction action = WaitForUIAction(co, main);
|
||||
if (action == UIAction_Cancel) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -782,24 +753,10 @@ void Coro_ReplaceAll(mco_coro *co) {
|
||||
|
||||
Caret field_seek = BaseFindNext(main.buffer, u"with::", MakeCaret(0), SeekFlag_None);
|
||||
main.view->carets[0] = MakeCaret(main.buffer->len, field_seek.range.max);
|
||||
AddCommand(&main.view->commands, "Submit", "enter", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Submit";});
|
||||
AddCommand(&main.view->commands, "Cancel", "escape", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Cancel";});
|
||||
String result = "Cancel";
|
||||
for (;;) {
|
||||
if (main.window->active_view != main.view->id || (main.window->id != PrimaryWindowID && main.window->id != ActiveWindowID) || main.window->close) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (main.view->hook_cmd != "") {
|
||||
result = main.view->hook_cmd;
|
||||
break;
|
||||
}
|
||||
|
||||
CoYield(co);
|
||||
}
|
||||
Close(main.buffer->id);
|
||||
|
||||
if (result == "Cancel") {
|
||||
AddUIAction(main.view, "Submit", EnterKey, UIAction_Yes);
|
||||
AddUIAction(main.view, "Cancel", EscapeKey, UIAction_Cancel);
|
||||
UIAction action = WaitForUIAction(co, main);
|
||||
if (action == UIAction_Cancel) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ void UpdateFuzzySearchView() {
|
||||
}
|
||||
|
||||
void SetFuzzy(View *view) {
|
||||
AddCommand(&view->commands, "Open", "ctrl-q | enter | f12", [](){
|
||||
AddCommand(&view->commands, "Open", OpenKeySet, [](){
|
||||
BSet active = GetBSet(ActiveWindowID);
|
||||
BSet main = GetBSet(PrimaryWindowID);
|
||||
NextActiveWindowID = main.window->id;
|
||||
|
||||
@@ -39,6 +39,13 @@ WindowID NullWindowID;
|
||||
BufferID SearchBufferID;
|
||||
#endif
|
||||
|
||||
Trigger *EscapeKey;
|
||||
Trigger *EnterKey;
|
||||
Trigger *OpenKeySet;
|
||||
Trigger *EnterOrEscapeKeySet;
|
||||
Trigger *AltEnterKeySet;
|
||||
Trigger *ShiftEnterKeySet;
|
||||
|
||||
WindowID NextActiveWindowID;
|
||||
WindowID ActiveWindowID;
|
||||
WindowID PrimaryWindowID;
|
||||
|
||||
@@ -61,10 +61,10 @@ void CMD_RunFile() {
|
||||
|
||||
if (OS_WINDOWS) {
|
||||
String cmd = Format(scratch, "cl %S -Fe:cfile.exe /Zi /FC /nologo /WX /W3 /wd4200 /wd4334 /diagnostics:column && cfile.exe", primary.buffer->name);
|
||||
ExecBuild(cmd, GetDir(primary.buffer));
|
||||
ExecBuild(cmd, GetBufferDirectory(primary.buffer));
|
||||
} else {
|
||||
String cmd = Format(scratch, "bash <<EOF\nclang %S -o cfile.exe -g -Wall -Wno-missing-braces -Wno-writable-strings -Wno-writable-strings -fsanitize=address -fdiagnostics-absolute-paths -lm \n ./cfile.exe\nEOF", primary.buffer->name);
|
||||
ExecBuild(cmd, GetDir(primary.buffer));
|
||||
ExecBuild(cmd, GetBufferDirectory(primary.buffer));
|
||||
}
|
||||
build.window->visible = true;
|
||||
} RegisterCommand(CMD_RunFile, "", "Run and build current file, currently only C/C++ supported");
|
||||
|
||||
@@ -11,7 +11,7 @@ void SetProjectDirectory(String dir) {
|
||||
|
||||
void CMD_SetProjectDirectoryHere() {
|
||||
BSet main = GetBSet(PrimaryWindowID);
|
||||
SetProjectDirectory(GetDir(main.buffer));
|
||||
SetProjectDirectory(GetBufferDirectory(main.buffer));
|
||||
} RegisterCommand(CMD_SetProjectDirectoryHere, "", "Sets work directory to the directory of the current buffer, it also renames couple special buffers to make them accomodate the new ProjectDirectory");
|
||||
|
||||
void Coro_OpenCode(mco_coro *co) {
|
||||
|
||||
@@ -2109,7 +2109,7 @@ bool RDBG_InitConnection() {
|
||||
Scratch scratch;
|
||||
String session_name = Format(scratch, "te%llu", GetTimeNanos());
|
||||
String remedy_string = Format(scratch, "%S --servername %S", RemedyBGPath, session_name);
|
||||
Exec(NullViewID, true, remedy_string, GetMainDir());
|
||||
Exec(NullViewID, true, remedy_string, GetPrimaryDirectory());
|
||||
MemoryZero(&RDBG_Ctx, sizeof(RDBG_Ctx));
|
||||
RDBG_Ctx.cmd.data = command_buf;
|
||||
RDBG_Ctx.cmd.capacity = sizeof(command_buf);
|
||||
|
||||
@@ -76,7 +76,7 @@ void CMD_SearchOpenBuffers() {
|
||||
|
||||
NextActiveWindowID = main.window->id;
|
||||
JumpTempBuffer(&main);
|
||||
AddCommand(&main.view->commands, "Open", "ctrl-q | enter | f12", []() {
|
||||
AddCommand(&main.view->commands, "Open", OpenKeySet, []() {
|
||||
BSet active = GetBSet(ActiveWindowID);
|
||||
BSet main = GetBSet(PrimaryWindowID);
|
||||
NextActiveWindowID = main.window->id;
|
||||
|
||||
@@ -73,9 +73,9 @@ void InitSearchWindow() {
|
||||
window->visible = false;
|
||||
window->lose_visibility_on_escape = true;
|
||||
window->jump_history = false;
|
||||
AddCommand(&view->commands, "SearchAll", "alt-enter", CMD_SearchAll);
|
||||
AddCommand(&view->commands, "SearchPrevInSearch", "shift-enter", CMD_SearchPrevInSearch);
|
||||
AddCommand(&view->commands, "SearchNextInSearch", "enter", CMD_SearchNextInSearch);
|
||||
AddCommand(&view->commands, "SearchAll", AltEnterKeySet, CMD_SearchAll);
|
||||
AddCommand(&view->commands, "SearchPrevInSearch", ShiftEnterKeySet, CMD_SearchPrevInSearch);
|
||||
AddCommand(&view->commands, "SearchNextInSearch", EnterKey, CMD_SearchNextInSearch);
|
||||
}
|
||||
|
||||
void LayoutSearchWindow(Rect2I *rect, int16_t wx, int16_t wy) {
|
||||
|
||||
@@ -974,6 +974,13 @@ int main(int argc, char **argv)
|
||||
it.trigger = ParseKeyCached(it.binding);
|
||||
}
|
||||
}
|
||||
EnterKey = ParseKeyCached("enter");
|
||||
EscapeKey = ParseKeyCached("escape");
|
||||
OpenKeySet = ParseKeyCached("ctrl-q | enter | f12");
|
||||
EnterOrEscapeKeySet = ParseKeyCached("escape | enter");
|
||||
AltEnterKeySet = ParseKeyCached("alt-enter");
|
||||
ShiftEnterKeySet = ParseKeyCached("shift-enter");
|
||||
|
||||
|
||||
#if PLUGIN_CONFIG
|
||||
{
|
||||
|
||||
@@ -30,10 +30,17 @@ struct Command {
|
||||
String name;
|
||||
String docs;
|
||||
CMDFunction *function;
|
||||
String binding;
|
||||
String binding; // DONT USE, only for ParseKeyCached
|
||||
struct Trigger *trigger;
|
||||
};
|
||||
|
||||
enum UIAction {
|
||||
UIAction_Null,
|
||||
UIAction_Cancel,
|
||||
UIAction_Yes,
|
||||
UIAction_No,
|
||||
};
|
||||
|
||||
struct Buffer {
|
||||
BufferID id;
|
||||
String name;
|
||||
@@ -79,7 +86,7 @@ struct View {
|
||||
Caret main_caret_on_begin_frame;
|
||||
bool update_scroll;
|
||||
|
||||
String hook_cmd;
|
||||
UIAction ui_action;
|
||||
Array<Command> commands;
|
||||
Function *update_hook;
|
||||
uint64_t prev_search_line_hash;
|
||||
@@ -264,7 +271,7 @@ struct ResolvedOpen {
|
||||
bool existing_buffer;
|
||||
};
|
||||
|
||||
void AddCommand(Array<Command> *arr, String name, String binding, CMDFunction *function);
|
||||
void AddCommand(Array<Command> *arr, String name, struct Trigger *trigger, CMDFunction *function);
|
||||
#define RegisterCommand(name, ...) Register_Command RC__##name(&GlobalCommands, name, #name, __VA_ARGS__)
|
||||
struct Register_Command {
|
||||
Register_Command(Array<Command> *funcs, CMDFunction *function, String name, String binding, String docs = "") {
|
||||
|
||||
Reference in New Issue
Block a user