From f8b3ab0ce7e10acca0418bdae870dfaee9ba3ae4 Mon Sep 17 00:00:00 2001 From: sxyazi Date: Thu, 9 Nov 2023 11:01:20 +0800 Subject: [PATCH] .. --- yazi-core/src/select/commands/arrow.rs | 48 +++++++++++++++++++++++ yazi-core/src/select/commands/close.rs | 29 ++++++++++++++ yazi-core/src/select/commands/mod.rs | 2 + yazi-core/src/select/mod.rs | 1 + yazi-core/src/select/select.rs | 53 ++++---------------------- yazi-fm/src/executor.rs | 20 +++++----- 6 files changed, 97 insertions(+), 56 deletions(-) create mode 100644 yazi-core/src/select/commands/arrow.rs create mode 100644 yazi-core/src/select/commands/close.rs create mode 100644 yazi-core/src/select/commands/mod.rs diff --git a/yazi-core/src/select/commands/arrow.rs b/yazi-core/src/select/commands/arrow.rs new file mode 100644 index 00000000..e06a3ddc --- /dev/null +++ b/yazi-core/src/select/commands/arrow.rs @@ -0,0 +1,48 @@ +use yazi_config::keymap::Exec; + +use crate::select::Select; + +pub struct Opt { + step: isize, +} + +impl From<&Exec> for Opt { + fn from(e: &Exec) -> Self { + Self { step: e.args.first().and_then(|s| s.parse().ok()).unwrap_or(0) } + } +} + +impl Select { + fn next(&mut self, step: usize) -> bool { + let len = self.items.len(); + if len == 0 { + return false; + } + + let old = self.cursor; + self.cursor = (self.cursor + step).min(len - 1); + + let limit = self.limit(); + if self.cursor >= len.min(self.offset + limit) { + self.offset = len.saturating_sub(limit).min(self.offset + self.cursor - old); + } + + old != self.cursor + } + + fn prev(&mut self, step: usize) -> bool { + let old = self.cursor; + self.cursor = self.cursor.saturating_sub(step); + + if self.cursor < self.offset { + self.offset = self.offset.saturating_sub(old - self.cursor); + } + + old != self.cursor + } + + pub fn arrow(&mut self, opt: impl Into) -> bool { + let opt = opt.into() as Opt; + if opt.step > 0 { self.next(opt.step as usize) } else { self.prev(opt.step.unsigned_abs()) } + } +} diff --git a/yazi-core/src/select/commands/close.rs b/yazi-core/src/select/commands/close.rs new file mode 100644 index 00000000..edc575df --- /dev/null +++ b/yazi-core/src/select/commands/close.rs @@ -0,0 +1,29 @@ +use anyhow::anyhow; +use yazi_config::keymap::Exec; + +use crate::select::Select; + +pub struct Opt { + submit: bool, +} + +impl From<&Exec> for Opt { + fn from(e: &Exec) -> Self { Self { submit: e.named.contains_key("submit") } } +} +impl From for Opt { + fn from(submit: bool) -> Self { Self { submit } } +} + +impl Select { + pub fn close(&mut self, opt: impl Into) -> bool { + let opt = opt.into() as Opt; + if let Some(cb) = self.callback.take() { + _ = cb.send(if opt.submit { Ok(self.cursor) } else { Err(anyhow!("canceled")) }); + } + + self.cursor = 0; + self.offset = 0; + self.visible = false; + true + } +} diff --git a/yazi-core/src/select/commands/mod.rs b/yazi-core/src/select/commands/mod.rs new file mode 100644 index 00000000..9225a7a8 --- /dev/null +++ b/yazi-core/src/select/commands/mod.rs @@ -0,0 +1,2 @@ +mod arrow; +mod close; diff --git a/yazi-core/src/select/mod.rs b/yazi-core/src/select/mod.rs index fa446e89..3b4cf878 100644 --- a/yazi-core/src/select/mod.rs +++ b/yazi-core/src/select/mod.rs @@ -1,3 +1,4 @@ +mod commands; mod option; mod select; diff --git a/yazi-core/src/select/select.rs b/yazi-core/src/select/select.rs index ed7762c7..38fb14a6 100644 --- a/yazi-core/src/select/select.rs +++ b/yazi-core/src/select/select.rs @@ -1,4 +1,4 @@ -use anyhow::{anyhow, Result}; +use anyhow::Result; use tokio::sync::oneshot::Sender; use super::SelectOpt; @@ -6,13 +6,13 @@ use crate::Position; #[derive(Default)] pub struct Select { - title: String, - items: Vec, - pub position: Position, + title: String, + pub(super) items: Vec, + pub position: Position, - offset: usize, - cursor: usize, - callback: Option>>, + pub(super) offset: usize, + pub(super) cursor: usize, + pub(super) callback: Option>>, pub visible: bool, } @@ -29,45 +29,6 @@ impl Select { self.visible = true; } - pub fn close(&mut self, submit: bool) -> bool { - if let Some(cb) = self.callback.take() { - _ = cb.send(if submit { Ok(self.cursor) } else { Err(anyhow!("canceled")) }); - } - - self.cursor = 0; - self.offset = 0; - self.visible = false; - true - } - - pub fn next(&mut self, step: usize) -> bool { - let len = self.items.len(); - if len == 0 { - return false; - } - - let old = self.cursor; - self.cursor = (self.cursor + step).min(len - 1); - - let limit = self.limit(); - if self.cursor >= len.min(self.offset + limit) { - self.offset = len.saturating_sub(limit).min(self.offset + self.cursor - old); - } - - old != self.cursor - } - - pub fn prev(&mut self, step: usize) -> bool { - let old = self.cursor; - self.cursor = self.cursor.saturating_sub(step); - - if self.cursor < self.offset { - self.offset = self.offset.saturating_sub(old - self.cursor); - } - - old != self.cursor - } - #[inline] pub fn window(&self) -> &[String] { let end = (self.offset + self.limit()).min(self.items.len()); diff --git a/yazi-fm/src/executor.rs b/yazi-fm/src/executor.rs index d0da7d2b..427efc61 100644 --- a/yazi-fm/src/executor.rs +++ b/yazi-fm/src/executor.rs @@ -166,18 +166,18 @@ impl<'a> Executor<'a> { } fn select(&mut self, exec: &Exec) -> bool { - match exec.cmd.as_str() { - "close" => self.cx.select.close(exec.named.contains_key("submit")), - - "arrow" => { - let step: isize = exec.args.first().and_then(|s| s.parse().ok()).unwrap_or(0); - if step > 0 { - self.cx.select.next(step as usize) - } else { - self.cx.select.prev(step.unsigned_abs()) + macro_rules! on { + ($name:ident) => { + if exec.cmd == stringify!($name) { + return self.cx.select.$name(exec); } - } + }; + } + on!(close); + on!(arrow); + + match exec.cmd.as_str() { "help" => self.cx.help.toggle(KeymapLayer::Select), _ => false, }