diff --git a/src/app.rs b/src/app.rs index 3a91723..31d137b 100644 --- a/src/app.rs +++ b/src/app.rs @@ -97,35 +97,44 @@ pub struct AdapterEntry { pub kind: ArtifactKind, } -impl AdapterEntry { - /// Classify the location of this artifact for display purposes. - /// - /// - `"Onde Inference"`: inside the shared App Group container - /// - `"HF Cache"`: inside `~/.cache/huggingface/hub` or `$HF_HOME` - /// - the raw path string: anything else, usually a custom or local export - pub fn location_label(&self) -> String { - let path_str = self.path.to_string_lossy(); +/// Classify a filesystem path into a short, human-friendly location label. +/// +/// Long absolute paths (e.g. the App Group container) get truncated to +/// gibberish in narrow TUI fields, so anywhere we'd otherwise print a raw +/// path we show this label instead. +/// +/// - `"Onde Inference"`: inside the shared App Group container +/// - `"HF Cache"`: inside `~/.cache/huggingface/hub` or `$HF_HOME` +/// - the parent directory string: anything else, usually a custom or local export +pub fn location_label_for_path(path: &std::path::Path) -> String { + let path_str = path.to_string_lossy(); + + // App Group container (macOS) + if path_str.contains("group.com.ondeinference.apps") { + return "Onde Inference".to_string(); + } - // App Group container (macOS) - if path_str.contains("group.com.ondeinference.apps") { - return "Onde Inference".to_string(); - } + // Standard HF cache locations + if path_str.contains(".cache/huggingface/hub") { + return "HF Cache".to_string(); + } + if let Ok(hf_home) = std::env::var("HF_HOME") + && path_str.starts_with(&hf_home) + { + return "HF Cache".to_string(); + } - // Standard HF cache locations - if path_str.contains(".cache/huggingface/hub") { - return "HF Cache".to_string(); - } - if let Ok(hf_home) = std::env::var("HF_HOME") - && path_str.starts_with(&hf_home) - { - return "HF Cache".to_string(); - } + // For custom or local paths, just show the directory. + path.parent() + .map(|p| p.to_string_lossy().to_string()) + .unwrap_or_else(|| path_str.to_string()) +} - // For custom or local paths, just show the directory. - self.path - .parent() - .map(|p| p.to_string_lossy().to_string()) - .unwrap_or_else(|| path_str.to_string()) +impl AdapterEntry { + /// Classify the location of this artifact for display purposes. + /// See [`location_label_for_path`]. + pub fn location_label(&self) -> String { + location_label_for_path(&self.path) } /// Whether this GGUF should show the upload-to-HuggingFace UI. diff --git a/src/ui.rs b/src/ui.rs index 09e109d..3c4f0b7 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1860,10 +1860,21 @@ fn render_finetune_done(frame: &mut Frame, app: &App, adapter_path: &std::path:: .style(Style::new().bg(C_SURFACE_STRONG)); let path_inner = path_block.inner(rows[3]); frame.render_widget(path_block, rows[3]); + // Show a friendly location badge plus the file name instead of the raw + // absolute path, which truncates to gibberish in this narrow box. + let adapter_file = adapter_path + .file_name() + .map(|n| n.to_string_lossy().to_string()) + .unwrap_or_default(); frame.render_widget( - Paragraph::new(adapter_path.to_string_lossy().to_string()) - .style(Style::new().fg(C_NEON)) - .wrap(Wrap { trim: true }), + Paragraph::new(Line::from(vec![ + Span::styled( + format!("[{}]", crate::app::location_label_for_path(adapter_path)), + Style::new().fg(C_NEON).bold(), + ), + Span::styled(format!(" {adapter_file}"), Style::new().fg(C_TEXT)), + ])) + .wrap(Wrap { trim: true }), path_inner, ); @@ -1938,8 +1949,8 @@ fn render_merge_gguf_section(frame: &mut Frame, app: &App, area: Rect) { Span::styled("✓ ", Style::new().fg(C_NEON)), Span::styled("Merged → ", Style::new().fg(C_NEON).bold()), Span::styled( - output_path.to_string_lossy().to_string(), - Style::new().fg(C_TEXT), + format!("[{}]", crate::app::location_label_for_path(output_path)), + Style::new().fg(C_TEXT).bold(), ), ])), rows[0],