mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
feat: ya.input() plugin API (#762)
This commit is contained in:
parent
b39b506e27
commit
bd572706cd
60 changed files with 550 additions and 286 deletions
14
Cargo.lock
generated
14
Cargo.lock
generated
|
|
@ -2740,6 +2740,7 @@ dependencies = [
|
|||
"yazi-boot",
|
||||
"yazi-config",
|
||||
"yazi-plugin",
|
||||
"yazi-proxy",
|
||||
"yazi-scheduler",
|
||||
"yazi-shared",
|
||||
]
|
||||
|
|
@ -2770,6 +2771,7 @@ dependencies = [
|
|||
"yazi-config",
|
||||
"yazi-core",
|
||||
"yazi-plugin",
|
||||
"yazi-proxy",
|
||||
"yazi-scheduler",
|
||||
"yazi-shared",
|
||||
]
|
||||
|
|
@ -2801,6 +2803,7 @@ dependencies = [
|
|||
"yazi-boot",
|
||||
"yazi-config",
|
||||
"yazi-prebuild",
|
||||
"yazi-proxy",
|
||||
"yazi-shared",
|
||||
]
|
||||
|
||||
|
|
@ -2810,6 +2813,16 @@ version = "0.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4b6c8e12e39ac0f79fa96f36e5b88e0da8d230691abd729eec709b43c74f632"
|
||||
|
||||
[[package]]
|
||||
name = "yazi-proxy"
|
||||
version = "0.2.3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"tokio",
|
||||
"yazi-config",
|
||||
"yazi-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yazi-scheduler"
|
||||
version = "0.2.3"
|
||||
|
|
@ -2828,6 +2841,7 @@ dependencies = [
|
|||
"yazi-adaptor",
|
||||
"yazi-config",
|
||||
"yazi-plugin",
|
||||
"yazi-proxy",
|
||||
"yazi-shared",
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,63 @@
|
|||
use std::{fmt::Display, str::FromStr};
|
||||
|
||||
use anyhow::bail;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Clone, Copy, Default, Deserialize, PartialEq, Eq)]
|
||||
#[serde(try_from = "String")]
|
||||
pub enum Origin {
|
||||
#[default]
|
||||
#[serde(rename = "top-left")]
|
||||
TopLeft,
|
||||
#[serde(rename = "top-center")]
|
||||
TopCenter,
|
||||
#[serde(rename = "top-right")]
|
||||
TopRight,
|
||||
|
||||
#[serde(rename = "bottom-left")]
|
||||
BottomLeft,
|
||||
#[serde(rename = "bottom-center")]
|
||||
BottomCenter,
|
||||
#[serde(rename = "bottom-right")]
|
||||
BottomRight,
|
||||
|
||||
#[serde(rename = "center")]
|
||||
Center,
|
||||
#[serde(rename = "hovered")]
|
||||
Hovered,
|
||||
}
|
||||
|
||||
impl FromStr for Origin {
|
||||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(match s {
|
||||
"top-left" => Self::TopLeft,
|
||||
"top-center" => Self::TopCenter,
|
||||
"top-right" => Self::TopRight,
|
||||
|
||||
"bottom-left" => Self::BottomLeft,
|
||||
"bottom-center" => Self::BottomCenter,
|
||||
"bottom-right" => Self::BottomRight,
|
||||
|
||||
"center" => Self::Center,
|
||||
"hovered" => Self::Hovered,
|
||||
_ => bail!("Invalid `origin` value: {s}"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<String> for Origin {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(value: String) -> Result<Self, Self::Error> { Self::from_str(&value) }
|
||||
}
|
||||
|
||||
impl Display for Origin {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(match self {
|
||||
Self::TopLeft => "top-left",
|
||||
Self::TopCenter => "top-center",
|
||||
Self::TopRight => "top-right",
|
||||
|
||||
Self::BottomLeft => "bottom-left",
|
||||
Self::BottomCenter => "bottom-center",
|
||||
Self::BottomRight => "bottom-right",
|
||||
|
||||
Self::Center => "center",
|
||||
Self::Hovered => "hovered",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ impl FromStr for SortBy {
|
|||
"none" => Self::None,
|
||||
"key" => Self::Key,
|
||||
"desc" => Self::Desc,
|
||||
_ => bail!("Invalid sort option: {s}"),
|
||||
_ => bail!("Invalid `sort_by` value: {s}"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ yazi-adaptor = { path = "../yazi-adaptor", version = "0.2.3" }
|
|||
yazi-boot = { path = "../yazi-boot", version = "0.2.3" }
|
||||
yazi-config = { path = "../yazi-config", version = "0.2.3" }
|
||||
yazi-plugin = { path = "../yazi-plugin", version = "0.2.3" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "0.2.3" }
|
||||
yazi-scheduler = { path = "../yazi-scheduler", version = "0.2.3" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "0.2.3" }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use yazi_shared::{emit, event::Cmd, render, Layer};
|
||||
use yazi_proxy::InputProxy;
|
||||
use yazi_shared::{event::Cmd, render};
|
||||
|
||||
use crate::{completion::Completion, input::Input};
|
||||
use crate::completion::Completion;
|
||||
|
||||
pub struct Opt {
|
||||
submit: bool,
|
||||
|
|
@ -11,16 +12,11 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Completion {
|
||||
#[inline]
|
||||
pub fn _close() {
|
||||
emit!(Call(Cmd::new("close"), Layer::Completion));
|
||||
}
|
||||
|
||||
pub fn close(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
|
||||
if let Some(s) = self.selected().filter(|_| opt.submit) {
|
||||
Input::_complete(s, self.ticket);
|
||||
InputProxy::complete(s, self.ticket);
|
||||
}
|
||||
|
||||
self.caches.clear();
|
||||
|
|
|
|||
|
|
@ -20,14 +20,6 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Completion {
|
||||
#[inline]
|
||||
pub fn _trigger(word: &str, ticket: usize) {
|
||||
emit!(Call(
|
||||
Cmd::args("trigger", vec![word.to_owned()]).with("ticket", ticket),
|
||||
Layer::Completion
|
||||
));
|
||||
}
|
||||
|
||||
pub fn trigger(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
if opt.ticket < self.ticket {
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@ use std::{mem, time::SystemTime};
|
|||
|
||||
use ratatui::layout::Rect;
|
||||
use yazi_config::{LAYOUT, MANAGER};
|
||||
use yazi_proxy::ManagerProxy;
|
||||
use yazi_shared::fs::{File, FilesOp, Url};
|
||||
|
||||
use super::FolderStage;
|
||||
use crate::{folder::Files, manager::Manager, Step};
|
||||
use crate::{folder::Files, Step};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Folder {
|
||||
|
|
@ -99,7 +100,7 @@ impl Folder {
|
|||
|
||||
let new = self.cursor / limit;
|
||||
if mem::replace(&mut self.page, new) != new || force {
|
||||
Manager::_update_paged_by(new, &self.cwd);
|
||||
ManagerProxy::update_paged_by(new, &self.cwd);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use yazi_proxy::CompletionProxy;
|
||||
use yazi_shared::{event::Cmd, render, InputError};
|
||||
|
||||
use crate::{completion::Completion, input::Input};
|
||||
use crate::input::Input;
|
||||
|
||||
pub struct Opt {
|
||||
submit: bool,
|
||||
|
|
@ -18,7 +19,7 @@ impl Input {
|
|||
let opt = opt.into() as Opt;
|
||||
|
||||
if self.completion {
|
||||
Completion::_close();
|
||||
CompletionProxy::close();
|
||||
}
|
||||
|
||||
if let Some(cb) = self.callback.take() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::path::MAIN_SEPARATOR;
|
||||
|
||||
use yazi_shared::{emit, event::Cmd, render, Layer};
|
||||
use yazi_shared::{event::Cmd, render};
|
||||
|
||||
use crate::input::Input;
|
||||
|
||||
|
|
@ -19,11 +19,6 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Input {
|
||||
#[inline]
|
||||
pub fn _complete(word: &str, ticket: usize) {
|
||||
emit!(Call(Cmd::args("complete", vec![word.to_owned()]).with("ticket", ticket), Layer::Input));
|
||||
}
|
||||
|
||||
pub fn complete(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
if self.ticket != opt.ticket {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use yazi_proxy::CompletionProxy;
|
||||
use yazi_shared::{event::Cmd, render};
|
||||
|
||||
use crate::{completion::Completion, input::{op::InputOp, Input, InputMode}};
|
||||
use crate::input::{op::InputOp, Input, InputMode};
|
||||
|
||||
pub struct Opt;
|
||||
|
||||
|
|
@ -26,7 +27,7 @@ impl Input {
|
|||
self.move_(-1);
|
||||
|
||||
if self.completion {
|
||||
Completion::_close();
|
||||
CompletionProxy::close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,10 @@
|
|||
use tokio::sync::mpsc;
|
||||
use yazi_config::popup::InputCfg;
|
||||
use yazi_shared::{emit, event::Cmd, render, InputError, Layer};
|
||||
use yazi_proxy::InputOpt;
|
||||
use yazi_shared::render;
|
||||
|
||||
use crate::input::Input;
|
||||
|
||||
pub struct Opt {
|
||||
cfg: InputCfg,
|
||||
tx: mpsc::UnboundedSender<Result<String, InputError>>,
|
||||
}
|
||||
|
||||
impl TryFrom<Cmd> for Opt {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(mut c: Cmd) -> Result<Self, Self::Error> { c.take_data().ok_or(()) }
|
||||
}
|
||||
|
||||
impl Input {
|
||||
pub fn _show(cfg: InputCfg) -> mpsc::UnboundedReceiver<Result<String, InputError>> {
|
||||
let (tx, rx) = mpsc::unbounded_channel();
|
||||
emit!(Call(Cmd::new("show").with_data(Opt { cfg, tx }), Layer::Input));
|
||||
rx
|
||||
}
|
||||
|
||||
pub fn show(&mut self, opt: impl TryInto<Opt>) {
|
||||
pub fn show(&mut self, opt: impl TryInto<InputOpt>) {
|
||||
let Ok(opt) = opt.try_into() else {
|
||||
return;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,9 +2,10 @@ use std::path::PathBuf;
|
|||
|
||||
use tokio::fs;
|
||||
use yazi_config::popup::InputCfg;
|
||||
use yazi_proxy::{InputProxy, ManagerProxy};
|
||||
use yazi_shared::{event::Cmd, fs::{File, FilesOp, Url}};
|
||||
|
||||
use crate::{input::Input, manager::Manager};
|
||||
use crate::manager::Manager;
|
||||
|
||||
pub struct Opt {
|
||||
force: bool,
|
||||
|
|
@ -19,14 +20,14 @@ impl Manager {
|
|||
let opt = opt.into() as Opt;
|
||||
let cwd = self.cwd().to_owned();
|
||||
tokio::spawn(async move {
|
||||
let mut result = Input::_show(InputCfg::create());
|
||||
let mut result = InputProxy::show(InputCfg::create());
|
||||
let Some(Ok(name)) = result.recv().await else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
let path = cwd.join(&name);
|
||||
if !opt.force && fs::symlink_metadata(&path).await.is_ok() {
|
||||
match Input::_show(InputCfg::overwrite()).recv().await {
|
||||
match InputProxy::show(InputCfg::overwrite()).recv().await {
|
||||
Some(Ok(c)) if c == "y" || c == "Y" => (),
|
||||
_ => return Ok(()),
|
||||
}
|
||||
|
|
@ -43,7 +44,7 @@ impl Manager {
|
|||
Url::from(path.components().take(cwd.components().count() + 1).collect::<PathBuf>());
|
||||
if let Ok(f) = File::from(child.clone()).await {
|
||||
FilesOp::Creating(cwd, vec![f]).emit();
|
||||
Manager::_hover(Some(child));
|
||||
ManagerProxy::hover(Some(child));
|
||||
}
|
||||
Ok::<(), anyhow::Error>(())
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::collections::BTreeSet;
|
||||
|
||||
use yazi_shared::{emit, event::Cmd, fs::Url, render, Layer};
|
||||
use yazi_shared::{event::Cmd, fs::Url, render};
|
||||
|
||||
use crate::manager::Manager;
|
||||
|
||||
|
|
@ -16,14 +16,6 @@ impl From<Option<Url>> for Opt {
|
|||
}
|
||||
|
||||
impl Manager {
|
||||
#[inline]
|
||||
pub fn _hover(url: Option<Url>) {
|
||||
emit!(Call(
|
||||
Cmd::args("hover", url.map_or_else(Vec::new, |u| vec![u.to_string()])),
|
||||
Layer::Manager
|
||||
));
|
||||
}
|
||||
|
||||
pub fn hover(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@ use tracing::error;
|
|||
use yazi_boot::ARGS;
|
||||
use yazi_config::{popup::SelectCfg, OPEN};
|
||||
use yazi_plugin::isolate;
|
||||
use yazi_shared::{emit, event::{Cmd, EventQuit}, fs::{File, Url}, Layer, MIME_DIR};
|
||||
use yazi_proxy::{ManagerProxy, OpenDoOpt, TasksProxy};
|
||||
use yazi_shared::{emit, event::{Cmd, EventQuit}, fs::{File, Url}, MIME_DIR};
|
||||
|
||||
use crate::{folder::Folder, manager::Manager, select::Select, tasks::Tasks};
|
||||
use crate::{folder::Folder, manager::Manager, tasks::Tasks};
|
||||
|
||||
pub struct Opt {
|
||||
interactive: bool,
|
||||
|
|
@ -22,17 +23,6 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct OptDo {
|
||||
hovered: Url,
|
||||
targets: Vec<(Url, String)>,
|
||||
interactive: bool,
|
||||
}
|
||||
|
||||
impl From<Cmd> for OptDo {
|
||||
fn from(mut c: Cmd) -> Self { c.take_data().unwrap_or_default() }
|
||||
}
|
||||
|
||||
impl Manager {
|
||||
pub fn open(&mut self, opt: impl Into<Opt>, tasks: &Tasks) {
|
||||
if !self.active_mut().try_escape_visual() {
|
||||
|
|
@ -50,7 +40,7 @@ impl Manager {
|
|||
|
||||
let (mut done, mut todo) = (Vec::with_capacity(selected.len()), vec![]);
|
||||
for u in selected {
|
||||
if self.mimetype.get(u).is_some() {
|
||||
if self.mimetype.contains_key(u) {
|
||||
done.push((u.clone(), String::new()));
|
||||
} else if self.guess_folder(u) {
|
||||
done.push((u.clone(), MIME_DIR.to_owned()));
|
||||
|
|
@ -60,7 +50,8 @@ impl Manager {
|
|||
}
|
||||
|
||||
if todo.is_empty() {
|
||||
return self.open_do(OptDo { hovered, targets: done, interactive: opt.interactive }, tasks);
|
||||
return self
|
||||
.open_do(OpenDoOpt { hovered, targets: done, interactive: opt.interactive }, tasks);
|
||||
}
|
||||
|
||||
tokio::spawn(async move {
|
||||
|
|
@ -76,17 +67,12 @@ impl Manager {
|
|||
error!("preload in open failed: {e}");
|
||||
}
|
||||
|
||||
Self::_open_do(OptDo { hovered, targets: done, interactive: opt.interactive });
|
||||
ManagerProxy::open_do(OpenDoOpt { hovered, targets: done, interactive: opt.interactive });
|
||||
});
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn _open_do(opt: OptDo) {
|
||||
emit!(Call(Cmd::new("open_do").with_data(opt), Layer::Manager));
|
||||
}
|
||||
|
||||
pub fn open_do(&mut self, opt: impl Into<OptDo>, tasks: &Tasks) {
|
||||
let opt = opt.into() as OptDo;
|
||||
pub fn open_do(&mut self, opt: impl Into<OpenDoOpt>, tasks: &Tasks) {
|
||||
let opt = opt.into() as OpenDoOpt;
|
||||
let targets: Vec<_> = opt
|
||||
.targets
|
||||
.into_iter()
|
||||
|
|
@ -108,9 +94,11 @@ impl Manager {
|
|||
|
||||
let urls = [opt.hovered].into_iter().chain(targets.into_iter().map(|(u, _)| u)).collect();
|
||||
tokio::spawn(async move {
|
||||
let result = Select::_show(SelectCfg::open(openers.iter().map(|o| o.desc.clone()).collect()));
|
||||
let result = yazi_proxy::SelectProxy::show(SelectCfg::open(
|
||||
openers.iter().map(|o| o.desc.clone()).collect(),
|
||||
));
|
||||
if let Ok(choice) = result.await {
|
||||
Tasks::_open_with(urls, openers[choice].clone());
|
||||
TasksProxy::open_with(urls, openers[choice].clone());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use yazi_shared::{emit, event::Cmd, fs::Url, render, Layer};
|
||||
use yazi_shared::{event::Cmd, fs::Url, render};
|
||||
|
||||
use crate::manager::Manager;
|
||||
|
||||
|
|
@ -25,11 +25,6 @@ impl From<bool> for Opt {
|
|||
}
|
||||
|
||||
impl Manager {
|
||||
#[inline]
|
||||
pub fn _peek(force: bool) {
|
||||
emit!(Call(Cmd::new("peek").with_bool("force", force), Layer::Manager));
|
||||
}
|
||||
|
||||
pub fn peek(&mut self, opt: impl Into<Opt>) {
|
||||
let Some(hovered) = self.hovered().cloned() else {
|
||||
return render!(self.active_mut().preview.reset());
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use yazi_config::popup::InputCfg;
|
||||
use yazi_proxy::InputProxy;
|
||||
use yazi_shared::{emit, event::{Cmd, EventQuit}};
|
||||
|
||||
use crate::{input::Input, manager::Manager, tasks::Tasks};
|
||||
use crate::{manager::Manager, tasks::Tasks};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Opt {
|
||||
|
|
@ -25,7 +26,7 @@ impl Manager {
|
|||
}
|
||||
|
||||
tokio::spawn(async move {
|
||||
let mut result = Input::_show(InputCfg::quit(tasks));
|
||||
let mut result = InputProxy::show(InputCfg::quit(tasks));
|
||||
if let Some(Ok(choice)) = result.recv().await {
|
||||
if choice == "y" || choice == "Y" {
|
||||
emit!(Quit(opt));
|
||||
|
|
|
|||
|
|
@ -1,15 +1,10 @@
|
|||
use std::env;
|
||||
|
||||
use yazi_shared::{emit, event::Cmd, Layer};
|
||||
use yazi_shared::event::Cmd;
|
||||
|
||||
use crate::{manager::Manager, tasks::Tasks};
|
||||
|
||||
impl Manager {
|
||||
#[inline]
|
||||
pub fn _refresh() {
|
||||
emit!(Call(Cmd::new("refresh"), Layer::Manager));
|
||||
}
|
||||
|
||||
pub fn refresh(&mut self, _: Cmd, tasks: &Tasks) {
|
||||
env::set_current_dir(self.cwd()).ok();
|
||||
env::set_var("PWD", self.cwd());
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use yazi_config::popup::InputCfg;
|
||||
use yazi_shared::{emit, event::Cmd, fs::Url, Layer};
|
||||
use yazi_proxy::{InputProxy, ManagerProxy};
|
||||
use yazi_shared::{event::Cmd, fs::Url};
|
||||
|
||||
use crate::{input::Input, manager::Manager, tasks::Tasks};
|
||||
use crate::{manager::Manager, tasks::Tasks};
|
||||
|
||||
pub struct Opt {
|
||||
force: bool,
|
||||
|
|
@ -33,7 +34,7 @@ impl Manager {
|
|||
}
|
||||
|
||||
tokio::spawn(async move {
|
||||
let mut result = Input::_show(if opt.permanently {
|
||||
let mut result = InputProxy::show(if opt.permanently {
|
||||
InputCfg::delete(opt.targets.len())
|
||||
} else {
|
||||
InputCfg::trash(opt.targets.len())
|
||||
|
|
@ -44,19 +45,11 @@ impl Manager {
|
|||
return;
|
||||
}
|
||||
|
||||
Self::_remove_do(opt.targets, opt.permanently);
|
||||
ManagerProxy::remove_do(opt.targets, opt.permanently);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn _remove_do(targets: Vec<Url>, permanently: bool) {
|
||||
emit!(Call(
|
||||
Cmd::new("remove_do").with_bool("permanently", permanently).with_data(targets),
|
||||
Layer::Manager
|
||||
));
|
||||
}
|
||||
|
||||
pub fn remove_do(&mut self, opt: impl Into<Opt>, tasks: &Tasks) {
|
||||
let opt = opt.into() as Opt;
|
||||
for u in &opt.targets {
|
||||
|
|
|
|||
|
|
@ -4,10 +4,11 @@ use anyhow::{anyhow, bail, Result};
|
|||
use tokio::{fs::{self, OpenOptions}, io::{stdin, AsyncReadExt, AsyncWriteExt}};
|
||||
use yazi_config::{popup::InputCfg, OPEN, PREVIEW};
|
||||
use yazi_plugin::external::{self, ShellOpt};
|
||||
use yazi_scheduler::{Scheduler, BLOCKER};
|
||||
use yazi_proxy::{AppProxy, InputProxy, ManagerProxy};
|
||||
use yazi_scheduler::BLOCKER;
|
||||
use yazi_shared::{event::Cmd, fs::{max_common_root, File, FilesOp, Url}, term::Term, Defer};
|
||||
|
||||
use crate::{input::Input, manager::Manager};
|
||||
use crate::manager::Manager;
|
||||
|
||||
pub struct Opt {
|
||||
force: bool,
|
||||
|
|
@ -49,7 +50,7 @@ impl Manager {
|
|||
let file = File::from(new.clone()).await?;
|
||||
FilesOp::Deleting(file.parent().unwrap(), vec![new.clone()]).emit();
|
||||
FilesOp::Upserting(file.parent().unwrap(), BTreeMap::from_iter([(old, file)])).emit();
|
||||
Ok(Self::_hover(Some(new)))
|
||||
Ok(ManagerProxy::hover(Some(new)))
|
||||
}
|
||||
|
||||
pub fn rename(&mut self, opt: impl Into<Opt>) {
|
||||
|
|
@ -77,7 +78,7 @@ impl Manager {
|
|||
};
|
||||
|
||||
tokio::spawn(async move {
|
||||
let mut result = Input::_show(InputCfg::rename().with_value(name).with_cursor(cursor));
|
||||
let mut result = InputProxy::show(InputCfg::rename().with_value(name).with_cursor(cursor));
|
||||
let Some(Ok(name)) = result.recv().await else {
|
||||
return;
|
||||
};
|
||||
|
|
@ -88,7 +89,7 @@ impl Manager {
|
|||
return;
|
||||
}
|
||||
|
||||
let mut result = Input::_show(InputCfg::overwrite());
|
||||
let mut result = InputProxy::show(InputCfg::overwrite());
|
||||
if let Some(Ok(choice)) = result.recv().await {
|
||||
if choice == "y" || choice == "Y" {
|
||||
Self::rename_and_hover(hovered, Url::from(new)).await.ok();
|
||||
|
|
@ -122,10 +123,10 @@ impl Manager {
|
|||
|
||||
let _guard = BLOCKER.acquire().await.unwrap();
|
||||
let _defer = Defer::new(|| {
|
||||
Scheduler::app_resume();
|
||||
AppProxy::resume();
|
||||
tokio::spawn(fs::remove_file(tmp.clone()))
|
||||
});
|
||||
Scheduler::app_stop().await;
|
||||
AppProxy::stop().await;
|
||||
|
||||
let mut child = external::shell(ShellOpt {
|
||||
cmd: (*opener.exec).into(),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use yazi_scheduler::Scheduler;
|
||||
use yazi_proxy::AppProxy;
|
||||
use yazi_shared::event::Cmd;
|
||||
|
||||
use crate::manager::Manager;
|
||||
|
|
@ -7,7 +7,7 @@ impl Manager {
|
|||
pub fn suspend(&mut self, _: Cmd) {
|
||||
#[cfg(unix)]
|
||||
tokio::spawn(async move {
|
||||
Scheduler::app_stop().await;
|
||||
AppProxy::stop().await;
|
||||
unsafe { libc::raise(libc::SIGTSTP) };
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use yazi_proxy::ManagerProxy;
|
||||
use yazi_shared::{event::Cmd, fs::FilesOp, render};
|
||||
|
||||
use crate::{folder::Folder, manager::Manager, tab::Tab, tasks::Tasks};
|
||||
|
|
@ -56,8 +57,8 @@ impl Manager {
|
|||
return;
|
||||
}
|
||||
|
||||
Self::_hover(None); // Re-hover in next loop
|
||||
Self::_update_paged(); // Update for paged files in next loop
|
||||
ManagerProxy::hover(None); // Re-hover in next loop
|
||||
ManagerProxy::update_paged(); // Update for paged files in next loop
|
||||
if calc {
|
||||
tasks.preload_sorted(&tab.current.files);
|
||||
}
|
||||
|
|
@ -73,7 +74,7 @@ impl Manager {
|
|||
}
|
||||
|
||||
if !foreign {
|
||||
Self::_peek(true);
|
||||
ManagerProxy::peek(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use yazi_shared::{emit, event::Cmd, fs::Url, Layer};
|
||||
use yazi_shared::{event::Cmd, fs::Url};
|
||||
|
||||
use crate::{manager::Manager, tasks::Tasks};
|
||||
|
||||
|
|
@ -22,19 +22,6 @@ impl From<()> for Opt {
|
|||
}
|
||||
|
||||
impl Manager {
|
||||
#[inline]
|
||||
pub fn _update_paged() {
|
||||
emit!(Call(Cmd::new("update_paged"), Layer::Manager));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn _update_paged_by(page: usize, only_if: &Url) {
|
||||
emit!(Call(
|
||||
Cmd::args("update_paged", vec![page.to_string()]).with("only-if", only_if.to_string()),
|
||||
Layer::Manager
|
||||
));
|
||||
}
|
||||
|
||||
pub fn update_paged(&mut self, opt: impl TryInto<Opt>, tasks: &Tasks) {
|
||||
let Ok(opt) = opt.try_into() else {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use yazi_boot::BOOT;
|
||||
use yazi_proxy::ManagerProxy;
|
||||
use yazi_shared::fs::Url;
|
||||
|
||||
use crate::{manager::Manager, tab::Tab};
|
||||
use crate::tab::Tab;
|
||||
|
||||
pub struct Tabs {
|
||||
pub idx: usize,
|
||||
|
|
@ -17,7 +18,7 @@ impl Tabs {
|
|||
tabs.items[0].reveal(Url::from(BOOT.cwd.join(file)));
|
||||
}
|
||||
|
||||
Manager::_refresh();
|
||||
ManagerProxy::refresh();
|
||||
tabs
|
||||
}
|
||||
|
||||
|
|
@ -42,8 +43,8 @@ impl Tabs {
|
|||
}
|
||||
|
||||
self.idx = idx;
|
||||
Manager::_refresh();
|
||||
Manager::_peek(true);
|
||||
ManagerProxy::refresh();
|
||||
ManagerProxy::peek(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,18 +5,6 @@ use yazi_shared::{emit, event::Cmd, Layer};
|
|||
use crate::notify::{Message, Notify};
|
||||
|
||||
impl Notify {
|
||||
#[inline]
|
||||
pub fn _push_warn(title: &str, content: &str) {
|
||||
emit!(Call(
|
||||
Cmd::new("notify")
|
||||
.with("title", title)
|
||||
.with("content", content)
|
||||
.with("level", "warn")
|
||||
.with("timeout", 5),
|
||||
Layer::App
|
||||
));
|
||||
}
|
||||
|
||||
pub fn push(&mut self, msg: impl TryInto<Message>) {
|
||||
let Ok(mut msg) = msg.try_into() else {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,29 +1,10 @@
|
|||
use anyhow::Result;
|
||||
use tokio::sync::oneshot;
|
||||
use yazi_config::popup::SelectCfg;
|
||||
use yazi_shared::{emit, event::Cmd, render, term::Term, Layer};
|
||||
use yazi_proxy::SelectOpt;
|
||||
use yazi_shared::render;
|
||||
|
||||
use crate::select::Select;
|
||||
|
||||
pub struct Opt {
|
||||
cfg: SelectCfg,
|
||||
tx: oneshot::Sender<Result<usize>>,
|
||||
}
|
||||
|
||||
impl TryFrom<Cmd> for Opt {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(mut c: Cmd) -> Result<Self, Self::Error> { c.take_data().ok_or(()) }
|
||||
}
|
||||
|
||||
impl Select {
|
||||
pub async fn _show(cfg: SelectCfg) -> Result<usize> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
emit!(Call(Cmd::new("show").with_data(Opt { cfg, tx }), Layer::Select));
|
||||
rx.await.unwrap_or_else(|_| Term::goodbye(|| false))
|
||||
}
|
||||
|
||||
pub fn show(&mut self, opt: impl TryInto<Opt>) {
|
||||
pub fn show(&mut self, opt: impl TryInto<SelectOpt>) {
|
||||
let Ok(opt) = opt.try_into() else {
|
||||
return;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use yazi_proxy::ManagerProxy;
|
||||
use yazi_shared::{event::Cmd, render};
|
||||
|
||||
use crate::{manager::Manager, tab::Tab, Step};
|
||||
use crate::{tab::Tab, Step};
|
||||
|
||||
pub struct Opt {
|
||||
step: Step,
|
||||
|
|
@ -36,7 +37,7 @@ impl Tab {
|
|||
}
|
||||
}
|
||||
|
||||
Manager::_hover(None);
|
||||
ManagerProxy::hover(None);
|
||||
render!();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@ use std::{mem, time::Duration};
|
|||
use tokio::{fs, pin};
|
||||
use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};
|
||||
use yazi_config::popup::InputCfg;
|
||||
use yazi_shared::{emit, event::Cmd, fs::{expand_path, Url}, render, Debounce, InputError, Layer};
|
||||
use yazi_proxy::{CompletionProxy, InputProxy, ManagerProxy, TabProxy};
|
||||
use yazi_shared::{event::Cmd, fs::{expand_path, Url}, render, Debounce, InputError};
|
||||
|
||||
use crate::{completion::Completion, input::Input, manager::Manager, tab::Tab};
|
||||
use crate::tab::Tab;
|
||||
|
||||
pub struct Opt {
|
||||
target: Url,
|
||||
|
|
@ -27,11 +28,6 @@ impl From<Url> for Opt {
|
|||
}
|
||||
|
||||
impl Tab {
|
||||
#[inline]
|
||||
pub fn _cd(target: &Url) {
|
||||
emit!(Call(Cmd::args("cd", vec![target.to_string()]), Layer::Manager));
|
||||
}
|
||||
|
||||
pub fn cd(&mut self, opt: impl Into<Opt>) {
|
||||
if !self.try_escape_visual() {
|
||||
return;
|
||||
|
|
@ -68,13 +64,13 @@ impl Tab {
|
|||
self.backstack.push(opt.target.clone());
|
||||
}
|
||||
|
||||
Manager::_refresh();
|
||||
ManagerProxy::refresh();
|
||||
render!();
|
||||
}
|
||||
|
||||
fn cd_interactive(&mut self) {
|
||||
tokio::spawn(async move {
|
||||
let rx = Input::_show(InputCfg::cd());
|
||||
let rx = InputProxy::show(InputCfg::cd());
|
||||
|
||||
let rx = Debounce::new(UnboundedReceiverStream::new(rx), Duration::from_millis(50));
|
||||
pin!(rx);
|
||||
|
|
@ -88,13 +84,13 @@ impl Tab {
|
|||
};
|
||||
|
||||
if meta.is_dir() {
|
||||
Tab::_cd(&u);
|
||||
TabProxy::cd(&u);
|
||||
} else {
|
||||
Tab::_reveal(&u);
|
||||
TabProxy::reveal(&u);
|
||||
}
|
||||
}
|
||||
Err(InputError::Completed(before, ticket)) => {
|
||||
Completion::_trigger(&before, ticket);
|
||||
CompletionProxy::trigger(&before, ticket);
|
||||
}
|
||||
_ => break,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use bitflags::bitflags;
|
||||
use yazi_proxy::{AppProxy, ManagerProxy};
|
||||
use yazi_shared::{event::Cmd, render, render_and};
|
||||
|
||||
use crate::{manager::Manager, notify::Notify, tab::Tab};
|
||||
use crate::tab::Tab;
|
||||
|
||||
bitflags! {
|
||||
pub struct Opt: u8 {
|
||||
|
|
@ -74,7 +75,7 @@ impl Tab {
|
|||
|
||||
self.selected.clear();
|
||||
if self.current.hovered().is_some_and(|h| h.is_dir()) {
|
||||
Manager::_peek(true);
|
||||
ManagerProxy::peek(true);
|
||||
}
|
||||
render_and!(true)
|
||||
}
|
||||
|
|
@ -110,7 +111,7 @@ impl Tab {
|
|||
if !select {
|
||||
self.selected.remove_many(&urls);
|
||||
} else if self.selected.add_many(&urls) != urls.len() {
|
||||
Notify::_push_warn(
|
||||
AppProxy::warn(
|
||||
"Escape visual mode",
|
||||
"Some files cannot be selected, due to path nesting conflict.",
|
||||
);
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@ use std::time::Duration;
|
|||
use tokio::pin;
|
||||
use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};
|
||||
use yazi_config::popup::InputCfg;
|
||||
use yazi_proxy::{InputProxy, ManagerProxy};
|
||||
use yazi_shared::{emit, event::Cmd, render, Debounce, InputError, Layer};
|
||||
|
||||
use crate::{folder::{Filter, FilterCase}, input::Input, manager::Manager, tab::Tab};
|
||||
use crate::{folder::{Filter, FilterCase}, tab::Tab};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Opt {
|
||||
|
|
@ -28,7 +29,7 @@ impl Tab {
|
|||
pub fn filter(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
tokio::spawn(async move {
|
||||
let rx = Input::_show(InputCfg::filter());
|
||||
let rx = InputProxy::show(InputCfg::filter());
|
||||
|
||||
let rx = Debounce::new(UnboundedReceiverStream::new(rx), Duration::from_millis(50));
|
||||
pin!(rx);
|
||||
|
|
@ -62,7 +63,7 @@ impl Tab {
|
|||
};
|
||||
|
||||
if opt.done {
|
||||
Manager::_update_paged(); // Update for paged files in next loop
|
||||
ManagerProxy::update_paged(); // Update for paged files in next loop
|
||||
}
|
||||
|
||||
let hovered = self.current.hovered().map(|f| f.url());
|
||||
|
|
@ -71,7 +72,7 @@ impl Tab {
|
|||
}
|
||||
|
||||
if self.current.repos(hovered) {
|
||||
Manager::_hover(None);
|
||||
ManagerProxy::hover(None);
|
||||
}
|
||||
render!();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@ use std::time::Duration;
|
|||
use tokio::pin;
|
||||
use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};
|
||||
use yazi_config::popup::InputCfg;
|
||||
use yazi_proxy::InputProxy;
|
||||
use yazi_shared::{emit, event::Cmd, render, Debounce, InputError, Layer};
|
||||
|
||||
use crate::{folder::FilterCase, input::Input, tab::{Finder, Tab}};
|
||||
use crate::{folder::FilterCase, tab::{Finder, Tab}};
|
||||
|
||||
pub struct Opt {
|
||||
query: Option<String>,
|
||||
|
|
@ -35,7 +36,7 @@ impl Tab {
|
|||
pub fn find(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
tokio::spawn(async move {
|
||||
let rx = Input::_show(InputCfg::find(opt.prev));
|
||||
let rx = InputProxy::show(InputCfg::find(opt.prev));
|
||||
|
||||
let rx = Debounce::new(UnboundedReceiverStream::new(rx), Duration::from_millis(50));
|
||||
pin!(rx);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use yazi_proxy::ManagerProxy;
|
||||
use yazi_shared::event::Cmd;
|
||||
|
||||
use crate::{manager::Manager, tab::Tab};
|
||||
use crate::tab::Tab;
|
||||
|
||||
impl Tab {
|
||||
pub fn hidden(&mut self, c: Cmd) {
|
||||
|
|
@ -14,10 +15,10 @@ impl Tab {
|
|||
self.apply_files_attrs();
|
||||
|
||||
if hovered.as_ref() != self.current.hovered().map(|f| &f.url) {
|
||||
Manager::_hover(hovered);
|
||||
ManagerProxy::hover(hovered);
|
||||
} else if self.current.hovered().is_some_and(|f| f.is_dir()) {
|
||||
Manager::_peek(true);
|
||||
ManagerProxy::peek(true);
|
||||
}
|
||||
Manager::_update_paged();
|
||||
ManagerProxy::update_paged();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use yazi_plugin::external::{self, FzfOpt, ZoxideOpt};
|
||||
use yazi_scheduler::{Scheduler, BLOCKER};
|
||||
use yazi_proxy::{AppProxy, TabProxy};
|
||||
use yazi_scheduler::BLOCKER;
|
||||
use yazi_shared::{event::Cmd, fs::ends_with_slash, Defer};
|
||||
|
||||
use crate::tab::Tab;
|
||||
|
|
@ -37,8 +38,8 @@ impl Tab {
|
|||
let cwd = self.current.cwd.clone();
|
||||
tokio::spawn(async move {
|
||||
let _guard = BLOCKER.acquire().await.unwrap();
|
||||
let _defer = Defer::new(Scheduler::app_resume);
|
||||
Scheduler::app_stop().await;
|
||||
let _defer = Defer::new(AppProxy::resume);
|
||||
AppProxy::stop().await;
|
||||
|
||||
let result = if opt.type_ == OptType::Fzf {
|
||||
external::fzf(FzfOpt { cwd }).await
|
||||
|
|
@ -51,9 +52,9 @@ impl Tab {
|
|||
};
|
||||
|
||||
if opt.type_ == OptType::Fzf && !ends_with_slash(&url) {
|
||||
Tab::_reveal(&url)
|
||||
TabProxy::reveal(&url)
|
||||
} else {
|
||||
Tab::_cd(&url)
|
||||
TabProxy::cd(&url)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use yazi_shared::{emit, event::Cmd, fs::{expand_path, File, FilesOp, Url}, Layer};
|
||||
use yazi_proxy::ManagerProxy;
|
||||
use yazi_shared::{event::Cmd, fs::{expand_path, File, FilesOp, Url}};
|
||||
|
||||
use crate::{manager::Manager, tab::Tab};
|
||||
use crate::tab::Tab;
|
||||
|
||||
pub struct Opt {
|
||||
target: Url,
|
||||
|
|
@ -21,11 +22,6 @@ impl From<Url> for Opt {
|
|||
}
|
||||
|
||||
impl Tab {
|
||||
#[inline]
|
||||
pub fn _reveal(target: &Url) {
|
||||
emit!(Call(Cmd::args("reveal", vec![target.to_string()]), Layer::Manager));
|
||||
}
|
||||
|
||||
pub fn reveal(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
|
||||
|
|
@ -35,6 +31,6 @@ impl Tab {
|
|||
|
||||
self.cd(parent.clone());
|
||||
FilesOp::Creating(parent, vec![File::from_dummy(&opt.target)]).emit();
|
||||
Manager::_hover(Some(opt.target));
|
||||
ManagerProxy::hover(Some(opt.target));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,10 @@ use tokio::pin;
|
|||
use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};
|
||||
use yazi_config::popup::InputCfg;
|
||||
use yazi_plugin::external;
|
||||
use yazi_proxy::{InputProxy, ManagerProxy, TabProxy};
|
||||
use yazi_shared::{event::Cmd, fs::FilesOp, render};
|
||||
|
||||
use crate::{input::Input, manager::Manager, tab::Tab};
|
||||
use crate::tab::Tab;
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub enum OptType {
|
||||
|
|
@ -59,7 +60,7 @@ impl Tab {
|
|||
let hidden = self.conf.show_hidden;
|
||||
|
||||
self.search = Some(tokio::spawn(async move {
|
||||
let mut input = Input::_show(InputCfg::search(&opt.type_.to_string()));
|
||||
let mut input = InputProxy::show(InputCfg::search(&opt.type_.to_string()));
|
||||
let Some(Ok(subject)) = input.recv().await else { bail!("") };
|
||||
|
||||
cwd = cwd.into_search(subject.clone());
|
||||
|
|
@ -72,7 +73,7 @@ impl Tab {
|
|||
let rx = UnboundedReceiverStream::new(rx).chunks_timeout(1000, Duration::from_millis(300));
|
||||
pin!(rx);
|
||||
|
||||
let ((), ticket) = (Tab::_cd(&cwd), FilesOp::prepare(&cwd));
|
||||
let ((), ticket) = (TabProxy::cd(&cwd), FilesOp::prepare(&cwd));
|
||||
while let Some(chunk) = rx.next().await {
|
||||
FilesOp::Part(cwd.clone(), chunk, ticket).emit();
|
||||
}
|
||||
|
|
@ -90,7 +91,7 @@ impl Tab {
|
|||
if self.current.cwd.is_search() {
|
||||
let rep = self.history_new(&self.current.cwd.to_regular());
|
||||
drop(mem::replace(&mut self.current, rep));
|
||||
Manager::_refresh();
|
||||
ManagerProxy::refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use yazi_proxy::AppProxy;
|
||||
use yazi_shared::{event::Cmd, fs::Url, render, render_and};
|
||||
|
||||
use crate::{notify::Notify, tab::Tab};
|
||||
use crate::tab::Tab;
|
||||
|
||||
pub struct Opt<'a> {
|
||||
url: Option<Cow<'a, Url>>,
|
||||
|
|
@ -37,10 +38,7 @@ impl<'a> Tab {
|
|||
};
|
||||
|
||||
if !b {
|
||||
Notify::_push_warn(
|
||||
"Select one",
|
||||
"This file cannot be selected, due to path nesting conflict.",
|
||||
);
|
||||
AppProxy::warn("Select one", "This file cannot be selected, due to path nesting conflict.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use yazi_proxy::AppProxy;
|
||||
use yazi_shared::{event::Cmd, render};
|
||||
|
||||
use crate::{notify::Notify, tab::Tab};
|
||||
use crate::tab::Tab;
|
||||
|
||||
pub struct Opt {
|
||||
state: Option<bool>,
|
||||
|
|
@ -35,10 +36,7 @@ impl Tab {
|
|||
|
||||
render!(added > 0);
|
||||
if added != addition.len() {
|
||||
Notify::_push_warn(
|
||||
"Select all",
|
||||
"Some files cannot be selected, due to path nesting conflict.",
|
||||
);
|
||||
AppProxy::warn("Select all", "Some files cannot be selected, due to path nesting conflict.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use yazi_config::{open::Opener, popup::InputCfg};
|
||||
use yazi_proxy::{InputProxy, TasksProxy};
|
||||
use yazi_shared::event::Cmd;
|
||||
|
||||
use crate::{input::Input, tab::Tab, tasks::Tasks};
|
||||
use crate::tab::Tab;
|
||||
|
||||
pub struct Opt {
|
||||
exec: String,
|
||||
|
|
@ -30,14 +31,14 @@ impl Tab {
|
|||
|
||||
tokio::spawn(async move {
|
||||
if !opt.confirm || opt.exec.is_empty() {
|
||||
let mut result = Input::_show(InputCfg::shell(opt.block).with_value(opt.exec));
|
||||
let mut result = InputProxy::show(InputCfg::shell(opt.block).with_value(opt.exec));
|
||||
match result.recv().await {
|
||||
Some(Ok(e)) => opt.exec = e,
|
||||
_ => return,
|
||||
}
|
||||
}
|
||||
|
||||
Tasks::_open_with(selected, Opener {
|
||||
TasksProxy::open_with(selected, Opener {
|
||||
exec: opt.exec,
|
||||
block: opt.block,
|
||||
orphan: false,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use std::str::FromStr;
|
||||
|
||||
use yazi_config::manager::SortBy;
|
||||
use yazi_proxy::ManagerProxy;
|
||||
use yazi_shared::event::Cmd;
|
||||
|
||||
use crate::{manager::Manager, tab::Tab, tasks::Tasks};
|
||||
use crate::{tab::Tab, tasks::Tasks};
|
||||
|
||||
impl Tab {
|
||||
pub fn sort(&mut self, c: Cmd, tasks: &Tasks) {
|
||||
|
|
@ -15,7 +16,7 @@ impl Tab {
|
|||
self.conf.sort_dir_first = c.named.contains_key("dir-first");
|
||||
|
||||
self.apply_files_attrs();
|
||||
Manager::_update_paged();
|
||||
ManagerProxy::update_paged();
|
||||
|
||||
tasks.preload_sorted(&self.current.files);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ use std::io::{stdout, Write};
|
|||
|
||||
use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
|
||||
use tokio::{io::{stdin, AsyncReadExt}, select, sync::mpsc, time};
|
||||
use yazi_scheduler::{Scheduler, BLOCKER};
|
||||
use yazi_proxy::AppProxy;
|
||||
use yazi_scheduler::BLOCKER;
|
||||
use yazi_shared::{event::Cmd, term::Term, Defer};
|
||||
|
||||
use crate::tasks::Tasks;
|
||||
|
|
@ -26,10 +27,10 @@ impl Tasks {
|
|||
task.logs.clone()
|
||||
};
|
||||
|
||||
Scheduler::app_stop().await;
|
||||
AppProxy::stop().await;
|
||||
let _defer = Defer::new(|| {
|
||||
disable_raw_mode().ok();
|
||||
Scheduler::app_resume();
|
||||
AppProxy::resume();
|
||||
});
|
||||
|
||||
Term::clear(&mut stdout()).ok();
|
||||
|
|
|
|||
|
|
@ -1,25 +1,9 @@
|
|||
use yazi_config::open::Opener;
|
||||
use yazi_shared::{emit, event::Cmd, fs::Url, Layer};
|
||||
use yazi_proxy::OpenWithOpt;
|
||||
|
||||
use crate::tasks::Tasks;
|
||||
|
||||
pub struct Opt {
|
||||
targets: Vec<Url>,
|
||||
opener: Opener,
|
||||
}
|
||||
|
||||
impl TryFrom<Cmd> for Opt {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(mut c: Cmd) -> Result<Self, Self::Error> { c.take_data().ok_or(()) }
|
||||
}
|
||||
|
||||
impl Tasks {
|
||||
pub fn _open_with(targets: Vec<Url>, opener: Opener) {
|
||||
emit!(Call(Cmd::new("open_with").with_data(Opt { targets, opener }), Layer::Tasks));
|
||||
}
|
||||
|
||||
pub fn open_with(&mut self, opt: impl TryInto<Opt>) {
|
||||
pub fn open_with(&mut self, opt: impl TryInto<OpenWithOpt>) {
|
||||
if let Ok(opt) = opt.try_into() {
|
||||
self.file_open_with(&opt.opener, &opt.targets);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ yazi-boot = { path = "../yazi-boot", version = "0.2.3" }
|
|||
yazi-config = { path = "../yazi-config", version = "0.2.3" }
|
||||
yazi-core = { path = "../yazi-core", version = "0.2.3" }
|
||||
yazi-plugin = { path = "../yazi-plugin", version = "0.2.3" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "0.2.3" }
|
||||
yazi-scheduler = { path = "../yazi-scheduler", version = "0.2.3" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "0.2.3" }
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ impl<'a> Widget for Layout<'a> {
|
|||
|
||||
let chunks = layout::Layout::vertical([Constraint::Fill(1), Constraint::Length(1)]).split(area);
|
||||
Line::styled(
|
||||
help.keyword().unwrap_or_else(|| format!("{}.help", help.layer.to_string())),
|
||||
help.keyword().unwrap_or_else(|| format!("{}.help", help.layer)),
|
||||
THEME.help.footer,
|
||||
)
|
||||
.render(chunks[1], buf);
|
||||
|
|
|
|||
|
|
@ -43,7 +43,8 @@ impl Signals {
|
|||
#[cfg(unix)]
|
||||
fn spawn_system_task(&self) -> Result<JoinHandle<()>> {
|
||||
use libc::{SIGCONT, SIGHUP, SIGINT, SIGQUIT, SIGTERM};
|
||||
use yazi_scheduler::{Scheduler, BLOCKER};
|
||||
use yazi_proxy::AppProxy;
|
||||
use yazi_scheduler::BLOCKER;
|
||||
|
||||
let mut signals = signal_hook_tokio::Signals::new([
|
||||
// Terminating signals
|
||||
|
|
@ -65,7 +66,7 @@ impl Signals {
|
|||
break;
|
||||
}
|
||||
}
|
||||
SIGCONT => Scheduler::app_resume(),
|
||||
SIGCONT => AppProxy::resume(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ repository = "https://github.com/sxyazi/yazi"
|
|||
yazi-adaptor = { path = "../yazi-adaptor", version = "0.2.3" }
|
||||
yazi-boot = { path = "../yazi-boot", version = "0.2.3" }
|
||||
yazi-config = { path = "../yazi-config", version = "0.2.3" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "0.2.3" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "0.2.3" }
|
||||
|
||||
# External dependencies
|
||||
|
|
|
|||
32
yazi-plugin/src/bindings/input.rs
Normal file
32
yazi-plugin/src/bindings/input.rs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
use mlua::{prelude::LuaUserDataMethods, UserData};
|
||||
use tokio::sync::mpsc::UnboundedReceiver;
|
||||
use yazi_shared::InputError;
|
||||
|
||||
pub struct InputRx {
|
||||
inner: UnboundedReceiver<Result<String, InputError>>,
|
||||
}
|
||||
|
||||
impl InputRx {
|
||||
pub fn new(inner: UnboundedReceiver<Result<String, InputError>>) -> Self { Self { inner } }
|
||||
|
||||
pub fn parse(res: Result<String, InputError>) -> (Option<String>, u8) {
|
||||
match res {
|
||||
Ok(s) => (Some(s), 1),
|
||||
Err(InputError::Canceled(s)) => (Some(s), 2),
|
||||
Err(InputError::Typed(s)) => (Some(s), 3),
|
||||
_ => (None, 0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for InputRx {
|
||||
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_async_method_mut("recv", |_, me, ()| async move {
|
||||
let Some(res) = me.inner.recv().await else {
|
||||
return Ok((None, 0));
|
||||
};
|
||||
|
||||
Ok(Self::parse(res))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,8 @@ mod bindings;
|
|||
mod cha;
|
||||
mod file;
|
||||
mod icon;
|
||||
mod input;
|
||||
mod position;
|
||||
mod range;
|
||||
mod window;
|
||||
|
||||
|
|
@ -11,5 +13,7 @@ pub use bindings::*;
|
|||
pub use cha::*;
|
||||
pub use file::*;
|
||||
pub use icon::*;
|
||||
pub use input::*;
|
||||
pub use position::*;
|
||||
pub use range::*;
|
||||
pub use window::*;
|
||||
|
|
|
|||
47
yazi-plugin/src/bindings/position.rs
Normal file
47
yazi-plugin/src/bindings/position.rs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
use std::{ops::Deref, str::FromStr};
|
||||
|
||||
use mlua::{ExternalResult, IntoLua};
|
||||
|
||||
pub struct Position(yazi_config::popup::Position);
|
||||
|
||||
impl Deref for Position {
|
||||
type Target = yazi_config::popup::Position;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.0 }
|
||||
}
|
||||
|
||||
impl From<Position> for yazi_config::popup::Position {
|
||||
fn from(value: Position) -> Self { value.0 }
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<mlua::Table<'a>> for Position {
|
||||
type Error = mlua::Error;
|
||||
|
||||
fn try_from(t: mlua::Table<'a>) -> Result<Self, Self::Error> {
|
||||
use yazi_config::popup::{Offset, Origin, Position};
|
||||
|
||||
Ok(Self(Position {
|
||||
origin: Origin::from_str(t.raw_get::<_, mlua::String>(1)?.to_str()?).into_lua_err()?,
|
||||
offset: Offset {
|
||||
x: t.raw_get("x").unwrap_or_default(),
|
||||
y: t.raw_get("y").unwrap_or_default(),
|
||||
width: t.raw_get("w").unwrap_or_default(),
|
||||
height: 3,
|
||||
},
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> IntoLua<'lua> for Position {
|
||||
fn into_lua(self, lua: &'lua mlua::Lua) -> mlua::Result<mlua::Value> {
|
||||
lua
|
||||
.create_table_from([
|
||||
(1.into_lua(lua)?, self.origin.to_string().into_lua(lua)?),
|
||||
("x".into_lua(lua)?, self.offset.x.into_lua(lua)?),
|
||||
("y".into_lua(lua)?, self.offset.y.into_lua(lua)?),
|
||||
("w".into_lua(lua)?, self.offset.width.into_lua(lua)?),
|
||||
("h".into_lua(lua)?, self.offset.height.into_lua(lua)?),
|
||||
])?
|
||||
.into_lua(lua)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,13 @@
|
|||
use std::str::FromStr;
|
||||
|
||||
use mlua::{ExternalError, ExternalResult, Lua, Table, Value};
|
||||
use mlua::{ExternalError, ExternalResult, IntoLuaMulti, Lua, Table, Value};
|
||||
use tokio::sync::mpsc;
|
||||
use yazi_config::keymap::{Control, Key};
|
||||
use yazi_config::{keymap::{Control, Key}, popup::InputCfg};
|
||||
use yazi_proxy::InputProxy;
|
||||
use yazi_shared::{emit, event::Cmd, Layer};
|
||||
|
||||
use super::Utils;
|
||||
use crate::bindings::{InputRx, Position};
|
||||
|
||||
impl Utils {
|
||||
fn parse_keys(value: Value) -> mlua::Result<Vec<Key>> {
|
||||
|
|
@ -53,6 +55,30 @@ impl Utils {
|
|||
})?,
|
||||
)?;
|
||||
|
||||
ya.raw_set(
|
||||
"input",
|
||||
lua.create_async_function(|lua, t: Table| async move {
|
||||
let realtime = t.raw_get("realtime").unwrap_or_default();
|
||||
let mut rx = InputProxy::show(InputCfg {
|
||||
title: t.raw_get("title")?,
|
||||
value: t.raw_get("value").unwrap_or_default(),
|
||||
cursor: None, // TODO
|
||||
position: Position::try_from(t.raw_get::<_, Table>("position")?)?.into(),
|
||||
realtime,
|
||||
completion: false,
|
||||
highlight: false,
|
||||
});
|
||||
|
||||
if realtime {
|
||||
(InputRx::new(rx), Value::Nil).into_lua_multi(lua)
|
||||
} else if let Some(res) = rx.recv().await {
|
||||
InputRx::parse(res).into_lua_multi(lua)
|
||||
} else {
|
||||
(Value::Nil, 0).into_lua_multi(lua)
|
||||
}
|
||||
})?,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
17
yazi-proxy/Cargo.toml
Normal file
17
yazi-proxy/Cargo.toml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
[package]
|
||||
name = "yazi-proxy"
|
||||
version = "0.2.3"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
description = "Yazi event proxy"
|
||||
homepage = "https://yazi-rs.github.io"
|
||||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-config = { path = "../yazi-config", version = "0.2.3" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "0.2.3" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = "^1"
|
||||
tokio = { version = "^1", features = [ "parking_lot" ] }
|
||||
30
yazi-proxy/src/app.rs
Normal file
30
yazi-proxy/src/app.rs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
use tokio::sync::oneshot;
|
||||
use yazi_shared::{emit, event::Cmd, Layer};
|
||||
|
||||
pub struct AppProxy;
|
||||
|
||||
impl AppProxy {
|
||||
#[inline]
|
||||
pub async fn stop() {
|
||||
let (tx, rx) = oneshot::channel::<()>();
|
||||
emit!(Call(Cmd::new("stop").with_data(tx), Layer::App));
|
||||
rx.await.ok();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn resume() {
|
||||
emit!(Call(Cmd::new("resume"), Layer::App));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn warn(title: &str, content: &str) {
|
||||
emit!(Call(
|
||||
Cmd::new("notify")
|
||||
.with("title", title)
|
||||
.with("content", content)
|
||||
.with("level", "warn")
|
||||
.with("timeout", 5),
|
||||
Layer::App
|
||||
));
|
||||
}
|
||||
}
|
||||
18
yazi-proxy/src/completion.rs
Normal file
18
yazi-proxy/src/completion.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
use yazi_shared::{emit, event::Cmd, Layer};
|
||||
|
||||
pub struct CompletionProxy;
|
||||
|
||||
impl CompletionProxy {
|
||||
#[inline]
|
||||
pub fn close() {
|
||||
emit!(Call(Cmd::new("close"), Layer::Completion));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn trigger(word: &str, ticket: usize) {
|
||||
emit!(Call(
|
||||
Cmd::args("trigger", vec![word.to_owned()]).with("ticket", ticket),
|
||||
Layer::Completion
|
||||
));
|
||||
}
|
||||
}
|
||||
30
yazi-proxy/src/input.rs
Normal file
30
yazi-proxy/src/input.rs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
use tokio::sync::mpsc;
|
||||
use yazi_config::popup::InputCfg;
|
||||
use yazi_shared::{emit, event::Cmd, InputError, Layer};
|
||||
|
||||
pub struct InputOpt {
|
||||
pub cfg: InputCfg,
|
||||
pub tx: mpsc::UnboundedSender<Result<String, InputError>>,
|
||||
}
|
||||
|
||||
impl TryFrom<Cmd> for InputOpt {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(mut c: Cmd) -> Result<Self, Self::Error> { c.take_data().ok_or(()) }
|
||||
}
|
||||
|
||||
pub struct InputProxy;
|
||||
|
||||
impl InputProxy {
|
||||
#[inline]
|
||||
pub fn show(cfg: InputCfg) -> mpsc::UnboundedReceiver<Result<String, InputError>> {
|
||||
let (tx, rx) = mpsc::unbounded_channel();
|
||||
emit!(Call(Cmd::new("show").with_data(InputOpt { cfg, tx }), Layer::Input));
|
||||
rx
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn complete(word: &str, ticket: usize) {
|
||||
emit!(Call(Cmd::args("complete", vec![word.to_owned()]).with("ticket", ticket), Layer::Input));
|
||||
}
|
||||
}
|
||||
15
yazi-proxy/src/lib.rs
Normal file
15
yazi-proxy/src/lib.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
mod app;
|
||||
mod completion;
|
||||
mod input;
|
||||
mod manager;
|
||||
mod select;
|
||||
mod tab;
|
||||
mod tasks;
|
||||
|
||||
pub use app::*;
|
||||
pub use completion::*;
|
||||
pub use input::*;
|
||||
pub use manager::*;
|
||||
pub use select::*;
|
||||
pub use tab::*;
|
||||
pub use tasks::*;
|
||||
60
yazi-proxy/src/manager.rs
Normal file
60
yazi-proxy/src/manager.rs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
use yazi_shared::{emit, event::Cmd, fs::Url, Layer};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct OpenDoOpt {
|
||||
pub hovered: Url,
|
||||
pub targets: Vec<(Url, String)>,
|
||||
pub interactive: bool,
|
||||
}
|
||||
|
||||
impl From<Cmd> for OpenDoOpt {
|
||||
fn from(mut c: Cmd) -> Self { c.take_data().unwrap_or_default() }
|
||||
}
|
||||
|
||||
pub struct ManagerProxy;
|
||||
|
||||
impl ManagerProxy {
|
||||
#[inline]
|
||||
pub fn peek(force: bool) {
|
||||
emit!(Call(Cmd::new("peek").with_bool("force", force), Layer::Manager));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn hover(url: Option<Url>) {
|
||||
emit!(Call(
|
||||
Cmd::args("hover", url.map_or_else(Vec::new, |u| vec![u.to_string()])),
|
||||
Layer::Manager
|
||||
));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn refresh() {
|
||||
emit!(Call(Cmd::new("refresh"), Layer::Manager));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn open_do(opt: OpenDoOpt) {
|
||||
emit!(Call(Cmd::new("open_do").with_data(opt), Layer::Manager));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn remove_do(targets: Vec<Url>, permanently: bool) {
|
||||
emit!(Call(
|
||||
Cmd::new("remove_do").with_bool("permanently", permanently).with_data(targets),
|
||||
Layer::Manager
|
||||
));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn update_paged() {
|
||||
emit!(Call(Cmd::new("update_paged"), Layer::Manager));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn update_paged_by(page: usize, only_if: &Url) {
|
||||
emit!(Call(
|
||||
Cmd::args("update_paged", vec![page.to_string()]).with("only-if", only_if.to_string()),
|
||||
Layer::Manager
|
||||
));
|
||||
}
|
||||
}
|
||||
25
yazi-proxy/src/select.rs
Normal file
25
yazi-proxy/src/select.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
use tokio::sync::oneshot;
|
||||
use yazi_config::popup::SelectCfg;
|
||||
use yazi_shared::{emit, event::Cmd, term::Term, Layer};
|
||||
|
||||
pub struct SelectOpt {
|
||||
pub cfg: SelectCfg,
|
||||
pub tx: oneshot::Sender<anyhow::Result<usize>>,
|
||||
}
|
||||
|
||||
impl TryFrom<Cmd> for SelectOpt {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(mut c: Cmd) -> Result<Self, Self::Error> { c.take_data().ok_or(()) }
|
||||
}
|
||||
|
||||
pub struct SelectProxy;
|
||||
|
||||
impl SelectProxy {
|
||||
#[inline]
|
||||
pub async fn show(cfg: SelectCfg) -> anyhow::Result<usize> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
emit!(Call(Cmd::new("show").with_data(SelectOpt { cfg, tx }), Layer::Select));
|
||||
rx.await.unwrap_or_else(|_| Term::goodbye(|| false))
|
||||
}
|
||||
}
|
||||
15
yazi-proxy/src/tab.rs
Normal file
15
yazi-proxy/src/tab.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
use yazi_shared::{emit, event::Cmd, fs::Url, Layer};
|
||||
|
||||
pub struct TabProxy;
|
||||
|
||||
impl TabProxy {
|
||||
#[inline]
|
||||
pub fn cd(target: &Url) {
|
||||
emit!(Call(Cmd::args("cd", vec![target.to_string()]), Layer::Manager));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn reveal(target: &Url) {
|
||||
emit!(Call(Cmd::args("reveal", vec![target.to_string()]), Layer::Manager));
|
||||
}
|
||||
}
|
||||
22
yazi-proxy/src/tasks.rs
Normal file
22
yazi-proxy/src/tasks.rs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
use yazi_config::open::Opener;
|
||||
use yazi_shared::{emit, event::Cmd, fs::Url, Layer};
|
||||
|
||||
pub struct TasksProxy;
|
||||
|
||||
pub struct OpenWithOpt {
|
||||
pub targets: Vec<Url>,
|
||||
pub opener: Opener,
|
||||
}
|
||||
|
||||
impl TryFrom<Cmd> for OpenWithOpt {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(mut c: Cmd) -> Result<Self, Self::Error> { c.take_data().ok_or(()) }
|
||||
}
|
||||
|
||||
impl TasksProxy {
|
||||
#[inline]
|
||||
pub fn open_with(targets: Vec<Url>, opener: Opener) {
|
||||
emit!(Call(Cmd::new("open_with").with_data(OpenWithOpt { targets, opener }), Layer::Tasks));
|
||||
}
|
||||
}
|
||||
|
|
@ -11,8 +11,9 @@ repository = "https://github.com/sxyazi/yazi"
|
|||
[dependencies]
|
||||
yazi-adaptor = { path = "../yazi-adaptor", version = "0.2.3" }
|
||||
yazi-config = { path = "../yazi-config", version = "0.2.3" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "0.2.3" }
|
||||
yazi-plugin = { path = "../yazi-plugin", version = "0.2.3" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "0.2.3" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "0.2.3" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = "^1"
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use anyhow::Result;
|
||||
use tokio::{io::{AsyncBufReadExt, BufReader}, select, sync::mpsc};
|
||||
use yazi_plugin::external::{self, ShellOpt};
|
||||
use yazi_proxy::AppProxy;
|
||||
|
||||
use super::ProcessOpOpen;
|
||||
use crate::{Scheduler, TaskProg, BLOCKER};
|
||||
use crate::{TaskProg, BLOCKER};
|
||||
|
||||
pub struct Process {
|
||||
prog: mpsc::UnboundedSender<TaskProg>,
|
||||
|
|
@ -16,7 +17,7 @@ impl Process {
|
|||
let opt = ShellOpt::from(&mut task);
|
||||
if task.block {
|
||||
let _guard = BLOCKER.acquire().await.unwrap();
|
||||
Scheduler::app_stop().await;
|
||||
AppProxy::stop().await;
|
||||
|
||||
match external::shell(opt) {
|
||||
Ok(mut child) => {
|
||||
|
|
@ -28,7 +29,7 @@ impl Process {
|
|||
self.fail(task.id, format!("Failed to spawn process: {e}"))?;
|
||||
}
|
||||
}
|
||||
return Ok(Scheduler::app_resume());
|
||||
return Ok(AppProxy::resume());
|
||||
}
|
||||
|
||||
if task.orphan {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use parking_lot::Mutex;
|
|||
use tokio::{fs, select, sync::{mpsc::{self, UnboundedReceiver}, oneshot}};
|
||||
use yazi_config::{open::Opener, plugin::PluginRule, TASKS};
|
||||
use yazi_plugin::ValueSendable;
|
||||
use yazi_shared::{emit, event::Cmd, fs::{unique_path, Url}, Layer, Throttle};
|
||||
use yazi_shared::{fs::{unique_path, Url}, Throttle};
|
||||
|
||||
use super::{Running, TaskProg, TaskStage};
|
||||
use crate::{file::{File, FileOpDelete, FileOpLink, FileOpPaste, FileOpTrash}, plugin::{Plugin, PluginOpEntry}, preload::{Preload, PreloadOpRule, PreloadOpSize}, process::{Process, ProcessOpOpen}, TaskKind, TaskOp, HIGH, LOW, NORMAL};
|
||||
|
|
@ -163,16 +163,6 @@ impl Scheduler {
|
|||
b
|
||||
}
|
||||
|
||||
pub async fn app_stop() {
|
||||
let (tx, rx) = oneshot::channel::<()>();
|
||||
emit!(Call(Cmd::new("stop").with_data(tx), Layer::App));
|
||||
rx.await.ok();
|
||||
}
|
||||
|
||||
pub fn app_resume() {
|
||||
emit!(Call(Cmd::new("resume"), Layer::App));
|
||||
}
|
||||
|
||||
pub fn file_cut(&self, from: Url, mut to: Url, force: bool) {
|
||||
let mut running = self.running.lock();
|
||||
let id = running.add(TaskKind::User, format!("Cut {:?} to {:?}", from, to));
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue