From 21e5b771783e591d46421e572cc67031b59be701 Mon Sep 17 00:00:00 2001 From: OliverGuy Date: Thu, 7 May 2026 00:46:38 +0200 Subject: [PATCH] refactor(history): generalize up/down to offset --- yazi-config/preset/keymap-default.toml | 8 ++--- yazi-widgets/src/input/actor/history.rs | 4 +-- yazi-widgets/src/input/history.rs | 41 ++++++++++-------------- yazi-widgets/src/input/parser/history.rs | 14 +++++--- 4 files changed, 33 insertions(+), 34 deletions(-) diff --git a/yazi-config/preset/keymap-default.toml b/yazi-config/preset/keymap-default.toml index d2384505..212633c5 100644 --- a/yazi-config/preset/keymap-default.toml +++ b/yazi-config/preset/keymap-default.toml @@ -305,10 +305,10 @@ keymap = [ { on = "P", run = "paste --before", desc = "Paste copied characters before the cursor" }, # History - { on = "", run = "history up", desc = "Navigate to the previous history entry" }, - { on = "", run = "history down", desc = "Navigate to the next history entry" }, - { on = "", run = "history up", desc = "Navigate to the previous history entry" }, - { on = "", run = "history down", desc = "Navigate to the next history entry" }, + { on = "", run = "history -1", desc = "Navigate to the previous history entry" }, + { on = "", run = "history +1", desc = "Navigate to the next history entry" }, + { on = "", run = "history -1", desc = "Navigate to the previous history entry" }, + { on = "", run = "history +1", desc = "Navigate to the next history entry" }, # Undo/Redo/Casefy { on = "u", run = [ "undo", "casefy lower" ], desc = "Undo, or lowercase if in visual mode" }, diff --git a/yazi-widgets/src/input/actor/history.rs b/yazi-widgets/src/input/actor/history.rs index 9f7f786f..7c985eb3 100644 --- a/yazi-widgets/src/input/actor/history.rs +++ b/yazi-widgets/src/input/actor/history.rs @@ -2,7 +2,7 @@ use anyhow::Result; use yazi_macro::{act, render, succ}; use yazi_shared::data::Data; -use crate::input::{Input, InputOp, INPUT_HISTORY, parser::HistoryOpt}; +use crate::input::{INPUT_HISTORY, Input, InputOp, parser::HistoryOpt}; impl Input { pub fn history(&mut self, opt: HistoryOpt) -> Result { @@ -10,7 +10,7 @@ impl Input { succ!(); } - let new_value = INPUT_HISTORY.lock().unwrap().navigate(opt.up, &self.snap().value); + let new_value = INPUT_HISTORY.lock().unwrap().navigate(opt.offset, &self.snap().value); let Some(value) = new_value else { succ!() }; let snap = self.snap_mut(); diff --git a/yazi-widgets/src/input/history.rs b/yazi-widgets/src/input/history.rs index 3752e0e4..e123019d 100644 --- a/yazi-widgets/src/input/history.rs +++ b/yazi-widgets/src/input/history.rs @@ -29,35 +29,28 @@ impl InputHistory { self.draft.clear(); } - pub fn navigate(&mut self, up: bool, current: &str) -> Option { - if self.entries.is_empty() { + pub fn navigate(&mut self, step: i64, current: &str) -> Option { + if self.entries.is_empty() || step == 0 { return None; } - if up { - let new_idx = match self.idx { - None => { - self.draft = current.to_owned(); - self.entries.len() - 1 - } - Some(0) => return None, - Some(i) => i - 1, - }; - self.idx = Some(new_idx); - Some(self.entries[new_idx].clone()) + let len = self.entries.len() as i64; + let pos = self.idx.map_or(len, |i| i as i64); + let new_pos = (pos + step).clamp(0, len); + + if new_pos == pos { + return None; + } + + if new_pos == len { + self.idx = None; + Some(std::mem::take(&mut self.draft)) } else { - match self.idx { - None => None, - Some(i) if i + 1 >= self.entries.len() => { - self.idx = None; - let draft = std::mem::take(&mut self.draft); - Some(draft) - } - Some(i) => { - self.idx = Some(i + 1); - Some(self.entries[i + 1].clone()) - } + if self.idx.is_none() { + self.draft = current.to_owned(); } + self.idx = Some(new_pos as usize); + Some(self.entries[new_pos as usize].clone()) } } } diff --git a/yazi-widgets/src/input/parser/history.rs b/yazi-widgets/src/input/parser/history.rs index 57f39d0b..2b37c01a 100644 --- a/yazi-widgets/src/input/parser/history.rs +++ b/yazi-widgets/src/input/parser/history.rs @@ -3,17 +3,23 @@ use yazi_shared::event::ActionCow; #[derive(Debug)] pub struct HistoryOpt { - pub up: bool, + pub offset: i64, } impl From for HistoryOpt { - fn from(a: ActionCow) -> Self { Self { up: a.str(0) == "up" } } + fn from(a: ActionCow) -> Self { + Self { offset: a.str(0).parse().unwrap_or(0) } + } } impl FromLua for HistoryOpt { - fn from_lua(_: Value, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } + fn from_lua(_: Value, _: &Lua) -> mlua::Result { + Err("unsupported".into_lua_err()) + } } impl IntoLua for HistoryOpt { - fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } + fn into_lua(self, _: &Lua) -> mlua::Result { + Err("unsupported".into_lua_err()) + } }