Fix surrogate pair handling on Windows
Not tested
diff --git a/TODO.md b/TODO.md
index 0de744b..97c6da4 100644
--- a/TODO.md
+++ b/TODO.md
@@ -67,5 +67,5 @@
Windows
- [ ] is_atty is not working with cygwin/msys
-- [ ] UTF-16 surrogate pair
+- [X] UTF-16 surrogate pair
- [ ] handle ansi escape code (https://docs.rs/console/0.6.1/console/fn.strip_ansi_codes.html ?)
diff --git a/src/tty/windows.rs b/src/tty/windows.rs
index 4ec4209..0bdfc2f 100644
--- a/src/tty/windows.rs
+++ b/src/tty/windows.rs
@@ -87,13 +87,13 @@
/// Console input reader
pub struct ConsoleRawReader {
handle: HANDLE,
- buf: Option<u16>,
+ buf: [u16; 2],
}
impl ConsoleRawReader {
pub fn new() -> Result<ConsoleRawReader> {
let handle = try!(get_std_handle(STDIN_FILENO));
- Ok(ConsoleRawReader { handle, buf: None })
+ Ok(ConsoleRawReader { handle, buf: [0; 2] })
}
}
@@ -105,6 +105,7 @@
let mut rec: wincon::INPUT_RECORD = unsafe { mem::zeroed() };
let mut count = 0;
+ let mut surrogate = false;
loop {
// TODO GetNumberOfConsoleInputEvents
check!(consoleapi::ReadConsoleInputW(
@@ -192,9 +193,19 @@
} else if utf16 == 27 {
return Ok(KeyPress::Esc);
} else {
- // TODO How to support surrogate pair ?
- self.buf = Some(utf16);
- let orc = decode_utf16(self).next();
+ if utf16 >= 0xD800 && utf16 < 0xDC00 {
+ surrogate = true;
+ self.buf[0] = utf16;
+ continue;
+ }
+ let buf = if surrogate {
+ self.buf[1] = utf16;
+ &self.buf[..]
+ } else {
+ self.buf[0] = utf16;
+ &self.buf[..1]
+ };
+ let orc = decode_utf16(buf.iter().cloned()).next();
if orc.is_none() {
return Err(error::ReadlineError::Eof);
}
@@ -209,16 +220,6 @@
}
}
-impl Iterator for ConsoleRawReader {
- type Item = u16;
-
- fn next(&mut self) -> Option<u16> {
- let buf = self.buf;
- self.buf = None;
- buf
- }
-}
-
pub struct ConsoleRenderer {
out: Stdout,
handle: HANDLE,