From ec00007e619d29a0502bd8131e17d8648bb091a6 Mon Sep 17 00:00:00 2001 From: Trevor Arjeski Date: Wed, 12 Aug 2020 11:15:04 +0300 Subject: [PATCH] Added help command (/help). --- libtiny_tui/src/tui.rs | 62 ++++++++++++++++++++++++++++++++++------- tiny/src/cmd.rs | 63 ++++++++++++++++++++++++++++++++---------- 2 files changed, 100 insertions(+), 25 deletions(-) diff --git a/libtiny_tui/src/tui.rs b/libtiny_tui/src/tui.rs index 9d0f2007..b2f332c1 100644 --- a/libtiny_tui/src/tui.rs +++ b/libtiny_tui/src/tui.rs @@ -38,6 +38,42 @@ pub(crate) enum TUIRet { const LEFT_ARROW: char = '<'; const RIGHT_ARROW: char = '>'; +struct CmdUsage { + name: &'static str, + description: &'static str, + usage: &'static str, +} + +impl CmdUsage { + const fn new(name: &'static str, description: &'static str, usage: &'static str) -> CmdUsage { + CmdUsage { + name, + description, + usage, + } + } +} + +const CLEAR_CMD: CmdUsage = CmdUsage::new("clear", "Clears current tab", "/clear"); +const IGNORE_CMD: CmdUsage = CmdUsage::new("ignore", "Ignore join/quit messages", "/ignore"); +const NOTIFY_CMD: CmdUsage = CmdUsage::new( + "notify", + "Set channel notifications", + "/notify [off|mentions|messages]", +); +const SWITCH_CMD: CmdUsage = CmdUsage::new("switch", "Switches to tab", "/switch "); +const STATUSLINE_CMD: CmdUsage = CmdUsage::new("statusline", "Toggles statusline", "/statusline"); +const RELOAD_CMD: CmdUsage = CmdUsage::new("reload", "Reloads config file", "/reload"); + +const TUI_COMMANDS: [CmdUsage; 6] = [ + CLEAR_CMD, + IGNORE_CMD, + NOTIFY_CMD, + SWITCH_CMD, + STATUSLINE_CMD, + RELOAD_CMD, +]; + pub(crate) struct TUI { /// Termbox instance tb: Termbox, @@ -139,12 +175,7 @@ impl TUI { fn notify(&mut self, words: &mut SplitWhitespace, src: &MsgSource) { let words: Vec<&str> = words.collect(); - let mut show_usage = || { - self.add_client_err_msg( - "/notify usage: /notify [off|mentions|messages]", - &MsgTarget::CurrentTab, - ) - }; + let mut show_usage = || self.add_client_err_msg(NOTIFY_CMD.usage, &MsgTarget::CurrentTab); if words.is_empty() { self.show_notify_mode(&MsgTarget::CurrentTab); @@ -202,10 +233,7 @@ impl TUI { Some("switch") => { match words.next() { Some(s) => self.switch(s), - None => self.add_client_err_msg( - "/switch usage: /switch ", - &MsgTarget::CurrentTab, - ), + None => self.add_client_err_msg(SWITCH_CMD.usage, &MsgTarget::CurrentTab), } true } @@ -217,6 +245,20 @@ impl TUI { self.reload_config(); true } + Some("help") => { + self.add_client_msg("TUI Commands: ", &MsgTarget::CurrentTab); + for cmd in TUI_COMMANDS.iter() { + self.add_client_msg( + &format!( + "/{:<10} - {:<25} - Usage: {}", + cmd.name, cmd.description, cmd.usage + ), + &MsgTarget::CurrentTab, + ); + } + // false to fall through to print help for cmd.rs commands + false + } _ => false, } } diff --git a/tiny/src/cmd.rs b/tiny/src/cmd.rs index a98fa461..7b87bf02 100644 --- a/tiny/src/cmd.rs +++ b/tiny/src/cmd.rs @@ -19,11 +19,12 @@ pub(crate) struct CmdArgs<'a> { pub(crate) struct Cmd { /// Command name. E.g. if this is `"cmd"`, `/cmd ...` will call this command. pub(crate) name: &'static str, - - // Command help message. Shown in `/help`. - // pub(crate) help: &'static str, /// Command function. pub(crate) cmd_fn: fn(CmdArgs), + /// Command description + description: &'static str, + /// Command usage + usage: &'static str, } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -96,7 +97,7 @@ fn find_client<'a>(clients: &'a mut Vec, serv_name: &str) -> Option<&'a //////////////////////////////////////////////////////////////////////////////////////////////////// -static CMDS: [&Cmd; 8] = [ +static CMDS: [&Cmd; 9] = [ &AWAY_CMD, &CLOSE_CMD, &CONNECT_CMD, @@ -105,6 +106,7 @@ static CMDS: [&Cmd; 8] = [ &MSG_CMD, &NAMES_CMD, &NICK_CMD, + &HELP_CMD, ]; //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -112,6 +114,8 @@ static CMDS: [&Cmd; 8] = [ static AWAY_CMD: Cmd = Cmd { name: "away", cmd_fn: away, + description: "Sets/removes away message", + usage: "/away [msg]", }; fn away(args: CmdArgs) { @@ -130,6 +134,8 @@ fn away(args: CmdArgs) { static CLOSE_CMD: Cmd = Cmd { name: "close", cmd_fn: close, + description: "Closes current tab", + usage: "/close", }; fn close(args: CmdArgs) { @@ -163,6 +169,8 @@ fn close(args: CmdArgs) { static CONNECT_CMD: Cmd = Cmd { name: "connect", cmd_fn: connect, + description: "Connects to a server", + usage: "/connect : or /connect (to reconnect)", }; fn connect(args: CmdArgs) { @@ -183,10 +191,7 @@ fn connect(args: CmdArgs) { _ => // wat { - ui.add_client_err_msg( - "/connect usage: /connect : or /connect (to reconnect)", - &MsgTarget::CurrentTab, - ) + ui.add_client_err_msg(CONNECT_CMD.usage, &MsgTarget::CurrentTab) } } } @@ -273,6 +278,8 @@ fn connect_( static JOIN_CMD: Cmd = Cmd { name: "join", cmd_fn: join, + description: "Joins a channel", + usage: "/join chan1[,chan2...]", }; fn join(args: CmdArgs) { @@ -285,10 +292,7 @@ fn join(args: CmdArgs) { } = args; let words = args.split_whitespace().collect::>(); if words.is_empty() { - return ui.add_client_err_msg( - "/join usage: /join chan1[,chan2...]", - &MsgTarget::CurrentTab, - ); + return ui.add_client_err_msg(JOIN_CMD.usage, &MsgTarget::CurrentTab); } match find_client(clients, src.serv_name()) { @@ -305,6 +309,8 @@ fn join(args: CmdArgs) { static ME_CMD: Cmd = Cmd { name: "me", cmd_fn: me, + description: "Sends emote message", + usage: "/me message", }; fn me(args: CmdArgs) { @@ -316,7 +322,7 @@ fn me(args: CmdArgs) { .. } = args; if args.is_empty() { - return ui.add_client_err_msg("/me usage: /me message", &MsgTarget::CurrentTab); + return ui.add_client_err_msg(ME_CMD.usage, &MsgTarget::CurrentTab); } crate::ui::send_msg(&**ui, clients, &src, args.to_string(), true); } @@ -326,6 +332,8 @@ fn me(args: CmdArgs) { static MSG_CMD: Cmd = Cmd { name: "msg", cmd_fn: msg, + description: "Sends a message", + usage: "/msg target message", }; fn split_msg_args(args: &str) -> Option<(&str, &str)> { @@ -355,7 +363,7 @@ fn msg(args: CmdArgs) { .. } = args; let fail = || { - ui.add_client_err_msg("/msg usage: /msg target message", &MsgTarget::CurrentTab); + ui.add_client_err_msg(MSG_CMD.usage, &MsgTarget::CurrentTab); }; let (target, msg) = match split_msg_args(args) { @@ -392,6 +400,8 @@ fn msg(args: CmdArgs) { static NAMES_CMD: Cmd = Cmd { name: "names", cmd_fn: names, + description: "Shows users in channel", + usage: "/names", }; fn names(args: CmdArgs) { @@ -437,6 +447,8 @@ fn names(args: CmdArgs) { static NICK_CMD: Cmd = Cmd { name: "nick", cmd_fn: nick, + description: "Sets your nick", + usage: "/nick ", }; fn nick(args: CmdArgs) { @@ -454,7 +466,28 @@ fn nick(args: CmdArgs) { client.nick(new_nick); } } else { - ui.add_client_err_msg("/nick usage: /nick ", &MsgTarget::CurrentTab); + ui.add_client_err_msg(NICK_CMD.usage, &MsgTarget::CurrentTab); + } +} + +static HELP_CMD: Cmd = Cmd { + name: "help", + cmd_fn: help, + description: "Displays this message", + usage: "/help", +}; + +fn help(args: CmdArgs) { + let CmdArgs { ui, .. } = args; + ui.add_client_msg("Client Commands:", &MsgTarget::CurrentTab); + for cmd in CMDS.iter() { + ui.add_client_msg( + &format!( + "/{:<10} - {:<25} - Usage: {}", + cmd.name, cmd.description, cmd.usage + ), + &MsgTarget::CurrentTab, + ) } }