use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Mode {
Normal,
Insert,
Visual,
Command,
}
impl Mode {
pub fn name(&self) -> &str {
match self {
Mode::Normal => "NORMAL",
Mode::Insert => "INSERT",
Mode::Visual => "VISUAL",
Mode::Command => "COMMAND",
}
}
pub fn color(&self) -> ratatui::style::Color {
match self {
Mode::Normal => ratatui::style::Color::Cyan,
Mode::Insert => ratatui::style::Color::Green,
Mode::Visual => ratatui::style::Color::Yellow,
Mode::Command => ratatui::style::Color::Magenta,
}
}
}
impl fmt::Display for Mode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.name())
}
}
#[derive(Debug, Clone)]
pub struct EditorMode {
pub mode: Mode,
pub command_buffer: String,
pub visual_start: Option<(usize, usize)>,
pub last_action: Option<String>,
}
impl Default for EditorMode {
fn default() -> Self {
Self {
mode: Mode::Normal,
command_buffer: String::new(),
visual_start: None,
last_action: None,
}
}
}
impl EditorMode {
pub fn new() -> Self {
Self::default()
}
pub fn switch_to(&mut self, mode: Mode) {
self.mode = mode;
match mode {
Mode::Normal => {
self.visual_start = None;
}
Mode::Command => {
self.command_buffer.clear();
}
_ => {}
}
}
pub fn is_normal(&self) -> bool {
self.mode == Mode::Normal
}
pub fn is_insert(&self) -> bool {
self.mode == Mode::Insert
}
pub fn is_visual(&self) -> bool {
self.mode == Mode::Visual
}
pub fn is_command(&self) -> bool {
self.mode == Mode::Command
}
pub fn push_command_char(&mut self, c: char) {
if self.is_command() {
self.command_buffer.push(c);
}
}
pub fn pop_command_char(&mut self) {
if self.is_command() {
self.command_buffer.pop();
}
}
pub fn command(&self) -> &str {
&self.command_buffer
}
pub fn clear_command(&mut self) {
self.command_buffer.clear();
}
}