Skip to content

Commit 2fd8759

Browse files
committed
wip: improve list_files command
1 parent 88a0a6f commit 2fd8759

4 files changed

Lines changed: 94 additions & 97 deletions

File tree

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,11 @@ slog-async = "2.8.0"
6767
slog-stdlog = "4.1.1"
6868
[target.'cfg(target_os = "linux")'.dependencies]
6969
slog-journald = {version = "2.2.0", optional = true }
70+
tabled = "0.19.0"
71+
terminal_size = "0.4.2"
7072

7173
[dependencies.clap]
72-
version = "4.5.38"
74+
version = "4.5.39"
7375
features = ["cargo", "derive"]
7476

7577
[dev-dependencies]

src/core/commands/config.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,37 @@
11
use crate::utils::{app_config::AppConfig, error::Result};
2+
use tabled::{Table, Tabled};
3+
4+
#[derive(Tabled)]
5+
struct ConfigDisplay {
6+
#[tabled(rename = "Setting")]
7+
key: String,
8+
#[tabled(rename = "Value")]
9+
value: String,
10+
}
211

312
/// Show the configuration file
413
pub(crate) fn run() -> Result<()> {
514
let config = AppConfig::fetch()?;
6-
println!("{:#?}", config);
15+
16+
let table_data = vec![
17+
ConfigDisplay {
18+
key: "Debug Mode".to_string(),
19+
value: config.debug.to_string(),
20+
},
21+
ConfigDisplay {
22+
key: "Log Level".to_string(),
23+
value: config.log_level.to_string(),
24+
},
25+
ConfigDisplay {
26+
key: "Cache File".to_string(),
27+
value: config.cache_file,
28+
},
29+
];
30+
31+
let mut table = Table::new(table_data);
32+
table.with(tabled::settings::Style::modern());
33+
34+
println!("{}", table);
735

836
Ok(())
937
}

src/core/commands/list_files.rs

Lines changed: 61 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,23 @@
11
use crate::{
2-
core::{cache::sync_cache, types::OutputFormat},
2+
core::{
3+
cache::sync_cache,
4+
display::{truncate_path, truncate_string},
5+
types::OutputFormat,
6+
},
37
utils::error::{Error, Result},
48
};
59
use std::io::{self, Write};
10+
use tabled::{Table, Tabled};
11+
12+
#[derive(Tabled)]
13+
struct FileDisplay {
14+
#[tabled(rename = "File Path")]
15+
path: String,
16+
#[tabled(rename = "Owners")]
17+
owners: String,
18+
#[tabled(rename = "Tags")]
19+
tags: String,
20+
}
621

722
/// Find and list files with their owners based on filter criteria
823
pub(crate) fn run(
@@ -66,107 +81,58 @@ pub(crate) fn run(
6681
// Output the filtered files in the requested format
6782
match format {
6883
OutputFormat::Text => {
69-
// Set column widths that work better for most displays
70-
let path_width = 45; // Max width for path display
71-
let owner_width = 26; // More space for owners
72-
let tag_width = 26; // More space for tags
73-
74-
// Print header
75-
println!(
76-
"==============================================================================="
77-
);
78-
println!(
79-
" {:<path_width$} {:<owner_width$} {:<tag_width$}",
80-
"File Path",
81-
"Owners",
82-
"Tags",
83-
path_width = path_width,
84-
owner_width = owner_width,
85-
tag_width = tag_width
86-
);
87-
println!(
88-
"==============================================================================="
89-
);
90-
91-
// Print each file entry
92-
for file in &filtered_files {
93-
// Format the path - keep the filename but truncate the path if needed
94-
let path_str = file.path.to_string_lossy();
95-
let path_display = if path_str.len() > path_width {
96-
// Extract filename
97-
let filename = file
98-
.path
99-
.file_name()
100-
.map(|f| f.to_string_lossy().to_string())
101-
.unwrap_or_default();
102-
103-
// Calculate available space for parent path
104-
let available_space = path_width.saturating_sub(filename.len() + 4); // +4 for ".../"
105-
106-
if available_space > 5 {
107-
// Show part of the parent path
108-
let parent_path = path_str.to_string();
109-
let start_pos = parent_path.len().saturating_sub(path_width - 3);
110-
format!("...{}", &parent_path[start_pos..])
84+
// Create table data
85+
let table_data: Vec<FileDisplay> = filtered_files
86+
.iter()
87+
.map(|file| {
88+
let path_str = file.path.to_string_lossy().to_string();
89+
90+
let owners_str = if file.owners.is_empty() {
91+
"None".to_string()
11192
} else {
112-
// Just show the filename with ellipsis
113-
format!(".../{}", filename)
114-
}
115-
} else {
116-
path_str.to_string()
117-
};
118-
119-
// Format owners with more space
120-
let owners_str = if file.owners.is_empty() {
121-
"None".to_string()
122-
} else {
123-
file.owners
124-
.iter()
125-
.map(|o| o.identifier.clone())
126-
.collect::<Vec<_>>()
127-
.join(", ")
128-
};
93+
file.owners
94+
.iter()
95+
.map(|o| o.identifier.clone())
96+
.collect::<Vec<_>>()
97+
.join(", ")
98+
};
12999

130-
let owners_display = if owners_str.len() > owner_width {
131-
format!("{}...", &owners_str[0..owner_width - 3])
132-
} else {
133-
owners_str
134-
};
100+
let tags_str = if file.tags.is_empty() {
101+
"None".to_string()
102+
} else {
103+
file.tags
104+
.iter()
105+
.map(|t| t.0.clone())
106+
.collect::<Vec<_>>()
107+
.join(", ")
108+
};
109+
110+
FileDisplay {
111+
path: truncate_path(&path_str, 60),
112+
owners: truncate_string(&owners_str, 40),
113+
tags: truncate_string(&tags_str, 30),
114+
}
115+
})
116+
.collect();
135117

136-
// Format tags with more space
137-
let tags_str = if file.tags.is_empty() {
138-
"None".to_string()
118+
// Get terminal width, fallback to 80 if unavailable
119+
let terminal_width =
120+
if let Some((terminal_size::Width(w), _)) = terminal_size::terminal_size() {
121+
w as usize
139122
} else {
140-
file.tags
141-
.iter()
142-
.map(|t| t.0.clone())
143-
.collect::<Vec<_>>()
144-
.join(", ")
123+
80
145124
};
146125

147-
let tags_display = if tags_str.len() > tag_width {
148-
format!("{}...", &tags_str[0..tag_width - 3])
149-
} else {
150-
tags_str
151-
};
126+
let mut table = Table::new(table_data);
127+
table
128+
.with(tabled::settings::Style::modern())
129+
.with(tabled::settings::Width::wrap(
130+
terminal_width.saturating_sub(4),
131+
))
132+
.with(tabled::settings::Padding::new(1, 1, 0, 0));
152133

153-
println!(
154-
" {:<path_width$} {:<owner_width$} {:<tag_width$}",
155-
path_display,
156-
owners_display,
157-
tags_display,
158-
path_width = path_width,
159-
owner_width = owner_width,
160-
tag_width = tag_width
161-
);
162-
}
163-
println!(
164-
"==============================================================================="
165-
);
166-
println!(" Total: {} files", filtered_files.len());
167-
println!(
168-
"==============================================================================="
169-
);
134+
println!("{}", table);
135+
println!("Total: {} files", filtered_files.len());
170136
}
171137
OutputFormat::Json => {
172138
println!("{}", serde_json::to_string_pretty(&filtered_files).unwrap());

src/core/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
pub(crate) mod cache;
22
pub(crate) mod commands;
33
pub(crate) mod common;
4+
pub(crate) mod display;
45
pub mod owner_resolver;
56
pub(crate) mod parse;
67
pub mod parser;

0 commit comments

Comments
 (0)