1use alacritty_terminal::event::EventListener;
10use alacritty_terminal::grid::Dimensions;
11use alacritty_terminal::index::Line;
12use alacritty_terminal::term::Term;
13use alacritty_terminal::vte::ansi::{
14 Attr, CharsetIndex, ClearMode, CursorShape, CursorStyle, Handler, Hyperlink, KeyboardModes,
15 KeyboardModesApplyBehavior, LineClearMode, Mode, ModifyOtherKeys, PrivateMode, Processor, Rgb,
16 ScpCharPath, ScpUpdateMode, StandardCharset, TabulationClearMode,
17};
18
19pub(crate) fn advance<T: EventListener>(
22 parser: &mut Processor,
23 term: &mut Term<T>,
24 bytes: &[u8],
25 history: usize,
26 appended: &mut u64,
27) {
28 let mut counted = Counted::new(term, history);
29 parser.advance(&mut counted, bytes);
30 *appended = appended.saturating_add(counted.finish());
31}
32
33struct Counted<'a, T: EventListener> {
35 term: &'a mut Term<T>,
36 total: usize,
38 history: usize,
40 scrolled: u64,
42}
43
44impl<'a, T: EventListener> Counted<'a, T> {
45 fn new(term: &'a mut Term<T>, history: usize) -> Self {
46 let total = term.grid().total_lines();
47 Self { term, total, history, scrolled: 0 }
48 }
49
50 fn finish(self) -> u64 {
53 let growth = self.term.grid().total_lines().saturating_sub(self.total);
54 u64::try_from(growth).unwrap_or(u64::MAX).saturating_add(self.scrolled)
55 }
56
57 fn scrolled_linefeed(&mut self, scrolls: impl FnOnce(&mut Term<T>)) {
61 let before = self.term.grid().cursor.point.line;
62 scrolls(self.term);
63 let grid = self.term.grid();
64 let last = Line(i32::try_from(grid.screen_lines().saturating_sub(1)).unwrap_or(i32::MAX));
65 let full = grid.total_lines() >= grid.screen_lines() + self.history;
66 if grid.cursor.point.line == before && before == last && full {
67 self.scrolled = self.scrolled.saturating_add(1);
68 }
69 }
70}
71
72macro_rules! forward {
73 ($($name:ident($($arg:ident: $ty:ty),*);)*) => {
74 $(
75 fn $name(&mut self, $($arg: $ty),*) {
76 self.term.$name($($arg),*);
77 }
78 )*
79 };
80}
81
82impl<T: EventListener> Handler for Counted<'_, T> {
83 fn linefeed(&mut self) {
84 self.scrolled_linefeed(Handler::linefeed);
85 }
86
87 fn newline(&mut self) {
88 self.scrolled_linefeed(Handler::newline);
89 }
90
91 forward!(
92 set_title(a0: Option<String>);
93 set_cursor_style(a0: Option<CursorStyle>);
94 set_cursor_shape(a0: CursorShape);
95 input(a0: char);
96 goto(a0: i32, a1: usize);
97 goto_line(a0: i32);
98 goto_col(a0: usize);
99 insert_blank(a0: usize);
100 move_up(a0: usize);
101 move_down(a0: usize);
102 identify_terminal(a0: Option<char>);
103 device_status(a0: usize);
104 move_forward(a0: usize);
105 move_backward(a0: usize);
106 move_down_and_cr(a0: usize);
107 move_up_and_cr(a0: usize);
108 put_tab(a0: u16);
109 backspace();
110 carriage_return();
111 bell();
112 substitute();
113 set_horizontal_tabstop();
114 scroll_up(a0: usize);
115 scroll_down(a0: usize);
116 insert_blank_lines(a0: usize);
117 delete_lines(a0: usize);
118 erase_chars(a0: usize);
119 delete_chars(a0: usize);
120 move_backward_tabs(a0: u16);
121 move_forward_tabs(a0: u16);
122 save_cursor_position();
123 restore_cursor_position();
124 clear_line(a0: LineClearMode);
125 clear_screen(a0: ClearMode);
126 clear_tabs(a0: TabulationClearMode);
127 set_tabs(a0: u16);
128 reset_state();
129 reverse_index();
130 terminal_attribute(a0: Attr);
131 set_mode(a0: Mode);
132 unset_mode(a0: Mode);
133 report_mode(a0: Mode);
134 set_private_mode(a0: PrivateMode);
135 unset_private_mode(a0: PrivateMode);
136 report_private_mode(a0: PrivateMode);
137 set_scrolling_region(a0: usize, a1: Option<usize>);
138 set_keypad_application_mode();
139 unset_keypad_application_mode();
140 set_active_charset(a0: CharsetIndex);
141 configure_charset(a0: CharsetIndex, a1: StandardCharset);
142 set_color(a0: usize, a1: Rgb);
143 dynamic_color_sequence(a0: String, a1: usize, a2: &str);
144 reset_color(a0: usize);
145 clipboard_store(a0: u8, a1: &[u8]);
146 clipboard_load(a0: u8, a1: &str);
147 decaln();
148 push_title();
149 pop_title();
150 text_area_size_pixels();
151 text_area_size_chars();
152 set_hyperlink(a0: Option<Hyperlink>);
153 report_keyboard_mode();
154 push_keyboard_mode(a0: KeyboardModes);
155 pop_keyboard_modes(a0: u16);
156 set_keyboard_mode(a0: KeyboardModes, a1: KeyboardModesApplyBehavior);
157 set_modify_other_keys(a0: ModifyOtherKeys);
158 report_modify_other_keys();
159 set_scp(a0: ScpCharPath, a1: ScpUpdateMode);
160 );
161}