Skip to content

Commit

Permalink
feat: new arrow top and arrow bot commands to jump to the top and…
Browse files Browse the repository at this point in the history
… bottom (#2294)
  • Loading branch information
sxyazi authored Feb 5, 2025
1 parent 0c100ae commit e9fcab3
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 26 deletions.
4 changes: 2 additions & 2 deletions yazi-config/preset/keymap-default.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ keymap = [
{ on = "<PageUp>", run = "arrow -100%", desc = "Move cursor up one page" },
{ on = "<PageDown>", run = "arrow 100%", desc = "Move cursor down one page" },

{ on = [ "g", "g" ], run = "arrow -99999999", desc = "Move cursor to the top" },
{ on = "G", run = "arrow 99999999", desc = "Move cursor to the bottom" },
{ on = [ "g", "g" ], run = "arrow top", desc = "Move cursor to the top" },
{ on = "G", run = "arrow bot", desc = "Move cursor to the bottom" },

# Navigation
{ on = "h", run = "leave", desc = "Go back to the parent directory" },
Expand Down
11 changes: 11 additions & 0 deletions yazi-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ pub fn init() -> anyhow::Result<()> {
try_init(false)?;
}

// TODO: remove this
for c in KEYMAP.manager.iter().flat_map(|c| c.run.iter()) {
if c.name == "arrow"
&& c.first_str().unwrap_or_default().parse::<isize>().is_ok_and(|n| n <= -999 || n >= 999)
{
eprintln!("Deprecated command: `arrow -99999999` and `arrow 99999999` have been deprecated, please use `arrow top` and `arrow bot` instead, in your `keymap.toml`.
See #2294 for more details: https://github.com/sxyazi/yazi/pull/2294");
}
}

Ok(())
}

Expand Down
6 changes: 3 additions & 3 deletions yazi-core/src/input/commands/move_.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::str::FromStr;
use std::{num::ParseIntError, str::FromStr};

use unicode_width::UnicodeWidthStr;
use yazi_macro::render;
Expand Down Expand Up @@ -76,14 +76,14 @@ impl Default for OptStep {
}

impl FromStr for OptStep {
type Err = ();
type Err = ParseIntError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"bol" => Self::Bol,
"eol" => Self::Eol,
"first-char" => Self::FirstChar,
s => Self::Offset(s.parse().map_err(|_| ())?),
s => Self::Offset(s.parse()?),
})
}
}
Expand Down
22 changes: 14 additions & 8 deletions yazi-core/src/tab/commands/arrow.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use yazi_fs::Step;
use yazi_macro::render;
use yazi_proxy::ManagerProxy;
use yazi_shared::event::{CmdCow, Data};
use yazi_shared::event::CmdCow;

use crate::tab::Tab;

Expand All @@ -11,13 +11,7 @@ struct Opt {

impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self {
let step = match c.first() {
Some(Data::Integer(i)) => Step::from(*i as isize),
Some(Data::String(s)) => s.parse().unwrap_or_default(),
_ => Step::default(),
};

Self { step }
Self { step: c.first().and_then(|d| d.try_into().ok()).unwrap_or_default() }
}
}

Expand All @@ -28,6 +22,18 @@ impl From<isize> for Opt {
impl Tab {
#[yazi_codegen::command]
pub fn arrow(&mut self, opt: Opt) {
// TODO: remove this
if let Step::Fixed(n) = opt.step {
if n <= -999 || n >= 999 {
yazi_proxy::AppProxy::notify_warn(
"Deprecated command",
"`arrow -99999999` and `arrow 99999999` have been deprecated, please use `arrow top` and `arrow bot` instead.
See #2294 for more details: https://github.com/sxyazi/yazi/pull/2294",
);
}
}

if !self.current.arrow(opt.step) {
return;
}
Expand Down
38 changes: 25 additions & 13 deletions yazi-fs/src/step.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
use std::{num::ParseIntError, str::FromStr};

use yazi_shared::event::Data;

#[derive(Clone, Copy)]
pub enum Step {
Top,
Bot,
Fixed(isize),
Percent(i8),
}
Expand All @@ -10,34 +14,41 @@ impl Default for Step {
fn default() -> Self { Self::Fixed(0) }
}

impl From<isize> for Step {
fn from(n: isize) -> Self { Self::Fixed(n) }
}

impl FromStr for Step {
type Err = ParseIntError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(if let Some(s) = s.strip_suffix('%') {
Self::Percent(s.parse()?)
} else {
Self::Fixed(s.parse()?)
Ok(match s {
"top" => Self::Top,
"bot" => Self::Bot,
s if s.ends_with('%') => Self::Percent(s[..s.len() - 1].parse()?),
s => Self::Fixed(s.parse()?),
})
}
}

impl From<isize> for Step {
fn from(n: isize) -> Self { Self::Fixed(n) }
}

impl Step {
#[inline]
pub fn prev(n: usize) -> Self { Self::Fixed(-(n as isize)) }
impl TryFrom<&Data> for Step {
type Error = ParseIntError;

#[inline]
pub fn next(n: usize) -> Self { Self::Fixed(n as isize) }
fn try_from(value: &Data) -> Result<Self, Self::Error> {
Ok(match value {
Data::Integer(i) => Self::from(*i as isize),
Data::String(s) => s.parse()?,
_ => "".parse()?,
})
}
}

impl Step {
#[inline]
pub fn add(self, pos: usize, limit: usize) -> usize {
let fixed = match self {
Self::Top => return 0,
Self::Bot => return usize::MAX,
Self::Fixed(n) => n,
Self::Percent(0) => 0,
Self::Percent(n) => n as isize * limit as isize / 100,
Expand All @@ -48,6 +59,7 @@ impl Step {
#[inline]
pub fn is_positive(self) -> bool {
match self {
Self::Top | Self::Bot => false,
Self::Fixed(n) => n > 0,
Self::Percent(n) => n > 0,
}
Expand Down

0 comments on commit e9fcab3

Please sign in to comment.