Merge branch 'master' of github.com:Ticki/libterm

This commit is contained in:
ticki 2016-12-18 19:29:18 +01:00
commit f9eaf6d0bc
4 changed files with 36 additions and 23 deletions

View File

@ -3,9 +3,7 @@
//! # Example
//!
//! ```rust
//! use termion::{color, style};
//!
//! use std::io;
//! use termion::color;
//!
//! fn main() {
//! println!("{}Red", color::Fg(color::Red));

View File

@ -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<u8>),
}
/// 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<Item = Result<u8, Error>>
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<Item = Result<u8, Error>>
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::<u16>().unwrap();
let cx = nums.next().unwrap().parse::<u16>().unwrap();
let cy = nums.next().unwrap().parse::<u16>().unwrap();
//
let nums: Vec<u16> = 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<Item = Result<u8, Error>>
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<Item = Result<u8, Error>>
// This CSI sequence can be a list of semicolon-separated
// numbers.
let nums: Vec<u8> = str_buf.split(';')
let nums: Vec<u8> = 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<Item = Result<u8, Error>>
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,

View File

@ -56,14 +56,14 @@ impl<R: Read> Iterator for Events<R> {
c => parse_event(Ok(c), &mut source.bytes()),
},
Ok(2) => {
if buf[0] != b'\x1B' {
// this is not an escape sequence, but we read two bytes, save the second byte
// for later
self.leftover = Some(buf[1]);
}
let mut iter = buf[1..2].iter().map(|c| Ok(*c)).chain(source.bytes());
parse_event(Ok(buf[0]), &mut iter)
let mut option_iter = &mut Some(buf[1]).into_iter();
let result = {
let mut iter = option_iter.map(|c| Ok(c)).chain(source.bytes());
parse_event(Ok(buf[0]), &mut iter)
};
// If the option_iter wasn't consumed, keep the byte for later.
self.leftover = option_iter.next();
result
}
Ok(_) => unreachable!(),
Err(e) => Err(e),

View File

@ -11,7 +11,7 @@
//!
//! # Example
//!
//! ```rust,ignore
//! ```rust,no_run
//! use termion::raw::IntoRawMode;
//! use std::io::{Write, stdout};
//!