todo_tree/printer/
utils.rs1use super::options::PrintOptions;
2use crate::utils::display::priority_to_color;
3use colored::Colorize;
4use std::path::Path;
5use todo_tree_core::Priority;
6
7pub fn format_path(path: &Path, options: &PrintOptions) -> String {
8 if options.full_paths {
9 path.display().to_string()
10 } else if let Some(base) = &options.base_path {
11 path.strip_prefix(base)
12 .map(|p| p.display().to_string())
13 .unwrap_or_else(|_| path.display().to_string())
14 } else {
15 path.display().to_string()
16 }
17}
18
19pub fn make_clickable_link(path: &Path, line: usize, options: &PrintOptions) -> Option<String> {
20 if !options.clickable_links || !supports_hyperlinks() {
21 return None;
22 }
23
24 let display_path = format_path(path, options);
25 let abs_path = path.canonicalize().ok()?;
26 let file_url = format!("file://{}:{}", abs_path.display(), line);
27
28 let link = format!(
29 "\x1b]8;;{}\x1b\\{}\x1b]8;;\x1b\\",
30 file_url,
31 if options.colored {
32 display_path.bold().to_string()
33 } else {
34 display_path
35 }
36 );
37
38 Some(link)
39}
40
41pub fn make_line_link(path: &Path, line: usize, options: &PrintOptions) -> Option<String> {
42 if !options.clickable_links || !supports_hyperlinks() {
43 return None;
44 }
45
46 let abs_path = path.canonicalize().ok()?;
47 let file_url = format!("file://{}:{}", abs_path.display(), line);
48 let display = format!("L{}", line);
49
50 let link = format!(
51 "\x1b]8;;{}\x1b\\{}\x1b]8;;\x1b\\",
52 file_url,
53 if options.colored {
54 display.cyan().to_string()
55 } else {
56 display
57 }
58 );
59
60 Some(link)
61}
62
63pub fn colorize_tag(tag: &str, options: &PrintOptions) -> String {
64 if !options.colored {
65 return tag.to_string();
66 }
67
68 let color = priority_to_color(Priority::from_tag(tag));
69 tag.color(color).bold().to_string()
70}
71
72fn supports_hyperlinks() -> bool {
73 if let Ok(term_program) = std::env::var("TERM_PROGRAM") {
74 let supported_terminals = [
75 "iTerm.app",
76 "WezTerm",
77 "Hyper",
78 "Tabby",
79 "Alacritty",
80 "vscode",
81 "VSCodium",
82 "Ghostty",
83 ];
84 if supported_terminals.iter().any(|t| term_program.contains(t)) {
85 return true;
86 }
87 }
88
89 if let Ok(colorterm) = std::env::var("COLORTERM")
90 && (colorterm == "truecolor" || colorterm == "24bit")
91 {
92 return true;
93 }
94
95 if std::env::var("VTE_VERSION").is_ok() {
96 return true;
97 }
98
99 if std::env::var("KONSOLE_VERSION").is_ok() {
100 return true;
101 }
102
103 false
104}