summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyohei Uto <im@kyoheiu.dev>2024-03-03 12:01:44 +0900
committerGitHub <noreply@github.com>2024-03-03 12:01:44 +0900
commit39ed788be8e3a69fd8034584be2a3046de859641 (patch)
tree12f9d85a4220357ffec7e37dbd555b0e55bad0ae
parent374af64758f71a3689bf8a3f527fca707e8b1785 (diff)
parenta2f6e1c467d93bc7207836800eaa8401ed4d834b (diff)
Merge pull request #289 from kyoheiu/fix/symlink
Show target path of symlink items at the footer
-rw-r--r--CHANGELOG.md9
-rw-r--r--Cargo.lock10
-rw-r--r--Cargo.toml1
-rw-r--r--src/run.rs24
-rw-r--r--src/state.rs104
5 files changed, 91 insertions, 57 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0e2156d..1cb2cd3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,15 @@
## Unreleased
+### Added
+- `ignore_case` option to do case-insensitie search by `/`.
+
+### Changed
+- Symlink items linked to directory now appears in the directory section, not the file section.
+
+### fixed
+- `z` command can now receive multiple arguments: `z dot files<CR>` works as in your terminal.
+
## v2.12.1 (2024-02-04)
### Fixed
diff --git a/Cargo.lock b/Cargo.lock
index b08d2aa..552a402 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -346,6 +346,7 @@ dependencies = [
"lzma-rs",
"natord",
"nix",
+ "normpath",
"rayon",
"serde",
"serde_yaml",
@@ -642,6 +643,15 @@ dependencies = [
]
[[package]]
+name = "normpath"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5831952a9476f2fed74b77d74182fa5ddc4d21c72ec45a333b250e3ed0272804"
+dependencies = [
+ "windows-sys 0.52.0",
+]
+
+[[package]]
name = "num-conv"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 3ccaf0f..87d9034 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -35,6 +35,7 @@ lzma-rs = "0.3.0"
zstd = "0.12.4"
unicode-width = "0.1.10"
git2 = {version = "0.18.0", default-features = false }
+normpath = "1.2.0"
[dev-dependencies]
bwrap = { version = "1.3.0", features = ["use_std"] }
diff --git a/src/run.rs b/src/run.rs
index f5b43f8..81a782c 100644
--- a/src/run.rs
+++ b/src/run.rs
@@ -13,6 +13,7 @@ use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind, KeyModifier
use crossterm::execute;
use crossterm::terminal::{EnterAlternateScreen, LeaveAlternateScreen};
use log::{error, info};
+use normpath::PathExt;
use std::env;
use std::io::{stdout, Write};
use std::panic;
@@ -118,12 +119,14 @@ pub fn run(arg: PathBuf, log: bool) -> Result<(), FxError> {
let mut state = State::new(&session_path)?;
state.trash_dir = trash_dir_path;
state.lwd_file = lwd_file_path;
- state.current_dir = if cfg!(not(windows)) {
- // If executed this on windows, "//?" will be inserted at the beginning of the path.
- arg.canonicalize()?
- } else {
- arg
- };
+ let normalized_arg = arg.normalize();
+ if normalized_arg.is_err() {
+ return Err(FxError::Arg(format!(
+ "Invalid path: {}\n`fx -h` shows help.",
+ &arg.display()
+ )));
+ }
+ state.current_dir = normalized_arg.unwrap().into_path_buf();
state.jumplist.add(&state.current_dir);
state.is_ro = match has_write_permission(&state.current_dir) {
Ok(b) => !b,
@@ -2241,12 +2244,13 @@ fn _run(mut state: State, session_path: PathBuf) -> Result<(), FxError> {
} else if commands.len() == 2 && command == "cd" {
if let Ok(target) =
std::path::Path::new(commands[1])
- .canonicalize()
+ .normalize()
{
if target.exists() {
- if let Err(e) =
- state.chdir(&target, Move::Jump)
- {
+ if let Err(e) = state.chdir(
+ &target.into_path_buf(),
+ Move::Jump,
+ ) {
print_warning(e, state.layout.y);
}
break 'command;
diff --git a/src/state.rs b/src/state.rs
index 23c17dc..632a818 100644
--- a/src/state.rs
+++ b/src/state.rs
@@ -16,6 +16,7 @@ use crossterm::event::KeyEventKind;
use crossterm::event::{Event, KeyCode, KeyEvent};
use crossterm::style::Stylize;
use log::info;
+use normpath::PathExt;
use std::collections::VecDeque;
use std::collections::{BTreeMap, BTreeSet};
use std::env;
@@ -1647,56 +1648,70 @@ impl State {
/// Return footer string.
fn make_footer(&self, item: &ItemInfo) -> String {
- match &item.file_ext {
- Some(ext) => {
- let footer = match item.permissions {
- Some(permissions) => {
- format!(
- " {}/{} {} {} {}",
+ let mut footer = String::new();
+ if item.file_type == FileType::Symlink {
+ footer = " linked to: ".to_owned();
+ match &item.symlink_dir_path {
+ Some(true_path) => {
+ footer.push_str(true_path.to_str().unwrap_or("(invalid unicode path)"))
+ }
+ None => match fs::read_link(&item.file_path) {
+ Ok(true_path) => match true_path.normalize() {
+ Ok(p) => footer
+ .push_str(p.as_path().to_str().unwrap_or("(invalid univode path)")),
+ Err(_) => footer.push_str("(invalid path)"),
+ },
+ Err(_) => footer.push_str("(broken link)"),
+ },
+ }
+ } else {
+ match &item.file_ext {
+ Some(ext) => {
+ footer = match item.permissions {
+ Some(permissions) => {
+ format!(
+ " {}/{} {} {} {}",
+ self.layout.nums.index + 1,
+ self.list.len(),
+ ext.clone(),
+ to_proper_size(item.file_size),
+ convert_to_permissions(permissions)
+ )
+ }
+ None => format!(
+ " {}/{} {} {}",
self.layout.nums.index + 1,
self.list.len(),
ext.clone(),
to_proper_size(item.file_size),
- convert_to_permissions(permissions)
- )
- }
- None => format!(
- " {}/{} {} {}",
- self.layout.nums.index + 1,
- self.list.len(),
- ext.clone(),
- to_proper_size(item.file_size),
- ),
- };
- footer
- .chars()
- .take(self.layout.terminal_column.into())
- .collect()
- }
- None => {
- let footer = match item.permissions {
- Some(permissions) => {
- format!(
- " {}/{} {} {}",
+ ),
+ };
+ }
+ None => {
+ footer = match item.permissions {
+ Some(permissions) => {
+ format!(
+ " {}/{} {} {}",
+ self.layout.nums.index + 1,
+ self.list.len(),
+ to_proper_size(item.file_size),
+ convert_to_permissions(permissions)
+ )
+ }
+ None => format!(
+ " {}/{} {}",
self.layout.nums.index + 1,
self.list.len(),
to_proper_size(item.file_size),
- convert_to_permissions(permissions)
- )
- }
- None => format!(
- " {}/{} {}",
- self.layout.nums.index + 1,
- self.list.len(),
- to_proper_size(item.file_size),
- ),
- };
- footer
- .chars()
- .take(self.layout.terminal_column.into())
- .collect()
+ ),
+ };
+ }
}
}
+ footer
+ .chars()
+ .take(self.layout.terminal_column.into())
+ .collect()
}
/// Scroll down previewed text.
@@ -1806,12 +1821,7 @@ fn read_item(entry: fs::DirEntry) -> ItemInfo {
if filetype == FileType::Symlink {
if let Ok(sym_meta) = fs::metadata(&path) {
if sym_meta.is_dir() {
- if cfg!(not(windows)) {
- // Avoid error on Windows
- path.canonicalize().ok()
- } else {
- Some(path.clone())
- }
+ path.normalize().map(|p| p.into_path_buf()).ok()
} else {
None
}