diff --git a/src/color.rs b/src/color.rs index e154ae2..c1eee52 100644 --- a/src/color.rs +++ b/src/color.rs @@ -3,9 +3,7 @@ //! # Example //! //! ```rust -//! use termion::{color, style}; -//! -//! use std::io; +//! use termion::color; //! //! fn main() { //! println!("{}Red", color::Fg(color::Red)); diff --git a/src/event.rs b/src/event.rs index 9d338c6..44a139e 100644 --- a/src/event.rs +++ b/src/event.rs @@ -5,7 +5,7 @@ use std::ascii::AsciiExt; use std::str; /// An event reported by the terminal. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Event { /// A key press. Key(Key), @@ -13,6 +13,9 @@ pub enum Event { Mouse(MouseEvent), /// An event that cannot currently be evaluated. Unsupported, + /// A CSI sequence unrecognized by termion. Does not inlude the leading `^[`. + UnknownCsi(Vec), + } /// A mouse related event. @@ -93,7 +96,6 @@ pub enum Key { /// Esc key. Esc, - #[allow(missing_docs)] #[doc(hidden)] __IsNotComplete } @@ -108,11 +110,13 @@ where I: Iterator> Ok(match iter.next() { Some(Ok(b'O')) => { match iter.next() { + // F1-F4 Some(Ok(val @ b'P' ... b'S')) => Event::Key(Key::F(1 + val - b'P')), _ => return error, } } Some(Ok(b'[')) => { + // This is a CSI sequence. match iter.next() { Some(Ok(b'D')) => Event::Key(Key::Left), Some(Ok(b'C')) => Event::Key(Key::Right), @@ -198,17 +202,24 @@ where I: Iterator> buf.push(c); c = iter.next().unwrap().unwrap(); } + // Include the terminal char in the buffer. + // We'll want it if we return an unknown sequence. + buf.push(c); match c { // rxvt mouse encoding: // ESC [ Cb ; Cx ; Cy ; M b'M' => { let str_buf = String::from_utf8(buf).unwrap(); - let nums = &mut str_buf.split(';'); - let cb = nums.next().unwrap().parse::().unwrap(); - let cx = nums.next().unwrap().parse::().unwrap(); - let cy = nums.next().unwrap().parse::().unwrap(); + // + let nums: Vec = str_buf[..str_buf.len()-1].split(';') + .map(|n| n.parse().unwrap()) + .collect(); + + let cb = nums[0]; + let cx = nums[1]; + let cy = nums[2]; let event = match cb { 32 => MouseEvent::Press(MouseButton::Left, cx, cy), @@ -218,7 +229,7 @@ where I: Iterator> 64 => MouseEvent::Hold(cx, cy), 96 | 97 => MouseEvent::Press(MouseButton::WheelUp, cx, cy), - _ => return error, + _ => return Ok(Event::UnknownCsi(str_buf.into_bytes())), }; Event::Mouse(event) @@ -229,16 +240,20 @@ where I: Iterator> // This CSI sequence can be a list of semicolon-separated // numbers. - let nums: Vec = str_buf.split(';') + let nums: Vec = str_buf[..str_buf.len()-1].split(';') .map(|n| n.parse().unwrap()) .collect(); if nums.is_empty() { - return error; + return Ok(Event::UnknownCsi(str_buf.into_bytes())); } // TODO: handle multiple values for key modififiers (ex: values // [3, 2] means Shift+Delete) + if nums.len() > 1 { + return Ok(Event::UnknownCsi(str_buf.into_bytes())); + } + match nums[0] { 1 | 7 => Event::Key(Key::Home), 2 => Event::Key(Key::Insert), @@ -249,10 +264,10 @@ where I: Iterator> v @ 11...15 => Event::Key(Key::F(v - 10)), v @ 17...21 => Event::Key(Key::F(v - 11)), v @ 23...24 => Event::Key(Key::F(v - 12)), - _ => return error, + _ => return Ok(Event::UnknownCsi(str_buf.into_bytes())), } }, - _ => return error, + _ => return Ok(Event::UnknownCsi(buf)), } }, _ => return error, diff --git a/src/raw.rs b/src/raw.rs index 20a07f9..09cd5e4 100644 --- a/src/raw.rs +++ b/src/raw.rs @@ -11,7 +11,7 @@ //! //! # Example //! -//! ```rust,ignore +//! ```rust,no_run //! use termion::raw::IntoRawMode; //! use std::io::{Write, stdout}; //!