mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
fix: set the current working directory in a thread-safe way (#2043)
This commit is contained in:
parent
c1048debc5
commit
6e1948e7e1
6 changed files with 53 additions and 34 deletions
20
Cargo.lock
generated
20
Cargo.lock
generated
|
|
@ -272,9 +272,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bstr"
|
name = "bstr"
|
||||||
version = "1.11.0"
|
version = "1.11.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a68f1f47cdf0ec8ee4b941b2eee2a80cb796db73118c0dd09ac63fbe405be22"
|
checksum = "786a307d683a5bf92e6fd5fd69a7eb613751668d1d8d67d802846dfe367c62c8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
@ -333,9 +333,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.3"
|
version = "1.2.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d"
|
checksum = "9157bbaa6b165880c27a4293a474c91cdcf265cc68cc829bf10be0964a391caf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jobserver",
|
"jobserver",
|
||||||
"libc",
|
"libc",
|
||||||
|
|
@ -2119,9 +2119,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.5.7"
|
version = "0.5.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
|
checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
]
|
]
|
||||||
|
|
@ -2250,9 +2250,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "1.0.23"
|
version = "1.0.24"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
|
checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
|
|
@ -3738,9 +3738,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zune-jpeg"
|
name = "zune-jpeg"
|
||||||
version = "0.4.13"
|
version = "0.4.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768"
|
checksum = "99a5bab8d7dedf81405c4bb1f2b83ea057643d9cb28778cea9eecddeedd2e028"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zune-core",
|
"zune-core",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ Yazi (means "duck") is a terminal file manager written in Rust, based on non-blo
|
||||||
- 💫 Vim-like input/pick/confirm/which/notify component, auto-completion for cd paths
|
- 💫 Vim-like input/pick/confirm/which/notify component, auto-completion for cd paths
|
||||||
- 🏷️ Multi-Tab Support, Cross-directory selection, Scrollable Preview (for videos, PDFs, archives, code, directories, etc.)
|
- 🏷️ Multi-Tab Support, Cross-directory selection, Scrollable Preview (for videos, PDFs, archives, code, directories, etc.)
|
||||||
- 🔄 Bulk Renaming, Visual Mode, File Chooser
|
- 🔄 Bulk Renaming, Visual Mode, File Chooser
|
||||||
- 🎨 Theme System, Mouse Support, Trash Bin, Custom Layouts, CSI u
|
- 🎨 Theme System, Mouse Support, Trash Bin, Custom Layouts, CSI u, OSC 52
|
||||||
- ... and more!
|
- ... and more!
|
||||||
|
|
||||||
https://github.com/sxyazi/yazi/assets/17523360/92ff23fa-0cd5-4f04-b387-894c12265cc7
|
https://github.com/sxyazi/yazi/assets/17523360/92ff23fa-0cd5-4f04-b387-894c12265cc7
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,7 @@ use crate::{manager::Manager, tasks::Tasks};
|
||||||
|
|
||||||
impl Manager {
|
impl Manager {
|
||||||
pub fn refresh(&mut self, _: CmdCow, tasks: &Tasks) {
|
pub fn refresh(&mut self, _: CmdCow, tasks: &Tasks) {
|
||||||
CWD.set(self.cwd());
|
if CWD.set(self.cwd()) && !MANAGER.title_format.is_empty() {
|
||||||
if !MANAGER.title_format.is_empty() {
|
|
||||||
execute!(std::io::stderr(), SetTitle(self.title())).ok();
|
execute!(std::io::stderr(), SetTitle(self.title())).ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,16 @@
|
||||||
use std::{ops::Deref, path::PathBuf, sync::Arc};
|
use std::{env::{current_dir, set_current_dir}, ops::Deref, path::PathBuf, sync::{Arc, atomic::{self, AtomicBool}}};
|
||||||
|
|
||||||
use arc_swap::ArcSwap;
|
use arc_swap::ArcSwap;
|
||||||
use yazi_shared::{RoCell, url::Url};
|
use yazi_shared::{RoCell, url::Url};
|
||||||
|
|
||||||
pub static CWD: RoCell<Cwd> = RoCell::new();
|
pub static CWD: RoCell<Cwd> = RoCell::new();
|
||||||
|
|
||||||
pub struct Cwd {
|
pub struct Cwd(ArcSwap<Url>);
|
||||||
inner: ArcSwap<Url>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for Cwd {
|
impl Deref for Cwd {
|
||||||
type Target = ArcSwap<Url>;
|
type Target = ArcSwap<Url>;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target { &self.inner }
|
fn deref(&self) -> &Self::Target { &self.0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Cwd {
|
impl Default for Cwd {
|
||||||
|
|
@ -20,16 +18,40 @@ impl Default for Cwd {
|
||||||
let p = std::env::var_os("PWD")
|
let p = std::env::var_os("PWD")
|
||||||
.map(PathBuf::from)
|
.map(PathBuf::from)
|
||||||
.filter(|p| p.is_absolute())
|
.filter(|p| p.is_absolute())
|
||||||
.or_else(|| std::env::current_dir().ok())
|
.or_else(|| current_dir().ok())
|
||||||
.expect("failed to get current working directory");
|
.expect("failed to get current working directory");
|
||||||
|
|
||||||
Self { inner: ArcSwap::new(Arc::new(Url::from(p))) }
|
Self(ArcSwap::new(Arc::new(Url::from(p))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cwd {
|
impl Cwd {
|
||||||
pub fn set(&self, url: &Url) {
|
pub fn set(&self, url: &Url) -> bool {
|
||||||
self.inner.store(Arc::new(url.clone()));
|
if self.load().as_ref() == url {
|
||||||
std::env::set_var("PWD", self.inner.load().as_ref());
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.store(Arc::new(url.clone()));
|
||||||
|
std::env::set_var("PWD", url);
|
||||||
|
|
||||||
|
Self::sync_cwd();
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sync_cwd() {
|
||||||
|
static SYNCING: AtomicBool = AtomicBool::new(false);
|
||||||
|
if SYNCING.swap(true, atomic::Ordering::Relaxed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tokio::task::spawn_blocking(move || {
|
||||||
|
_ = set_current_dir(CWD.load().as_ref());
|
||||||
|
let p = current_dir().unwrap_or_default();
|
||||||
|
|
||||||
|
SYNCING.store(false, atomic::Ordering::Relaxed);
|
||||||
|
if p != CWD.load().as_path() {
|
||||||
|
set_current_dir(CWD.load().as_ref()).ok();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,6 @@ use mlua::{Function, Lua};
|
||||||
|
|
||||||
use super::Utils;
|
use super::Utils;
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
static HOSTNAME_CACHE: std::sync::OnceLock<Option<String>> = std::sync::OnceLock::new();
|
|
||||||
|
|
||||||
impl Utils {
|
impl Utils {
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub(super) fn uid(lua: &Lua) -> mlua::Result<Function> {
|
pub(super) fn uid(lua: &Lua) -> mlua::Result<Function> {
|
||||||
|
|
@ -46,12 +43,6 @@ impl Utils {
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub(super) fn host_name(lua: &Lua) -> mlua::Result<Function> {
|
pub(super) fn host_name(lua: &Lua) -> mlua::Result<Function> {
|
||||||
lua.create_function(|lua, ()| {
|
lua.create_function(|lua, ()| yazi_shared::hostname().map(|s| lua.create_string(s)).transpose())
|
||||||
HOSTNAME_CACHE
|
|
||||||
.get_or_init(|| yazi_shared::hostname().ok())
|
|
||||||
.as_ref()
|
|
||||||
.map(|s| lua.create_string(s))
|
|
||||||
.transpose()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,14 @@
|
||||||
pub static USERS_CACHE: crate::RoCell<uzers::UsersCache> = crate::RoCell::new();
|
pub static USERS_CACHE: crate::RoCell<uzers::UsersCache> = crate::RoCell::new();
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub fn hostname() -> Result<String, std::io::Error> {
|
pub fn hostname() -> Option<&'static str> {
|
||||||
|
static CACHE: std::sync::OnceLock<Option<String>> = std::sync::OnceLock::new();
|
||||||
|
|
||||||
|
CACHE.get_or_init(|| hostname_impl().ok()).as_deref()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn hostname_impl() -> Result<String, std::io::Error> {
|
||||||
use std::io::{Error, ErrorKind};
|
use std::io::{Error, ErrorKind};
|
||||||
|
|
||||||
use libc::{gethostname, strlen};
|
use libc::{gethostname, strlen};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue