Skip to content

Commit

Permalink
Better symlink support
Browse files Browse the repository at this point in the history
Closes: #37
  • Loading branch information
sayanarijit committed Apr 13, 2021
1 parent 0d4cd29 commit f974991
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 4 deletions.
59 changes: 57 additions & 2 deletions src/app.rs
Expand Up @@ -78,17 +78,62 @@ impl Pipe {
}
}

#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct SymlinkNode {
pub absolute_path: String,
pub extension: String,
pub is_dir: bool,
pub is_file: bool,
pub is_readonly: bool,
pub mime_essence: String,
}

impl SymlinkNode {
pub fn from(path: PathBuf) -> Self {
let extension = path
.extension()
.map(|e| e.to_string_lossy().to_string())
.unwrap_or_default();

let maybe_metadata = path.metadata().ok();

let is_dir = maybe_metadata.clone().map(|m| m.is_dir()).unwrap_or(false);

let is_file = maybe_metadata.clone().map(|m| m.is_file()).unwrap_or(false);

let is_readonly = maybe_metadata
.map(|m| m.permissions().readonly())
.unwrap_or(false);

let mime_essence = mime_guess::from_path(&path)
.first()
.map(|m| m.essence_str().to_string())
.unwrap_or_default();

Self {
absolute_path: path.to_string_lossy().to_string(),
extension,
is_dir,
is_file,
is_readonly,
mime_essence,
}
}
}

#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct Node {
pub parent: String,
pub relative_path: String,
pub absolute_path: String,
pub extension: String,
pub is_symlink: bool,
pub is_dir: bool,
pub is_file: bool,
pub is_symlink: bool,
pub is_broken: bool,
pub is_readonly: bool,
pub mime_essence: String,
pub symlink: Option<SymlinkNode>,
}

impl Node {
Expand All @@ -112,6 +157,14 @@ impl Node {
.map(|m| m.file_type().is_symlink())
.unwrap_or(false);

let (is_broken, maybe_symlink_meta) = if is_symlink {
path.canonicalize()
.map(|p| (false, Some(SymlinkNode::from(p))))
.unwrap_or_else(|_| (true, None))
} else {
(false, None)
};

let is_dir = maybe_metadata.clone().map(|m| m.is_dir()).unwrap_or(false);

let is_file = maybe_metadata.clone().map(|m| m.is_file()).unwrap_or(false);
Expand All @@ -130,11 +183,13 @@ impl Node {
relative_path,
absolute_path,
extension,
is_symlink,
is_dir,
is_file,
is_symlink,
is_broken,
is_readonly,
mime_essence,
symlink: maybe_symlink_meta,
}
}
}
Expand Down
8 changes: 7 additions & 1 deletion src/config.yml
Expand Up @@ -42,7 +42,13 @@ general:
height: 1
row:
cols:
- format: '{{{tree}}}{{{prefix}}}{{{meta.icon}}} {{{relativePath}}}{{#if isDir}}/{{/if}}{{{suffix}}}'
- format: >
{{{tree}}}{{{prefix}}}{{{meta.icon}}}
{{{relativePath}}}{{#if isDir}}/{{/if}}{{{suffix}}}
{{#if isSymlink}}
->
{{#if isBroken}}×{{else}}{{{symlink.absolutePath}}}{{/if}}{{#if symlink.isDir}}/{{/if}}{{/if}}
style:
fg: null
bg: null
Expand Down
30 changes: 29 additions & 1 deletion src/ui.rs
@@ -1,6 +1,6 @@
use crate::app;
use crate::app::HelpMenuLine;
use crate::app::Node;
use crate::app::{Node, SymlinkNode};
use handlebars::Handlebars;
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
Expand All @@ -13,6 +13,30 @@ use tui::text::{Span, Spans};
use tui::widgets::{Block, Borders, Cell, List, ListItem, Paragraph, Row, Table};
use tui::Frame;

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SymlinkNodeUiMetadata {
pub absolute_path: String,
pub extension: String,
pub is_dir: bool,
pub is_file: bool,
pub is_readonly: bool,
pub mime_essence: String,
}

impl From<SymlinkNode> for SymlinkNodeUiMetadata {
fn from(node: SymlinkNode) -> Self {
Self {
absolute_path: node.absolute_path.clone(),
extension: node.extension.clone(),
is_dir: node.is_dir,
is_file: node.is_file,
is_readonly: node.is_readonly,
mime_essence: node.mime_essence,
}
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct NodeUiMetadata {
Expand All @@ -22,10 +46,12 @@ struct NodeUiMetadata {
pub absolute_path: String,
pub extension: String,
pub is_symlink: bool,
pub is_broken: bool,
pub is_dir: bool,
pub is_file: bool,
pub is_readonly: bool,
pub mime_essence: String,
pub symlink: Option<SymlinkNodeUiMetadata>,

// Extra
pub index: usize,
Expand Down Expand Up @@ -62,10 +88,12 @@ impl NodeUiMetadata {
absolute_path: node.absolute_path.clone(),
extension: node.extension.clone(),
is_symlink: node.is_symlink,
is_broken: node.is_broken,
is_dir: node.is_dir,
is_file: node.is_file,
is_readonly: node.is_readonly,
mime_essence: node.mime_essence.clone(),
symlink: node.symlink.to_owned().map(|s| s.into()),
index,
relative_index,
is_before_focus,
Expand Down

0 comments on commit f974991

Please sign in to comment.