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(|¶m| 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(|¶m| 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!(),
}
}