refactor: move event to shared (#403)

This commit is contained in:
三咲雅 · Misaki Masa 2023-11-28 02:21:36 +08:00 committed by GitHub
parent 4d7d2ef082
commit a1984725e4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
145 changed files with 850 additions and 671 deletions

View file

@ -3,7 +3,7 @@ use std::{fs::File, io::BufReader, path::{Path, PathBuf}};
use anyhow::Result; use anyhow::Result;
use image::{imageops::FilterType, io::Limits, DynamicImage, ImageFormat}; use image::{imageops::FilterType, io::Limits, DynamicImage, ImageFormat};
use yazi_config::{PREVIEW, TASKS}; use yazi_config::{PREVIEW, TASKS};
use yazi_shared::Term; use yazi_shared::term::Term;
pub struct Image; pub struct Image;

View file

@ -4,7 +4,7 @@ use anyhow::Result;
use base64::{engine::general_purpose, Engine}; use base64::{engine::general_purpose, Engine};
use image::{codecs::jpeg::JpegEncoder, DynamicImage}; use image::{codecs::jpeg::JpegEncoder, DynamicImage};
use ratatui::prelude::Rect; use ratatui::prelude::Rect;
use yazi_shared::Term; use yazi_shared::term::Term;
use super::image::Image; use super::image::Image;
use crate::{CLOSE, START}; use crate::{CLOSE, START};

View file

@ -4,7 +4,7 @@ use anyhow::Result;
use base64::{engine::general_purpose, Engine}; use base64::{engine::general_purpose, Engine};
use image::DynamicImage; use image::DynamicImage;
use ratatui::prelude::Rect; use ratatui::prelude::Rect;
use yazi_shared::Term; use yazi_shared::term::Term;
use super::image::Image; use super::image::Image;
use crate::{CLOSE, ESCAPE, START}; use crate::{CLOSE, ESCAPE, START};

View file

@ -4,7 +4,7 @@ use anyhow::Result;
use base64::{engine::general_purpose, Engine}; use base64::{engine::general_purpose, Engine};
use image::DynamicImage; use image::DynamicImage;
use ratatui::prelude::Rect; use ratatui::prelude::Rect;
use yazi_shared::Term; use yazi_shared::term::Term;
use super::image::Image; use super::image::Image;
use crate::{CLOSE, ESCAPE, START}; use crate::{CLOSE, ESCAPE, START};

View file

@ -4,7 +4,7 @@ use anyhow::{bail, Result};
use color_quant::NeuQuant; use color_quant::NeuQuant;
use image::DynamicImage; use image::DynamicImage;
use ratatui::prelude::Rect; use ratatui::prelude::Rect;
use yazi_shared::Term; use yazi_shared::term::Term;
use crate::{Image, CLOSE, ESCAPE, START}; use crate::{Image, CLOSE, ESCAPE, START};

View file

@ -1,7 +1,7 @@
use std::{ffi::OsString, fs, path::PathBuf, process}; use std::{ffi::OsString, fs, path::PathBuf, process};
use clap::Parser; use clap::Parser;
use yazi_shared::{current_cwd, expand_path}; use yazi_shared::fs::{current_cwd, expand_path};
use super::cli::Args; use super::cli::Args;
use crate::{Xdg, PREVIEW}; use crate::{Xdg, PREVIEW};

View file

@ -1,20 +1,31 @@
use std::borrow::Cow; use std::borrow::Cow;
use serde::Deserialize; use serde::Deserialize;
use yazi_shared::event::Exec;
use super::{Exec, Key}; use super::Key;
#[derive(Clone, Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct Control { pub struct Control {
pub on: Vec<Key>, pub on: Vec<Key>,
#[serde(deserialize_with = "Exec::deserialize")] #[serde(deserialize_with = "super::exec_deserialize")]
pub exec: Vec<Exec>, pub exec: Vec<Exec>,
pub desc: Option<String>, pub desc: Option<String>,
} }
impl Control { impl Control {
#[inline] pub fn to_call(&self) -> Vec<Exec> {
pub fn to_call(&self) -> Vec<Exec> { self.exec.clone() } self
.exec
.iter()
.map(|e| Exec {
cmd: e.cmd.clone(),
args: e.args.clone(),
named: e.named.clone(),
..Default::default()
})
.collect()
}
} }
impl Control { impl Control {

View file

@ -1,25 +1,22 @@
use std::{collections::BTreeMap, fmt::{self, Debug, Display}}; use std::fmt;
use anyhow::bail; use anyhow::{bail, Result};
use serde::{de::{self, Visitor}, Deserializer}; use serde::{de::{self, Visitor}, Deserializer};
use yazi_shared::event::Exec;
#[derive(Clone, Debug)] pub(super) fn exec_deserialize<'de, D>(deserializer: D) -> Result<Vec<Exec>, D::Error>
pub struct Exec { where
pub cmd: String, D: Deserializer<'de>,
pub args: Vec<String>, {
pub named: BTreeMap<String, String>, struct ExecVisitor;
}
impl TryFrom<&str> for Exec { fn parse(s: &str) -> Result<Exec> {
type Error = anyhow::Error;
fn try_from(s: &str) -> Result<Self, Self::Error> {
let s = shell_words::split(s)?; let s = shell_words::split(s)?;
if s.is_empty() { if s.is_empty() {
bail!("`exec` cannot be empty"); bail!("`exec` cannot be empty");
} }
let mut exec = Self { cmd: s[0].clone(), args: Vec::new(), named: BTreeMap::new() }; let mut exec = Exec { cmd: s[0].clone(), ..Default::default() };
for arg in s.into_iter().skip(1) { for arg in s.into_iter().skip(1) {
if arg.starts_with("--") { if arg.starts_with("--") {
let mut arg = arg.splitn(2, '='); let mut arg = arg.splitn(2, '=');
@ -32,86 +29,32 @@ impl TryFrom<&str> for Exec {
} }
Ok(exec) Ok(exec)
} }
}
impl Display for Exec { impl<'de> Visitor<'de> for ExecVisitor {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { type Value = Vec<Exec>;
write!(f, "{}", self.cmd)?;
if !self.args.is_empty() {
write!(f, " {}", self.args.join(" "))?;
}
for (k, v) in &self.named {
write!(f, " --{k}")?;
if !v.is_empty() {
write!(f, "={v}")?;
}
}
Ok(())
}
}
impl Exec { fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<Exec>, D::Error> formatter.write_str("a exec string, e.g. `tab_switch 0`")
where
D: Deserializer<'de>,
{
struct ExecVisitor;
impl<'de> Visitor<'de> for ExecVisitor {
type Value = Vec<Exec>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a exec string, e.g. tab_switch 0")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: de::SeqAccess<'de>,
{
let mut execs = Vec::new();
while let Some(value) = &seq.next_element::<String>()? {
execs.push(Exec::try_from(value.as_str()).map_err(de::Error::custom)?);
}
Ok(execs)
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(vec![Exec::try_from(value).map_err(de::Error::custom)?])
}
} }
deserializer.deserialize_any(ExecVisitor) fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
} where
} A: de::SeqAccess<'de>,
{
impl Exec { let mut execs = Vec::new();
#[inline] while let Some(value) = &seq.next_element::<String>()? {
pub fn call(cwd: &str, args: Vec<String>) -> Self { execs.push(parse(value).map_err(de::Error::custom)?);
Exec { cmd: cwd.to_owned(), args, named: Default::default() } }
} Ok(execs)
}
#[inline]
pub fn call_named(cwd: &str, named: BTreeMap<String, String>) -> Self { fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
Exec { cmd: cwd.to_owned(), args: Default::default(), named } where
} E: de::Error,
{
#[inline] Ok(vec![parse(value).map_err(de::Error::custom)?])
pub fn vec(self) -> Vec<Self> { vec![self] }
#[inline]
pub fn with(mut self, name: impl ToString, value: impl ToString) -> Self {
self.named.insert(name.to_string(), value.to_string());
self
}
#[inline]
pub fn with_bool(mut self, name: impl ToString, state: bool) -> Self {
if state {
self.named.insert(name.to_string(), Default::default());
} }
self
} }
deserializer.deserialize_any(ExecVisitor)
} }

View file

@ -1,6 +1,5 @@
use std::fmt::{self, Display};
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
use yazi_shared::Layer;
use super::Control; use super::Control;
use crate::MERGED_KEYMAP; use crate::MERGED_KEYMAP;
@ -63,41 +62,16 @@ impl Default for Keymap {
impl Keymap { impl Keymap {
#[inline] #[inline]
pub fn get(&self, layer: KeymapLayer) -> &Vec<Control> { pub fn get(&self, layer: Layer) -> &Vec<Control> {
match layer { match layer {
KeymapLayer::Manager => &self.manager, Layer::App => unreachable!(),
KeymapLayer::Tasks => &self.tasks, Layer::Manager => &self.manager,
KeymapLayer::Select => &self.select, Layer::Tasks => &self.tasks,
KeymapLayer::Input => &self.input, Layer::Select => &self.select,
KeymapLayer::Help => &self.help, Layer::Input => &self.input,
KeymapLayer::Completion => &self.completion, Layer::Help => &self.help,
KeymapLayer::Which => unreachable!(), Layer::Completion => &self.completion,
} Layer::Which => unreachable!(),
}
}
#[derive(Debug, Default, PartialEq, Eq, Hash, Clone, Copy)]
pub enum KeymapLayer {
#[default]
Manager,
Tasks,
Select,
Input,
Help,
Completion,
Which,
}
impl Display for KeymapLayer {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
KeymapLayer::Manager => write!(f, "manager"),
KeymapLayer::Tasks => write!(f, "tasks"),
KeymapLayer::Select => write!(f, "select"),
KeymapLayer::Input => write!(f, "input"),
KeymapLayer::Help => write!(f, "help"),
KeymapLayer::Completion => write!(f, "completion"),
KeymapLayer::Which => write!(f, "which"),
} }
} }
} }

View file

@ -4,6 +4,7 @@ mod key;
mod keymap; mod keymap;
pub use control::*; pub use control::*;
#[allow(unused_imports)]
pub use exec::*; pub use exec::*;
pub use key::*; pub use key::*;
pub use keymap::*; pub use keymap::*;

View file

@ -2,7 +2,7 @@ use anyhow::bail;
use crossterm::terminal::WindowSize; use crossterm::terminal::WindowSize;
use ratatui::{prelude::Rect, widgets::{Block, Padding}}; use ratatui::{prelude::Rect, widgets::{Block, Padding}};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use yazi_shared::Term; use yazi_shared::term::Term;
use crate::{PREVIEW, THEME}; use crate::{PREVIEW, THEME};

View file

@ -2,7 +2,7 @@ use std::path::PathBuf;
use serde::Deserialize; use serde::Deserialize;
use validator::Validate; use validator::Validate;
use yazi_shared::expand_path; use yazi_shared::fs::expand_path;
use crate::MERGED_YAZI; use crate::MERGED_YAZI;

View file

@ -2,7 +2,7 @@ use super::{Offset, Position};
use crate::{INPUT, SELECT}; use crate::{INPUT, SELECT};
#[derive(Default)] #[derive(Default)]
pub struct InputOpt { pub struct InputCfg {
pub title: String, pub title: String,
pub value: String, pub value: String,
pub position: Position, pub position: Position,
@ -12,13 +12,13 @@ pub struct InputOpt {
} }
#[derive(Default)] #[derive(Default)]
pub struct SelectOpt { pub struct SelectCfg {
pub title: String, pub title: String,
pub items: Vec<String>, pub items: Vec<String>,
pub position: Position, pub position: Position,
} }
impl InputOpt { impl InputCfg {
#[inline] #[inline]
pub fn cd() -> Self { pub fn cd() -> Self {
Self { Self {
@ -122,7 +122,7 @@ impl InputOpt {
} }
} }
impl SelectOpt { impl SelectCfg {
#[inline] #[inline]
fn max_height(len: usize) -> u16 { fn max_height(len: usize) -> u16 {
SELECT.open_offset.height.min(SELECT.border().saturating_add(len as u16)) SELECT.open_offset.height.min(SELECT.border().saturating_add(len as u16))

View file

@ -1,6 +1,6 @@
use crossterm::terminal::WindowSize; use crossterm::terminal::WindowSize;
use ratatui::layout::Rect; use ratatui::layout::Rect;
use yazi_shared::Term; use yazi_shared::term::Term;
use super::{Offset, Origin}; use super::{Offset, Origin};

View file

@ -2,7 +2,7 @@ use std::{path::{Path, PathBuf}, time::{self, SystemTime}};
use md5::{Digest, Md5}; use md5::{Digest, Md5};
use serde::Deserialize; use serde::Deserialize;
use yazi_shared::expand_path; use yazi_shared::fs::expand_path;
use crate::{xdg::Xdg, MERGED_YAZI}; use crate::{xdg::Xdg, MERGED_YAZI};

View file

@ -2,7 +2,7 @@ use std::path::PathBuf;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use validator::Validate; use validator::Validate;
use yazi_shared::expand_path; use yazi_shared::fs::expand_path;
use super::{Filetype, Icon, Style}; use super::{Filetype, Icon, Style};
use crate::{validation::check_validation, MERGED_THEME}; use crate::{validation::check_validation, MERGED_THEME};

View file

@ -1,6 +1,6 @@
use std::{env, path::PathBuf}; use std::{env, path::PathBuf};
use yazi_shared::expand_path; use yazi_shared::fs::expand_path;
pub(super) struct Xdg; pub(super) struct Xdg;

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::completion::Completion; use crate::completion::Completion;

View file

@ -1,6 +1,6 @@
use yazi_config::keymap::{Exec, KeymapLayer}; use yazi_shared::{emit, event::Exec, Layer};
use crate::{completion::Completion, emit, input::Input}; use crate::{completion::Completion, input::Input};
pub struct Opt { pub struct Opt {
submit: bool, submit: bool,
@ -13,7 +13,7 @@ impl From<&Exec> for Opt {
impl Completion { impl Completion {
#[inline] #[inline]
pub fn _close() { pub fn _close() {
emit!(Call(Exec::call("close", vec![]).vec(), KeymapLayer::Completion)); emit!(Call(Exec::call("close", vec![]).vec(), Layer::Completion));
} }
pub fn close(&mut self, opt: impl Into<Opt>) -> bool { pub fn close(&mut self, opt: impl Into<Opt>) -> bool {

View file

@ -1,6 +1,6 @@
use std::{mem, ops::ControlFlow}; use std::{mem, ops::ControlFlow};
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::completion::Completion; use crate::completion::Completion;

View file

@ -1,9 +1,9 @@
use std::{mem, path::{MAIN_SEPARATOR, MAIN_SEPARATOR_STR}}; use std::{mem, path::{MAIN_SEPARATOR, MAIN_SEPARATOR_STR}};
use tokio::fs; use tokio::fs;
use yazi_config::keymap::{Exec, KeymapLayer}; use yazi_shared::{emit, event::Exec, Layer};
use crate::{completion::Completion, emit}; use crate::completion::Completion;
pub struct Opt<'a> { pub struct Opt<'a> {
word: &'a str, word: &'a str,
@ -24,7 +24,7 @@ impl Completion {
pub fn _trigger(word: &str, ticket: usize) { pub fn _trigger(word: &str, ticket: usize) {
emit!(Call( emit!(Call(
Exec::call("trigger", vec![word.to_owned()]).with("ticket", ticket).vec(), Exec::call("trigger", vec![word.to_owned()]).with("ticket", ticket).vec(),
KeymapLayer::Completion Layer::Completion
)); ));
} }
@ -69,7 +69,7 @@ impl Completion {
.with("word", child) .with("word", child)
.with("ticket", ticket) .with("ticket", ticket)
.vec(), .vec(),
KeymapLayer::Completion Layer::Completion
)); ));
} }

View file

@ -1,5 +1,7 @@
use ratatui::prelude::Rect; use ratatui::prelude::Rect;
use tokio::sync::oneshot;
use yazi_config::popup::{Origin, Position}; use yazi_config::popup::{Origin, Position};
use yazi_shared::{emit, event::Exec, Layer};
use crate::{completion::Completion, help::Help, input::Input, manager::Manager, select::Select, tasks::Tasks, which::Which}; use crate::{completion::Completion, help::Help, input::Input, manager::Manager, select::Select, tasks::Tasks, which::Which};
@ -26,6 +28,21 @@ impl Ctx {
} }
} }
#[inline]
pub async fn stop() {
let (tx, rx) = oneshot::channel::<()>();
emit!(Call(Exec::call("stop", vec!["true".to_string()]).with_data(Some(tx)).vec(), Layer::App));
rx.await.ok();
}
#[inline]
pub fn resume() {
emit!(Call(
Exec::call("stop", vec!["false".to_string()]).with_data(None::<oneshot::Sender<()>>).vec(),
Layer::App
));
}
pub fn area(&self, position: &Position) -> Rect { pub fn area(&self, position: &Position) -> Rect {
if position.origin != Origin::Hovered { if position.origin != Origin::Hovered {
return position.rect(); return position.rect();

View file

@ -1,106 +0,0 @@
use std::{collections::BTreeMap, ffi::OsString};
use anyhow::Result;
use crossterm::event::KeyEvent;
use tokio::sync::{mpsc::{self, UnboundedSender}, oneshot};
use yazi_config::{keymap::{Exec, KeymapLayer}, open::Opener, popup::{InputOpt, SelectOpt}};
use yazi_shared::{InputError, RoCell, Url};
use super::files::FilesOp;
use crate::{preview::PreviewLock, tasks::TasksProgress};
static TX: RoCell<UnboundedSender<Event>> = RoCell::new();
pub enum Event {
Quit(bool), // no-cwd-file
Key(KeyEvent),
Paste(String),
Render(String),
Resize(u16, u16),
Stop(bool, Option<oneshot::Sender<()>>),
Call(Vec<Exec>, KeymapLayer),
// Manager
Files(FilesOp),
Pages(usize),
Mimetype(BTreeMap<Url, String>),
Preview(PreviewLock),
// Input
Select(SelectOpt, oneshot::Sender<Result<usize>>),
Input(InputOpt, mpsc::UnboundedSender<Result<String, InputError>>),
// Tasks
Open(Vec<(OsString, String)>, Option<Opener>),
Progress(TasksProgress),
}
impl Event {
#[inline]
pub fn init(tx: UnboundedSender<Event>) { TX.init(tx); }
#[inline]
pub fn emit(self) { TX.send(self).ok(); }
pub async fn wait<T>(self, rx: oneshot::Receiver<T>) -> T {
TX.send(self).ok();
rx.await.unwrap_or_else(|_| std::process::exit(0))
}
}
#[macro_export]
macro_rules! emit {
(Quit($no_cwd_file:expr)) => {
$crate::Event::Quit($no_cwd_file).emit();
};
(Key($key:expr)) => {
$crate::Event::Key($key).emit();
};
(Render) => {
$crate::Event::Render(format!("{}:{}", file!(), line!())).emit();
};
(Resize($cols:expr, $rows:expr)) => {
$crate::Event::Resize($cols, $rows).emit();
};
(Stop($state:expr)) => {{
let (tx, rx) = tokio::sync::oneshot::channel();
$crate::Event::Stop($state, Some(tx)).wait(rx)
}};
(Call($exec:expr, $layer:expr)) => {
$crate::Event::Call($exec, $layer).emit();
};
(Files($op:expr)) => {
$crate::Event::Files($op).emit();
};
(Pages($page:expr)) => {
$crate::Event::Pages($page).emit();
};
(Mimetype($mimes:expr)) => {
$crate::Event::Mimetype($mimes).emit();
};
(Preview($lock:expr)) => {
$crate::Event::Preview($lock).emit();
};
(Select($opt:expr)) => {{
let (tx, rx) = tokio::sync::oneshot::channel();
$crate::Event::Select($opt, tx).wait(rx)
}};
(Input($opt:expr)) => {{
let (tx, rx) = tokio::sync::mpsc::unbounded_channel();
$crate::Event::Input($opt, tx).emit();
rx
}};
(Open($targets:expr, $opener:expr)) => {
$crate::Event::Open($targets, $opener).emit();
};
(Progress($progress:expr)) => {
$crate::Event::Progress($progress).emit();
};
($event:ident) => {
$crate::Event::$event.emit();
};
}

View file

@ -2,9 +2,7 @@ use std::process::Stdio;
use anyhow::Result; use anyhow::Result;
use tokio::{io::{AsyncBufReadExt, BufReader}, process::Command, sync::mpsc::{self, UnboundedReceiver}}; use tokio::{io::{AsyncBufReadExt, BufReader}, process::Command, sync::mpsc::{self, UnboundedReceiver}};
use yazi_shared::Url; use yazi_shared::{files::File, fs::Url};
use crate::files::File;
pub struct FdOpt { pub struct FdOpt {
pub cwd: Url, pub cwd: Url,

View file

@ -4,7 +4,7 @@ use anyhow::{bail, Result};
use futures::TryFutureExt; use futures::TryFutureExt;
use tokio::process::Command; use tokio::process::Command;
use tracing::error; use tracing::error;
use yazi_shared::{MimeKind, Url}; use yazi_shared::{fs::Url, MimeKind};
async fn _file(files: &[&Url]) -> Result<BTreeMap<Url, String>> { async fn _file(files: &[&Url]) -> Result<BTreeMap<Url, String>> {
if files.is_empty() { if files.is_empty() {

View file

@ -2,7 +2,7 @@ use std::{path::Path, process::Stdio};
use anyhow::{bail, Result}; use anyhow::{bail, Result};
use tokio::process::Command; use tokio::process::Command;
use yazi_shared::Url; use yazi_shared::fs::Url;
pub struct FzfOpt { pub struct FzfOpt {
pub cwd: Url, pub cwd: Url,

View file

@ -2,9 +2,7 @@ use std::process::Stdio;
use anyhow::Result; use anyhow::Result;
use tokio::{io::{AsyncBufReadExt, BufReader}, process::Command, sync::mpsc::{self, UnboundedReceiver}}; use tokio::{io::{AsyncBufReadExt, BufReader}, process::Command, sync::mpsc::{self, UnboundedReceiver}};
use yazi_shared::Url; use yazi_shared::{files::File, fs::Url};
use crate::files::File;
pub struct RgOpt { pub struct RgOpt {
pub cwd: Url, pub cwd: Url,

View file

@ -2,7 +2,7 @@ use std::process::Stdio;
use anyhow::{bail, Result}; use anyhow::{bail, Result};
use tokio::process::Command; use tokio::process::Command;
use yazi_shared::Url; use yazi_shared::fs::Url;
pub struct ZoxideOpt { pub struct ZoxideOpt {
pub cwd: Url, pub cwd: Url,

View file

@ -3,9 +3,9 @@ use std::{collections::{BTreeMap, BTreeSet}, mem, ops::Deref, sync::atomic::Orde
use anyhow::Result; use anyhow::Result;
use tokio::{fs, select, sync::mpsc::{self, UnboundedReceiver}}; use tokio::{fs, select, sync::mpsc::{self, UnboundedReceiver}};
use yazi_config::{manager::SortBy, MANAGER}; use yazi_config::{manager::SortBy, MANAGER};
use yazi_shared::Url; use yazi_shared::{files::{File, FILES_TICKET}, fs::Url};
use super::{File, FilesSorter, FILES_TICKET}; use super::FilesSorter;
pub struct Files { pub struct Files {
items: Vec<File>, items: Vec<File>,

View file

@ -1,9 +1,5 @@
mod file;
mod files; mod files;
mod op;
mod sorter; mod sorter;
pub use file::*;
pub use files::*; pub use files::*;
pub use op::*;
pub use sorter::*; pub use sorter::*;

View file

@ -1,9 +1,7 @@
use std::{cmp::Ordering, collections::BTreeMap, mem}; use std::{cmp::Ordering, collections::BTreeMap, mem};
use yazi_config::manager::SortBy; use yazi_config::manager::SortBy;
use yazi_shared::{natsort, Url}; use yazi_shared::{files::File, fs::Url, natsort};
use super::File;
#[derive(Clone, Copy, Default, PartialEq)] #[derive(Clone, Copy, Default, PartialEq)]
pub struct FilesSorter { pub struct FilesSorter {

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::help::Help; use crate::help::Help;

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::help::Help; use crate::help::Help;

View file

@ -1,4 +1,5 @@
use yazi_config::{keymap::Exec, popup::{Offset, Origin, Position}}; use yazi_config::popup::{Offset, Origin, Position};
use yazi_shared::event::Exec;
use crate::{help::Help, input::Input}; use crate::{help::Help, input::Input};

View file

@ -1,7 +1,7 @@
use crossterm::event::KeyCode; use crossterm::event::KeyCode;
use unicode_width::UnicodeWidthStr; use unicode_width::UnicodeWidthStr;
use yazi_config::{keymap::{Control, Key, KeymapLayer}, KEYMAP}; use yazi_config::{keymap::{Control, Key}, KEYMAP};
use yazi_shared::Term; use yazi_shared::{term::Term, Layer};
use super::HELP_MARGIN; use super::HELP_MARGIN;
use crate::input::Input; use crate::input::Input;
@ -9,8 +9,8 @@ use crate::input::Input;
#[derive(Default)] #[derive(Default)]
pub struct Help { pub struct Help {
pub visible: bool, pub visible: bool,
pub layer: KeymapLayer, pub layer: Layer,
pub(super) bindings: Vec<Control>, pub(super) bindings: Vec<&'static Control>,
// Filter // Filter
keyword: Option<String>, keyword: Option<String>,
@ -24,7 +24,7 @@ impl Help {
#[inline] #[inline]
pub fn limit() -> usize { Term::size().rows.saturating_sub(HELP_MARGIN) as usize } pub fn limit() -> usize { Term::size().rows.saturating_sub(HELP_MARGIN) as usize }
pub fn toggle(&mut self, layer: KeymapLayer) -> bool { pub fn toggle(&mut self, layer: Layer) -> bool {
self.visible = !self.visible; self.visible = !self.visible;
self.layer = layer; self.layer = layer;
@ -44,9 +44,9 @@ impl Help {
} }
if let Some(kw) = kw { if let Some(kw) = kw {
self.bindings = KEYMAP.get(self.layer).iter().filter(|&c| c.contains(kw)).cloned().collect(); self.bindings = KEYMAP.get(self.layer).iter().filter(|&c| c.contains(kw)).collect();
} else { } else {
self.bindings = KEYMAP.get(self.layer).clone(); self.bindings = KEYMAP.get(self.layer).iter().collect();
} }
self.keyword = kw.map(|s| s.to_owned()); self.keyword = kw.map(|s| s.to_owned());
@ -89,7 +89,7 @@ impl Help {
// --- Bindings // --- Bindings
#[inline] #[inline]
pub fn window(&self) -> &[Control] { pub fn window(&self) -> &[&Control] {
let end = (self.offset + Self::limit()).min(self.bindings.len()); let end = (self.offset + Self::limit()).min(self.bindings.len());
&self.bindings[self.offset..end] &self.bindings[self.offset..end]
} }

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::input::Input; use crate::input::Input;

View file

@ -1,5 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::{event::Exec, CharKind};
use yazi_shared::CharKind;
use crate::input::Input; use crate::input::Input;

View file

@ -1,5 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::{event::Exec, InputError};
use yazi_shared::InputError;
use crate::{completion::Completion, input::Input}; use crate::{completion::Completion, input::Input};

View file

@ -1,8 +1,8 @@
use std::path::MAIN_SEPARATOR; use std::path::MAIN_SEPARATOR;
use yazi_config::keymap::{Exec, KeymapLayer}; use yazi_shared::{emit, event::Exec, Layer};
use crate::{emit, input::Input}; use crate::input::Input;
pub struct Opt<'a> { pub struct Opt<'a> {
word: &'a str, word: &'a str,
@ -23,7 +23,7 @@ impl Input {
pub fn _complete(word: &str, ticket: usize) { pub fn _complete(word: &str, ticket: usize) {
emit!(Call( emit!(Call(
Exec::call("complete", vec![word.to_owned()]).with("ticket", ticket).vec(), Exec::call("complete", vec![word.to_owned()]).with("ticket", ticket).vec(),
KeymapLayer::Input Layer::Input
)); ));
} }

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::input::{op::InputOp, Input}; use crate::input::{op::InputOp, Input};

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::{completion::Completion, input::{op::InputOp, Input, InputMode}}; use crate::{completion::Completion, input::{op::InputOp, Input, InputMode}};

View file

@ -1,5 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::{event::Exec, CharKind};
use yazi_shared::CharKind;
use crate::input::{op::InputOp, Input}; use crate::input::{op::InputOp, Input};

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::input::{op::InputOp, Input, InputMode}; use crate::input::{op::InputOp, Input, InputMode};

View file

@ -1,7 +1,6 @@
use std::ops::RangeBounds; use std::ops::RangeBounds;
use yazi_config::keymap::Exec; use yazi_shared::{event::Exec, CharKind};
use yazi_shared::CharKind;
use crate::input::Input; use crate::input::Input;

View file

@ -10,6 +10,7 @@ mod kill;
mod move_; mod move_;
mod paste; mod paste;
mod redo; mod redo;
mod show;
mod type_; mod type_;
mod undo; mod undo;
mod visual; mod visual;

View file

@ -1,5 +1,5 @@
use unicode_width::UnicodeWidthStr; use unicode_width::UnicodeWidthStr;
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::input::{op::InputOp, snap::InputSnap, Input}; use crate::input::{op::InputOp, snap::InputSnap, Input};

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::{external, input::{op::InputOp, Input}}; use crate::{external, input::{op::InputOp, Input}};

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::input::Input; use crate::input::Input;

View file

@ -0,0 +1,50 @@
use anyhow::anyhow;
use tokio::sync::mpsc;
use yazi_config::popup::InputCfg;
use yazi_shared::{emit, event::Exec, InputError, Layer};
use crate::input::Input;
pub struct Opt {
cfg: InputCfg,
tx: mpsc::UnboundedSender<Result<String, InputError>>,
}
impl TryFrom<&Exec> for Opt {
type Error = anyhow::Error;
fn try_from(e: &Exec) -> Result<Self, Self::Error> {
e.take_data().ok_or_else(|| anyhow!("invalid data"))
}
}
impl Input {
pub fn _show(cfg: InputCfg) -> mpsc::UnboundedReceiver<Result<String, InputError>> {
let (tx, rx) = mpsc::unbounded_channel();
emit!(Call(Exec::call("show", vec![]).with_data(Opt { cfg, tx }).vec(), Layer::Input));
rx
}
pub fn show(&mut self, opt: impl TryInto<Opt>) -> bool {
let Ok(opt) = opt.try_into() else {
return false;
};
self.close(false);
self.visible = true;
self.title = opt.cfg.title;
self.position = opt.cfg.position;
// Typing
self.callback = Some(opt.tx);
self.realtime = opt.cfg.realtime;
self.completion = opt.cfg.completion;
// Shell
self.highlight = opt.cfg.highlight;
// Reset snaps
self.snaps.reset(opt.cfg.value, self.limit());
true
}
}

View file

@ -1,4 +1,5 @@
use yazi_config::keymap::{Exec, Key}; use yazi_config::keymap::Key;
use yazi_shared::event::Exec;
use crate::input::{Input, InputMode}; use crate::input::{Input, InputMode};

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::input::{Input, InputMode}; use crate::input::{Input, InputMode};

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::input::{op::InputOp, Input, InputMode}; use crate::input::{op::InputOp, Input, InputMode};

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::input::{op::InputOp, Input}; use crate::input::{op::InputOp, Input};

View file

@ -2,7 +2,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::{InputOpt, Position}, INPUT}; use yazi_config::{popup::Position, INPUT};
use yazi_shared::InputError; use yazi_shared::InputError;
use super::{mode::InputMode, op::InputOp, InputSnap, InputSnaps}; use super::{mode::InputMode, op::InputOp, InputSnap, InputSnaps};
@ -19,7 +19,7 @@ pub struct Input {
// Typing // Typing
pub(super) callback: Option<UnboundedSender<Result<String, InputError>>>, pub(super) callback: Option<UnboundedSender<Result<String, InputError>>>,
realtime: bool, pub(super) realtime: bool,
pub(super) completion: bool, pub(super) completion: bool,
// Shell // Shell
@ -27,24 +27,6 @@ pub struct Input {
} }
impl Input { impl Input {
pub fn show(&mut self, opt: InputOpt, tx: UnboundedSender<Result<String, InputError>>) {
self.close(false);
self.visible = true;
self.title = opt.title;
self.position = opt.position;
// Typing
self.callback = Some(tx);
self.realtime = opt.realtime;
self.completion = opt.completion;
// Shell
self.highlight = opt.highlight;
// Reset snaps
self.snaps.reset(opt.value, self.limit());
}
#[inline] #[inline]
pub(super) fn limit(&self) -> usize { pub(super) fn limit(&self) -> usize {
self.position.offset.width.saturating_sub(INPUT.border()) as usize self.position.offset.width.saturating_sub(INPUT.border()) as usize

View file

@ -9,7 +9,6 @@
mod blocker; mod blocker;
pub mod completion; pub mod completion;
mod context; mod context;
mod event;
pub mod external; pub mod external;
pub mod files; pub mod files;
pub mod help; pub mod help;
@ -25,7 +24,6 @@ pub mod which;
pub use blocker::*; pub use blocker::*;
pub use context::*; pub use context::*;
pub use event::*;
pub use highlighter::*; pub use highlighter::*;
pub use step::*; pub use step::*;

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::{manager::Manager, tasks::Tasks}; use crate::{manager::Manager, tasks::Tasks};

View file

@ -1,10 +1,10 @@
use std::path::{PathBuf, MAIN_SEPARATOR}; use std::path::{PathBuf, MAIN_SEPARATOR};
use tokio::fs; use tokio::fs;
use yazi_config::{keymap::Exec, popup::InputOpt}; use yazi_config::popup::InputCfg;
use yazi_shared::Url; use yazi_shared::{emit, event::Exec, files::{File, FilesOp}, fs::Url};
use crate::{emit, files::{File, FilesOp}, manager::Manager}; use crate::{input::Input, manager::Manager};
pub struct Opt { pub struct Opt {
force: bool, force: bool,
@ -19,14 +19,14 @@ impl Manager {
let opt = opt.into() as Opt; let opt = opt.into() as Opt;
let cwd = self.cwd().to_owned(); let cwd = self.cwd().to_owned();
tokio::spawn(async move { tokio::spawn(async move {
let mut result = emit!(Input(InputOpt::create())); let mut result = Input::_show(InputCfg::create());
let Some(Ok(name)) = result.recv().await else { let Some(Ok(name)) = result.recv().await else {
return Ok(()); return Ok(());
}; };
let path = cwd.join(&name); let path = cwd.join(&name);
if !opt.force && fs::symlink_metadata(&path).await.is_ok() { if !opt.force && fs::symlink_metadata(&path).await.is_ok() {
match emit!(Input(InputOpt::overwrite())).recv().await { match Input::_show(InputCfg::overwrite()).recv().await {
Some(Ok(c)) if c == "y" || c == "Y" => (), Some(Ok(c)) if c == "y" || c == "Y" => (),
_ => return Ok(()), _ => return Ok(()),
} }

View file

@ -1,9 +1,8 @@
use std::collections::BTreeSet; use std::collections::BTreeSet;
use yazi_config::keymap::{Exec, KeymapLayer}; use yazi_shared::{emit, event::Exec, fs::Url, Layer};
use yazi_shared::Url;
use crate::{emit, manager::Manager}; use crate::manager::Manager;
pub struct Opt { pub struct Opt {
url: Option<Url>, url: Option<Url>,
@ -18,7 +17,7 @@ impl Manager {
pub fn _hover(url: Option<Url>) { pub fn _hover(url: Option<Url>) {
emit!(Call( emit!(Call(
Exec::call("hover", url.map_or_else(Vec::new, |u| vec![u.to_string()])).vec(), Exec::call("hover", url.map_or_else(Vec::new, |u| vec![u.to_string()])).vec(),
KeymapLayer::Manager Layer::Manager
)); ));
} }

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::{manager::Manager, tasks::Tasks}; use crate::{manager::Manager, tasks::Tasks};

View file

@ -1,9 +1,9 @@
use std::ffi::OsString; use std::ffi::OsString;
use yazi_config::{keymap::Exec, popup::SelectOpt, OPEN}; use yazi_config::{popup::SelectCfg, OPEN};
use yazi_shared::MIME_DIR; use yazi_shared::{event::Exec, MIME_DIR};
use crate::{emit, external, manager::Manager}; use crate::{external, manager::Manager, select::Select, tasks::Tasks};
pub struct Opt { pub struct Opt {
interactive: bool, interactive: bool,
@ -20,9 +20,9 @@ impl Manager {
return; return;
} }
let result = emit!(Select(SelectOpt::open(openers.iter().map(|o| o.desc.clone()).collect()))); let result = Select::_show(SelectCfg::open(openers.iter().map(|o| o.desc.clone()).collect()));
if let Ok(choice) = result.await { if let Ok(choice) = result.await {
emit!(Open(files, Some(openers[choice].clone()))); Tasks::_open(files, Some(openers[choice].clone()));
} }
} }
@ -63,7 +63,7 @@ impl Manager {
return; return;
} }
emit!(Open(files, None)); Tasks::_open(files, None);
}); });
false false
} }

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::{manager::Manager, tasks::Tasks}; use crate::{manager::Manager, tasks::Tasks};

View file

@ -1,7 +1,7 @@
use yazi_config::{keymap::{Exec, KeymapLayer}, MANAGER}; use yazi_config::MANAGER;
use yazi_shared::{Url, MIME_DIR}; use yazi_shared::{emit, event::Exec, fs::Url, Layer, MIME_DIR};
use crate::{emit, manager::Manager}; use crate::manager::Manager;
#[derive(Debug)] #[derive(Debug)]
pub struct Opt { pub struct Opt {
@ -31,7 +31,7 @@ impl Manager {
.with("only-if", only_if.to_string()) .with("only-if", only_if.to_string())
.with_bool("upper-bound", true) .with_bool("upper-bound", true)
.vec(), .vec(),
KeymapLayer::Manager Layer::Manager
)); ));
} }

View file

@ -1,6 +1,7 @@
use yazi_config::{keymap::Exec, popup::InputOpt}; use yazi_config::popup::InputCfg;
use yazi_shared::{emit, event::Exec};
use crate::{emit, manager::Manager, tasks::Tasks}; use crate::{input::Input, manager::Manager, tasks::Tasks};
#[derive(Default)] #[derive(Default)]
pub struct Opt { pub struct Opt {
@ -24,7 +25,7 @@ impl Manager {
} }
tokio::spawn(async move { tokio::spawn(async move {
let mut result = emit!(Input(InputOpt::quit(tasks))); let mut result = Input::_show(InputCfg::quit(tasks));
if let Some(Ok(choice)) = result.recv().await { if let Some(Ok(choice)) = result.recv().await {
if choice == "y" || choice == "Y" { if choice == "y" || choice == "Y" {
emit!(Quit(opt.no_cwd_file)); emit!(Quit(opt.no_cwd_file));

View file

@ -1,8 +1,8 @@
use std::env; use std::env;
use yazi_config::keymap::{Exec, KeymapLayer}; use yazi_shared::{emit, event::Exec, Layer};
use crate::{emit, manager::Manager}; use crate::manager::Manager;
pub struct Opt; pub struct Opt;
@ -13,7 +13,7 @@ impl From<&Exec> for Opt {
impl Manager { impl Manager {
#[inline] #[inline]
pub fn _refresh() { pub fn _refresh() {
emit!(Call(Exec::call("refresh", vec![]).vec(), KeymapLayer::Manager)); emit!(Call(Exec::call("refresh", vec![]).vec(), Layer::Manager));
} }
pub fn refresh(&mut self, _: impl Into<Opt>) -> bool { pub fn refresh(&mut self, _: impl Into<Opt>) -> bool {

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::{manager::Manager, tasks::Tasks}; use crate::{manager::Manager, tasks::Tasks};

View file

@ -2,10 +2,10 @@ use std::{collections::BTreeMap, ffi::OsStr, io::{stdout, BufWriter, Write}, pat
use anyhow::{anyhow, bail, Result}; use anyhow::{anyhow, bail, Result};
use tokio::{fs::{self, OpenOptions}, io::{stdin, AsyncReadExt, AsyncWriteExt}}; use tokio::{fs::{self, OpenOptions}, io::{stdin, AsyncReadExt, AsyncWriteExt}};
use yazi_config::{keymap::Exec, popup::InputOpt, OPEN, PREVIEW}; use yazi_config::{popup::InputCfg, OPEN, PREVIEW};
use yazi_shared::{max_common_root, Defer, Term, Url}; use yazi_shared::{emit, event::Exec, files::{File, FilesOp}, fs::{max_common_root, Url}, term::Term, Defer};
use crate::{emit, external::{self, ShellOpt}, files::{File, FilesOp}, manager::Manager, Event, BLOCKER}; use crate::{external::{self, ShellOpt}, input::Input, manager::Manager, Ctx, BLOCKER};
pub struct Opt { pub struct Opt {
force: bool, force: bool,
@ -39,7 +39,7 @@ impl Manager {
let opt = opt.into() as Opt; let opt = opt.into() as Opt;
tokio::spawn(async move { tokio::spawn(async move {
let mut result = let mut result =
emit!(Input(InputOpt::rename().with_value(hovered.file_name().unwrap().to_string_lossy()))); Input::_show(InputCfg::rename().with_value(hovered.file_name().unwrap().to_string_lossy()));
let Some(Ok(name)) = result.recv().await else { let Some(Ok(name)) = result.recv().await else {
return; return;
@ -51,7 +51,7 @@ impl Manager {
return; return;
} }
let mut result = emit!(Input(InputOpt::overwrite())); let mut result = Input::_show(InputCfg::overwrite());
if let Some(Ok(choice)) = result.recv().await { if let Some(Ok(choice)) = result.recv().await {
if choice == "y" || choice == "Y" { if choice == "y" || choice == "Y" {
Self::rename_and_hover(hovered, Url::from(new)).await.ok(); Self::rename_and_hover(hovered, Url::from(new)).await.ok();
@ -86,10 +86,10 @@ impl Manager {
let _guard = BLOCKER.acquire().await.unwrap(); let _guard = BLOCKER.acquire().await.unwrap();
let _defer = Defer::new(|| { let _defer = Defer::new(|| {
Event::Stop(false, None).emit(); Ctx::resume();
tokio::spawn(fs::remove_file(tmp.clone())) tokio::spawn(fs::remove_file(tmp.clone()))
}); });
emit!(Stop(true)).await; Ctx::stop().await;
let mut child = external::shell(ShellOpt { let mut child = external::shell(ShellOpt {
cmd: (*opener.exec).into(), cmd: (*opener.exec).into(),

View file

@ -1,6 +1,6 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::manager::Manager; use crate::{manager::Manager, Ctx};
pub struct Opt; pub struct Opt;
impl From<&Exec> for Opt { impl From<&Exec> for Opt {
@ -11,7 +11,7 @@ impl Manager {
pub fn suspend(&mut self, _: impl Into<Opt>) -> bool { pub fn suspend(&mut self, _: impl Into<Opt>) -> bool {
#[cfg(unix)] #[cfg(unix)]
tokio::spawn(async move { tokio::spawn(async move {
crate::emit!(Stop(true)).await; Ctx::stop().await;
unsafe { libc::raise(libc::SIGTSTP) }; unsafe { libc::raise(libc::SIGTSTP) };
}); });
false false

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::manager::Tabs; use crate::manager::Tabs;

View file

@ -1,5 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::{event::Exec, fs::Url};
use yazi_shared::Url;
use crate::{manager::Tabs, tab::Tab}; use crate::{manager::Tabs, tab::Tab};

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::manager::Tabs; use crate::manager::Tabs;

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::manager::Tabs; use crate::manager::Tabs;

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::manager::Manager; use crate::manager::Manager;

View file

@ -1,9 +1,9 @@
use std::collections::{BTreeMap, HashMap, HashSet}; use std::collections::{BTreeMap, HashMap, HashSet};
use yazi_shared::Url; use yazi_shared::{files::{File, FilesOp}, fs::Url};
use super::{Tabs, Watcher}; use super::{Tabs, Watcher};
use crate::{files::{File, FilesOp}, tab::{Folder, Tab}, tasks::Tasks}; use crate::{tab::{Folder, Tab}, tasks::Tasks};
pub struct Manager { pub struct Manager {
pub tabs: Tabs, pub tabs: Tabs,

View file

@ -1,5 +1,5 @@
use yazi_config::BOOT; use yazi_config::BOOT;
use yazi_shared::Url; use yazi_shared::fs::Url;
use crate::{manager::Manager, tab::Tab}; use crate::{manager::Manager, tab::Tab};

View file

@ -5,9 +5,9 @@ use notify::{event::{MetadataKind, ModifyKind}, EventKind, RecommendedWatcher, R
use parking_lot::RwLock; use parking_lot::RwLock;
use tokio::{fs, pin, sync::mpsc::{self, UnboundedReceiver}}; use tokio::{fs, pin, sync::mpsc::{self, UnboundedReceiver}};
use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt}; use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};
use yazi_shared::Url; use yazi_shared::{emit, files::{File, FilesOp}, fs::Url};
use crate::{emit, external, files::{File, Files, FilesOp}}; use crate::{external, files::Files};
pub struct Watcher { pub struct Watcher {
watcher: RecommendedWatcher, watcher: RecommendedWatcher,

View file

@ -4,10 +4,10 @@ use tokio::{pin, task::JoinHandle};
use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt}; use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};
use yazi_adaptor::ADAPTOR; use yazi_adaptor::ADAPTOR;
use yazi_config::MANAGER; use yazi_config::MANAGER;
use yazi_shared::{Cha, MimeKind, PeekError, Url}; use yazi_shared::{emit, event::{PreviewData, PreviewLock}, files::FilesOp, fs::{Cha, Url}, MimeKind, PeekError};
use super::Provider; use super::Provider;
use crate::{emit, files::{Files, FilesOp}, manager::Manager, Highlighter}; use crate::{files::Files, manager::Manager, Highlighter};
#[derive(Default)] #[derive(Default)]
pub struct Preview { pub struct Preview {
@ -17,20 +17,6 @@ pub struct Preview {
handle: Option<JoinHandle<()>>, handle: Option<JoinHandle<()>>,
} }
pub struct PreviewLock {
pub url: Url,
pub cha: Option<Cha>,
pub skip: usize,
pub data: PreviewData,
}
#[derive(Debug)]
pub enum PreviewData {
Folder,
Text(String),
Image,
}
impl Preview { impl Preview {
pub fn go(&mut self, url: &Url, cha: Cha, mime: &str) { pub fn go(&mut self, url: &Url, cha: Cha, mime: &str) {
if self.content_unchanged(url, &cha) { if self.content_unchanged(url, &cha) {
@ -152,11 +138,3 @@ impl Preview {
} }
} }
} }
impl PreviewLock {
#[inline]
pub fn is_image(&self) -> bool { matches!(self.data, PreviewData::Image) }
#[inline]
pub fn is_folder(&self) -> bool { matches!(self.data, PreviewData::Folder) }
}

View file

@ -3,9 +3,8 @@ use std::path::Path;
use tokio::fs; use tokio::fs;
use yazi_adaptor::ADAPTOR; use yazi_adaptor::ADAPTOR;
use yazi_config::{MANAGER, PREVIEW}; use yazi_config::{MANAGER, PREVIEW};
use yazi_shared::{MimeKind, PeekError}; use yazi_shared::{event::PreviewData, MimeKind, PeekError};
use super::PreviewData;
use crate::{external, Highlighter}; use crate::{external, Highlighter};
pub(super) struct Provider; pub(super) struct Provider;

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::select::Select; use crate::select::Select;

View file

@ -1,5 +1,5 @@
use anyhow::anyhow; use anyhow::anyhow;
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::select::Select; use crate::select::Select;

View file

@ -1,2 +1,3 @@
mod arrow; mod arrow;
mod close; mod close;
mod show;

View file

@ -0,0 +1,42 @@
use anyhow::{anyhow, Result};
use tokio::sync::oneshot;
use yazi_config::popup::SelectCfg;
use yazi_shared::{emit, event::Exec, term::Term, Layer};
use crate::select::Select;
pub struct Opt {
cfg: SelectCfg,
tx: oneshot::Sender<Result<usize>>,
}
impl TryFrom<&Exec> for Opt {
type Error = anyhow::Error;
fn try_from(e: &Exec) -> Result<Self, Self::Error> {
e.take_data().ok_or_else(|| anyhow!("invalid data"))
}
}
impl Select {
pub async fn _show(cfg: SelectCfg) -> Result<usize> {
let (tx, rx) = oneshot::channel();
emit!(Call(Exec::call("show", vec![]).with_data(Opt { cfg, tx }).vec(), Layer::Select));
rx.await.unwrap_or_else(|_| Term::goodbye(|| false))
}
pub fn show(&mut self, opt: impl TryInto<Opt>) -> bool {
let Ok(opt) = opt.try_into() else {
return false;
};
self.close(false);
self.title = opt.cfg.title;
self.items = opt.cfg.items;
self.position = opt.cfg.position;
self.callback = Some(opt.tx);
self.visible = true;
true
}
}

View file

@ -1,10 +1,10 @@
use anyhow::Result; use anyhow::Result;
use tokio::sync::oneshot::Sender; use tokio::sync::oneshot::Sender;
use yazi_config::{popup::{Position, SelectOpt}, SELECT}; use yazi_config::{popup::Position, SELECT};
#[derive(Default)] #[derive(Default)]
pub struct Select { pub struct Select {
title: String, pub(super) title: String,
pub(super) items: Vec<String>, pub(super) items: Vec<String>,
pub position: Position, pub position: Position,
@ -16,17 +16,6 @@ pub struct Select {
} }
impl Select { impl Select {
pub fn show(&mut self, opt: SelectOpt, tx: Sender<Result<usize>>) {
self.close(false);
self.title = opt.title;
self.items = opt.items;
self.position = opt.position;
self.callback = Some(tx);
self.visible = true;
}
#[inline] #[inline]
pub fn window(&self) -> &[String] { pub fn window(&self) -> &[String] {
let end = (self.offset + self.limit()).min(self.items.len()); let end = (self.offset + self.limit()).min(self.items.len());

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::{manager::Manager, tab::Tab, Step}; use crate::{manager::Manager, tab::Tab, Step};

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::tab::Tab; use crate::tab::Tab;

View file

@ -2,10 +2,10 @@ use std::{mem, time::Duration};
use tokio::{fs, pin}; use tokio::{fs, pin};
use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt}; use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};
use yazi_config::{keymap::{Exec, KeymapLayer}, popup::InputOpt}; use yazi_config::popup::InputCfg;
use yazi_shared::{expand_path, Debounce, InputError, Url}; use yazi_shared::{emit, event::Exec, fs::{expand_path, Url}, Debounce, InputError, Layer};
use crate::{completion::Completion, emit, manager::Manager, tab::Tab}; use crate::{completion::Completion, input::Input, manager::Manager, tab::Tab};
pub struct Opt { pub struct Opt {
target: Url, target: Url,
@ -29,7 +29,7 @@ impl From<Url> for Opt {
impl Tab { impl Tab {
#[inline] #[inline]
pub fn _cd(target: &Url) { pub fn _cd(target: &Url) {
emit!(Call(Exec::call("cd", vec![target.to_string()]).vec(), KeymapLayer::Manager)); emit!(Call(Exec::call("cd", vec![target.to_string()]).vec(), Layer::Manager));
} }
pub fn cd(&mut self, opt: impl Into<Opt>) -> bool { pub fn cd(&mut self, opt: impl Into<Opt>) -> bool {
@ -72,7 +72,7 @@ impl Tab {
let opt = opt.into() as Opt; let opt = opt.into() as Opt;
tokio::spawn(async move { tokio::spawn(async move {
let rx = emit!(Input(InputOpt::cd().with_value(opt.target.to_string_lossy()))); let rx = Input::_show(InputCfg::cd().with_value(opt.target.to_string_lossy()));
let rx = Debounce::new(UnboundedReceiverStream::new(rx), Duration::from_millis(50)); let rx = Debounce::new(UnboundedReceiverStream::new(rx), Duration::from_millis(50));
pin!(rx); pin!(rx);

View file

@ -1,6 +1,6 @@
use std::ffi::{OsStr, OsString}; use std::ffi::{OsStr, OsString};
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::{external, tab::Tab}; use crate::{external, tab::Tab};

View file

@ -1,6 +1,6 @@
use std::mem; use std::mem;
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::{manager::Manager, tab::Tab}; use crate::{manager::Manager, tab::Tab};

View file

@ -1,5 +1,5 @@
use bitflags::bitflags; use bitflags::bitflags;
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::tab::{Mode, Tab}; use crate::tab::{Mode, Tab};

View file

@ -2,10 +2,10 @@ use std::time::Duration;
use tokio::pin; use tokio::pin;
use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt}; use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};
use yazi_config::{keymap::{Exec, KeymapLayer}, popup::InputOpt}; use yazi_config::popup::InputCfg;
use yazi_shared::{Debounce, InputError}; use yazi_shared::{emit, event::Exec, Debounce, InputError, Layer};
use crate::{emit, tab::{Finder, FinderCase, Tab}}; use crate::{input::Input, tab::{Finder, FinderCase, Tab}};
pub struct Opt<'a> { pub struct Opt<'a> {
query: Option<&'a str>, query: Option<&'a str>,
@ -39,7 +39,7 @@ impl Tab {
pub fn find<'a>(&mut self, opt: impl Into<Opt<'a>>) -> bool { pub fn find<'a>(&mut self, opt: impl Into<Opt<'a>>) -> bool {
let opt = opt.into() as Opt; let opt = opt.into() as Opt;
tokio::spawn(async move { tokio::spawn(async move {
let rx = emit!(Input(InputOpt::find(opt.prev))); let rx = Input::_show(InputCfg::find(opt.prev));
let rx = Debounce::new(UnboundedReceiverStream::new(rx), Duration::from_millis(50)); let rx = Debounce::new(UnboundedReceiverStream::new(rx), Duration::from_millis(50));
pin!(rx); pin!(rx);
@ -51,7 +51,7 @@ impl Tab {
.with_bool("smart", opt.case == FinderCase::Smart) .with_bool("smart", opt.case == FinderCase::Smart)
.with_bool("insensitive", opt.case == FinderCase::Insensitive) .with_bool("insensitive", opt.case == FinderCase::Insensitive)
.vec(), .vec(),
KeymapLayer::Manager Layer::Manager
)); ));
} }
}); });

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::{manager::Manager, tab::Tab}; use crate::{manager::Manager, tab::Tab};

View file

@ -1,7 +1,6 @@
use yazi_config::keymap::Exec; use yazi_shared::{event::Exec, fs::ends_with_slash, Defer};
use yazi_shared::{ends_with_slash, Defer};
use crate::{emit, external::{self, FzfOpt, ZoxideOpt}, tab::Tab, Event, BLOCKER}; use crate::{external::{self, FzfOpt, ZoxideOpt}, tab::Tab, Ctx, BLOCKER};
pub struct Opt { pub struct Opt {
type_: OptType, type_: OptType,
@ -36,8 +35,8 @@ impl Tab {
let cwd = self.current.cwd.clone(); let cwd = self.current.cwd.clone();
tokio::spawn(async move { tokio::spawn(async move {
let _guard = BLOCKER.acquire().await.unwrap(); let _guard = BLOCKER.acquire().await.unwrap();
let _defer = Defer::new(|| Event::Stop(false, None).emit()); let _defer = Defer::new(Ctx::resume);
emit!(Stop(true)).await; Ctx::stop().await;
let result = if opt.type_ == OptType::Fzf { let result = if opt.type_ == OptType::Fzf {
external::fzf(FzfOpt { cwd }).await external::fzf(FzfOpt { cwd }).await

View file

@ -1,6 +1,6 @@
use std::mem; use std::mem;
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::{manager::Manager, tab::Tab}; use crate::{manager::Manager, tab::Tab};

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::tab::Tab; use crate::tab::Tab;

View file

@ -1,7 +1,6 @@
use yazi_config::keymap::{Exec, KeymapLayer}; use yazi_shared::{emit, event::Exec, files::{File, FilesOp}, fs::{expand_path, Url}, Layer};
use yazi_shared::{expand_path, Url};
use crate::{emit, files::{File, FilesOp}, manager::Manager, tab::Tab}; use crate::{manager::Manager, tab::Tab};
pub struct Opt { pub struct Opt {
target: Url, target: Url,
@ -24,7 +23,7 @@ impl From<Url> for Opt {
impl Tab { impl Tab {
#[inline] #[inline]
pub fn _reveal(target: &Url) { pub fn _reveal(target: &Url) {
emit!(Call(Exec::call("reveal", vec![target.to_string()]).vec(), KeymapLayer::Manager)); emit!(Call(Exec::call("reveal", vec![target.to_string()]).vec(), Layer::Manager));
} }
pub fn reveal(&mut self, opt: impl Into<Opt>) -> bool { pub fn reveal(&mut self, opt: impl Into<Opt>) -> bool {

View file

@ -3,9 +3,10 @@ use std::{mem, time::Duration};
use anyhow::bail; use anyhow::bail;
use tokio::pin; use tokio::pin;
use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt}; use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};
use yazi_config::{keymap::Exec, popup::InputOpt}; use yazi_config::popup::InputCfg;
use yazi_shared::{emit, event::Exec, files::FilesOp};
use crate::{emit, external, files::FilesOp, manager::Manager, tab::Tab}; use crate::{external, input::Input, manager::Manager, tab::Tab};
pub struct Opt { pub struct Opt {
pub type_: OptType, pub type_: OptType,
@ -45,7 +46,7 @@ impl Tab {
let hidden = self.conf.show_hidden; let hidden = self.conf.show_hidden;
self.search = Some(tokio::spawn(async move { self.search = Some(tokio::spawn(async move {
let Some(Ok(subject)) = emit!(Input(InputOpt::search())).recv().await else { bail!("") }; let Some(Ok(subject)) = Input::_show(InputCfg::search()).recv().await else { bail!("") };
cwd = cwd.into_search(subject.clone()); cwd = cwd.into_search(subject.clone());
let rx = if opt.type_ == OptType::Rg { let rx = if opt.type_ == OptType::Rg {

View file

@ -1,4 +1,4 @@
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::tab::Tab; use crate::tab::Tab;

View file

@ -1,6 +1,7 @@
use yazi_config::{keymap::Exec, open::Opener, popup::InputOpt}; use yazi_config::{open::Opener, popup::InputCfg};
use yazi_shared::event::Exec;
use crate::{emit, tab::Tab}; use crate::{input::Input, tab::Tab, tasks::Tasks};
pub struct Opt { pub struct Opt {
cmd: String, cmd: String,
@ -29,14 +30,14 @@ impl Tab {
let mut opt = opt.into() as Opt; let mut opt = opt.into() as Opt;
tokio::spawn(async move { tokio::spawn(async move {
if !opt.confirm || opt.cmd.is_empty() { if !opt.confirm || opt.cmd.is_empty() {
let mut result = emit!(Input(InputOpt::shell(opt.block).with_value(opt.cmd))); let mut result = Input::_show(InputCfg::shell(opt.block).with_value(opt.cmd));
match result.recv().await { match result.recv().await {
Some(Ok(e)) => opt.cmd = e, Some(Ok(e)) => opt.cmd = e,
_ => return, _ => return,
} }
} }
emit!(Open( Tasks::_open(
selected, selected,
Some(Opener { Some(Opener {
exec: opt.cmd, exec: opt.cmd,
@ -45,8 +46,8 @@ impl Tab {
desc: Default::default(), desc: Default::default(),
for_: None, for_: None,
spread: true, spread: true,
}) }),
)); );
}); });
false false

View file

@ -1,6 +1,7 @@
use std::str::FromStr; use std::str::FromStr;
use yazi_config::{keymap::Exec, manager::SortBy}; use yazi_config::manager::SortBy;
use yazi_shared::event::Exec;
use crate::tab::Tab; use crate::tab::Tab;

View file

@ -1,6 +1,6 @@
use std::collections::BTreeSet; use std::collections::BTreeSet;
use yazi_config::keymap::Exec; use yazi_shared::event::Exec;
use crate::tab::{Mode, Tab}; use crate::tab::{Mode, Tab};

View file

@ -2,7 +2,7 @@ use std::{collections::BTreeMap, ffi::OsStr, ops::Range};
use anyhow::Result; use anyhow::Result;
use regex::bytes::{Regex, RegexBuilder}; use regex::bytes::{Regex, RegexBuilder};
use yazi_shared::Url; use yazi_shared::fs::Url;
use crate::files::Files; use crate::files::Files;

Some files were not shown because too many files have changed in this diff Show more