some more ansi parsing improvements
This commit is contained in:
parent
4ad8316636
commit
43321d18fb
1 changed files with 116 additions and 60 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -161,7 +170,7 @@ impl Perform for PerfAtom {
|
||||||
"[hook] params={:?}, intermediates={:?}, ignore={:?}, char={:?}",
|
"[hook] params={:?}, intermediates={:?}, ignore={:?}, char={:?}",
|
||||||
params, intermediates, ignore, c
|
params, intermediates, ignore, c
|
||||||
);
|
);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
fn put(&mut self, byte: u8) {
|
fn put(&mut self, byte: u8) {
|
||||||
|
@ -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
|
||||||
|
@ -366,40 +368,94 @@ impl Perform for PerfAtom {
|
||||||
1 => {
|
1 => {
|
||||||
for x in 0 .. self.cursor.x {
|
for x in 0 .. self.cursor.x {
|
||||||
self.write_atom(Point2::new(x, self.cursor.y), Some(TerminalAtom::new(' ', self.get_style())));
|
self.write_atom(Point2::new(x, self.cursor.y), Some(TerminalAtom::new(' ', self.get_style())));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// clear entire line
|
// clear entire line
|
||||||
2 => {
|
2 => {
|
||||||
for x in 0 .. self.term_width {
|
for x in 0 .. self.term_width {
|
||||||
self.write_atom(Point2::new(x, self.cursor.y), Some(TerminalAtom::new(' ', self.get_style())));
|
self.write_atom(Point2::new(x, self.cursor.y), Some(TerminalAtom::new(' ', self.get_style())));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// invalid
|
// invalid
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
's' => {
|
/*
|
||||||
self.cursor_stack.push(self.cursor);
|
'M' => {
|
||||||
}
|
let n = piter.next().unwrap_or(&[1])[0] as i16;
|
||||||
'u' => {
|
for y in 0 .. n {
|
||||||
if let Some(c) = self.cursor_stack.pop() {
|
for x in 0 .. self.term_width {
|
||||||
self.cursor = c;
|
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' => {
|
||||||
|
self.save_cursor_position();
|
||||||
|
}
|
||||||
|
'u' => {
|
||||||
|
self.restore_cursor_position();
|
||||||
|
}
|
||||||
|
|
||||||
_ => {}
|
_ => {
|
||||||
|
/*
|
||||||
|
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) {
|
||||||
/*
|
|
||||||
eprintln!(
|
match (byte, intermediates) {
|
||||||
"[esc_dispatch] intermediates={:?}, ignore={:?}, byte={:02x}",
|
//(b'B', intermediates) => configure_charset!(StandardCharset::Ascii, intermediates),
|
||||||
intermediates, ignore, byte
|
(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!(
|
||||||
|
"unhandled esc_dispatch intermediates={:?}, ignore={:?}, byte={:02x}",
|
||||||
|
intermediates, ignore, byte
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue