aboutsummaryrefslogtreecommitdiff
path: root/src/ansi.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/ansi.rs')
-rw-r--r--src/ansi.rs91
1 files changed, 60 insertions, 31 deletions
diff --git a/src/ansi.rs b/src/ansi.rs
index fe271c82..c1829f19 100644
--- a/src/ansi.rs
+++ b/src/ansi.rs
@@ -26,6 +26,12 @@ pub enum Escape {
DisplayAttr(u8),
}
+/// Trait that provides properties of terminal
+pub trait TermInfo {
+ fn rows(&self) -> usize;
+ fn cols(&self) -> usize;
+}
+
/// Control requiring action
#[derive(Debug, Eq, PartialEq)]
pub enum Control {
@@ -359,6 +365,9 @@ pub trait Handler {
/// Unset mode
fn unset_mode(&mut self, Mode) {}
+
+ /// DECSTBM - Set the terminal scrolling region
+ fn set_scrolling_region(&mut self, top: i64, bot: i64) {}
}
/// An implementation of handler that just prints everything it gets
@@ -403,6 +412,19 @@ impl Handler for DebugHandler {
fn terminal_attribute(&mut self, attr: Attr) { println!("terminal_attribute: {:?}", attr); }
fn set_mode(&mut self, mode: Mode) { println!("set_mode: {:?}", mode); }
fn unset_mode(&mut self, mode: Mode) { println!("unset_mode: {:?}", mode); }
+ fn set_scrolling_region(&mut self, top: i64, bot: i64) {
+ println!("set scroll region: {:?} - {:?}", top, bot);
+ }
+}
+
+impl TermInfo for DebugHandler {
+ fn rows(&self) -> usize {
+ 24
+ }
+
+ fn cols(&self) -> usize {
+ 80
+ }
}
impl Parser {
@@ -418,7 +440,7 @@ impl Parser {
///
/// Maybe returns an Item which represents a state change of the terminal
pub fn advance<H>(&mut self, handler: &mut H, c: char)
- where H: Handler
+ where H: Handler + TermInfo
{
// println!("state: {:?}; char: {:?}", self.state, c);
// Control characters get handled immediately
@@ -444,13 +466,13 @@ impl Parser {
}
fn advance_base<H>(&mut self, handler: &mut H, c: char)
- where H: Handler
+ where H: Handler + TermInfo
{
handler.input(c);
}
fn other<H>(&mut self, handler: &mut H, c: char)
- where H: Handler
+ where H: Handler + TermInfo
{
if c == 0x07 as char || c == 0x18 as char || c == 0x1a as char ||
c == 0x1b as char || is_control_c1(c)
@@ -466,7 +488,7 @@ impl Parser {
/// TODO Handle `ST`, `'#'`, `'P'`, `'_'`, `'^'`, `']'`, `'k'`,
/// 'n', 'o', '(', ')', '*', '+', '=', '>'
fn escape<H>(&mut self, handler: &mut H, c: char)
- where H: Handler
+ where H: Handler + TermInfo
{
// Helper for items which complete a sequence.
macro_rules! sequence_complete {
@@ -499,7 +521,7 @@ impl Parser {
}
fn csi<H>(&mut self, handler: &mut H, c: char)
- where H: Handler
+ where H: Handler + TermInfo
{
self.buf[self.idx] = c;
self.idx += 1;
@@ -513,7 +535,7 @@ impl Parser {
///
/// ESC '[' [[ [<priv>] <arg> [;]] <mode> [<mode>]] */
fn csi_parse<H>(&mut self, handler: &mut H)
- where H: Handler
+ where H: Handler + TermInfo
{
let mut idx = 0;
let mut args = [0i64; CSI_ATTR_MAX];
@@ -739,7 +761,15 @@ impl Parser {
}
}
'n' => handler.identify_terminal(),
- 'r' => unknown!(), // set scrolling region
+ 'r' => {
+ if private {
+ unknown!();
+ }
+ let top = arg_or_default!(args[0], 1);
+ let bottom = arg_or_default!(args[1], handler.rows() as i64);
+
+ handler.set_scrolling_region(top - 1, bottom - 1);
+ },
's' => handler.save_cursor_position(),
'u' => handler.restore_cursor_position(),
_ => unknown!(),
@@ -753,7 +783,7 @@ impl Parser {
}
fn control<H>(&mut self, handler: &mut H, c: char)
- where H: Handler
+ where H: Handler + TermInfo
{
match c {
C0::HT => handler.put_tab(1),
@@ -1094,29 +1124,39 @@ impl Default for State {
#[cfg(test)]
mod tests {
use std::io::{Cursor, Read};
- use super::{Parser, Escape, Handler, Attr, Rgb, DebugHandler};
+ use super::{Parser, Escape, Handler, Attr, DebugHandler, TermInfo};
use ::Rgb;
- #[test]
- fn parse_control_attribute() {
- #[derive(Default)]
- struct TestHandler {
- attr: Option<Attr>,
+ #[derive(Default)]
+ struct AttrHandler {
+ attr: Option<Attr>,
+ }
+
+ impl Handler for AttrHandler {
+ fn terminal_attribute(&mut self, attr: Attr) {
+ self.attr = Some(attr);
}
+ }
- impl Handler for TestHandler {
- fn terminal_attribute(&mut self, attr: Attr) {
- self.attr = Some(attr);
- }
+ impl TermInfo for AttrHandler {
+ fn rows(&self) -> usize {
+ 24
}
+ fn cols(&self) -> usize {
+ 80
+ }
+ }
+
+ #[test]
+ fn parse_control_attribute() {
static BYTES: &'static [u8] = &[
0x1b, 0x5b, 0x31, 0x6d
];
let cursor = Cursor::new(BYTES);
let mut parser = Parser::new();
- let mut handler = TestHandler::default();
+ let mut handler = AttrHandler::default();
for c in cursor.chars() {
parser.advance(&mut handler, c.unwrap());
@@ -1127,17 +1167,6 @@ mod tests {
#[test]
fn parse_truecolor_attr() {
- #[derive(Default)]
- struct TestHandler {
- attr: Option<Attr>,
- }
-
- impl Handler for TestHandler {
- fn terminal_attribute(&mut self, attr: Attr) {
- self.attr = Some(attr);
- }
- }
-
static BYTES: &'static [u8] = &[
0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x32, 0x3b, 0x31, 0x32,
0x38, 0x3b, 0x36, 0x36, 0x3b, 0x32, 0x35, 0x35, 0x6d
@@ -1145,7 +1174,7 @@ mod tests {
let mut cursor = Cursor::new(BYTES);
let mut parser = Parser::new();
- let mut handler = TestHandler::default();
+ let mut handler = AttrHandler::default();
for c in cursor.chars() {
parser.advance(&mut handler, c.unwrap());