feat: support wrap around for arrow actions

This commit is contained in:
XOR-op 2025-03-27 09:09:58 -04:00
parent ad09fb89d9
commit 13fde686ed
4 changed files with 57 additions and 49 deletions

View file

@ -1,34 +1,39 @@
use yazi_fs::Step;
use yazi_macro::render;
use yazi_shared::event::{CmdCow, Data};
use yazi_shared::event::CmdCow;
use crate::cmp::Cmp;
struct Opt {
step: isize,
step: Step,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self { Self { step: c.first().and_then(Data::as_isize).unwrap_or(0) } }
fn from(c: CmdCow) -> Self {
Self { step: c.first().and_then(|d| d.try_into().ok()).unwrap_or_default() }
}
}
impl Cmp {
#[yazi_codegen::command]
pub fn arrow(&mut self, opt: Opt) {
if opt.step > 0 {
self.next(opt.step as usize);
} else {
self.prev(opt.step.unsigned_abs());
}
}
fn next(&mut self, step: usize) {
let len = self.cands.len();
if len == 0 {
return;
}
let new = opt.step.add(self.cursor, self.cands.len(), self.limit());
if new > self.cursor {
self.next(new);
} else {
self.prev(new);
}
}
fn next(&mut self, new: usize) {
let len = self.cands.len();
let old = self.cursor;
self.cursor = (self.cursor + step).min(len - 1);
self.cursor = new.min(len - 1);
let limit = self.limit();
if self.cursor >= len.min(self.offset + limit) {
@ -38,9 +43,9 @@ impl Cmp {
render!(old != self.cursor);
}
fn prev(&mut self, step: usize) {
fn prev(&mut self, new: usize) {
let old = self.cursor;
self.cursor = self.cursor.saturating_sub(step);
self.cursor = new.min(self.cands.len().saturating_sub(1));
if self.cursor < self.offset {
self.offset = self.offset.saturating_sub(old - self.cursor);

View file

@ -1,41 +1,31 @@
use yazi_fs::Step;
use yazi_macro::render;
use yazi_shared::event::{CmdCow, Data};
use yazi_shared::event::CmdCow;
use crate::{confirm::Confirm, mgr::Mgr};
struct Opt {
step: isize,
step: Step,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self { Self { step: c.first().and_then(Data::as_isize).unwrap_or(0) } }
fn from(c: CmdCow) -> Self {
Self { step: c.first().and_then(|d| d.try_into().ok()).unwrap_or_default() }
}
}
impl Confirm {
#[yazi_codegen::command]
pub fn arrow(&mut self, opt: Opt, mgr: &Mgr) {
if opt.step > 0 {
self.next(opt.step as usize, mgr.area(self.position).width)
} else {
self.prev(opt.step.unsigned_abs())
}
}
fn next(&mut self, step: usize, width: u16) {
let width = mgr.area(self.position).width;
let height = self.list.line_count(width);
if height == 0 {
return;
}
let old = self.offset;
self.offset = (self.offset + step).min(height - 1);
render!(old != self.offset);
}
fn prev(&mut self, step: usize) {
let old = self.offset;
self.offset -= step.min(self.offset);
let new = opt.step.add(self.offset, height, height);
self.offset = new.min(height - 1);
render!(old != self.offset);
}

View file

@ -1,30 +1,39 @@
use yazi_fs::Step;
use yazi_macro::render;
use yazi_shared::event::{CmdCow, Data};
use yazi_shared::event::CmdCow;
use crate::pick::Pick;
struct Opt {
step: isize,
step: Step,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self { Self { step: c.first().and_then(Data::as_isize).unwrap_or(0) } }
fn from(c: CmdCow) -> Self {
Self { step: c.first().and_then(|d| d.try_into().ok()).unwrap_or_default() }
}
}
impl Pick {
#[yazi_codegen::command]
pub fn arrow(&mut self, opt: Opt) {
if opt.step > 0 { self.next(opt.step as usize) } else { self.prev(opt.step.unsigned_abs()) }
}
fn next(&mut self, step: usize) {
let len = self.items.len();
if len == 0 {
return;
}
let new = opt.step.add(self.cursor, len, self.limit());
if new > self.cursor {
self.next(new);
} else {
self.prev(new);
}
}
fn next(&mut self, new: usize) {
let len = self.items.len();
let old = self.cursor;
self.cursor = (self.cursor + step).min(len - 1);
self.cursor = new.min(len - 1);
let limit = self.limit();
if self.cursor >= len.min(self.offset + limit) {
@ -34,9 +43,9 @@ impl Pick {
render!(old != self.cursor);
}
fn prev(&mut self, step: usize) {
fn prev(&mut self, new: usize) {
let old = self.cursor;
self.cursor = self.cursor.saturating_sub(step);
self.cursor = new.min(self.items.len().saturating_sub(1));
if self.cursor < self.offset {
self.offset = self.offset.saturating_sub(old - self.cursor);

View file

@ -1,31 +1,35 @@
use yazi_fs::Step;
use yazi_macro::render;
use yazi_shared::event::{CmdCow, Data};
use yazi_shared::event::CmdCow;
use crate::tasks::Tasks;
struct Opt {
step: isize,
step: Step,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self { Self { step: c.first().and_then(Data::as_isize).unwrap_or(0) } }
fn from(c: CmdCow) -> Self {
Self { step: c.first().and_then(|d| d.try_into().ok()).unwrap_or_default() }
}
}
impl From<isize> for Opt {
fn from(step: isize) -> Self { Self { step } }
fn from(step: isize) -> Self { Self { step: step.into() } }
}
impl Tasks {
#[yazi_codegen::command]
pub fn arrow(&mut self, opt: Opt) {
let max = Self::limit().min(self.summaries.len());
let old = self.cursor;
if opt.step > 0 {
let new = opt.step.add(self.cursor, max, max);
if new > old {
self.cursor += 1;
} else {
self.cursor = self.cursor.saturating_sub(1);
}
let max = Self::limit().min(self.summaries.len());
self.cursor = self.cursor.min(max.saturating_sub(1));
render!(self.cursor != old);
}