mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01: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]]
|
||||
name = "bstr"
|
||||
version = "1.11.0"
|
||||
version = "1.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a68f1f47cdf0ec8ee4b941b2eee2a80cb796db73118c0dd09ac63fbe405be22"
|
||||
checksum = "786a307d683a5bf92e6fd5fd69a7eb613751668d1d8d67d802846dfe367c62c8"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"serde",
|
||||
|
|
@ -333,9 +333,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.3"
|
||||
version = "1.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d"
|
||||
checksum = "9157bbaa6b165880c27a4293a474c91cdcf265cc68cc829bf10be0964a391caf"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
"libc",
|
||||
|
|
@ -2119,9 +2119,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.7"
|
||||
version = "0.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
|
||||
checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
]
|
||||
|
|
@ -2250,9 +2250,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
|||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.23"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
|
||||
checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
|
|
@ -3738,9 +3738,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zune-jpeg"
|
||||
version = "0.4.13"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768"
|
||||
checksum = "99a5bab8d7dedf81405c4bb1f2b83ea057643d9cb28778cea9eecddeedd2e028"
|
||||
dependencies = [
|
||||
"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
|
||||
- 🏷️ Multi-Tab Support, Cross-directory selection, Scrollable Preview (for videos, PDFs, archives, code, directories, etc.)
|
||||
- 🔄 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!
|
||||
|
||||
https://github.com/sxyazi/yazi/assets/17523360/92ff23fa-0cd5-4f04-b387-894c12265cc7
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ use crate::{manager::Manager, tasks::Tasks};
|
|||
|
||||
impl Manager {
|
||||
pub fn refresh(&mut self, _: CmdCow, tasks: &Tasks) {
|
||||
CWD.set(self.cwd());
|
||||
if !MANAGER.title_format.is_empty() {
|
||||
if CWD.set(self.cwd()) && !MANAGER.title_format.is_empty() {
|
||||
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 yazi_shared::{RoCell, url::Url};
|
||||
|
||||
pub static CWD: RoCell<Cwd> = RoCell::new();
|
||||
|
||||
pub struct Cwd {
|
||||
inner: ArcSwap<Url>,
|
||||
}
|
||||
pub struct Cwd(ArcSwap<Url>);
|
||||
|
||||
impl Deref for Cwd {
|
||||
type Target = ArcSwap<Url>;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.inner }
|
||||
fn deref(&self) -> &Self::Target { &self.0 }
|
||||
}
|
||||
|
||||
impl Default for Cwd {
|
||||
|
|
@ -20,16 +18,40 @@ impl Default for Cwd {
|
|||
let p = std::env::var_os("PWD")
|
||||
.map(PathBuf::from)
|
||||
.filter(|p| p.is_absolute())
|
||||
.or_else(|| std::env::current_dir().ok())
|
||||
.or_else(|| current_dir().ok())
|
||||
.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 {
|
||||
pub fn set(&self, url: &Url) {
|
||||
self.inner.store(Arc::new(url.clone()));
|
||||
std::env::set_var("PWD", self.inner.load().as_ref());
|
||||
pub fn set(&self, url: &Url) -> bool {
|
||||
if self.load().as_ref() == url {
|
||||
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;
|
||||
|
||||
#[cfg(unix)]
|
||||
static HOSTNAME_CACHE: std::sync::OnceLock<Option<String>> = std::sync::OnceLock::new();
|
||||
|
||||
impl Utils {
|
||||
#[cfg(unix)]
|
||||
pub(super) fn uid(lua: &Lua) -> mlua::Result<Function> {
|
||||
|
|
@ -46,12 +43,6 @@ impl Utils {
|
|||
|
||||
#[cfg(unix)]
|
||||
pub(super) fn host_name(lua: &Lua) -> mlua::Result<Function> {
|
||||
lua.create_function(|lua, ()| {
|
||||
HOSTNAME_CACHE
|
||||
.get_or_init(|| yazi_shared::hostname().ok())
|
||||
.as_ref()
|
||||
.map(|s| lua.create_string(s))
|
||||
.transpose()
|
||||
})
|
||||
lua.create_function(|lua, ()| yazi_shared::hostname().map(|s| lua.create_string(s)).transpose())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,14 @@
|
|||
pub static USERS_CACHE: crate::RoCell<uzers::UsersCache> = crate::RoCell::new();
|
||||
|
||||
#[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 libc::{gethostname, strlen};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue