aboutsummaryrefslogtreecommitdiffstats
path: root/src/state.rs
blob: 1268574b1c377e65fca6cd349d4282549e7f2ad3 (plain) (blame)
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
pub struct State<'a, T: crate::callbacks::Callbacks> {
    screen: &'a mut crate::perform::WrappedScreen,
    callbacks: &'a mut T,
}

impl<'a, T: crate::callbacks::Callbacks> State<'a, T> {
    pub fn new(
        screen: &'a mut crate::perform::WrappedScreen,
        callbacks: &'a mut T,
    ) -> Self {
        Self { screen, callbacks }
    }
}

impl<'a, T: crate::callbacks::Callbacks> vte::Perform for State<'a, T> {
    fn print(&mut self, c: char) {
        if c == '\u{fffd}' || ('\u{80}'..'\u{a0}').contains(&c) {
            self.callbacks.error(&mut self.screen.0);
        }
        self.screen.print(c);
    }

    fn execute(&mut self, b: u8) {
        match b {
            7 => self.callbacks.audible_bell(&mut self.screen.0),
            8..=15 => {}
            _ => {
                self.callbacks.error(&mut self.screen.0);
            }
        }
        self.screen.execute(b);
    }

    fn esc_dispatch(&mut self, intermediates: &[u8], ignore: bool, b: u8) {
        if intermediates.is_empty() && b == b'g' {
            self.callbacks.visual_bell(&mut self.screen.0);
        }
        self.screen.esc_dispatch(intermediates, ignore, b);
    }

    fn csi_dispatch(
        &mut self,
        params: &vte::Params,
        intermediates: &[u8],
        ignore: bool,
        c: char,
    ) {
        if intermediates.first().is_none() && c == 't' {
            let mut iter = params.iter();
            let op = iter.next().and_then(|x| x.first().copied());
            if op == Some(8) {
                let (screen_rows, screen_cols) = self.screen.0.size();
                let rows = iter.next().map_or(screen_rows, |x| {
                    *x.first().unwrap_or(&screen_rows)
                });
                let cols = iter.next().map_or(screen_cols, |x| {
                    *x.first().unwrap_or(&screen_cols)
                });
                self.callbacks.resize(&mut self.screen.0, (rows, cols));
            }
        }
        self.screen.csi_dispatch(params, intermediates, ignore, c);
    }

    fn osc_dispatch(&mut self, params: &[&[u8]], bel_terminated: bool) {
        self.screen.osc_dispatch(params, bel_terminated);
    }

    fn hook(
        &mut self,
        params: &vte::Params,
        intermediates: &[u8],
        ignore: bool,
        action: char,
    ) {
        self.screen.hook(params, intermediates, ignore, action);
    }
}