Merge branch 'master' of github.com:Ticki/libterm
This commit is contained in:
commit
f9eaf6d0bc
|
@ -3,9 +3,7 @@
|
||||||
//! # Example
|
//! # Example
|
||||||
//!
|
//!
|
||||||
//! ```rust
|
//! ```rust
|
||||||
//! use termion::{color, style};
|
//! use termion::color;
|
||||||
//!
|
|
||||||
//! use std::io;
|
|
||||||
//!
|
//!
|
||||||
//! fn main() {
|
//! fn main() {
|
||||||
//! println!("{}Red", color::Fg(color::Red));
|
//! println!("{}Red", color::Fg(color::Red));
|
||||||
|
|
37
src/event.rs
37
src/event.rs
|
@ -5,7 +5,7 @@ use std::ascii::AsciiExt;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
/// An event reported by the terminal.
|
/// An event reported by the terminal.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
/// A key press.
|
/// A key press.
|
||||||
Key(Key),
|
Key(Key),
|
||||||
|
@ -13,6 +13,9 @@ pub enum Event {
|
||||||
Mouse(MouseEvent),
|
Mouse(MouseEvent),
|
||||||
/// An event that cannot currently be evaluated.
|
/// An event that cannot currently be evaluated.
|
||||||
Unsupported,
|
Unsupported,
|
||||||
|
/// A CSI sequence unrecognized by termion. Does not inlude the leading `^[`.
|
||||||
|
UnknownCsi(Vec<u8>),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A mouse related event.
|
/// A mouse related event.
|
||||||
|
@ -93,7 +96,6 @@ pub enum Key {
|
||||||
/// Esc key.
|
/// Esc key.
|
||||||
Esc,
|
Esc,
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
__IsNotComplete
|
__IsNotComplete
|
||||||
}
|
}
|
||||||
|
@ -108,11 +110,13 @@ where I: Iterator<Item = Result<u8, Error>>
|
||||||
Ok(match iter.next() {
|
Ok(match iter.next() {
|
||||||
Some(Ok(b'O')) => {
|
Some(Ok(b'O')) => {
|
||||||
match iter.next() {
|
match iter.next() {
|
||||||
|
// F1-F4
|
||||||
Some(Ok(val @ b'P' ... b'S')) => Event::Key(Key::F(1 + val - b'P')),
|
Some(Ok(val @ b'P' ... b'S')) => Event::Key(Key::F(1 + val - b'P')),
|
||||||
_ => return error,
|
_ => return error,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(Ok(b'[')) => {
|
Some(Ok(b'[')) => {
|
||||||
|
// This is a CSI sequence.
|
||||||
match iter.next() {
|
match iter.next() {
|
||||||
Some(Ok(b'D')) => Event::Key(Key::Left),
|
Some(Ok(b'D')) => Event::Key(Key::Left),
|
||||||
Some(Ok(b'C')) => Event::Key(Key::Right),
|
Some(Ok(b'C')) => Event::Key(Key::Right),
|
||||||
|
@ -198,17 +202,24 @@ where I: Iterator<Item = Result<u8, Error>>
|
||||||
buf.push(c);
|
buf.push(c);
|
||||||
c = iter.next().unwrap().unwrap();
|
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 {
|
match c {
|
||||||
// rxvt mouse encoding:
|
// rxvt mouse encoding:
|
||||||
// ESC [ Cb ; Cx ; Cy ; M
|
// ESC [ Cb ; Cx ; Cy ; M
|
||||||
b'M' => {
|
b'M' => {
|
||||||
let str_buf = String::from_utf8(buf).unwrap();
|
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 nums: Vec<u16> = str_buf[..str_buf.len()-1].split(';')
|
||||||
let cy = nums.next().unwrap().parse::<u16>().unwrap();
|
.map(|n| n.parse().unwrap())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let cb = nums[0];
|
||||||
|
let cx = nums[1];
|
||||||
|
let cy = nums[2];
|
||||||
|
|
||||||
let event = match cb {
|
let event = match cb {
|
||||||
32 => MouseEvent::Press(MouseButton::Left, cx, cy),
|
32 => MouseEvent::Press(MouseButton::Left, cx, cy),
|
||||||
|
@ -218,7 +229,7 @@ where I: Iterator<Item = Result<u8, Error>>
|
||||||
64 => MouseEvent::Hold(cx, cy),
|
64 => MouseEvent::Hold(cx, cy),
|
||||||
96 |
|
96 |
|
||||||
97 => MouseEvent::Press(MouseButton::WheelUp, cx, cy),
|
97 => MouseEvent::Press(MouseButton::WheelUp, cx, cy),
|
||||||
_ => return error,
|
_ => return Ok(Event::UnknownCsi(str_buf.into_bytes())),
|
||||||
};
|
};
|
||||||
|
|
||||||
Event::Mouse(event)
|
Event::Mouse(event)
|
||||||
|
@ -229,16 +240,20 @@ where I: Iterator<Item = Result<u8, Error>>
|
||||||
|
|
||||||
// This CSI sequence can be a list of semicolon-separated
|
// This CSI sequence can be a list of semicolon-separated
|
||||||
// numbers.
|
// numbers.
|
||||||
let nums: Vec<u8> = str_buf.split(';')
|
let nums: Vec<u8> = str_buf[..str_buf.len()-1].split(';')
|
||||||
.map(|n| n.parse().unwrap())
|
.map(|n| n.parse().unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if nums.is_empty() {
|
if nums.is_empty() {
|
||||||
return error;
|
return Ok(Event::UnknownCsi(str_buf.into_bytes()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: handle multiple values for key modififiers (ex: values
|
// TODO: handle multiple values for key modififiers (ex: values
|
||||||
// [3, 2] means Shift+Delete)
|
// [3, 2] means Shift+Delete)
|
||||||
|
if nums.len() > 1 {
|
||||||
|
return Ok(Event::UnknownCsi(str_buf.into_bytes()));
|
||||||
|
}
|
||||||
|
|
||||||
match nums[0] {
|
match nums[0] {
|
||||||
1 | 7 => Event::Key(Key::Home),
|
1 | 7 => Event::Key(Key::Home),
|
||||||
2 => Event::Key(Key::Insert),
|
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 @ 11...15 => Event::Key(Key::F(v - 10)),
|
||||||
v @ 17...21 => Event::Key(Key::F(v - 11)),
|
v @ 17...21 => Event::Key(Key::F(v - 11)),
|
||||||
v @ 23...24 => Event::Key(Key::F(v - 12)),
|
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,
|
_ => return error,
|
||||||
|
|
16
src/input.rs
16
src/input.rs
|
@ -56,14 +56,14 @@ impl<R: Read> Iterator for Events<R> {
|
||||||
c => parse_event(Ok(c), &mut source.bytes()),
|
c => parse_event(Ok(c), &mut source.bytes()),
|
||||||
},
|
},
|
||||||
Ok(2) => {
|
Ok(2) => {
|
||||||
if buf[0] != b'\x1B' {
|
let mut option_iter = &mut Some(buf[1]).into_iter();
|
||||||
// this is not an escape sequence, but we read two bytes, save the second byte
|
let result = {
|
||||||
// for later
|
let mut iter = option_iter.map(|c| Ok(c)).chain(source.bytes());
|
||||||
self.leftover = Some(buf[1]);
|
parse_event(Ok(buf[0]), &mut iter)
|
||||||
}
|
};
|
||||||
|
// If the option_iter wasn't consumed, keep the byte for later.
|
||||||
let mut iter = buf[1..2].iter().map(|c| Ok(*c)).chain(source.bytes());
|
self.leftover = option_iter.next();
|
||||||
parse_event(Ok(buf[0]), &mut iter)
|
result
|
||||||
}
|
}
|
||||||
Ok(_) => unreachable!(),
|
Ok(_) => unreachable!(),
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
//!
|
//!
|
||||||
//! # Example
|
//! # Example
|
||||||
//!
|
//!
|
||||||
//! ```rust,ignore
|
//! ```rust,no_run
|
||||||
//! use termion::raw::IntoRawMode;
|
//! use termion::raw::IntoRawMode;
|
||||||
//! use std::io::{Write, stdout};
|
//! use std::io::{Write, stdout};
|
||||||
//!
|
//!
|
||||||
|
|
Loading…
Reference in New Issue