mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
..
This commit is contained in:
parent
b71bd8a30e
commit
9e05099a50
48 changed files with 333 additions and 263 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -2816,6 +2816,7 @@ checksum = "f4b6c8e12e39ac0f79fa96f36e5b88e0da8d230691abd729eec709b43c74f632"
|
|||
name = "yazi-proxy"
|
||||
version = "0.2.3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"tokio",
|
||||
"yazi-config",
|
||||
"yazi-shared",
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
@ -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,11 +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_proxy::App;
|
||||
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,
|
||||
|
|
@ -50,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>) {
|
||||
|
|
@ -78,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;
|
||||
};
|
||||
|
|
@ -89,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();
|
||||
|
|
@ -123,10 +123,10 @@ impl Manager {
|
|||
|
||||
let _guard = BLOCKER.acquire().await.unwrap();
|
||||
let _defer = Defer::new(|| {
|
||||
App::resume();
|
||||
AppProxy::resume();
|
||||
tokio::spawn(fs::remove_file(tmp.clone()))
|
||||
});
|
||||
App::stop().await;
|
||||
AppProxy::stop().await;
|
||||
|
||||
let mut child = external::shell(ShellOpt {
|
||||
cmd: (*opener.exec).into(),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use yazi_proxy::App;
|
||||
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 {
|
||||
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,5 @@
|
|||
use yazi_plugin::external::{self, FzfOpt, ZoxideOpt};
|
||||
use yazi_proxy::App;
|
||||
use yazi_proxy::{AppProxy, TabProxy};
|
||||
use yazi_scheduler::BLOCKER;
|
||||
use yazi_shared::{event::Cmd, fs::ends_with_slash, Defer};
|
||||
|
||||
|
|
@ -38,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(App::resume);
|
||||
App::stop().await;
|
||||
let _defer = Defer::new(AppProxy::resume);
|
||||
AppProxy::stop().await;
|
||||
|
||||
let result = if opt.type_ == OptType::Fzf {
|
||||
external::fzf(FzfOpt { cwd }).await
|
||||
|
|
@ -52,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,7 @@ 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_proxy::App;
|
||||
use yazi_proxy::AppProxy;
|
||||
use yazi_scheduler::BLOCKER;
|
||||
use yazi_shared::{event::Cmd, term::Term, Defer};
|
||||
|
||||
|
|
@ -27,10 +27,10 @@ impl Tasks {
|
|||
task.logs.clone()
|
||||
};
|
||||
|
||||
App::stop().await;
|
||||
AppProxy::stop().await;
|
||||
let _defer = Defer::new(|| {
|
||||
disable_raw_mode().ok();
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ impl Signals {
|
|||
#[cfg(unix)]
|
||||
fn spawn_system_task(&self) -> Result<JoinHandle<()>> {
|
||||
use libc::{SIGCONT, SIGHUP, SIGINT, SIGQUIT, SIGTERM};
|
||||
use yazi_proxy::AppProxy;
|
||||
use yazi_scheduler::BLOCKER;
|
||||
|
||||
let mut signals = signal_hook_tokio::Signals::new([
|
||||
|
|
@ -65,7 +66,7 @@ impl Signals {
|
|||
break;
|
||||
}
|
||||
}
|
||||
SIGCONT => yazi_proxy::App::resume(),
|
||||
SIGCONT => AppProxy::resume(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,4 +13,5 @@ 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" ] }
|
||||
|
|
|
|||
|
|
@ -1,16 +1,30 @@
|
|||
use tokio::sync::oneshot;
|
||||
use yazi_shared::{emit, event::Cmd, Layer};
|
||||
|
||||
pub struct App;
|
||||
pub struct AppProxy;
|
||||
|
||||
impl App {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +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));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
use anyhow::Result;
|
||||
use tokio::{io::{AsyncBufReadExt, BufReader}, select, sync::mpsc};
|
||||
use yazi_plugin::external::{self, ShellOpt};
|
||||
use yazi_proxy::App;
|
||||
use yazi_proxy::AppProxy;
|
||||
|
||||
use super::ProcessOpOpen;
|
||||
use crate::{TaskProg, BLOCKER};
|
||||
|
|
@ -17,7 +17,7 @@ impl Process {
|
|||
let opt = ShellOpt::from(&mut task);
|
||||
if task.block {
|
||||
let _guard = BLOCKER.acquire().await.unwrap();
|
||||
App::stop().await;
|
||||
AppProxy::stop().await;
|
||||
|
||||
match external::shell(opt) {
|
||||
Ok(mut child) => {
|
||||
|
|
@ -29,7 +29,7 @@ impl Process {
|
|||
self.fail(task.id, format!("Failed to spawn process: {e}"))?;
|
||||
}
|
||||
}
|
||||
return Ok(App::resume());
|
||||
return Ok(AppProxy::resume());
|
||||
}
|
||||
|
||||
if task.orphan {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue