use clap::ArgEnum; use serde::{Deserialize, Serialize}; use std::fmt; use std::str::FromStr; use strum_macros::{EnumDiscriminants, EnumIter, EnumString, ToString}; pub type ClientId = u16; // TODO: merge with crate type? pub fn client_id_to_colors( client_id: ClientId, colors: Palette, ) -> Option<(PaletteColor, PaletteColor)> { // (primary color, secondary color) match client_id { 1 => Some((colors.magenta, colors.black)), 2 => Some((colors.blue, colors.black)), 3 => Some((colors.purple, colors.black)), 4 => Some((colors.yellow, colors.black)), 5 => Some((colors.cyan, colors.black)), 6 => Some((colors.gold, colors.black)), 7 => Some((colors.red, colors.black)), 8 => Some((colors.silver, colors.black)), 9 => Some((colors.pink, colors.black)), 10 => Some((colors.brown, colors.black)), _ => None, } } pub fn single_client_color(colors: Palette) -> (PaletteColor, PaletteColor) { (colors.green, colors.black) } #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum Key { Backspace, Left, Right, Up, Down, Home, End, PageUp, PageDown, BackTab, Delete, Insert, F(u8), Char(char), Alt(char), Ctrl(char), Null, Esc, } #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] // FIXME: This should be extended to handle different button clicks (not just // left click) and the `ScrollUp` and `ScrollDown` events could probably be // merged into a single `Scroll(isize)` event. pub enum Mouse { ScrollUp(usize), // number of lines ScrollDown(usize), // number of lines LeftClick(isize, usize), // line and column RightClick(isize, usize), // line and column Hold(isize, usize), // line and column Release(isize, usize), // line and column } #[derive(Debug, Clone, PartialEq, EnumDiscriminants, ToString, Serialize, Deserialize)] #[strum_discriminants(derive(EnumString, Hash, Serialize, Deserialize))] #[strum_discriminants(name(EventType))] #[non_exhaustive] pub enum Event { ModeUpdate(ModeInfo), TabUpdate(Vec), Key(Key), Mouse(Mouse), Timer(f64), CopyToClipboard(CopyDestination), SystemClipboardFailure, InputReceived, Visible(bool), } /// Describes the different input modes, which change the way that keystrokes will be interpreted. #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, EnumIter, Serialize, Deserialize, ArgEnum)] pub enum InputMode { /// In `Normal` mode, input is always written to the terminal, except for the shortcuts leading /// to other modes #[serde(alias = "normal")] Normal, /// In `Locked` mode, input is always written to the terminal and all shortcuts are disabled /// except the one leading back to normal mode #[serde(alias = "locked")] Locked, /// `Resize` mode allows resizing the different existing panes. #[serde(alias = "resize")] Resize, /// `Pane` mode allows creating and closing panes, as well as moving between them. #[serde(alias = "pane")] Pane, /// `Tab` mode allows creating and closing tabs, as well as moving between them. #[serde(alias = "tab")] Tab, /// `Scroll` mode allows scrolling up and down within a pane. #[serde(alias = "scroll")] Scroll, /// `RenameTab` mode allows assigning a new name to a tab. #[serde(alias = "renametab")] RenameTab, /// `RenamePane` mode allows assigning a new name to a pane. #[serde(alias = "renamepane")] RenamePane, /// `Session` mode allows detaching sessions #[serde(alias = "session")] Session, /// `Move` mode allows moving the different existing panes within a tab #[serde(alias = "move")] Move, /// `Prompt` mode allows interacting with active prompts. #[serde(alias = "prompt")] Prompt, /// `Tmux` mode allows for basic tmux keybindings functionality #[serde(alias = "tmux")] Tmux, } impl Default for InputMode { fn default() -> InputMode { InputMode::Normal } } #[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] pub enum ThemeHue { Light, Dark, } impl Default for ThemeHue { fn default() -> ThemeHue { ThemeHue::Dark } } #[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] pub enum PaletteColor { Rgb((u8, u8, u8)), EightBit(u8), } impl Default for PaletteColor { fn default() -> PaletteColor { PaletteColor::EightBit(0) } } impl FromStr for InputMode { type Err = Box; fn from_str(s: &str) -> Result { match s { "normal" => Ok(InputMode::Normal), "resize" => Ok(InputMode::Resize), "locked" => Ok(InputMode::Locked), "pane" => Ok(InputMode::Pane), "tab" => Ok(InputMode::Tab), "scroll" => Ok(InputMode::Scroll), "renametab" => Ok(InputMode::RenameTab), "session" => Ok(InputMode::Session), "move" => Ok(InputMode::Move), "tmux" => Ok(InputMode::Tmux), "prompt" => Ok(InputMode::Prompt), "renamepane" => Ok(InputMode::RenamePane), e => Err(e.to_string().into()), } } } #[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] pub enum PaletteSource { Default, Xresources, } impl Default for PaletteSource { fn default() -> PaletteSource { PaletteSource::Default } } #[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, Default)] pub struct Palette { pub source: PaletteSource, pub theme_hue: ThemeHue, pub fg: PaletteColor, pub bg: PaletteColor, pub black: PaletteColor, pub red: PaletteColor, pub green: PaletteColor, pub yellow: PaletteColor, pub blue: PaletteColor, pub magenta: PaletteColor, pub cyan: PaletteColor, pub white: PaletteColor, pub orange: PaletteColor, pub gray: PaletteColor, pub purple: PaletteColor, pub gold: PaletteColor, pub silver: PaletteColor, pub pink: PaletteColor, pub brown: PaletteColor, } /// Represents the contents of the help message that is printed in the status bar, /// which indicates the current [`InputMode`] and what the keybinds for that mode /// are. Related to the default `status-bar` plugin. #[derive(Default, Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct ModeInfo { pub mode: InputMode, // FIXME: This should probably return Keys and Actions, then sort out strings plugin-side pub keybinds: Vec<(String, String)>, // => pub palette: Palette, pub capabilities: PluginCapabilities, pub session_name: Option, } #[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] pub struct TabInfo { /* subset of fields to publish to plugins */ pub position: usize, pub name: String, pub active: bool, pub panes_to_hide: usize, pub is_fullscreen_active: bool, pub is_sync_panes_active: bool, pub are_floating_panes_visible: bool, pub other_focused_clients: Vec, } #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] pub struct PluginIds { pub plugin_id: u32, pub zellij_pid: u32, } /// Tag used to identify the plugin in layout and config yaml files #[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] pub struct PluginTag(String); impl PluginTag { pub fn new(url: impl Into) -> Self { PluginTag(url.into()) } } impl From for String { fn from(tag: PluginTag) -> Self { tag.0 } } impl fmt::Display for PluginTag { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.0) } } #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] pub struct PluginCapabilities { pub arrow_fonts: bool, } impl Default for PluginCapabilities { fn default() -> PluginCapabilities { PluginCapabilities { arrow_fonts: true } } } #[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)] pub enum CopyDestination { Command, Primary, System, }