use crate::prelude::*;
pub const NORMAL: &str = "normal";
pub const N: &str = "n";
pub const VISUAL: &str = "visual";
pub const V: &str = "v";
pub const SELECT: &str = "select";
pub const S: &str = "s";
pub const OP_PENDING: &str = "op-pending";
pub const O: &str = "o";
pub const INSERT: &str = "insert";
pub const I: &str = "i";
pub const CMDLINE: &str = "cmdline";
pub const C: &str = "c";
pub const CMDLINE_SEARCH_FORWARD: &str = "cmdline-search-forward";
pub const CF: &str = "cf";
pub const CMDLINE_SEARCH_BACKWARD: &str = "cmdline-search-backward";
pub const CB: &str = "cb";
#[derive(
Debug,
Copy,
Clone,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
strum_macros::Display,
strum_macros::EnumString,
)]
pub enum Mode {
#[strum(to_string = "normal", serialize = "n")]
Normal,
#[strum(to_string = "visual", serialize = "v")]
Visual,
#[strum(to_string = "select", serialize = "s")]
Select,
#[strum(
to_string = "operator-pending",
serialize = "op-pending",
serialize = "o"
)]
OperatorPending,
#[strum(to_string = "insert", serialize = "i")]
Insert,
#[strum(to_string = "command-line", serialize = "cmdline", serialize = "c")]
CmdlineEx,
#[strum(to_string = "command-line-search-forward")]
CmdlineSearchForward,
#[strum(to_string = "command-line-search-backward")]
CmdlineSearchBackward,
}
impl Mode {
pub fn name(&self) -> &str {
match self {
Mode::Normal => NORMAL,
Mode::Visual => VISUAL,
Mode::Select => SELECT,
Mode::OperatorPending => OP_PENDING,
Mode::Insert => INSERT,
Mode::CmdlineEx => CMDLINE,
Mode::CmdlineSearchForward => CMDLINE_SEARCH_FORWARD,
Mode::CmdlineSearchBackward => CMDLINE_SEARCH_BACKWARD,
}
}
pub fn short_name(&self) -> &str {
match self {
Mode::Normal => N,
Mode::Visual => V,
Mode::Select => S,
Mode::OperatorPending => O,
Mode::Insert => I,
Mode::CmdlineEx => C,
Mode::CmdlineSearchForward => CF,
Mode::CmdlineSearchBackward => CB,
}
}
}
impl Mode {
pub fn all() -> Vec<Mode> {
vec![
Mode::Normal,
Mode::Visual,
Mode::Select,
Mode::OperatorPending,
Mode::Insert,
Mode::CmdlineEx,
Mode::CmdlineSearchForward,
Mode::CmdlineSearchBackward,
]
}
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct Modes {
values: BTreeSet<Mode>,
}
impl Modes {
pub fn new() -> Self {
Modes {
values: BTreeSet::new(),
}
}
pub fn with(&mut self, mode: Mode) -> &Self {
self.values.insert(mode);
self
}
pub fn without(&mut self, mode: Mode) -> &Self {
self.values.remove(&mode);
self
}
pub fn extend(&mut self, modes: Modes) -> &Self {
self.values.extend(modes.values.iter());
self
}
pub fn set(&mut self, mode: Mode) -> bool {
self.values.insert(mode)
}
pub fn unset(&mut self, mode: Mode) -> bool {
self.values.remove(&mode)
}
pub fn is_empty(&self) -> bool {
self.values.is_empty()
}
pub fn len(&self) -> usize {
self.values.len()
}
pub fn contains(&self, mode: &Mode) -> bool {
self.values.contains(mode)
}
pub fn iter(&self) -> std::collections::btree_set::Iter<'_, Mode> {
self.values.iter()
}
}
impl From<Mode> for Modes {
fn from(mode: Mode) -> Self {
let mut values = BTreeSet::new();
values.insert(mode);
Modes { values }
}
}
impl From<Vec<Mode>> for Modes {
fn from(modes: Vec<Mode>) -> Self {
let mut values = BTreeSet::new();
for m in modes {
values.insert(m);
}
Modes { values }
}
}