fix: respect symlink paths without canonicalizing them (#126)

This commit is contained in:
三咲雅 · Misaki Masa 2023-09-08 23:25:14 +08:00 committed by GitHub
parent c1f3c8f82d
commit 3544578a12
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 21 additions and 22 deletions

View file

@ -4,7 +4,7 @@ use std::ffi::OsString;
use anyhow::{Ok, Result}; use anyhow::{Ok, Result};
use config::{keymap::{Control, Key, KeymapLayer}, BOOT}; use config::{keymap::{Control, Key, KeymapLayer}, BOOT};
use crossterm::event::KeyEvent; use crossterm::event::KeyEvent;
use shared::{absolute_url, Term}; use shared::{expand_url, Term};
use tokio::sync::oneshot; use tokio::sync::oneshot;
use crate::{Ctx, Executor, Logs, Root, Signals}; use crate::{Ctx, Executor, Logs, Root, Signals};
@ -121,7 +121,7 @@ impl App {
match event { match event {
Event::Cd(url) => { Event::Cd(url) => {
futures::executor::block_on(async { futures::executor::block_on(async {
manager.active_mut().cd(absolute_url(url)).await; manager.active_mut().cd(expand_url(url)).await;
}); });
} }
Event::Refresh => { Event::Refresh => {

View file

@ -1,5 +1,5 @@
use ratatui::{layout, prelude::{Buffer, Constraint, Direction, Rect}, style::{Color, Style}, widgets::{Paragraph, Widget}}; use ratatui::{layout, prelude::{Buffer, Constraint, Direction, Rect}, style::{Color, Style}, widgets::{Paragraph, Widget}};
use shared::readable_home; use shared::readable_path;
use super::Tabs; use super::Tabs;
use crate::Ctx; use crate::Ctx;
@ -21,9 +21,9 @@ impl<'a> Widget for Layout<'a> {
let current = &self.cx.manager.current(); let current = &self.cx.manager.current();
let location = if current.cwd.is_search() { let location = if current.cwd.is_search() {
format!("{} (search)", readable_home(&current.cwd)) format!("{} (search)", readable_path(&current.cwd))
} else { } else {
readable_home(&current.cwd) readable_path(&current.cwd)
}; };
Paragraph::new(location).style(Style::new().fg(Color::Cyan)).render(chunks[0], buf); Paragraph::new(location).style(Style::new().fg(Color::Cyan)).render(chunks[0], buf);

View file

@ -2,7 +2,7 @@ use core::files::File;
use config::{MANAGER, THEME}; use config::{MANAGER, THEME};
use ratatui::{buffer::Buffer, layout::Rect, style::Style, widgets::{List, ListItem, Widget}}; use ratatui::{buffer::Buffer, layout::Rect, style::Style, widgets::{List, ListItem, Widget}};
use shared::readable_path; use shared::short_path;
use crate::Ctx; use crate::Ctx;
@ -87,7 +87,7 @@ impl<'a> Widget for Folder<'a> {
self.file_style(f) self.file_style(f)
}; };
let mut path = format!(" {icon} {}", readable_path(f.url(), &self.folder.cwd)); let mut path = format!(" {icon} {}", short_path(f.url(), &self.folder.cwd));
if let Some(link_to) = f.link_to() { if let Some(link_to) = f.link_to() {
if MANAGER.show_symlink { if MANAGER.show_symlink {
path.push_str(&format!(" -> {}", link_to.display())); path.push_str(&format!(" -> {}", link_to.display()));

View file

@ -1,7 +1,7 @@
use std::{env, fs, path::PathBuf, process}; use std::{env, fs, path::PathBuf, process};
use clap::{command, Parser}; use clap::{command, Parser};
use shared::absolute_path; use shared::expand_path;
use crate::{Xdg, PREVIEW}; use crate::{Xdg, PREVIEW};
@ -38,8 +38,7 @@ impl Default for Boot {
fn default() -> Self { fn default() -> Self {
let args = Args::parse(); let args = Args::parse();
let cwd = let cwd = args.cwd.map(expand_path).filter(|p| p.is_dir()).or_else(|| env::current_dir().ok());
args.cwd.map(absolute_path).filter(|p| p.is_dir()).or_else(|| env::current_dir().ok());
let boot = Self { let boot = Self {
cwd: cwd.unwrap_or("/".into()), cwd: cwd.unwrap_or("/".into()),

View file

@ -2,7 +2,7 @@ use std::{path::{Path, PathBuf}, time::{self, SystemTime}};
use md5::{Digest, Md5}; use md5::{Digest, Md5};
use serde::Deserialize; use serde::Deserialize;
use shared::absolute_path; use shared::expand_path;
use super::PreviewAdaptor; use super::PreviewAdaptor;
use crate::{xdg::Xdg, MERGED_YAZI}; use crate::{xdg::Xdg, MERGED_YAZI};
@ -36,7 +36,7 @@ impl Default for Preview {
let preview = toml::from_str::<Outer>(&MERGED_YAZI).unwrap().preview; let preview = toml::from_str::<Outer>(&MERGED_YAZI).unwrap().preview;
let cache_dir = let cache_dir =
preview.cache_dir.filter(|p| !p.is_empty()).map_or_else(Xdg::cache_dir, absolute_path); preview.cache_dir.filter(|p| !p.is_empty()).map_or_else(Xdg::cache_dir, expand_path);
Preview { Preview {
adaptor: Default::default(), adaptor: Default::default(),

View file

@ -1,7 +1,7 @@
use std::path::PathBuf; use std::path::PathBuf;
use serde::Deserialize; use serde::Deserialize;
use shared::absolute_path; use shared::expand_path;
use validator::Validate; use validator::Validate;
use super::{ColorGroup, Filetype, Icon, Style}; use super::{ColorGroup, Filetype, Icon, Style};
@ -78,7 +78,7 @@ impl Default for Theme {
check_validation(theme.tab.validate()); check_validation(theme.tab.validate());
theme.preview.syntect_theme = absolute_path(&theme.preview.syntect_theme); theme.preview.syntect_theme = expand_path(&theme.preview.syntect_theme);
theme theme
} }

View file

@ -1,13 +1,13 @@
use std::{env, path::PathBuf}; use std::{env, path::PathBuf};
use shared::absolute_path; use shared::expand_path;
pub(super) struct Xdg; pub(super) struct Xdg;
impl Xdg { impl Xdg {
pub(super) fn config_dir() -> Option<PathBuf> { pub(super) fn config_dir() -> Option<PathBuf> {
if let Some(s) = env::var_os("YAZI_CONFIG_HOME").filter(|s| !s.is_empty()) { if let Some(s) = env::var_os("YAZI_CONFIG_HOME").filter(|s| !s.is_empty()) {
return Some(absolute_path(s)); return Some(expand_path(s));
} }
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]

View file

@ -4,30 +4,30 @@ use tokio::fs;
use crate::Url; use crate::Url;
pub fn absolute_path(p: impl AsRef<Path>) -> PathBuf { pub fn expand_path(p: impl AsRef<Path>) -> PathBuf {
let p = p.as_ref(); let p = p.as_ref();
if let Ok(p) = p.strip_prefix("~") { if let Ok(p) = p.strip_prefix("~") {
if let Some(home) = env::var_os("HOME") { if let Some(home) = env::var_os("HOME") {
return PathBuf::from_iter([&home, p.as_os_str()]); return PathBuf::from_iter([&home, p.as_os_str()]);
} }
} }
std::fs::canonicalize(p).unwrap_or_else(|_| p.to_path_buf()) p.to_path_buf()
} }
#[inline] #[inline]
pub fn absolute_url(mut u: Url) -> Url { pub fn expand_url(mut u: Url) -> Url {
u.set_path(absolute_path(&u)); u.set_path(expand_path(&u));
u u
} }
pub fn readable_path(p: &Path, base: &Path) -> String { pub fn short_path(p: &Path, base: &Path) -> String {
if let Ok(p) = p.strip_prefix(base) { if let Ok(p) = p.strip_prefix(base) {
return p.display().to_string(); return p.display().to_string();
} }
p.display().to_string() p.display().to_string()
} }
pub fn readable_home(p: &Path) -> String { pub fn readable_path(p: &Path) -> String {
if let Ok(home) = env::var("HOME") { if let Ok(home) = env::var("HOME") {
if let Ok(p) = p.strip_prefix(home) { if let Ok(p) = p.strip_prefix(home) {
return format!("~/{}", p.display()); return format!("~/{}", p.display());