use ratatui::{text::{Line, Text}, widgets::{Paragraph, Wrap}}; use yazi_shared::{IntoStringLossy, url::Url}; use super::{Offset, Position}; use crate::YAZI; #[derive(Debug, Default)] pub struct InputCfg { pub title: String, pub value: String, pub cursor: Option, pub obscure: bool, pub position: Position, pub realtime: bool, pub completion: bool, } #[derive(Debug, Default)] pub struct PickCfg { pub title: String, pub items: Vec, pub position: Position, } #[derive(Debug, Default)] pub struct ConfirmCfg { pub position: Position, pub title: Line<'static>, pub body: Paragraph<'static>, pub list: Paragraph<'static>, } impl InputCfg { pub fn cd() -> Self { Self { title: YAZI.input.cd_title.to_owned(), position: Position::new(YAZI.input.cd_origin, YAZI.input.cd_offset), completion: true, ..Default::default() } } pub fn create(dir: bool) -> Self { Self { title: YAZI.input.create_title[dir as usize].to_owned(), position: Position::new(YAZI.input.create_origin, YAZI.input.create_offset), ..Default::default() } } pub fn rename() -> Self { Self { title: YAZI.input.rename_title.to_owned(), position: Position::new(YAZI.input.rename_origin, YAZI.input.rename_offset), ..Default::default() } } pub fn filter() -> Self { Self { title: YAZI.input.filter_title.to_owned(), position: Position::new(YAZI.input.filter_origin, YAZI.input.filter_offset), realtime: true, ..Default::default() } } pub fn find(prev: bool) -> Self { Self { title: YAZI.input.find_title[prev as usize].to_owned(), position: Position::new(YAZI.input.find_origin, YAZI.input.find_offset), realtime: true, ..Default::default() } } pub fn search(name: &str) -> Self { Self { title: YAZI.input.search_title.replace("{n}", name), position: Position::new(YAZI.input.search_origin, YAZI.input.search_offset), ..Default::default() } } pub fn shell(block: bool) -> Self { Self { title: YAZI.input.shell_title[block as usize].to_owned(), position: Position::new(YAZI.input.shell_origin, YAZI.input.shell_offset), ..Default::default() } } #[inline] pub fn with_value(mut self, value: impl Into) -> Self { self.value = value.into(); self } #[inline] pub fn with_cursor(mut self, cursor: Option) -> Self { self.cursor = cursor; self } } impl ConfirmCfg { fn new( title: String, position: Position, body: Option>, list: Option>, ) -> Self { Self { position, title: Line::raw(title), body: body.map(|b| Paragraph::new(b).wrap(Wrap { trim: false })).unwrap_or_default(), list: list.map(|l| Paragraph::new(l).wrap(Wrap { trim: false })).unwrap_or_default(), } } pub fn trash(urls: &[yazi_shared::url::Url]) -> Self { Self::new( Self::replace_number(&YAZI.confirm.trash_title, urls.len()), YAZI.confirm.trash_position(), None, Self::truncate_list(urls.iter(), urls.len(), 100), ) } pub fn delete(urls: &[yazi_shared::url::Url]) -> Self { Self::new( Self::replace_number(&YAZI.confirm.delete_title, urls.len()), YAZI.confirm.delete_position(), None, Self::truncate_list(urls.iter(), urls.len(), 100), ) } pub fn overwrite(url: &Url) -> Self { Self::new( YAZI.confirm.overwrite_title.to_owned(), YAZI.confirm.overwrite_position(), Some(Text::raw(&YAZI.confirm.overwrite_body)), Some(url.into_string_lossy().into()), ) } pub fn quit(len: usize, names: Vec) -> Self { Self::new( Self::replace_number(&YAZI.confirm.quit_title, len), YAZI.confirm.quit_position(), Some(Text::raw(&YAZI.confirm.quit_body)), Self::truncate_list(names.into_iter(), len, 10), ) } fn replace_number(tpl: &str, n: usize) -> String { tpl.replace("{n}", &n.to_string()).replace("{s}", if n > 1 { "s" } else { "" }) } fn truncate_list( it: impl Iterator, len: usize, max: usize, ) -> Option> { let mut lines = Vec::with_capacity(len.min(max + 1)); for (i, s) in it.enumerate() { if i >= max { lines.push(format!("... and {} more", len - max)); break; } lines.push(s.into_string_lossy()); } Some(Text::from_iter(lines)) } } impl PickCfg { #[inline] fn max_height(len: usize) -> u16 { YAZI.pick.open_offset.height.min(YAZI.pick.border().saturating_add(len as u16)) } pub fn open(items: Vec) -> Self { let max_height = Self::max_height(items.len()); Self { title: YAZI.pick.open_title.to_owned(), items, position: Position::new(YAZI.pick.open_origin, Offset { height: max_height, ..YAZI.pick.open_offset }), } } }