From 15c65dc5f99fefab1ad8f3ce49621191484ea898 Mon Sep 17 00:00:00 2001 From: ticki Date: Fri, 24 Mar 2017 21:53:05 +0100 Subject: [PATCH] Run rustfmt on the code. --- examples/alternate_screen_raw.rs | 6 +- examples/async.rs | 6 +- examples/click.rs | 8 +- examples/commie.rs | 16 +- examples/keys.rs | 14 +- examples/mouse.rs | 5 +- examples/rainbow.rs | 27 ++- examples/rustc_fun.rs | 18 +- examples/simple.rs | 29 ++- src/async.rs | 18 +- src/color.rs | 41 ++-- src/cursor.rs | 16 +- src/event.rs | 343 ++++++++++++++++--------------- src/input.rs | 11 +- src/raw.rs | 4 +- src/screen.rs | 4 +- src/style.rs | 4 +- src/termios.rs | 6 +- src/tty.rs | 2 +- 19 files changed, 314 insertions(+), 264 deletions(-) diff --git a/examples/alternate_screen_raw.rs b/examples/alternate_screen_raw.rs index beea9e9..7ba7888 100644 --- a/examples/alternate_screen_raw.rs +++ b/examples/alternate_screen_raw.rs @@ -27,12 +27,12 @@ fn main() { Key::Char('q') => break, Key::Char('1') => { write!(screen, "{}", ToMainScreen).unwrap(); - }, + } Key::Char('2') => { write!(screen, "{}", ToAlternateScreen).unwrap(); write_alt_screen_msg(&mut screen); - }, - _ => {}, + } + _ => {} } screen.flush().unwrap(); } diff --git a/examples/async.rs b/examples/async.rs index a1848dd..b16bb78 100644 --- a/examples/async.rs +++ b/examples/async.rs @@ -11,7 +11,11 @@ fn main() { let mut stdout = stdout.lock().into_raw_mode().unwrap(); let mut stdin = async_stdin().bytes(); - write!(stdout, "{}{}", termion::clear::All, termion::cursor::Goto(1, 1)).unwrap(); + write!(stdout, + "{}{}", + termion::clear::All, + termion::cursor::Goto(1, 1)) + .unwrap(); loop { write!(stdout, "{}", termion::clear::CurrentLine).unwrap(); diff --git a/examples/click.rs b/examples/click.rs index d756374..fe903d8 100644 --- a/examples/click.rs +++ b/examples/click.rs @@ -9,7 +9,11 @@ fn main() { let stdin = stdin(); let mut stdout = MouseTerminal::from(stdout().into_raw_mode().unwrap()); - write!(stdout, "{}{}q to exit. Click, click, click!", termion::clear::All, termion::cursor::Goto(1, 1)).unwrap(); + write!(stdout, + "{}{}q to exit. Click, click, click!", + termion::clear::All, + termion::cursor::Goto(1, 1)) + .unwrap(); stdout.flush().unwrap(); for c in stdin.events() { @@ -20,7 +24,7 @@ fn main() { match me { MouseEvent::Press(_, x, y) => { write!(stdout, "{}x", termion::cursor::Goto(x, y)).unwrap(); - }, + } _ => (), } } diff --git a/examples/commie.rs b/examples/commie.rs index feb80df..32f8820 100644 --- a/examples/commie.rs +++ b/examples/commie.rs @@ -28,10 +28,20 @@ const COMMUNISM: &'static str = r#" fn main() { let mut state = 0; - println!("\n{}{}{}{}{}{}", cursor::Hide, clear::All, cursor::Goto(1, 1), color::Fg(color::Black), color::Bg(color::Red), COMMUNISM); + println!("\n{}{}{}{}{}{}", + cursor::Hide, + clear::All, + cursor::Goto(1, 1), + color::Fg(color::Black), + color::Bg(color::Red), + COMMUNISM); loop { - println!("{}{} ☭ GAY ☭ SPACE ☭ COMMUNISM ☭ ", cursor::Goto(1, 1), color::Bg(color::AnsiValue(state))); - println!("{}{} WILL PREVAIL, COMRADES! ", cursor::Goto(1, 20), color::Bg(color::AnsiValue(state))); + println!("{}{} ☭ GAY ☭ SPACE ☭ COMMUNISM ☭ ", + cursor::Goto(1, 1), + color::Bg(color::AnsiValue(state))); + println!("{}{} WILL PREVAIL, COMRADES! ", + cursor::Goto(1, 20), + color::Bg(color::AnsiValue(state))); state += 1; state %= 8; diff --git a/examples/keys.rs b/examples/keys.rs index 1b44bc7..272ffd1 100644 --- a/examples/keys.rs +++ b/examples/keys.rs @@ -9,14 +9,20 @@ fn main() { let stdin = stdin(); let mut stdout = stdout().into_raw_mode().unwrap(); - write!(stdout, "{}{}q to exit. Type stuff, use alt, and so on.{}", + write!(stdout, + "{}{}q to exit. Type stuff, use alt, and so on.{}", termion::clear::All, termion::cursor::Goto(1, 1), - termion::cursor::Hide).unwrap(); + termion::cursor::Hide) + .unwrap(); stdout.flush().unwrap(); for c in stdin.keys() { - write!(stdout, "{}{}", termion::cursor::Goto(1, 1), termion::clear::CurrentLine).unwrap(); + write!(stdout, + "{}{}", + termion::cursor::Goto(1, 1), + termion::clear::CurrentLine) + .unwrap(); match c.unwrap() { Key::Char('q') => break, @@ -29,7 +35,7 @@ fn main() { Key::Up => println!("↑"), Key::Down => println!("↓"), Key::Backspace => println!("×"), - _ => {}, + _ => {} } stdout.flush().unwrap(); } diff --git a/examples/mouse.rs b/examples/mouse.rs index c8510c8..cbe8baf 100644 --- a/examples/mouse.rs +++ b/examples/mouse.rs @@ -14,7 +14,7 @@ fn main() { "{}{}q to exit. Type stuff, use alt, click around...", termion::clear::All, termion::cursor::Goto(1, 1)) - .unwrap(); + .unwrap(); for c in stdin.events() { let evt = c.unwrap(); @@ -33,7 +33,8 @@ fn main() { termion::clear::UntilNewline, x, y, - cursor::Goto(a, b)).unwrap(); + cursor::Goto(a, b)) + .unwrap(); } } } diff --git a/examples/rainbow.rs b/examples/rainbow.rs index e6ee27b..4ee4000 100644 --- a/examples/rainbow.rs +++ b/examples/rainbow.rs @@ -6,13 +6,20 @@ use termion::raw::IntoRawMode; use std::io::{Write, stdout, stdin}; fn rainbow(stdout: &mut W, blue: u8) { - write!(stdout, "{}{}", termion::cursor::Goto(1, 1), termion::clear::All).unwrap(); + write!(stdout, + "{}{}", + termion::cursor::Goto(1, 1), + termion::clear::All) + .unwrap(); for red in 0..32 { let red = red * 8; for green in 0..64 { let green = green * 4; - write!(stdout, "{} ", termion::color::Bg(termion::color::Rgb(red, green, blue))).unwrap(); + write!(stdout, + "{} ", + termion::color::Bg(termion::color::Rgb(red, green, blue))) + .unwrap(); } write!(stdout, "\n\r").unwrap(); } @@ -24,10 +31,12 @@ fn main() { let stdin = stdin(); let mut stdout = stdout().into_raw_mode().unwrap(); - writeln!(stdout, "{}{}{}Use the up/down arrow keys to change the blue in the rainbow.", - termion::clear::All, - termion::cursor::Goto(1, 1), - termion::cursor::Hide).unwrap(); + writeln!(stdout, + "{}{}{}Use the up/down arrow keys to change the blue in the rainbow.", + termion::clear::All, + termion::cursor::Goto(1, 1), + termion::cursor::Hide) + .unwrap(); let mut blue = 172u8; @@ -36,13 +45,13 @@ fn main() { Key::Up => { blue = blue.saturating_add(4); rainbow(&mut stdout, blue); - }, + } Key::Down => { blue = blue.saturating_sub(4); rainbow(&mut stdout, blue); - }, + } Key::Char('q') => break, - _ => {}, + _ => {} } stdout.flush().unwrap(); } diff --git a/examples/rustc_fun.rs b/examples/rustc_fun.rs index fcca043..734e89f 100644 --- a/examples/rustc_fun.rs +++ b/examples/rustc_fun.rs @@ -12,13 +12,13 @@ fn main() { {line_num_fg}{line_num_bg}84 {reset} }};\n\ {line_num_fg}{line_num_bg}85 {reset} }}\n\ {line_num_fg}{line_num_bg}{info_line}{reset} {red}^{reset} {error_fg}borrow from first closure ends here", - lighgreen=color::Fg(color::LightGreen), - red=color::Fg(color::Red), - bold=style::Bold, - reset=style::Reset, - magenta=color::Fg(color::Magenta), - line_num_bg=color::Bg(color::AnsiValue::grayscale(3)), - line_num_fg=color::Fg(color::AnsiValue::grayscale(18)), - info_line="| ", - error_fg=color::Fg(color::AnsiValue::grayscale(17))) + lighgreen = color::Fg(color::LightGreen), + red = color::Fg(color::Red), + bold = style::Bold, + reset = style::Reset, + magenta = color::Fg(color::Magenta), + line_num_bg = color::Bg(color::AnsiValue::grayscale(3)), + line_num_fg = color::Fg(color::AnsiValue::grayscale(18)), + info_line = "| ", + error_fg = color::Fg(color::AnsiValue::grayscale(17))) } diff --git a/examples/simple.rs b/examples/simple.rs index 23fe480..93ef1df 100644 --- a/examples/simple.rs +++ b/examples/simple.rs @@ -11,8 +11,14 @@ fn main() { let stdin = stdin(); let stdin = stdin.lock(); - write!(stdout, "{}{}{}yo, 'q' will exit.{}{}", termion::clear::All, termion::cursor::Goto(5, 5), - termion::style::Bold, termion::style::Reset, termion::cursor::Goto(20, 10)).unwrap(); + write!(stdout, + "{}{}{}yo, 'q' will exit.{}{}", + termion::clear::All, + termion::cursor::Goto(5, 5), + termion::style::Bold, + termion::style::Reset, + termion::cursor::Goto(20, 10)) + .unwrap(); stdout.flush().unwrap(); let mut bytes = stdin.bytes(); @@ -20,15 +26,16 @@ fn main() { let b = bytes.next().unwrap().unwrap(); match b { - // Quit - b'q' => return, - // Clear the screen - b'c' => write!(stdout, "{}", termion::clear::All), - // Set red color - b'r' => write!(stdout, "{}", color::Fg(color::Rgb(5, 0, 0))), - // Write it to stdout. - a => write!(stdout, "{}", a), - }.unwrap(); + // Quit + b'q' => return, + // Clear the screen + b'c' => write!(stdout, "{}", termion::clear::All), + // Set red color + b'r' => write!(stdout, "{}", color::Fg(color::Rgb(5, 0, 0))), + // Write it to stdout. + a => write!(stdout, "{}", a), + } + .unwrap(); stdout.flush().unwrap(); } diff --git a/src/async.rs b/src/async.rs index 1db9429..6255b78 100644 --- a/src/async.rs +++ b/src/async.rs @@ -17,17 +17,13 @@ use tty; pub fn async_stdin() -> AsyncReader { let (send, recv) = mpsc::channel(); - thread::spawn(move || { - for i in tty::get_tty().unwrap().bytes() { - if send.send(i).is_err() { - return; - } - } - }); + thread::spawn(move || for i in tty::get_tty().unwrap().bytes() { + if send.send(i).is_err() { + return; + } + }); - AsyncReader { - recv: recv, - } + AsyncReader { recv: recv } } /// An asynchronous reader. @@ -59,7 +55,7 @@ impl Read for AsyncReader { Ok(Ok(b)) => { buf[total] = b; total += 1; - }, + } Ok(Err(e)) => return Err(e), Err(_) => break, } diff --git a/src/color.rs b/src/color.rs index 1cdf32c..6f3fd88 100644 --- a/src/color.rs +++ b/src/color.rs @@ -83,9 +83,15 @@ pub struct AnsiValue(pub u8); impl AnsiValue { /// 216-color (r, g, b ≤ 5) RGB. pub fn rgb(r: u8, g: u8, b: u8) -> AnsiValue { - debug_assert!(r <= 5, "Red color fragment (r = {}) is out of bound. Make sure r ≤ 5.", r); - debug_assert!(g <= 5, "Green color fragment (g = {}) is out of bound. Make sure g ≤ 5.", g); - debug_assert!(b <= 5, "Blue color fragment (b = {}) is out of bound. Make sure b ≤ 5.", b); + debug_assert!(r <= 5, + "Red color fragment (r = {}) is out of bound. Make sure r ≤ 5.", + r); + debug_assert!(g <= 5, + "Green color fragment (g = {}) is out of bound. Make sure g ≤ 5.", + g); + debug_assert!(b <= 5, + "Blue color fragment (b = {}) is out of bound. Make sure b ≤ 5.", + b); AnsiValue(16 + 36 * r + 6 * g + b) } @@ -95,8 +101,10 @@ impl AnsiValue { /// There are 24 shades of gray. pub fn grayscale(shade: u8) -> AnsiValue { // Unfortunately, there are a little less than fifty shades. - debug_assert!(shade < 24, "Grayscale out of bound (shade = {}). There are only 24 shades of \ - gray.", shade); + debug_assert!(shade < 24, + "Grayscale out of bound (shade = {}). There are only 24 shades of \ + gray.", + shade); AnsiValue(0xE8 + shade) } @@ -197,24 +205,21 @@ impl DetectColors for W { } else { // OSC 4 is not supported, trust TERM contents. Ok(match env::var_os("TERM") { - Some(val) => { - if val.to_str().unwrap_or("").contains("256color") { - 256 - } else { - 8 - } - } - None => 8, - }) + Some(val) => { + if val.to_str().unwrap_or("").contains("256color") { + 256 + } else { + 8 + } + } + None => 8, + }) } } } /// Detect a color using OSC 4. -fn detect_color(stdout: &mut Write, - stdin: &mut Read, - color: u16) - -> io::Result { +fn detect_color(stdout: &mut Write, stdin: &mut Read, color: u16) -> io::Result { // Is the color available? // Use `ESC ] 4 ; color ; ? BEL`. write!(stdout, "\x1B]4;{};?\x07", color)?; diff --git a/src/cursor.rs b/src/cursor.rs index 6aef5dd..5cfa72e 100644 --- a/src/cursor.rs +++ b/src/cursor.rs @@ -30,7 +30,9 @@ derive_csi_sequence!("Show the cursor.", Show, "?25h"); pub struct Goto(pub u16, pub u16); impl Default for Goto { - fn default() -> Goto { Goto(1, 1) } + fn default() -> Goto { + Goto(1, 1) + } } impl fmt::Display for Goto { @@ -118,11 +120,17 @@ impl DetectCursorPos for W { read_chars.pop(); // remove trailing R. let read_str = String::from_utf8(read_chars).unwrap(); let beg = read_str.rfind('[').unwrap(); - let coords: String = read_str.chars().skip(beg+1).collect(); + let coords: String = read_str.chars().skip(beg + 1).collect(); let mut nums = coords.split(';'); - let cy = nums.next().unwrap().parse::().unwrap(); - let cx = nums.next().unwrap().parse::().unwrap(); + let cy = nums.next() + .unwrap() + .parse::() + .unwrap(); + let cx = nums.next() + .unwrap() + .parse::() + .unwrap(); Ok((cx, cy)) } diff --git a/src/event.rs b/src/event.rs index 4c70ea9..688f8e0 100644 --- a/src/event.rs +++ b/src/event.rs @@ -106,23 +106,23 @@ pub fn parse_event(item: u8, iter: &mut I) -> Result b'\x1B' => { // This is an escape character, leading a control sequence. 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 Err(error), - } + 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 Err(error), } - Some(Ok(b'[')) => { - // This is a CSI sequence. - parse_csi(iter).ok_or(error)? - } - Some(Ok(c)) => { - let ch = parse_utf8_char(c, iter); - Event::Key(Key::Alt(try!(ch))) - } - Some(Err(_)) | None => return Err(error), - }) + } + Some(Ok(b'[')) => { + // This is a CSI sequence. + parse_csi(iter).ok_or(error)? + } + Some(Ok(c)) => { + let ch = parse_utf8_char(c, iter); + Event::Key(Key::Alt(try!(ch))) + } + Some(Err(_)) | None => return Err(error), + }) } b'\n' | b'\r' => Ok(Event::Key(Key::Char('\n'))), b'\t' => Ok(Event::Key(Key::Char('\t'))), @@ -132,9 +132,9 @@ pub fn parse_event(item: u8, iter: &mut I) -> Result b'\0' => Ok(Event::Key(Key::Null)), c => { Ok({ - let ch = parse_utf8_char(c, iter); - Event::Key(Key::Char(try!(ch))) - }) + let ch = parse_utf8_char(c, iter); + Event::Key(Key::Char(try!(ch))) + }) } } } @@ -146,160 +146,163 @@ fn parse_csi(iter: &mut I) -> Option where I: Iterator> { Some(match iter.next() { - Some(Ok(b'D')) => Event::Key(Key::Left), - Some(Ok(b'C')) => Event::Key(Key::Right), - Some(Ok(b'A')) => Event::Key(Key::Up), - Some(Ok(b'B')) => Event::Key(Key::Down), - Some(Ok(b'H')) => Event::Key(Key::Home), - Some(Ok(b'F')) => Event::Key(Key::End), - Some(Ok(b'M')) => { - // X10 emulation mouse encoding: ESC [ CB Cx Cy (6 characters only). - let mut next = || iter.next().unwrap().unwrap(); + Some(Ok(b'D')) => Event::Key(Key::Left), + Some(Ok(b'C')) => Event::Key(Key::Right), + Some(Ok(b'A')) => Event::Key(Key::Up), + Some(Ok(b'B')) => Event::Key(Key::Down), + Some(Ok(b'H')) => Event::Key(Key::Home), + Some(Ok(b'F')) => Event::Key(Key::End), + Some(Ok(b'M')) => { + // X10 emulation mouse encoding: ESC [ CB Cx Cy (6 characters only). + let mut next = || iter.next().unwrap().unwrap(); - let cb = next() as i8 - 32; - // (1, 1) are the coords for upper left. - let cx = next().saturating_sub(32) as u16; - let cy = next().saturating_sub(32) as u16; - Event::Mouse(match cb & 0b11 { - 0 => { - if cb & 0x40 != 0 { - MouseEvent::Press(MouseButton::WheelUp, cx, cy) - } else { - MouseEvent::Press(MouseButton::Left, cx, cy) - } - } - 1 => { - if cb & 0x40 != 0 { - MouseEvent::Press(MouseButton::WheelDown, cx, cy) - } else { - MouseEvent::Press(MouseButton::Middle, cx, cy) - } - } - 2 => MouseEvent::Press(MouseButton::Right, cx, cy), - 3 => MouseEvent::Release(cx, cy), - _ => return None, - }) - } - Some(Ok(b'<')) => { - // xterm mouse encoding: - // ESC [ < Cb ; Cx ; Cy (;) (M or m) - let mut buf = Vec::new(); - let mut c = iter.next().unwrap().unwrap(); - while match c { - b'm' | b'M' => false, - _ => true, - } { - buf.push(c); - c = iter.next().unwrap().unwrap(); - } - 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 event = match cb { - 0...2 | 64...65 => { - let button = match cb { - 0 => MouseButton::Left, - 1 => MouseButton::Middle, - 2 => MouseButton::Right, - 64 => MouseButton::WheelUp, - 65 => MouseButton::WheelDown, - _ => unreachable!(), - }; - match c { - b'M' => MouseEvent::Press(button, cx, cy), - b'm' => MouseEvent::Release(cx, cy), - _ => return None, - } - } - 32 => MouseEvent::Hold(cx, cy), - 3 => MouseEvent::Release(cx, cy), - _ => return None, - }; - - Event::Mouse(event) - } - Some(Ok(c @ b'0'...b'9')) => { - // Numbered escape code. - let mut buf = Vec::new(); + let cb = next() as i8 - 32; + // (1, 1) are the coords for upper left. + let cx = next().saturating_sub(32) as u16; + let cy = next().saturating_sub(32) as u16; + Event::Mouse(match cb & 0b11 { + 0 => { + if cb & 0x40 != 0 { + MouseEvent::Press(MouseButton::WheelUp, cx, cy) + } else { + MouseEvent::Press(MouseButton::Left, cx, cy) + } + } + 1 => { + if cb & 0x40 != 0 { + MouseEvent::Press(MouseButton::WheelDown, cx, cy) + } else { + MouseEvent::Press(MouseButton::Middle, cx, cy) + } + } + 2 => MouseEvent::Press(MouseButton::Right, cx, cy), + 3 => MouseEvent::Release(cx, cy), + _ => return None, + }) + } + Some(Ok(b'<')) => { + // xterm mouse encoding: + // ESC [ < Cb ; Cx ; Cy (;) (M or m) + let mut buf = Vec::new(); + let mut c = iter.next().unwrap().unwrap(); + while match c { + b'm' | b'M' => false, + _ => true, + } { buf.push(c); - let mut c = iter.next().unwrap().unwrap(); - // The final byte of a CSI sequence can be in the range 64-126, so - // let's keep reading anything else. - while c < 64 || c > 126 { - buf.push(c); - c = iter.next().unwrap().unwrap(); - } - - match c { - // rxvt mouse encoding: - // ESC [ Cb ; Cx ; Cy ; M - b'M' => { - let str_buf = String::from_utf8(buf).unwrap(); - - let nums: Vec = str_buf - .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), - 33 => MouseEvent::Press(MouseButton::Middle, cx, cy), - 34 => MouseEvent::Press(MouseButton::Right, cx, cy), - 35 => MouseEvent::Release(cx, cy), - 64 => MouseEvent::Hold(cx, cy), - 96 | 97 => MouseEvent::Press(MouseButton::WheelUp, cx, cy), - _ => return None, - }; - - Event::Mouse(event) - } - // Special key code. - b'~' => { - let str_buf = String::from_utf8(buf).unwrap(); - - // This CSI sequence can be a list of semicolon-separated - // numbers. - let nums: Vec = str_buf - .split(';') - .map(|n| n.parse().unwrap()) - .collect(); - - if nums.is_empty() { - return None; - } - - // TODO: handle multiple values for key modififiers (ex: values - // [3, 2] means Shift+Delete) - if nums.len() > 1 { - return None; - } - - match nums[0] { - 1 | 7 => Event::Key(Key::Home), - 2 => Event::Key(Key::Insert), - 3 => Event::Key(Key::Delete), - 4 | 8 => Event::Key(Key::End), - 5 => Event::Key(Key::PageUp), - 6 => Event::Key(Key::PageDown), - 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 None, - } - } - _ => return None, - } + c = iter.next().unwrap().unwrap(); } - _ => return None, - }) + 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 event = match cb { + 0...2 | 64...65 => { + let button = match cb { + 0 => MouseButton::Left, + 1 => MouseButton::Middle, + 2 => MouseButton::Right, + 64 => MouseButton::WheelUp, + 65 => MouseButton::WheelDown, + _ => unreachable!(), + }; + match c { + b'M' => MouseEvent::Press(button, cx, cy), + b'm' => MouseEvent::Release(cx, cy), + _ => return None, + } + } + 32 => MouseEvent::Hold(cx, cy), + 3 => MouseEvent::Release(cx, cy), + _ => return None, + }; + + Event::Mouse(event) + } + Some(Ok(c @ b'0'...b'9')) => { + // Numbered escape code. + let mut buf = Vec::new(); + buf.push(c); + let mut c = iter.next().unwrap().unwrap(); + // The final byte of a CSI sequence can be in the range 64-126, so + // let's keep reading anything else. + while c < 64 || c > 126 { + buf.push(c); + c = iter.next().unwrap().unwrap(); + } + + match c { + // rxvt mouse encoding: + // ESC [ Cb ; Cx ; Cy ; M + b'M' => { + let str_buf = String::from_utf8(buf).unwrap(); + + let nums: Vec = str_buf.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), + 33 => MouseEvent::Press(MouseButton::Middle, cx, cy), + 34 => MouseEvent::Press(MouseButton::Right, cx, cy), + 35 => MouseEvent::Release(cx, cy), + 64 => MouseEvent::Hold(cx, cy), + 96 | 97 => MouseEvent::Press(MouseButton::WheelUp, cx, cy), + _ => return None, + }; + + Event::Mouse(event) + } + // Special key code. + b'~' => { + let str_buf = String::from_utf8(buf).unwrap(); + + // This CSI sequence can be a list of semicolon-separated + // numbers. + let nums: Vec = str_buf.split(';').map(|n| n.parse().unwrap()).collect(); + + if nums.is_empty() { + return None; + } + + // TODO: handle multiple values for key modififiers (ex: values + // [3, 2] means Shift+Delete) + if nums.len() > 1 { + return None; + } + + match nums[0] { + 1 | 7 => Event::Key(Key::Home), + 2 => Event::Key(Key::Insert), + 3 => Event::Key(Key::Delete), + 4 | 8 => Event::Key(Key::End), + 5 => Event::Key(Key::PageUp), + 6 => Event::Key(Key::PageDown), + 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 None, + } + } + _ => return None, + } + } + _ => return None, + }) } diff --git a/src/input.rs b/src/input.rs index 4f84221..a9e874d 100644 --- a/src/input.rs +++ b/src/input.rs @@ -81,8 +81,8 @@ fn parse_event(item: u8, iter: &mut I) -> Result let mut buf = vec![item]; let result = { let mut iter = iter.inspect(|byte| if let &Ok(byte) = byte { - buf.push(byte); - }); + buf.push(byte); + }); event::parse_event(item, &mut iter) }; result.or(Ok(Event::Unsupported(buf))) @@ -216,9 +216,10 @@ mod test { #[test] fn test_events() { - let mut i = b"\x1B[\x00bc\x7F\x1B[D\ + let mut i = + b"\x1B[\x00bc\x7F\x1B[D\ \x1B[M\x00\x22\x24\x1B[<0;2;4;M\x1B[32;2;4M\x1B[<0;2;4;m\x1B[35;2;4Mb" - .events(); + .events(); assert_eq!(i.next().unwrap().unwrap(), Event::Unsupported(vec![0x1B, b'[', 0x00])); @@ -249,7 +250,7 @@ mod test { let mut st = b"\x1B[11~\x1B[12~\x1B[13~\x1B[14~\x1B[15~\ \x1B[17~\x1B[18~\x1B[19~\x1B[20~\x1B[21~\x1B[23~\x1B[24~" - .keys(); + .keys(); for i in 1..13 { assert_eq!(st.next().unwrap().unwrap(), Key::F(i)); } diff --git a/src/raw.rs b/src/raw.rs index 952ab20..14cc87c 100644 --- a/src/raw.rs +++ b/src/raw.rs @@ -129,9 +129,7 @@ impl IntoRawMode for W { #[cfg(target_os = "redox")] fn into_raw_mode(mut self) -> io::Result> { - write!(self, csi!("?82h")).map(|_| { - RawTerminal { output: self } - }) + write!(self, csi!("?82h")).map(|_| RawTerminal { output: self }) } } diff --git a/src/screen.rs b/src/screen.rs index ef70a74..822399e 100644 --- a/src/screen.rs +++ b/src/screen.rs @@ -56,9 +56,7 @@ impl AlternateScreen { /// to the alternate screen. pub fn from(mut output: W) -> Self { write!(output, "{}", ToAlternateScreen).expect("switch to alternate screen"); - AlternateScreen { - output: output, - } + AlternateScreen { output: output } } } diff --git a/src/style.rs b/src/style.rs index cd3eb24..58e9a78 100644 --- a/src/style.rs +++ b/src/style.rs @@ -16,5 +16,7 @@ derive_csi_sequence!("Undo italic text.", NoItalic, "23m"); derive_csi_sequence!("Undo underlined text.", NoUnderline, "24m"); derive_csi_sequence!("Undo blinking text (not widely supported).", NoBlink, "25m"); derive_csi_sequence!("Undo inverted colors (negative mode).", NoInvert, "27m"); -derive_csi_sequence!("Undo crossed out text (not widely supported).", NoCrossedOut, "29m"); +derive_csi_sequence!("Undo crossed out text (not widely supported).", + NoCrossedOut, + "29m"); derive_csi_sequence!("Framed text (not widely supported).", Framed, "51m"); diff --git a/src/termios.rs b/src/termios.rs index 6da58cc..420408f 100644 --- a/src/termios.rs +++ b/src/termios.rs @@ -9,7 +9,7 @@ pub const TIOCGWINSZ: usize = 0x00005413; #[cfg(not(target_os = "linux"))] pub const TIOCGWINSZ: usize = 0x40087468; -extern { +extern "C" { pub fn tcgetattr(fd: c_int, termptr: *mut Termios) -> c_int; pub fn tcsetattr(fd: c_int, opt: c_int, termptr: *mut Termios) -> c_int; pub fn cfmakeraw(termptr: *mut Termios); @@ -24,9 +24,7 @@ pub fn get_terminal_attr() -> (Termios, c_int) { } pub fn set_terminal_attr(ios: *mut Termios) -> c_int { - unsafe { - tcsetattr(0, 0, ios) - } + unsafe { tcsetattr(0, 0, ios) } } #[cfg(test)] diff --git a/src/tty.rs b/src/tty.rs index deab3f4..9788e54 100644 --- a/src/tty.rs +++ b/src/tty.rs @@ -6,7 +6,7 @@ use std::os::unix::io::AsRawFd; pub fn is_tty(stream: &T) -> bool { use libc; - unsafe { libc::isatty(stream.as_raw_fd()) == 1} + unsafe { libc::isatty(stream.as_raw_fd()) == 1 } } /// This will panic.