mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: better api to move input cursor to bol/eol
This commit is contained in:
parent
8c92fa9f53
commit
5ce55232f7
2 changed files with 91 additions and 32 deletions
|
|
@ -232,13 +232,13 @@ keymap = [
|
|||
{ on = "<C-[>", run = "escape", desc = "Go back the normal mode, or cancel input" },
|
||||
|
||||
# Mode
|
||||
{ on = "i", run = "insert", desc = "Enter insert mode" },
|
||||
{ on = "a", run = "insert --append", desc = "Enter append mode" },
|
||||
{ on = "I", run = [ "move -999", "insert" ], desc = "Move to the BOL, and enter insert mode" },
|
||||
{ on = "A", run = [ "move 999", "insert --append" ], desc = "Move to the EOL, and enter append mode" },
|
||||
{ on = "v", run = "visual", desc = "Enter visual mode" },
|
||||
{ on = "V", run = [ "move -999", "visual", "move 999" ], desc = "Enter visual mode and select all" },
|
||||
{ on = "r", run = "replace", desc = "Replace a single character" },
|
||||
{ on = "i", run = "insert", desc = "Enter insert mode" },
|
||||
{ on = "a", run = "insert --append", desc = "Enter append mode" },
|
||||
{ on = "I", run = [ "move first-char", "insert" ], desc = "Move to the BOL, and enter insert mode" },
|
||||
{ on = "A", run = [ "move eol", "insert --append" ], desc = "Move to the EOL, and enter append mode" },
|
||||
{ on = "v", run = "visual", desc = "Enter visual mode" },
|
||||
{ on = "V", run = [ "move first-char", "visual", "move eol" ], desc = "Enter visual mode and select all" },
|
||||
{ on = "r", run = "replace", desc = "Replace a single character" },
|
||||
|
||||
# Character-wise movement
|
||||
{ on = "h", run = "move -1", desc = "Move back a character" },
|
||||
|
|
@ -256,12 +256,14 @@ keymap = [
|
|||
{ on = "<A-f>", run = "forward --end-of-word", desc = "Move forward to the end of the current or next word" },
|
||||
|
||||
# Line-wise movement
|
||||
{ on = "0", run = "move -999", desc = "Move to the BOL" },
|
||||
{ on = "$", run = "move 999", desc = "Move to the EOL" },
|
||||
{ on = "<C-a>", run = "move -999", desc = "Move to the BOL" },
|
||||
{ on = "<C-e>", run = "move 999", desc = "Move to the EOL" },
|
||||
{ on = "<Home>", run = "move -999", desc = "Move to the BOL" },
|
||||
{ on = "<End>", run = "move 999", desc = "Move to the EOL" },
|
||||
{ on = "0", run = "move bol", desc = "Move to the BOL" },
|
||||
{ on = "_", run = "move first-char", desc = "Move to the first non-whitespace character" },
|
||||
{ on = "^", run = "move first-char", desc = "Move to the first non-whitespace character" },
|
||||
{ on = "$", run = "move eol", desc = "Move to the EOL" },
|
||||
{ on = "<C-a>", run = "move first-char", desc = "Move to the BOL" },
|
||||
{ on = "<C-e>", run = "move eol", desc = "Move to the EOL" },
|
||||
{ on = "<Home>", run = "move first-char", desc = "Move to the BOL" },
|
||||
{ on = "<End>", run = "move eol", desc = "Move to the EOL" },
|
||||
|
||||
# Delete
|
||||
{ on = "<Backspace>", run = "backspace", desc = "Delete the character before the cursor" },
|
||||
|
|
@ -276,14 +278,14 @@ keymap = [
|
|||
{ on = "<A-d>", run = "kill forward", desc = "Kill forwards to the end of the current word" },
|
||||
|
||||
# Cut/Yank/Paste
|
||||
{ on = "d", run = "delete --cut", desc = "Cut the selected characters" },
|
||||
{ on = "D", run = [ "delete --cut", "move 999" ], desc = "Cut until the EOL" },
|
||||
{ on = "c", run = "delete --cut --insert", desc = "Cut the selected characters, and enter insert mode" },
|
||||
{ on = "C", run = [ "delete --cut --insert", "move 999" ], desc = "Cut until the EOL, and enter insert mode" },
|
||||
{ on = "x", run = [ "delete --cut", "move 1 --in-operating" ], desc = "Cut the current character" },
|
||||
{ on = "y", run = "yank", desc = "Copy the selected characters" },
|
||||
{ on = "p", run = "paste", desc = "Paste the copied characters after the cursor" },
|
||||
{ on = "P", run = "paste --before", desc = "Paste the copied characters before the cursor" },
|
||||
{ on = "d", run = "delete --cut", desc = "Cut the selected characters" },
|
||||
{ on = "D", run = [ "delete --cut", "move eol" ], desc = "Cut until the EOL" },
|
||||
{ on = "c", run = "delete --cut --insert", desc = "Cut the selected characters, and enter insert mode" },
|
||||
{ on = "C", run = [ "delete --cut --insert", "move eol" ], desc = "Cut until the EOL, and enter insert mode" },
|
||||
{ on = "x", run = [ "delete --cut", "move 1 --in-operating" ], desc = "Cut the current character" },
|
||||
{ on = "y", run = "yank", desc = "Copy the selected characters" },
|
||||
{ on = "p", run = "paste", desc = "Paste the copied characters after the cursor" },
|
||||
{ on = "P", run = "paste --before", desc = "Paste the copied characters before the cursor" },
|
||||
|
||||
# Undo/Redo
|
||||
{ on = "u", run = "undo", desc = "Undo the last operation" },
|
||||
|
|
|
|||
|
|
@ -5,20 +5,56 @@ use yazi_shared::event::{CmdCow, Data};
|
|||
use crate::input::{Input, op::InputOp, snap::InputSnap};
|
||||
|
||||
struct Opt {
|
||||
step: isize,
|
||||
step: Step,
|
||||
in_operating: bool,
|
||||
}
|
||||
|
||||
enum Step {
|
||||
Offset(isize),
|
||||
Bol,
|
||||
Eol,
|
||||
FirstChar,
|
||||
LastChar,
|
||||
}
|
||||
|
||||
impl TryFrom<&Data> for Step {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(d: &Data) -> Result<Self, Self::Error> {
|
||||
if let Some(offset) = d.as_isize() {
|
||||
return Ok(Step::Offset(offset));
|
||||
};
|
||||
if let Some(s) = d.as_str() {
|
||||
if let Ok(offset) = s.parse() {
|
||||
return Ok(Step::Offset(offset));
|
||||
};
|
||||
match s.as_ref() {
|
||||
"bol" => return Ok(Step::Bol),
|
||||
"eol" => return Ok(Step::Eol),
|
||||
"first-char" => return Ok(Step::FirstChar),
|
||||
"last-char" => return Ok(Step::LastChar),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CmdCow> for Opt {
|
||||
fn from(c: CmdCow) -> Self {
|
||||
Self {
|
||||
step: c.first().and_then(Data::as_isize).unwrap_or(0),
|
||||
step: c.get(0).unwrap().try_into().unwrap(),
|
||||
in_operating: c.bool("in-operating"),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl From<isize> for Opt {
|
||||
fn from(step: isize) -> Self { Self { step, in_operating: false } }
|
||||
fn from(step: isize) -> Self {
|
||||
Self {
|
||||
step: Step::Offset(step),
|
||||
in_operating: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Input {
|
||||
|
|
@ -29,14 +65,35 @@ impl Input {
|
|||
return;
|
||||
}
|
||||
|
||||
render!(self.handle_op(
|
||||
if opt.step <= 0 {
|
||||
snap.cursor.saturating_sub(opt.step.unsigned_abs())
|
||||
} else {
|
||||
snap.count().min(snap.cursor + opt.step as usize)
|
||||
},
|
||||
false,
|
||||
));
|
||||
let position = match opt.step {
|
||||
Step::Offset(offset) =>
|
||||
if offset <= 0 {
|
||||
snap.cursor.saturating_sub(offset.unsigned_abs())
|
||||
} else {
|
||||
snap.count().min(snap.cursor + offset as usize)
|
||||
},
|
||||
Step::Bol => 0,
|
||||
Step::Eol => snap.count(),
|
||||
Step::FirstChar => snap
|
||||
.value
|
||||
.chars()
|
||||
.enumerate()
|
||||
.filter(|(_, ch)| !ch.is_whitespace())
|
||||
.map(|(i, _)| i)
|
||||
.next()
|
||||
.unwrap_or(0),
|
||||
Step::LastChar => snap
|
||||
.value
|
||||
.chars()
|
||||
.rev()
|
||||
.enumerate()
|
||||
.filter(|(_, ch)| !ch.is_whitespace())
|
||||
.map(|(i, _)| i)
|
||||
.next()
|
||||
.unwrap_or(0),
|
||||
};
|
||||
|
||||
render!(self.handle_op(position, false));
|
||||
|
||||
let (limit, snap) = (self.limit(), self.snap_mut());
|
||||
if snap.offset > snap.cursor {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue