mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
fix: directories are recreated after deletion did not update the watcher tracking properly (#381)
This commit is contained in:
parent
a6f76400f8
commit
ac039c628e
24 changed files with 181 additions and 118 deletions
29
Cargo.lock
generated
29
Cargo.lock
generated
|
|
@ -557,9 +557,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.6"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c18ee0ed65a5f1f81cac6b1d213b69c35fa47d4252ad41f1486dbd8226fe36e"
|
||||
checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.48.0",
|
||||
|
|
@ -1576,9 +1576,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
|||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.21"
|
||||
version = "0.38.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3"
|
||||
checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"errno",
|
||||
|
|
@ -2017,11 +2017,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tracing-appender"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e"
|
||||
checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
|
@ -2049,9 +2050,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tracing-log"
|
||||
version = "0.1.4"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2"
|
||||
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
|
||||
dependencies = [
|
||||
"log",
|
||||
"once_cell",
|
||||
|
|
@ -2060,9 +2061,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.17"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77"
|
||||
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
|
||||
dependencies = [
|
||||
"nu-ansi-term",
|
||||
"sharded-slab",
|
||||
|
|
@ -2608,18 +2609,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.25"
|
||||
version = "0.7.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cd369a67c0edfef15010f980c3cbe45d7f651deac2cd67ce097cd801de16557"
|
||||
checksum = "e97e415490559a91254a2979b4829267a57d2fcd741a98eee8b722fb57289aa0"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.25"
|
||||
version = "0.7.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2f140bda219a26ccc0cdb03dba58af72590c53b22642577d88a927bc5c87d6b"
|
||||
checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use yazi_config::keymap::{Exec, KeymapLayer};
|
||||
|
||||
use crate::{completion::Completion, emit};
|
||||
use crate::{completion::Completion, emit, input::Input};
|
||||
|
||||
pub struct Opt {
|
||||
submit: bool,
|
||||
|
|
@ -11,13 +11,15 @@ impl From<&Exec> for Opt {
|
|||
}
|
||||
|
||||
impl Completion {
|
||||
#[inline]
|
||||
pub fn _close() {
|
||||
emit!(Call(Exec::call("close", vec![]).vec(), KeymapLayer::Completion));
|
||||
}
|
||||
|
||||
pub fn close(&mut self, opt: impl Into<Opt>) -> bool {
|
||||
let opt = opt.into() as Opt;
|
||||
if opt.submit {
|
||||
emit!(Call(
|
||||
Exec::call("complete", vec![self.selected().into()]).with("ticket", self.ticket).vec(),
|
||||
KeymapLayer::Input
|
||||
));
|
||||
Input::_complete(self.selected(), self.ticket);
|
||||
}
|
||||
|
||||
self.caches.clear();
|
||||
|
|
|
|||
|
|
@ -6,14 +6,14 @@ use yazi_config::keymap::{Exec, KeymapLayer};
|
|||
use crate::{completion::Completion, emit};
|
||||
|
||||
pub struct Opt<'a> {
|
||||
before: &'a str,
|
||||
word: &'a str,
|
||||
ticket: usize,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Exec> for Opt<'a> {
|
||||
fn from(e: &'a Exec) -> Self {
|
||||
Self {
|
||||
before: e.named.get("before").map(|s| s.as_str()).unwrap_or_default(),
|
||||
word: e.args.first().map(|s| s.as_str()).unwrap_or_default(),
|
||||
ticket: e.named.get("ticket").and_then(|s| s.parse().ok()).unwrap_or(0),
|
||||
}
|
||||
}
|
||||
|
|
@ -21,11 +21,11 @@ impl<'a> From<&'a Exec> for Opt<'a> {
|
|||
|
||||
impl Completion {
|
||||
#[inline]
|
||||
fn split_path(s: &str) -> (String, String) {
|
||||
match s.rsplit_once(MAIN_SEPARATOR) {
|
||||
Some((p, c)) => (format!("{p}{}", MAIN_SEPARATOR), c.to_owned()),
|
||||
None => (".".to_owned(), s.to_owned()),
|
||||
}
|
||||
pub fn _trigger(word: &str, ticket: usize) {
|
||||
emit!(Call(
|
||||
Exec::call("trigger", vec![word.to_owned()]).with("ticket", ticket).vec(),
|
||||
KeymapLayer::Completion
|
||||
));
|
||||
}
|
||||
|
||||
pub fn trigger<'a>(&mut self, opt: impl Into<Opt<'a>>) -> bool {
|
||||
|
|
@ -35,7 +35,7 @@ impl Completion {
|
|||
}
|
||||
|
||||
self.ticket = opt.ticket;
|
||||
let (parent, child) = Self::split_path(opt.before);
|
||||
let (parent, child) = Self::split_path(opt.word);
|
||||
|
||||
if self.caches.contains_key(&parent) {
|
||||
return self.show(
|
||||
|
|
@ -78,6 +78,14 @@ impl Completion {
|
|||
|
||||
mem::replace(&mut self.visible, false)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn split_path(s: &str) -> (String, String) {
|
||||
match s.rsplit_once(MAIN_SEPARATOR) {
|
||||
Some((p, c)) => (format!("{p}{}", MAIN_SEPARATOR), c.to_owned()),
|
||||
None => (".".to_owned(), s.to_owned()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
|
|
@ -21,11 +21,9 @@ pub enum Event {
|
|||
Call(Vec<Exec>, KeymapLayer),
|
||||
|
||||
// Manager
|
||||
Refresh,
|
||||
Files(FilesOp),
|
||||
Pages(usize),
|
||||
Mimetype(BTreeMap<Url, String>),
|
||||
Hover(Option<Url>),
|
||||
Peek(Option<(usize, Url)>),
|
||||
Preview(PreviewLock),
|
||||
|
||||
|
|
@ -82,12 +80,6 @@ macro_rules! emit {
|
|||
(Mimetype($mimes:expr)) => {
|
||||
$crate::Event::Mimetype($mimes).emit();
|
||||
};
|
||||
(Hover) => {
|
||||
$crate::Event::Hover(None).emit();
|
||||
};
|
||||
(Hover($file:expr)) => {
|
||||
$crate::Event::Hover(Some($file)).emit();
|
||||
};
|
||||
(Peek) => {
|
||||
$crate::Event::Peek(None).emit();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use yazi_config::keymap::{Exec, KeymapLayer};
|
||||
use yazi_config::keymap::Exec;
|
||||
use yazi_shared::InputError;
|
||||
|
||||
use crate::{emit, input::Input};
|
||||
use crate::{completion::Completion, input::Input};
|
||||
|
||||
pub struct Opt {
|
||||
submit: bool,
|
||||
|
|
@ -19,7 +19,7 @@ impl Input {
|
|||
let opt = opt.into() as Opt;
|
||||
|
||||
if self.completion {
|
||||
emit!(Call(Exec::call("close", vec![]).vec(), KeymapLayer::Completion));
|
||||
Completion::_close();
|
||||
}
|
||||
|
||||
if let Some(cb) = self.callback.take() {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use std::path::MAIN_SEPARATOR;
|
||||
|
||||
use yazi_config::keymap::Exec;
|
||||
use yazi_config::keymap::{Exec, KeymapLayer};
|
||||
|
||||
use crate::input::Input;
|
||||
use crate::{emit, input::Input};
|
||||
|
||||
pub struct Opt<'a> {
|
||||
word: &'a str,
|
||||
|
|
@ -19,6 +19,14 @@ impl<'a> From<&'a Exec> for Opt<'a> {
|
|||
}
|
||||
|
||||
impl Input {
|
||||
#[inline]
|
||||
pub fn _complete(word: &str, ticket: usize) {
|
||||
emit!(Call(
|
||||
Exec::call("complete", vec![word.to_owned()]).with("ticket", ticket).vec(),
|
||||
KeymapLayer::Input
|
||||
));
|
||||
}
|
||||
|
||||
pub fn complete<'a>(&mut self, opt: impl Into<Opt<'a>>) -> bool {
|
||||
let opt = opt.into() as Opt;
|
||||
if self.ticket != opt.ticket {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use yazi_config::keymap::{Exec, KeymapLayer};
|
||||
use yazi_config::keymap::Exec;
|
||||
|
||||
use crate::{emit, input::{op::InputOp, Input, InputMode}};
|
||||
use crate::{completion::Completion, input::{op::InputOp, Input, InputMode}};
|
||||
|
||||
pub struct Opt;
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ impl Input {
|
|||
self.move_(-1);
|
||||
|
||||
if self.completion {
|
||||
emit!(Call(Exec::call("close", vec![]).vec(), KeymapLayer::Completion));
|
||||
Completion::_close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ impl Manager {
|
|||
Url::from(path.components().take(cwd.components().count() + 1).collect::<PathBuf>());
|
||||
if let Ok(f) = File::from(child.clone()).await {
|
||||
emit!(Files(FilesOp::Creating(cwd, f.into_map())));
|
||||
emit!(Hover(child));
|
||||
emit!(Refresh);
|
||||
Manager::_hover(Some(child));
|
||||
Manager::_refresh();
|
||||
}
|
||||
Ok::<(), anyhow::Error>(())
|
||||
});
|
||||
|
|
|
|||
47
yazi-core/src/manager/commands/hover.rs
Normal file
47
yazi-core/src/manager/commands/hover.rs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
use std::collections::BTreeSet;
|
||||
|
||||
use yazi_config::keymap::{Exec, KeymapLayer};
|
||||
use yazi_shared::Url;
|
||||
|
||||
use crate::{emit, manager::Manager};
|
||||
|
||||
pub struct Opt {
|
||||
url: Option<Url>,
|
||||
}
|
||||
|
||||
impl From<&Exec> for Opt {
|
||||
fn from(e: &Exec) -> Self { Self { url: e.args.first().map(Url::from) } }
|
||||
}
|
||||
|
||||
impl Manager {
|
||||
#[inline]
|
||||
pub fn _hover(url: Option<Url>) {
|
||||
emit!(Call(
|
||||
Exec::call("hover", url.map_or_else(Vec::new, |u| vec![u.to_string()])).vec(),
|
||||
KeymapLayer::Manager
|
||||
));
|
||||
}
|
||||
|
||||
pub fn hover(&mut self, opt: impl Into<Opt>) -> bool {
|
||||
// Refresh watcher
|
||||
let mut to_watch = BTreeSet::new();
|
||||
for tab in self.tabs.iter() {
|
||||
to_watch.insert(&tab.current.cwd);
|
||||
match tab.current.hovered() {
|
||||
Some(h) if h.is_dir() => _ = to_watch.insert(&h.url),
|
||||
_ => {}
|
||||
}
|
||||
if let Some(ref p) = tab.parent {
|
||||
to_watch.insert(&p.cwd);
|
||||
}
|
||||
}
|
||||
self.watcher.watch(to_watch);
|
||||
|
||||
// Trigger peek
|
||||
emit!(Peek);
|
||||
|
||||
// Hover
|
||||
let opt = opt.into() as Opt;
|
||||
self.current_mut().repos(opt.url)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
mod close;
|
||||
mod create;
|
||||
mod hover;
|
||||
mod link;
|
||||
mod open;
|
||||
mod paste;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,24 @@
|
|||
use std::{collections::BTreeSet, env};
|
||||
use std::env;
|
||||
|
||||
use yazi_config::keymap::{Exec, KeymapLayer};
|
||||
|
||||
use crate::{emit, manager::Manager};
|
||||
|
||||
pub struct Opt;
|
||||
|
||||
impl From<&Exec> for Opt {
|
||||
fn from(_: &Exec) -> Self { Self }
|
||||
}
|
||||
|
||||
impl Manager {
|
||||
pub fn refresh(&mut self) {
|
||||
#[inline]
|
||||
pub fn _refresh() {
|
||||
emit!(Call(Exec::call("refresh", vec![]).vec(), KeymapLayer::Manager));
|
||||
}
|
||||
|
||||
pub fn refresh(&mut self, _: impl Into<Opt>) -> bool {
|
||||
env::set_current_dir(self.cwd()).ok();
|
||||
env::set_var("PWD", self.cwd());
|
||||
|
||||
self.active_mut().apply_files_attrs(false);
|
||||
|
||||
|
|
@ -13,19 +27,8 @@ impl Manager {
|
|||
} else {
|
||||
self.watcher.trigger_dirs(&[self.cwd()]);
|
||||
}
|
||||
emit!(Hover);
|
||||
|
||||
let mut to_watch = BTreeSet::new();
|
||||
for tab in self.tabs.iter() {
|
||||
to_watch.insert(&tab.current.cwd);
|
||||
match tab.current.hovered() {
|
||||
Some(h) if h.is_dir() => _ = to_watch.insert(&h.url),
|
||||
_ => {}
|
||||
}
|
||||
if let Some(ref p) = tab.parent {
|
||||
to_watch.insert(&p.cwd);
|
||||
}
|
||||
}
|
||||
self.watcher.watch(to_watch);
|
||||
Self::_hover(None);
|
||||
false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ impl Manager {
|
|||
|
||||
let file = File::from(new.clone()).await?;
|
||||
emit!(Files(FilesOp::Creating(file.parent().unwrap(), file.into_map())));
|
||||
emit!(Hover(new));
|
||||
Self::_hover(Some(new));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::collections::{BTreeMap, HashMap, HashSet};
|
|||
use yazi_shared::Url;
|
||||
|
||||
use super::{Tabs, Watcher};
|
||||
use crate::{emit, files::{File, FilesOp}, tab::{Folder, Tab}, tasks::Tasks};
|
||||
use crate::{files::{File, FilesOp}, tab::{Folder, Tab}, tasks::Tasks};
|
||||
|
||||
pub struct Manager {
|
||||
pub tabs: Tabs,
|
||||
|
|
@ -46,7 +46,7 @@ impl Manager {
|
|||
b |= hovered.as_ref().is_some_and(|h| self.current_mut().hover(h));
|
||||
|
||||
if hovered.as_ref() != self.hovered().map(|h| &h.url) {
|
||||
emit!(Hover);
|
||||
Self::_hover(None);
|
||||
}
|
||||
b
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use yazi_config::BOOT;
|
||||
use yazi_shared::Url;
|
||||
|
||||
use crate::{emit, tab::Tab};
|
||||
use crate::{manager::Manager, tab::Tab};
|
||||
|
||||
pub struct Tabs {
|
||||
pub idx: usize,
|
||||
|
|
@ -32,7 +32,7 @@ impl Tabs {
|
|||
pub(super) fn set_idx(&mut self, idx: usize) {
|
||||
self.idx = idx;
|
||||
self.active_mut().preview.reset(|l| l.is_image());
|
||||
emit!(Refresh);
|
||||
Manager::_refresh();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -91,8 +91,8 @@ impl Watcher {
|
|||
*guard = watched
|
||||
.into_iter()
|
||||
.map(|k| {
|
||||
if let Some((k, v)) = guard.remove_entry(k) {
|
||||
(k, v)
|
||||
if let Some(old) = guard.remove_entry(k) {
|
||||
old
|
||||
} else {
|
||||
to_resolve.push(k.clone());
|
||||
(k.clone(), None)
|
||||
|
|
@ -102,17 +102,14 @@ impl Watcher {
|
|||
|
||||
let lock = self.watched.clone();
|
||||
tokio::spawn(async move {
|
||||
let mut ext = IndexMap::new();
|
||||
for k in to_resolve {
|
||||
match fs::canonicalize(&k).await {
|
||||
Ok(v) if v != *k => {
|
||||
ext.insert(k, Some(Url::from(v)));
|
||||
lock.write().insert(k, Some(Url::from(v)));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
lock.write().extend(ext);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use yazi_config::keymap::Exec;
|
||||
|
||||
use crate::{emit, tab::Tab, Step};
|
||||
use crate::{manager::Manager, tab::Tab, Step};
|
||||
|
||||
pub struct Opt {
|
||||
step: Step,
|
||||
|
|
@ -41,7 +41,7 @@ impl Tab {
|
|||
}
|
||||
}
|
||||
|
||||
emit!(Hover);
|
||||
Manager::_hover(None);
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};
|
|||
use yazi_config::{keymap::{Exec, KeymapLayer}, popup::InputOpt};
|
||||
use yazi_shared::{expand_path, Debounce, InputError, Url};
|
||||
|
||||
use crate::{emit, tab::Tab};
|
||||
use crate::{completion::Completion, emit, manager::Manager, tab::Tab};
|
||||
|
||||
pub struct Opt {
|
||||
target: Url,
|
||||
|
|
@ -27,6 +27,11 @@ impl From<Url> for Opt {
|
|||
}
|
||||
|
||||
impl Tab {
|
||||
#[inline]
|
||||
pub fn _cd(target: &Url) {
|
||||
emit!(Call(Exec::call("cd", vec![target.to_string()]).vec(), KeymapLayer::Manager));
|
||||
}
|
||||
|
||||
pub fn cd(&mut self, opt: impl Into<Opt>) -> bool {
|
||||
let opt = opt.into() as Opt;
|
||||
if opt.interactive {
|
||||
|
|
@ -59,7 +64,7 @@ impl Tab {
|
|||
self.backstack.push(opt.target.clone());
|
||||
}
|
||||
|
||||
emit!(Refresh);
|
||||
Manager::_refresh();
|
||||
true
|
||||
}
|
||||
|
||||
|
|
@ -75,24 +80,19 @@ impl Tab {
|
|||
while let Some(result) = rx.next().await {
|
||||
match result {
|
||||
Ok(s) => {
|
||||
let p = expand_path(s);
|
||||
let Ok(meta) = fs::metadata(&p).await else {
|
||||
let u = Url::from(expand_path(s));
|
||||
let Ok(meta) = fs::metadata(&u).await else {
|
||||
return;
|
||||
};
|
||||
|
||||
emit!(Call(
|
||||
Exec::call(if meta.is_dir() { "cd" } else { "reveal" }, vec![
|
||||
p.to_string_lossy().to_string()
|
||||
])
|
||||
.vec(),
|
||||
KeymapLayer::Manager
|
||||
));
|
||||
if meta.is_dir() {
|
||||
Tab::_cd(&u);
|
||||
} else {
|
||||
Tab::_reveal(&u);
|
||||
}
|
||||
}
|
||||
Err(InputError::Completed(before, ticket)) => {
|
||||
emit!(Call(
|
||||
Exec::call("complete", vec![]).with("before", before).with("ticket", ticket).vec(),
|
||||
KeymapLayer::Input
|
||||
));
|
||||
Completion::_trigger(&before, ticket);
|
||||
}
|
||||
_ => break,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::mem;
|
|||
|
||||
use yazi_config::keymap::Exec;
|
||||
|
||||
use crate::{emit, tab::Tab};
|
||||
use crate::{manager::Manager, tab::Tab};
|
||||
|
||||
pub struct Opt;
|
||||
impl From<()> for Opt {
|
||||
|
|
@ -34,7 +34,7 @@ impl Tab {
|
|||
// Backstack
|
||||
self.backstack.push(hovered);
|
||||
|
||||
emit!(Refresh);
|
||||
Manager::_refresh();
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use yazi_config::keymap::{Exec, KeymapLayer};
|
||||
use yazi_config::keymap::Exec;
|
||||
use yazi_shared::{ends_with_slash, Defer};
|
||||
|
||||
use crate::{emit, external::{self, FzfOpt, ZoxideOpt}, tab::Tab, Event, BLOCKER};
|
||||
|
|
@ -39,15 +39,21 @@ impl Tab {
|
|||
let _defer = Defer::new(|| Event::Stop(false, None).emit());
|
||||
emit!(Stop(true)).await;
|
||||
|
||||
let url = if opt.type_ == OptType::Fzf {
|
||||
let result = if opt.type_ == OptType::Fzf {
|
||||
external::fzf(FzfOpt { cwd }).await
|
||||
} else {
|
||||
external::zoxide(ZoxideOpt { cwd }).await
|
||||
}?;
|
||||
};
|
||||
|
||||
let op = if opt.type_ == OptType::Fzf && !ends_with_slash(&url) { "reveal" } else { "cd" };
|
||||
emit!(Call(Exec::call(op, vec![url.to_string()]).vec(), KeymapLayer::Manager));
|
||||
Ok::<(), anyhow::Error>(())
|
||||
let Ok(url) = result else {
|
||||
return;
|
||||
};
|
||||
|
||||
if opt.type_ == OptType::Fzf && !ends_with_slash(&url) {
|
||||
Tab::_reveal(&url)
|
||||
} else {
|
||||
Tab::_cd(&url)
|
||||
}
|
||||
});
|
||||
false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::mem;
|
|||
|
||||
use yazi_config::keymap::Exec;
|
||||
|
||||
use crate::{emit, tab::Tab};
|
||||
use crate::{manager::Manager, tab::Tab};
|
||||
|
||||
pub struct Opt;
|
||||
impl From<()> for Opt {
|
||||
|
|
@ -43,7 +43,7 @@ impl Tab {
|
|||
// Backstack
|
||||
self.backstack.push(current);
|
||||
|
||||
emit!(Refresh);
|
||||
Manager::_refresh();
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use yazi_config::keymap::Exec;
|
||||
use yazi_config::keymap::{Exec, KeymapLayer};
|
||||
use yazi_shared::{expand_path, Url};
|
||||
|
||||
use crate::{emit, files::{File, FilesOp}, tab::Tab};
|
||||
use crate::{emit, files::{File, FilesOp}, manager::Manager, tab::Tab};
|
||||
|
||||
pub struct Opt {
|
||||
target: Url,
|
||||
|
|
@ -22,6 +22,11 @@ impl From<Url> for Opt {
|
|||
}
|
||||
|
||||
impl Tab {
|
||||
#[inline]
|
||||
pub fn _reveal(target: &Url) {
|
||||
emit!(Call(Exec::call("reveal", vec![target.to_string()]).vec(), KeymapLayer::Manager));
|
||||
}
|
||||
|
||||
pub fn reveal(&mut self, opt: impl Into<Opt>) -> bool {
|
||||
let opt = opt.into() as Opt;
|
||||
|
||||
|
|
@ -34,7 +39,7 @@ impl Tab {
|
|||
parent.clone(),
|
||||
File::from_dummy(opt.target.clone()).into_map()
|
||||
)));
|
||||
emit!(Hover(opt.target));
|
||||
Manager::_hover(Some(opt.target));
|
||||
b
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ use std::{mem, time::Duration};
|
|||
use anyhow::bail;
|
||||
use tokio::pin;
|
||||
use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};
|
||||
use yazi_config::{keymap::{Exec, KeymapLayer}, popup::InputOpt};
|
||||
use yazi_config::{keymap::Exec, popup::InputOpt};
|
||||
|
||||
use crate::{emit, external, files::FilesOp, tab::Tab};
|
||||
use crate::{emit, external, files::FilesOp, manager::Manager, tab::Tab};
|
||||
|
||||
pub struct Opt {
|
||||
pub type_: OptType,
|
||||
|
|
@ -61,7 +61,7 @@ impl Tab {
|
|||
let mut first = true;
|
||||
while let Some(chunk) = rx.next().await {
|
||||
if first {
|
||||
emit!(Call(Exec::call("cd", vec![cwd.clone().to_string()]).vec(), KeymapLayer::Manager));
|
||||
Tab::_cd(&cwd);
|
||||
first = false;
|
||||
}
|
||||
emit!(Files(FilesOp::Part(cwd.clone(), ticket, chunk)));
|
||||
|
|
@ -80,7 +80,7 @@ impl Tab {
|
|||
|
||||
let rep = self.history_new(&self.current.cwd.to_regular());
|
||||
drop(mem::replace(&mut self.current, rep));
|
||||
emit!(Refresh);
|
||||
Manager::_refresh();
|
||||
}
|
||||
false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use crossterm::event::KeyEvent;
|
|||
use ratatui::prelude::Rect;
|
||||
use tokio::sync::oneshot;
|
||||
use yazi_config::{keymap::{Exec, Key, KeymapLayer}, BOOT};
|
||||
use yazi_core::{emit, files::FilesOp, input::InputMode, Ctx, Event};
|
||||
use yazi_core::{emit, files::FilesOp, input::InputMode, manager::Manager, Ctx, Event};
|
||||
use yazi_shared::Term;
|
||||
|
||||
use crate::{Executor, Logs, Panic, Root, Signals};
|
||||
|
|
@ -110,7 +110,7 @@ impl App {
|
|||
self.term = Some(Term::start().unwrap());
|
||||
self.signals.stop_term(false);
|
||||
emit!(Render);
|
||||
emit!(Hover);
|
||||
Manager::_hover(None);
|
||||
}
|
||||
if let Some(tx) = tx {
|
||||
tx.send(()).ok();
|
||||
|
|
@ -128,9 +128,6 @@ impl App {
|
|||
let manager = &mut self.cx.manager;
|
||||
let tasks = &mut self.cx.tasks;
|
||||
match event {
|
||||
Event::Refresh => {
|
||||
manager.refresh();
|
||||
}
|
||||
Event::Files(op) => {
|
||||
let calc = !matches!(op, FilesOp::Size(..) | FilesOp::IOErr(_));
|
||||
let b = match op {
|
||||
|
|
@ -154,12 +151,6 @@ impl App {
|
|||
emit!(Peek);
|
||||
}
|
||||
}
|
||||
Event::Hover(url) => {
|
||||
if manager.current_mut().repos(url) {
|
||||
emit!(Render);
|
||||
}
|
||||
emit!(Peek);
|
||||
}
|
||||
Event::Peek(sequent) => {
|
||||
if let Some((max, url)) = sequent {
|
||||
manager.active_mut().update_peek(max, url);
|
||||
|
|
|
|||
|
|
@ -88,10 +88,12 @@ impl<'a> Executor<'a> {
|
|||
};
|
||||
}
|
||||
|
||||
on!(ACTIVE, escape);
|
||||
on!(MANAGER, hover);
|
||||
on!(MANAGER, refresh);
|
||||
on!(MANAGER, quit, &self.cx.tasks);
|
||||
on!(MANAGER, close, &self.cx.tasks);
|
||||
on!(MANAGER, suspend);
|
||||
on!(ACTIVE, escape);
|
||||
|
||||
// Navigation
|
||||
on!(ACTIVE, arrow);
|
||||
|
|
@ -212,7 +214,7 @@ impl<'a> Executor<'a> {
|
|||
on!(move_, "move");
|
||||
|
||||
if exec.cmd.as_str() == "complete" {
|
||||
return if exec.args.is_empty() {
|
||||
return if exec.named.contains_key("trigger") {
|
||||
self.cx.completion.trigger(exec)
|
||||
} else {
|
||||
self.cx.input.complete(exec)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue