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
#[inline]
pub fn filter(&self) -> Option<&Filter> { self.filter.as_ref() }
pub fn set_filter(&mut self, filter: Option<Filter>) -> bool {
if self.filter == filter {
return false;

View file

@ -54,23 +54,27 @@ impl Help {
true
}
pub fn type_(&mut self, key: &Key) {
pub fn type_(&mut self, key: &Key) -> bool {
let Some(input) = &mut self.in_filter else {
return;
return false;
};
if key.is_enter() {
self.in_filter = None;
return render!();
render!();
return true;
}
match &key {
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();
true
}
}

View file

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

View file

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

View file

@ -1,5 +1,5 @@
use yazi_config::keymap::Key;
use yazi_shared::{event::Exec, render};
use yazi_shared::event::Exec;
use crate::input::{Input, InputMode};
@ -10,14 +10,16 @@ impl From<&Exec> for Opt {
}
impl Input {
pub fn type_(&mut self, key: &Key) {
pub fn type_(&mut self, key: &Key) -> bool {
if self.mode() != InputMode::Insert {
return;
return false;
}
if let Some(c) = key.plain() {
let mut bits = [0; 4];
render!(self.type_str(c.encode_utf8(&mut bits)));
self.type_str(c.encode_utf8(&mut [0; 4]));
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};
@ -10,10 +10,8 @@ impl Input {
}
InputOp::Select(start) => {
self.snap_mut().op = InputOp::Yank(start);
// TODO: render
todo!();
// return self.handle_op(self.snap().cursor, true).then(||
// self.move_(0)).is_some();
render!(self.handle_op(self.snap().cursor, true));
self.move_(0);
}
InputOp::Yank(_) => {
self.snap_mut().op = InputOp::Yank(0);

View file

@ -3,7 +3,7 @@ use std::ops::Range;
use tokio::sync::mpsc::UnboundedSender;
use unicode_width::UnicodeWidthStr;
use yazi_config::{popup::Position, INPUT};
use yazi_shared::InputError;
use yazi_shared::{render, InputError};
use super::{mode::InputMode, op::InputOp, InputSnap, InputSnaps};
use crate::CLIPBOARD;
@ -32,7 +32,7 @@ impl Input {
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();
if snap.cursor < 1 {
snap.value.insert_str(0, s);
@ -42,7 +42,7 @@ impl Input {
self.move_(s.chars().count() as isize);
self.flush_value();
true
render!();
}
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());
};
let opt = opt.into() as Opt;
if matches!(opt.only_if, Some(ref u) if *u != hovered.url) {
return;
}
let hovered = hovered.clone();
if !self.active().preview.same_url(&hovered.url) {
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 {

View file

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

View file

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

View file

@ -1,8 +1,10 @@
use std::sync::atomic::Ordering;
use anyhow::{Ok, Result};
use crossterm::event::KeyEvent;
use yazi_config::{keymap::Key, ARGS};
use yazi_config::keymap::Key;
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};
@ -16,47 +18,44 @@ impl App {
pub(crate) async fn run() -> Result<()> {
Panic::install();
let _log = Logs::init()?;
let term = Term::start()?;
let signals = Signals::start()?;
Lives::register()?;
let mut app = Self { cx: Ctx::make(), term: Some(term), signals };
app.render()?;
while let Some(event) = app.signals.recv().await {
match event {
Event::Quit(no_cwd_file) => {
app.dispatch_quit(no_cwd_file);
break;
let mut events = Vec::with_capacity(10);
while app.signals.rx.recv_many(&mut events, 10).await > 0 {
for event in events.drain(..) {
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
// Event::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),
}
if NEED_RENDER.swap(false, Ordering::Relaxed) {
app.render()?;
}
}
Ok(())
}
fn dispatch_quit(&mut self, no_cwd_file: bool) {
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);
}
#[inline]
fn dispatch_key(&mut self, key: KeyEvent) { Executor::new(self).handle(Key::from(key)); }
fn dispatch_paste(&mut self, str: String) {
if self.cx.input.visible {
let input = &mut self.cx.input;
if input.mode() == InputMode::Insert && input.type_str(&str) {
render!();
if input.mode() == InputMode::Insert {
input.type_str(&str);
}
}
}

View file

@ -1,3 +1,4 @@
mod plugin;
mod quit;
mod render;
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 {
return cx.which.press(key);
}
// TODO: render
// if cx.help.visible && cx.help.type_(&key) {
// return true;
// }
// TODO: render
// if cx.input.visible && cx.input.type_(&key) {
// return true;
// }
if cx.help.visible && cx.help.type_(&key) {
return true;
}
if cx.input.visible && cx.input.type_(&key) {
return true;
}
if cx.completion.visible {
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;
pub(super) struct Signals {
tx: UnboundedSender<Event>,
rx: UnboundedReceiver<Event>,
tx: UnboundedSender<Event>,
pub(super) rx: UnboundedReceiver<Event>,
term_stop_tx: Option<oneshot::Sender<()>>,
term_stop_rx: Option<oneshot::Receiver<()>>,
@ -27,9 +27,6 @@ impl 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) {
if state == self.term_stop_tx.is_none() {
return;