use std::sync::Arc;
use crate::core::event::{KeyCode, KeyEvent, KeyMods};
use crate::input::KeyBindings;
use crate::style::{Style, StyleSlot};
#[non_exhaustive]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub enum TextAreaVimMode {
Insert,
#[default]
Normal,
Visual,
VisualLine,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct TextAreaVimKeymap {
bindings: Vec<TextAreaVimKeyBinding>,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct TextAreaVimKeyBinding {
pub bindings: KeyBindings,
pub command: char,
}
impl TextAreaVimKeymap {
pub fn new() -> Self {
Self::default()
}
pub fn bind(mut self, bindings: KeyBindings, command: char) -> Self {
self.bindings
.push(TextAreaVimKeyBinding { bindings, command });
self
}
pub(crate) fn translate_key(&self, key: KeyEvent) -> KeyEvent {
let Some(binding) = self.bindings.iter().find(|binding| {
binding
.bindings
.iter()
.any(|candidate| !candidate.is_chord() && candidate.matches_sequence(&[key]))
}) else {
return key;
};
KeyEvent {
code: KeyCode::Char(binding.command),
mods: KeyMods::default(),
}
}
}
#[non_exhaustive]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub enum TextAreaVimCurrentLineHighlight {
#[default]
Off,
Content,
Full,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct TextAreaVimConfig {
pub search_bar_style: StyleSlot,
pub search_bar_prefix_style: StyleSlot,
pub search_bar_count_style: StyleSlot,
pub search_match_style: StyleSlot,
pub current_search_match_style: StyleSlot,
pub current_line_highlight: TextAreaVimCurrentLineHighlight,
pub current_line_style: StyleSlot,
pub current_line_number_style: StyleSlot,
}
impl Default for TextAreaVimConfig {
fn default() -> Self {
Self {
search_bar_style: StyleSlot::Extend(Style::new().reverse()),
search_bar_prefix_style: StyleSlot::Inherit,
search_bar_count_style: StyleSlot::Inherit,
search_match_style: StyleSlot::Replace(Style::new().underline().bold()),
current_search_match_style: StyleSlot::Inherit,
current_line_highlight: TextAreaVimCurrentLineHighlight::Off,
current_line_style: StyleSlot::Inherit,
current_line_number_style: StyleSlot::Inherit,
}
}
}
impl TextAreaVimConfig {
pub fn new() -> Self {
Self::default()
}
pub fn search_bar_style(mut self, style: Style) -> Self {
self.search_bar_style = StyleSlot::Replace(style);
self
}
pub fn extend_search_bar_style(mut self, style: Style) -> Self {
self.search_bar_style = StyleSlot::Extend(style);
self
}
pub fn search_bar_style_slot(mut self, slot: StyleSlot) -> Self {
self.search_bar_style = slot;
self
}
pub fn search_bar_prefix_style(mut self, style: Style) -> Self {
self.search_bar_prefix_style = StyleSlot::Replace(style);
self
}
pub fn extend_search_bar_prefix_style(mut self, style: Style) -> Self {
self.search_bar_prefix_style = StyleSlot::Extend(style);
self
}
pub fn search_bar_prefix_style_slot(mut self, slot: StyleSlot) -> Self {
self.search_bar_prefix_style = slot;
self
}
pub fn search_bar_count_style(mut self, style: Style) -> Self {
self.search_bar_count_style = StyleSlot::Replace(style);
self
}
pub fn extend_search_bar_count_style(mut self, style: Style) -> Self {
self.search_bar_count_style = StyleSlot::Extend(style);
self
}
pub fn search_bar_count_style_slot(mut self, slot: StyleSlot) -> Self {
self.search_bar_count_style = slot;
self
}
pub fn search_match_style(mut self, style: Style) -> Self {
self.search_match_style = StyleSlot::Replace(style);
self
}
pub fn extend_search_match_style(mut self, style: Style) -> Self {
self.search_match_style = StyleSlot::Extend(style);
self
}
pub fn search_match_style_slot(mut self, slot: StyleSlot) -> Self {
self.search_match_style = slot;
self
}
pub fn current_search_match_style(mut self, style: Style) -> Self {
self.current_search_match_style = StyleSlot::Replace(style);
self
}
pub fn extend_current_search_match_style(mut self, style: Style) -> Self {
self.current_search_match_style = StyleSlot::Extend(style);
self
}
pub fn current_search_match_style_slot(mut self, slot: StyleSlot) -> Self {
self.current_search_match_style = slot;
self
}
pub fn current_line_highlight(mut self, mode: TextAreaVimCurrentLineHighlight) -> Self {
self.current_line_highlight = mode;
self
}
pub fn highlight_current_line(mut self, enabled: bool) -> Self {
self.current_line_highlight = if enabled {
TextAreaVimCurrentLineHighlight::Full
} else {
TextAreaVimCurrentLineHighlight::Off
};
self
}
pub fn current_line_style(mut self, style: Style) -> Self {
self.current_line_style = StyleSlot::Replace(style);
self
}
pub fn extend_current_line_style(mut self, style: Style) -> Self {
self.current_line_style = StyleSlot::Extend(style);
self
}
pub fn current_line_style_slot(mut self, slot: StyleSlot) -> Self {
self.current_line_style = slot;
self
}
pub fn current_line_number_style(mut self, style: Style) -> Self {
self.current_line_number_style = StyleSlot::Replace(style);
self
}
pub fn extend_current_line_number_style(mut self, style: Style) -> Self {
self.current_line_number_style = StyleSlot::Extend(style);
self
}
pub fn current_line_number_style_slot(mut self, slot: StyleSlot) -> Self {
self.current_line_number_style = slot;
self
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub(crate) struct TextAreaVimSearchFeedback {
pub query: Arc<str>,
pub cursor: usize,
pub forward: bool,
pub pending: bool,
pub target_range: Option<(usize, usize)>,
pub current_match_index: Option<usize>,
pub match_count: usize,
}