use super::keymap::{default_key_map, KeyMap};
#[cfg(feature = "clipboard-support")]
use super::types::PasteMsg;
use super::types::{EchoMode, PasteErrMsg, ValidateFunc};
use crate::cursor::{new as cursor_new, Model as Cursor};
use bubbletea_rs::{Cmd, Model as BubbleTeaModel, Msg};
use lipgloss_extras::prelude::*;
use std::time::Duration;
#[allow(dead_code)]
pub struct Model {
pub err: Option<String>,
pub prompt: String,
pub prompt_style: Style,
pub text_style: Style,
pub placeholder: String,
pub placeholder_style: Style,
pub cursor: Cursor,
pub cursor_mode: crate::cursor::Mode,
pub(super) value: Vec<char>,
pub(super) focus: bool,
pub(super) pos: usize,
pub width: i32,
pub key_map: KeyMap,
pub char_limit: i32,
pub echo_mode: EchoMode,
pub echo_character: char,
pub completion_style: Style,
pub(super) validate: Option<ValidateFunc>,
pub(super) offset: usize,
pub(super) offset_right: usize,
pub(super) suggestions: Vec<Vec<char>>,
pub(super) matched_suggestions: Vec<Vec<char>>,
pub(super) show_suggestions: bool,
pub(super) current_suggestion_index: usize,
}
pub fn new() -> Model {
let mut m = Model {
err: None,
prompt: "> ".to_string(),
prompt_style: Style::new(),
text_style: Style::new(),
placeholder: String::new(),
placeholder_style: Style::new().foreground(Color::from("240")),
cursor: cursor_new(),
cursor_mode: crate::cursor::Mode::Blink,
value: Vec::new(),
focus: false,
pos: 0,
width: 0,
key_map: default_key_map(),
char_limit: 0,
echo_mode: EchoMode::EchoNormal,
echo_character: '*',
completion_style: Style::new().foreground(Color::from("240")),
validate: None,
offset: 0,
offset_right: 0,
suggestions: Vec::new(),
matched_suggestions: Vec::new(),
show_suggestions: false,
current_suggestion_index: 0,
};
m.cursor.set_mode(crate::cursor::Mode::Blink);
m
}
pub fn new_model() -> Model {
new()
}
impl Default for Model {
fn default() -> Self {
new()
}
}
pub fn blink() -> Cmd {
use bubbletea_rs::tick as bubbletea_tick;
let id = 0usize;
let tag = 0usize;
bubbletea_tick(Duration::from_millis(500), move |_| {
Box::new(crate::cursor::BlinkMsg { id, tag }) as Msg
})
}
pub fn paste() -> Cmd {
use bubbletea_rs::tick as bubbletea_tick;
bubbletea_tick(Duration::from_nanos(1), |_| {
#[cfg(feature = "clipboard-support")]
{
use clipboard::{ClipboardContext, ClipboardProvider};
let res: Result<String, String> = (|| {
let mut ctx: ClipboardContext = ClipboardProvider::new()
.map_err(|e| format!("Failed to create clipboard context: {}", e))?;
ctx.get_contents()
.map_err(|e| format!("Failed to read clipboard: {}", e))
})();
match res {
Ok(s) => Box::new(PasteMsg(s)) as Msg,
Err(e) => Box::new(PasteErrMsg(e)) as Msg,
}
}
#[cfg(not(feature = "clipboard-support"))]
{
Box::new(PasteErrMsg("Clipboard support not enabled".to_string())) as Msg
}
})
}
impl BubbleTeaModel for Model {
fn init() -> (Self, std::option::Option<Cmd>) {
let model = new();
(model, std::option::Option::None)
}
fn update(&mut self, msg: Msg) -> std::option::Option<Cmd> {
self.update(msg)
}
fn view(&self) -> String {
self.view()
}
}