use ansi_term::ANSIStrings; use zellij_tile::prelude::*; use crate::color_elements; use crate::{ColoredElements, LinePart}; struct CtrlKeyShortcut { mode: CtrlKeyMode, action: CtrlKeyAction, } impl CtrlKeyShortcut { pub fn new(mode: CtrlKeyMode, action: CtrlKeyAction) -> Self { CtrlKeyShortcut { mode, action } } } enum CtrlKeyAction { Lock, Pane, Tab, Resize, Scroll, Quit, Session, Move, } enum CtrlKeyMode { Unselected, Selected, Disabled, } impl CtrlKeyShortcut { pub fn full_text(&self) -> String { match self.action { CtrlKeyAction::Lock => String::from("LOCK"), CtrlKeyAction::Pane => String::from("PANE"), CtrlKeyAction::Tab => String::from("TAB"), CtrlKeyAction::Resize => String::from("RESIZE"), CtrlKeyAction::Scroll => String::from("SCROLL"), CtrlKeyAction::Quit => String::from("QUIT"), CtrlKeyAction::Session => String::from("SESSION"), CtrlKeyAction::Move => String::from("MOVE"), } } pub fn letter_shortcut(&self) -> char { match self.action { CtrlKeyAction::Lock => 'g', CtrlKeyAction::Pane => 'p', CtrlKeyAction::Tab => 't', CtrlKeyAction::Resize => 'n', CtrlKeyAction::Scroll => 's', CtrlKeyAction::Quit => 'q', CtrlKeyAction::Session => 'o', CtrlKeyAction::Move => 'h', } } } fn unselected_mode_shortcut( letter: char, text: &str, palette: ColoredElements, separator: &str, ) -> LinePart { let prefix_separator = palette.unselected_prefix_separator.paint(separator); let char_left_separator = palette.unselected_char_left_separator.paint(" <"); let char_shortcut = palette.unselected_char_shortcut.paint(letter.to_string()); let char_right_separator = palette.unselected_char_right_separator.paint(">"); let styled_text = palette.unselected_styled_text.paint(format!("{} ", text)); let suffix_separator = palette.unselected_suffix_separator.paint(separator); LinePart { part: ANSIStrings(&[ prefix_separator, char_left_separator, char_shortcut, char_right_separator, styled_text, suffix_separator, ]) .to_string(), len: text.chars().count() + 7, // 2 for the arrows, 3 for the char separators, 1 for the character, 1 for the text padding } } fn selected_mode_shortcut( letter: char, text: &str, palette: ColoredElements, separator: &str, ) -> LinePart { let prefix_separator = palette.selected_prefix_separator.paint(separator); let char_left_separator = palette.selected_char_left_separator.paint(" <".to_string()); let char_shortcut = palette.selected_char_shortcut.paint(letter.to_string()); let char_right_separator = palette.selected_char_right_separator.paint(">".to_string()); let styled_text = palette.selected_styled_text.paint(format!("{} ", text)); let suffix_separator = palette.selected_suffix_separator.paint(separator); LinePart { part: ANSIStrings(&[ prefix_separator, char_left_separator, char_shortcut, char_right_separator, styled_text, suffix_separator, ]) .to_string(), len: text.chars().count() + 7, // 2 for the arrows, 3 for the char separators, 1 for the character, 1 for the text padding } } fn disabled_mode_shortcut(text: &str, palette: ColoredElements, separator: &str) -> LinePart { let prefix_separator = palette.disabled_prefix_separator.paint(separator); let styled_text = palette.disabled_styled_text.paint(format!("{} ", text)); let suffix_separator = palette.disabled_suffix_separator.paint(separator); LinePart { part: format!("{}{}{}", prefix_separator, styled_text, suffix_separator), len: text.chars().count() + 2 + 1, // 2 for the arrows, 1 for the padding in the end } } fn selected_mode_shortcut_single_letter( letter: char, palette: ColoredElements, separator: &str, ) -> LinePart { let char_shortcut_text = format!(" {} ", letter); let len = char_shortcut_text.chars().count() + 4; // 2 for the arrows, 2 for the padding let prefix_separator = palette .selected_single_letter_prefix_separator .paint(separator); let char_shortcut = palette .selected_single_letter_char_shortcut .paint(char_shortcut_text); let suffix_separator = palette .selected_single_letter_suffix_separator .paint(separator); LinePart { part: ANSIStrings(&[prefix_separator, char_shortcut, suffix_separator]).to_string(), len, } } fn unselected_mode_shortcut_single_letter( letter: char, palette: ColoredElements, separator: &str, ) -> LinePart { let char_shortcut_text = format!(" {} ", letter); let len = char_shortcut_text.chars().count() + 4; // 2 for the arrows, 2 for the padding let prefix_separator = palette .unselected_single_letter_prefix_separator .paint(separator); let char_shortcut = palette .unselected_single_letter_char_shortcut .paint(char_shortcut_text); let suffix_separator = palette .unselected_single_letter_suffix_separator .paint(separator); LinePart { part: ANSIStrings(&[prefix_separator, char_shortcut, suffix_separator]).to_string(), len, } } fn full_ctrl_key(key: &CtrlKeyShortcut, palette: ColoredElements, separator: &str) -> LinePart { let full_text = key.full_text(); let letter_shortcut = key.letter_shortcut(); match key.mode { CtrlKeyMode::Unselected => unselected_mode_shortcut( letter_shortcut, &format!(" {}", full_text), palette, separator, ), CtrlKeyMode::Selected => selected_mode_shortcut( letter_shortcut, &format!(" {}", full_text), palette, separator, ), CtrlKeyMode::Disabled => disabled_mode_shortcut( &format!(" <{}> {}", letter_shortcut, full_text), palette, separator, ), } } fn single_letter_ctrl_key( key: &CtrlKeyShortcut, palette: ColoredElements, separator: &str, ) -> LinePart { let letter_shortcut = key.letter_shortcut(); match key.mode { CtrlKeyMode::Unselected => { unselected_mode_shortcut_single_letter(letter_shortcut, palette, separator) } CtrlKeyMode::Selected => { selected_mode_shortcut_single_letter(letter_shortcut, palette, separator) } CtrlKeyMode::Disabled => { disabled_mode_shortcut(&format!(" {}", letter_shortcut), palette, separator) } } } fn key_indicators( max_len: usize, keys: &[CtrlKeyShortcut], palette: ColoredElements, separator: &str, ) -> LinePart { let mut line_part = LinePart::default(); for ctrl_key in keys { let key = full_ctrl_key(ctrl_key, palette, separator); line_part.part = format!("{}{}", line_part.part, key.part); line_part.len += key.len; } if line_part.len < max_len { return line_part; } line_part = LinePart::default(); for ctrl_key in keys { let key = single_letter_ctrl_key(ctrl_key, palette, separator); line_part.part = format!("{}{}", line_part.part, key.part); line_part.len += key.len; } if line_part.len < max_len { return line_part; } line_part = LinePart::default(); line_part } pub fn superkey(palette: ColoredElements, separator: &str) -> LinePart { let prefix_text = " Ctrl +"; let prefix = palette.superkey_prefix.paint(prefix_text); let suffix_separator = palette.superkey_suffix_separator.paint(separator); LinePart { part: ANSIStrings(&[prefix, suffix_separator]).to_string(), len: prefix_text.chars().count(), } } pub fn ctrl_keys(help: &ModeInfo, max_len: usize, separator: &str) -> LinePart { let colored_elements = color_elements(help.style.colors); match &help.mode { InputMode::Locked => key_indicators( max_len, &[ CtrlKeyShortcut::new(CtrlKeyMode::Selected, CtrlKeyAction::Lock), CtrlKeyShortcut::new(CtrlKeyMode::Disabled, CtrlKeyAction::Pane), CtrlKeyShortcut::new(CtrlKeyMode::Disabled, CtrlKeyAction::Tab), CtrlKeyShortcut::new(CtrlKeyMode::Disabled, CtrlKeyAction::Resize), CtrlKeyShortcut::new(CtrlKeyMode::Disabled, CtrlKeyAction::Move), CtrlKeyShortcut::new(CtrlKeyMode::Disabled, CtrlKeyAction::Scroll), CtrlKeyShortcut::new(CtrlKeyMode::Disabled, CtrlKeyAction::Session), CtrlKeyShortcut::new(CtrlKeyMode::Disabled, CtrlKeyAction::Quit), ], colored_elements, separator, ), InputMode::Resize => key_indicators( max_len, &[ CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Lock), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Pane), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Tab), CtrlKeyShortcut::new(CtrlKeyMode::Selected, CtrlKeyAction::Resize), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Move), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Scroll), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Session), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Quit), ], colored_elements, separator, ), InputMode::Pane | InputMode::RenamePane => key_indicators( max_len, &[ CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Lock), CtrlKeyShortcut::new(CtrlKeyMode::Selected, CtrlKeyAction::Pane), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Tab), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Resize), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Move), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Scroll), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Session), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Quit), ], colored_elements, separator, ), InputMode::Tab | InputMode::RenameTab => key_indicators( max_len, &[ CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Lock), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Pane), CtrlKeyShortcut::new(CtrlKeyMode::Selected, CtrlKeyAction::Tab), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Resize), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Move), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Scroll), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Session), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Quit), ], colored_elements, separator, ), InputMode::Scroll => key_indicators( max_len, &[ CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Lock), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Pane), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Tab), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Resize), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Move), CtrlKeyShortcut::new(CtrlKeyMode::Selected, CtrlKeyAction::Scroll), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Session), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Quit), ], colored_elements, separator, ), InputMode::Move => key_indicators( max_len, &[ CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Lock), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Pane), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Tab), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Resize), CtrlKeyShortcut::new(CtrlKeyMode::Selected, CtrlKeyAction::Move), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Scroll), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Session), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Quit), ], colored_elements, separator, ), InputMode::Normal | InputMode::Prompt => key_indicators( max_len, &[ CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Lock), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Pane), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Tab), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Resize), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Move), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Scroll), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Session), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Quit), ], colored_elements, separator, ), InputMode::Session => key_indicators( max_len, &[ CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Lock), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Pane), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Tab), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Resize), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Move), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Scroll), CtrlKeyShortcut::new(CtrlKeyMode::Selected, CtrlKeyAction::Session), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Quit), ], colored_elements, separator, ), InputMode::Tmux => key_indicators( max_len, &[ CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Lock), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Pane), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Tab), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Resize), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Move), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Scroll), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Session), CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Quit), ], colored_elements, separator, ), } }