some more ansi parsing improvements

This commit is contained in:
Michael Sippel 2021-11-09 02:56:21 +01:00
parent 4ad8316636
commit 43321d18fb
Signed by: senvas
GPG key ID: F96CF119C34B64A6

View file

@ -29,7 +29,7 @@ pub fn read_ansi_from<R: Read + Unpin>(ansi_reader: &mut R, port: InnerViewPort<
invert: false, invert: false,
term_width: 80, term_width: 80,
cursor_stack: Vec::new(), cursor_save: Point2::new(0, 0),
buf: IndexBuffer::new(port), buf: IndexBuffer::new(port),
@ -81,7 +81,7 @@ struct PerfAtom {
cursor: Point2<i16>, cursor: Point2<i16>,
style: TerminalStyle, style: TerminalStyle,
invert: bool, invert: bool,
cursor_stack: Vec<Point2<i16>>, cursor_save: Point2<i16>,
buf: IndexBuffer<Point2<i16>, TerminalAtom>, buf: IndexBuffer<Point2<i16>, TerminalAtom>,
} }
@ -104,11 +104,41 @@ impl PerfAtom {
style style
} }
fn linefeed(&mut self) {
self.cursor.x = 0;
self.cursor.y += 1;
}
fn carriage_return(&mut self) {
self.cursor.x = 0;
}
fn horizontal_tab(&mut self) {
self.cursor.x += 8 - (self.cursor.x % 8);
}
fn backspace(&mut self) {
self.write_atom(self.cursor, None);
self.cursor.x -= 1;
if self.cursor.x < 0 {
self.cursor.y -= 0;
self.cursor.x = self.term_width - 1;
}
}
fn cursor_up(&mut self, n: usize) { fn cursor_up(&mut self, n: usize) {
} }
fn cursor_down(&mut self, n: usize) { fn cursor_down(&mut self, n: usize) {
} }
fn save_cursor_position(&mut self) {
self.cursor_save = self.cursor;
}
fn restore_cursor_position(&mut self) {
self.cursor = self.cursor_save;
}
} }
impl Perform for PerfAtom { impl Perform for PerfAtom {
@ -124,31 +154,10 @@ impl Perform for PerfAtom {
fn execute(&mut self, byte: u8) { fn execute(&mut self, byte: u8) {
match byte { match byte {
// linefeed b'\n' => self.linefeed(),
b'\n' => { b'\r' => self.carriage_return(),
self.cursor.x = 0; b'\t' => self.horizontal_tab(),
self.cursor.y += 1; 0x8 => self.backspace(),
},
// carriage return
b'\r' => {
self.cursor.x = 0;
},
// horizontal tab
b'\t' => {
self.cursor.x += 8 - (self.cursor.x % 8);
},
// backspace
0x8 => {
self.cursor.x -= 1;
if self.cursor.x < 0 {
self.cursor.y -= 0;
self.cursor.x = self.term_width - 1;
}
}
_ => { _ => {
eprintln!("unhandled execute byte {:02x}", byte); eprintln!("unhandled execute byte {:02x}", byte);
} }
@ -177,15 +186,7 @@ impl Perform for PerfAtom {
} }
fn csi_dispatch(&mut self, params: &Params, intermediates: &[u8], ignore: bool, c: char) { fn csi_dispatch(&mut self, params: &Params, intermediates: &[u8], ignore: bool, c: char) {
/*
eprintln!(
"[csi_dispatch] params={:#?}, intermediates={:?}, ignore={:?}, char={:?}",
params, intermediates, ignore, c
);
*/
let mut piter = params.into_iter(); let mut piter = params.into_iter();
match c { match c {
// Set SGR // Set SGR
'm' => while let Some(n) = piter.next() { 'm' => while let Some(n) = piter.next() {
@ -224,7 +225,7 @@ impl Perform for PerfAtom {
let r = piter.next().unwrap(); let r = piter.next().unwrap();
let g = piter.next().unwrap(); let g = piter.next().unwrap();
let b = piter.next().unwrap(); let b = piter.next().unwrap();
self.style = self.style.add(TerminalStyle::fg_color((r[0] as u8, g[0] as u8, b[30] as u8))) self.style = self.style.add(TerminalStyle::fg_color((r[0] as u8, g[0] as u8, b[0] as u8)))
}, },
5 => { 5 => {
let v = piter.next().unwrap(); let v = piter.next().unwrap();
@ -240,7 +241,7 @@ impl Perform for PerfAtom {
let r = piter.next().unwrap(); let r = piter.next().unwrap();
let g = piter.next().unwrap(); let g = piter.next().unwrap();
let b = piter.next().unwrap(); let b = piter.next().unwrap();
self.style = self.style.add(TerminalStyle::bg_color((r[0] as u8, g[0] as u8, b[30] as u8))) self.style = self.style.add(TerminalStyle::bg_color((r[0] as u8, g[0] as u8, b[0] as u8)))
}, },
5 => { 5 => {
let v = piter.next().unwrap(); let v = piter.next().unwrap();
@ -267,10 +268,11 @@ impl Perform for PerfAtom {
self.cursor.x = 0; self.cursor.x = 0;
} }
} }
'C' => { 'C' | 'a' => {
self.cursor.x += piter.next().unwrap_or(&[1])[0] as i16; self.cursor.x += piter.next().unwrap_or(&[1])[0] as i16;
if self.cursor.x >= self.term_width { if self.cursor.x >= self.term_width {
self.cursor.x = 0; self.cursor.y += self.cursor.x / self.term_width;
self.cursor.x %= self.term_width;
} }
} }
'D' => { 'D' => {
@ -294,12 +296,12 @@ impl Perform for PerfAtom {
self.cursor.x = 0; self.cursor.x = 0;
self.cursor.y -= piter.next().unwrap_or(&[1])[0] as i16; self.cursor.y -= piter.next().unwrap_or(&[1])[0] as i16;
} }
'G' => { 'G' | '`' => {
self.cursor.x = piter.next().unwrap()[0] as i16 - 1; self.cursor.x = piter.next().unwrap_or(&[1])[0] as i16 - 1;
} }
'H' => { 'H' | 'f' => {
if let Some(y) = piter.next() { self.cursor.y = y[0] as i16 - 1 }; self.cursor.y = piter.next().unwrap_or(&[1])[0] as i16 - 1;
if let Some(x) = piter.next() { self.cursor.x = x[0] as i16 - 1 }; self.cursor.x = piter.next().unwrap_or(&[1])[0] as i16 - 1;
} }
'J' => { 'J' => {
let x = piter.next().unwrap_or(&[0 as u16; 1]); let x = piter.next().unwrap_or(&[0 as u16; 1]);
@ -333,7 +335,7 @@ impl Perform for PerfAtom {
} }
} }
//self.cursor. //self.cursor.x = 0;
} }
// erase entire screen // erase entire screen
@ -380,27 +382,81 @@ impl Perform for PerfAtom {
_ => {} _ => {}
} }
} }
/*
'M' => {
let n = piter.next().unwrap_or(&[1])[0] as i16;
for y in 0 .. n {
for x in 0 .. self.term_width {
self.write_atom(Point2::new(x, self.cursor.y+y), None);
}
}
}
'P' => {
for x in 0 .. piter.next().unwrap_or(&[1])[0] {
self.backspace();
}
}
'X' => {
for x in 0 .. piter.next().unwrap_or(&[1])[0] {
self.write_atom(Point2::new(self.cursor.x + x as i16, self.cursor.y), None);
}
}
*/
's' => { 's' => {
self.cursor_stack.push(self.cursor); self.save_cursor_position();
} }
'u' => { 'u' => {
if let Some(c) = self.cursor_stack.pop() { self.restore_cursor_position();
self.cursor = c;
}
} }
_ => {} _ => {
/*
eprintln!(
"[csi_dispatch] params={:#?}, intermediates={:?}, ignore={:?}, char={:?}",
params, intermediates, ignore, c
);
*/
}
} }
} }
fn esc_dispatch(&mut self, intermediates: &[u8], ignore: bool, byte: u8) { fn esc_dispatch(&mut self, intermediates: &[u8], ignore: bool, byte: u8) {
match (byte, intermediates) {
//(b'B', intermediates) => configure_charset!(StandardCharset::Ascii, intermediates),
(b'D', []) => self.linefeed(),
(b'E', []) => {
self.linefeed();
self.carriage_return();
},
/*
(b'H', []) => self.handler.set_horizontal_tabstop(),
(b'M', []) => self.handler.reverse_index(),
(b'Z', []) => self.handler.identify_terminal(None),
(b'c', []) => self.handler.reset_state(),
(b'0', intermediates) => {
configure_charset!(StandardCharset::SpecialCharacterAndLineDrawing, intermediates)
},
*/
(b'7', []) => self.save_cursor_position(),
//(b'8', [b'#']) => self.handler.decaln(),
(b'8', []) => self.restore_cursor_position(),
/*
(b'=', []) => self.handler.set_keypad_application_mode(),
(b'>', []) => self.handler.unset_keypad_application_mode(),
**/
// String terminator, do nothing (parser handles as string terminator).
(b'\\', []) => (),
_ => {
/* /*
eprintln!( eprintln!(
"[esc_dispatch] intermediates={:?}, ignore={:?}, byte={:02x}", "unhandled esc_dispatch intermediates={:?}, ignore={:?}, byte={:02x}",
intermediates, ignore, byte intermediates, ignore, byte
); );
*/ */
} }
} }
}
}