diff options
| author | Aram Drevekenin <aram@poor.dev> | 2025-06-03 17:15:32 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-03 17:15:32 +0200 |
| commit | a9f8bbcd197c8d14832fc1ab1fbe4d4111a2014d (patch) | |
| tree | 6d354fdd36cf534d73e0cb81a7cacd3fedc1ebb9 /default-plugins/status-bar/src | |
| parent | docs(changelog): theme fixes (diff) | |
| download | sl0ppij-a9f8bbcd197c8d14832fc1ab1fbe4d4111a2014d.tar.gz sl0ppij-a9f8bbcd197c8d14832fc1ab1fbe4d4111a2014d.tar.xz sl0ppij-a9f8bbcd197c8d14832fc1ab1fbe4d4111a2014d.zip | |
feat(ux): improve multiple select (#4221)
* intercept/clear-intercept key APIs
* allow opening a pinned unfocused floating pane
* rework plugin
* improve some apis
* fix tests
* tests for pane groups
* more exact placement and tests
* plugin command permission and cleanup
* improve some multiselect ux
* improve plugin ui
* remove old status indicator
* allow moving plugin out of the way
* style(fmt): rustfmt
* update plugins
* remove old keybinding
* cleanups
* fix: only rename pane if needed
* changelog and some cleanups
* style(fmt): rustfmt
Diffstat (limited to 'default-plugins/status-bar/src')
| -rw-r--r-- | default-plugins/status-bar/src/main.rs | 26 | ||||
| -rw-r--r-- | default-plugins/status-bar/src/one_line_ui.rs | 252 |
2 files changed, 3 insertions, 275 deletions
diff --git a/default-plugins/status-bar/src/main.rs b/default-plugins/status-bar/src/main.rs index dd5d54c5..5bc54da0 100644 --- a/default-plugins/status-bar/src/main.rs +++ b/default-plugins/status-bar/src/main.rs @@ -39,8 +39,6 @@ struct State { display_system_clipboard_failure: bool, classic_ui: bool, base_mode_is_locked: bool, - own_client_id: Option<ClientId>, - grouped_panes_count: Option<usize>, } register_plugin!(State); @@ -199,7 +197,6 @@ impl ZellijPlugin for State { .get("classic") .map(|c| c == "true") .unwrap_or(false); - self.own_client_id = Some(get_plugin_ids().client_id); set_selectable(false); subscribe(&[ EventType::ModeUpdate, @@ -227,28 +224,6 @@ impl ZellijPlugin for State { } self.tabs = tabs; }, - Event::PaneUpdate(pane_manifest) => { - if let Some(own_client_id) = self.own_client_id { - let mut grouped_panes_count = 0; - for (_tab_index, pane_infos) in pane_manifest.panes { - for pane_info in pane_infos { - let is_in_pane_group = - pane_info.index_in_pane_group.get(&own_client_id).is_some(); - if is_in_pane_group { - grouped_panes_count += 1; - } - } - } - if Some(grouped_panes_count) != self.grouped_panes_count { - if grouped_panes_count == 0 { - self.grouped_panes_count = None; - } else { - self.grouped_panes_count = Some(grouped_panes_count); - } - should_render = true; - } - } - }, Event::CopyToClipboard(copy_destination) => { match self.text_copy_destination { Some(text_copy_destination) => { @@ -306,7 +281,6 @@ impl ZellijPlugin for State { self.base_mode_is_locked, self.text_copy_destination, self.display_system_clipboard_failure, - self.grouped_panes_count, ), fill_bg, ); diff --git a/default-plugins/status-bar/src/one_line_ui.rs b/default-plugins/status-bar/src/one_line_ui.rs index f6b88491..5abf67b6 100644 --- a/default-plugins/status-bar/src/one_line_ui.rs +++ b/default-plugins/status-bar/src/one_line_ui.rs @@ -6,7 +6,7 @@ use ansi_term::{ use std::collections::HashMap; use zellij_tile::prelude::actions::Action; use zellij_tile::prelude::*; -use zellij_tile_utils::{palette_match, style}; +use zellij_tile_utils::palette_match; use crate::first_line::{to_char, KeyAction, KeyMode, KeyShortcut}; use crate::second_line::{system_clipboard_error, text_copied_hint}; @@ -22,7 +22,6 @@ pub fn one_line_ui( base_mode_is_locked: bool, text_copied_to_clipboard_destination: Option<CopyDestination>, clipboard_failure: bool, - grouped_pane_count: Option<usize>, ) -> LinePart { if let Some(text_copied_to_clipboard_destination) = text_copied_to_clipboard_destination { return text_copied_hint(text_copied_to_clipboard_destination); @@ -36,18 +35,11 @@ pub fn one_line_ui( *max_len = max_len.saturating_sub(line_part.len); }; - let currently_marking_pane_group = help.currently_marking_pane_group.unwrap_or(false); render_mode_key_indicators(help, max_len, separator, base_mode_is_locked) .map(|mode_key_indicators| append(&mode_key_indicators, &mut max_len)) .and_then(|_| match help.mode { - InputMode::Normal | InputMode::Locked => match grouped_pane_count { - Some(grouped_pane_count) => { - render_group_controls(help, grouped_pane_count, max_len) - }, - None if currently_marking_pane_group => render_group_controls(help, 0, max_len), - None => render_secondary_info(help, tab_info, max_len), - } - .map(|secondary_info| append(&secondary_info, &mut max_len)), + InputMode::Normal | InputMode::Locked => render_secondary_info(help, tab_info, max_len) + .map(|secondary_info| append(&secondary_info, &mut max_len)), _ => add_keygroup_separator(help, max_len) .map(|key_group_separator| append(&key_group_separator, &mut max_len)) .and_then(|_| keybinds(help, max_len)) @@ -664,225 +656,6 @@ fn render_common_modifiers( line_part_to_render.len += prefix_text.chars().count() + separator.chars().count(); } -fn render_group_controls( - help: &ModeInfo, - grouped_pane_count: usize, - max_len: usize, -) -> Option<LinePart> { - let currently_marking_group = help.currently_marking_pane_group.unwrap_or(false); - let keymap = help.get_mode_keybinds(); - let (common_modifiers, multiple_select_key, pane_group_toggle_key, group_mark_toggle_key) = { - let multiple_select_key = multiple_select_key(&keymap); - let pane_group_toggle_key = single_action_key(&keymap, &[Action::TogglePaneInGroup]); - let group_mark_toggle_key = single_action_key(&keymap, &[Action::ToggleGroupMarking]); - let common_modifiers = get_common_modifiers( - vec![ - multiple_select_key.iter().next(), - pane_group_toggle_key.iter().next(), - group_mark_toggle_key.iter().next(), - ] - .into_iter() - .filter_map(|k| k) - .collect(), - ); - let multiple_select_key: Vec<KeyWithModifier> = multiple_select_key - .iter() - .map(|k| k.strip_common_modifiers(&common_modifiers)) - .collect(); - let pane_group_toggle_key: Vec<KeyWithModifier> = pane_group_toggle_key - .iter() - .map(|k| k.strip_common_modifiers(&common_modifiers)) - .collect(); - let group_mark_toggle_key: Vec<KeyWithModifier> = group_mark_toggle_key - .iter() - .map(|k| k.strip_common_modifiers(&common_modifiers)) - .collect(); - ( - common_modifiers, - multiple_select_key, - pane_group_toggle_key, - group_mark_toggle_key, - ) - }; - let multiple_select_key = multiple_select_key - .iter() - .next() - .map(|key| format!("{}", key)) - .unwrap_or("UNBOUND".to_owned()); - let pane_group_toggle_key = pane_group_toggle_key - .iter() - .next() - .map(|key| format!("{}", key)) - .unwrap_or("UNBOUND".to_owned()); - let group_mark_toggle_key = group_mark_toggle_key - .iter() - .next() - .map(|key| format!("{}", key)) - .unwrap_or("UNBOUND".to_owned()); - let background = help.style.colors.text_unselected.background; - let foreground = help.style.colors.text_unselected.base; - let superkey_prefix_style = style!(foreground, background).bold(); - let common_modifier_text = if common_modifiers.is_empty() { - "".to_owned() - } else { - format!( - "{} + ", - common_modifiers - .iter() - .map(|c| c.to_string()) - .collect::<Vec<_>>() - .join("-") - ) - }; - - // full - let full_selected_panes_text = if common_modifier_text.is_empty() { - format!("{} SELECTED PANES", grouped_pane_count) - } else { - format!("{} SELECTED PANES |", grouped_pane_count) - }; - let full_group_actions_text = format!("<{}> Group Actions", &multiple_select_key); - let full_toggle_group_text = format!("<{}> Toggle Group", &pane_group_toggle_key); - let full_group_mark_toggle_text = format!("<{}> Follow Focus", &group_mark_toggle_key); - let ribbon_paddings_len = 12; - let full_controls_line_len = full_selected_panes_text.chars().count() - + 1 - + common_modifier_text.chars().count() - + full_group_actions_text.chars().count() - + full_toggle_group_text.chars().count() - + full_group_mark_toggle_text.chars().count() - + ribbon_paddings_len - + 1; // 1 for the end padding - - // medium - let medium_selected_panes_text = if common_modifier_text.is_empty() { - format!("{} SELECTED", grouped_pane_count) - } else { - format!("{} SELECTED |", grouped_pane_count) - }; - let medium_group_actions_text = format!("<{}> Actions", &multiple_select_key); - let medium_toggle_group_text = format!("<{}> Toggle", &pane_group_toggle_key); - let medium_group_mark_toggle_text = format!("<{}> Follow", &group_mark_toggle_key); - let ribbon_paddings_len = 12; - let medium_controls_line_len = medium_selected_panes_text.chars().count() - + 1 - + common_modifier_text.chars().count() - + medium_group_actions_text.chars().count() - + medium_toggle_group_text.chars().count() - + medium_group_mark_toggle_text.chars().count() - + ribbon_paddings_len - + 1; // 1 for the end padding - - // short - let short_selected_panes_text = if common_modifier_text.is_empty() { - format!("{} SELECTED", grouped_pane_count) - } else { - format!("{} SELECTED |", grouped_pane_count) - }; - let short_group_actions_text = format!("<{}>", &multiple_select_key); - let short_toggle_group_text = format!("<{}>", &pane_group_toggle_key); - let short_group_mark_toggle_text = format!("<{}>", &group_mark_toggle_key); - let color_emphasis_range_end = if common_modifier_text.is_empty() { - 0 - } else { - 2 - }; - let ribbon_paddings_len = 12; - let short_controls_line_len = short_selected_panes_text.chars().count() - + 1 - + common_modifier_text.chars().count() - + short_group_actions_text.chars().count() - + short_toggle_group_text.chars().count() - + short_group_mark_toggle_text.chars().count() - + ribbon_paddings_len - + 1; // 1 for the end padding - - let ( - selected_panes_text, - group_actions_text, - toggle_group_text, - group_mark_toggle_text, - controls_line_len, - ) = if max_len >= full_controls_line_len { - ( - full_selected_panes_text, - full_group_actions_text, - full_toggle_group_text, - full_group_mark_toggle_text, - full_controls_line_len, - ) - } else if max_len >= medium_controls_line_len { - ( - medium_selected_panes_text, - medium_group_actions_text, - medium_toggle_group_text, - medium_group_mark_toggle_text, - medium_controls_line_len, - ) - } else if max_len >= short_controls_line_len { - ( - short_selected_panes_text, - short_group_actions_text, - short_toggle_group_text, - short_group_mark_toggle_text, - short_controls_line_len, - ) - } else { - return None; - }; - let selected_panes = serialize_text( - &Text::new(&selected_panes_text) - .color_range( - 3, - ..selected_panes_text - .chars() - .count() - .saturating_sub(color_emphasis_range_end), - ) - .opaque(), - ); - let group_actions_ribbon = serialize_ribbon( - &Text::new(&group_actions_text).color_range(0, 1..=multiple_select_key.chars().count()), - ); - let toggle_group_ribbon = serialize_ribbon( - &Text::new(&toggle_group_text).color_range(0, 1..=pane_group_toggle_key.chars().count()), - ); - let mut group_mark_toggle_ribbon = Text::new(&group_mark_toggle_text) - .color_range(0, 1..=group_mark_toggle_key.chars().count()); - if currently_marking_group { - group_mark_toggle_ribbon = group_mark_toggle_ribbon.selected(); - } - let group_mark_toggle_ribbon = serialize_ribbon(&group_mark_toggle_ribbon); - let controls_line = if common_modifiers.is_empty() { - format!( - "{} {}{}{}", - selected_panes, group_actions_ribbon, toggle_group_ribbon, group_mark_toggle_ribbon - ) - } else { - let common_modifier = - serialize_text(&Text::new(&common_modifier_text).color_range(0, ..).opaque()); - format!( - "{} {}{}{}{}", - selected_panes, - common_modifier, - group_actions_ribbon, - toggle_group_ribbon, - group_mark_toggle_ribbon - ) - }; - let remaining_space = max_len.saturating_sub(controls_line_len); - let mut padding = String::new(); - let mut padding_len = 0; - for _ in 0..remaining_space { - padding.push_str(&ANSIStrings(&[superkey_prefix_style.paint(" ")]).to_string()); - padding_len += 1; - } - Some(LinePart { - part: format!("{}{}", padding, controls_line), - len: controls_line_len + padding_len, - }) -} - fn render_secondary_info( help: &ModeInfo, tab_info: Option<&TabInfo>, @@ -1745,25 +1518,6 @@ fn configuration_key(keymap: &[(KeyWithModifier, Vec<Action>)]) -> Vec<KeyWithMo } } -fn multiple_select_key(keymap: &[(KeyWithModifier, Vec<Action>)]) -> Vec<KeyWithModifier> { - let mut matching = keymap.iter().find_map(|(key, acvec)| { - let has_match = acvec - .iter() - .find(|a| a.launches_plugin("zellij:multiple-select")) // TODO: make this an alias - .is_some(); - if has_match { - Some(key.clone()) - } else { - None - } - }); - if let Some(matching) = matching.take() { - vec![matching] - } else { - vec![] - } -} - fn style_key_with_modifier(keyvec: &[KeyWithModifier], color_index: Option<usize>) -> LinePart { if keyvec.is_empty() { return LinePart::default(); |
