summaryrefslogtreecommitdiffstats
path: root/src/fs
diff options
context:
space:
mode:
authorDLFW <daniel@llin.info>2021-06-20 01:14:10 +0200
committerGitHub <noreply@github.com>2021-06-19 19:14:10 -0400
commite6359a599e804031189eb9bc067c4eff9b01a1a8 (patch)
treef94102b28145f91db5b0bded5e38869157c1946f /src/fs
parent362a507ad60ee479fb68a48fc7daf4a49652f1bf (diff)
Show symlinked files and dirs correctly (#72)
* Treat symlinks as normal files and dirs * Dirs are recognized as dirs no matter is they are a symlink (correct devicon) * Permission flags shown in the footer are the permissions of the target in case a symlink is selected * Size of a symlinked file is the size of the target * File display to be fixed: symlink arrow now just overrides the file size, but both need to be shown one after the other * Correctly show symlink arrow and file size next This commit includes quite some refactoring. The shortening of the left and right part of an entry in a dir list and the shortening of the file name are separated into functions which don't directly write to the buffer but just return strings. That way, they get testable and further enhancements like different line modes should be easier to implement. * fix review findings * better file name truncation File names are only truncated at grapheme border, while the width is calculated on the actual nuber of terminal cells. * more adequate test organization * more code structure
Diffstat (limited to 'src/fs')
-rw-r--r--src/fs/metadata.rs48
-rw-r--r--src/fs/mod.rs2
2 files changed, 32 insertions, 18 deletions
diff --git a/src/fs/metadata.rs b/src/fs/metadata.rs
index ef7e1c9..809c205 100644
--- a/src/fs/metadata.rs
+++ b/src/fs/metadata.rs
@@ -3,16 +3,22 @@ use std::{fs, io, path, time};
#[derive(Clone, Debug)]
pub enum FileType {
Directory,
- Symlink(String),
File,
}
#[derive(Clone, Debug)]
+pub enum LinkType {
+ Normal,
+ Symlink(String),
+}
+
+#[derive(Clone, Debug)]
pub struct JoshutoMetadata {
_len: u64,
_modified: time::SystemTime,
_permissions: fs::Permissions,
_file_type: FileType,
+ _link_type: LinkType,
#[cfg(unix)]
pub uid: u32,
#[cfg(unix)]
@@ -26,40 +32,44 @@ impl JoshutoMetadata {
#[cfg(unix)]
use std::os::unix::fs::MetadataExt;
- let metadata = fs::symlink_metadata(path)?;
+ let symlink_metadata = fs::symlink_metadata(path)?;
+ let metadata = fs::metadata(path)?;
let _len = metadata.len();
let _modified = metadata.modified()?;
let _permissions = metadata.permissions();
- let file_type = metadata.file_type();
-
- let file_type = if file_type.is_dir() {
+ let _file_type = if metadata.file_type().is_dir() {
FileType::Directory
- } else if file_type.is_symlink() {
- let mut link = "".to_string();
+ } else {
+ FileType::File
+ };
+ let _link_type = match symlink_metadata.file_type().is_symlink() {
+ true => {
+ let mut link = "".to_string();
- if let Ok(path) = fs::read_link(path) {
- if let Some(s) = path.to_str() {
- link = s.to_string();
+ if let Ok(path) = fs::read_link(path) {
+ if let Some(s) = path.to_str() {
+ link = s.to_string();
+ }
}
+ LinkType::Symlink(link)
}
- FileType::Symlink(link)
- } else {
- FileType::File
+ false => LinkType::Normal,
};
#[cfg(unix)]
- let uid = metadata.uid();
+ let uid = symlink_metadata.uid();
#[cfg(unix)]
- let gid = metadata.gid();
+ let gid = symlink_metadata.gid();
#[cfg(unix)]
- let mode = metadata.mode();
+ let mode = symlink_metadata.mode();
Ok(Self {
_len,
_modified,
_permissions,
- _file_type: file_type,
+ _file_type,
+ _link_type,
#[cfg(unix)]
uid,
#[cfg(unix)]
@@ -88,4 +98,8 @@ impl JoshutoMetadata {
pub fn file_type(&self) -> &FileType {
&self._file_type
}
+
+ pub fn link_type(&self) -> &LinkType {
+ &self._link_type
+ }
}
diff --git a/src/fs/mod.rs b/src/fs/mod.rs
index 2704bdc..159d63b 100644
--- a/src/fs/mod.rs
+++ b/src/fs/mod.rs
@@ -4,4 +4,4 @@ mod metadata;
pub use self::dirlist::JoshutoDirList;
pub use self::entry::JoshutoDirEntry;
-pub use self::metadata::{FileType, JoshutoMetadata};
+pub use self::metadata::{FileType, JoshutoMetadata, LinkType};