Improved formatting of tab title

Mikayla Maki created

Change summary

crates/terminal/src/terminal_container_view.rs | 36 ++++++++++++-------
crates/util/src/lib.rs                         | 17 +++++++++
2 files changed, 40 insertions(+), 13 deletions(-)

Detailed changes

crates/terminal/src/terminal_container_view.rs 🔗

@@ -7,6 +7,7 @@ use gpui::{
     actions, elements::*, AnyViewHandle, AppContext, Entity, ModelHandle, MutableAppContext, Task,
     View, ViewContext, ViewHandle,
 };
+use util::truncate_and_trailoff;
 use workspace::searchable::{SearchEvent, SearchOptions, SearchableItem, SearchableItemHandle};
 use workspace::{Item, Workspace};
 
@@ -253,19 +254,28 @@ impl Item for TerminalContainer {
                 .as_ref()
                 .map(|fpi| {
                     format!(
-                        "{} - {}{}",
-                        fpi.cwd
-                            .file_name()
-                            .map(|name| name.to_string_lossy().to_string())
-                            .unwrap_or_default(),
-                        fpi.name,
-                        {
-                            if fpi.argv.len() >= 1 {
-                                format!(" {}", (&fpi.argv[1..]).join(" "))
-                            } else {
-                                "".to_string()
-                            }
-                        }
+                        "{} — {}",
+                        truncate_and_trailoff(
+                            &fpi.cwd
+                                .file_name()
+                                .map(|name| name.to_string_lossy().to_string())
+                                .unwrap_or_default(),
+                            25
+                        ),
+                        truncate_and_trailoff(
+                            &{
+                                format!(
+                                    "{}{}",
+                                    fpi.name,
+                                    if fpi.argv.len() >= 1 {
+                                        format!(" {}", (&fpi.argv[1..]).join(" "))
+                                    } else {
+                                        "".to_string()
+                                    }
+                                )
+                            },
+                            25
+                        )
                     )
                 })
                 .unwrap_or_else(|| "Terminal".to_string()),

crates/util/src/lib.rs 🔗

@@ -9,6 +9,23 @@ use std::{
     task::{Context, Poll},
 };
 
+pub fn truncate(s: &str, max_chars: usize) -> &str {
+    match s.char_indices().nth(max_chars) {
+        None => s,
+        Some((idx, _)) => &s[..idx],
+    }
+}
+
+pub fn truncate_and_trailoff(s: &str, max_chars: usize) -> String {
+    debug_assert!(max_chars >= 5);
+
+    if s.len() > max_chars {
+        format!("{}…", truncate(&s, max_chars.saturating_sub(3)))
+    } else {
+        s.to_string()
+    }
+}
+
 pub fn post_inc<T: From<u8> + AddAssign<T> + Copy>(value: &mut T) -> T {
     let prev = *value;
     *value += T::from(1);