diff --git a/yazi-config/preset/yazi.toml b/yazi-config/preset/yazi.toml index d9e6911a..8403c6a7 100644 --- a/yazi-config/preset/yazi.toml +++ b/yazi-config/preset/yazi.toml @@ -35,6 +35,11 @@ create_offset = [0, 2, 50, 3] rename_position = "hovered" rename_offset = [0, 1, 50, 3] +[select] +open_position = "hovered" +# height takes no effect +open_offset = [0, 1, 50, 3] + [opener] edit = [ { exec = '$EDITOR "$@"', block = true, for = "unix" }, diff --git a/yazi-config/src/lib.rs b/yazi-config/src/lib.rs index df556b9e..a75675d3 100644 --- a/yazi-config/src/lib.rs +++ b/yazi-config/src/lib.rs @@ -34,6 +34,7 @@ pub static PREVIEW: RoCell = RoCell::new(); pub static TASKS: RoCell = RoCell::new(); pub static THEME: RoCell = RoCell::new(); pub static INPUTBOX: RoCell = RoCell::new(); +pub static SELECTBOX: RoCell = RoCell::new(); pub static BOOT: RoCell = RoCell::new(); @@ -51,6 +52,7 @@ pub fn init() { TASKS.with(Default::default); THEME.with(Default::default); INPUTBOX.with(Default::default); + SELECTBOX.with(Default::default); BOOT.with(Default::default); } diff --git a/yazi-config/src/popup/input.rs b/yazi-config/src/popup/input.rs index 0223f8f9..6f4fd953 100644 --- a/yazi-config/src/popup/input.rs +++ b/yazi-config/src/popup/input.rs @@ -32,7 +32,6 @@ impl Default for Input { input: Input, } - // TODO: toml::from_str::(&MERGED_YAZI).unwrap().input } } diff --git a/yazi-config/src/popup/select.rs b/yazi-config/src/popup/select.rs index 6c8ea4d0..8f0da248 100644 --- a/yazi-config/src/popup/select.rs +++ b/yazi-config/src/popup/select.rs @@ -1 +1,22 @@ -// TODO: +use serde::Deserialize; + +use super::position::{Offset, Position}; +use crate::MERGED_YAZI; + +#[derive(Debug, Deserialize)] +pub struct Select { + // open + pub open_position: Position, + pub open_offset: Offset, +} + +impl Default for Select { + fn default() -> Self { + #[derive(Deserialize)] + struct Outer { + select: Select, + } + + toml::from_str::(&MERGED_YAZI).unwrap().select + } +} diff --git a/yazi-core/src/manager/commands/open.rs b/yazi-core/src/manager/commands/open.rs index 50fca89f..c8a635af 100644 --- a/yazi-core/src/manager/commands/open.rs +++ b/yazi-core/src/manager/commands/open.rs @@ -1,6 +1,6 @@ use std::ffi::OsString; -use yazi_config::{keymap::Exec, OPEN}; +use yazi_config::{keymap::Exec, OPEN, SELECTBOX}; use yazi_shared::MIME_DIR; use crate::{emit, external, manager::Manager, select::SelectOpt}; @@ -20,9 +20,11 @@ impl Manager { return; } - let result = emit!(Select(SelectOpt::hovered( + let result = emit!(Select(SelectOpt::from_cfg( "Open with:", - openers.iter().map(|o| o.desc.clone()).collect() + openers.iter().map(|o| o.desc.clone()).collect(), + &SELECTBOX.open_position, + &SELECTBOX.open_offset ))); if let Ok(choice) = result.await { diff --git a/yazi-core/src/select/option.rs b/yazi-core/src/select/option.rs index 1491057c..357fc1be 100644 --- a/yazi-core/src/select/option.rs +++ b/yazi-core/src/select/option.rs @@ -1,4 +1,4 @@ -use ratatui::prelude::Rect; +use yazi_config::popup::{Offset as CfgOffset, Position as CfgPosition}; use crate::{Position, RectShim}; @@ -8,28 +8,52 @@ pub struct SelectOpt { pub position: Position, } -impl SelectOpt { - pub fn top(title: &str, items: Vec) -> Self { - let height = 2 + items.len().min(/* TODO: hardcode */ 5) as u16; - Self { - title: title.to_owned(), - items, - position: Position::Top( - // TODO: - RectShim { x_offset: 0, y_offset: 2, width: 50, height }, - ), +macro_rules! gen_method { + ($func_name:ident, $position:ident) => { + pub fn $func_name(title: &str, items: Vec, rect: RectShim) -> SelectOpt { + let height = 2 + + items.len().min( + 5, // TODO: hardcode + ) as u16; + Self { + title: title.to_owned(), + items, + position: Position::$position(RectShim { height, ..rect }), + } } - } + }; +} - pub fn hovered(title: &str, items: Vec) -> Self { - let height = 2 + items.len().min(/* TODO: hardcode */ 5) as u16; - Self { - title: title.to_owned(), - items, - position: Position::Hovered( - // TODO: - RectShim { x_offset: 0, y_offset: 1, width: 50, height }, - ), +impl SelectOpt { + gen_method!(top_left, TopLeft); + + gen_method!(top_right, TopRight); + + gen_method!(top, Top); + + gen_method!(center, Center); + + gen_method!(bottom, Bottom); + + gen_method!(bottom_left, BottomLeft); + + gen_method!(bottom_right, BottomRight); + + gen_method!(hovered, Hovered); + + pub fn from_cfg(title: &str, items: Vec, pos: &CfgPosition, rect: &CfgOffset) -> Self { + let rect = + RectShim { x_offset: rect.x, y_offset: rect.y, width: rect.width, height: rect.height }; + + match pos { + CfgPosition::TopLeft => Self::top_left(title, items, rect), + CfgPosition::TopRight => Self::top_right(title, items, rect), + CfgPosition::Top => Self::top(title, items, rect), + CfgPosition::Center => Self::center(title, items, rect), + CfgPosition::Bottom => Self::bottom(title, items, rect), + CfgPosition::BottomLeft => Self::bottom_left(title, items, rect), + CfgPosition::BottomRight => Self::bottom_right(title, items, rect), + CfgPosition::Hovered => Self::hovered(title, items, rect), } } }