mirror of
https://github.com/sxyazi/yazi.git
synced 2024-12-24 09:12:43 +03:00
feat: enable bracketed paste (#5)
This commit is contained in:
parent
1f8c170359
commit
a8a5ab7f8c
@ -12,6 +12,7 @@ static mut TX: Option<UnboundedSender<Event>> = None;
|
||||
pub enum Event {
|
||||
Quit,
|
||||
Key(KeyEvent),
|
||||
Paste(String),
|
||||
Render(String),
|
||||
Resize(u16, u16),
|
||||
Stop(bool, Option<oneshot::Sender<()>>),
|
||||
|
@ -34,7 +34,7 @@ pub enum InputMode {
|
||||
|
||||
impl InputMode {
|
||||
#[inline]
|
||||
fn delta(&self) -> usize { (*self != InputMode::Insert) as usize }
|
||||
pub(super) fn delta(&self) -> usize { (*self != InputMode::Insert) as usize }
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||
@ -199,24 +199,26 @@ impl Input {
|
||||
self.move_(snap.len() as isize)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn type_(&mut self, c: char) -> bool {
|
||||
let mut bits = [0; 4];
|
||||
self.type_str(c.encode_utf8(&mut bits))
|
||||
}
|
||||
|
||||
pub fn type_str(&mut self, s: &str) -> bool {
|
||||
let snap = self.snap_mut();
|
||||
if snap.cursor < 1 {
|
||||
snap.value.insert(0, c);
|
||||
} else if snap.cursor == snap.count() {
|
||||
snap.value.push(c);
|
||||
snap.value.insert_str(0, s);
|
||||
} else {
|
||||
snap.value.insert(snap.idx(snap.cursor).unwrap(), c);
|
||||
snap.value.insert_str(snap.idx(snap.cursor).unwrap(), s);
|
||||
}
|
||||
self.move_(1)
|
||||
self.move_(s.chars().count() as isize)
|
||||
}
|
||||
|
||||
pub fn backspace(&mut self) -> bool {
|
||||
let snap = self.snap_mut();
|
||||
if snap.cursor < 1 {
|
||||
return false;
|
||||
} else if snap.cursor == snap.count() {
|
||||
snap.value.pop();
|
||||
} else {
|
||||
snap.value.remove(snap.idx(snap.cursor - 1).unwrap());
|
||||
}
|
||||
|
@ -18,20 +18,25 @@ pub(super) struct InputSnap {
|
||||
|
||||
impl InputSnap {
|
||||
pub(super) fn new(value: String) -> Self {
|
||||
let cursor = value.chars().count();
|
||||
let offset =
|
||||
cursor.saturating_sub(Self::find_window(&value.chars().rev().collect::<String>(), 0).end);
|
||||
|
||||
Self {
|
||||
let mut snap = Self {
|
||||
value,
|
||||
|
||||
op: Default::default(),
|
||||
start: Default::default(),
|
||||
|
||||
mode: Default::default(),
|
||||
offset,
|
||||
cursor,
|
||||
}
|
||||
offset: usize::MAX,
|
||||
cursor: usize::MAX,
|
||||
};
|
||||
snap.reset();
|
||||
snap
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn reset(&mut self) {
|
||||
self.cursor = self.cursor.min(self.value.chars().count().saturating_sub(self.mode.delta()));
|
||||
self.offset =
|
||||
self.offset.min(self.cursor.saturating_sub(Self::find_window(&self.rev(), 0).end));
|
||||
}
|
||||
|
||||
pub(super) fn insert(&mut self) -> bool {
|
||||
@ -80,6 +85,9 @@ impl InputSnap {
|
||||
&self.value[s.unwrap()..e.unwrap()]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn rev(&self) -> String { self.value.chars().rev().collect::<String>() }
|
||||
|
||||
#[inline]
|
||||
pub(super) fn range(&mut self, cursor: usize, include: bool) -> Option<Range<usize>> {
|
||||
self
|
||||
|
@ -55,6 +55,7 @@ impl InputSnaps {
|
||||
let value = mem::replace(&mut self.versions[self.idx].value, String::new());
|
||||
self.versions[self.idx] = self.current.clone();
|
||||
self.versions[self.idx].value = value;
|
||||
self.versions[self.idx].reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ use crossterm::event::KeyEvent;
|
||||
use tokio::sync::oneshot::{self};
|
||||
|
||||
use super::{root::Root, Ctx, Executor, Logs, Signals, Term};
|
||||
use crate::{config::keymap::{Control, Key, KeymapLayer}, core::{files::FilesOp, Event}, emit, misc::absolute_path};
|
||||
use crate::{config::keymap::{Control, Key, KeymapLayer}, core::{files::FilesOp, input::InputMode, Event}, emit, misc::absolute_path};
|
||||
|
||||
pub struct App {
|
||||
cx: Ctx,
|
||||
@ -23,6 +23,7 @@ impl App {
|
||||
match event {
|
||||
Event::Quit => break,
|
||||
Event::Key(key) => app.dispatch_key(key),
|
||||
Event::Paste(str) => app.dispatch_paste(str),
|
||||
Event::Render(_) => app.dispatch_render(),
|
||||
Event::Resize(..) => app.dispatch_resize(),
|
||||
Event::Stop(state, tx) => app.dispatch_stop(state, tx),
|
||||
@ -40,6 +41,15 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
fn dispatch_paste(&mut self, str: String) {
|
||||
if self.cx.layer() == KeymapLayer::Input {
|
||||
let input = &mut self.cx.input;
|
||||
if input.mode() == InputMode::Insert && input.type_str(&str) {
|
||||
emit!(Render);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn dispatch_render(&mut self) {
|
||||
if let Some(term) = &mut self.term {
|
||||
let _ = term.draw(|f| {
|
||||
|
@ -60,6 +60,7 @@ impl Signals {
|
||||
Some(Ok(event)) = reader.next() => {
|
||||
let event = match event {
|
||||
CrosstermEvent::Key(key) => Event::Key(key),
|
||||
CrosstermEvent::Paste(str) => Event::Paste(str),
|
||||
CrosstermEvent::Resize(cols, rows) => Event::Resize(cols, rows),
|
||||
_ => continue,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user