This commit is contained in:
sxyazi 2024-01-02 08:35:04 +08:00
parent 4ddecbb6ee
commit 86538e6555
No known key found for this signature in database
15 changed files with 104 additions and 77 deletions

View file

@ -391,6 +391,9 @@ impl Files {
} }
// --- Filter // --- Filter
#[inline]
pub fn filter(&self) -> Option<&Filter> { self.filter.as_ref() }
pub fn set_filter(&mut self, filter: Option<Filter>) -> bool { pub fn set_filter(&mut self, filter: Option<Filter>) -> bool {
if self.filter == filter { if self.filter == filter {
return false; return false;

View file

@ -54,23 +54,27 @@ impl Help {
true true
} }
pub fn type_(&mut self, key: &Key) { pub fn type_(&mut self, key: &Key) -> bool {
let Some(input) = &mut self.in_filter else { let Some(input) = &mut self.in_filter else {
return; return false;
}; };
if key.is_enter() { if key.is_enter() {
self.in_filter = None; self.in_filter = None;
return render!(); render!();
return true;
} }
match &key { match &key {
Key { code: KeyCode::Backspace, shift: false, ctrl: false, alt: false } => { Key { code: KeyCode::Backspace, shift: false, ctrl: false, alt: false } => {
input.backspace(false) input.backspace(false);
}
_ => {
input.type_(key);
} }
_ => input.type_(key),
} }
self.filter_apply(); self.filter_apply();
true
} }
} }

View file

@ -1,4 +1,4 @@
use yazi_shared::event::Exec; use yazi_shared::{event::Exec, render};
use crate::input::{op::InputOp, Input}; use crate::input::{op::InputOp, Input};
@ -22,10 +22,8 @@ impl Input {
} }
InputOp::Select(start) => { InputOp::Select(start) => {
self.snap_mut().op = InputOp::Delete(opt.cut, opt.insert, start); self.snap_mut().op = InputOp::Delete(opt.cut, opt.insert, start);
// TODO: render render!(self.handle_op(self.snap().cursor, true));
todo!(); self.move_(0);
// return self.handle_op(self.snap().cursor, true).then(||
// self.move_(0)).is_some();
} }
InputOp::Delete(..) => { InputOp::Delete(..) => {
self.snap_mut().op = InputOp::Delete(opt.cut, opt.insert, 0); self.snap_mut().op = InputOp::Delete(opt.cut, opt.insert, 0);

View file

@ -30,6 +30,7 @@ impl Input {
} }
} }
} }
self.snaps.tag(self.limit()); self.snaps.tag(self.limit());
render!(); render!();
} }

View file

@ -1,5 +1,5 @@
use yazi_config::keymap::Key; use yazi_config::keymap::Key;
use yazi_shared::{event::Exec, render}; use yazi_shared::event::Exec;
use crate::input::{Input, InputMode}; use crate::input::{Input, InputMode};
@ -10,14 +10,16 @@ impl From<&Exec> for Opt {
} }
impl Input { impl Input {
pub fn type_(&mut self, key: &Key) { pub fn type_(&mut self, key: &Key) -> bool {
if self.mode() != InputMode::Insert { if self.mode() != InputMode::Insert {
return; return false;
} }
if let Some(c) = key.plain() { if let Some(c) = key.plain() {
let mut bits = [0; 4]; self.type_str(c.encode_utf8(&mut [0; 4]));
render!(self.type_str(c.encode_utf8(&mut bits))); return true;
} }
false
} }
} }

View file

@ -1,4 +1,4 @@
use yazi_shared::event::Exec; use yazi_shared::{event::Exec, render};
use crate::input::{op::InputOp, Input}; use crate::input::{op::InputOp, Input};
@ -10,10 +10,8 @@ impl Input {
} }
InputOp::Select(start) => { InputOp::Select(start) => {
self.snap_mut().op = InputOp::Yank(start); self.snap_mut().op = InputOp::Yank(start);
// TODO: render render!(self.handle_op(self.snap().cursor, true));
todo!(); self.move_(0);
// return self.handle_op(self.snap().cursor, true).then(||
// self.move_(0)).is_some();
} }
InputOp::Yank(_) => { InputOp::Yank(_) => {
self.snap_mut().op = InputOp::Yank(0); self.snap_mut().op = InputOp::Yank(0);

View file

@ -3,7 +3,7 @@ use std::ops::Range;
use tokio::sync::mpsc::UnboundedSender; use tokio::sync::mpsc::UnboundedSender;
use unicode_width::UnicodeWidthStr; use unicode_width::UnicodeWidthStr;
use yazi_config::{popup::Position, INPUT}; use yazi_config::{popup::Position, INPUT};
use yazi_shared::InputError; use yazi_shared::{render, InputError};
use super::{mode::InputMode, op::InputOp, InputSnap, InputSnaps}; use super::{mode::InputMode, op::InputOp, InputSnap, InputSnaps};
use crate::CLIPBOARD; use crate::CLIPBOARD;
@ -32,7 +32,7 @@ impl Input {
self.position.offset.width.saturating_sub(INPUT.border()) as usize self.position.offset.width.saturating_sub(INPUT.border()) as usize
} }
pub fn type_str(&mut self, s: &str) -> bool { pub fn type_str(&mut self, s: &str) {
let snap = self.snaps.current_mut(); let snap = self.snaps.current_mut();
if snap.cursor < 1 { if snap.cursor < 1 {
snap.value.insert_str(0, s); snap.value.insert_str(0, s);
@ -42,7 +42,7 @@ impl Input {
self.move_(s.chars().count() as isize); self.move_(s.chars().count() as isize);
self.flush_value(); self.flush_value();
true render!();
} }
pub(super) fn handle_op(&mut self, cursor: usize, include: bool) -> bool { pub(super) fn handle_op(&mut self, cursor: usize, include: bool) -> bool {

View file

@ -35,15 +35,15 @@ impl Manager {
return render!(self.active_mut().preview.reset()); return render!(self.active_mut().preview.reset());
}; };
let opt = opt.into() as Opt;
if matches!(opt.only_if, Some(ref u) if *u != hovered.url) {
return;
}
let hovered = hovered.clone(); let hovered = hovered.clone();
if !self.active().preview.same_url(&hovered.url) { if !self.active().preview.same_url(&hovered.url) {
self.active_mut().preview.skip = 0; self.active_mut().preview.skip = 0;
self.active_mut().preview.reset(); render!(self.active_mut().preview.reset());
}
let opt = opt.into() as Opt;
if matches!(opt.only_if, Some(ref u) if *u != hovered.url) {
return;
} }
if let Some(skip) = opt.skip { if let Some(skip) = opt.skip {

View file

@ -42,20 +42,20 @@ impl Tab {
} }
#[inline] #[inline]
fn escape_select(&mut self) -> bool { self.current.files.select_all(None) } fn escape_select(&mut self) -> bool { self.current.files.select_all(Some(false)) }
#[inline] #[inline]
fn escape_filter(&mut self) -> bool { fn escape_filter(&mut self) -> bool {
// TODO: render let b = self.current.files.filter().is_some();
todo!(); self.filter_do(super::filter::Opt { query: "", ..Default::default() });
// self.filter_do(super::filter::Opt { query: "", ..Default::default() }) b
} }
#[inline] #[inline]
fn escape_search(&mut self) -> bool { fn escape_search(&mut self) -> bool {
let b = self.current.cwd.is_search();
self.search_stop(); self.search_stop();
// TODO: render b
false
} }
pub fn escape(&mut self, opt: impl Into<Opt>) { pub fn escape(&mut self, opt: impl Into<Opt>) {

View file

@ -9,9 +9,9 @@ pub struct Opt {
impl From<&Exec> for Opt { impl From<&Exec> for Opt {
fn from(e: &Exec) -> Self { fn from(e: &Exec) -> Self {
Self { Self {
state: match e.named.get("state").map(|s| s.as_bytes()) { state: match e.named.get("state").map(|s| s.as_str()) {
Some(b"true") => Some(true), Some("true") => Some(true),
Some(b"false") => Some(false), Some("false") => Some(false),
_ => None, _ => None,
}, },
} }

View file

@ -1,8 +1,10 @@
use std::sync::atomic::Ordering;
use anyhow::{Ok, Result}; use anyhow::{Ok, Result};
use crossterm::event::KeyEvent; use crossterm::event::KeyEvent;
use yazi_config::{keymap::Key, ARGS}; use yazi_config::keymap::Key;
use yazi_core::input::InputMode; use yazi_core::input::InputMode;
use yazi_shared::{event::{Event, Exec}, render, term::Term, Layer}; use yazi_shared::{event::{Event, Exec, NEED_RENDER}, term::Term, Layer};
use crate::{lives::Lives, Ctx, Executor, Logs, Panic, Signals}; use crate::{lives::Lives, Ctx, Executor, Logs, Panic, Signals};
@ -16,47 +18,44 @@ impl App {
pub(crate) async fn run() -> Result<()> { pub(crate) async fn run() -> Result<()> {
Panic::install(); Panic::install();
let _log = Logs::init()?; let _log = Logs::init()?;
let term = Term::start()?; let term = Term::start()?;
let signals = Signals::start()?; let signals = Signals::start()?;
Lives::register()?; Lives::register()?;
let mut app = Self { cx: Ctx::make(), term: Some(term), signals }; let mut app = Self { cx: Ctx::make(), term: Some(term), signals };
app.render()?; app.render()?;
while let Some(event) = app.signals.recv().await {
match event { let mut events = Vec::with_capacity(10);
Event::Quit(no_cwd_file) => { while app.signals.rx.recv_many(&mut events, 10).await > 0 {
app.dispatch_quit(no_cwd_file); for event in events.drain(..) {
break; match event {
Event::Quit(no_cwd_file) => {
app.quit(no_cwd_file)?;
break;
}
Event::Key(key) => app.dispatch_key(key),
Event::Paste(str) => app.dispatch_paste(str),
Event::Resize(cols, rows) => app.dispatch_resize(cols, rows)?,
Event::Call(exec, layer) => app.dispatch_call(exec, layer),
event => app.dispatch_module(event),
} }
Event::Key(key) => app.dispatch_key(key), }
Event::Paste(str) => app.dispatch_paste(str),
// TODO: render if NEED_RENDER.swap(false, Ordering::Relaxed) {
// Event::Render(_) => app.render()?, app.render()?;
Event::Resize(cols, rows) => app.dispatch_resize(cols, rows)?,
Event::Call(exec, layer) => app.dispatch_call(exec, layer),
event => app.dispatch_module(event),
} }
} }
Ok(()) Ok(())
} }
fn dispatch_quit(&mut self, no_cwd_file: bool) { #[inline]
if let Some(p) = ARGS.cwd_file.as_ref().filter(|_| !no_cwd_file) {
let cwd = self.cx.manager.cwd().as_os_str();
std::fs::write(p, cwd.as_encoded_bytes()).ok();
}
Term::goodbye(|| false);
}
fn dispatch_key(&mut self, key: KeyEvent) { Executor::new(self).handle(Key::from(key)); } fn dispatch_key(&mut self, key: KeyEvent) { Executor::new(self).handle(Key::from(key)); }
fn dispatch_paste(&mut self, str: String) { fn dispatch_paste(&mut self, str: String) {
if self.cx.input.visible { if self.cx.input.visible {
let input = &mut self.cx.input; let input = &mut self.cx.input;
if input.mode() == InputMode::Insert && input.type_str(&str) { if input.mode() == InputMode::Insert {
render!(); input.type_str(&str);
} }
} }
} }

View file

@ -1,3 +1,4 @@
mod plugin; mod plugin;
mod quit;
mod render; mod render;
mod stop; mod stop;

View file

@ -0,0 +1,26 @@
use anyhow::Result;
use yazi_config::ARGS;
use yazi_shared::term::Term;
use crate::app::App;
pub struct Opt {
no_cwd_file: bool,
}
impl From<bool> for Opt {
fn from(no_cwd_file: bool) -> Self { Self { no_cwd_file } }
}
impl App {
pub(crate) fn quit(&mut self, opt: impl Into<Opt>) -> Result<()> {
let opt = opt.into() as Opt;
if let Some(p) = ARGS.cwd_file.as_ref().filter(|_| !opt.no_cwd_file) {
let cwd = self.cx.manager.cwd().as_os_str();
std::fs::write(p, cwd.as_encoded_bytes()).ok();
}
Term::goodbye(|| false);
}
}

View file

@ -18,14 +18,12 @@ impl<'a> Executor<'a> {
if cx.which.visible { if cx.which.visible {
return cx.which.press(key); return cx.which.press(key);
} }
// TODO: render if cx.help.visible && cx.help.type_(&key) {
// if cx.help.visible && cx.help.type_(&key) { return true;
// return true; }
// } if cx.input.visible && cx.input.type_(&key) {
// TODO: render return true;
// if cx.input.visible && cx.input.type_(&key) { }
// return true;
// }
if cx.completion.visible { if cx.completion.visible {
self.matches(Layer::Completion, key) || self.matches(Layer::Input, key) self.matches(Layer::Completion, key) || self.matches(Layer::Input, key)

View file

@ -5,8 +5,8 @@ use tokio::{select, sync::{mpsc::{self, UnboundedReceiver, UnboundedSender}, one
use yazi_shared::event::Event; use yazi_shared::event::Event;
pub(super) struct Signals { pub(super) struct Signals {
tx: UnboundedSender<Event>, tx: UnboundedSender<Event>,
rx: UnboundedReceiver<Event>, pub(super) rx: UnboundedReceiver<Event>,
term_stop_tx: Option<oneshot::Sender<()>>, term_stop_tx: Option<oneshot::Sender<()>>,
term_stop_rx: Option<oneshot::Receiver<()>>, term_stop_rx: Option<oneshot::Receiver<()>>,
@ -27,9 +27,6 @@ impl Signals {
Ok(signals) Ok(signals)
} }
#[inline]
pub(super) async fn recv(&mut self) -> Option<Event> { self.rx.recv().await }
pub(super) fn stop_term(&mut self, state: bool) { pub(super) fn stop_term(&mut self, state: bool) {
if state == self.term_stop_tx.is_none() { if state == self.term_stop_tx.is_none() {
return; return;