diff --git a/src/enums.rs b/src/enums.rs index 9fc6da8..ecbb72f 100644 --- a/src/enums.rs +++ b/src/enums.rs @@ -37,88 +37,133 @@ pub enum AnsiSequence { ResetAutoWrap, ResetAutoRepeat, ResetInterlacing, + SetAlternateKeypad, + SetNumericKeypad, + SetUKG0, + SetUKG1, + SetUSG0, + SetUSG1, + SetG0SpecialChars, + SetG1SpecialChars, + SetG0AlternateChar, + SetG1AlternateChar, + SetG0AltAndSpecialGraph, + SetG1AltAndSpecialGraph, + SetSingleShift2, + SetSingleShift3, + SetTopAndBottom(u32, u32), } use std::fmt::Display; impl Display for AnsiSequence { fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(formatter, "\u{1b}[")?; + write!(formatter, "\u{1b}")?; use AnsiSequence::*; match self { CursorPos(line, col) - => write!(formatter, "{};{}H", line, col), + => write!(formatter, "[{};{}H", line, col), CursorUp(amt) - => write!(formatter, "{}A", amt), + => write!(formatter, "[{}A", amt), CursorDown(amt) - => write!(formatter, "{}B", amt), + => write!(formatter, "[{}B", amt), CursorForward(amt) - => write!(formatter, "{}C", amt), + => write!(formatter, "[{}C", amt), CursorBackward(amt) - => write!(formatter, "{}D", amt), + => write!(formatter, "[{}D", amt), CursorSave - => write!(formatter, "s"), + => write!(formatter, "[s"), CursorRestore - => write!(formatter, "u"), + => write!(formatter, "[u"), EraseDisplay - => write!(formatter, "2J"), + => write!(formatter, "[2J"), EraseLine - => write!(formatter, "K"), + => write!(formatter, "[K"), SetGraphicsMode(vec) => { match vec.len() { - 1 => write!(formatter, "{}m", vec[0]), - 2 => write!(formatter, "{};{}m", vec[0], vec[1]), - 3 => write!(formatter, "{};{};{}m", vec[0], vec[1], vec[2]), + 1 => write!(formatter, "[{}m", vec[0]), + 2 => write!(formatter, "[{};{}m", vec[0], vec[1]), + 3 => write!(formatter, "[{};{};{}m", vec[0], vec[1], vec[2]), _ => unreachable!() } }, SetMode(mode) - => write!(formatter, "={}h", mode), + => write!(formatter, "[={}h", mode), ResetMode(mode) - => write!(formatter, "={}l", mode), + => write!(formatter, "[={}l", mode), ShowCursor - => write!(formatter, "?25h"), + => write!(formatter, "[?25h"), HideCursor - => write!(formatter, "?25l"), + => write!(formatter, "[?25l"), CursorToApp - => write!(formatter, "?1h"), + => write!(formatter, "[?1h"), SetNewLineMode - => write!(formatter, "20h"), + => write!(formatter, "[20h"), SetCol132 - => write!(formatter, "?3h"), + => write!(formatter, "[?3h"), SetSmoothScroll - => write!(formatter, "?4h"), + => write!(formatter, "[?4h"), SetReverseVideo - => write!(formatter, "?5h"), + => write!(formatter, "[?5h"), SetOriginRelative - => write!(formatter, "?6h"), + => write!(formatter, "[?6h"), SetAutoWrap - => write!(formatter, "?7h"), + => write!(formatter, "[?7h"), SetAutoRepeat - => write!(formatter, "?8h"), + => write!(formatter, "[?8h"), SetInterlacing - => write!(formatter, "?9h"), + => write!(formatter, "[?9h"), SetLineFeedMode - => write!(formatter, "20l"), + => write!(formatter, "[20l"), SetCursorKeyToCursor - => write!(formatter, "?1l"), + => write!(formatter, "[?1l"), SetVT52 - => write!(formatter, "?2l"), + => write!(formatter, "[?2l"), SetCol80 - => write!(formatter, "?3l"), + => write!(formatter, "[?3l"), SetJumpScrolling - => write!(formatter, "?4l"), + => write!(formatter, "[?4l"), SetNormalVideo - => write!(formatter, "?5l"), + => write!(formatter, "[?5l"), SetOriginAbsolute - => write!(formatter, "?6l"), + => write!(formatter, "[?6l"), ResetAutoWrap - => write!(formatter, "?7l"), + => write!(formatter, "[?7l"), ResetAutoRepeat - => write!(formatter, "?8l"), + => write!(formatter, "[?8l"), ResetInterlacing - => write!(formatter, "?9l"), + => write!(formatter, "[?9l"), + SetAlternateKeypad + => write!(formatter, "="), + SetNumericKeypad + => write!(formatter, ">"), + SetUKG0 + => write!(formatter, "(A"), + SetUKG1 + => write!(formatter, ")A"), + SetUSG0 + => write!(formatter, "(B"), + SetUSG1 + => write!(formatter, ")B"), + SetG0SpecialChars + => write!(formatter, "(0"), + SetG1SpecialChars + => write!(formatter, ")0"), + SetG0AlternateChar + => write!(formatter, "(1"), + SetG1AlternateChar + => write!(formatter, ")1"), + SetG0AltAndSpecialGraph + => write!(formatter, "(2"), + SetG1AltAndSpecialGraph + => write!(formatter, ")2"), + SetSingleShift2 + => write!(formatter, "N"), + SetSingleShift3 + => write!(formatter, "O"), + SetTopAndBottom(x, y) + => write!(formatter, "{};{}r", x, y) } } } diff --git a/src/parsers.rs b/src/parsers.rs index 0d665c5..4381bf7 100644 --- a/src/parsers.rs +++ b/src/parsers.rs @@ -29,6 +29,7 @@ named!( named!( cursor_pos<&str, AnsiSequence>, do_parse!( + tag!("[") >> x: parse_int >> tag!(";") >> y: parse_int >> @@ -43,6 +44,7 @@ named!( named!( cursor_up<&str, AnsiSequence>, do_parse!( + tag!("[") >> am: parse_int >> tag!("A") >> (AnsiSequence::CursorUp(am)) @@ -52,6 +54,7 @@ named!( named!( cursor_down<&str, AnsiSequence>, do_parse!( + tag!("[") >> am: parse_int >> tag!("B") >> (AnsiSequence::CursorDown(am)) @@ -61,6 +64,7 @@ named!( named!( cursor_forward<&str, AnsiSequence>, do_parse!( + tag!("[") >> am: parse_int >> tag!("C") >> (AnsiSequence::CursorForward(am)) @@ -70,6 +74,7 @@ named!( named!( cursor_backward<&str, AnsiSequence>, do_parse!( + tag!("[") >> am: parse_int >> tag!("D") >> (AnsiSequence::CursorBackward(am)) @@ -79,6 +84,7 @@ named!( named!( graphics_mode1<&str, AnsiSequence>, do_parse!( + tag!("[") >> val: parse_int >> tag!("m") >> (AnsiSequence::SetGraphicsMode(vec![val])) @@ -88,6 +94,7 @@ named!( named!( graphics_mode2<&str, AnsiSequence>, do_parse!( + tag!("[") >> val1: parse_int >> tag!(";") >> val2: parse_int >> @@ -99,6 +106,7 @@ named!( named!( graphics_mode3<&str, AnsiSequence>, do_parse!( + tag!("[") >> val1: parse_int >> tag!(";") >> val2: parse_int >> @@ -120,7 +128,7 @@ named!( named!( set_mode<&str, AnsiSequence>, do_parse!( - tag!("=") >> + tag_s!("[=") >> mode: parse_int >> conv: expr_res!(mode.try_into()) >> tag!("h") >> @@ -131,7 +139,7 @@ named!( named!( reset_mode<&str, AnsiSequence>, do_parse!( - tag!("=") >> + tag_s!("[=") >> mode: parse_int >> conv: expr_res!(mode.try_into()) >> tag!("l") >> @@ -139,31 +147,58 @@ named!( ) ); -tag_parser!(cursor_save, "s", AnsiSequence::CursorSave); -tag_parser!(cursor_restore, "u", AnsiSequence::CursorRestore); -tag_parser!(erase_display, "2J", AnsiSequence::EraseDisplay); -tag_parser!(erase_line, "K", AnsiSequence::EraseLine); -tag_parser!(hide_cursor, "?25l", AnsiSequence::HideCursor); -tag_parser!(show_cursor, "?25h", AnsiSequence::ShowCursor); -tag_parser!(cursor_to_app, "?1h", AnsiSequence::CursorToApp); -tag_parser!(set_new_line_mode, "20h", AnsiSequence::SetNewLineMode); -tag_parser!(set_col_132, "?3h", AnsiSequence::SetCol132); -tag_parser!(set_smooth_scroll, "?4h", AnsiSequence::SetSmoothScroll); -tag_parser!(set_reverse_video, "?5h", AnsiSequence::SetReverseVideo); -tag_parser!(set_origin_rel, "?6h", AnsiSequence::SetOriginRelative); -tag_parser!(set_auto_wrap, "?7h", AnsiSequence::SetAutoWrap); -tag_parser!(set_auto_repeat, "?8h", AnsiSequence::SetAutoRepeat); -tag_parser!(set_interlacing, "?9h", AnsiSequence::SetInterlacing); -tag_parser!(set_linefeed, "20l", AnsiSequence::SetLineFeedMode); -tag_parser!(set_cursorkey, "?1l", AnsiSequence::SetCursorKeyToCursor); -tag_parser!(set_vt52, "?2l", AnsiSequence::SetVT52); -tag_parser!(set_col80, "?3l", AnsiSequence::SetCol80); -tag_parser!(set_jump_scroll, "?4l", AnsiSequence::SetJumpScrolling); -tag_parser!(set_normal_video, "?5l", AnsiSequence::SetNormalVideo); -tag_parser!(set_origin_abs, "?6l", AnsiSequence::SetOriginAbsolute); -tag_parser!(reset_auto_wrap, "?7l", AnsiSequence::ResetAutoWrap); -tag_parser!(reset_auto_repeat, "?8l", AnsiSequence::ResetAutoRepeat); -tag_parser!(reset_interlacing, "?9l", AnsiSequence::ResetInterlacing); +named!( + set_top_and_bottom<&str, AnsiSequence>, + do_parse!( + tag!("[") >> + x: parse_int >> + tag!(";") >> + y: parse_int >> + tag!("r") >> + (AnsiSequence::SetTopAndBottom(x, y)) + ) +); + +tag_parser!(cursor_save, "[s", AnsiSequence::CursorSave); +tag_parser!(cursor_restore, "[u", AnsiSequence::CursorRestore); +tag_parser!(erase_display, "[2J", AnsiSequence::EraseDisplay); +tag_parser!(erase_line, "[K", AnsiSequence::EraseLine); +tag_parser!(hide_cursor, "[?25l", AnsiSequence::HideCursor); +tag_parser!(show_cursor, "[?25h", AnsiSequence::ShowCursor); +tag_parser!(cursor_to_app, "[?1h", AnsiSequence::CursorToApp); +tag_parser!(set_new_line_mode, "[20h", AnsiSequence::SetNewLineMode); +tag_parser!(set_col_132, "[?3h", AnsiSequence::SetCol132); +tag_parser!(set_smooth_scroll, "[?4h", AnsiSequence::SetSmoothScroll); +tag_parser!(set_reverse_video, "[?5h", AnsiSequence::SetReverseVideo); +tag_parser!(set_origin_rel, "[?6h", AnsiSequence::SetOriginRelative); +tag_parser!(set_auto_wrap, "[?7h", AnsiSequence::SetAutoWrap); +tag_parser!(set_auto_repeat, "[?8h", AnsiSequence::SetAutoRepeat); +tag_parser!(set_interlacing, "[?9h", AnsiSequence::SetInterlacing); +tag_parser!(set_linefeed, "[20l", AnsiSequence::SetLineFeedMode); +tag_parser!(set_cursorkey, "[?1l", AnsiSequence::SetCursorKeyToCursor); +tag_parser!(set_vt52, "[?2l", AnsiSequence::SetVT52); +tag_parser!(set_col80, "[?3l", AnsiSequence::SetCol80); +tag_parser!(set_jump_scroll, "[?4l", AnsiSequence::SetJumpScrolling); +tag_parser!(set_normal_video, "[?5l", AnsiSequence::SetNormalVideo); +tag_parser!(set_origin_abs, "[?6l", AnsiSequence::SetOriginAbsolute); +tag_parser!(reset_auto_wrap, "[?7l", AnsiSequence::ResetAutoWrap); +tag_parser!(reset_auto_repeat, "[?8l", AnsiSequence::ResetAutoRepeat); +tag_parser!(reset_interlacing, "[?9l", AnsiSequence::ResetInterlacing); + +tag_parser!(set_alternate_keypad, "=", AnsiSequence::SetAlternateKeypad); +tag_parser!(set_numeric_keypad, ">", AnsiSequence::SetNumericKeypad); +tag_parser!(set_uk_g0, "(A", AnsiSequence::SetUKG0); +tag_parser!(set_uk_g1, ")A", AnsiSequence::SetUKG1); +tag_parser!(set_us_g0, "(B", AnsiSequence::SetUSG0); +tag_parser!(set_us_g1, ")B", AnsiSequence::SetUSG1); +tag_parser!(set_g0_special, "(0", AnsiSequence::SetG0SpecialChars); +tag_parser!(set_g1_special, ")0", AnsiSequence::SetG1SpecialChars); +tag_parser!(set_g0_alternate, "(1", AnsiSequence::SetG0AlternateChar); +tag_parser!(set_g1_alternate, ")1", AnsiSequence::SetG1AlternateChar); +tag_parser!(set_g0_graph, "(2", AnsiSequence::SetG0AltAndSpecialGraph); +tag_parser!(set_g1_graph, ")2", AnsiSequence::SetG1AltAndSpecialGraph); +tag_parser!(set_single_shift2, "N", AnsiSequence::SetSingleShift2); +tag_parser!(set_single_shift3, "O", AnsiSequence::SetSingleShift3); named!( combined<&str, AnsiSequence>, @@ -201,13 +236,28 @@ named!( | reset_auto_wrap | reset_auto_repeat | reset_interlacing + | set_top_and_bottom + | set_alternate_keypad + | set_numeric_keypad + | set_uk_g0 + | set_uk_g1 + | set_us_g0 + | set_us_g1 + | set_g0_special + | set_g1_special + | set_g0_alternate + | set_g1_alternate + | set_g0_graph + | set_g1_graph + | set_single_shift2 + | set_single_shift3 ) ); named!( pub parse_escape<&str, Output>, do_parse!( - tag_s!("\u{1b}[") >> + tag_s!("\u{1b}") >> seq: combined >> (Output::Escape(seq)) ) diff --git a/src/parsers/tests.rs b/src/parsers/tests.rs index 0e0ec7e..0a384ad 100644 --- a/src/parsers/tests.rs +++ b/src/parsers/tests.rs @@ -64,6 +64,20 @@ test_parser!(reset_auto_wrap, "\u{1b}[?7l"); test_parser!(reset_auto_repeat, "\u{1b}[?8l"); test_parser!(reset_interlacing, "\u{1b}[?9l"); +test_parser!(set_alternate_keypad, "\u{1b}="); +test_parser!(set_numeric_keypad, "\u{1b}>"); +test_parser!(set_uk_g0, "\u{1b}(A"); +test_parser!(set_uk_g1, "\u{1b})A"); +test_parser!(set_us_g0, "\u{1b}(B"); +test_parser!(set_us_g1, "\u{1b})B"); +test_parser!(set_g0_special, "\u{1b}(0"); +test_parser!(set_g1_special, "\u{1b})0"); +test_parser!(set_g0_alternate, "\u{1b}(1"); +test_parser!(set_g1_alternate, "\u{1b})1"); +test_parser!(set_g0_graph, "\u{1b}(2"); +test_parser!(set_g1_graph, "\u{1b})2"); +test_parser!(set_single_shift2, "\u{1b}N"); +test_parser!(set_single_shift3, "\u{1b}O"); #[test] fn test_parser_iterator() {