diff --git a/yazi-core/src/completion/commands/mod.rs b/yazi-core/src/completion/commands/mod.rs index c026b752..545bd455 100644 --- a/yazi-core/src/completion/commands/mod.rs +++ b/yazi-core/src/completion/commands/mod.rs @@ -1,5 +1,2 @@ mod show; mod trigger; - -pub use show::*; -pub use trigger::*; diff --git a/yazi-core/src/context.rs b/yazi-core/src/context.rs index 08b3206a..31546bb3 100644 --- a/yazi-core/src/context.rs +++ b/yazi-core/src/context.rs @@ -1,6 +1,5 @@ use crossterm::terminal::WindowSize; use ratatui::prelude::Rect; -use yazi_config::keymap::KeymapLayer; use yazi_shared::Term; use crate::{completion::Completion, help::Help, input::Input, manager::Manager, select::Select, tasks::Tasks, which::Which, Position}; @@ -32,29 +31,31 @@ impl Ctx { let WindowSize { columns, rows, .. } = Term::size(); let (x, y) = match pos { - Position::None => return Rect::default(), Position::Top(Rect { mut x, mut y, width, height }) => { x = x.min(columns.saturating_sub(*width)); y = y.min(rows.saturating_sub(*height)); ((columns / 2).saturating_sub(width / 2) + x, y) } - Position::Hovered(rect @ Rect { mut x, y, width, height }) => { - let Some(r) = - self.manager.hovered().and_then(|h| self.manager.current().rect_current(&h.url)) - else { - return self.area(&Position::Top(*rect)); - }; - + Position::Sticky(Rect { mut x, y, width, height }, r) => { x = x.min(columns.saturating_sub(*width)); if y + height + r.y + r.height > rows { - (x + r.x, r.y.saturating_sub(height.saturating_sub(1))) + (x + r.x, r.y.saturating_sub(height.saturating_sub(*y))) } else { (x + r.x, y + r.y + r.height) } } + Position::Hovered(rect) => { + return self.area(&if let Some(r) = + self.manager.hovered().and_then(|h| self.manager.current().rect_current(&h.url)) + { + Position::Sticky(*rect, r) + } else { + Position::Top(*rect) + }); + } }; - let (w, h) = pos.dimension().unwrap(); + let (w, h) = pos.dimension(); Rect { x, y, width: w.min(columns.saturating_sub(x)), height: h.min(rows.saturating_sub(y)) } } diff --git a/yazi-core/src/position.rs b/yazi-core/src/position.rs index 68c92a62..37bd0911 100644 --- a/yazi-core/src/position.rs +++ b/yazi-core/src/position.rs @@ -1,23 +1,25 @@ use ratatui::prelude::Rect; -#[derive(Default)] pub enum Position { - #[default] - None, Top(Rect), + Sticky(Rect, Rect), Hovered(Rect), } +impl Default for Position { + fn default() -> Self { Self::Top(Rect::default()) } +} + impl Position { #[inline] - pub fn rect(&self) -> Option { + pub fn rect(&self) -> Rect { match self { - Position::None => None, - Position::Top(rect) => Some(*rect), - Position::Hovered(rect) => Some(*rect), + Position::Top(rect) => *rect, + Position::Sticky(rect, _) => *rect, + Position::Hovered(rect) => *rect, } } #[inline] - pub fn dimension(&self) -> Option<(u16, u16)> { self.rect().map(|r| (r.width, r.height)) } + pub fn dimension(&self) -> (u16, u16) { (self.rect().width, self.rect().height) } } diff --git a/yazi-fm/src/completion/completion.rs b/yazi-fm/src/completion/completion.rs index b5cb1bd7..6b4cb2ef 100644 --- a/yazi-fm/src/completion/completion.rs +++ b/yazi-fm/src/completion/completion.rs @@ -1,5 +1,5 @@ -use ratatui::{buffer::Buffer, layout::Rect, widgets::{Block, BorderType, Borders, Cell, Clear, List, ListItem, Row, Table, Widget}}; -use yazi_core::Ctx; +use ratatui::{buffer::Buffer, layout::Rect, widgets::{Block, BorderType, Borders, Clear, List, ListItem, Widget}}; +use yazi_core::{Ctx, Position}; pub(crate) struct Completion<'a> { cx: &'a Ctx, @@ -10,54 +10,24 @@ impl<'a> Completion<'a> { } impl<'a> Widget for Completion<'a> { - fn render(self, _: Rect, buf: &mut Buffer) { + fn render(self, rect: Rect, buf: &mut Buffer) { let items = self.cx.completion.items.iter().map(|x| ListItem::new(x.as_str())).collect::>(); - // TODO - Clear.render(Rect { x: 10, y: 10, width: 10, height: 20 }, buf); - List::new(items).render(Rect { x: 10, y: 10, width: 10, height: 20 }, buf); + let input_area = self.cx.area(&self.cx.input.position); + let mut area = + self.cx.area(&Position::Sticky(Rect { x: 1, y: 0, width: 20, height: 15 }, input_area)); - // let completion = &self.cx.input.completion; - // let area = self.cx.area(&completion.position); + if area.y > input_area.y { + area.y = area.y.saturating_sub(1); + } else { + area.y = rect.height.min(area.y + 1); + area.height = rect.height.saturating_sub(area.y).min(area.height); + } - // let constraint = (0..completion.column_cnt) - // .map(|_| Constraint::Percentage(completion.max_width)) - // .collect::>(); - // let table = { - // let max_width = completion.max_width as usize; - // let mut table = vec![]; - // let mut cur_row = vec![]; - // for (idx, s) in completion.items.iter().enumerate() { - // if idx != 0 && idx % completion.column_cnt as usize == 0 { - // let t = mem::take(&mut cur_row); - // table.push(Row::new(t)); - // } - // cur_row.push( - // Cell::from(if s.len() < max_width { - // s.to_owned() - // } else { - // s.split_at(max_width - 1).0.to_string() + "…" - // }) - // .style(if completion.cursor == idx { - // THEME.completion.active.into() - // } else { - // THEME.completion.inactive.into() - // }), - // ); - // } - // table.push(Row::new(cur_row)); - // Table::new(table) - // .block( - // Block::new() - // .borders(Borders::ALL) - // .border_type(BorderType::Double) - // .border_style(THEME.completion.border.into()), - // ) - // .widths(&constraint) - // }; - - // Clear.render(area, buf); - // table.render(area, buf); + Clear.render(area, buf); + List::new(items) + .block(Block::new().borders(Borders::ALL).border_type(BorderType::Rounded)) + .render(area, buf); } } diff --git a/yazi-shared/src/term/mod.rs b/yazi-shared/src/term/mod.rs index f95ce14e..9b1c3465 100644 --- a/yazi-shared/src/term/mod.rs +++ b/yazi-shared/src/term/mod.rs @@ -1,3 +1,5 @@ +#![allow(clippy::module_inception)] + mod cursor; mod term;