mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: add change case vim input actions (#3233)
This commit is contained in:
parent
782ecb16b2
commit
c72ea628bd
7 changed files with 52 additions and 4 deletions
|
|
@ -301,9 +301,10 @@ keymap = [
|
||||||
{ on = "p", run = "paste", desc = "Paste copied characters after the cursor" },
|
{ on = "p", run = "paste", desc = "Paste copied characters after the cursor" },
|
||||||
{ on = "P", run = "paste --before", desc = "Paste copied characters before the cursor" },
|
{ on = "P", run = "paste --before", desc = "Paste copied characters before the cursor" },
|
||||||
|
|
||||||
# Undo/Redo
|
# Undo/Redo/Change case
|
||||||
{ on = "u", run = "undo", desc = "Undo the last operation" },
|
{ on = "u", run = [ "undo", "lowercase"], desc = "Undo the last operation or Lowercase selected characters" },
|
||||||
{ on = "<C-r>", run = "redo", desc = "Redo the last operation" },
|
{ on = "<C-r>", run = "redo", desc = "Redo the last operation" },
|
||||||
|
{ on = "U", run = "uppercase", desc = "Uppercase selected characters" },
|
||||||
|
|
||||||
# Help
|
# Help
|
||||||
{ on = "~", run = "help", desc = "Open help" },
|
{ on = "~", run = "help", desc = "Open help" },
|
||||||
|
|
|
||||||
24
yazi-widgets/src/input/commands/case.rs
Normal file
24
yazi-widgets/src/input/commands/case.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
use anyhow::Result;
|
||||||
|
use yazi_macro::{act, render, succ};
|
||||||
|
use yazi_parser::VoidOpt;
|
||||||
|
use yazi_shared::data::Data;
|
||||||
|
|
||||||
|
use crate::input::{Input, op::InputOp};
|
||||||
|
|
||||||
|
impl Input {
|
||||||
|
pub fn uppercase(&mut self, _: VoidOpt) -> Result<Data> { self.apply_case(true) }
|
||||||
|
|
||||||
|
pub fn lowercase(&mut self, _: VoidOpt) -> Result<Data> { self.apply_case(false) }
|
||||||
|
|
||||||
|
fn apply_case(&mut self, uppercase: bool) -> Result<Data> {
|
||||||
|
match self.snap().op {
|
||||||
|
InputOp::Select(start) => {
|
||||||
|
self.snap_mut().op = InputOp::Case(uppercase, start);
|
||||||
|
render!(self.handle_op(self.snap().cursor, true));
|
||||||
|
act!(r#move, self)?;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
succ!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -35,6 +35,9 @@ impl Input {
|
||||||
|
|
||||||
on!(undo);
|
on!(undo);
|
||||||
on!(redo);
|
on!(redo);
|
||||||
|
|
||||||
|
on!(uppercase);
|
||||||
|
on!(lowercase);
|
||||||
}
|
}
|
||||||
InputMode::Insert => {
|
InputMode::Insert => {
|
||||||
on!(visual);
|
on!(visual);
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
yazi_macro::mod_flat!(backspace backward commands complete delete escape forward insert kill paste r#move r#type redo replace undo visual yank);
|
yazi_macro::mod_flat!(backspace backward commands complete delete escape forward insert kill paste r#move r#type redo replace undo visual yank case);
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,14 @@ use yazi_macro::{act, render, succ};
|
||||||
use yazi_parser::VoidOpt;
|
use yazi_parser::VoidOpt;
|
||||||
use yazi_shared::data::Data;
|
use yazi_shared::data::Data;
|
||||||
|
|
||||||
use crate::input::{Input, InputMode};
|
use crate::input::{Input, InputMode, InputOp};
|
||||||
|
|
||||||
impl Input {
|
impl Input {
|
||||||
pub fn undo(&mut self, _: VoidOpt) -> Result<Data> {
|
pub fn undo(&mut self, _: VoidOpt) -> Result<Data> {
|
||||||
|
if let InputOp::Select(_) = self.snap().op {
|
||||||
|
succ!();
|
||||||
|
}
|
||||||
|
|
||||||
if !self.snaps.undo() {
|
if !self.snaps.undo() {
|
||||||
succ!();
|
succ!();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,20 @@ impl Input {
|
||||||
snap.op = InputOp::None;
|
snap.op = InputOp::None;
|
||||||
futures::executor::block_on(CLIPBOARD.set(yanked));
|
futures::executor::block_on(CLIPBOARD.set(yanked));
|
||||||
}
|
}
|
||||||
|
InputOp::Case(upper, _) => {
|
||||||
|
let range = snap.op.range(cursor, include).unwrap();
|
||||||
|
let Range { start, end } = snap.idx(range.start)..snap.idx(range.end);
|
||||||
|
|
||||||
|
if let (Some(start), Some(end)) = (start, end) {
|
||||||
|
let selected = &snap.value[start..end];
|
||||||
|
let replaced = if upper { selected.to_uppercase() } else { selected.to_lowercase() };
|
||||||
|
snap.value.replace_range(start..end, &replaced);
|
||||||
|
}
|
||||||
|
|
||||||
|
snap.op = InputOp::None;
|
||||||
|
snap.mode = InputMode::Normal;
|
||||||
|
snap.cursor = range.start;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
snap.cursor = snap.count().saturating_sub(snap.mode.delta()).min(snap.cursor);
|
snap.cursor = snap.count().saturating_sub(snap.mode.delta()).min(snap.cursor);
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ pub enum InputOp {
|
||||||
Select(usize),
|
Select(usize),
|
||||||
Delete(bool, bool, usize), // cut, insert, start
|
Delete(bool, bool, usize), // cut, insert, start
|
||||||
Yank(usize),
|
Yank(usize),
|
||||||
|
Case(bool, usize), // upper, start
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputOp {
|
impl InputOp {
|
||||||
|
|
@ -17,6 +18,7 @@ impl InputOp {
|
||||||
Self::Select(s) => Some(*s),
|
Self::Select(s) => Some(*s),
|
||||||
Self::Delete(.., s) => Some(*s),
|
Self::Delete(.., s) => Some(*s),
|
||||||
Self::Yank(s) => Some(*s),
|
Self::Yank(s) => Some(*s),
|
||||||
|
Self::Case(.., s) => Some(*s),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue