Skip to content

Commit

Permalink
feat: render truncated tab count to indicator
Browse files Browse the repository at this point in the history
  • Loading branch information
dj95 committed Jun 23, 2024
1 parent b286e02 commit 4c382a7
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 29 deletions.
4 changes: 2 additions & 2 deletions plugin-dev-workspace.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ layout {
tab_sync_indicator "S"
tab_fullscreen_indicator "FS"
tab_display_count "3"
tab_truncate_start_format "#[fg=red,bg=#181825] < ..."
tab_truncate_end_format "#[fg=red,bg=#181825] ...>"
tab_truncate_start_format "#[fg=red,bg=#181825] < +{count} ..."
tab_truncate_end_format "#[fg=red,bg=#181825] ... +{count} >"

command_0_command "echo \"平仮名, ひらがな 📦\""
command_0_clickaction "bash -c \"zellij --session zjstatus-dev pipe 'zjstatus::notify::hello world!' -n zjstatus\""
Expand Down
78 changes: 51 additions & 27 deletions src/widgets/tabs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,15 @@ impl Widget for TabsWidget {
let (truncated_start, truncated_end, tabs) =
get_tab_window(&state.tabs, self.tab_display_count);

if truncated_start {
if truncated_start > 0 {
if let Some(f) = &self.tab_truncate_start_format {
output = format!("{}{output}", f.format_string(&f.content));
let mut content = f.content.clone();

if content.contains("{count}") {
content = content.replace("{count}", (truncated_start).to_string().as_str());
}

output = format!("{}{output}", f.format_string(&content));
}
}

Expand All @@ -129,9 +135,15 @@ impl Widget for TabsWidget {
}
}

if truncated_end {
if truncated_end > 0 {
if let Some(f) = &self.tab_truncate_end_format {
output = format!("{output}{}", f.format_string(&f.content));
let mut content = f.content.clone();

if content.contains("{count}") {
content = content.replace("{count}", (truncated_end).to_string().as_str());
}

output = format!("{output}{}", f.format_string(&content));
}
}

Expand All @@ -153,9 +165,15 @@ impl Widget for TabsWidget {
.position
+ 1;

if truncated_start {
if truncated_start > 0 {
if let Some(f) = &self.tab_truncate_start_format {
offset = console::measure_text_width(&f.format_string(&f.content));
let mut content = f.content.clone();

if content.contains("{count}") {
content = content.replace("{count}", (truncated_end).to_string().as_str());
}

offset = console::measure_text_width(&f.format_string(&content));

if pos <= offset {
switch_tab_to(active_pos.saturating_sub(1) as u32);
Expand Down Expand Up @@ -186,9 +204,15 @@ impl Widget for TabsWidget {
offset += content_len;
}

if truncated_end {
if truncated_end > 0 {
if let Some(f) = &self.tab_truncate_end_format {
offset += console::measure_text_width(&f.format_string(&f.content));
let mut content = f.content.clone();

if content.contains("{count}") {
content = content.replace("{count}", (truncated_end).to_string().as_str());
}

offset += console::measure_text_width(&f.format_string(&content));

if pos <= offset {
switch_tab_to(cmp::min(active_pos + 1, state.tabs.len()) as u32);
Expand Down Expand Up @@ -312,23 +336,26 @@ impl TabsWidget {
}
}

pub fn get_tab_window(tabs: &Vec<TabInfo>, max_count: Option<usize>) -> (bool, bool, Vec<TabInfo>) {
pub fn get_tab_window(
tabs: &Vec<TabInfo>,
max_count: Option<usize>,
) -> (usize, usize, Vec<TabInfo>) {
let max_count = match max_count {
Some(count) => count,
None => return (false, false, tabs.to_vec()),
None => return (0, 0, tabs.to_vec()),
};

if tabs.len() <= max_count {
return (false, false, tabs.to_vec());
return (0, 0, tabs.to_vec());
}

let active_index = tabs.iter().position(|t| t.active).expect("no active tab");

// active tab is in the last #max_count tabs, so return the last #max_count
if active_index > tabs.len().saturating_sub(max_count) {
return (
true,
false,
tabs.len().saturating_sub(max_count),
0,
tabs.iter()
.cloned()
.rev()
Expand All @@ -342,12 +369,9 @@ pub fn get_tab_window(tabs: &Vec<TabInfo>, max_count: Option<usize>) -> (bool, b
let first_index = active_index.saturating_sub(1);
let last_index = cmp::min(first_index + max_count, tabs.len());

let truncated_start = first_index > 0;
let truncated_end = last_index < tabs.len();

return (
truncated_start,
truncated_end,
first_index,
tabs.len().saturating_sub(last_index),
tabs.as_slice()[first_index..last_index].to_vec(),
);
}
Expand Down Expand Up @@ -389,7 +413,7 @@ mod test {
},
],
Some(3),
(true, true, vec![
(1, 1, vec![
TabInfo {
active: false,
name: "2".to_owned(),
Expand Down Expand Up @@ -437,7 +461,7 @@ mod test {
},
],
Some(3),
(false, true, vec![
(0, 2, vec![
TabInfo {
active: true,
name: "1".to_owned(),
Expand Down Expand Up @@ -485,7 +509,7 @@ mod test {
},
],
Some(3),
(false, true, vec![
(0, 2, vec![
TabInfo {
active: false,
name: "1".to_owned(),
Expand Down Expand Up @@ -533,7 +557,7 @@ mod test {
},
],
Some(3),
(true, false, vec![
(2, 0, vec![
TabInfo {
active: false,
name: "3".to_owned(),
Expand Down Expand Up @@ -581,7 +605,7 @@ mod test {
},
],
Some(3),
(true, false, vec![
(2, 0, vec![
TabInfo {
active: false,
name: "3".to_owned(),
Expand Down Expand Up @@ -629,7 +653,7 @@ mod test {
},
],
None,
(false, false, vec![
(0, 0, vec![
TabInfo {
active: false,
name: "1".to_owned(),
Expand Down Expand Up @@ -672,7 +696,7 @@ mod test {
},
],
Some(3),
(false, false, vec![
(0, 0, vec![
TabInfo {
active: false,
name: "1".to_owned(),
Expand Down Expand Up @@ -705,7 +729,7 @@ mod test {
},
],
Some(3),
(false, false, vec![
(0, 0, vec![
TabInfo {
active: false,
name: "1".to_owned(),
Expand All @@ -727,7 +751,7 @@ mod test {
pub fn test_get_tab_window(
#[case] tabs: Vec<TabInfo>,
#[case] max_count: Option<usize>,
#[case] expected: (bool, bool, Vec<TabInfo>),
#[case] expected: (usize, usize, Vec<TabInfo>),
) {
let res = get_tab_window(&tabs, max_count);

Expand Down

0 comments on commit 4c382a7

Please sign in to comment.