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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//! Caller-owned OSC 1 fallback for hosts with no native icon backend.
//!
//! # What this is, and what it is not
//!
//! `OSC 1` is the xterm "set icon name" sequence. It sets a *name*, not an
//! image — the terminal decides what, if anything, to do with it. Some window
//! managers surface it as the iconified window's label; most modern emulators
//! ignore it outright.
//!
//! So this is deliberately a fallback of last resort, and deliberately narrow:
//!
//! - It is only emitted for [`IconSource::Stock`], because a stock name is the
//! one source that already *is* a symbolic name. Emitting bytes for a `.ico`
//! file would mean inventing a name the caller never chose.
//! - It is reported as [`IconSupport::Degraded`], never `Available`, so a
//! caller is told plainly that the host may ignore it. Reporting it as
//! available would be the worst outcome: a caller that checked support,
//! got a yes, and saw nothing change has no way to tell whether the icon
//! failed or the terminal simply does not do icons.
//!
//! [`IconSource::Stock`]: super::IconSource
//! [`IconSupport::Degraded`]: super::IconSupport
use Write as _;
/// Render the OSC 1 sequence for `name`.
///
/// `ESC ] 1 ; <name> BEL`. The BEL terminator is used rather than `ESC \`
/// because it is what xterm documents and what the widest range of emulators
/// parse; a terminal that does not understand the sequence discards it either
/// way.
/// Strip anything that would end the sequence early or start a new one.
///
/// A name carrying `ESC`, `BEL`, or a C0 control would terminate the OSC
/// mid-string and let the remainder be interpreted as terminal commands. The
/// names this crate emits are its own stock identifiers, so nothing hostile is
/// expected — but a sanitizer that only runs on untrusted input is one that
/// stops running the moment the input's provenance changes.
/// Longest icon name emitted.
///
/// Bounded because the sequence goes to a terminal that has to buffer it, and
/// an unbounded name from a caller is an unbounded write into someone else's
/// parser.
const MAX_NAME_CHARS: usize = 128;
/// Write the OSC 1 sequence for `name` to stdout.
///
/// Stdout rather than stderr: the sequence is addressed to the terminal
/// attached to this process's output, and a caller that redirected stdout to a
/// file has, by doing so, said there is no terminal to talk to.