fn csi_dispatch()

in crates/alacritty_terminal/src/ansi.rs [1279:1447]


    fn csi_dispatch(&mut self, params: &Params, intermediates: &[u8], has_ignored_intermediates: bool, action: char) {
        macro_rules! unhandled {
            () => {{
                if self
                    .handler
                    .unhandled_csi_dispatch(params, intermediates, has_ignored_intermediates, action)
                    == HandledStatus::Unhandled
                {
                    debug!(
                        "[Unhandled CSI] action={:?}, params={:?}, intermediates={:?}",
                        action, params, intermediates
                    );
                }
            }};
        }

        if has_ignored_intermediates || intermediates.len() > 1 {
            unhandled!();
            return;
        }

        let mut params_iter = params.iter();

        let mut next_param_or = |default: u16| {
            params_iter
                .next()
                .map(|param| param[0])
                .filter(|&param| param != 0)
                .unwrap_or(default)
        };

        match (action, intermediates) {
            ('@', []) => self.handler.insert_blank(next_param_or(1) as usize),
            ('A', []) => self.handler.move_up(next_param_or(1) as usize),
            ('B' | 'e', []) => self.handler.move_down(next_param_or(1) as usize),
            ('b', []) => {
                if let Some(c) = self.state.preceding_char {
                    for _ in 0..next_param_or(1) {
                        self.handler.input(c);
                    }
                } else {
                    debug!("tried to repeat with no preceding char");
                }
            },
            ('C' | 'a', []) => self.handler.move_forward(Column(next_param_or(1) as usize)),
            ('D', []) => self.handler.move_backward(Column(next_param_or(1) as usize)),
            ('d', []) => self.handler.goto_line(Line(next_param_or(1) as i32 - 1)),
            ('E', []) => self.handler.move_down_and_cr(next_param_or(1) as usize),
            ('F', []) => self.handler.move_up_and_cr(next_param_or(1) as usize),
            ('G' | '`', []) => self.handler.goto_col(Column(next_param_or(1) as usize - 1)),
            ('g', []) => {
                let mode = match next_param_or(0) {
                    0 => TabulationClearMode::Current,
                    3 => TabulationClearMode::All,
                    _ => {
                        unhandled!();
                        return;
                    },
                };

                self.handler.clear_tabs(mode);
            },
            ('H' | 'f', []) => {
                let y = next_param_or(1) as i32;
                let x = next_param_or(1) as usize;
                self.handler.goto(Line(y - 1), Column(x - 1));
            },
            ('h', intermediates) => {
                for param in params_iter.map(|param| param[0]) {
                    match Mode::from_primitive(intermediates.first(), param) {
                        Some(mode) => self.handler.set_mode(mode),
                        None => unhandled!(),
                    }
                }
            },
            ('I', []) => self.handler.move_forward_tabs(next_param_or(1)),
            ('J', []) => {
                let mode = match next_param_or(0) {
                    0 => ClearMode::Below,
                    1 => ClearMode::Above,
                    2 => ClearMode::All,
                    3 => ClearMode::Saved,
                    _ => {
                        unhandled!();
                        return;
                    },
                };

                self.handler.clear_screen(mode);
            },
            ('K', []) => {
                let mode = match next_param_or(0) {
                    0 => LineClearMode::Right,
                    1 => LineClearMode::Left,
                    2 => LineClearMode::All,
                    _ => {
                        unhandled!();
                        return;
                    },
                };

                self.handler.clear_line(mode);
            },
            ('L', []) => self.handler.insert_blank_lines(next_param_or(1) as usize),
            ('l', intermediates) => {
                for param in params_iter.map(|param| param[0]) {
                    match Mode::from_primitive(intermediates.first(), param) {
                        Some(mode) => self.handler.unset_mode(mode),
                        None => unhandled!(),
                    }
                }
            },
            ('M', []) => self.handler.delete_lines(next_param_or(1) as usize),
            ('m', []) => {
                if params.is_empty() {
                    self.handler.terminal_attribute(Attr::Reset);
                } else {
                    for attr in attrs_from_sgr_parameters(&mut params_iter) {
                        match attr {
                            Some(attr) => self.handler.terminal_attribute(attr),
                            None => unhandled!(),
                        }
                    }
                }
            },
            ('P', []) => self.handler.delete_chars(next_param_or(1) as usize),
            ('q', [b' ']) => {
                // DECSCUSR (CSI Ps SP q) -- Set Cursor Style.
                let cursor_style_id = next_param_or(0);
                let shape = match cursor_style_id {
                    0 => None,
                    1 | 2 => Some(CursorShape::Block),
                    3 | 4 => Some(CursorShape::Underline),
                    5 | 6 => Some(CursorShape::Beam),
                    _ => {
                        unhandled!();
                        return;
                    },
                };
                let cursor_style = shape.map(|shape| CursorStyle {
                    shape,
                    blinking: cursor_style_id % 2 == 1,
                });

                self.handler.set_cursor_style(cursor_style);
            },
            ('r', []) => {
                let top = next_param_or(1) as usize;
                let bottom = params_iter
                    .next()
                    .map(|param| param[0] as usize)
                    .filter(|&param| param != 0);

                self.handler.set_scrolling_region(top, bottom);
            },
            ('S', []) => self.handler.scroll_up(next_param_or(1) as usize),
            ('s', []) => self.handler.save_cursor_position(),
            ('T', []) => self.handler.scroll_down(next_param_or(1) as usize),
            ('t', []) => match next_param_or(1) as usize {
                22 => self.handler.push_title(),
                23 => self.handler.pop_title(),
                _ => unhandled!(),
            },
            ('u', []) => self.handler.restore_cursor_position(),
            ('X', []) => self.handler.erase_chars(Column(next_param_or(1) as usize)),
            ('Z', []) => self.handler.move_backward_tabs(next_param_or(1)),
            _ => unhandled!(),
        }
    }