mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: the cd event in DDS will now also be triggered when the tab is first created (#861)
This commit is contained in:
parent
7a99ea4409
commit
b51babde1c
12 changed files with 88 additions and 190 deletions
|
|
@ -22,12 +22,8 @@ pub struct Folder {
|
||||||
pub tracing: bool,
|
pub tracing: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Url> for Folder {
|
|
||||||
fn from(cwd: Url) -> Self { Self { cwd, ..Default::default() } }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&Url> for Folder {
|
impl From<&Url> for Folder {
|
||||||
fn from(cwd: &Url) -> Self { Self::from(cwd.clone()) }
|
fn from(cwd: &Url) -> Self { Self { cwd: cwd.clone(), ..Default::default() } }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Folder {
|
impl Folder {
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,10 @@ impl Tabs {
|
||||||
let opt = opt.into() as Opt;
|
let opt = opt.into() as Opt;
|
||||||
let url = if opt.current { self.active().current.cwd.to_owned() } else { opt.url.unwrap() };
|
let url = if opt.current { self.active().current.cwd.to_owned() } else { opt.url.unwrap() };
|
||||||
|
|
||||||
let mut tab = Tab::from(url);
|
let mut tab = Tab::default();
|
||||||
tab.conf = self.active().conf.clone();
|
tab.conf = self.active().conf.clone();
|
||||||
tab.apply_files_attrs();
|
tab.apply_files_attrs();
|
||||||
|
tab.cd(url);
|
||||||
|
|
||||||
self.items.insert(self.cursor + 1, tab);
|
self.items.insert(self.cursor + 1, tab);
|
||||||
self.set_idx(self.cursor + 1);
|
self.set_idx(self.cursor + 1);
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,13 @@ pub struct Tabs {
|
||||||
|
|
||||||
impl Tabs {
|
impl Tabs {
|
||||||
pub fn make() -> Self {
|
pub fn make() -> Self {
|
||||||
let mut tabs = Self { cursor: 0, items: vec![Tab::from(Url::from(&BOOT.cwd))] };
|
let mut tabs = Self { cursor: 0, items: vec![Tab::default()] };
|
||||||
if let Some(file) = &BOOT.file {
|
if let Some(file) = &BOOT.file {
|
||||||
tabs.items[0].reveal(Url::from(BOOT.cwd.join(file)));
|
tabs.items[0].reveal(Url::from(BOOT.cwd.join(file)));
|
||||||
|
} else {
|
||||||
|
tabs.items[0].cd(Url::from(&BOOT.cwd));
|
||||||
}
|
}
|
||||||
|
|
||||||
ManagerProxy::refresh();
|
|
||||||
tabs
|
tabs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,16 @@
|
||||||
|
#[derive(Default)]
|
||||||
pub struct Backstack<T: Eq> {
|
pub struct Backstack<T: Eq> {
|
||||||
cursor: usize,
|
cursor: usize,
|
||||||
stack: Vec<T>,
|
stack: Vec<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Eq> Backstack<T> {
|
impl<T: Eq> Backstack<T> {
|
||||||
pub fn new(item: T) -> Self { Self { cursor: 0, stack: vec![item] } }
|
|
||||||
|
|
||||||
pub fn push(&mut self, item: T) {
|
pub fn push(&mut self, item: T) {
|
||||||
|
if self.stack.is_empty() {
|
||||||
|
self.stack.push(item);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if self.stack[self.cursor] == item {
|
if self.stack[self.cursor] == item {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -27,10 +31,6 @@ impl<T: Eq> Backstack<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
#[inline]
|
|
||||||
pub fn current(&self) -> &T { &self.stack[self.cursor] }
|
|
||||||
|
|
||||||
pub fn shift_backward(&mut self) -> Option<&T> {
|
pub fn shift_backward(&mut self) -> Option<&T> {
|
||||||
if self.cursor > 0 {
|
if self.cursor > 0 {
|
||||||
self.cursor -= 1;
|
self.cursor -= 1;
|
||||||
|
|
@ -56,27 +56,28 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_backstack() {
|
fn test_backstack() {
|
||||||
let mut backstack = Backstack::<u32>::new(1);
|
let mut bs = Backstack::default();
|
||||||
assert_eq!(backstack.current(), &1);
|
bs.push(1);
|
||||||
|
assert_eq!(bs.stack[bs.cursor], 1);
|
||||||
|
|
||||||
backstack.push(2);
|
bs.push(2);
|
||||||
backstack.push(3);
|
bs.push(3);
|
||||||
assert_eq!(backstack.current(), &3);
|
assert_eq!(bs.stack[bs.cursor], 3);
|
||||||
|
|
||||||
assert_eq!(backstack.shift_backward(), Some(&2));
|
assert_eq!(bs.shift_backward(), Some(&2));
|
||||||
assert_eq!(backstack.shift_backward(), Some(&1));
|
assert_eq!(bs.shift_backward(), Some(&1));
|
||||||
assert_eq!(backstack.shift_backward(), None);
|
assert_eq!(bs.shift_backward(), None);
|
||||||
assert_eq!(backstack.shift_backward(), None);
|
assert_eq!(bs.shift_backward(), None);
|
||||||
assert_eq!(backstack.current(), &1);
|
assert_eq!(bs.stack[bs.cursor], 1);
|
||||||
assert_eq!(backstack.shift_forward(), Some(&2));
|
assert_eq!(bs.shift_forward(), Some(&2));
|
||||||
assert_eq!(backstack.shift_forward(), Some(&3));
|
assert_eq!(bs.shift_forward(), Some(&3));
|
||||||
assert_eq!(backstack.shift_forward(), None);
|
assert_eq!(bs.shift_forward(), None);
|
||||||
|
|
||||||
backstack.shift_backward();
|
bs.shift_backward();
|
||||||
backstack.push(4);
|
bs.push(4);
|
||||||
|
|
||||||
assert_eq!(backstack.current(), &4);
|
assert_eq!(bs.stack[bs.cursor], 4);
|
||||||
assert_eq!(backstack.shift_forward(), None);
|
assert_eq!(bs.shift_forward(), None);
|
||||||
assert_eq!(backstack.shift_backward(), Some(&2));
|
assert_eq!(bs.shift_backward(), Some(&2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ use yazi_shared::{fs::Url, render};
|
||||||
use super::{Backstack, Config, Finder, Mode, Preview};
|
use super::{Backstack, Config, Finder, Mode, Preview};
|
||||||
use crate::{folder::{Folder, FolderStage}, tab::Selected};
|
use crate::{folder::{Folder, FolderStage}, tab::Selected};
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
pub struct Tab {
|
pub struct Tab {
|
||||||
pub idx: usize,
|
pub idx: usize,
|
||||||
pub mode: Mode,
|
pub mode: Mode,
|
||||||
|
|
@ -23,33 +24,6 @@ pub struct Tab {
|
||||||
pub(super) search: Option<JoinHandle<Result<()>>>,
|
pub(super) search: Option<JoinHandle<Result<()>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Url> for Tab {
|
|
||||||
fn from(url: Url) -> Self {
|
|
||||||
let parent = url.parent_url().map(Folder::from);
|
|
||||||
|
|
||||||
Self {
|
|
||||||
idx: 0,
|
|
||||||
mode: Default::default(),
|
|
||||||
current: Folder::from(url.clone()),
|
|
||||||
parent,
|
|
||||||
|
|
||||||
backstack: Backstack::new(url),
|
|
||||||
history: Default::default(),
|
|
||||||
selected: Default::default(),
|
|
||||||
|
|
||||||
preview: Default::default(),
|
|
||||||
finder: None,
|
|
||||||
search: None,
|
|
||||||
|
|
||||||
conf: Default::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&Url> for Tab {
|
|
||||||
fn from(url: &Url) -> Self { Self::from(url.clone()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Tab {
|
impl Tab {
|
||||||
pub fn shutdown(&mut self) {
|
pub fn shutdown(&mut self) {
|
||||||
if let Some(handle) = self.search.take() {
|
if let Some(handle) = self.search.take() {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use anyhow::Result;
|
||||||
use mlua::{ExternalResult, IntoLua, Lua, Value};
|
use mlua::{ExternalResult, IntoLua, Lua, Value};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::{BodyBulk, BodyCd, BodyCustom, BodyHey, BodyHi, BodyHover, BodyRename, BodyTabs, BodyYank};
|
use super::{BodyBulk, BodyCd, BodyCustom, BodyHey, BodyHi, BodyHover, BodyRename, BodyYank};
|
||||||
use crate::Payload;
|
use crate::Payload;
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
|
@ -10,7 +10,6 @@ use crate::Payload;
|
||||||
pub enum Body<'a> {
|
pub enum Body<'a> {
|
||||||
Hi(BodyHi<'a>),
|
Hi(BodyHi<'a>),
|
||||||
Hey(BodyHey),
|
Hey(BodyHey),
|
||||||
Tabs(BodyTabs<'a>),
|
|
||||||
Cd(BodyCd<'a>),
|
Cd(BodyCd<'a>),
|
||||||
Hover(BodyHover<'a>),
|
Hover(BodyHover<'a>),
|
||||||
Rename(BodyRename<'a>),
|
Rename(BodyRename<'a>),
|
||||||
|
|
@ -24,7 +23,6 @@ impl<'a> Body<'a> {
|
||||||
Ok(match kind {
|
Ok(match kind {
|
||||||
"hi" => Body::Hi(serde_json::from_str(body)?),
|
"hi" => Body::Hi(serde_json::from_str(body)?),
|
||||||
"hey" => Body::Hey(serde_json::from_str(body)?),
|
"hey" => Body::Hey(serde_json::from_str(body)?),
|
||||||
"tabs" => Body::Tabs(serde_json::from_str(body)?),
|
|
||||||
"cd" => Body::Cd(serde_json::from_str(body)?),
|
"cd" => Body::Cd(serde_json::from_str(body)?),
|
||||||
"hover" => Body::Hover(serde_json::from_str(body)?),
|
"hover" => Body::Hover(serde_json::from_str(body)?),
|
||||||
"rename" => Body::Rename(serde_json::from_str(body)?),
|
"rename" => Body::Rename(serde_json::from_str(body)?),
|
||||||
|
|
@ -36,7 +34,7 @@ impl<'a> Body<'a> {
|
||||||
|
|
||||||
pub fn from_lua(kind: &str, value: Value) -> Result<Self> {
|
pub fn from_lua(kind: &str, value: Value) -> Result<Self> {
|
||||||
Ok(match kind {
|
Ok(match kind {
|
||||||
"hi" | "hey" | "tabs" | "cd" | "hover" | "rename" | "bulk" | "yank" => {
|
"hi" | "hey" | "cd" | "hover" | "rename" | "bulk" | "yank" => {
|
||||||
Err("Cannot construct system event from Lua").into_lua_err()?
|
Err("Cannot construct system event from Lua").into_lua_err()?
|
||||||
}
|
}
|
||||||
_ => BodyCustom::from_lua(kind, value)?,
|
_ => BodyCustom::from_lua(kind, value)?,
|
||||||
|
|
@ -48,7 +46,6 @@ impl<'a> Body<'a> {
|
||||||
match self {
|
match self {
|
||||||
Self::Hi(_) => "hi",
|
Self::Hi(_) => "hi",
|
||||||
Self::Hey(_) => "hey",
|
Self::Hey(_) => "hey",
|
||||||
Self::Tabs(_) => "tabs",
|
|
||||||
Self::Cd(_) => "cd",
|
Self::Cd(_) => "cd",
|
||||||
Self::Hover(_) => "hover",
|
Self::Hover(_) => "hover",
|
||||||
Self::Rename(_) => "rename",
|
Self::Rename(_) => "rename",
|
||||||
|
|
@ -73,18 +70,13 @@ impl<'a> Body<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn upgrade(self) -> Payload<'a> {
|
#[inline]
|
||||||
let severity = match self {
|
pub fn with_receiver(self, receiver: u64) -> Payload<'a> {
|
||||||
Body::Hi(_) => 0,
|
Payload::new(self).with_receiver(receiver)
|
||||||
Body::Hey(_) => 0,
|
}
|
||||||
Body::Tabs(_) => 10,
|
|
||||||
Body::Cd(_) => 20,
|
#[inline]
|
||||||
Body::Hover(_) => 30,
|
pub fn with_severity(self, severity: u8) -> Payload<'a> {
|
||||||
Body::Rename(_) => 0,
|
|
||||||
Body::Bulk(_) => 0,
|
|
||||||
Body::Yank(_) => 40,
|
|
||||||
Body::Custom(_) => 0,
|
|
||||||
};
|
|
||||||
Payload::new(self).with_severity(severity)
|
Payload::new(self).with_severity(severity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -94,7 +86,6 @@ impl IntoLua<'_> for Body<'static> {
|
||||||
match self {
|
match self {
|
||||||
Body::Hi(b) => b.into_lua(lua),
|
Body::Hi(b) => b.into_lua(lua),
|
||||||
Body::Hey(b) => b.into_lua(lua),
|
Body::Hey(b) => b.into_lua(lua),
|
||||||
Body::Tabs(b) => b.into_lua(lua),
|
|
||||||
Body::Cd(b) => b.into_lua(lua),
|
Body::Cd(b) => b.into_lua(lua),
|
||||||
Body::Hover(b) => b.into_lua(lua),
|
Body::Hover(b) => b.into_lua(lua),
|
||||||
Body::Rename(b) => b.into_lua(lua),
|
Body::Rename(b) => b.into_lua(lua),
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ mod hey;
|
||||||
mod hi;
|
mod hi;
|
||||||
mod hover;
|
mod hover;
|
||||||
mod rename;
|
mod rename;
|
||||||
mod tabs;
|
|
||||||
mod yank;
|
mod yank;
|
||||||
|
|
||||||
pub use body::*;
|
pub use body::*;
|
||||||
|
|
@ -19,5 +18,4 @@ pub use hey::*;
|
||||||
pub use hi::*;
|
pub use hi::*;
|
||||||
pub use hover::*;
|
pub use hover::*;
|
||||||
pub use rename::*;
|
pub use rename::*;
|
||||||
pub use tabs::*;
|
|
||||||
pub use yank::*;
|
pub use yank::*;
|
||||||
|
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
use std::borrow::Cow;
|
|
||||||
|
|
||||||
use mlua::{MetaMethod, UserData};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use yazi_shared::fs::Url;
|
|
||||||
|
|
||||||
use super::Body;
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
|
||||||
pub struct BodyTabs<'a> {
|
|
||||||
pub cursor: usize,
|
|
||||||
pub items: Vec<BodyTabsItem<'a>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> BodyTabs<'a> {
|
|
||||||
#[inline]
|
|
||||||
pub fn borrowed(cursor: usize, urls: &[&'a Url]) -> Body<'a> {
|
|
||||||
Self { cursor, items: urls.iter().map(|&u| BodyTabsItem::from(u)).collect() }.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BodyTabs<'static> {
|
|
||||||
#[inline]
|
|
||||||
pub fn dummy(cursor: usize) -> Body<'static> { Self { cursor, items: Default::default() }.into() }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<BodyTabs<'a>> for Body<'a> {
|
|
||||||
fn from(value: BodyTabs<'a>) -> Self { Self::Tabs(value) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UserData for BodyTabs<'static> {
|
|
||||||
fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) {
|
|
||||||
fields.add_field_method_get("cursor", |_, me| Ok(me.cursor));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
|
|
||||||
methods.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.items.len()));
|
|
||||||
|
|
||||||
methods.add_meta_method(MetaMethod::Index, |_, me, idx: usize| {
|
|
||||||
if idx > me.items.len() || idx == 0 { Ok(None) } else { Ok(Some(me.items[idx - 1].clone())) }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Item
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
||||||
pub struct BodyTabsItem<'a> {
|
|
||||||
pub url: Cow<'a, Url>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<&'a Url> for BodyTabsItem<'a> {
|
|
||||||
fn from(value: &'a Url) -> Self { Self { url: Cow::Borrowed(value) } }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UserData for BodyTabsItem<'static> {
|
|
||||||
fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) {
|
|
||||||
fields.add_field_method_get("url", |lua, me| lua.create_any_userdata(me.url.clone()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -10,18 +10,22 @@ use super::Body;
|
||||||
pub struct BodyYank<'a> {
|
pub struct BodyYank<'a> {
|
||||||
pub cut: bool,
|
pub cut: bool,
|
||||||
pub urls: Cow<'a, HashSet<Url>>,
|
pub urls: Cow<'a, HashSet<Url>>,
|
||||||
|
#[serde(skip)]
|
||||||
|
dummy: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> BodyYank<'a> {
|
impl<'a> BodyYank<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn borrowed(cut: bool, urls: &'a HashSet<Url>) -> Body<'a> {
|
pub fn borrowed(cut: bool, urls: &'a HashSet<Url>) -> Body<'a> {
|
||||||
Self { cut, urls: Cow::Borrowed(urls) }.into()
|
Self { cut, urls: Cow::Borrowed(urls), dummy: false }.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BodyYank<'static> {
|
impl BodyYank<'static> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn dummy(cut: bool) -> Body<'static> { Self { cut, urls: Default::default() }.into() }
|
pub fn dummy(cut: bool) -> Body<'static> {
|
||||||
|
Self { cut, urls: Default::default(), dummy: true }.into()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<BodyYank<'a>> for Body<'a> {
|
impl<'a> From<BodyYank<'a>> for Body<'a> {
|
||||||
|
|
@ -30,7 +34,7 @@ impl<'a> From<BodyYank<'a>> for Body<'a> {
|
||||||
|
|
||||||
impl IntoLua<'_> for BodyYank<'static> {
|
impl IntoLua<'_> for BodyYank<'static> {
|
||||||
fn into_lua(self, lua: &Lua) -> mlua::Result<Value<'_>> {
|
fn into_lua(self, lua: &Lua) -> mlua::Result<Value<'_>> {
|
||||||
if let Cow::Owned(urls) = self.urls {
|
if let Some(Cow::Owned(urls)) = Some(self.urls).filter(|_| !self.dummy) {
|
||||||
BodyYankIter { cut: self.cut, urls: urls.into_iter().collect() }.into_lua(lua)
|
BodyYankIter { cut: self.cut, urls: urls.into_iter().collect() }.into_lua(lua)
|
||||||
} else {
|
} else {
|
||||||
lua.create_table_from([("cut", self.cut)])?.into_lua(lua)
|
lua.create_table_from([("cut", self.cut)])?.into_lua(lua)
|
||||||
|
|
@ -46,7 +50,7 @@ pub struct BodyYankIter {
|
||||||
|
|
||||||
impl UserData for BodyYankIter {
|
impl UserData for BodyYankIter {
|
||||||
fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) {
|
fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) {
|
||||||
fields.add_field_method_get("is_cut", |_, me| Ok(me.cut));
|
fields.add_field_method_get("cut", |_, me| Ok(me.cut));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
|
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ impl Client {
|
||||||
if line.starts_with("hey,") {
|
if line.starts_with("hey,") {
|
||||||
Self::handle_hey(line);
|
Self::handle_hey(line);
|
||||||
} else {
|
} else {
|
||||||
Payload::from_str(&line).map(|p| p.flush(false).emit()).ok();
|
Payload::from_str(&line).map(|p| p.emit()).ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -62,7 +62,9 @@ impl Client {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super) fn push(payload: Payload) { QUEUE.send(format!("{}\n", payload)).ok(); }
|
pub(super) fn push<'a>(payload: impl Into<Payload<'a>>) {
|
||||||
|
QUEUE.send(format!("{}\n", payload.into())).ok();
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super) fn able(&self, ability: &str) -> bool { self.abilities.contains(ability) }
|
pub(super) fn able(&self, ability: &str) -> bool { self.abilities.contains(ability) }
|
||||||
|
|
|
||||||
|
|
@ -15,40 +15,38 @@ pub struct Payload<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Payload<'a> {
|
impl<'a> Payload<'a> {
|
||||||
#[inline]
|
|
||||||
pub(super) fn new(body: Body<'a>) -> Self { Self { receiver: 0, severity: 0, sender: *ID, body } }
|
pub(super) fn new(body: Body<'a>) -> Self { Self { receiver: 0, severity: 0, sender: *ID, body } }
|
||||||
|
|
||||||
#[inline]
|
pub(super) fn flush(&self) { writeln!(std::io::stdout(), "{self}").ok(); }
|
||||||
|
|
||||||
|
pub(super) fn try_flush(&self) {
|
||||||
|
let b = if self.receiver == 0 {
|
||||||
|
BOOT.remote_events.contains(self.body.kind())
|
||||||
|
} else if let Body::Custom(b) = &self.body {
|
||||||
|
BOOT.local_events.contains(&b.kind)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
|
if b {
|
||||||
|
self.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn with_receiver(mut self, receiver: u64) -> Self {
|
pub(super) fn with_receiver(mut self, receiver: u64) -> Self {
|
||||||
self.receiver = receiver;
|
self.receiver = receiver;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub(super) fn with_severity(mut self, severity: u8) -> Self {
|
pub(super) fn with_severity(mut self, severity: u8) -> Self {
|
||||||
self.severity = severity;
|
self.severity = severity;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn flush(self, force: bool) -> Self {
|
|
||||||
let b = force
|
|
||||||
|| if self.receiver == 0 {
|
|
||||||
BOOT.remote_events.contains(self.body.kind())
|
|
||||||
} else if let Body::Custom(b) = &self.body {
|
|
||||||
BOOT.local_events.contains(&b.kind)
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
};
|
|
||||||
|
|
||||||
if b {
|
|
||||||
writeln!(std::io::stdout(), "{self}").ok();
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Payload<'static> {
|
impl Payload<'static> {
|
||||||
pub(super) fn emit(self) {
|
pub(super) fn emit(self) {
|
||||||
|
self.try_flush();
|
||||||
emit!(Call(Cmd::new("accept_payload").with_data(self), Layer::App));
|
emit!(Call(Cmd::new("accept_payload").with_data(self), Layer::App));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -76,12 +74,15 @@ impl FromStr for Payload<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> From<Body<'a>> for Payload<'a> {
|
||||||
|
fn from(value: Body<'a>) -> Self { Self::new(value) }
|
||||||
|
}
|
||||||
|
|
||||||
impl Display for Payload<'_> {
|
impl Display for Payload<'_> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let result = match &self.body {
|
let result = match &self.body {
|
||||||
Body::Hi(b) => serde_json::to_string(b),
|
Body::Hi(b) => serde_json::to_string(b),
|
||||||
Body::Hey(b) => serde_json::to_string(b),
|
Body::Hey(b) => serde_json::to_string(b),
|
||||||
Body::Tabs(b) => serde_json::to_string(b),
|
|
||||||
Body::Cd(b) => serde_json::to_string(b),
|
Body::Cd(b) => serde_json::to_string(b),
|
||||||
Body::Hover(b) => serde_json::to_string(b),
|
Body::Hover(b) => serde_json::to_string(b),
|
||||||
Body::Rename(b) => serde_json::to_string(b),
|
Body::Rename(b) => serde_json::to_string(b),
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use parking_lot::RwLock;
|
||||||
use yazi_boot::BOOT;
|
use yazi_boot::BOOT;
|
||||||
use yazi_shared::{fs::Url, RoCell};
|
use yazi_shared::{fs::Url, RoCell};
|
||||||
|
|
||||||
use crate::{body::{Body, BodyCd, BodyHi, BodyHover, BodyRename, BodyTabs, BodyYank}, Client, ID, PEERS};
|
use crate::{body::{Body, BodyCd, BodyHi, BodyHover, BodyRename, BodyYank}, Client, ID, PEERS};
|
||||||
|
|
||||||
pub static LOCAL: RoCell<RwLock<HashMap<String, HashMap<String, Function<'static>>>>> =
|
pub static LOCAL: RoCell<RwLock<HashMap<String, HashMap<String, Function<'static>>>>> =
|
||||||
RoCell::new();
|
RoCell::new();
|
||||||
|
|
@ -65,7 +65,7 @@ impl Pubsub {
|
||||||
unsub!(REMOTE)(plugin, kind) && Self::pub_from_hi()
|
unsub!(REMOTE)(plugin, kind) && Self::pub_from_hi()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pub_(body: Body<'static>) { body.upgrade().with_receiver(*ID).flush(false).emit(); }
|
pub fn pub_(body: Body<'static>) { body.with_receiver(*ID).emit(); }
|
||||||
|
|
||||||
pub fn pub_to(receiver: u64, body: Body<'static>) {
|
pub fn pub_to(receiver: u64, body: Body<'static>) {
|
||||||
if receiver == *ID {
|
if receiver == *ID {
|
||||||
|
|
@ -74,16 +74,16 @@ impl Pubsub {
|
||||||
|
|
||||||
let (kind, peers) = (body.kind(), PEERS.read());
|
let (kind, peers) = (body.kind(), PEERS.read());
|
||||||
if receiver == 0 && peers.values().any(|c| c.able(kind)) {
|
if receiver == 0 && peers.values().any(|c| c.able(kind)) {
|
||||||
Client::push(body.upgrade());
|
Client::push(body);
|
||||||
} else if peers.get(&receiver).is_some_and(|c| c.able(kind)) {
|
} else if peers.get(&receiver).is_some_and(|c| c.able(kind)) {
|
||||||
Client::push(body.upgrade().with_receiver(receiver));
|
Client::push(body.with_receiver(receiver));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pub_static(severity: u8, body: Body) {
|
pub fn pub_static(severity: u8, body: Body) {
|
||||||
let (kind, peers) = (body.kind(), PEERS.read());
|
let (kind, peers) = (body.kind(), PEERS.read());
|
||||||
if peers.values().any(|c| c.able(kind)) {
|
if peers.values().any(|c| c.able(kind)) {
|
||||||
Client::push(body.upgrade().with_severity(severity));
|
Client::push(body.with_severity(severity));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,31 +91,19 @@ impl Pubsub {
|
||||||
let abilities = REMOTE.read().keys().cloned().collect();
|
let abilities = REMOTE.read().keys().cloned().collect();
|
||||||
let abilities = BOOT.remote_events.union(&abilities).collect();
|
let abilities = BOOT.remote_events.union(&abilities).collect();
|
||||||
|
|
||||||
Client::push(BodyHi::borrowed(abilities).upgrade());
|
Client::push(BodyHi::borrowed(abilities));
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pub_from_tabs(tab: usize, urls: &[&Url]) {
|
|
||||||
if LOCAL.read().contains_key("tabs") {
|
|
||||||
Self::pub_(BodyTabs::dummy(tab));
|
|
||||||
}
|
|
||||||
if PEERS.read().values().any(|p| p.able("tabs")) {
|
|
||||||
Client::push(BodyTabs::borrowed(tab, urls).upgrade());
|
|
||||||
}
|
|
||||||
if BOOT.local_events.contains("tabs") {
|
|
||||||
BodyTabs::borrowed(tab, urls).upgrade().with_receiver(*ID).flush(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn pub_from_cd(tab: usize, url: &Url) {
|
pub fn pub_from_cd(tab: usize, url: &Url) {
|
||||||
if LOCAL.read().contains_key("cd") {
|
if LOCAL.read().contains_key("cd") {
|
||||||
Self::pub_(BodyCd::dummy(tab));
|
Self::pub_(BodyCd::dummy(tab));
|
||||||
}
|
}
|
||||||
if PEERS.read().values().any(|p| p.able("cd")) {
|
if PEERS.read().values().any(|p| p.able("cd")) {
|
||||||
Client::push(BodyCd::borrowed(tab, url).upgrade());
|
Client::push(BodyCd::borrowed(tab, url).with_severity(10));
|
||||||
}
|
}
|
||||||
if BOOT.local_events.contains("cd") {
|
if BOOT.local_events.contains("cd") {
|
||||||
BodyCd::borrowed(tab, url).upgrade().with_receiver(*ID).flush(true);
|
BodyCd::borrowed(tab, url).with_receiver(*ID).flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,10 +112,10 @@ impl Pubsub {
|
||||||
Self::pub_(BodyHover::dummy(tab));
|
Self::pub_(BodyHover::dummy(tab));
|
||||||
}
|
}
|
||||||
if PEERS.read().values().any(|p| p.able("hover")) {
|
if PEERS.read().values().any(|p| p.able("hover")) {
|
||||||
Client::push(BodyHover::borrowed(tab, url).upgrade());
|
Client::push(BodyHover::borrowed(tab, url).with_severity(20));
|
||||||
}
|
}
|
||||||
if BOOT.local_events.contains("hover") {
|
if BOOT.local_events.contains("hover") {
|
||||||
BodyHover::borrowed(tab, url).upgrade().with_receiver(*ID).flush(true);
|
BodyHover::borrowed(tab, url).with_receiver(*ID).flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,10 +124,10 @@ impl Pubsub {
|
||||||
Self::pub_(BodyRename::dummy(tab, from, to));
|
Self::pub_(BodyRename::dummy(tab, from, to));
|
||||||
}
|
}
|
||||||
if PEERS.read().values().any(|p| p.able("rename")) {
|
if PEERS.read().values().any(|p| p.able("rename")) {
|
||||||
Client::push(BodyRename::borrowed(tab, from, to).upgrade());
|
Client::push(BodyRename::borrowed(tab, from, to));
|
||||||
}
|
}
|
||||||
if BOOT.local_events.contains("rename") {
|
if BOOT.local_events.contains("rename") {
|
||||||
BodyRename::borrowed(tab, from, to).upgrade().with_receiver(*ID).flush(true);
|
BodyRename::borrowed(tab, from, to).with_receiver(*ID).flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -148,10 +136,10 @@ impl Pubsub {
|
||||||
Self::pub_(BodyYank::dummy(cut));
|
Self::pub_(BodyYank::dummy(cut));
|
||||||
}
|
}
|
||||||
if PEERS.read().values().any(|p| p.able("yank")) {
|
if PEERS.read().values().any(|p| p.able("yank")) {
|
||||||
Client::push(BodyYank::borrowed(cut, urls).upgrade());
|
Client::push(BodyYank::borrowed(cut, urls).with_severity(30));
|
||||||
}
|
}
|
||||||
if BOOT.local_events.contains("yank") {
|
if BOOT.local_events.contains("yank") {
|
||||||
BodyYank::borrowed(cut, urls).upgrade().with_receiver(*ID).flush(true);
|
BodyYank::borrowed(cut, urls).with_receiver(*ID).flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue