mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: single-character replace keybind for inputs
This commit is contained in:
parent
2eed881f12
commit
873f47d214
11 changed files with 65 additions and 1 deletions
|
|
@ -238,6 +238,7 @@ keymap = [
|
|||
{ 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 = "Enter replace mode" },
|
||||
|
||||
# Character-wise movement
|
||||
{ on = "h", run = "move -1", desc = "Move back a character" },
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ impl Input {
|
|||
CompletionProxy::close();
|
||||
}
|
||||
}
|
||||
InputMode::Replace => {
|
||||
snap.mode = InputMode::Normal;
|
||||
}
|
||||
}
|
||||
|
||||
self.snaps.tag(self.limit());
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
yazi_macro::mod_flat!(
|
||||
backspace backward close complete delete escape forward insert kill move_ paste redo
|
||||
show type_ undo visual yank
|
||||
replace show type_ undo visual yank
|
||||
);
|
||||
|
|
|
|||
20
yazi-core/src/input/commands/replace.rs
Normal file
20
yazi-core/src/input/commands/replace.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
use yazi_macro::render;
|
||||
use yazi_shared::event::CmdCow;
|
||||
|
||||
use crate::input::{Input, InputMode, op::InputOp};
|
||||
|
||||
impl Input {
|
||||
#[yazi_codegen::command]
|
||||
pub fn replace(&mut self, _: CmdCow) {
|
||||
let snap = self.snap_mut();
|
||||
if snap.mode == InputMode::Normal {
|
||||
snap.op = InputOp::None;
|
||||
snap.mode = InputMode::Replace;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
render!();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -11,6 +11,18 @@ impl From<CmdCow> for Opt {
|
|||
|
||||
impl Input {
|
||||
pub fn type_(&mut self, key: &Key) -> bool {
|
||||
if self.mode() == InputMode::Replace {
|
||||
let Some(c) = key.plain() else {
|
||||
return false;
|
||||
};
|
||||
|
||||
let snap = self.snaps.current_mut();
|
||||
snap.mode = InputMode::Normal;
|
||||
self.replace_str(c.encode_utf8(&mut [0; 4]));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if self.mode() != InputMode::Insert {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,17 @@ impl Input {
|
|||
render!();
|
||||
}
|
||||
|
||||
pub fn replace_str(&mut self, s: &str) {
|
||||
let snap = self.snaps.current_mut();
|
||||
|
||||
let start = snap.idx(snap.cursor).unwrap();
|
||||
let end = snap.idx(snap.cursor + 1).unwrap();
|
||||
snap.value.replace_range(start..end, s);
|
||||
|
||||
self.flush_value();
|
||||
render!();
|
||||
}
|
||||
|
||||
pub(super) fn handle_op(&mut self, cursor: usize, include: bool) -> bool {
|
||||
let old = self.snap().clone();
|
||||
let snap = self.snaps.current_mut();
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ pub enum InputMode {
|
|||
Normal,
|
||||
#[default]
|
||||
Insert,
|
||||
Replace,
|
||||
}
|
||||
|
||||
impl InputMode {
|
||||
|
|
|
|||
|
|
@ -93,6 +93,9 @@ impl App {
|
|||
if input.mode() == InputMode::Insert {
|
||||
input.type_str(&str);
|
||||
}
|
||||
if input.mode() == InputMode::Replace {
|
||||
input.replace_str(&str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -259,6 +259,7 @@ impl<'a> Executor<'a> {
|
|||
InputMode::Normal => {
|
||||
on!(insert);
|
||||
on!(visual);
|
||||
on!(replace);
|
||||
|
||||
on!(delete);
|
||||
on!(yank);
|
||||
|
|
@ -279,6 +280,7 @@ impl<'a> Executor<'a> {
|
|||
on!(backspace);
|
||||
on!(kill);
|
||||
}
|
||||
InputMode::Replace => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ impl Widget for Input<'_> {
|
|||
|
||||
_ = match input.mode() {
|
||||
InputMode::Insert => Term::set_cursor_bar(),
|
||||
InputMode::Replace => Term::set_cursor_underscore(),
|
||||
_ => Term::set_cursor_block(),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -159,6 +159,16 @@ impl Term {
|
|||
queue!(stderr(), SetCursorStyle::SteadyBar)?
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn set_cursor_underscore() -> Result<()> {
|
||||
use crossterm::cursor::SetCursorStyle;
|
||||
Ok(if INPUT.cursor_blink {
|
||||
queue!(stderr(), SetCursorStyle::BlinkingUnderScore)?
|
||||
} else {
|
||||
queue!(stderr(), SetCursorStyle::SteadyUnderScore)?
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Term {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue