diff --git a/src/tty/fuchsia.rs b/src/tty/fuchsia.rs
index a63723b..febb577 100644
--- a/src/tty/fuchsia.rs
+++ b/src/tty/fuchsia.rs
@@ -3,17 +3,22 @@
 use std::mem;
 use std::sync::atomic;
 use libc;
-use char_iter;
+use unicode_segmentation::UnicodeSegmentation;
+use utf8parse::{Parser, Receiver};
 
-use config::Config;
-use consts::{self, KeyPress};
+use config::{ColorMode, Config, OutputStreamType};
+use highlight::Highlighter;
+use keys::{self, KeyPress};
+use line_buffer::LineBuffer;
 use error;
 use Result;
-use super::{RawMode, RawReader, Term};
+use super::{truncate, width, Position, RawMode, RawReader, Renderer, Term};
 use fuchsia_device::pty;
+use StdStream;
 
-const STDIN_FILENO: usize = 0;
-const STDOUT_FILENO: usize = 1;
+const STDIN_FILENO: libc::c_int = libc::STDIN_FILENO;
+const STDOUT_FILENO: libc::c_int = libc::STDOUT_FILENO;
+const STDERR_FILENO: libc::c_int = libc::STDERR_FILENO;
 
 fn get_win_size() -> (usize, usize) {
     match pty::get_window_size() {
@@ -60,185 +65,522 @@
     }
 }
 
-pub type Terminal = Console;
+pub type Terminal = FuchsiaTerminal;
 
 #[derive(Clone, Debug)]
-pub struct Console {
+pub struct FuchsiaTerminal {
+    unsupported: bool,
     stdin_isatty: bool,
+    stdstream_isatty: bool,
+    pub(crate) color_mode: ColorMode,
+    stream_type: OutputStreamType,
+}
+
+struct Utf8 {
+    c: Option<char>,
+    valid: bool,
 }
 
 pub struct FuchsiaRawReader {
-    chars: char_iter::Chars<StdinRaw>,
+    stdin: StdinRaw,
+    timeout_ms: i32,
+    buf: [u8; 1],
+    parser: Parser,
+    receiver: Utf8,
 }
 
 impl FuchsiaRawReader {
-    pub fn new() -> Result<FuchsiaRawReader> {
-        let stdin = StdinRaw {};
+    pub fn new(config: &Config) -> Result<FuchsiaRawReader> {
         Ok(FuchsiaRawReader {
-            chars: char_iter::chars(stdin),
+            stdin: StdinRaw {},
+            timeout_ms: config.keyseq_timeout(),
+            buf: [0; 1],
+            parser: Parser::new(),
+            receiver: Utf8 {
+                c: None,
+                valid: true,
+            }
         })
     }
+
+    /// Handle ESC <seq1> sequences
     fn escape_sequence(&mut self) -> Result<KeyPress> {
-        // Read the next two bytes representing the escape sequence.
+        // Read the next byte representing the escape sequence.
         let seq1 = try!(self.next_char());
         if seq1 == '[' {
-            // ESC [ sequences.
-            let seq2 = try!(self.next_char());
-            if seq2.is_digit(10) {
-                // Extended escape, read additional byte.
-                let seq3 = try!(self.next_char());
-                if seq3 == '~' {
-                    Ok(match seq2 {
-                        '1' | '7' => KeyPress::Home, // '1': xterm
-                        '3' => KeyPress::Delete,
-                        '4' | '8' => KeyPress::End, // '4': xterm
-                        '5' => KeyPress::PageUp,
-                        '6' => KeyPress::PageDown,
-                        _ => {
-                            debug!(target: "rustyline", "unsupported esc sequence: ESC{:?}{:?}{:?}", seq1, seq2, seq3);
-                            KeyPress::UnknownEscSeq
-                        }
-                    })
-                } else {
-                    debug!(target: "rustyline", "unsupported esc sequence: ESC{:?}{:?}{:?}", seq1, seq2, seq3);
+            // ESC [ sequences. (CSI)
+            self.escape_csi()
+        } else if seq1 == 'O' {
+            // xterm
+            // ESC O sequences. (SS3)
+            self.escape_o()
+        } else if seq1 == '\x1b' {
+            // ESC ESC
+            Ok(KeyPress::Esc)
+        } else {
+            // TODO ESC-R (r): Undo all changes made to this line.
+            Ok(KeyPress::Meta(seq1))
+        }
+    }
+
+    /// Handle ESC [ <seq2> escape sequences
+    fn escape_csi(&mut self) -> Result<KeyPress> {
+        let seq2 = try!(self.next_char());
+        if seq2.is_digit(10) {
+            match seq2 {
+                '0' | '9' => {
+                    debug!(target: "rustyline", "unsupported esc sequence: ESC [ {:?}", seq2);
                     Ok(KeyPress::UnknownEscSeq)
                 }
-            } else {
-                Ok(match seq2 {
-                    'A' => KeyPress::Up, // ANSI
-                    'B' => KeyPress::Down,
-                    'C' => KeyPress::Right,
-                    'D' => KeyPress::Left,
-                    'F' => KeyPress::End,
-                    'H' => KeyPress::Home,
-                    _ => {
-                        debug!(target: "rustyline", "unsupported esc sequence: ESC{:?}{:?}", seq1, seq2);
-                        KeyPress::UnknownEscSeq
-                    }
-                })
-            }
-        } else if seq1 == 'O' {
-            // ESC O sequences.
-            let seq2 = try!(self.next_char());
-            Ok(match seq2 {
-                'A' => KeyPress::Up,
-                'B' => KeyPress::Down,
-                'C' => KeyPress::Right,
-                'D' => KeyPress::Left,
-                'F' => KeyPress::End,
-                'H' => KeyPress::Home,
                 _ => {
-                    debug!(target: "rustyline", "unsupported esc sequence: ESC{:?}{:?}", seq1, seq2);
+                    // Extended escape, read additional byte.
+                    self.extended_escape(seq2)
+                }
+            }
+        } else if seq2 == '[' {
+            let seq3 = try!(self.next_char());
+            // Linux console
+            Ok(match seq3 {
+                'A' => KeyPress::F(1),
+                'B' => KeyPress::F(2),
+                'C' => KeyPress::F(3),
+                'D' => KeyPress::F(4),
+                'E' => KeyPress::F(5),
+                _ => {
+                    debug!(target: "rustyline", "unsupported esc sequence: ESC [ [ {:?}", seq3);
                     KeyPress::UnknownEscSeq
                 }
             })
         } else {
-            // TODO ESC-R (r): Undo all changes made to this line.
-            Ok(match seq1 {
-                '\x08' => KeyPress::Meta('\x08'), // Backspace
-                '-' => KeyPress::Meta('-'),
-                '0'...'9' => KeyPress::Meta(seq1),
-                '<' => KeyPress::Meta('<'),
-                '>' => KeyPress::Meta('>'),
-                'b' | 'B' => KeyPress::Meta('B'),
-                'c' | 'C' => KeyPress::Meta('C'),
-                'd' | 'D' => KeyPress::Meta('D'),
-                'f' | 'F' => KeyPress::Meta('F'),
-                'l' | 'L' => KeyPress::Meta('L'),
-                'n' | 'N' => KeyPress::Meta('N'),
-                'p' | 'P' => KeyPress::Meta('P'),
-                't' | 'T' => KeyPress::Meta('T'),
-                'u' | 'U' => KeyPress::Meta('U'),
-                'y' | 'Y' => KeyPress::Meta('Y'),
-                '\x7f' => KeyPress::Meta('\x7f'), // Delete
+            // ANSI
+            Ok(match seq2 {
+                'A' => KeyPress::Up,    // kcuu1
+                'B' => KeyPress::Down,  // kcud1
+                'C' => KeyPress::Right, // kcuf1
+                'D' => KeyPress::Left,  // kcub1
+                'F' => KeyPress::End,
+                'H' => KeyPress::Home, // khome
+                'Z' => KeyPress::BackTab,
                 _ => {
-                    debug!(target: "rustyline", "unsupported esc sequence: M-{:?}", seq1);
+                    debug!(target: "rustyline", "unsupported esc sequence: ESC [ {:?}", seq2);
                     KeyPress::UnknownEscSeq
                 }
             })
         }
     }
+
+    /// Handle ESC [ <seq2:digit> escape sequences
+    fn extended_escape(&mut self, seq2: char) -> Result<KeyPress> {
+        let seq3 = try!(self.next_char());
+        if seq3 == '~' {
+            Ok(match seq2 {
+                '1' | '7' => KeyPress::Home, // tmux, xrvt
+                '2' => KeyPress::Insert,
+                '3' => KeyPress::Delete,    // kdch1
+                '4' | '8' => KeyPress::End, // tmux, xrvt
+                '5' => KeyPress::PageUp,    // kpp
+                '6' => KeyPress::PageDown,  // knp
+                _ => {
+                    debug!(target: "rustyline",
+                           "unsupported esc sequence: ESC [ {} ~", seq2);
+                    KeyPress::UnknownEscSeq
+                }
+            })
+        } else if seq3.is_digit(10) {
+            let seq4 = try!(self.next_char());
+            if seq4 == '~' {
+                Ok(match (seq2, seq3) {
+                    ('1', '1') => KeyPress::F(1),  // rxvt-unicode
+                    ('1', '2') => KeyPress::F(2),  // rxvt-unicode
+                    ('1', '3') => KeyPress::F(3),  // rxvt-unicode
+                    ('1', '4') => KeyPress::F(4),  // rxvt-unicode
+                    ('1', '5') => KeyPress::F(5),  // kf5
+                    ('1', '7') => KeyPress::F(6),  // kf6
+                    ('1', '8') => KeyPress::F(7),  // kf7
+                    ('1', '9') => KeyPress::F(8),  // kf8
+                    ('2', '0') => KeyPress::F(9),  // kf9
+                    ('2', '1') => KeyPress::F(10), // kf10
+                    ('2', '3') => KeyPress::F(11), // kf11
+                    ('2', '4') => KeyPress::F(12), // kf12
+                    _ => {
+                        debug!(target: "rustyline",
+                               "unsupported esc sequence: ESC [ {}{} ~", seq2, seq3);
+                        KeyPress::UnknownEscSeq
+                    }
+                })
+            } else if seq4 == ';' {
+                let seq5 = try!(self.next_char());
+                if seq5.is_digit(10) {
+                    let seq6 = try!(self.next_char()); // '~' expected
+                    debug!(target: "rustyline",
+                           "unsupported esc sequence: ESC [ {}{} ; {} {}", seq2, seq3, seq5, seq6);
+                } else {
+                    debug!(target: "rustyline",
+                           "unsupported esc sequence: ESC [ {}{} ; {:?}", seq2, seq3, seq5);
+                }
+                Ok(KeyPress::UnknownEscSeq)
+            } else {
+                debug!(target: "rustyline",
+                       "unsupported esc sequence: ESC [ {}{} {:?}", seq2, seq3, seq4);
+                Ok(KeyPress::UnknownEscSeq)
+            }
+        } else if seq3 == ';' {
+            let seq4 = try!(self.next_char());
+            if seq4.is_digit(10) {
+                let seq5 = try!(self.next_char());
+                if seq2 == '1' {
+                    Ok(match (seq4, seq5) {
+                        ('5', 'A') => KeyPress::ControlUp,
+                        ('5', 'B') => KeyPress::ControlDown,
+                        ('5', 'C') => KeyPress::ControlRight,
+                        ('5', 'D') => KeyPress::ControlLeft,
+                        ('2', 'A') => KeyPress::ShiftUp,
+                        ('2', 'B') => KeyPress::ShiftDown,
+                        ('2', 'C') => KeyPress::ShiftRight,
+                        ('2', 'D') => KeyPress::ShiftLeft,
+                        _ => {
+                            debug!(target: "rustyline",
+                                   "unsupported esc sequence: ESC [ 1 ; {} {:?}", seq4, seq5);
+                            KeyPress::UnknownEscSeq
+                        }
+                    })
+                } else {
+                    debug!(target: "rustyline",
+                           "unsupported esc sequence: ESC [ {} ; {} {:?}", seq2, seq4, seq5);
+                    Ok(KeyPress::UnknownEscSeq)
+                }
+            } else {
+                debug!(target: "rustyline",
+                       "unsupported esc sequence: ESC [ {} ; {:?}", seq2, seq4);
+                Ok(KeyPress::UnknownEscSeq)
+            }
+        } else {
+            Ok(match (seq2, seq3) {
+                ('5', 'A') => KeyPress::ControlUp,
+                ('5', 'B') => KeyPress::ControlDown,
+                ('5', 'C') => KeyPress::ControlRight,
+                ('5', 'D') => KeyPress::ControlLeft,
+                _ => {
+                    debug!(target: "rustyline",
+                           "unsupported esc sequence: ESC [ {} {:?}", seq2, seq3);
+                    KeyPress::UnknownEscSeq
+                }
+            })
+        }
+    }
+
+    /// Handle ESC O <seq2> escape sequences
+    fn escape_o(&mut self) -> Result<KeyPress> {
+        let seq2 = try!(self.next_char());
+        Ok(match seq2 {
+            'A' => KeyPress::Up,    // kcuu1
+            'B' => KeyPress::Down,  // kcud1
+            'C' => KeyPress::Right, // kcuf1
+            'D' => KeyPress::Left,  // kcub1
+            'F' => KeyPress::End,   // kend
+            'H' => KeyPress::Home,  // khome
+            'P' => KeyPress::F(1),  // kf1
+            'Q' => KeyPress::F(2),  // kf2
+            'R' => KeyPress::F(3),  // kf3
+            'S' => KeyPress::F(4),  // kf4
+            'a' => KeyPress::ControlUp,
+            'b' => KeyPress::ControlDown,
+            'c' => KeyPress::ControlRight, // rxvt
+            'd' => KeyPress::ControlLeft,  // rxvt
+            _ => {
+                debug!(target: "rustyline", "unsupported esc sequence: ESC O {:?}", seq2);
+                KeyPress::UnknownEscSeq
+            }
+        })
+    }
 }
 
-// TODO properly set raw mode, process escape keys
+pub struct FuchsiaRenderer {
+    out: StdStream,
+    cols: usize,
+    buffer: String,
+}
+
+impl FuchsiaRenderer {
+    pub fn new(stream_type: OutputStreamType) -> FuchsiaRenderer {
+        let out = StdStream::from_stream_type(stream_type);
+        let (cols, _) = get_win_size();
+        FuchsiaRenderer {
+            out,
+            cols,
+            buffer: String::with_capacity(1024),
+        }
+    }
+}
+
+impl Renderer for FuchsiaRenderer {
+    fn move_cursor(&mut self, old: Position, new: Position) -> Result<()> {
+        use std::fmt::Write;
+        let mut ab = String::new();
+        if new.row > old.row {
+            // move down
+            let row_shift = new.row - old.row;
+            if row_shift == 1 {
+                ab.push_str("\x1b[B");
+            } else {
+                write!(ab, "\x1b[{}B", row_shift).unwrap();
+            }
+        } else if new.row < old.row {
+            // move up
+            let row_shift = old.row - new.row;
+            if row_shift == 1 {
+                ab.push_str("\x1b[A");
+            } else {
+                write!(ab, "\x1b[{}A", row_shift).unwrap();
+            }
+        }
+        if new.col > old.col {
+            // move right
+            let col_shift = new.col - old.col;
+            if col_shift == 1 {
+                ab.push_str("\x1b[C");
+            } else {
+                write!(ab, "\x1b[{}C", col_shift).unwrap();
+            }
+        } else if new.col < old.col {
+            // move left
+            let col_shift = old.col - new.col;
+            if col_shift == 1 {
+                ab.push_str("\x1b[D");
+            } else {
+                write!(ab, "\x1b[{}D", col_shift).unwrap();
+            }
+        }
+        self.write_and_flush(ab.as_bytes())
+    }
+
+    /// Display `prompt`, line and cursor in terminal output
+    fn refresh_line(
+        &mut self,
+        prompt: &str,
+        prompt_size: Position,
+        line: &LineBuffer,
+        hint: Option<String>,
+        current_row: usize,
+        old_rows: usize,
+        highlighter: Option<&Highlighter>,
+    ) -> Result<(Position, Position)> {
+        use std::fmt::Write;
+        self.buffer.clear();
+
+        // calculate the position of the end of the input line
+        let end_pos = self.calculate_position(line, prompt_size);
+        // calculate the desired position of the cursor
+        let cursor = self.calculate_position(&line[..line.pos()], prompt_size);
+
+        // self.old_rows < self.cursor.row if the prompt spans multiple lines and if
+        // this is the default State.
+        let cursor_row_movement = old_rows.checked_sub(current_row).unwrap_or(0);
+        // move the cursor down as required
+        if cursor_row_movement > 0 {
+            write!(self.buffer, "\x1b[{}B", cursor_row_movement).unwrap();
+        }
+        // clear old rows
+        for _ in 0..old_rows {
+            self.buffer.push_str("\r\x1b[0K\x1b[A");
+        }
+        // clear the line
+        self.buffer.push_str("\r\x1b[0K");
+
+        if let Some(highlighter) = highlighter {
+            // display the prompt
+            self.buffer.push_str(&highlighter.highlight_prompt(prompt));
+            // display the input line
+            self.buffer
+                .push_str(&highlighter.highlight(line, line.pos()));
+        } else {
+            // display the prompt
+            self.buffer.push_str(prompt);
+            // display the input line
+            self.buffer.push_str(line);
+        }
+        // display hint
+        if let Some(hint) = hint {
+            let truncate = truncate(&hint, end_pos.col, self.cols);
+            if let Some(highlighter) = highlighter {
+                self.buffer.push_str(&highlighter.highlight_hint(truncate));
+            } else {
+                self.buffer.push_str(truncate);
+            }
+        }
+        // we have to generate our own newline on line wrap
+        if end_pos.col == 0 && end_pos.row > 0 {
+            self.buffer.push_str("\n");
+        }
+        // position the cursor
+        let cursor_row_movement = end_pos.row - cursor.row;
+        // move the cursor up as required
+        if cursor_row_movement > 0 {
+            write!(self.buffer, "\x1b[{}A", cursor_row_movement).unwrap();
+        }
+        // position the cursor within the line
+        if cursor.col > 0 {
+            write!(self.buffer, "\r\x1b[{}C", cursor.col).unwrap();
+        } else {
+            self.buffer.push('\r');
+        }
+
+        try!(self.out.write_all(self.buffer.as_bytes()));
+        try!(self.out.flush());
+        Ok((cursor, end_pos))
+    }
+
+    /// Calculate the number of columns and rows used to display `s` on a
+    /// `cols` width terminal starting at `orig`.
+    fn calculate_position(&self, s: &str, orig: Position) -> Position {
+        let mut pos = orig;
+        let mut esc_seq = 0;
+        for c in s.graphemes(true) {
+            if c == "\n" {
+                pos.row += 1;
+                pos.col = 0;
+                continue;
+            }
+            let cw = width(c, &mut esc_seq);
+            pos.col += cw;
+            if pos.col > self.cols {
+                pos.row += 1;
+                pos.col = cw;
+            }
+        }
+        if pos.col == self.cols {
+            pos.col = 0;
+            pos.row += 1;
+        }
+        pos
+    }
+
+    fn write_and_flush(&mut self, buf: &[u8]) -> Result<()> {
+        try!(self.out.write_all(buf));
+        try!(self.out.flush());
+        Ok(())
+    }
+
+    /// Clear the screen. Used to handle ctrl+l
+    fn clear_screen(&mut self) -> Result<()> {
+        self.write_and_flush(b"\x1b[H\x1b[2J")
+    }
+
+    /// Check if a SIGWINCH signal has been received
+    fn sigwinch(&self) -> bool {
+        false
+    }
+
+    /// Update the number of columns/rows in the current terminal.
+    fn update_size(&mut self) {
+        let (cols, _) = get_win_size();
+        self.cols = cols;
+    }
+
+    /// Get the number of columns in the current terminal.
+    fn get_columns(&self) -> usize {
+        let (cols, _) = get_win_size();
+        cols
+    }
+
+    /// Get the number of rows in the current terminal.
+    fn get_rows(&self) -> usize {
+        let (_, rows) = get_win_size();
+        rows
+    }
+}
+
+
+// TODO properly set raw mode, handle escape key timeouts
 
 impl RawReader for FuchsiaRawReader {
-    fn next_key(&mut self) -> Result<KeyPress> {
+    fn next_key(&mut self, single_esc_abort: bool) -> Result<KeyPress> {
         let c = try!(self.next_char());
 
-        let mut key = consts::char_to_key_press(c);
+        let mut key = keys::char_to_key_press(c);
         if key == KeyPress::Esc {
-            // TODO
-            debug!(target: "rustyline", "ESC + {:?} currently unsupported", key);
+            return self.escape_sequence();
         }
 
         Ok(key)
     }
 
     fn next_char(&mut self) -> Result<char> {
-        match self.chars.next() {
-            Some(ch) => Ok(ch?),
-            None => Err(error::ReadlineError::Eof),
+        loop {
+            let n = try!(self.stdin.read(&mut self.buf));
+            if n == 0 {
+                return Err(error::ReadlineError::Eof);
+            }
+            let b = self.buf[0];
+            self.parser.advance(&mut self.receiver, b);
+            if !self.receiver.valid {
+                return Err(error::ReadlineError::Utf8Error);
+            } else if self.receiver.c.is_some() {
+                return Ok(self.receiver.c.take().unwrap());
+            }
         }
     }
 }
 
-impl Term for Console {
-    type Reader = FuchsiaRawReader;
-    type Writer = Stdout;
-    type Mode = Mode;
-
-    fn new() -> Console {
-        let stdin_isatty = true;
-        Console {
-            stdin_isatty: stdin_isatty,
-        }
+impl Receiver for Utf8 {
+    /// Called whenever a codepoint is parsed successfully
+    fn codepoint(&mut self, c: char) {
+        self.c = Some(c);
+        self.valid = true;
     }
 
-    /// Checking for an unsupported TERM in fuchsia is a no-op
+    /// Called when an invalid_sequence is detected
+    fn invalid_sequence(&mut self) {
+        self.c = None;
+        self.valid = false;
+    }
+}
+
+fn is_a_tty(fd: libc::c_int) -> bool {
+    unsafe { libc::isatty(fd) != 0 }
+}
+
+impl Term for FuchsiaTerminal {
+    type Reader = FuchsiaRawReader;
+    type Writer = FuchsiaRenderer;
+    type Mode = Mode;
+
+    fn new(color_mode: ColorMode, stream_type: OutputStreamType) -> FuchsiaTerminal {
+        FuchsiaTerminal {
+            unsupported: false,
+            stdin_isatty: is_a_tty(STDIN_FILENO as i32),
+            stdstream_isatty: is_a_tty(if stream_type == OutputStreamType::Stdout {
+                STDOUT_FILENO as i32
+            } else {
+                STDERR_FILENO as i32
+            }),
+            color_mode,
+            stream_type,
+        }
+    }
+    /// Check if current terminal can provide a rich line-editing user
+    /// interface.
     fn is_unsupported(&self) -> bool {
         false
     }
-
+    /// check if stdin is connected to a terminal.
     fn is_stdin_tty(&self) -> bool {
         self.stdin_isatty
     }
-
-    /// Try to get the number of columns in the current terminal,
-    /// or assume 80 if it fails.
-    fn get_columns(&self) -> usize {
-        let (cols, _) = get_win_size();
-        cols
+    /// Check if output supports colors.
+    fn colors_enabled(&self) -> bool {
+        true
     }
-
-    /// Try to get the number of rows in the current terminal,
-    /// or assume 24 if it fails.
-    fn get_rows(&self) -> usize {
-        let (_, rows) = get_win_size();
-        rows
-    }
-
-    /// Enable RAW mode for the terminal. No termios support, so this fakes it
-    fn enable_raw_mode(&self) -> Result<Mode> {
+    /// Enable RAW mode for the terminal.
+    fn enable_raw_mode(&mut self) -> Result<Self::Mode> {
         Ok(Mode {})
     }
-
-    fn create_reader(&self, _: &Config) -> Result<FuchsiaRawReader> {
-        FuchsiaRawReader::new()
+    /// Create a RAW reader
+    fn create_reader(&self, config: &Config) -> Result<Self::Reader> {
+        FuchsiaRawReader::new(config)
     }
-
-    fn create_writer(&self) -> Stdout {
-        io::stdout()
-    }
-
-    fn sigwinch(&self) -> bool {
-        false
-    }
-
-    /// Clear the screen. Used to handle ctrl+l
-    fn clear_screen(&mut self, w: &mut Write) -> Result<()> {
-        try!(w.write_all(b"\x1b[H\x1b[2J"));
-        try!(w.flush());
-        Ok(())
+    /// Create a writer
+    fn create_writer(&self) -> Self::Writer {
+        FuchsiaRenderer::new(self.stream_type)
     }
 }
