1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//! OSC-8 hyperlink escape sequences.
//!
//! OSC-8 is a terminal escape sequence that makes a span of text
//! clickable in supporting terminals (iTerm2, kitty, recent xterm,
//! WezTerm, Alacritty, VTE-based). The format is:
//!
//! ```text
//! ESC ]8;;<url> ESC \ <text> ESC ]8;; ESC \
//! ```
//!
//! # Scope in symbi-shell
//!
//! The sequences contain escape chars that [`unicode_width`] (and
//! therefore ratatui) counts as printable. Embedding OSC-8 inside a
//! ratatui `Span` breaks column widths, truncation, and popup
//! alignment — so we deliberately **do not** use OSC-8 inside the
//! live viewport or `insert_before`-rendered lines.
//!
//! We only use OSC-8 for plain `println!` paths that run *after* the
//! ratatui terminal has been dropped — the session-saved resume hint,
//! CLI early-exit listings, and similar one-shot output. In those
//! contexts the terminal handles the escape as intended and the extra
//! chars don't collide with any TUI layout math.
//!
//! [`unicode_width`]: https://docs.rs/unicode-width/
use Path;
/// Emit text wrapped in an OSC-8 hyperlink to `url`. Supporting
/// terminals render `text` as clickable; others display `text` as
/// plain text (the escape sequence is invisible even when unsupported,
/// so it's safe to always include).
///
/// Caller is responsible for deciding whether this output will end up
/// somewhere safe to interpret OSC-8 (see module docs — do NOT feed
/// this into a ratatui Span).
/// Convenience: turn a filesystem path into a `file://` hyperlink.
/// If the path can't be made absolute, emit `text` unwrapped.
/// Best-effort check that stdout is a terminal that will render OSC-8.
///
/// We treat a non-TTY stdout as "don't emit" because escape sequences
/// leak into pipes/logs as junk. Terminals without OSC-8 support see
/// the sequences as no-ops so true/true is safe; false/true would clog
/// a pipe.