termina/escape/
osc.rs

1// CREDIT: this is a quite shallow copy of <https://github.com/wezterm/wezterm/blob/a87358516004a652ad840bc1661bdf65ffc89b43/termwiz/src/escape/osc.rs>.
2// I've replaced some macros and the base64 implementation however, as well as make the commands
3// borrow a `str` instead of own a `String`.
4
5use std::fmt::{self, Display};
6
7use crate::base64;
8
9pub enum Osc<'a> {
10    SetIconNameAndWindowTitle(&'a str),
11    SetWindowTitle(&'a str),
12    SetWindowTitleSun(&'a str),
13    SetIconName(&'a str),
14    SetIconNameSun(&'a str),
15    ClearSelection(Selection),
16    QuerySelection(Selection),
17    SetSelection(Selection, &'a str),
18    // TODO: I didn't copy many available commands yet...
19}
20
21impl Display for Osc<'_> {
22    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23        f.write_str(super::OSC)?;
24        match self {
25            Self::SetIconNameAndWindowTitle(s) => write!(f, "0;{s}")?,
26            Self::SetWindowTitle(s) => write!(f, "2;{s}")?,
27            Self::SetWindowTitleSun(s) => write!(f, "l{s}")?,
28            Self::SetIconName(s) => write!(f, "1;{s}")?,
29            Self::SetIconNameSun(s) => write!(f, "L{s}")?,
30            Self::ClearSelection(selection) => write!(f, "52;{selection}")?,
31            Self::QuerySelection(selection) => write!(f, "52;{selection};?")?,
32            Self::SetSelection(selection, content) => {
33                // TODO: it'd be nice to avoid allocating a string to base64 encode.
34                write!(f, "52;{selection};{}", base64::encode(content.as_bytes()))?
35            }
36        }
37        f.write_str(super::ST)?;
38        Ok(())
39    }
40}
41
42bitflags::bitflags! {
43    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
44    pub struct Selection : u16 {
45        const NONE = 0;
46        const CLIPBOARD = 1<<1;
47        const PRIMARY=1<<2;
48        const SELECT=1<<3;
49        const CUT0=1<<4;
50        const CUT1=1<<5;
51        const CUT2=1<<6;
52        const CUT3=1<<7;
53        const CUT4=1<<8;
54        const CUT5=1<<9;
55        const CUT6=1<<10;
56        const CUT7=1<<11;
57        const CUT8=1<<12;
58        const CUT9=1<<13;
59    }
60}
61
62impl Display for Selection {
63    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64        if self.contains(Self::CLIPBOARD) {
65            write!(f, "c")?;
66        }
67        if self.contains(Self::PRIMARY) {
68            write!(f, "p")?;
69        }
70        if self.contains(Self::SELECT) {
71            write!(f, "s")?;
72        }
73        if self.contains(Self::CUT0) {
74            write!(f, "0")?;
75        }
76        if self.contains(Self::CUT1) {
77            write!(f, "1")?;
78        }
79        if self.contains(Self::CUT2) {
80            write!(f, "2")?;
81        }
82        if self.contains(Self::CUT3) {
83            write!(f, "3")?;
84        }
85        if self.contains(Self::CUT4) {
86            write!(f, "4")?;
87        }
88        if self.contains(Self::CUT5) {
89            write!(f, "5")?;
90        }
91        if self.contains(Self::CUT6) {
92            write!(f, "6")?;
93        }
94        if self.contains(Self::CUT7) {
95            write!(f, "7")?;
96        }
97        if self.contains(Self::CUT8) {
98            write!(f, "8")?;
99        }
100        if self.contains(Self::CUT9) {
101            write!(f, "9")?;
102        }
103        Ok(())
104    }
105}