feat: add change case vim input actions (#3233)

This commit is contained in:
Krystof Gartner 2025-10-09 20:54:11 +02:00 committed by sxyazi
parent 782ecb16b2
commit c72ea628bd
No known key found for this signature in database
7 changed files with 52 additions and 4 deletions

View file

@ -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" },

View 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!();
}
}

View file

@ -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);

View file

@ -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);

View file

@ -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!();
} }

View file

@ -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);

View file

@ -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),
} }
} }