Repository: osa1/tiny (language: rust)

Issue:
Allow naming servers to give them a better display name
Currently the address of the server is used to display the server tab. For some servers this can be unhelpful (ip address) or too long (very long domain name). I would like to be able to give my servers a helpful name in the config. This name would be used instead.


Discussion / hints:
Implementing feature here:
https://github.com/osa1/tiny/pull/188

Fix patch:
diff --git a/libtiny_logger/src/lib.rs b/libtiny_logger/src/lib.rs
index 8438bcf3..85859461 100644
--- a/libtiny_logger/src/lib.rs
+++ b/libtiny_logger/src/lib.rs
@@ -37,7 +37,7 @@ macro_rules! delegate {
 
 impl UI for Logger {
     fn draw(&self) {}
-    delegate!(new_server_tab(serv: &str,));
+    delegate!(new_server_tab(serv: &str, alias: Option<String>,));
     delegate!(close_server_tab(serv: &str,));
     delegate!(new_chan_tab(serv: &str, chan: &str,));
     delegate!(close_chan_tab(serv: &str, chan: &str,));
@@ -127,7 +127,7 @@ impl LoggerInner {
         })
     }
 
-    fn new_server_tab(&mut self, serv: &str) {
+    fn new_server_tab(&mut self, serv: &str, _alias: Option<String>) {
         if self.servers.contains_key(serv) {
             return;
         }
diff --git a/libtiny_tui/examples/chat.rs b/libtiny_tui/examples/chat.rs
index 13475202..95ea4731 100644
--- a/libtiny_tui/examples/chat.rs
+++ b/libtiny_tui/examples/chat.rs
@@ -29,7 +29,7 @@ fn main() {
 
     local.block_on(&mut runtime, async move {
         let (tui, rcv_ev) = TUI::run(PathBuf::from("../tiny/config.yml"));
-        tui.new_server_tab("debug");
+        tui.new_server_tab("debug", None);
         tui.new_chan_tab("debug", "chan");
         tui.set_topic("This is channel topic", time::now(), SERV, CHAN);
         tui.draw();
diff --git a/libtiny_tui/examples/completion.rs b/libtiny_tui/examples/completion.rs
index 034c5fc1..8b2c807c 100644
--- a/libtiny_tui/examples/completion.rs
+++ b/libtiny_tui/examples/completion.rs
@@ -16,7 +16,7 @@ fn main() {
 
     local.block_on(&mut runtime, async move {
         let (tui, _) = TUI::run(PathBuf::from("../tiny/config.yml"));
-        tui.new_server_tab("debug");
+        tui.new_server_tab("debug", None);
         let debug_tab = MsgTarget::Server { serv: "debug" };
 
         tui.add_msg(
diff --git a/libtiny_tui/examples/tabs.rs b/libtiny_tui/examples/tabs.rs
index de53e75b..7ce03b3b 100644
--- a/libtiny_tui/examples/tabs.rs
+++ b/libtiny_tui/examples/tabs.rs
@@ -20,7 +20,7 @@ fn main() {
 
         for serv_idx in 0..10 {
             let server = format!("server_{}", serv_idx);
-            tui.new_server_tab(&server);
+            tui.new_server_tab(&server, None);
 
             tui.new_chan_tab(&server, "chan_0");
             tui.set_tab_style(
diff --git a/libtiny_tui/src/lib.rs b/libtiny_tui/src/lib.rs
index e2af781f..c47f62b8 100644
--- a/libtiny_tui/src/lib.rs
+++ b/libtiny_tui/src/lib.rs
@@ -160,7 +160,7 @@ macro_rules! delegate {
 
 impl UI for TUI {
     delegate!(draw());
-    delegate!(new_server_tab(serv_name: &str,));
+    delegate!(new_server_tab(serv_name: &str, alias: Option<String>,));
     delegate!(close_server_tab(serv_name: &str,));
     delegate!(new_chan_tab(serv_name: &str, chan: &str,));
     delegate!(close_chan_tab(serv_name: &str, chan: &str,));
diff --git a/libtiny_tui/src/tab.rs b/libtiny_tui/src/tab.rs
index dbb71328..2a072658 100644
--- a/libtiny_tui/src/tab.rs
+++ b/libtiny_tui/src/tab.rs
@@ -9,6 +9,7 @@ use crate::{
 };
 
 pub(crate) struct Tab {
+    pub(crate) alias: Option<String>,
     pub(crate) widget: MessagingUI,
     pub(crate) src: MsgSource,
     pub(crate) style: TabStyle,
@@ -27,7 +28,10 @@ fn tab_style(style: TabStyle, colors: &Colors) -> Style {
 
 impl Tab {
     pub(crate) fn visible_name(&self) -> &str {
-        self.src.visible_name()
+        match self.alias {
+            Some(ref alias) => &alias,
+            None => self.src.visible_name(),
+        }
     }
 
     pub(crate) fn set_style(&mut self, style: TabStyle) {
diff --git a/libtiny_tui/src/tui.rs b/libtiny_tui/src/tui.rs
index 7270429e..85acc138 100644
--- a/libtiny_tui/src/tui.rs
+++ b/libtiny_tui/src/tui.rs
@@ -103,7 +103,7 @@ impl TUI {
 
         // Init "mentions" tab. This needs to happen right after creating the TUI to be able to
         // show any errors in TUI.
-        tui.new_server_tab("mentions");
+        tui.new_server_tab("mentions", None);
         tui.add_client_msg(
             "Any mentions to you will be listed here.",
             &MsgTarget::Server { serv: "mentions" },
@@ -240,7 +240,14 @@ impl TUI {
         self.colors = colors;
     }
 
-    fn new_tab(&mut self, idx: usize, src: MsgSource, status: bool, notifier: Notifier) {
+    fn new_tab(
+        &mut self,
+        idx: usize,
+        src: MsgSource,
+        status: bool,
+        notifier: Notifier,
+        alias: Option<String>,
+    ) {
         use std::collections::HashMap;
 
         let mut switch_keys: HashMap<char, i8> = HashMap::with_capacity(self.tabs.len());
@@ -253,7 +260,11 @@ impl TUI {
         let switch = {
             let mut ret = None;
             let mut n = 0;
-            for ch in src.visible_name().chars() {
+            let visible_name = match alias.as_ref() {
+                None => src.visible_name(),
+                Some(ref alias) => alias,
+            };
+            for ch in visible_name.chars() {
                 if !ch.is_alphabetic() {
                     continue;
                 }
@@ -281,6 +292,7 @@ impl TUI {
         self.tabs.insert(
             idx,
             Tab {
+                alias,
                 widget: MessagingUI::new(self.width, self.height - 1 - statusline_height, status),
                 src,
                 style: TabStyle::Normal,
@@ -291,7 +303,7 @@ impl TUI {
     }
 
     /// Returns index of the new tab if a new tab is created.
-    pub(crate) fn new_server_tab(&mut self, serv: &str) -> Option<usize> {
+    pub(crate) fn new_server_tab(&mut self, serv: &str, alias: Option<String>) -> Option<usize> {
         match self.find_serv_tab_idx(serv) {
             None => {
                 let tab_idx = self.tabs.len();
@@ -302,6 +314,7 @@ impl TUI {
                     },
                     true,
                     Notifier::Mentions,
+                    alias,
                 );
                 Some(tab_idx)
             }
@@ -325,7 +338,7 @@ impl TUI {
         match self.find_chan_tab_idx(serv, chan) {
             None => match self.find_last_serv_tab_idx(serv) {
                 None => {
-                    self.new_server_tab(serv);
+                    self.new_server_tab(serv, None);
                     self.new_chan_tab(serv, chan)
                 }
                 Some(serv_tab_idx) => {
@@ -349,6 +362,7 @@ impl TUI {
                         },
                         status_val,
                         notifier,
+                        None,
                     );
                     if self.active_idx >= tab_idx {
                         self.next_tab();
@@ -379,7 +393,7 @@ impl TUI {
         match self.find_user_tab_idx(serv, nick) {
             None => match self.find_last_serv_tab_idx(serv) {
                 None => {
-                    self.new_server_tab(serv);
+                    self.new_server_tab(serv, None);
                     self.new_user_tab(serv, nick)
                 }
                 Some(tab_idx) => {
@@ -391,6 +405,7 @@ impl TUI {
                         },
                         true,
                         Notifier::Messages,
+                        None,
                     );
                     if let Some(nick) = self.tabs[tab_idx].widget.get_nick().map(str::to_owned) {
                         self.tabs[tab_idx + 1].widget.set_nick(nick);
@@ -1071,7 +1086,7 @@ impl TUI {
     fn maybe_create_tab(&mut self, target: &MsgTarget) -> Option<usize> {
         match *target {
             MsgTarget::Server { serv } | MsgTarget::AllServTabs { serv } => {
-                self.new_server_tab(serv)
+                self.new_server_tab(serv, None)
             }
 
             MsgTarget::Chan { serv, chan } => self.new_chan_tab(serv, chan),
diff --git a/libtiny_ui/src/lib.rs b/libtiny_ui/src/lib.rs
index d10f6fff..3515bafb 100644
--- a/libtiny_ui/src/lib.rs
+++ b/libtiny_ui/src/lib.rs
@@ -91,7 +91,7 @@ pub trait UI: objekt::Clone {
     fn draw(&self);
 
     /// Create a new server tab.
-    fn new_server_tab(&self, serv: &str);
+    fn new_server_tab(&self, serv: &str, alias: Option<String>);
 
     /// Close a server tab and all channel and user tabs for that server.
     fn close_server_tab(&self, serv: &str);
@@ -177,9 +177,9 @@ impl<UI1: UI + Clone, UI2: UI + Clone> UI for CombinedUIs<UI1, UI2> {
         self.ui2.draw();
     }
 
-    fn new_server_tab(&self, serv: &str) {
-        self.ui1.new_server_tab(serv);
-        self.ui2.new_server_tab(serv);
+    fn new_server_tab(&self, serv: &str, alias: Option<String>) {
+        self.ui1.new_server_tab(serv, alias.clone());
+        self.ui2.new_server_tab(serv, alias);
     }
 
     fn close_server_tab(&self, serv: &str) {
diff --git a/tiny/config.yml b/tiny/config.yml
index d985a4fc..0825bdee 100644
--- a/tiny/config.yml
+++ b/tiny/config.yml
@@ -6,6 +6,9 @@ servers:
       realname: yourname
       nicks: [tiny_user]
 
+      # (optional) Server alias for display in tab line
+      # alias: Freenode
+
       # Channels to automatically join
       join:
           - '##rust'
diff --git a/tiny/src/cmd.rs b/tiny/src/cmd.rs
index a8f23eba..a98fa461 100644
--- a/tiny/src/cmd.rs
+++ b/tiny/src/cmd.rs
@@ -244,7 +244,7 @@ fn connect_(
     // can't move the rest to an else branch because of borrowchk
 
     // otherwise create a new Conn, tab etc.
-    ui.new_server_tab(serv_name);
+    ui.new_server_tab(serv_name, None);
     let msg_target = MsgTarget::Server { serv: serv_name };
     ui.add_client_msg("Connecting...", &msg_target);
 
diff --git a/tiny/src/config.rs b/tiny/src/config.rs
index c4b697bc..ab510dce 100644
--- a/tiny/src/config.rs
+++ b/tiny/src/config.rs
@@ -15,6 +15,10 @@ pub(crate) struct Server {
     /// Address of the server
     pub(crate) addr: String,
 
+    /// Optional server alias to be shown in the tab line.
+    #[serde(default)]
+    pub(crate) alias: Option<String>,
+
     /// Port of the server
     pub(crate) port: u16,
 
diff --git a/tiny/src/main.rs b/tiny/src/main.rs
index 8ae491a6..0720349b 100644
--- a/tiny/src/main.rs
+++ b/tiny/src/main.rs
@@ -110,7 +110,7 @@ fn run(
                 Ok(logger) => {
                     // Create "mentions" log file manually -- the tab is already created in the TUI so
                     // we won't be creating a "mentions" file in the logger without this.
-                    logger.new_server_tab("mentions");
+                    logger.new_server_tab("mentions", None);
                     Some(logger)
                 }
             });
@@ -123,7 +123,7 @@ fn run(
         let mut clients: Vec<Client> = Vec::with_capacity(servers.len());
 
         for server in servers.iter().cloned() {
-            tui.new_server_tab(&server.addr);
+            tui.new_server_tab(&server.addr, server.alias);
 
             let server_info = ServerInfo {
                 addr: server.addr,


Test patch:
diff --git a/libtiny_tui/src/tests/mod.rs b/libtiny_tui/src/tests/mod.rs
index e0083ae1..a8903a54 100644
--- a/libtiny_tui/src/tests/mod.rs
+++ b/libtiny_tui/src/tests/mod.rs
@@ -68,8 +68,8 @@ fn init_screen() {
 fn close_rightmost_tab() {
     // After closing right-most tab the tab bar should scroll left.
     let mut tui = TUI::new_test(20, 4);
-    tui.new_server_tab("irc.server_1.org");
-    tui.new_server_tab("irc.server_2.org");
+    tui.new_server_tab("irc.server_1.org", None);
+    tui.new_server_tab("irc.server_2.org", None);
     tui.next_tab();
     tui.next_tab();
     tui.draw();
@@ -113,7 +113,7 @@ fn small_screen_1() {
     let mut tui = TUI::new_test(21, 3);
     let serv = "irc.server_1.org";
     let chan = "#chan";
-    tui.new_server_tab(serv);
+    tui.new_server_tab(serv, None);
     tui.set_nick(serv, "osa1");
     tui.new_chan_tab(serv, chan);
     tui.next_tab();
@@ -159,7 +159,7 @@ fn small_screen_2() {
     let mut tui = TUI::new_test(21, 4);
     let serv = "irc.server_1.org";
     let chan = "#chan";
-    tui.new_server_tab(serv);
+    tui.new_server_tab(serv, None);
     tui.set_nick(serv, "osa1");
     tui.new_chan_tab(serv, chan);
     tui.next_tab();