diff options
author | DLFW <daniel@llin.info> | 2021-06-20 01:14:10 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-19 19:14:10 -0400 |
commit | e6359a599e804031189eb9bc067c4eff9b01a1a8 (patch) | |
tree | f94102b28145f91db5b0bded5e38869157c1946f /src/fs | |
parent | 362a507ad60ee479fb68a48fc7daf4a49652f1bf (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.rs | 48 | ||||
-rw-r--r-- | src/fs/mod.rs | 2 |
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}; |