1extern crate base64;
18
19use base64::encode;
20use std::io::stdout;
21use std::io::Write;
22
23pub type TerminalError = Result<(), std::io::Error>;
24
25#[derive(Debug, Clone, Copy)]
27pub enum CursorShape {
28 Block,
30 VerticalBar,
32 Underline,
34}
35
36#[derive(Debug, Clone, Copy)]
38pub enum AttentionType {
39 Yes,
41 No,
43 Firework,
45}
46
47pub fn anchor(url: &str, display_text: &str) -> TerminalError {
49 stdout().write_all(format!("\x1b]8;;{}\x07{}\x1b]8;;\x07", url, display_text).as_bytes())
50}
51
52pub fn set_cursor_shape(shape: CursorShape) -> TerminalError {
54 use CursorShape::*;
55 let shape_val = match shape {
56 Block => 0,
57 VerticalBar => 1,
58 Underline => 2,
59 };
60 stdout().write_all(format!("\x1b]1337;CursorShape={}\x07", shape_val).as_bytes())
61}
62
63pub fn set_mark() -> TerminalError {
65 stdout().write_all(b"\x1b]1337;SetMark\x07")
66}
67
68pub fn steal_focus() -> TerminalError {
70 stdout().write_all(b"\x1b]1337;StealFocus\x07")
71}
72
73pub fn clear_scrollback() -> TerminalError {
75 stdout().write_all(b"\x1b]1337;ClearScrollback\x07")
76}
77
78pub fn set_current_dir(dir: &str) -> TerminalError {
80 stdout().write_all(format!("\x1b]1337;CurrentDir={}\x07", dir).as_bytes())
81}
82
83pub fn send_notification(message: &str) -> TerminalError {
85 stdout().write_all(format!("\x1b]9;{}\x07", message).as_bytes())
86}
87
88pub fn set_clipboard(text: &str) -> TerminalError {
91 stdout().write_all(b"\x1b]1337;CopyToClipboard=\x07")?;
92 stdout().write_all(text.as_bytes())?;
93 stdout().write_all(b"\n\x1b]1337;EndCopy\x07")
94}
95
96pub fn set_tab_colors(red: u8, green: u8, blue: u8) -> TerminalError {
98 stdout().write_all(format!("\x1b]6;1;bg;red;brightness;{}\x07", red).as_bytes())?;
99 stdout().write_all(format!("\x1b]6;1;bg;green;brightness;{}\x07", green).as_bytes())?;
100 stdout().write_all(format!("\x1b]6;1;bg;blue;brightness;{}\x07", blue).as_bytes())
101}
102
103pub fn restore_tab_colors() -> TerminalError {
105 stdout().write_all(b"\x1b]6;1;bg;*;default\x07")
106}
107
108pub fn set_color_palette(colors: &str) -> TerminalError {
113 stdout().write_all(format!("\x1b]1337;SetColors={}\x07", colors).as_bytes())
114}
115
116pub struct Annotation {
118 message: String,
119 length: Option<usize>,
120 xcoord: Option<usize>,
121 ycoord: Option<usize>,
122 hidden: bool,
123}
124
125impl Annotation {
126 pub fn new(message: &str) -> Annotation {
128 Annotation {
129 message: message.to_owned(),
130 length: None,
131 xcoord: None,
132 ycoord: None,
133 hidden: false,
134 }
135 }
136
137 pub fn length(&mut self, length: usize) -> &mut Annotation {
139 self.length = Some(length);
140 self
141 }
142
143 pub fn coords(&mut self, x: usize, y: usize) -> &mut Annotation {
145 self.xcoord = Some(x);
146 self.ycoord = Some(y);
147 self
148 }
149
150 pub fn hidden(&mut self, hide: bool) -> &mut Annotation {
152 self.hidden = hide;
153 self
154 }
155
156 pub fn show(&self) -> TerminalError {
158 let value = match self {
159 Annotation {
160 message: msg,
161 length: None,
162 xcoord: None,
163 ycoord: None,
164 ..
165 } => msg.to_owned(),
166 Annotation {
167 message: msg,
168 length: Some(len),
169 xcoord: None,
170 ycoord: None,
171 ..
172 } => format!("{}|{}", len, msg),
173 Annotation {
174 message: msg,
175 length: Some(len),
176 xcoord: Some(x),
177 ycoord: Some(y),
178 ..
179 } => format!("{}|{}|{}|{}", msg, len, x, y),
180 _ => panic!("Invalid parameters"), };
182 let key = if self.hidden {
183 "AddHiddenAnnotation"
184 } else {
185 "AddAnnotation"
186 };
187 stdout().write_all(format!("\x1b]1337;{}={}\x07", key, value).as_bytes())
188 }
189}
190
191pub fn cursor_guide(show: bool) -> TerminalError {
193 let value = if show { "yes" } else { "no" };
194 stdout().write_all(format!("\x1b]1337;HighlightCursorLine={}\x07", value).as_bytes())
195}
196
197pub fn attention(kind: AttentionType) -> TerminalError {
199 use AttentionType::*;
200 let value = match kind {
201 Yes => "yes",
202 No => "no",
203 Firework => "fireworks",
204 };
205 stdout().write_all(format!("\x1b]1337;RequestAttention={}\x07", value).as_bytes())
206}
207
208pub fn set_background_image(filename: &str) -> TerminalError {
210 let base64_filename = encode(filename.as_bytes());
211 stdout()
212 .write_all(format!("\x1b]1337;SetBackgroundImageFile={}\x07", base64_filename).as_bytes())
213}
214
215#[allow(unused_variables)]
220pub fn get_cell_size(filename: &str) -> Result<(f32, f32), std::io::Error> {
221 unimplemented!()
222}
223
224#[allow(unused_variables)]
229pub fn get_terminal_variable(filename: &str) -> Result<String, std::io::Error> {
230 unimplemented!()
231}
232
233pub fn download_file(args: &[(&str, &str)], img_data: &[u8]) -> TerminalError {
237 let joined_args = args
238 .iter()
239 .map(|item| format!("{}={}", item.0, item.1))
240 .collect::<Vec<_>>()
241 .join(";");
242 stdout().write_all(format!("\x1b]1337;File={}:", joined_args).as_bytes())?;
243
244 let encoded_data = base64::encode(img_data);
245 stdout().write_all(&encoded_data.as_bytes())?;
246 stdout().write_all(b"\x07")
247}
248
249pub fn set_touchbar_key_label(key: &str, value: &str) -> TerminalError {
253 stdout().write_all(format!("\x1b]1337;SetKeyLabel={}={}\x07", key, value).as_bytes())
254}
255
256pub fn push_current_touchbar_labels() -> TerminalError {
258 stdout().write_all(b"\x1b]1337;PushKeyLabels\x07")
259}
260
261pub fn pop_current_touchbar_labels() -> TerminalError {
263 stdout().write_all(b"\x1b]1337;PopKeyLabels\x07")
264}
265
266pub fn push_touchbar_label(label: &str) -> TerminalError {
268 stdout().write_all(format!("\x1b1337;PushKeyLabels={}\x07", label).as_bytes())
269}
270
271pub fn pop_touchbar_label(label: &str) -> TerminalError {
273 stdout().write_all(format!("\x1b1337;PopKeyLabels={}\x07", label).as_bytes())
274}
275
276pub fn set_unicode_version(version: u8) -> TerminalError {
278 stdout().write_all(format!("\x1b1337;UnicodeVersion={}\x07", version).as_bytes())
279}