diff options
Diffstat (limited to 'command.c')
-rw-r--r-- | command.c | 186 |
1 files changed, 111 insertions, 75 deletions
diff --git a/command.c b/command.c index 335c396..502ff17 100644 --- a/command.c +++ b/command.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2020 C. McEnroe <june@causal.agency> +/* Copyright (C) 2020 June McEnroe <june@causal.agency> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -144,7 +144,7 @@ static void commandMsg(uint id, char *params) { if (params) { splitMessage("PRIVMSG", msg, params); } else { - uiShowID(msg); + windowShow(windowFor(msg)); } } @@ -176,8 +176,14 @@ static void commandQuit(uint id, char *params) { static void commandNick(uint id, char *params) { (void)id; - if (!params) return; - ircFormat("NICK :%s\r\n", params); + if (params) { + ircFormat("NICK :%s\r\n", params); + } else { + uiFormat( + Network, Warm, NULL, "You are \3%02d%s", + self.color, self.nick + ); + } } static void commandAway(uint id, char *params) { @@ -213,8 +219,31 @@ static void commandNames(uint id, char *params) { static void commandOps(uint id, char *params) { (void)params; - ircFormat("WHO %s\r\n", idNames[id]); - replies[ReplyWho]++; + char buf[1024]; + char *ptr = buf, *end = &buf[sizeof(buf)]; + ptr = seprintf( + ptr, end, "The council of \3%02d%s\3 are ", + idColors[id], idNames[id] + ); + bool first = true; + struct Cursor curs = {0}; + for (const char *nick; (nick = completeEach(&curs, id));) { + char prefix = bitPrefix(*completeBits(id, nick)); + if (!prefix || prefix == '+') continue; + ptr = seprintf( + ptr, end, "%s\3%02d%c%s\3", + (first ? "" : ", "), completeColor(id, nick), prefix, nick + ); + first = false; + } + if (first) { + uiFormat( + id, Warm, NULL, "\3%02d%s\3 is a lawless wasteland", + idColors[id], idNames[id] + ); + } else { + uiWrite(id, Warm, NULL, buf); + } } static void commandInvite(uint id, char *params) { @@ -376,25 +405,26 @@ static void commandQuery(uint id, char *params) { if (idColors[query] == Default) { idColors[query] = completeColor(id, params); } - uiShowID(query); + windowShow(windowFor(query)); } static void commandWindow(uint id, char *params) { if (!params) { - uiWindows(); + windowList(); } else if (isdigit(params[0])) { - uiShowNum(strtoul(params, NULL, 10)); + windowShow(strtoul(params, NULL, 10)); } else { id = idFind(params); if (id) { - uiShowID(id); + windowShow(windowFor(id)); return; } - for (const char *match; (match = completeSubstr(None, params));) { - id = idFind(match); + struct Cursor curs = {0}; + for (const char *str; (str = completeSubstr(&curs, None, params));) { + id = idFind(str); if (!id) continue; - completeAccept(); - uiShowID(id); + completeAccept(&curs); + windowShow(windowFor(id)); break; } } @@ -405,20 +435,20 @@ static void commandMove(uint id, char *params) { char *name = strsep(¶ms, " "); if (params) { id = idFind(name); - if (id) uiMoveID(id, strtoul(params, NULL, 10)); + if (id) windowMove(windowFor(id), strtoul(params, NULL, 10)); } else { - uiMoveID(id, strtoul(name, NULL, 10)); + windowMove(windowFor(id), strtoul(name, NULL, 10)); } } static void commandClose(uint id, char *params) { if (!params) { - uiCloseID(id); + windowClose(windowFor(id)); } else if (isdigit(params[0])) { - uiCloseNum(strtoul(params, NULL, 10)); + windowClose(strtoul(params, NULL, 10)); } else { id = idFind(params); - if (id) uiCloseID(id); + if (id) windowClose(windowFor(id)); } } @@ -530,60 +560,60 @@ static void commandHelp(uint id, char *params) { enum Flag { BIT(Multiline), BIT(Restrict), - BIT(Kiosk), }; static const struct Handler { const char *cmd; Command *fn; enum Flag flags; + enum Cap caps; } Commands[] = { - { "/away", commandAway, 0 }, - { "/ban", commandBan, 0 }, - { "/close", commandClose, 0 }, - { "/copy", commandCopy, Restrict | Kiosk }, - { "/cs", commandCS, 0 }, - { "/debug", commandDebug, Kiosk }, - { "/deop", commandDeop, 0 }, - { "/devoice", commandDevoice, 0 }, - { "/except", commandExcept, 0 }, - { "/exec", commandExec, Multiline | Restrict | Kiosk }, - { "/help", commandHelp, 0 }, // Restrict special case. - { "/highlight", commandHighlight, 0 }, - { "/ignore", commandIgnore, 0 }, - { "/invex", commandInvex, 0 }, - { "/invite", commandInvite, 0 }, - { "/join", commandJoin, Kiosk }, - { "/kick", commandKick, 0 }, - { "/list", commandList, Kiosk }, - { "/me", commandMe, Multiline }, - { "/mode", commandMode, 0 }, - { "/move", commandMove, 0 }, - { "/msg", commandMsg, Multiline | Kiosk }, - { "/names", commandNames, 0 }, - { "/nick", commandNick, 0 }, - { "/notice", commandNotice, Multiline }, - { "/ns", commandNS, 0 }, - { "/o", commandOpen, Restrict | Kiosk }, - { "/op", commandOp, 0 }, - { "/open", commandOpen, Restrict | Kiosk }, - { "/ops", commandOps, 0 }, - { "/part", commandPart, Kiosk }, - { "/query", commandQuery, Kiosk }, - { "/quit", commandQuit, 0 }, - { "/quote", commandQuote, Multiline | Kiosk }, - { "/say", commandPrivmsg, Multiline }, - { "/setname", commandSetname, 0 }, - { "/topic", commandTopic, 0 }, - { "/unban", commandUnban, 0 }, - { "/unexcept", commandUnexcept, 0 }, - { "/unhighlight", commandUnhighlight, 0 }, - { "/unignore", commandUnignore, 0 }, - { "/uninvex", commandUninvex, 0 }, - { "/voice", commandVoice, 0 }, - { "/whois", commandWhois, 0 }, - { "/whowas", commandWhowas, 0 }, - { "/window", commandWindow, 0 }, + { "/away", commandAway, 0, 0 }, + { "/ban", commandBan, 0, 0 }, + { "/close", commandClose, 0, 0 }, + { "/copy", commandCopy, Restrict, 0 }, + { "/cs", commandCS, 0, 0 }, + { "/debug", commandDebug, 0, 0 }, + { "/deop", commandDeop, 0, 0 }, + { "/devoice", commandDevoice, 0, 0 }, + { "/except", commandExcept, 0, 0 }, + { "/exec", commandExec, Multiline | Restrict, 0 }, + { "/help", commandHelp, 0, 0 }, // Restrict special case. + { "/highlight", commandHighlight, 0, 0 }, + { "/ignore", commandIgnore, 0, 0 }, + { "/invex", commandInvex, 0, 0 }, + { "/invite", commandInvite, 0, 0 }, + { "/join", commandJoin, 0, 0 }, + { "/kick", commandKick, 0, 0 }, + { "/list", commandList, 0, 0 }, + { "/me", commandMe, Multiline, 0 }, + { "/mode", commandMode, 0, 0 }, + { "/move", commandMove, 0, 0 }, + { "/msg", commandMsg, Multiline, 0 }, + { "/names", commandNames, 0, 0 }, + { "/nick", commandNick, 0, 0 }, + { "/notice", commandNotice, Multiline, 0 }, + { "/ns", commandNS, 0, 0 }, + { "/o", commandOpen, Restrict, 0 }, + { "/op", commandOp, 0, 0 }, + { "/open", commandOpen, Restrict, 0 }, + { "/ops", commandOps, 0, 0 }, + { "/part", commandPart, 0, 0 }, + { "/query", commandQuery, 0, 0 }, + { "/quit", commandQuit, 0, 0 }, + { "/quote", commandQuote, Multiline, 0 }, + { "/say", commandPrivmsg, Multiline, 0 }, + { "/setname", commandSetname, 0, CapSetname }, + { "/topic", commandTopic, 0, 0 }, + { "/unban", commandUnban, 0, 0 }, + { "/unexcept", commandUnexcept, 0, 0 }, + { "/unhighlight", commandUnhighlight, 0, 0 }, + { "/unignore", commandUnignore, 0, 0 }, + { "/uninvex", commandUninvex, 0, 0 }, + { "/voice", commandVoice, 0, 0 }, + { "/whois", commandWhois, 0, 0 }, + { "/whowas", commandWhowas, 0, 0 }, + { "/window", commandWindow, 0, 0 }, }; static int compar(const void *cmd, const void *_handler) { @@ -639,6 +669,14 @@ size_t commandWillSplit(uint id, const char *input) { return 0; } +static bool commandAvailable(const struct Handler *handler) { + if (handler->flags & Restrict && self.restricted) return false; + if (handler->caps && (handler->caps & self.caps) != handler->caps) { + return false; + } + return true; +} + void command(uint id, char *input) { if (id == Debug && input[0] != '/' && !self.restricted) { commandQuote(id, input); @@ -653,11 +691,11 @@ void command(uint id, char *input) { return; } + struct Cursor curs = {0}; const char *cmd = strsep(&input, " "); - const char *unique = complete(None, cmd); - if (unique && !complete(None, cmd)) { + const char *unique = completePrefix(&curs, None, cmd); + if (unique && !completePrefix(&curs, None, cmd)) { cmd = unique; - completeReject(); } const struct Handler *handler = bsearch( @@ -667,10 +705,7 @@ void command(uint id, char *input) { uiFormat(id, Warm, NULL, "No such command %s", cmd); return; } - if ( - (self.restricted && handler->flags & Restrict) || - (self.kiosk && handler->flags & Kiosk) - ) { + if (!commandAvailable(handler)) { uiFormat(id, Warm, NULL, "Command %s is unavailable", cmd); return; } @@ -687,8 +722,9 @@ void command(uint id, char *input) { handler->fn(id, input); } -void commandCompleteAdd(void) { +void commandCompletion(void) { for (size_t i = 0; i < ARRAY_LEN(Commands); ++i) { - completeAdd(None, Commands[i].cmd, Default); + if (!commandAvailable(&Commands[i])) continue; + completePush(None, Commands[i].cmd, Default); } } |