mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat(arrow): move cursor in percentage of page
This commit is contained in:
parent
ec261a2708
commit
8260274459
4 changed files with 49 additions and 14 deletions
|
|
@ -61,7 +61,7 @@ impl Executor {
|
||||||
|
|
||||||
// Navigation
|
// Navigation
|
||||||
"arrow" => {
|
"arrow" => {
|
||||||
let step = exec.args.get(0).and_then(|s| s.parse().ok()).unwrap_or(0);
|
let step = exec.args.get(0).and_then(|s| s.parse().ok()).unwrap_or_default();
|
||||||
cx.manager.active_mut().arrow(step)
|
cx.manager.active_mut().arrow(step)
|
||||||
}
|
}
|
||||||
"peek" => {
|
"peek" => {
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,10 @@ keymap = [
|
||||||
{ on = [ "k" ], exec = "arrow -1", desc = "Move cursor up" },
|
{ on = [ "k" ], exec = "arrow -1", desc = "Move cursor up" },
|
||||||
{ on = [ "j" ], exec = "arrow 1", desc = "Move cursor down" },
|
{ on = [ "j" ], exec = "arrow 1", desc = "Move cursor down" },
|
||||||
|
|
||||||
{ on = [ "K" ], exec = "arrow -5", desc = "Move cursor up 5 lines" },
|
{ on = [ "<C-u>" ], exec = "arrow -50%", desc = "Move cursor up half page" },
|
||||||
{ on = [ "J" ], exec = "arrow 5", desc = "Move cursor down 5 lines" },
|
{ on = [ "<C-d>" ], exec = "arrow 50%", desc = "Move cursor down half page" },
|
||||||
|
{ on = [ "<C-b>" ], exec = "arrow -100%", desc = "Move cursor up one page" },
|
||||||
|
{ on = [ "<C-f>" ], exec = "arrow 100%", desc = "Move cursor down one page" },
|
||||||
|
|
||||||
{ on = [ "h" ], exec = "leave", desc = "Go back to the parent directory" },
|
{ on = [ "h" ], exec = "leave", desc = "Go back to the parent directory" },
|
||||||
{ on = [ "l" ], exec = "enter", desc = "Enter the child directory" },
|
{ on = [ "l" ], exec = "enter", desc = "Enter the child directory" },
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::{num::ParseIntError, str::FromStr};
|
||||||
|
|
||||||
use config::MANAGER;
|
use config::MANAGER;
|
||||||
use ratatui::layout::Rect;
|
use ratatui::layout::Rect;
|
||||||
use shared::Url;
|
use shared::Url;
|
||||||
|
|
@ -16,6 +18,12 @@ pub struct Folder {
|
||||||
pub hovered: Option<File>,
|
pub hovered: Option<File>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct Step {
|
||||||
|
pub(super) num: isize,
|
||||||
|
pub(super) percent: bool,
|
||||||
|
}
|
||||||
|
|
||||||
impl From<Url> for Folder {
|
impl From<Url> for Folder {
|
||||||
fn from(cwd: Url) -> Self { Self { cwd, ..Default::default() } }
|
fn from(cwd: Url) -> Self { Self { cwd, ..Default::default() } }
|
||||||
}
|
}
|
||||||
|
|
@ -24,6 +32,19 @@ impl From<&Url> for Folder {
|
||||||
fn from(cwd: &Url) -> Self { Self::from(cwd.clone()) }
|
fn from(cwd: &Url) -> Self { Self::from(cwd.clone()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromStr for Step {
|
||||||
|
type Err = ParseIntError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
Ok(Self { num: s.trim_end_matches('%').parse()?, percent: s.ends_with('%') })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<isize> for Step {
|
||||||
|
#[inline]
|
||||||
|
fn from(num: isize) -> Self { Self { num, percent: false } }
|
||||||
|
}
|
||||||
|
|
||||||
impl Folder {
|
impl Folder {
|
||||||
pub fn update(&mut self, op: FilesOp) -> bool {
|
pub fn update(&mut self, op: FilesOp) -> bool {
|
||||||
let b = match op {
|
let b = match op {
|
||||||
|
|
@ -58,18 +79,21 @@ impl Folder {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next(&mut self, step: usize) -> bool {
|
pub fn next(&mut self, mut step: usize, percent: bool) -> bool {
|
||||||
let len = self.files.len();
|
let len = self.files.len();
|
||||||
if len == 0 {
|
if len == 0 {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let limit = MANAGER.layout.folder_height();
|
||||||
|
if percent {
|
||||||
|
step = ((limit * step) as f64 * 0.01) as usize;
|
||||||
|
}
|
||||||
let old = self.cursor;
|
let old = self.cursor;
|
||||||
self.cursor = (self.cursor + step).min(len - 1);
|
self.cursor = (self.cursor + step).min(len - 1);
|
||||||
self.hovered = self.files.duplicate(self.cursor);
|
self.hovered = self.files.duplicate(self.cursor);
|
||||||
self.set_page(false);
|
self.set_page(false);
|
||||||
|
|
||||||
let limit = MANAGER.layout.folder_height();
|
|
||||||
if self.cursor >= (self.offset + limit).min(len).saturating_sub(5) {
|
if self.cursor >= (self.offset + limit).min(len).saturating_sub(5) {
|
||||||
self.offset = len.saturating_sub(limit).min(self.offset + self.cursor - old);
|
self.offset = len.saturating_sub(limit).min(self.offset + self.cursor - old);
|
||||||
}
|
}
|
||||||
|
|
@ -77,7 +101,11 @@ impl Folder {
|
||||||
old != self.cursor
|
old != self.cursor
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prev(&mut self, step: usize) -> bool {
|
pub fn prev(&mut self, mut step: usize, percent: bool) -> bool {
|
||||||
|
if percent {
|
||||||
|
let limit = MANAGER.layout.folder_height();
|
||||||
|
step = ((limit * step) as f64 * 0.01) as usize;
|
||||||
|
}
|
||||||
let old = self.cursor;
|
let old = self.cursor;
|
||||||
self.cursor = self.cursor.saturating_sub(step);
|
self.cursor = self.cursor.saturating_sub(step);
|
||||||
self.hovered = self.files.duplicate(self.cursor);
|
self.hovered = self.files.duplicate(self.cursor);
|
||||||
|
|
@ -105,7 +133,11 @@ impl Folder {
|
||||||
|
|
||||||
pub fn hover(&mut self, url: &Url) -> bool {
|
pub fn hover(&mut self, url: &Url) -> bool {
|
||||||
let new = self.files.position(url).unwrap_or(self.cursor);
|
let new = self.files.position(url).unwrap_or(self.cursor);
|
||||||
if new > self.cursor { self.next(new - self.cursor) } else { self.prev(self.cursor - new) }
|
if new > self.cursor {
|
||||||
|
self.next(new - self.cursor, false)
|
||||||
|
} else {
|
||||||
|
self.prev(self.cursor - new, false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use shared::{Debounce, Defer, InputError, Url};
|
||||||
use tokio::{pin, task::JoinHandle};
|
use tokio::{pin, task::JoinHandle};
|
||||||
use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};
|
use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};
|
||||||
|
|
||||||
use super::{Finder, Folder, Mode, Preview, PreviewLock};
|
use super::{Finder, Folder, Mode, Preview, PreviewLock, Step};
|
||||||
use crate::{emit, external::{self, FzfOpt, ZoxideOpt}, files::{File, FilesOp, FilesSorter}, input::InputOpt, Event, BLOCKER};
|
use crate::{emit, external::{self, FzfOpt, ZoxideOpt}, files::{File, FilesOp, FilesSorter}, input::InputOpt, Event, BLOCKER};
|
||||||
|
|
||||||
pub struct Tab {
|
pub struct Tab {
|
||||||
|
|
@ -67,11 +67,12 @@ impl Tab {
|
||||||
self.search_stop()
|
self.search_stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn arrow(&mut self, step: isize) -> bool {
|
pub fn arrow(&mut self, step: Step) -> bool {
|
||||||
let ok = if step > 0 {
|
let Step { num, percent } = step;
|
||||||
self.current.next(step as usize)
|
let ok = if step.num > 0 {
|
||||||
|
self.current.next(num as usize, percent)
|
||||||
} else {
|
} else {
|
||||||
self.current.prev(step.unsigned_abs())
|
self.current.prev(num.unsigned_abs(), percent)
|
||||||
};
|
};
|
||||||
if !ok {
|
if !ok {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -248,7 +249,7 @@ impl Tab {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(step) = finder.ring(&self.current.files, self.current.cursor(), prev) {
|
if let Some(step) = finder.ring(&self.current.files, self.current.cursor(), prev) {
|
||||||
self.arrow(step);
|
self.arrow(step.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.finder = Some(finder);
|
self.finder = Some(finder);
|
||||||
|
|
@ -280,7 +281,7 @@ impl Tab {
|
||||||
|
|
||||||
let mut b = finder.catchup(&self.current.files);
|
let mut b = finder.catchup(&self.current.files);
|
||||||
if let Some(step) = finder.arrow(&self.current.files, self.current.cursor(), prev) {
|
if let Some(step) = finder.arrow(&self.current.files, self.current.cursor(), prev) {
|
||||||
b |= self.arrow(step);
|
b |= self.arrow(step.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
b
|
b
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue