diff --git a/.travis.yml b/.travis.yml
index af46809..711713e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,16 +1,5 @@
+sudo: false
 language: rust
-rust:
-  - stable
-  - beta
-  - nightly
 script:
   - cargo build --verbose
   - cargo test --verbose
-  - cargo doc
-after_success: |
-  [ $TRAVIS_BRANCH = master ] &&
-  [ $TRAVIS_PULL_REQUEST = false ] &&
-  bash deploy-docs.sh
-env:
-  global:
-    secure: "XxaPXHiVplTwMaAytYC0VQR/nNnm7SJVzXiUuaVEjssHip0Uje/4f3vGqtJjnD70FfxwNWQKiSYOcbYjWPlsJeANRt4ZoCsRt5eLGUZ+wH79n1fOkp5EIpFT/isjCB51A4n8PRUvuWfQ2OtNNeGLL6akMxt19sHdXoiQkLOe338="
diff --git a/BUILD.gn b/BUILD.gn
index 8663ce4..824e6d2 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1,24 +1,25 @@
 # Copyright 2018 The Fuchsia Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
-
+ 
 # This file is currently a stopgap for building on Fuchsia
 # contact bwb@google.com if you are running into problems with
 # how it is mirrored
-
+ 
 import("//build/rust/rustc_library.gni")
-
+ 
 rustc_library("rustyline") {
   name = "rustyline"
   edition = "2015"
   deps = [
     "//garnet/public/rust/fuchsia-device",
     "//garnet/public/rust/fuchsia-zircon",
-
+ 
     "//third_party/rust-crates/rustc_deps:log",
     "//third_party/rust-crates/rustc_deps:libc",
+    "//third_party/rust-crates/rustc_deps:memchr",
     "//third_party/rust-crates/rustc_deps:unicode-segmentation",
     "//third_party/rust-crates/rustc_deps:unicode-width",
-    "//third_party/rust-crates/rustc_deps:encode_unicode",
+    "//third_party/rust-crates/rustc_deps:utf8parse",
   ]
 }
diff --git a/Cargo.toml b/Cargo.toml
index c35c55d..43a3648 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "rustyline"
-version = "1.0.0"
+version = "2.1.0"
 authors = ["Katsu Kawakami <kkawa1570@gmail.com>"]
 description = "Rustyline, a readline implementation based on Antirez's Linenoise"
 documentation = "http://docs.rs/rustyline"
@@ -13,25 +13,30 @@
 [badges]
 travis-ci = { repository = "kkawakam/rustyline" }
 appveyor = { repository = "kkawakam/rustyline" }
+maintenance = { status = "actively-developed" }
 
 
 [dependencies]
-libc = "0.2.7"
-log = "0.3"
-unicode-width = "0.1.3"
+libc = "0.2"
+log = "0.4"
+unicode-width = "0.1"
 unicode-segmentation = "1.0"
-encode_unicode = "0.1.3"
+memchr = "2.0"
+
+[target.'cfg(unix)'.dependencies]
+utf8parse = "0.1"
 
 [target.'cfg(all(unix, not(any(target_os = "fuchsia"))))'.dependencies]
-nix = "0.8"
+dirs = "1.0"
+nix = "0.11"
 
 [target.'cfg(target_os = "fuchsia")'.dependencies]
 fuchsia-zircon = "0.3.2"
 fuchsia-device = "0.1.0"
 
 [target.'cfg(windows)'.dependencies]
-winapi = "0.2"
-kernel32-sys = "0.2"
+winapi = { version = "0.3", features = ["consoleapi", "handleapi", "minwindef", "processenv", "winbase", "wincon", "winuser"] }
 
 [dev-dependencies]
-tempdir = "0.3.4"
+tempdir = "0.3"
+assert_matches = "1.2"
diff --git a/README.md b/README.md
index f031d1b..ea66ccc 100644
--- a/README.md
+++ b/README.md
@@ -1,28 +1,21 @@
 # RustyLine
 [![Build Status](https://travis-ci.org/kkawakam/rustyline.svg?branch=master)](https://travis-ci.org/kkawakam/rustyline)
-[![Build status](https://ci.appveyor.com/api/projects/status/ls7sty8nt25rdfkq/branch/master?svg=true)](https://ci.appveyor.com/project/kkawakam/rustyline/branch/master)
-[![Clippy Linting Result](https://clippy.bashy.io/github/kkawakam/rustyline/master/badge.svg)](https://clippy.bashy.io/github/kkawakam/rustyline/master/log)
+[![Build Status](https://ci.appveyor.com/api/projects/status/github/kkawakam/rustyline?branch=master&svg=true)](https://ci.appveyor.com/project/kkawakam/rustyline/branch/master)
+[![dependency status](https://deps.rs/repo/github/kkawakam/rustyline/status.svg)](https://deps.rs/repo/github/kkawakam/rustyline)
 [![](http://meritbadge.herokuapp.com/rustyline)](https://crates.io/crates/rustyline)
+[![Docs](https://docs.rs/rustyline/badge.svg)](https://docs.rs/rustyline)
 
 Readline implementation in Rust that is based on [Antirez' Linenoise](https://github.com/antirez/linenoise)
 
-[Documentation (Releases)](https://docs.rs/rustyline)
-
-[Documentation (Master)](https://kkawakam.github.io/rustyline/rustyline/)
-
 **Supported Platforms**
-* Linux
+* Unix (tested on FreeBSD, Linux and macOS)
 * Windows
    * cmd.exe
    * Powershell
 
-**Note**: Powershell ISE is not supported, check [issue #56](https://github.com/kkawakam/rustyline/issues/56)
-
-## Build
-This project uses Cargo and Rust stable
-```bash
-cargo build --release
-```
+**Note**:
+* Powershell ISE is not supported, check [issue #56](https://github.com/kkawakam/rustyline/issues/56)
+* Mintty (Cygwin/Mingw) is not supported
 
 ## Example
 ```rust
@@ -34,14 +27,14 @@
 fn main() {
     // `()` can be used when no completer is required
     let mut rl = Editor::<()>::new();
-    if let Err(_) = rl.load_history("history.txt") {
+    if rl.load_history("history.txt").is_err() {
         println!("No previous history.");
     }
     loop {
         let readline = rl.readline(">> ");
         match readline {
             Ok(line) => {
-                rl.add_history_entry(&line);
+                rl.add_history_entry(line.as_ref());
                 println!("Line: {}", line);
             },
             Err(ReadlineError::Interrupted) => {
@@ -68,7 +61,7 @@
 
 ```toml
 [dependencies]
-rustyline = "1.0.0"
+rustyline = "2.1.0"
 ```
 
 ## Features
@@ -76,10 +69,11 @@
  - Unicode (UTF-8) (linenoise supports only ASCII)
  - Word completion (linenoise supports only line completion)
  - Filename completion
- - History search ([Searching for Commands in the History](http://cnswww.cns.cwru.edu/php/chet/readline/readline.html#SEC8))
- - Kill ring ([Killing Commands](http://cnswww.cns.cwru.edu/php/chet/readline/readline.html#IDX3))
- - Multi line mode
+ - History search ([Searching for Commands in the History](http://tiswww.case.edu/php/chet/readline/readline.html#SEC8))
+ - Kill ring ([Killing Commands](http://tiswww.case.edu/php/chet/readline/readline.html#IDX3))
+ - Multi line mode (line wrapping)
  - Word commands
+ - Hints
 
 ## Actions
 
@@ -102,6 +96,7 @@
 Ctrl-W       | Delete word leading up to cursor (using white space as a word boundary)
 Ctrl-Y       | Paste from Yank buffer
 Ctrl-Z       | Suspend (unix only)
+Ctrl-_       | Undo
 
 ### Emacs mode (default mode)
 
@@ -117,6 +112,7 @@
 Ctrl-L       | Clear screen
 Ctrl-N, Down | Next match from history
 Ctrl-P, Up   | Previous match from history
+Ctrl-X Ctrl-U | Undo
 Ctrl-Y       | Paste from Yank buffer (Meta-Y to paste next yank instead)
 Meta-<       | Move to first entry in history
 Meta->       | Move to last entry in history
@@ -169,6 +165,7 @@
 S            | Change current line (equivalent to 0c$)
 t<char>      | Move right to the next occurance of `char`, then one char backward
 T<char>      | Move left to the previous occurance of `char`, then one char forward
+u            | Undo
 w            | Move one word or token right
 W            | Move one non-blank word right
 x            | Delete a single character under the cursor
@@ -187,12 +184,6 @@
 
 [Terminal codes (ANSI/VT100)](http://wiki.bash-hackers.org/scripting/terminalcodes)
 
-## ToDo
-
- - Undos
- - Read input with timeout to properly handle single ESC key
- - expose an API callable from C
-
 ## Wine
 
 ```sh
@@ -214,10 +205,26 @@
 
 ## Similar projects
 
- - [copperline](https://github.com/srijs/rust-copperline) (Rust)
- - [linefeed](https://github.com/murarth/linefeed) (Rust)
- - [liner](https://github.com/MovingtoMars/liner) (Rust)
- - [linenoise-ng](https://github.com/arangodb/linenoise-ng) (C++)
- - [liner](https://github.com/peterh/liner) (Go)
- - [readline](https://github.com/chzyer/readline) (Go)
- - [haskeline](https://github.com/judah/haskeline) (Haskell)
+Library            | Lang    | OS     | Term  | Unicode | History       | Completion | Keymap        | Kill Ring | Undo | Colors     | Hint/Auto suggest |
+--------           | ----    | --     | ----  | ------- | -------       | ---------- | -------       | --------- | ---- | ------     | ----------------- |
+[Go-prompt][]      | Go      | Ux/win | ANSI  | Yes     | Yes           | any        | Emacs/prog    | No        | No   | Yes   | Yes               |
+[Haskeline][]      | Haskell | Ux/Win | Any   | Yes     | Yes           | any        | Emacs/Vi/conf | Yes       | Yes  | ?          | ?                 |
+[Linenoise][]      | C       | Ux     | ANSI  | No      | Yes           | only line  | Emacs         | No        | No   | Ux         | Yes               |
+[Linenoise-ng][]   | C       | Ux/Win | ANSI  | Yes     | Yes           | only line  | Emacs         | Yes       | No   | ?          | ?                 |
+[Linefeed][]       | Rust    | Ux/Win | Any   |         | Yes           | any        | Emacs/conf    | Yes       | No   | ?          | No                |
+[Liner][]          | Rust    | Ux     | ANSI  |         | No inc search | only word  | Emacs/Vi/prog | No        | Yes  | Ux         | History based     |
+[Prompt-toolkit][] | Python  | Ux/Win | ANSI  | Yes     | Yes           | any        | Emacs/Vi/conf | Yes       | Yes  | Ux/Win     | Yes               |
+[Rb-readline][]    | Ruby    | Ux/Win | ANSI  | Yes     | Yes           | only word  | Emacs/Vi/conf | Yes       | Yes  | ?          | No                |
+[Replxx][]         | C/C++   | Ux/Win | ANSI  | Yes     | Yes           | only line  | Emacs         | Yes       | No   | Ux/Win     | Yes               |
+Rustyline          | Rust    | Ux/Win | ANSI  | Yes     | Yes           | any        | Emacs/Vi/bind | Yes       | Yes  | Ux/Win 10+ | Yes               |
+
+[Go-prompt]: https://github.com/c-bata/go-prompt
+[Haskeline]: https://github.com/judah/haskeline
+[Linefeed]: https://github.com/murarth/linefeed
+[Linenoise]: https://github.com/antirez/linenoise
+[Linenoise-ng]: https://github.com/arangodb/linenoise-ng
+[Liner]: https://github.com/redox-os/liner
+[Prompt-toolkit]: https://github.com/jonathanslenders/python-prompt-toolkit
+[Rb-readline]: https://github.com/ConnorAtherton/rb-readline
+[Replxx]: https://github.com/AmokHuginnsson/replxx
+
diff --git a/TODO.md b/TODO.md
new file mode 100644
index 0000000..7037243
--- /dev/null
+++ b/TODO.md
@@ -0,0 +1,88 @@
+API
+- [ ] expose an API callable from C
+
+Async (#126)
+
+Bell
+- [ ] bell-style
+
+Color
+- [X] ANSI Colors & Windows 10+
+- [ ] ANSI Colors & Windows <10 (https://docs.rs/console/0.6.1/console/fn.strip_ansi_codes.html ? https://github.com/mattn/go-colorable/blob/master/colorable_windows.go)
+- [ ] Syntax highlighting (https://github.com/trishume/syntect/)
+- [ ] clicolors spec (https://docs.rs/console/0.6.1/console/fn.colors_enabled.html)
+
+Completion
+- [X] Quoted path
+- [ ] Windows escape/unescape space in path
+- [ ] file completion & escape/unescape (#106)
+- [ ] file completion & tilde (#62)
+- [X] display versus replacement
+- [ ] composite/alternate completer (if the current completer returns nothing, try the next one)
+
+Config
+- [ ] Maximum buffer size for the line read
+
+Cursor
+- [ ] insert versus overwrite versus command mode
+- [ ] In Vi command mode, prevent user from going to end of line. (#94)
+
+Grapheme
+- [ ] grapheme & input auto-wrap are buggy
+
+Hints Callback
+- [X] Not implemented on windows
+- [ ] Do an implementation based on previous history
+
+History
+- [ ] Move to the history line n
+- [ ] historyFile: Where to read/write the history at the start and end of
+each line input session.
+- [ ] append_history
+- [ ] history_truncate_file
+
+Input
+- [ ] Password input (#58)
+- [X] quoted insert (#65)
+- [ ] quoted TAB (`\t`) insert and width
+- [ ] Overwrite mode (em-toggle-overwrite, vi-replace-mode, rl_insert_mode)
+- [ ] Encoding
+- [ ] [Ctrl-][Alt-][Shift-]<Key> (#121)
+
+Layout
+- [ ] Redraw perf (https://crates.io/crates/cassowary)
+
+Mouse
+- [ ] Mouse support
+
+Movement
+- [ ] Move to the corresponding opening/closing bracket
+
+Redo
+- [X] redo substitute
+
+Repeat
+- [X] dynamic prompt (arg: ?)
+- [ ] transpose chars
+
+Syntax
+- [ ] syntax specific tokenizer/parser
+- [ ] highlighting
+
+Undo
+- [ ] Merge consecutive Replace
+- [X] Undo group
+- [ ] Undo all changes made to this line.
+- [X] Kill+Insert (substitute/replace)
+- [X] Repeated undo `Undo(RepeatCount)`
+
+Unix
+- [ ] Terminfo (https://github.com/Stebalien/term)
+- [ ] [ncurses](https://crates.io/crates/ncurses) alternative backend ?
+- [ ] [bracketed paste mode](https://cirw.in/blog/bracketed-paste)
+- [ ] async stdin (https://github.com/Rufflewind/tokio-file-unix)
+
+Windows
+- [ ] is_atty is not working with cygwin/msys (https://github.com/softprops/atty works but then how to make `enable_raw_mode` works ?)
+- [X] UTF-16 surrogate pair
+- [ ] handle ansi escape code (https://docs.rs/console/0.6.1/console/fn.strip_ansi_codes.html ? https://github.com/mattn/go-colorable/blob/master/colorable_windows.go)
diff --git a/appveyor.yml b/appveyor.yml
index 8934d30..4506f3a 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,14 +1,9 @@
 environment:
-  matrix:
-  - TARGET: 1.16.0-x86_64-pc-windows-msvc
-  - TARGET: 1.16.0-x86_64-pc-windows-gnu
-  - TARGET: beta-x86_64-pc-windows-msvc
-  - TARGET: beta-x86_64-pc-windows-gnu
+  TARGET: x86_64-pc-windows-msvc
 install:
-  - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-${env:TARGET}.exe"
-  - rust-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
-  - SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin
-  - SET PATH=%PATH%;C:\MinGW\bin
+  - appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
+  - rustup-init -yv --default-toolchain stable --default-host %TARGET%
+  - set PATH=%PATH%;%USERPROFILE%\.cargo\bin
   - rustc -V
   - cargo -V
 
diff --git a/deploy-docs.sh b/deploy-docs.sh
deleted file mode 100755
index efd5a56..0000000
--- a/deploy-docs.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-
-rev=$(git rev-parse --short HEAD)
-
-cd target/doc
-
-echo '<meta http-equiv=refresh content=0;url=rustyline/index.html>' > index.html
-
-git init
-git config user.name "Katsu Kawakami"
-git config user.email "kkawa1570@gmail.com"
-
-git remote add upstream "https://$GH_TOKEN@github.com/kkawakam/rustyline.git"
-git fetch upstream
-git push upstream --delete gh-pages > /dev/null 2>&1
-
-touch .
-
-git add -A .
-git commit -m "rebuild pages at ${rev}"
-git push -q upstream HEAD:gh-pages > /dev/null 2>&1
diff --git a/examples/example.rs b/examples/example.rs
index 8f02337..497bc34 100644
--- a/examples/example.rs
+++ b/examples/example.rs
@@ -1,32 +1,67 @@
 extern crate log;
 extern crate rustyline;
 
-use std::io::{self, Write};
-use log::{LogRecord, LogLevel, LogLevelFilter, LogMetadata, SetLoggerError};
+use log::{Level, LevelFilter, Metadata, Record, SetLoggerError};
+use std::borrow::Cow::{self, Borrowed, Owned};
 
-use rustyline::completion::FilenameCompleter;
+use rustyline::completion::{Completer, FilenameCompleter, Pair};
+use rustyline::config::OutputStreamType;
 use rustyline::error::ReadlineError;
-use rustyline::{Cmd, Config, CompletionType, Editor, EditMode, KeyPress};
+use rustyline::highlight::Highlighter;
+use rustyline::hint::Hinter;
+use rustyline::{Cmd, CompletionType, Config, EditMode, Editor, Helper, KeyPress};
 
-// On unix platforms you can use ANSI escape sequences
-#[cfg(unix)]
-static PROMPT: &'static str = "\x1b[1;32m>>\x1b[0m ";
+static COLORED_PROMPT: &'static str = "\x1b[1;32m>>\x1b[0m ";
 
-// Windows consoles typically don't support ANSI escape sequences out
-// of the box
-#[cfg(windows)]
 static PROMPT: &'static str = ">> ";
 
+struct MyHelper(FilenameCompleter);
+
+impl Completer for MyHelper {
+    type Candidate = Pair;
+
+    fn complete(&self, line: &str, pos: usize) -> Result<(usize, Vec<Pair>), ReadlineError> {
+        self.0.complete(line, pos)
+    }
+}
+
+impl Hinter for MyHelper {
+    fn hint(&self, line: &str, _pos: usize) -> Option<String> {
+        if line == "hello" {
+            Some(" World".to_owned())
+        } else {
+            None
+        }
+    }
+}
+
+impl Highlighter for MyHelper {
+    fn highlight_prompt<'p>(&self, prompt: &'p str) -> Cow<'p, str> {
+        if prompt == PROMPT {
+            Borrowed(COLORED_PROMPT)
+        } else {
+            Borrowed(prompt)
+        }
+    }
+
+    fn highlight_hint<'h>(&self, hint: &'h str) -> Cow<'h, str> {
+        Owned("\x1b[1m".to_owned() + hint + "\x1b[m")
+    }
+}
+
+impl Helper for MyHelper {}
+
 fn main() {
     init_logger().is_ok();
     let config = Config::builder()
         .history_ignore_space(true)
         .completion_type(CompletionType::List)
         .edit_mode(EditMode::Emacs)
+        .output_stream(OutputStreamType::Stdout)
         .build();
-    let c = FilenameCompleter::new();
+    let h = MyHelper(FilenameCompleter::new());
     let mut rl = Editor::with_config(config);
-    rl.set_completer(Some(c));
+    rl.set_helper(Some(h));
     rl.bind_sequence(KeyPress::Meta('N'), Cmd::HistorySearchForward);
     rl.bind_sequence(KeyPress::Meta('P'), Cmd::HistorySearchBackward);
     if rl.load_history("history.txt").is_err() {
@@ -56,23 +91,25 @@
     rl.save_history("history.txt").unwrap();
 }
 
+static LOGGER: Logger = Logger;
 struct Logger;
 
 impl log::Log for Logger {
-    fn enabled(&self, metadata: &LogMetadata) -> bool {
-        metadata.level() <= LogLevel::Debug
+    fn enabled(&self, metadata: &Metadata) -> bool {
+        metadata.level() <= Level::Debug
     }
 
-    fn log(&self, record: &LogRecord) {
+    fn log(&self, record: &Record) {
         if self.enabled(record.metadata()) {
-            writeln!(io::stderr(), "{} - {}", record.level(), record.args()).unwrap();
+            eprintln!("{} - {}", record.level(), record.args());
         }
     }
+
+    fn flush(&self) {}
 }
 
 fn init_logger() -> Result<(), SetLoggerError> {
-    log::set_logger(|max_log_level| {
-                        max_log_level.set(LogLevelFilter::Info);
-                        Box::new(Logger)
-                    })
+    try!(log::set_logger(&LOGGER));
+    log::set_max_level(LevelFilter::Info);
+    Ok(())
 }
diff --git a/index.html b/index.html
deleted file mode 100644
index 269d4c6..0000000
--- a/index.html
+++ /dev/null
@@ -1 +0,0 @@
-<meta http-equiv=refresh content=0;url=rustyline/index.html>
diff --git a/rustfmt.toml b/rustfmt.toml
index 6496add..83697e3 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -1,3 +1,4 @@
-reorder_imports = false
-normalise_comments = false
-write_mode = "Overwrite"
\ No newline at end of file
+wrap_comments = true
+format_strings = true
+error_on_unformatted = false
+reorder_impl_items = true
diff --git a/src/char_iter.rs b/src/char_iter.rs
deleted file mode 100644
index 1866dbd..0000000
--- a/src/char_iter.rs
+++ /dev/null
@@ -1,111 +0,0 @@
-//! An iterator over the `char`s of a reader.
-//!
-//! A copy of the unstable code from the stdlib's std::io::Read::chars.
-//! TODO: Remove this once [Read::chars](https://github.com/rust-lang/rust/issues/27802) has been stabilized
-
-use std::error;
-use std::fmt;
-use std::io;
-use std::io::Read;
-use std::str;
-
-pub fn chars<R: Read>(read: R) -> Chars<R>
-    where R: Sized
-{
-    Chars { inner: read }
-}
-
-// https://tools.ietf.org/html/rfc3629
-static UTF8_CHAR_WIDTH: [u8; 256] = [
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1F
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x3F
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x5F
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x7F
-    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x9F
-    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xBF
-    0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xDF
-    3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 0xEF
-    4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0, // 0xFF
-];
-
-/// Given a first byte, determine how many bytes are in this UTF-8 character
-#[inline]
-fn utf8_char_width(b: u8) -> usize {
-    return UTF8_CHAR_WIDTH[b as usize] as usize;
-}
-
-pub struct Chars<R> {
-    inner: R,
-}
-
-#[derive(Debug)]
-pub enum CharsError {
-    NotUtf8,
-    Other(io::Error),
-}
-
-impl<R: Read> Iterator for Chars<R> {
-    type Item = Result<char, CharsError>;
-
-    fn next(&mut self) -> Option<Result<char, CharsError>> {
-        let mut buf = [0];
-        let first_byte = match self.inner.read(&mut buf) {
-            Ok(0) => return None,
-            Ok(..) => buf[0],
-            Err(e) => return Some(Err(CharsError::Other(e))),
-        };
-        let width = utf8_char_width(first_byte);
-        if width == 1 {
-            return Some(Ok(first_byte as char));
-        }
-        if width == 0 {
-            return Some(Err(CharsError::NotUtf8));
-        }
-        let mut buf = [first_byte, 0, 0, 0];
-        {
-            let mut start = 1;
-            while start < width {
-                match self.inner.read(&mut buf[start..width]) {
-                    Ok(0) => return Some(Err(CharsError::NotUtf8)),
-                    Ok(n) => start += n,
-                    Err(e) => return Some(Err(CharsError::Other(e))),
-                }
-            }
-        }
-        Some(match str::from_utf8(&buf[..width]).ok() {
-                 Some(s) => Ok(s.chars().next().unwrap()),
-                 None => Err(CharsError::NotUtf8),
-             })
-    }
-}
-
-impl error::Error for CharsError {
-    fn description(&self) -> &str {
-        match *self {
-            CharsError::NotUtf8 => "invalid utf8 encoding",
-            CharsError::Other(ref e) => error::Error::description(e),
-        }
-    }
-    fn cause(&self) -> Option<&error::Error> {
-        match *self {
-            CharsError::NotUtf8 => None,
-            CharsError::Other(ref e) => e.cause(),
-        }
-    }
-}
-
-impl fmt::Display for CharsError {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            CharsError::NotUtf8 => "byte stream did not contain valid utf8".fmt(f),
-            CharsError::Other(ref e) => e.fmt(f),
-        }
-    }
-}
diff --git a/src/completion.rs b/src/completion.rs
index 9c07c4d..b71e762 100644
--- a/src/completion.rs
+++ b/src/completion.rs
@@ -1,22 +1,60 @@
 //! Completion API
 use std::borrow::Cow::{self, Borrowed, Owned};
-use std::collections::BTreeSet;
 use std::fs;
 use std::path::{self, Path};
 
 use super::Result;
 use line_buffer::LineBuffer;
+use memchr::memchr;
 
 // TODO: let the implementers choose/find word boudaries ???
-// (line, pos) is like (rl_line_buffer, rl_point) to make contextual completion ("select t.na| from tbl as t")
-// TOOD: make &self &mut self ???
+// (line, pos) is like (rl_line_buffer, rl_point) to make contextual completion
+// ("select t.na| from tbl as t")
+// TODO: make &self &mut self ???
+
+/// A completion candidate.
+pub trait Candidate {
+    /// Text to display when listing alternatives.
+    fn display(&self) -> &str;
+    /// Text to insert in line.
+    fn replacement(&self) -> &str;
+}
+
+impl Candidate for String {
+    fn display(&self) -> &str {
+        self.as_str()
+    }
+
+    fn replacement(&self) -> &str {
+        self.as_str()
+    }
+}
+
+pub struct Pair {
+    pub display: String,
+    pub replacement: String,
+}
+
+impl Candidate for Pair {
+    fn display(&self) -> &str {
+        self.display.as_str()
+    }
+
+    fn replacement(&self) -> &str {
+        self.replacement.as_str()
+    }
+}
 
 /// To be called for tab-completion.
 pub trait Completer {
+    type Candidate: Candidate;
+
     /// Takes the currently edited `line` with the cursor `pos`ition and
-    /// returns the start position and the completion candidates for the partial word to be completed.
-    /// "ls /usr/loc" => Ok((3, vec!["/usr/local/"]))
-    fn complete(&self, line: &str, pos: usize) -> Result<(usize, Vec<String>)>;
+    /// returns the start position and the completion candidates for the
+    /// partial word to be completed.
+    ///
+    /// ("ls /usr/loc", 11) => Ok((3, vec!["/usr/local/"]))
+    fn complete(&self, line: &str, pos: usize) -> Result<(usize, Vec<Self::Candidate>)>;
     /// Updates the edited `line` with the `elected` candidate.
     fn update(&self, line: &mut LineBuffer, start: usize, elected: &str) {
         let end = line.pos();
@@ -25,18 +63,24 @@
 }
 
 impl Completer for () {
+    type Candidate = String;
+
     fn complete(&self, _line: &str, _pos: usize) -> Result<(usize, Vec<String>)> {
-        Ok((0, Vec::new()))
+        Ok((0, Vec::with_capacity(0)))
     }
+
     fn update(&self, _line: &mut LineBuffer, _start: usize, _elected: &str) {
         unreachable!()
     }
 }
 
 impl<'c, C: ?Sized + Completer> Completer for &'c C {
-    fn complete(&self, line: &str, pos: usize) -> Result<(usize, Vec<String>)> {
+    type Candidate = C::Candidate;
+
+    fn complete(&self, line: &str, pos: usize) -> Result<(usize, Vec<Self::Candidate>)> {
         (**self).complete(line, pos)
     }
+
     fn update(&self, line: &mut LineBuffer, start: usize, elected: &str) {
         (**self).update(line, start, elected)
     }
@@ -45,7 +89,9 @@
     ($($id: ident)*) => {
         $(
             impl<C: ?Sized + Completer> Completer for $id<C> {
-                fn complete(&self, line: &str, pos: usize) -> Result<(usize, Vec<String>)> {
+                type Candidate = C::Candidate;
+
+                fn complete(&self, line: &str, pos: usize) -> Result<(usize, Vec<Self::Candidate>)> {
                     (**self).complete(line, pos)
                 }
                 fn update(&self, line: &mut LineBuffer, start: usize, elected: &str) {
@@ -62,24 +108,49 @@
 
 /// A `Completer` for file and folder names.
 pub struct FilenameCompleter {
-    break_chars: BTreeSet<char>,
+    break_chars: &'static [u8],
+    double_quotes_special_chars: &'static [u8],
 }
 
+static DOUBLE_QUOTES_ESCAPE_CHAR: Option<char> = Some('\\');
+
+// rl_basic_word_break_characters, rl_completer_word_break_characters
 #[cfg(unix)]
-static DEFAULT_BREAK_CHARS: [char; 18] = [' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$', '>',
-                                          '<', '=', ';', '|', '&', '{', '(', '\0'];
+static DEFAULT_BREAK_CHARS: [u8; 18] = [
+    b' ', b'\t', b'\n', b'"', b'\\', b'\'', b'`', b'@', b'$', b'>', b'<', b'=', b';', b'|', b'&',
+    b'{', b'(', b'\0',
+];
 #[cfg(unix)]
 static ESCAPE_CHAR: Option<char> = Some('\\');
 // Remove \ to make file completion works on windows
 #[cfg(windows)]
-static DEFAULT_BREAK_CHARS: [char; 17] = [' ', '\t', '\n', '"', '\'', '`', '@', '$', '>', '<',
-                                          '=', ';', '|', '&', '{', '(', '\0'];
+static DEFAULT_BREAK_CHARS: [u8; 17] = [
+    b' ', b'\t', b'\n', b'"', b'\'', b'`', b'@', b'$', b'>', b'<', b'=', b';', b'|', b'&', b'{',
+    b'(', b'\0',
+];
 #[cfg(windows)]
 static ESCAPE_CHAR: Option<char> = None;
 
+// In double quotes, not all break_chars need to be escaped
+// https://www.gnu.org/software/bash/manual/html_node/Double-Quotes.html
+#[cfg(unix)]
+static DOUBLE_QUOTES_SPECIAL_CHARS: [u8; 4] = [b'"', b'$', b'\\', b'`'];
+#[cfg(windows)]
+static DOUBLE_QUOTES_SPECIAL_CHARS: [u8; 1] = [b'"']; // TODO Validate: only '"' ?
+
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub enum Quote {
+    Double,
+    Single,
+    None,
+}
+
 impl FilenameCompleter {
     pub fn new() -> FilenameCompleter {
-        FilenameCompleter { break_chars: DEFAULT_BREAK_CHARS.iter().cloned().collect() }
+        FilenameCompleter {
+            break_chars: &DEFAULT_BREAK_CHARS,
+            double_quotes_special_chars: &DOUBLE_QUOTES_SPECIAL_CHARS,
+        }
     }
 }
 
@@ -90,10 +161,35 @@
 }
 
 impl Completer for FilenameCompleter {
-    fn complete(&self, line: &str, pos: usize) -> Result<(usize, Vec<String>)> {
-        let (start, path) = extract_word(line, pos, ESCAPE_CHAR, &self.break_chars);
-        let path = unescape(path, ESCAPE_CHAR);
-        let matches = try!(filename_complete(&path, ESCAPE_CHAR, &self.break_chars));
+    type Candidate = Pair;
+
+    fn complete(&self, line: &str, pos: usize) -> Result<(usize, Vec<Pair>)> {
+        let (start, path, esc_char, break_chars, quote) =
+            if let Some((idx, quote)) = find_unclosed_quote(&line[..pos]) {
+                let start = idx + 1;
+                if quote == Quote::Double {
+                    (
+                        start,
+                        unescape(&line[start..pos], DOUBLE_QUOTES_ESCAPE_CHAR),
+                        DOUBLE_QUOTES_ESCAPE_CHAR,
+                        &self.double_quotes_special_chars,
+                        quote,
+                    )
+                } else {
+                    (
+                        start,
+                        Borrowed(&line[start..pos]),
+                        None,
+                        &self.break_chars,
+                        quote,
+                    )
+                }
+            } else {
+                let (start, path) = extract_word(line, pos, ESCAPE_CHAR, &self.break_chars);
+                let path = unescape(path, ESCAPE_CHAR);
+                (start, path, ESCAPE_CHAR, &self.break_chars, Quote::None)
+            };
+        let matches = try!(filename_complete(&path, esc_char, break_chars, quote));
         Ok((start, matches))
     }
 }
@@ -104,15 +200,20 @@
         return Borrowed(input);
     }
     let esc_char = esc_char.unwrap();
-    let n = input.chars().filter(|&c| c == esc_char).count();
-    if n == 0 {
+    if !input.chars().any(|c| c == esc_char) {
         return Borrowed(input);
     }
-    let mut result = String::with_capacity(input.len() - n);
+    let mut result = String::with_capacity(input.len());
     let mut chars = input.chars();
     while let Some(ch) = chars.next() {
         if ch == esc_char {
             if let Some(ch) = chars.next() {
+                if cfg!(windows) && ch != '"' {
+                    // TODO Validate: only '"' ?
+                    result.push(esc_char);
+                }
+                result.push(ch);
+            } else if cfg!(windows) {
                 result.push(ch);
             }
         } else {
@@ -124,23 +225,35 @@
 
 /// Escape any `break_chars` in `input` string with `esc_char`.
 /// For example, '/User Information' becomes '/User\ Information'
-/// when space is a breaking char and '\' the escape char.
-pub fn escape(input: String, esc_char: Option<char>, break_chars: &BTreeSet<char>) -> String {
+/// when space is a breaking char and '\\' the escape char.
+pub fn escape(
+    mut input: String,
+    esc_char: Option<char>,
+    break_chars: &[u8],
+    quote: Quote,
+) -> String {
+    if quote == Quote::Single {
+        return input; // no escape in single quotes
+    }
+    let n = input
+        .bytes()
+        .filter(|b| memchr(*b, break_chars).is_some())
+        .count();
+    if n == 0 {
+        return input; // no need to escape
+    }
     if esc_char.is_none() {
+        if cfg!(windows) && quote == Quote::None {
+            input.insert(0, '"'); // force double quote
+            return input;
+        }
         return input;
     }
     let esc_char = esc_char.unwrap();
-    let n = input
-        .chars()
-        .filter(|c| break_chars.contains(c))
-        .count();
-    if n == 0 {
-        return input;
-    }
     let mut result = String::with_capacity(input.len() + n);
 
     for c in input.chars() {
-        if break_chars.contains(&c) {
+        if c.is_ascii() && memchr(c as u8, break_chars).is_some() {
             result.push(esc_char);
         }
         result.push(c);
@@ -148,11 +261,15 @@
     result
 }
 
-fn filename_complete(path: &str,
-                     esc_char: Option<char>,
-                     break_chars: &BTreeSet<char>)
-                     -> Result<Vec<String>> {
-    use std::env::{current_dir, home_dir};
+fn filename_complete(
+    path: &str,
+    esc_char: Option<char>,
+    break_chars: &[u8],
+    quote: Quote,
+) -> Result<Vec<Pair>> {
+    #[cfg(all(unix, not(any(target_os = "fuchsia"))))]
+    use dirs::home_dir;
+    use std::env::current_dir;
 
     let sep = path::MAIN_SEPARATOR;
     let (dir_name, file_name) = match path.rfind(sep) {
@@ -161,37 +278,68 @@
     };
 
     let dir_path = Path::new(dir_name);
-    let dir = if dir_path.starts_with("~") {
-        // ~[/...]
-        if let Some(home) = home_dir() {
-            match dir_path.strip_prefix("~") {
-                Ok(rel_path) => home.join(rel_path),
-                _ => home,
+    #[cfg(all(unix, not(any(target_os = "fuchsia"))))]
+    let dir = {
+        if dir_path.starts_with("~") {
+            // ~[/...]
+            if let Some(home) = home_dir() {
+                match dir_path.strip_prefix("~") {
+                    Ok(rel_path) => home.join(rel_path),
+                    _ => home,
+                }
+            } else {
+                dir_path.to_path_buf()
+            }
+        } else if dir_path.is_relative() {
+            // TODO ~user[/...] (https://crates.io/crates/users)
+            if let Ok(cwd) = current_dir() {
+                cwd.join(dir_path)
+            } else {
+                dir_path.to_path_buf()
             }
         } else {
             dir_path.to_path_buf()
         }
-    } else if dir_path.is_relative() {
-        // TODO ~user[/...] (https://crates.io/crates/users)
-        if let Ok(cwd) = current_dir() {
-            cwd.join(dir_path)
+    };
+    #[cfg(target_os = "fuchsia")]
+    let dir = {
+        if dir_path.is_relative() {
+            // TODO ~user[/...] (https://crates.io/crates/users)
+            if let Ok(cwd) = current_dir() {
+                cwd.join(dir_path)
+            } else {
+                dir_path.to_path_buf()
+            }
         } else {
             dir_path.to_path_buf()
         }
-    } else {
-        dir_path.to_path_buf()
     };
 
-    let mut entries: Vec<String> = Vec::new();
-    for entry in try!(dir.read_dir()) {
-        let entry = try!(entry);
-        if let Some(s) = entry.file_name().to_str() {
-            if s.starts_with(file_name) {
-                let mut path = String::from(dir_name) + s;
-                if try!(fs::metadata(entry.path())).is_dir() {
-                    path.push(sep);
+    let mut entries: Vec<Pair> = Vec::new();
+
+    // if dir doesn't exist, then don't offer any completions
+    if !dir.exists() {
+        return Ok(entries);
+    }
+
+    // if any of the below IO operations have errors, just ignore them
+    if let Ok(read_dir) = dir.read_dir() {
+        for entry in read_dir {
+            if let Ok(entry) = entry {
+                if let Some(s) = entry.file_name().to_str() {
+                    if s.starts_with(file_name) {
+                        if let Ok(metadata) = fs::metadata(entry.path()) {
+                            let mut path = String::from(dir_name) + s;
+                            if metadata.is_dir() {
+                                path.push(sep);
+                            }
+                            entries.push(Pair {
+                                display: String::from(s),
+                                replacement: escape(path, esc_char, break_chars, quote),
+                            });
+                        } // else ignore PermissionDenied
+                    }
                 }
-                entries.push(escape(path, esc_char, break_chars));
             }
         }
     }
@@ -202,11 +350,12 @@
 /// try to find backward the start of a word.
 /// Return (0, `line[..pos]`) if no break char has been found.
 /// Return the word and its start position (idx, `line[idx..pos]`) otherwise.
-pub fn extract_word<'l>(line: &'l str,
-                        pos: usize,
-                        esc_char: Option<char>,
-                        break_chars: &BTreeSet<char>)
-                        -> (usize, &'l str) {
+pub fn extract_word<'l>(
+    line: &'l str,
+    pos: usize,
+    esc_char: Option<char>,
+    break_chars: &[u8],
+) -> (usize, &'l str) {
     let line = &line[..pos];
     if line.is_empty() {
         return (0, line);
@@ -222,7 +371,7 @@
                 break;
             }
         }
-        if break_chars.contains(&c) {
+        if c.is_ascii() && memchr(c as u8, break_chars).is_some() {
             start = Some(i + c.len_utf8());
             if esc_char.is_none() {
                 break;
@@ -236,46 +385,109 @@
     }
 }
 
-pub fn longest_common_prefix(candidates: &[String]) -> Option<&str> {
+pub fn longest_common_prefix<C: Candidate>(candidates: &[C]) -> Option<&str> {
     if candidates.is_empty() {
         return None;
     } else if candidates.len() == 1 {
-        return Some(&candidates[0]);
+        return Some(&candidates[0].replacement());
     }
     let mut longest_common_prefix = 0;
     'o: loop {
         for (i, c1) in candidates.iter().enumerate().take(candidates.len() - 1) {
-            let b1 = c1.as_bytes();
-            let b2 = candidates[i + 1].as_bytes();
-            if b1.len() <= longest_common_prefix || b2.len() <= longest_common_prefix ||
-               b1[longest_common_prefix] != b2[longest_common_prefix] {
+            let b1 = c1.replacement().as_bytes();
+            let b2 = candidates[i + 1].replacement().as_bytes();
+            if b1.len() <= longest_common_prefix
+                || b2.len() <= longest_common_prefix
+                || b1[longest_common_prefix] != b2[longest_common_prefix]
+            {
                 break 'o;
             }
         }
         longest_common_prefix += 1;
     }
-    while !candidates[0].is_char_boundary(longest_common_prefix) {
+    let candidate = candidates[0].replacement();
+    while !candidate.is_char_boundary(longest_common_prefix) {
         longest_common_prefix -= 1;
     }
     if longest_common_prefix == 0 {
         return None;
     }
-    Some(&candidates[0][0..longest_common_prefix])
+    Some(&candidate[0..longest_common_prefix])
+}
+
+#[derive(PartialEq)]
+enum ScanMode {
+    DoubleQuote,
+    Escape,
+    EscapeInDoubleQuote,
+    Normal,
+    SingleQuote,
+}
+
+/// try to find an unclosed single/double quote in `s`.
+/// Return `None` if no unclosed quote is found.
+/// Return the unclosed quote position and if it is a double quote.
+fn find_unclosed_quote(s: &str) -> Option<(usize, Quote)> {
+    let char_indices = s.char_indices();
+    let mut mode = ScanMode::Normal;
+    let mut quote_index = 0;
+    for (index, char) in char_indices {
+        match mode {
+            ScanMode::DoubleQuote => {
+                if char == '"' {
+                    mode = ScanMode::Normal;
+                } else if char == '\\' {
+                    // both windows and unix support escape in double quote
+                    mode = ScanMode::EscapeInDoubleQuote;
+                }
+            }
+            ScanMode::Escape => {
+                mode = ScanMode::Normal;
+            }
+            ScanMode::EscapeInDoubleQuote => {
+                mode = ScanMode::DoubleQuote;
+            }
+            ScanMode::Normal => {
+                if char == '"' {
+                    mode = ScanMode::DoubleQuote;
+                    quote_index = index;
+                } else if char == '\\' && cfg!(not(windows)) {
+                    mode = ScanMode::Escape;
+                } else if char == '\'' && cfg!(not(windows)) {
+                    mode = ScanMode::SingleQuote;
+                    quote_index = index;
+                }
+            }
+            ScanMode::SingleQuote => {
+                if char == '\'' {
+                    mode = ScanMode::Normal;
+                } // no escape in single quotes
+            }
+        };
+    }
+    if ScanMode::DoubleQuote == mode || ScanMode::EscapeInDoubleQuote == mode {
+        return Some((quote_index, Quote::Double));
+    } else if ScanMode::SingleQuote == mode {
+        return Some((quote_index, Quote::Single));
+    }
+    None
 }
 
 #[cfg(test)]
 mod tests {
-    use std::collections::BTreeSet;
-
     #[test]
     pub fn extract_word() {
-        let break_chars: BTreeSet<char> = super::DEFAULT_BREAK_CHARS.iter().cloned().collect();
+        let break_chars: &[u8] = &super::DEFAULT_BREAK_CHARS;
         let line = "ls '/usr/local/b";
-        assert_eq!((4, "/usr/local/b"),
-                   super::extract_word(line, line.len(), Some('\\'), &break_chars));
+        assert_eq!(
+            (4, "/usr/local/b"),
+            super::extract_word(line, line.len(), Some('\\'), &break_chars)
+        );
         let line = "ls /User\\ Information";
-        assert_eq!((3, "/User\\ Information"),
-                   super::extract_word(line, line.len(), Some('\\'), &break_chars));
+        assert_eq!(
+            (3, "/User\\ Information"),
+            super::extract_word(line, line.len(), Some('\\'), &break_chars)
+        );
     }
 
     #[test]
@@ -283,20 +495,31 @@
         use std::borrow::Cow::{self, Borrowed, Owned};
         let input = "/usr/local/b";
         assert_eq!(Borrowed(input), super::unescape(input, Some('\\')));
-        let input = "/User\\ Information";
-        let result: Cow<str> = Owned(String::from("/User Information"));
-        assert_eq!(result, super::unescape(input, Some('\\')));
+        if cfg!(windows) {
+            let input = "c:\\users\\All Users\\";
+            let result: Cow<str> = Borrowed(input);
+            assert_eq!(result, super::unescape(input, Some('\\')));
+        } else {
+            let input = "/User\\ Information";
+            let result: Cow<str> = Owned(String::from("/User Information"));
+            assert_eq!(result, super::unescape(input, Some('\\')));
+        }
     }
 
     #[test]
     pub fn escape() {
-        let break_chars: BTreeSet<char> = super::DEFAULT_BREAK_CHARS.iter().cloned().collect();
+        let break_chars: &[u8] = &super::DEFAULT_BREAK_CHARS;
         let input = String::from("/usr/local/b");
-        assert_eq!(input.clone(),
-                   super::escape(input, Some('\\'), &break_chars));
+        assert_eq!(
+            input.clone(),
+            super::escape(input, Some('\\'), &break_chars, super::Quote::None)
+        );
         let input = String::from("/User Information");
         let result = String::from("/User\\ Information");
-        assert_eq!(result, super::escape(input, Some('\\'), &break_chars));
+        assert_eq!(
+            result,
+            super::escape(input, Some('\\'), &break_chars, super::Quote::None)
+        );
     }
 
     #[test]
@@ -333,4 +556,21 @@
         let lcp = super::longest_common_prefix(&candidates);
         assert_eq!(Some("f"), lcp);
     }
+
+    #[test]
+    pub fn find_unclosed_quote() {
+        assert_eq!(None, super::find_unclosed_quote("ls /etc"));
+        assert_eq!(
+            Some((3, super::Quote::Double)),
+            super::find_unclosed_quote("ls \"User Information")
+        );
+        assert_eq!(
+            None,
+            super::find_unclosed_quote("ls \"/User Information\" /etc")
+        );
+        assert_eq!(
+            Some((0, super::Quote::Double)),
+            super::find_unclosed_quote("\"c:\\users\\All Users\\")
+        )
+    }
 }
diff --git a/src/config.rs b/src/config.rs
index 3be614c..e59a308 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,20 +1,29 @@
 //! Customize line editor
 use std::default::Default;
 
+/// User preferences
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub struct Config {
     /// Maximum number of entries in History.
-    max_history_size: usize,
+    max_history_size: usize, // history_max_entries
     history_duplicates: HistoryDuplicates,
     history_ignore_space: bool,
     completion_type: CompletionType,
     /// When listing completion alternatives, only display
     /// one screen of possibilities at a time.
     completion_prompt_limit: usize,
-    /// Duration (milliseconds) Rustyline will wait for a character when reading an ambiguous key sequence.
+    /// Duration (milliseconds) Rustyline will wait for a character when
+    /// reading an ambiguous key sequence.
     keyseq_timeout: i32,
-    // Emacs or Vi mode
+    /// Emacs or Vi mode
     edit_mode: EditMode,
+    /// If true, each nonblank line returned by `readline` will be
+    /// automatically added to the history.
+    auto_add_history: bool,
+    /// if colors should be enabled.
+    color_mode: ColorMode,
+    /// Whether to use stdout or stderr
+    output_stream: OutputStreamType,
 }
 
 impl Config {
@@ -27,18 +36,38 @@
         self.max_history_size
     }
 
-    /// Tell if lines which match the previous history entry are saved or not in the history list.
+    pub(crate) fn set_max_history_size(&mut self, max_size: usize) {
+        self.max_history_size = max_size;
+    }
+
+    /// Tell if lines which match the previous history entry are saved or not
+    /// in the history list.
+    ///
     /// By default, they are ignored.
     pub fn history_duplicates(&self) -> HistoryDuplicates {
         self.history_duplicates
     }
 
-    /// Tell if lines which begin with a space character are saved or not in the history list.
+    pub(crate) fn set_history_ignore_dups(&mut self, yes: bool) {
+        self.history_duplicates = if yes {
+            HistoryDuplicates::IgnoreConsecutive
+        } else {
+            HistoryDuplicates::AlwaysAdd
+        };
+    }
+
+    /// Tell if lines which begin with a space character are saved or not in
+    /// the history list.
+    ///
     /// By default, they are saved.
     pub fn history_ignore_space(&self) -> bool {
         self.history_ignore_space
     }
 
+    pub(crate) fn set_history_ignore_space(&mut self, yes: bool) {
+        self.history_ignore_space = yes;
+    }
+
     pub fn completion_type(&self) -> CompletionType {
         self.completion_type
     }
@@ -54,6 +83,32 @@
     pub fn edit_mode(&self) -> EditMode {
         self.edit_mode
     }
+
+    /// Tell if lines are automatically added to the history.
+    ///
+    /// By default, they are not.
+    pub fn auto_add_history(&self) -> bool {
+        self.auto_add_history
+    }
+
+    /// Tell if colors should be enabled.
+    ///
+    /// By default, they are except if stdout is not a tty.
+    pub fn color_mode(&self) -> ColorMode {
+        self.color_mode
+    }
+
+    pub(crate) fn set_color_mode(&mut self, color_mode: ColorMode) {
+        self.color_mode = color_mode;
+    }
+
+    pub fn output_stream(&self) -> OutputStreamType {
+        self.output_stream
+    }
+
+    pub(crate) fn set_output_stream(&mut self, stream: OutputStreamType) {
+        self.output_stream = stream;
+    }
 }
 
 impl Default for Config {
@@ -64,8 +119,11 @@
             history_ignore_space: false,
             completion_type: CompletionType::Circular, // TODO Validate
             completion_prompt_limit: 100,
-            keyseq_timeout: 500,
+            keyseq_timeout: -1,
             edit_mode: EditMode::Emacs,
+            auto_add_history: false,
+            color_mode: ColorMode::Enabled,
+            output_stream: OutputStreamType::Stdout,
         }
     }
 }
@@ -73,6 +131,7 @@
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub enum HistoryDuplicates {
     AlwaysAdd,
+    /// a line will not be added to the history if it matches the previous entry
     IgnoreConsecutive,
 }
 
@@ -86,12 +145,29 @@
     List,
 }
 
+/// Style of editing / Standard keymaps
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub enum EditMode {
     Emacs,
     Vi,
 }
 
+/// Colorization mode
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub enum ColorMode {
+    Enabled,
+    Forced,
+    Disabled,
+}
+
+/// Should the editor use stdout or stderr
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub enum OutputStreamType {
+    Stderr,
+    Stdout,
+}
+
+/// Configuration builder
 #[derive(Debug, Default)]
 pub struct Builder {
     p: Config,
@@ -99,57 +175,85 @@
 
 impl Builder {
     pub fn new() -> Builder {
-        Builder { p: Config::default() }
+        Builder {
+            p: Config::default(),
+        }
     }
 
     /// Set the maximum length for the history.
     pub fn max_history_size(mut self, max_size: usize) -> Builder {
-        self.p.max_history_size = max_size;
+        self.set_max_history_size(max_size);
         self
     }
 
-    /// Tell if lines which match the previous history entry are saved or not in the history list.
+    /// Tell if lines which match the previous history entry are saved or not
+    /// in the history list.
+    ///
     /// By default, they are ignored.
     pub fn history_ignore_dups(mut self, yes: bool) -> Builder {
-        self.p.history_duplicates = if yes {
-            HistoryDuplicates::IgnoreConsecutive
-        } else {
-            HistoryDuplicates::AlwaysAdd
-        };
+        self.set_history_ignore_dups(yes);
         self
     }
 
-    /// Tell if lines which begin with a space character are saved or not in the history list.
+    /// Tell if lines which begin with a space character are saved or not in
+    /// the history list.
+    ///
     /// By default, they are saved.
     pub fn history_ignore_space(mut self, yes: bool) -> Builder {
-        self.p.history_ignore_space = yes;
+        self.set_history_ignore_space(yes);
         self
     }
 
     /// Set `completion_type`.
     pub fn completion_type(mut self, completion_type: CompletionType) -> Builder {
-        self.p.completion_type = completion_type;
+        self.set_completion_type(completion_type);
         self
     }
 
-    /// The number of possible completions that determines when the user is asked
-    /// whether the list of possibilities should be displayed.
+    /// The number of possible completions that determines when the user is
+    /// asked whether the list of possibilities should be displayed.
     pub fn completion_prompt_limit(mut self, completion_prompt_limit: usize) -> Builder {
-        self.p.completion_prompt_limit = completion_prompt_limit;
+        self.set_completion_prompt_limit(completion_prompt_limit);
         self
     }
 
     /// Timeout for ambiguous key sequences in milliseconds.
-    /// Currently, it is used only to distinguish a single ESC from an ESC sequence.
-    /// After seeing an ESC key, wait at most `keyseq_timeout_ms` for another byte.
+    /// Currently, it is used only to distinguish a single ESC from an ESC
+    /// sequence.
+    /// After seeing an ESC key, wait at most `keyseq_timeout_ms` for another
+    /// byte.
     pub fn keyseq_timeout(mut self, keyseq_timeout_ms: i32) -> Builder {
-        self.p.keyseq_timeout = keyseq_timeout_ms;
+        self.set_keyseq_timeout(keyseq_timeout_ms);
         self
     }
 
     /// Choose between Emacs or Vi mode.
     pub fn edit_mode(mut self, edit_mode: EditMode) -> Builder {
-        self.p.edit_mode = edit_mode;
+        self.set_edit_mode(edit_mode);
+        self
+    }
+
+    /// Tell if lines are automatically added to the history.
+    ///
+    /// By default, they are not.
+    pub fn auto_add_history(mut self, yes: bool) -> Builder {
+        self.set_auto_add_history(yes);
+        self
+    }
+
+    /// Forces colorization on or off.
+    ///
+    /// By default, colorization is on except if stdout is not a tty.
+    pub fn color_mode(mut self, color_mode: ColorMode) -> Builder {
+        self.set_color_mode(color_mode);
+        self
+    }
+
+    /// Whether to use stdout or stderr.
+    ///
+    /// Be default, use stdout
+    pub fn output_stream(mut self, stream: OutputStreamType) -> Builder {
+        self.set_output_stream(stream);
         self
     }
 
@@ -157,3 +261,79 @@
         self.p
     }
 }
+
+impl Configurer for Builder {
+    fn config_mut(&mut self) -> &mut Config {
+        &mut self.p
+    }
+}
+
+pub trait Configurer {
+    fn config_mut(&mut self) -> &mut Config;
+
+    /// Set the maximum length for the history.
+    fn set_max_history_size(&mut self, max_size: usize) {
+        self.config_mut().set_max_history_size(max_size);
+    }
+
+    /// Tell if lines which match the previous history entry are saved or not
+    /// in the history list.
+    ///
+    /// By default, they are ignored.
+    fn set_history_ignore_dups(&mut self, yes: bool) {
+        self.config_mut().set_history_ignore_dups(yes);
+    }
+
+    /// Tell if lines which begin with a space character are saved or not in
+    /// the history list.
+    ///
+    /// By default, they are saved.
+    fn set_history_ignore_space(&mut self, yes: bool) {
+        self.config_mut().set_history_ignore_space(yes);
+    }
+    /// Set `completion_type`.
+    fn set_completion_type(&mut self, completion_type: CompletionType) {
+        self.config_mut().completion_type = completion_type;
+    }
+
+    /// The number of possible completions that determines when the user is
+    /// asked whether the list of possibilities should be displayed.
+    fn set_completion_prompt_limit(&mut self, completion_prompt_limit: usize) {
+        self.config_mut().completion_prompt_limit = completion_prompt_limit;
+    }
+
+    /// Timeout for ambiguous key sequences in milliseconds.
+    fn set_keyseq_timeout(&mut self, keyseq_timeout_ms: i32) {
+        self.config_mut().keyseq_timeout = keyseq_timeout_ms;
+    }
+
+    /// Choose between Emacs or Vi mode.
+    fn set_edit_mode(&mut self, edit_mode: EditMode) {
+        self.config_mut().edit_mode = edit_mode;
+        match edit_mode {
+            EditMode::Emacs => self.set_keyseq_timeout(-1), // no timeout
+            EditMode::Vi => self.set_keyseq_timeout(500),
+        }
+    }
+
+    /// Tell if lines are automatically added to the history.
+    ///
+    /// By default, they are not.
+    fn set_auto_add_history(&mut self, yes: bool) {
+        self.config_mut().auto_add_history = yes;
+    }
+
+    /// Forces colorization on or off.
+    ///
+    /// By default, colorization is on except if stdout is not a tty.
+    fn set_color_mode(&mut self, color_mode: ColorMode) {
+        self.config_mut().set_color_mode(color_mode);
+    }
+
+    /// Whether to use stdout or stderr
+    ///
+    /// By default, use stdout
+    fn set_output_stream(&mut self, stream: OutputStreamType) {
+        self.config_mut().set_output_stream(stream);
+    }
+}
diff --git a/src/edit.rs b/src/edit.rs
new file mode 100644
index 0000000..7d706f5
--- /dev/null
+++ b/src/edit.rs
@@ -0,0 +1,560 @@
+//! Command processor
+
+use std::cell::RefCell;
+use std::fmt;
+use std::rc::Rc;
+use unicode_segmentation::UnicodeSegmentation;
+use unicode_width::UnicodeWidthChar;
+
+use super::Result;
+use highlight::Highlighter;
+use hint::Hinter;
+use history::{Direction, History};
+use keymap::{Anchor, At, CharSearch, Cmd, Movement, RepeatCount, Word};
+use keymap::{InputState, Refresher};
+use line_buffer::{LineBuffer, WordAction, MAX_LINE};
+use tty::{Position, RawReader, Renderer};
+use undo::Changeset;
+
+/// Represent the state during line editing.
+/// Implement rendering.
+pub struct State<'out, 'prompt> {
+    pub out: &'out mut Renderer,
+    prompt: &'prompt str,  // Prompt to display (rl_prompt)
+    prompt_size: Position, // Prompt Unicode/visible width and height
+    pub line: LineBuffer,  // Edited line buffer
+    pub cursor: Position,  /* Cursor position (relative to the start of the prompt
+                            * for `row`) */
+    pub old_rows: usize, // Number of rows used so far (from start of prompt to end of input)
+    history_index: usize, // The history index we are currently editing
+    saved_line_for_history: LineBuffer, // Current edited line before history browsing
+    byte_buffer: [u8; 4],
+    pub changes: Rc<RefCell<Changeset>>, // changes to line, for undo/redo
+    pub hinter: Option<&'out Hinter>,
+    pub highlighter: Option<&'out Highlighter>,
+    no_hint: bool, // `false` if an hint has been displayed
+}
+
+impl<'out, 'prompt> State<'out, 'prompt> {
+    pub fn new(
+        out: &'out mut Renderer,
+        prompt: &'prompt str,
+        history_index: usize,
+        hinter: Option<&'out Hinter>,
+        highlighter: Option<&'out Highlighter>,
+    ) -> State<'out, 'prompt> {
+        let capacity = MAX_LINE;
+        let prompt_size = out.calculate_position(prompt, Position::default());
+        State {
+            out,
+            prompt,
+            prompt_size,
+            line: LineBuffer::with_capacity(capacity),
+            cursor: prompt_size,
+            old_rows: 0,
+            history_index,
+            saved_line_for_history: LineBuffer::with_capacity(capacity),
+            byte_buffer: [0; 4],
+            changes: Rc::new(RefCell::new(Changeset::new())),
+            hinter,
+            highlighter,
+            no_hint: true,
+        }
+    }
+
+    pub fn next_cmd<R: RawReader>(
+        &mut self,
+        input_state: &mut InputState,
+        rdr: &mut R,
+        single_esc_abort: bool,
+    ) -> Result<Cmd> {
+        loop {
+            let rc = input_state.next_cmd(rdr, self, single_esc_abort);
+            if rc.is_err() && self.out.sigwinch() {
+                self.out.update_size();
+                try!(self.refresh_line());
+                continue;
+            }
+            if let Ok(Cmd::Replace(_, _)) = rc {
+                self.changes.borrow_mut().begin();
+            }
+            return rc;
+        }
+    }
+
+    pub fn backup(&mut self) {
+        self.saved_line_for_history
+            .update(self.line.as_str(), self.line.pos());
+    }
+
+    pub fn restore(&mut self) {
+        self.line.update(
+            self.saved_line_for_history.as_str(),
+            self.saved_line_for_history.pos(),
+        );
+    }
+
+    pub fn move_cursor(&mut self) -> Result<()> {
+        // calculate the desired position of the cursor
+        let cursor = self
+            .out
+            .calculate_position(&self.line[..self.line.pos()], self.prompt_size);
+        if self.cursor == cursor {
+            return Ok(());
+        }
+        if self.highlighter.map_or(false, |h| {
+            self.line
+                .grapheme_at_cursor()
+                .map_or(false, |s| h.highlight_char(s))
+        }) {
+            let prompt_size = self.prompt_size;
+            try!(self.refresh(self.prompt, prompt_size, None));
+        } else {
+            try!(self.out.move_cursor(self.cursor, cursor));
+        }
+        self.cursor = cursor;
+        Ok(())
+    }
+
+    fn refresh(&mut self, prompt: &str, prompt_size: Position, hint: Option<String>) -> Result<()> {
+        let (cursor, end_pos) = try!(self.out.refresh_line(
+            prompt,
+            prompt_size,
+            &self.line,
+            hint,
+            self.cursor.row,
+            self.old_rows,
+            self.highlighter,
+        ));
+
+        self.cursor = cursor;
+        self.old_rows = end_pos.row;
+        Ok(())
+    }
+
+    fn hint(&mut self) -> Option<String> {
+        if let Some(hinter) = self.hinter {
+            self.no_hint = false;
+            hinter.hint(self.line.as_str(), self.line.pos())
+        } else {
+            self.no_hint = true;
+            None
+        }
+    }
+}
+
+impl<'out, 'prompt> Refresher for State<'out, 'prompt> {
+    fn refresh_line(&mut self) -> Result<()> {
+        let prompt_size = self.prompt_size;
+        let hint = self.hint();
+        self.refresh(self.prompt, prompt_size, hint)
+    }
+
+    fn refresh_prompt_and_line(&mut self, prompt: &str) -> Result<()> {
+        let prompt_size = self.out.calculate_position(prompt, Position::default());
+        let hint = self.hint();
+        self.refresh(prompt, prompt_size, hint)
+    }
+
+    fn doing_insert(&mut self) {
+        self.changes.borrow_mut().begin();
+    }
+
+    fn done_inserting(&mut self) {
+        self.changes.borrow_mut().end();
+    }
+
+    fn last_insert(&self) -> Option<String> {
+        self.changes.borrow().last_insert()
+    }
+}
+
+impl<'out, 'prompt> fmt::Debug for State<'out, 'prompt> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("State")
+            .field("prompt", &self.prompt)
+            .field("prompt_size", &self.prompt_size)
+            .field("buf", &self.line)
+            .field("cursor", &self.cursor)
+            .field("cols", &self.out.get_columns())
+            .field("old_rows", &self.old_rows)
+            .field("history_index", &self.history_index)
+            .field("saved_line_for_history", &self.saved_line_for_history)
+            .finish()
+    }
+}
+
+impl<'out, 'prompt> State<'out, 'prompt> {
+    /// Insert the character `ch` at cursor current position.
+    pub fn edit_insert(&mut self, ch: char, n: RepeatCount) -> Result<()> {
+        if let Some(push) = self.line.insert(ch, n) {
+            if push {
+                let prompt_size = self.prompt_size;
+                let no_previous_hint = self.no_hint;
+                let hint = self.hint();
+                if n == 1
+                    && self.cursor.col + ch.width().unwrap_or(0) < self.out.get_columns()
+                    && (hint.is_none() && no_previous_hint) // TODO refresh only current line
+                    && !self.highlighter.map_or(true, |h| h.highlight_char(ch.encode_utf8(&mut self.byte_buffer)))
+                {
+                    // Avoid a full update of the line in the trivial case.
+                    let cursor = self
+                        .out
+                        .calculate_position(&self.line[..self.line.pos()], self.prompt_size);
+                    self.cursor = cursor;
+                    let bits = ch.encode_utf8(&mut self.byte_buffer);
+                    let bits = bits.as_bytes();
+                    self.out.write_and_flush(bits)
+                } else {
+                    self.refresh(self.prompt, prompt_size, hint)
+                }
+            } else {
+                self.refresh_line()
+            }
+        } else {
+            Ok(())
+        }
+    }
+
+    /// Replace a single (or n) character(s) under the cursor (Vi mode)
+    pub fn edit_replace_char(&mut self, ch: char, n: RepeatCount) -> Result<()> {
+        self.changes.borrow_mut().begin();
+        let succeed = if let Some(chars) = self.line.delete(n) {
+            let count = chars.graphemes(true).count();
+            self.line.insert(ch, count);
+            self.line.move_backward(1);
+            true
+        } else {
+            false
+        };
+        self.changes.borrow_mut().end();
+        if succeed {
+            self.refresh_line()
+        } else {
+            Ok(())
+        }
+    }
+
+    /// Overwrite the character under the cursor (Vi mode)
+    pub fn edit_overwrite_char(&mut self, ch: char) -> Result<()> {
+        if let Some(end) = self.line.next_pos(1) {
+            {
+                let text = ch.encode_utf8(&mut self.byte_buffer);
+                let start = self.line.pos();
+                self.line.replace(start..end, text);
+            }
+            self.refresh_line()
+        } else {
+            Ok(())
+        }
+    }
+
+    // Yank/paste `text` at current position.
+    pub fn edit_yank(
+        &mut self,
+        input_state: &InputState,
+        text: &str,
+        anchor: Anchor,
+        n: RepeatCount,
+    ) -> Result<()> {
+        if let Anchor::After = anchor {
+            self.line.move_forward(1);
+        }
+        if self.line.yank(text, n).is_some() {
+            if !input_state.is_emacs_mode() {
+                self.line.move_backward(1);
+            }
+            self.refresh_line()
+        } else {
+            Ok(())
+        }
+    }
+
+    // Delete previously yanked text and yank/paste `text` at current position.
+    pub fn edit_yank_pop(&mut self, yank_size: usize, text: &str) -> Result<()> {
+        self.changes.borrow_mut().begin();
+        let result = if self.line.yank_pop(yank_size, text).is_some() {
+            self.refresh_line()
+        } else {
+            Ok(())
+        };
+        self.changes.borrow_mut().end();
+        result
+    }
+
+    /// Move cursor on the left.
+    pub fn edit_move_backward(&mut self, n: RepeatCount) -> Result<()> {
+        if self.line.move_backward(n) {
+            self.move_cursor()
+        } else {
+            Ok(())
+        }
+    }
+
+    /// Move cursor on the right.
+    pub fn edit_move_forward(&mut self, n: RepeatCount) -> Result<()> {
+        if self.line.move_forward(n) {
+            self.move_cursor()
+        } else {
+            Ok(())
+        }
+    }
+
+    /// Move cursor to the start of the line.
+    pub fn edit_move_home(&mut self) -> Result<()> {
+        if self.line.move_home() {
+            self.move_cursor()
+        } else {
+            Ok(())
+        }
+    }
+
+    /// Move cursor to the end of the line.
+    pub fn edit_move_end(&mut self) -> Result<()> {
+        if self.line.move_end() {
+            self.move_cursor()
+        } else {
+            Ok(())
+        }
+    }
+
+    pub fn edit_kill(&mut self, mvt: &Movement) -> Result<()> {
+        if self.line.kill(mvt) {
+            self.refresh_line()
+        } else {
+            Ok(())
+        }
+    }
+
+    pub fn edit_insert_text(&mut self, text: &str) -> Result<()> {
+        if text.is_empty() {
+            return Ok(());
+        }
+        let cursor = self.line.pos();
+        self.line.insert_str(cursor, text);
+        self.refresh_line()
+    }
+
+    pub fn edit_delete(&mut self, n: RepeatCount) -> Result<()> {
+        if self.line.delete(n).is_some() {
+            self.refresh_line()
+        } else {
+            Ok(())
+        }
+    }
+
+    /// Exchange the char before cursor with the character at cursor.
+    pub fn edit_transpose_chars(&mut self) -> Result<()> {
+        self.changes.borrow_mut().begin();
+        let succeed = self.line.transpose_chars();
+        self.changes.borrow_mut().end();
+        if succeed {
+            self.refresh_line()
+        } else {
+            Ok(())
+        }
+    }
+
+    pub fn edit_move_to_prev_word(&mut self, word_def: Word, n: RepeatCount) -> Result<()> {
+        if self.line.move_to_prev_word(word_def, n) {
+            self.move_cursor()
+        } else {
+            Ok(())
+        }
+    }
+
+    pub fn edit_move_to_next_word(&mut self, at: At, word_def: Word, n: RepeatCount) -> Result<()> {
+        if self.line.move_to_next_word(at, word_def, n) {
+            self.move_cursor()
+        } else {
+            Ok(())
+        }
+    }
+
+    pub fn edit_move_to(&mut self, cs: CharSearch, n: RepeatCount) -> Result<()> {
+        if self.line.move_to(cs, n) {
+            self.move_cursor()
+        } else {
+            Ok(())
+        }
+    }
+
+    pub fn edit_word(&mut self, a: WordAction) -> Result<()> {
+        self.changes.borrow_mut().begin();
+        let succeed = self.line.edit_word(a);
+        self.changes.borrow_mut().end();
+        if succeed {
+            self.refresh_line()
+        } else {
+            Ok(())
+        }
+    }
+
+    pub fn edit_transpose_words(&mut self, n: RepeatCount) -> Result<()> {
+        self.changes.borrow_mut().begin();
+        let succeed = self.line.transpose_words(n);
+        self.changes.borrow_mut().end();
+        if succeed {
+            self.refresh_line()
+        } else {
+            Ok(())
+        }
+    }
+
+    /// Substitute the currently edited line with the next or previous history
+    /// entry.
+    pub fn edit_history_next(&mut self, history: &History, prev: bool) -> Result<()> {
+        if history.is_empty() {
+            return Ok(());
+        }
+        if self.history_index == history.len() {
+            if prev {
+                // Save the current edited line before overwriting it
+                self.backup();
+            } else {
+                return Ok(());
+            }
+        } else if self.history_index == 0 && prev {
+            return Ok(());
+        }
+        if prev {
+            self.history_index -= 1;
+        } else {
+            self.history_index += 1;
+        }
+        if self.history_index < history.len() {
+            let buf = history.get(self.history_index).unwrap();
+            self.changes.borrow_mut().begin();
+            self.line.update(buf, buf.len());
+            self.changes.borrow_mut().end();
+        } else {
+            // Restore current edited line
+            self.restore();
+        }
+        self.refresh_line()
+    }
+
+    // Non-incremental, anchored search
+    pub fn edit_history_search(&mut self, history: &History, dir: Direction) -> Result<()> {
+        if history.is_empty() {
+            return self.out.beep();
+        }
+        if self.history_index == history.len() && dir == Direction::Forward
+            || self.history_index == 0 && dir == Direction::Reverse
+        {
+            return self.out.beep();
+        }
+        if dir == Direction::Reverse {
+            self.history_index -= 1;
+        } else {
+            self.history_index += 1;
+        }
+        if let Some(history_index) = history.starts_with(
+            &self.line.as_str()[..self.line.pos()],
+            self.history_index,
+            dir,
+        ) {
+            self.history_index = history_index;
+            let buf = history.get(history_index).unwrap();
+            self.changes.borrow_mut().begin();
+            self.line.update(buf, buf.len());
+            self.changes.borrow_mut().end();
+            self.refresh_line()
+        } else {
+            self.out.beep()
+        }
+    }
+
+    /// Substitute the currently edited line with the first/last history entry.
+    pub fn edit_history(&mut self, history: &History, first: bool) -> Result<()> {
+        if history.is_empty() {
+            return Ok(());
+        }
+        if self.history_index == history.len() {
+            if first {
+                // Save the current edited line before overwriting it
+                self.backup();
+            } else {
+                return Ok(());
+            }
+        } else if self.history_index == 0 && first {
+            return Ok(());
+        }
+        if first {
+            self.history_index = 0;
+            let buf = history.get(self.history_index).unwrap();
+            self.changes.borrow_mut().begin();
+            self.line.update(buf, buf.len());
+            self.changes.borrow_mut().end();
+        } else {
+            self.history_index = history.len();
+            // Restore current edited line
+            self.restore();
+        }
+        self.refresh_line()
+    }
+}
+
+#[cfg(test)]
+pub fn init_state<'out>(out: &'out mut Renderer, line: &str, pos: usize) -> State<'out, 'static> {
+    State {
+        out,
+        prompt: "",
+        prompt_size: Position::default(),
+        line: LineBuffer::init(line, pos, None),
+        cursor: Position::default(),
+        old_rows: 0,
+        history_index: 0,
+        saved_line_for_history: LineBuffer::with_capacity(100),
+        byte_buffer: [0; 4],
+        changes: Rc::new(RefCell::new(Changeset::new())),
+        hinter: None,
+        highlighter: None,
+        no_hint: true,
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::init_state;
+    use history::History;
+    use tty::Sink;
+
+    #[test]
+    fn edit_history_next() {
+        let mut out = Sink::new();
+        let line = "current edited line";
+        let mut s = init_state(&mut out, line, 6);
+        let mut history = History::new();
+        history.add("line0");
+        history.add("line1");
+        s.history_index = history.len();
+
+        for _ in 0..2 {
+            s.edit_history_next(&history, false).unwrap();
+            assert_eq!(line, s.line.as_str());
+        }
+
+        s.edit_history_next(&history, true).unwrap();
+        assert_eq!(line, s.saved_line_for_history.as_str());
+        assert_eq!(1, s.history_index);
+        assert_eq!("line1", s.line.as_str());
+
+        for _ in 0..2 {
+            s.edit_history_next(&history, true).unwrap();
+            assert_eq!(line, s.saved_line_for_history.as_str());
+            assert_eq!(0, s.history_index);
+            assert_eq!("line0", s.line.as_str());
+        }
+
+        s.edit_history_next(&history, false).unwrap();
+        assert_eq!(line, s.saved_line_for_history.as_str());
+        assert_eq!(1, s.history_index);
+        assert_eq!("line1", s.line.as_str());
+
+        s.edit_history_next(&history, false).unwrap();
+        // assert_eq!(line, s.saved_line_for_history);
+        assert_eq!(2, s.history_index);
+        assert_eq!(line, s.line.as_str());
+    }
+}
diff --git a/src/error.rs b/src/error.rs
index d778960..f096521 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -1,17 +1,16 @@
 //! Contains error type for handling I/O and Errno errors
-#[cfg(windows)]
-use std::char;
-use std::io;
-use std::error;
-use std::fmt;
 #[cfg(all(unix, not(any(target_os = "fuchsia"))))]
 use nix;
-
-#[cfg(unix)]
-use char_iter;
+#[cfg(windows)]
+use std::char;
+use std::error;
+use std::fmt;
+use std::io;
+use std::str;
 
 /// The error type for Rustyline errors that can arise from
 /// I/O related errors or Errno when using the nix-rust library
+/// #[non_exhaustive]
 #[derive(Debug)]
 pub enum ReadlineError {
     /// I/O Error
@@ -22,7 +21,7 @@
     Interrupted,
     /// Chars Error
     #[cfg(unix)]
-    Char(char_iter::CharsError),
+    Utf8Error,
     /// Unix Error from syscall
     #[cfg(all(unix, not(any(target_os = "fuchsia"))))]
     Errno(nix::Error),
@@ -39,9 +38,9 @@
             ReadlineError::Eof => write!(f, "EOF"),
             ReadlineError::Interrupted => write!(f, "Interrupted"),
             #[cfg(unix)]
-            ReadlineError::Char(ref err) => err.fmt(f),
+            ReadlineError::Utf8Error => write!(f, "invalid utf-8: corrupt contents"),
             #[cfg(all(unix, not(any(target_os = "fuchsia"))))]
-            ReadlineError::Errno(ref err) => write!(f, "Errno: {}", err.errno().desc()),
+            ReadlineError::Errno(ref err) => err.fmt(f),
             #[cfg(windows)]
             ReadlineError::WindowResize => write!(f, "WindowResize"),
             #[cfg(windows)]
@@ -57,9 +56,9 @@
             ReadlineError::Eof => "EOF",
             ReadlineError::Interrupted => "Interrupted",
             #[cfg(unix)]
-            ReadlineError::Char(ref err) => err.description(),
+            ReadlineError::Utf8Error => "invalid utf-8: corrupt contents",
             #[cfg(all(unix, not(any(target_os = "fuchsia"))))]
-            ReadlineError::Errno(ref err) => err.errno().desc(),
+            ReadlineError::Errno(ref err) => err.description(),
             #[cfg(windows)]
             ReadlineError::WindowResize => "WindowResize",
             #[cfg(windows)]
@@ -81,13 +80,6 @@
     }
 }
 
-#[cfg(unix)]
-impl From<char_iter::CharsError> for ReadlineError {
-    fn from(err: char_iter::CharsError) -> ReadlineError {
-        ReadlineError::Char(err)
-    }
-}
-
 #[cfg(windows)]
 impl From<char::DecodeUtf16Error> for ReadlineError {
     fn from(err: char::DecodeUtf16Error) -> ReadlineError {
diff --git a/src/highlight.rs b/src/highlight.rs
new file mode 100644
index 0000000..e8a9742
--- /dev/null
+++ b/src/highlight.rs
@@ -0,0 +1,64 @@
+//! Syntax highlighting
+
+use config::CompletionType;
+use std::borrow::Cow::{self, Borrowed};
+
+/// Syntax highlighter with [ansi color](https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters).
+/// Rustyline will try to handle escape sequence for ansi color on windows
+/// when not supported natively (windows <10).
+///
+/// Currently, the highlighted version *must* have the same display width as
+/// the original input.
+pub trait Highlighter {
+    /// Takes the currently edited `line` with the cursor `pos`ition and
+    /// returns the highlighted version (with ANSI color).
+    ///
+    /// For example, you can implement
+    /// [blink-matching-paren](https://www.gnu.org/software/bash/manual/html_node/Readline-Init-File-Syntax.html).
+    fn highlight<'l>(&self, line: &'l str, pos: usize) -> Cow<'l, str> {
+        let _ = pos;
+        Borrowed(line)
+    }
+    /// Takes the `prompt` and
+    /// returns the highlighted version (with ANSI color).
+    fn highlight_prompt<'p>(&self, prompt: &'p str) -> Cow<'p, str> {
+        Borrowed(prompt)
+    }
+    /// Takes the dynamic `prompt` and
+    /// returns the highlighted version (with ANSI color).
+    #[deprecated(
+        since = "2.0.1",
+        note = "please use `highlight_prompt` instead"
+    )]
+    fn highlight_dynamic_prompt<'p>(&self, prompt: &'p str) -> Cow<'p, str> {
+        Borrowed(prompt)
+    }
+    /// Takes the `hint` and
+    /// returns the highlighted version (with ANSI color).
+    fn highlight_hint<'h>(&self, hint: &'h str) -> Cow<'h, str> {
+        Borrowed(hint)
+    }
+    /// Takes the completion `canditate` and
+    /// returns the highlighted version (with ANSI color).
+    ///
+    /// Currently, used only with `CompletionType::List`.
+    fn highlight_candidate<'c>(
+        &self,
+        candidate: &'c str,
+        completion: CompletionType,
+    ) -> Cow<'c, str> {
+        let _ = completion;
+        Borrowed(candidate)
+    }
+    /// Tells if the `ch`ar needs to be highlighted when typed or when cursor
+    /// is moved under.
+    ///
+    /// Used to optimize refresh when a character is inserted or the cursor is
+    /// moved.
+    fn highlight_char(&self, grapheme: &str) -> bool {
+        let _ = grapheme;
+        false
+    }
+}
+
+impl Highlighter for () {}
diff --git a/src/hint.rs b/src/hint.rs
new file mode 100644
index 0000000..c15db9c
--- /dev/null
+++ b/src/hint.rs
@@ -0,0 +1,15 @@
+//! Hints (suggestions at the right of the prompt as you type).
+
+/// Hints provider
+pub trait Hinter {
+    /// Takes the currently edited `line` with the cursor `pos`ition and
+    /// returns the string that should be displayed or `None`
+    /// if no hint is available for the text the user currently typed.
+    fn hint(&self, line: &str, pos: usize) -> Option<String>;
+}
+
+impl Hinter for () {
+    fn hint(&self, _line: &str, _pos: usize) -> Option<String> {
+        None
+    }
+}
diff --git a/src/history.rs b/src/history.rs
index e283cb4..dac738b 100644
--- a/src/history.rs
+++ b/src/history.rs
@@ -1,17 +1,18 @@
 //! History API
 
-use std::collections::VecDeque;
+#[cfg(unix)]
+use libc;
 use std::collections::vec_deque;
+use std::collections::VecDeque;
 use std::fs::File;
 use std::iter::DoubleEndedIterator;
 use std::ops::Index;
 use std::path::Path;
-#[cfg(unix)]
-use libc;
 
 use super::Result;
 use config::{Config, HistoryDuplicates};
 
+/// Search direction
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub enum Direction {
     Forward,
@@ -23,20 +24,21 @@
 pub struct History {
     entries: VecDeque<String>,
     max_len: usize,
-    ignore_space: bool,
-    ignore_dups: bool,
+    pub(crate) ignore_space: bool,
+    pub(crate) ignore_dups: bool,
 }
 
 impl History {
     pub fn new() -> History {
         Self::with_config(Config::default())
     }
+
     pub fn with_config(config: Config) -> History {
         History {
             entries: VecDeque::new(),
             max_len: config.max_history_size(),
-            ignore_space: config.history_duplicates() == HistoryDuplicates::IgnoreConsecutive,
-            ignore_dups: config.history_ignore_space(),
+            ignore_space: config.history_ignore_space(),
+            ignore_dups: config.history_duplicates() == HistoryDuplicates::IgnoreConsecutive,
         }
     }
 
@@ -55,12 +57,13 @@
         if self.max_len == 0 {
             return false;
         }
-        if line.as_ref().is_empty() ||
-           (self.ignore_space &&
-            line.as_ref()
+        if line.as_ref().is_empty()
+            || (self.ignore_space && line
+                .as_ref()
                 .chars()
                 .next()
-                .map_or(true, |c| c.is_whitespace())) {
+                .map_or(true, |c| c.is_whitespace()))
+        {
             return false;
         }
         if self.ignore_dups {
@@ -77,19 +80,23 @@
         true
     }
 
-    /// Returns the number of entries in the history.
+    /// Return the number of entries in the history.
     pub fn len(&self) -> usize {
         self.entries.len()
     }
-    /// Returns true if the history has no entry.
+
+    /// Return true if the history has no entry.
     pub fn is_empty(&self) -> bool {
         self.entries.is_empty()
     }
 
     /// Set the maximum length for the history. This function can be called even
     /// if there is already some history, the function will make sure to retain
-    /// just the latest `len` elements if the new history length value is smaller
-    /// than the amount of items already inside the history.
+    /// just the latest `len` elements if the new history length value is
+    /// smaller than the amount of items already inside the history.
+    ///
+    /// Like [stifle_history](http://cnswww.cns.cwru.
+    /// edu/php/chet/readline/history.html#IDX11).
     pub fn set_max_len(&mut self, len: usize) {
         self.max_len = len;
         if len == 0 {
@@ -105,6 +112,10 @@
     }
 
     /// Save the history in the specified file.
+    // TODO append_history
+    // http://cnswww.cns.cwru.edu/php/chet/readline/history.html#IDX30
+    // TODO history_truncate_file
+    // http://cnswww.cns.cwru.edu/php/chet/readline/history.html#IDX31
     pub fn save<P: AsRef<Path> + ?Sized>(&self, path: &P) -> Result<()> {
         use std::io::{BufWriter, Write};
 
@@ -121,13 +132,15 @@
             try!(wtr.write_all(entry.as_bytes()));
             try!(wtr.write_all(b"\n"));
         }
+        // https://github.com/rust-lang/rust/issues/32677#issuecomment-204833485
+        try!(wtr.flush());
         Ok(())
     }
 
     /// Load the history from the specified file.
     ///
-    /// # Failure
-    /// Will return `Err` if path does not already exist.
+    /// # Errors
+    /// Will return `Err` if path does not already exist or could not be read.
     pub fn load<P: AsRef<Path> + ?Sized>(&mut self, path: &P) -> Result<()> {
         use std::io::{BufRead, BufReader};
 
@@ -144,29 +157,36 @@
         self.entries.clear()
     }
 
-    /// Search history (start position inclusive [0, len-1])
-    /// Return the absolute index of the nearest history entry that matches `term`.
-    /// Return None if no entry contains `term` between [start, len -1] for forward search
+    /// Search history (start position inclusive [0, len-1]).
+    ///
+    /// Return the absolute index of the nearest history entry that matches
+    /// `term`.
+    ///
+    /// Return None if no entry contains `term` between [start, len -1] for
+    /// forward search
     /// or between [0, start] for reverse search.
     pub fn search(&self, term: &str, start: usize, dir: Direction) -> Option<usize> {
         let test = |entry: &String| entry.contains(term);
         self.search_match(term, start, dir, test)
     }
 
+    /// Anchored search
     pub fn starts_with(&self, term: &str, start: usize, dir: Direction) -> Option<usize> {
         let test = |entry: &String| entry.starts_with(term);
         self.search_match(term, start, dir, test)
     }
 
     fn search_match<F>(&self, term: &str, start: usize, dir: Direction, test: F) -> Option<usize>
-        where F: Fn(&String) -> bool
+    where
+        F: Fn(&String) -> bool,
     {
         if term.is_empty() || start >= self.len() {
             return None;
         }
         match dir {
             Direction::Reverse => {
-                let index = self.entries
+                let index = self
+                    .entries
                     .iter()
                     .rev()
                     .skip(self.entries.len() - 1 - start)
@@ -195,8 +215,8 @@
 }
 
 impl<'a> IntoIterator for &'a History {
-    type Item = &'a String;
     type IntoIter = Iter<'a>;
+    type Item = &'a String;
 
     fn into_iter(self) -> Iter<'a> {
         self.iter()
@@ -254,9 +274,9 @@
 #[cfg(test)]
 mod tests {
     extern crate tempdir;
-    use std::path::Path;
     use super::{Direction, History};
     use config::Config;
+    use std::path::Path;
 
     fn init() -> History {
         let mut history = History::new();
@@ -289,7 +309,7 @@
         let mut history = init();
         history.set_max_len(1);
         assert_eq!(1, history.entries.len());
-        assert_eq!(Some(&"line3".to_string()), history.last());
+        assert_eq!(Some(&"line3".to_owned()), history.last());
     }
 
     #[test]
diff --git a/src/keymap.rs b/src/keymap.rs
index 7141066..50f50cd 100644
--- a/src/keymap.rs
+++ b/src/keymap.rs
@@ -1,74 +1,118 @@
 //! Bindings from keys to command for Emacs and Vi modes
-use std::cell::RefCell;
 use std::collections::HashMap;
-use std::rc::Rc;
+use std::sync::{Arc, RwLock};
 
+use super::Result;
 use config::Config;
 use config::EditMode;
-use consts::KeyPress;
+use keys::KeyPress;
 use tty::RawReader;
-use super::Result;
 
+/// The number of times one command should be repeated.
 pub type RepeatCount = usize;
 
+/// Commands
+/// #[non_exhaustive]
 #[derive(Debug, Clone, PartialEq)]
 pub enum Cmd {
+    /// abort
     Abort, // Miscellaneous Command
+    /// accept-line
     AcceptLine,
+    /// beginning-of-history
     BeginningOfHistory,
+    /// capitalize-word
     CapitalizeWord,
+    /// clear-screen
     ClearScreen,
+    /// complete
     Complete,
+    /// downcase-word
     DowncaseWord,
+    /// vi-eof-maybe
     EndOfFile,
+    /// end-of-history
     EndOfHistory,
+    /// forward-search-history
     ForwardSearchHistory,
+    /// history-search-backward
     HistorySearchBackward,
+    /// history-search-forward
     HistorySearchForward,
     Insert(RepeatCount, String),
     Interrupt,
+    /// backward-delete-char, backward-kill-line, backward-kill-word
+    /// delete-char, kill-line, kill-word, unix-line-discard, unix-word-rubout,
+    /// vi-delete, vi-delete-to, vi-rubout
     Kill(Movement),
+    /// backward-char, backward-word, beginning-of-line, end-of-line,
+    /// forward-char, forward-word, vi-char-search, vi-end-word, vi-next-word,
+    /// vi-prev-word
     Move(Movement),
+    /// next-history
     NextHistory,
     Noop,
+    /// vi-replace
+    Overwrite(char),
+    /// previous-history
     PreviousHistory,
+    /// quoted-insert
     QuotedInsert,
-    Replace(RepeatCount, char),
+    /// vi-change-char
+    ReplaceChar(RepeatCount, char),
+    /// vi-change-to, vi-substitute
+    Replace(Movement, Option<String>),
+    /// reverse-search-history
     ReverseSearchHistory,
+    /// self-insert
     SelfInsert(RepeatCount, char),
     Suspend,
+    /// transpose-chars
     TransposeChars,
+    /// transpose-words
     TransposeWords(RepeatCount),
+    /// undo
+    Undo(RepeatCount),
     Unknown,
+    /// upcase-word
     UpcaseWord,
+    /// vi-yank-to
     ViYankTo(Movement),
+    /// yank, vi-put
     Yank(RepeatCount, Anchor),
+    /// yank-pop
     YankPop,
 }
 
 impl Cmd {
     pub fn should_reset_kill_ring(&self) -> bool {
         match *self {
-            Cmd::Kill(Movement::BackwardChar(_)) |
-            Cmd::Kill(Movement::ForwardChar(_)) => true,
-            Cmd::ClearScreen | Cmd::Kill(_) | Cmd::Noop | Cmd::Suspend | Cmd::Yank(_, _) |
-            Cmd::YankPop => false,
+            Cmd::Kill(Movement::BackwardChar(_)) | Cmd::Kill(Movement::ForwardChar(_)) => true,
+            Cmd::ClearScreen
+            | Cmd::Kill(_)
+            | Cmd::Replace(_, _)
+            | Cmd::Noop
+            | Cmd::Suspend
+            | Cmd::Yank(_, _)
+            | Cmd::YankPop => false,
             _ => true,
         }
     }
 
     fn is_repeatable_change(&self) -> bool {
         match *self {
-            Cmd::Insert(_, _) => true,
-            Cmd::Kill(_) => true,
-            Cmd::Replace(_, _) => true,
-            Cmd::SelfInsert(_, _) => true,
+            Cmd::Insert(_, _)
+            | Cmd::Kill(_)
+            | Cmd::ReplaceChar(_, _)
+            | Cmd::Replace(_, _)
+            | Cmd::SelfInsert(_, _)
+            | Cmd::ViYankTo(_)
+            | Cmd::Yank(_, _) => true,
             Cmd::TransposeChars => false, // TODO Validate
-            Cmd::ViYankTo(_) => true,
-            Cmd::Yank(_, _) => true,
             _ => false,
         }
     }
+
     fn is_repeatable(&self) -> bool {
         match *self {
             Cmd::Move(_) => true,
@@ -76,16 +120,41 @@
         }
     }
 
-    fn redo(&self, new: Option<RepeatCount>) -> Cmd {
+    // Replay this command with a possible different `RepeatCount`.
+    fn redo(&self, new: Option<RepeatCount>, wrt: &Refresher) -> Cmd {
         match *self {
             Cmd::Insert(previous, ref text) => {
                 Cmd::Insert(repeat_count(previous, new), text.clone())
             }
             Cmd::Kill(ref mvt) => Cmd::Kill(mvt.redo(new)),
             Cmd::Move(ref mvt) => Cmd::Move(mvt.redo(new)),
-            Cmd::Replace(previous, c) => Cmd::Replace(repeat_count(previous, new), c),
-            Cmd::SelfInsert(previous, c) => Cmd::SelfInsert(repeat_count(previous, new), c),
-            //Cmd::TransposeChars => Cmd::TransposeChars,
+            Cmd::ReplaceChar(previous, c) => Cmd::ReplaceChar(repeat_count(previous, new), c),
+            Cmd::Replace(ref mvt, ref text) => {
+                if text.is_none() {
+                    let last_insert = wrt.last_insert();
+                    if let Movement::ForwardChar(0) = mvt {
+                        Cmd::Replace(
+                            Movement::ForwardChar(
+                                last_insert.as_ref().map_or(0, |text| text.len()),
+                            ),
+                            last_insert,
+                        )
+                    } else {
+                        Cmd::Replace(mvt.redo(new), last_insert)
+                    }
+                } else {
+                    Cmd::Replace(mvt.redo(new), text.clone())
+                }
+            }
+            Cmd::SelfInsert(previous, c) => {
+                // consecutive char inserts are repeatable not only the last one...
+                if let Some(text) = wrt.last_insert() {
+                    Cmd::Insert(repeat_count(previous, new), text)
+                } else {
+                    Cmd::SelfInsert(repeat_count(previous, new), c)
+                }
+            }
+            // Cmd::TransposeChars => Cmd::TransposeChars,
             Cmd::ViYankTo(ref mvt) => Cmd::ViYankTo(mvt.redo(new)),
             Cmd::Yank(previous, anchor) => Cmd::Yank(repeat_count(previous, new), anchor),
             _ => unreachable!(),
@@ -100,16 +169,18 @@
     }
 }
 
+/// Different word definitions
 #[derive(Debug, Clone, PartialEq, Copy)]
 pub enum Word {
-    // non-blanks characters
+    /// non-blanks characters
     Big,
-    // alphanumeric characters
+    /// alphanumeric characters
     Emacs,
-    // alphanumeric (and '_') characters
+    /// alphanumeric (and '_') characters
     Vi,
 }
 
+/// Where to move with respect to word boundary
 #[derive(Debug, Clone, PartialEq, Copy)]
 pub enum At {
     Start,
@@ -117,13 +188,15 @@
     AfterEnd,
 }
 
+/// Where to paste (relative to cursor position)
 #[derive(Debug, Clone, PartialEq, Copy)]
 pub enum Anchor {
     After,
     Before,
 }
 
-#[derive(Debug, Clone, PartialEq)]
+/// Vi character search
+#[derive(Debug, Clone, PartialEq, Copy)]
 pub enum CharSearch {
     Forward(char),
     // until
@@ -134,8 +207,8 @@
 }
 
 impl CharSearch {
-    fn opposite(&self) -> CharSearch {
-        match *self {
+    fn opposite(self) -> CharSearch {
+        match self {
             CharSearch::Forward(c) => CharSearch::Backward(c),
             CharSearch::ForwardBefore(c) => CharSearch::BackwardAfter(c),
             CharSearch::Backward(c) => CharSearch::Forward(c),
@@ -144,21 +217,30 @@
     }
 }
 
-
+/// Where to move
 #[derive(Debug, Clone, PartialEq)]
 pub enum Movement {
     WholeLine, // not really a movement
+    /// beginning-of-line
     BeginningOfLine,
+    /// end-of-line
     EndOfLine,
+    /// backward-word, vi-prev-word
     BackwardWord(RepeatCount, Word), // Backward until start of word
+    /// forward-word, vi-end-word, vi-next-word
     ForwardWord(RepeatCount, At, Word), // Forward until start/end of word
+    /// vi-char-search
     ViCharSearch(RepeatCount, CharSearch),
+    /// vi-first-print
     ViFirstPrint,
+    /// backward-char
     BackwardChar(RepeatCount),
+    /// forward-char
     ForwardChar(RepeatCount),
 }
 
 impl Movement {
+    // Replay this movement with a possible different `RepeatCount`.
     fn redo(&self, new: Option<RepeatCount>) -> Movement {
         match *self {
             Movement::WholeLine => Movement::WholeLine,
@@ -171,8 +253,8 @@
             Movement::ForwardWord(previous, at, word) => {
                 Movement::ForwardWord(repeat_count(previous, new), at, word)
             }
-            Movement::ViCharSearch(previous, ref char_search) => {
-                Movement::ViCharSearch(repeat_count(previous, new), char_search.clone())
+            Movement::ViCharSearch(previous, char_search) => {
+                Movement::ViCharSearch(repeat_count(previous, new), char_search)
             }
             Movement::BackwardChar(previous) => Movement::BackwardChar(repeat_count(previous, new)),
             Movement::ForwardChar(previous) => Movement::ForwardChar(repeat_count(previous, new)),
@@ -180,27 +262,52 @@
     }
 }
 
-pub struct EditState {
+#[derive(PartialEq)]
+enum InputMode {
+    /// Vi Command/Alternate
+    Command,
+    /// Insert/Input mode
+    Insert,
+    /// Overwrite mode
+    Replace,
+}
+
+/// Tranform key(s) to commands based on current input mode
+pub struct InputState {
     mode: EditMode,
-    custom_bindings: Rc<RefCell<HashMap<KeyPress, Cmd>>>,
-    // Vi Command/Alternate, Insert/Input mode
-    insert: bool, // vi only ?
+    custom_bindings: Arc<RwLock<HashMap<KeyPress, Cmd>>>,
+    input_mode: InputMode, // vi only ?
     // numeric arguments: http://web.mit.edu/gnu/doc/html/rlman_1.html#SEC7
     num_args: i16,
-    last_cmd: Cmd, // vi only
-    consecutive_insert: bool,
+    last_cmd: Cmd,                        // vi only
     last_char_search: Option<CharSearch>, // vi only
 }
 
-impl EditState {
-    pub fn new(config: &Config, custom_bindings: Rc<RefCell<HashMap<KeyPress, Cmd>>>) -> EditState {
-        EditState {
+pub trait Refresher {
+    /// Rewrite the currently edited line accordingly to the buffer content,
+    /// cursor position, and number of columns of the terminal.
+    fn refresh_line(&mut self) -> Result<()>;
+    /// Same as `refresh_line` but with a dynamic prompt.
+    fn refresh_prompt_and_line(&mut self, prompt: &str) -> Result<()>;
+    /// Vi only, switch to insert mode.
+    fn doing_insert(&mut self);
+    /// Vi only, switch to command mode.
+    fn done_inserting(&mut self);
+    /// Vi only, last text inserted.
+    fn last_insert(&self) -> Option<String>;
+}
+
+impl InputState {
+    pub fn new(
+        config: &Config,
+        custom_bindings: Arc<RwLock<HashMap<KeyPress, Cmd>>>,
+    ) -> InputState {
+        InputState {
             mode: config.edit_mode(),
-            custom_bindings: custom_bindings,
-            insert: true,
+            custom_bindings,
+            input_mode: InputMode::Insert,
             num_args: 0,
             last_cmd: Cmd::Noop,
-            consecutive_insert: false,
             last_char_search: None,
         }
     }
@@ -209,16 +316,29 @@
         self.mode == EditMode::Emacs
     }
 
-    pub fn next_cmd<R: RawReader>(&mut self, rdr: &mut R) -> Result<Cmd> {
+    /// Parse user input into one command
+    /// `single_esc_abort` is used in emacs mode on unix platform when a single
+    /// esc key is expected to abort current action.
+    pub fn next_cmd<R: RawReader>(
+        &mut self,
+        rdr: &mut R,
+        wrt: &mut Refresher,
+        single_esc_abort: bool,
+    ) -> Result<Cmd> {
         match self.mode {
-            EditMode::Emacs => self.emacs(rdr),
-            EditMode::Vi if self.insert => self.vi_insert(rdr),
-            EditMode::Vi => self.vi_command(rdr),
+            EditMode::Emacs => self.emacs(rdr, wrt, single_esc_abort),
+            EditMode::Vi if self.input_mode != InputMode::Command => self.vi_insert(rdr, wrt),
+            EditMode::Vi => self.vi_command(rdr, wrt),
         }
     }
 
     // TODO dynamic prompt (arg: ?)
-    fn emacs_digit_argument<R: RawReader>(&mut self, rdr: &mut R, digit: char) -> Result<KeyPress> {
+    fn emacs_digit_argument<R: RawReader>(
+        &mut self,
+        rdr: &mut R,
+        wrt: &mut Refresher,
+        digit: char,
+    ) -> Result<KeyPress> {
         match digit {
             '0'...'9' => {
                 self.num_args = digit.to_digit(10).unwrap() as i16;
@@ -229,38 +349,52 @@
             _ => unreachable!(),
         }
         loop {
-            let key = try!(rdr.next_key());
+            try!(wrt.refresh_prompt_and_line(&format!("(arg: {}) ", self.num_args)));
+            let key = try!(rdr.next_key(true));
             match key {
-                KeyPress::Char(digit @ '0'...'9') |
-                KeyPress::Meta(digit @ '0'...'9') => {
+                KeyPress::Char(digit @ '0'...'9') | KeyPress::Meta(digit @ '0'...'9') => {
                     if self.num_args == -1 {
                         self.num_args *= digit.to_digit(10).unwrap() as i16;
-                    } else {
-                        self.num_args = self.num_args
+                    } else if self.num_args.abs() < 1000 {
+                        // shouldn't ever need more than 4 digits
+                        self.num_args = self
+                            .num_args
                             .saturating_mul(10)
                             .saturating_add(digit.to_digit(10).unwrap() as i16);
                     }
                 }
-                _ => return Ok(key),
+                KeyPress::Char('-') | KeyPress::Meta('-') => {}
+                _ => {
+                    try!(wrt.refresh_line());
+                    return Ok(key);
+                }
             };
         }
     }
 
-    fn emacs<R: RawReader>(&mut self, rdr: &mut R) -> Result<Cmd> {
-        let mut key = try!(rdr.next_key());
+    fn emacs<R: RawReader>(
+        &mut self,
+        rdr: &mut R,
+        wrt: &mut Refresher,
+        single_esc_abort: bool,
+    ) -> Result<Cmd> {
+        let mut key = try!(rdr.next_key(single_esc_abort));
         if let KeyPress::Meta(digit @ '-') = key {
-            key = try!(self.emacs_digit_argument(rdr, digit));
+            key = try!(self.emacs_digit_argument(rdr, wrt, digit));
         } else if let KeyPress::Meta(digit @ '0'...'9') = key {
-            key = try!(self.emacs_digit_argument(rdr, digit));
+            key = try!(self.emacs_digit_argument(rdr, wrt, digit));
         }
         let (n, positive) = self.emacs_num_args(); // consume them in all cases
-        if let Some(cmd) = self.custom_bindings.borrow().get(&key) {
-            debug!(target: "rustyline", "Custom command: {:?}", cmd);
-            return Ok(if cmd.is_repeatable() {
-                          cmd.redo(Some(n))
-                      } else {
-                          cmd.clone()
-                      });
+        {
+            let bindings = self.custom_bindings.read().unwrap();
+            if let Some(cmd) = bindings.get(&key) {
+                debug!(target: "rustyline", "Custom command: {:?}", cmd);
+                return Ok(if cmd.is_repeatable() {
+                    cmd.redo(Some(n), wrt)
+                } else {
+                    cmd.clone()
+                });
+            }
         }
         let cmd = match key {
             KeyPress::Char(c) => {
@@ -286,10 +420,8 @@
                     Cmd::Move(Movement::BackwardChar(n))
                 }
             }
-            KeyPress::Ctrl('G') |
-            KeyPress::Esc => Cmd::Abort,
-            KeyPress::Ctrl('H') |
-            KeyPress::Backspace => {
+            KeyPress::Ctrl('G') | KeyPress::Esc | KeyPress::Meta('\x07') => Cmd::Abort,
+            KeyPress::Ctrl('H') | KeyPress::Backspace => {
                 if positive {
                     Cmd::Kill(Movement::BackwardChar(n))
                 } else {
@@ -307,8 +439,15 @@
             KeyPress::Ctrl('L') => Cmd::ClearScreen,
             KeyPress::Ctrl('N') => Cmd::NextHistory,
             KeyPress::Ctrl('P') => Cmd::PreviousHistory,
-            KeyPress::Meta('\x08') |
-            KeyPress::Meta('\x7f') => {
+            KeyPress::Ctrl('X') => {
+                let snd_key = try!(rdr.next_key(true));
+                match snd_key {
+                    KeyPress::Ctrl('G') | KeyPress::Esc => Cmd::Abort,
+                    KeyPress::Ctrl('U') => Cmd::Undo(n),
+                    _ => Cmd::Unknown,
+                }
+            }
+            KeyPress::Meta('\x08') | KeyPress::Meta('\x7f') => {
                 if positive {
                     Cmd::Kill(Movement::BackwardWord(n, Word::Emacs))
                 } else {
@@ -317,110 +456,125 @@
             }
             KeyPress::Meta('<') => Cmd::BeginningOfHistory,
             KeyPress::Meta('>') => Cmd::EndOfHistory,
-            KeyPress::Meta('B') => {
+            KeyPress::Meta('B') | KeyPress::Meta('b') => {
                 if positive {
                     Cmd::Move(Movement::BackwardWord(n, Word::Emacs))
                 } else {
                     Cmd::Move(Movement::ForwardWord(n, At::AfterEnd, Word::Emacs))
                 }
             }
-            KeyPress::Meta('C') => Cmd::CapitalizeWord,
-            KeyPress::Meta('D') => {
+            KeyPress::Meta('C') | KeyPress::Meta('c') => Cmd::CapitalizeWord,
+            KeyPress::Meta('D') | KeyPress::Meta('d') => {
                 if positive {
                     Cmd::Kill(Movement::ForwardWord(n, At::AfterEnd, Word::Emacs))
                 } else {
                     Cmd::Kill(Movement::BackwardWord(n, Word::Emacs))
                 }
             }
-            KeyPress::Meta('F') => {
+            KeyPress::Meta('F') | KeyPress::Meta('f') => {
                 if positive {
                     Cmd::Move(Movement::ForwardWord(n, At::AfterEnd, Word::Emacs))
                 } else {
                     Cmd::Move(Movement::BackwardWord(n, Word::Emacs))
                 }
             }
-            KeyPress::Meta('L') => Cmd::DowncaseWord,
-            KeyPress::Meta('T') => Cmd::TransposeWords(n),
-            KeyPress::Meta('U') => Cmd::UpcaseWord,
-            KeyPress::Meta('Y') => Cmd::YankPop,
+            KeyPress::Meta('L') | KeyPress::Meta('l') => Cmd::DowncaseWord,
+            KeyPress::Meta('T') | KeyPress::Meta('t') => Cmd::TransposeWords(n),
+            KeyPress::Meta('U') | KeyPress::Meta('u') => Cmd::UpcaseWord,
+            KeyPress::Meta('Y') | KeyPress::Meta('y') => Cmd::YankPop,
             _ => self.common(key, n, positive),
         };
         debug!(target: "rustyline", "Emacs command: {:?}", cmd);
         Ok(cmd)
     }
 
-    fn vi_arg_digit<R: RawReader>(&mut self, rdr: &mut R, digit: char) -> Result<KeyPress> {
+    fn vi_arg_digit<R: RawReader>(
+        &mut self,
+        rdr: &mut R,
+        wrt: &mut Refresher,
+        digit: char,
+    ) -> Result<KeyPress> {
         self.num_args = digit.to_digit(10).unwrap() as i16;
         loop {
-            let key = try!(rdr.next_key());
-            match key {
-                KeyPress::Char(digit @ '0'...'9') => {
-                    self.num_args = self.num_args
+            try!(wrt.refresh_prompt_and_line(&format!("(arg: {}) ", self.num_args)));
+            let key = try!(rdr.next_key(false));
+            if let KeyPress::Char(digit @ '0'...'9') = key {
+                if self.num_args.abs() < 1000 {
+                    // shouldn't ever need more than 4 digits
+                    self.num_args = self
+                        .num_args
                         .saturating_mul(10)
                         .saturating_add(digit.to_digit(10).unwrap() as i16);
                 }
-                _ => return Ok(key),
+            } else {
+                try!(wrt.refresh_line());
+                return Ok(key);
             };
         }
     }
 
-    fn vi_command<R: RawReader>(&mut self, rdr: &mut R) -> Result<Cmd> {
-        let mut key = try!(rdr.next_key());
+    fn vi_command<R: RawReader>(&mut self, rdr: &mut R, wrt: &mut Refresher) -> Result<Cmd> {
+        let mut key = try!(rdr.next_key(false));
         if let KeyPress::Char(digit @ '1'...'9') = key {
-            key = try!(self.vi_arg_digit(rdr, digit));
+            key = try!(self.vi_arg_digit(rdr, wrt, digit));
         }
         let no_num_args = self.num_args == 0;
         let n = self.vi_num_args(); // consume them in all cases
-        if let Some(cmd) = self.custom_bindings.borrow().get(&key) {
-            debug!(target: "rustyline", "Custom command: {:?}", cmd);
-            return Ok(if cmd.is_repeatable() {
-                          if no_num_args {
-                              cmd.redo(None)
-                          } else {
-                              cmd.redo(Some(n))
-                          }
-                      } else {
-                          cmd.clone()
-                      });
+        {
+            let bindings = self.custom_bindings.read().unwrap();
+            if let Some(cmd) = bindings.get(&key) {
+                debug!(target: "rustyline", "Custom command: {:?}", cmd);
+                return Ok(if cmd.is_repeatable() {
+                    if no_num_args {
+                        cmd.redo(None, wrt)
+                    } else {
+                        cmd.redo(Some(n), wrt)
+                    }
+                } else {
+                    cmd.clone()
+                });
+            }
         }
         let cmd = match key {
             KeyPress::Char('$') |
             KeyPress::End => Cmd::Move(Movement::EndOfLine),
-            KeyPress::Char('.') => { // vi-redo
+            KeyPress::Char('.') => { // vi-redo (repeat last command)
                 if no_num_args {
-                    self.last_cmd.redo(None)
+                    self.last_cmd.redo(None, wrt)
                 } else {
-                    self.last_cmd.redo(Some(n))
+                    self.last_cmd.redo(Some(n), wrt)
                 }
             },
             // TODO KeyPress::Char('%') => Cmd::???, Move to the corresponding opening/closing bracket
             KeyPress::Char('0') => Cmd::Move(Movement::BeginningOfLine),
             KeyPress::Char('^') => Cmd::Move(Movement::ViFirstPrint),
             KeyPress::Char('a') => {
-                // vi-append-mode: Vi enter insert mode after the cursor.
-                self.insert = true;
+                // vi-append-mode
+                self.input_mode = InputMode::Insert;
+                wrt.doing_insert();
                 Cmd::Move(Movement::ForwardChar(n))
             }
             KeyPress::Char('A') => {
-                // vi-append-eol: Vi enter insert mode at end of line.
-                self.insert = true;
+                // vi-append-eol
+                self.input_mode = InputMode::Insert;
+                wrt.doing_insert();
                 Cmd::Move(Movement::EndOfLine)
             }
             KeyPress::Char('b') => Cmd::Move(Movement::BackwardWord(n, Word::Vi)), // vi-prev-word
             KeyPress::Char('B') => Cmd::Move(Movement::BackwardWord(n, Word::Big)),
             KeyPress::Char('c') => {
-                self.insert = true;
-                match try!(self.vi_cmd_motion(rdr, key, n)) {
-                    Some(mvt) => Cmd::Kill(mvt),
+                self.input_mode = InputMode::Insert;
+                match try!(self.vi_cmd_motion(rdr, wrt, key, n)) {
+                    Some(mvt) => Cmd::Replace(mvt, None),
                     None => Cmd::Unknown,
                 }
             }
             KeyPress::Char('C') => {
-                self.insert = true;
-                Cmd::Kill(Movement::EndOfLine)
+                self.input_mode = InputMode::Insert;
+                Cmd::Replace(Movement::EndOfLine, None)
             }
             KeyPress::Char('d') => {
-                match try!(self.vi_cmd_motion(rdr, key, n)) {
+                match try!(self.vi_cmd_motion(rdr, wrt, key, n)) {
                     Some(mvt) => Cmd::Kill(mvt),
                     None => Cmd::Unknown,
                 }
@@ -431,12 +585,14 @@
             KeyPress::Char('E') => Cmd::Move(Movement::ForwardWord(n, At::BeforeEnd, Word::Big)),
             KeyPress::Char('i') => {
                 // vi-insertion-mode
-                self.insert = true;
+                self.input_mode = InputMode::Insert;
+                wrt.doing_insert();
                 Cmd::Noop
             }
             KeyPress::Char('I') => {
                 // vi-insert-beg
-                self.insert = true;
+                self.input_mode = InputMode::Insert;
+                wrt.doing_insert();
                 Cmd::Move(Movement::BeginningOfLine)
             }
             KeyPress::Char(c) if c == 'f' || c == 'F' || c == 't' || c == 'T' => {
@@ -449,7 +605,7 @@
             }
             KeyPress::Char(';') => {
                 match self.last_char_search {
-                    Some(ref cs) => Cmd::Move(Movement::ViCharSearch(n, cs.clone())),
+                    Some(cs) => Cmd::Move(Movement::ViCharSearch(n, cs)),
                     None => Cmd::Noop,
                 }
             }
@@ -463,32 +619,37 @@
             KeyPress::Char('p') => Cmd::Yank(n, Anchor::After), // vi-put
             KeyPress::Char('P') => Cmd::Yank(n, Anchor::Before), // vi-put
             KeyPress::Char('r') => {
-                // vi-replace-char: Vi replace character under the cursor with the next character typed.
-                let ch = try!(rdr.next_key());
+                // vi-replace-char:
+                let ch = try!(rdr.next_key(false));
                 match ch {
-                    KeyPress::Char(c) => Cmd::Replace(n, c),
+                    KeyPress::Char(c) => Cmd::ReplaceChar(n, c),
                     KeyPress::Esc => Cmd::Noop,
                     _ => Cmd::Unknown,
                 }
             }
-            // TODO KeyPress::Char('R') => Cmd::???, vi-replace-mode: Vi enter replace mode. Replaces characters under the cursor. (overwrite-mode)
+            KeyPress::Char('R') => {
+                //  vi-replace-mode (overwrite-mode)
+                self.input_mode = InputMode::Replace;
+                Cmd::Replace(Movement::ForwardChar(0), None)
+            }
             KeyPress::Char('s') => {
-                // vi-substitute-char: Vi replace character under the cursor and enter insert mode.
-                self.insert = true;
-                Cmd::Kill(Movement::ForwardChar(n))
+                // vi-substitute-char:
+                self.input_mode = InputMode::Insert;
+                Cmd::Replace(Movement::ForwardChar(n), None)
             }
             KeyPress::Char('S') => {
-                // vi-substitute-line: Vi substitute entire line.
-                self.insert = true;
-                Cmd::Kill(Movement::WholeLine)
+                // vi-substitute-line:
+                self.input_mode = InputMode::Insert;
+                Cmd::Replace(Movement::WholeLine, None)
             }
+            KeyPress::Char('u') => Cmd::Undo(n),
             // KeyPress::Char('U') => Cmd::???, // revert-line
             KeyPress::Char('w') => Cmd::Move(Movement::ForwardWord(n, At::Start, Word::Vi)), // vi-next-word
             KeyPress::Char('W') => Cmd::Move(Movement::ForwardWord(n, At::Start, Word::Big)), // vi-next-word
             KeyPress::Char('x') => Cmd::Kill(Movement::ForwardChar(n)), // vi-delete: TODO move backward if eol
             KeyPress::Char('X') => Cmd::Kill(Movement::BackwardChar(n)), // vi-rubout
             KeyPress::Char('y') => {
-                match try!(self.vi_cmd_motion(rdr, key, n)) {
+                match try!(self.vi_cmd_motion(rdr, wrt, key, n)) {
                     Some(mvt) => Cmd::ViYankTo(mvt),
                     None => Cmd::Unknown,
                 }
@@ -508,11 +669,11 @@
             KeyPress::Char('k') | // TODO: move to the start of the line.
             KeyPress::Ctrl('P') => Cmd::PreviousHistory,
             KeyPress::Ctrl('R') => {
-                self.insert = true; // TODO Validate
+                self.input_mode = InputMode::Insert; // TODO Validate
                 Cmd::ReverseSearchHistory
             }
             KeyPress::Ctrl('S') => {
-                self.insert = true; // TODO Validate
+                self.input_mode = InputMode::Insert; // TODO Validate
                 Cmd::ForwardSearchHistory
             }
             KeyPress::Esc => Cmd::Noop,
@@ -520,130 +681,139 @@
         };
         debug!(target: "rustyline", "Vi command: {:?}", cmd);
         if cmd.is_repeatable_change() {
-            self.update_last_cmd(cmd.clone());
+            self.last_cmd = cmd.clone();
         }
         Ok(cmd)
     }
 
-    fn vi_insert<R: RawReader>(&mut self, rdr: &mut R) -> Result<Cmd> {
-        let key = try!(rdr.next_key());
-        if let Some(cmd) = self.custom_bindings.borrow().get(&key) {
-            debug!(target: "rustyline", "Custom command: {:?}", cmd);
-            return Ok(if cmd.is_repeatable() {
-                          cmd.redo(None)
-                      } else {
-                          cmd.clone()
-                      });
+    fn vi_insert<R: RawReader>(&mut self, rdr: &mut R, wrt: &mut Refresher) -> Result<Cmd> {
+        let key = try!(rdr.next_key(false));
+        {
+            let bindings = self.custom_bindings.read().unwrap();
+            if let Some(cmd) = bindings.get(&key) {
+                debug!(target: "rustyline", "Custom command: {:?}", cmd);
+                return Ok(if cmd.is_repeatable() {
+                    cmd.redo(None, wrt)
+                } else {
+                    cmd.clone()
+                });
+            }
         }
         let cmd = match key {
-            KeyPress::Char(c) => Cmd::SelfInsert(1, c),
-            KeyPress::Ctrl('H') |
-            KeyPress::Backspace => Cmd::Kill(Movement::BackwardChar(1)),
+            KeyPress::Char(c) => {
+                if self.input_mode == InputMode::Replace {
+                    Cmd::Overwrite(c)
+                } else {
+                    Cmd::SelfInsert(1, c)
+                }
+            }
+            KeyPress::Ctrl('H') | KeyPress::Backspace => Cmd::Kill(Movement::BackwardChar(1)),
             KeyPress::Tab => Cmd::Complete,
             KeyPress::Esc => {
-                // vi-movement-mode/vi-command-mode: Vi enter command mode (use alternative key bindings).
-                self.insert = false;
+                // vi-movement-mode/vi-command-mode
+                self.input_mode = InputMode::Command;
+                wrt.done_inserting();
                 Cmd::Move(Movement::BackwardChar(1))
             }
             _ => self.common(key, 1, true),
         };
         debug!(target: "rustyline", "Vi insert: {:?}", cmd);
         if cmd.is_repeatable_change() {
-            self.update_last_cmd(cmd.clone());
+            if let (Cmd::Replace(_, _), Cmd::SelfInsert(_, _)) = (&self.last_cmd, &cmd) {
+                // replacing...
+            } else if let (Cmd::SelfInsert(_, _), Cmd::SelfInsert(_, _)) = (&self.last_cmd, &cmd) {
+                // inserting...
+            } else {
+                self.last_cmd = cmd.clone();
+            }
         }
-        self.consecutive_insert = match cmd {
-            Cmd::SelfInsert(_, _) => true,
-            _ => false,
-        };
         Ok(cmd)
     }
 
-    fn vi_cmd_motion<R: RawReader>(&mut self,
-                                   rdr: &mut R,
-                                   key: KeyPress,
-                                   n: RepeatCount)
-                                   -> Result<Option<Movement>> {
-        let mut mvt = try!(rdr.next_key());
+    fn vi_cmd_motion<R: RawReader>(
+        &mut self,
+        rdr: &mut R,
+        wrt: &mut Refresher,
+        key: KeyPress,
+        n: RepeatCount,
+    ) -> Result<Option<Movement>> {
+        let mut mvt = try!(rdr.next_key(false));
         if mvt == key {
             return Ok(Some(Movement::WholeLine));
         }
         let mut n = n;
         if let KeyPress::Char(digit @ '1'...'9') = mvt {
             // vi-arg-digit
-            mvt = try!(self.vi_arg_digit(rdr, digit));
+            mvt = try!(self.vi_arg_digit(rdr, wrt, digit));
             n = self.vi_num_args().saturating_mul(n);
         }
         Ok(match mvt {
-               KeyPress::Char('$') => Some(Movement::EndOfLine), // vi-change-to-eol: Vi change to end of line.
-               KeyPress::Char('0') => Some(Movement::BeginningOfLine), // vi-kill-line-prev: Vi cut from beginning of line to cursor.
-               KeyPress::Char('^') => Some(Movement::ViFirstPrint),
-               KeyPress::Char('b') => Some(Movement::BackwardWord(n, Word::Vi)),
-               KeyPress::Char('B') => Some(Movement::BackwardWord(n, Word::Big)),
-               KeyPress::Char('e') => Some(Movement::ForwardWord(n, At::AfterEnd, Word::Vi)),
-               KeyPress::Char('E') => Some(Movement::ForwardWord(n, At::AfterEnd, Word::Big)),
-               KeyPress::Char(c) if c == 'f' || c == 'F' || c == 't' || c == 'T' => {
-            let cs = try!(self.vi_char_search(rdr, c));
-            match cs {
+            KeyPress::Char('$') => Some(Movement::EndOfLine),
+            KeyPress::Char('0') => Some(Movement::BeginningOfLine),
+            KeyPress::Char('^') => Some(Movement::ViFirstPrint),
+            KeyPress::Char('b') => Some(Movement::BackwardWord(n, Word::Vi)),
+            KeyPress::Char('B') => Some(Movement::BackwardWord(n, Word::Big)),
+            KeyPress::Char('e') => Some(Movement::ForwardWord(n, At::AfterEnd, Word::Vi)),
+            KeyPress::Char('E') => Some(Movement::ForwardWord(n, At::AfterEnd, Word::Big)),
+            KeyPress::Char(c) if c == 'f' || c == 'F' || c == 't' || c == 'T' => {
+                let cs = try!(self.vi_char_search(rdr, c));
+                match cs {
+                    Some(cs) => Some(Movement::ViCharSearch(n, cs)),
+                    None => None,
+                }
+            }
+            KeyPress::Char(';') => match self.last_char_search {
                 Some(cs) => Some(Movement::ViCharSearch(n, cs)),
                 None => None,
+            },
+            KeyPress::Char(',') => match self.last_char_search {
+                Some(ref cs) => Some(Movement::ViCharSearch(n, cs.opposite())),
+                None => None,
+            },
+            KeyPress::Char('h') | KeyPress::Ctrl('H') | KeyPress::Backspace => {
+                Some(Movement::BackwardChar(n))
             }
-        }
-               KeyPress::Char(';') => {
-                   match self.last_char_search {
-                       Some(ref cs) => Some(Movement::ViCharSearch(n, cs.clone())),
-                       None => None,
-                   }
-               }
-               KeyPress::Char(',') => {
-                   match self.last_char_search {
-                       Some(ref cs) => Some(Movement::ViCharSearch(n, cs.opposite())),
-                       None => None,
-                   }
-               }
-               KeyPress::Char('h') |
-               KeyPress::Ctrl('H') |
-               KeyPress::Backspace => Some(Movement::BackwardChar(n)), // vi-delete-prev-char: Vi move to previous character (backspace).
-               KeyPress::Char('l') |
-               KeyPress::Char(' ') => Some(Movement::ForwardChar(n)),
-               KeyPress::Char('w') => {
-            // 'cw' is 'ce'
-            if key == KeyPress::Char('c') {
-                Some(Movement::ForwardWord(n, At::AfterEnd, Word::Vi))
-            } else {
-                Some(Movement::ForwardWord(n, At::Start, Word::Vi))
+            KeyPress::Char('l') | KeyPress::Char(' ') => Some(Movement::ForwardChar(n)),
+            KeyPress::Char('w') => {
+                // 'cw' is 'ce'
+                if key == KeyPress::Char('c') {
+                    Some(Movement::ForwardWord(n, At::AfterEnd, Word::Vi))
+                } else {
+                    Some(Movement::ForwardWord(n, At::Start, Word::Vi))
+                }
             }
-        }
-               KeyPress::Char('W') => {
-            // 'cW' is 'cE'
-            if key == KeyPress::Char('c') {
-                Some(Movement::ForwardWord(n, At::AfterEnd, Word::Big))
-            } else {
-                Some(Movement::ForwardWord(n, At::Start, Word::Big))
+            KeyPress::Char('W') => {
+                // 'cW' is 'cE'
+                if key == KeyPress::Char('c') {
+                    Some(Movement::ForwardWord(n, At::AfterEnd, Word::Big))
+                } else {
+                    Some(Movement::ForwardWord(n, At::Start, Word::Big))
+                }
             }
-        }
-               _ => None,
-           })
+            _ => None,
+        })
     }
 
-    fn vi_char_search<R: RawReader>(&mut self,
-                                    rdr: &mut R,
-                                    cmd: char)
-                                    -> Result<Option<CharSearch>> {
-        let ch = try!(rdr.next_key());
+    fn vi_char_search<R: RawReader>(
+        &mut self,
+        rdr: &mut R,
+        cmd: char,
+    ) -> Result<Option<CharSearch>> {
+        let ch = try!(rdr.next_key(false));
         Ok(match ch {
-               KeyPress::Char(ch) => {
-            let cs = match cmd {
-                'f' => CharSearch::Forward(ch),
-                't' => CharSearch::ForwardBefore(ch),
-                'F' => CharSearch::Backward(ch),
-                'T' => CharSearch::BackwardAfter(ch),
-                _ => unreachable!(),
-            };
-            self.last_char_search = Some(cs.clone());
-            Some(cs)
-        }
-               _ => None,
-           })
+            KeyPress::Char(ch) => {
+                let cs = match cmd {
+                    'f' => CharSearch::Forward(ch),
+                    't' => CharSearch::ForwardBefore(ch),
+                    'F' => CharSearch::Backward(ch),
+                    'T' => CharSearch::BackwardAfter(ch),
+                    _ => unreachable!(),
+                };
+                self.last_char_search = Some(cs);
+                Some(cs)
+            }
+            _ => None,
+        })
     }
 
     fn common(&mut self, key: KeyPress, n: RepeatCount, positive: bool) -> Cmd {
@@ -682,9 +852,9 @@
             KeyPress::Ctrl('T') => Cmd::TransposeChars,
             KeyPress::Ctrl('U') => {
                 if positive {
-                Cmd::Kill(Movement::BeginningOfLine)
+                    Cmd::Kill(Movement::BeginningOfLine)
                 } else {
-                Cmd::Kill(Movement::EndOfLine)
+                    Cmd::Kill(Movement::EndOfLine)
                 }
             },
             KeyPress::Ctrl('Q') | // most terminals override Ctrl+Q to resume execution
@@ -704,6 +874,7 @@
                 }
             }
             KeyPress::Ctrl('Z') => Cmd::Suspend,
+            KeyPress::Ctrl('_') => Cmd::Undo(n),
             KeyPress::UnknownEscSeq => Cmd::Noop,
             _ => Cmd::Unknown,
         }
@@ -739,26 +910,4 @@
             num_args.abs() as RepeatCount
         }
     }
-
-    fn update_last_cmd(&mut self, new: Cmd) {
-        // consecutive char inserts are repeatable not only the last one...
-        if !self.consecutive_insert {
-            self.last_cmd = new;
-        } else if let Cmd::SelfInsert(_, c) = new {
-            match self.last_cmd {
-                Cmd::SelfInsert(_, pc) => {
-                    let mut text = String::new();
-                    text.push(pc);
-                    text.push(c);
-                    self.last_cmd = Cmd::Insert(1, text);
-                }
-                Cmd::Insert(_, ref mut text) => {
-                    text.push(c);
-                }
-                _ => self.last_cmd = new,
-            }
-        } else {
-            self.last_cmd = new;
-        }
-    }
 }
diff --git a/src/consts.rs b/src/keys.rs
similarity index 69%
rename from src/consts.rs
rename to src/keys.rs
index aadac84..c355e5a 100644
--- a/src/consts.rs
+++ b/src/keys.rs
@@ -1,34 +1,46 @@
 //! Key constants
 
+/// #[non_exhaustive]
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub enum KeyPress {
     UnknownEscSeq,
-    Backspace,
+    Backspace, // Ctrl('H')
+    BackTab,
     Char(char),
+    ControlDown,
+    ControlLeft,
+    ControlRight,
+    ControlUp,
     Ctrl(char),
     Delete,
     Down,
     End,
     Enter, // Ctrl('M')
-    Esc,
+    Esc,   // Ctrl('[')
+    F(u8),
     Home,
+    Insert,
     Left,
     Meta(char),
     Null,
     PageDown,
     PageUp,
     Right,
+    ShiftDown,
+    ShiftLeft,
+    ShiftRight,
+    ShiftUp,
     Tab, // Ctrl('I')
     Up,
 }
 
-#[allow(match_same_arms)]
+//#[allow(clippy::match_same_arms)]
 pub fn char_to_key_press(c: char) -> KeyPress {
     if !c.is_control() {
         return KeyPress::Char(c);
     }
     match c {
-        '\x00' => KeyPress::Null,
+        '\x00' => KeyPress::Ctrl(' '),
         '\x01' => KeyPress::Ctrl('A'),
         '\x02' => KeyPress::Ctrl('B'),
         '\x03' => KeyPress::Ctrl('C'),
@@ -37,12 +49,13 @@
         '\x06' => KeyPress::Ctrl('F'),
         '\x07' => KeyPress::Ctrl('G'),
         '\x08' => KeyPress::Backspace, // '\b'
-        '\x09' => KeyPress::Tab,
+        '\x09' => KeyPress::Tab,       // '\t'
         '\x0a' => KeyPress::Ctrl('J'), // '\n' (10)
         '\x0b' => KeyPress::Ctrl('K'),
         '\x0c' => KeyPress::Ctrl('L'),
         '\x0d' => KeyPress::Enter, // '\r' (13)
         '\x0e' => KeyPress::Ctrl('N'),
+        '\x0f' => KeyPress::Ctrl('O'),
         '\x10' => KeyPress::Ctrl('P'),
         '\x12' => KeyPress::Ctrl('R'),
         '\x13' => KeyPress::Ctrl('S'),
@@ -50,10 +63,15 @@
         '\x15' => KeyPress::Ctrl('U'),
         '\x16' => KeyPress::Ctrl('V'),
         '\x17' => KeyPress::Ctrl('W'),
+        '\x18' => KeyPress::Ctrl('X'),
         '\x19' => KeyPress::Ctrl('Y'),
         '\x1a' => KeyPress::Ctrl('Z'),
-        '\x1b' => KeyPress::Esc,
-        '\x7f' => KeyPress::Backspace,
+        '\x1b' => KeyPress::Esc, // Ctrl-[
+        '\x1c' => KeyPress::Ctrl('\\'),
+        '\x1d' => KeyPress::Ctrl(']'),
+        '\x1e' => KeyPress::Ctrl('^'),
+        '\x1f' => KeyPress::Ctrl('_'),
+        '\x7f' => KeyPress::Backspace, // Rubout
         _ => KeyPress::Null,
     }
 }
diff --git a/src/kill_ring.rs b/src/kill_ring.rs
index 635cb4f..03a202f 100644
--- a/src/kill_ring.rs
+++ b/src/kill_ring.rs
@@ -1,4 +1,5 @@
-//! Kill Ring
+//! Kill Ring management
+use line_buffer::{DeleteListener, Direction};
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
 enum Action {
@@ -19,6 +20,7 @@
     index: usize,
     // whether or not the last command was a kill or a yank
     last_action: Action,
+    killing: bool,
 }
 
 impl KillRing {
@@ -28,6 +30,7 @@
             slots: Vec::with_capacity(size),
             index: 0,
             last_action: Action::Other,
+            killing: false,
         }
     }
 
@@ -38,34 +41,31 @@
 
     /// Add `text` to the kill-ring.
     pub fn kill(&mut self, text: &str, dir: Mode) {
-        match self.last_action {
-            Action::Kill => {
-                if self.slots.capacity() == 0 {
-                    // disabled
-                    return;
-                }
-                match dir {
-                    Mode::Append => self.slots[self.index].push_str(text),
-                    Mode::Prepend => self.slots[self.index].insert_str(0, text),
-                };
+        if let Action::Kill = self.last_action {
+            if self.slots.capacity() == 0 {
+                // disabled
+                return;
             }
-            _ => {
-                self.last_action = Action::Kill;
-                if self.slots.capacity() == 0 {
-                    // disabled
-                    return;
-                }
-                if self.index == self.slots.capacity() - 1 {
-                    // full
-                    self.index = 0;
-                } else if !self.slots.is_empty() {
-                    self.index += 1;
-                }
-                if self.index == self.slots.len() {
-                    self.slots.push(String::from(text))
-                } else {
-                    self.slots[self.index] = String::from(text);
-                }
+            match dir {
+                Mode::Append => self.slots[self.index].push_str(text),
+                Mode::Prepend => self.slots[self.index].insert_str(0, text),
+            };
+        } else {
+            self.last_action = Action::Kill;
+            if self.slots.capacity() == 0 {
+                // disabled
+                return;
+            }
+            if self.index == self.slots.capacity() - 1 {
+                // full
+                self.index = 0;
+            } else if !self.slots.is_empty() {
+                self.index += 1;
+            }
+            if self.index == self.slots.len() {
+                self.slots.push(String::from(text))
+            } else {
+                self.slots[self.index] = String::from(text);
             }
         }
     }
@@ -102,9 +102,30 @@
     }
 }
 
+impl DeleteListener for KillRing {
+    fn start_killing(&mut self) {
+        self.killing = true;
+    }
+
+    fn delete(&mut self, _: usize, string: &str, dir: Direction) {
+        if !self.killing {
+            return;
+        }
+        let mode = match dir {
+            Direction::Forward => Mode::Append,
+            Direction::Backward => Mode::Prepend,
+        };
+        self.kill(string, mode);
+    }
+
+    fn stop_killing(&mut self) {
+        self.killing = false;
+    }
+}
+
 #[cfg(test)]
 mod tests {
-    use super::{Action, Mode, KillRing};
+    use super::{Action, KillRing, Mode};
 
     #[test]
     fn disabled() {
@@ -187,9 +208,9 @@
         kill_ring.reset();
         kill_ring.kill("word2", Mode::Append);
 
-        assert_eq!(Some(&"word2".to_string()), kill_ring.yank());
+        assert_eq!(Some(&"word2".to_owned()), kill_ring.yank());
         assert_eq!(Action::Yank(5), kill_ring.last_action);
-        assert_eq!(Some(&"word2".to_string()), kill_ring.yank());
+        assert_eq!(Some(&"word2".to_owned()), kill_ring.yank());
         assert_eq!(Action::Yank(5), kill_ring.last_action);
     }
 
@@ -202,8 +223,8 @@
 
         assert_eq!(None, kill_ring.yank_pop());
         kill_ring.yank();
-        assert_eq!(Some((9, &"word1".to_string())), kill_ring.yank_pop());
-        assert_eq!(Some((5, &"longword2".to_string())), kill_ring.yank_pop());
-        assert_eq!(Some((9, &"word1".to_string())), kill_ring.yank_pop());
+        assert_eq!(Some((9, &"word1".to_owned())), kill_ring.yank_pop());
+        assert_eq!(Some((5, &"longword2".to_owned())), kill_ring.yank_pop());
+        assert_eq!(Some((9, &"word1".to_owned())), kill_ring.yank_pop());
     }
 }
diff --git a/src/lib.rs b/src/lib.rs
index 133b569..cb1d284 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,6 +1,7 @@
 //! Readline for Rust
 //!
-//! This implementation is based on [Antirez's Linenoise](https://github.com/antirez/linenoise)
+//! This implementation is based on [Antirez's
+//! Linenoise](https://github.com/antirez/linenoise)
 //!
 //! # Example
 //!
@@ -10,20 +11,26 @@
 //! let mut rl = rustyline::Editor::<()>::new();
 //! let readline = rl.readline(">> ");
 //! match readline {
-//!     Ok(line) => println!("Line: {:?}",line),
-//!     Err(_)   => println!("No input"),
+//!     Ok(line) => println!("Line: {:?}", line),
+//!     Err(_) => println!("No input"),
 //! }
 //! ```
 #![allow(unknown_lints)]
+// #![feature(non_exhaustive)]
+// #![feature(tool_lints)]
 
+#[cfg(all(unix, not(any(target_os = "fuchsia"))))]
+extern crate dirs;
 extern crate libc;
-extern crate encode_unicode;
 #[macro_use]
 extern crate log;
-extern crate unicode_segmentation;
-extern crate unicode_width;
+extern crate memchr;
 #[cfg(all(unix, not(any(target_os = "fuchsia"))))]
 extern crate nix;
+extern crate unicode_segmentation;
+extern crate unicode_width;
+#[cfg(unix)]
+extern crate utf8parse;
 #[cfg(windows)]
 extern crate winapi;
 #[cfg(windows)]
@@ -34,688 +41,155 @@
 extern crate fuchsia_device;
 
 pub mod completion;
-mod consts;
+pub mod config;
+mod edit;
 pub mod error;
+pub mod highlight;
+pub mod hint;
 pub mod history;
 mod keymap;
+mod keys;
 mod kill_ring;
 pub mod line_buffer;
-#[cfg(unix)]
-mod char_iter;
-pub mod config;
+mod undo;
 
 mod tty;
 
-use std::cell::RefCell;
 use std::collections::HashMap;
 use std::fmt;
 use std::io::{self, Write};
-use std::mem;
 use std::path::Path;
-use std::rc::Rc;
 use std::result;
-use unicode_segmentation::UnicodeSegmentation;
-use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
+use std::sync::{Arc, Mutex, RwLock};
+use unicode_width::UnicodeWidthStr;
 
-use tty::{RawMode, RawReader, Terminal, Term};
+use tty::{RawMode, RawReader, Renderer, Term, Terminal};
 
-use encode_unicode::CharExt;
-use completion::{Completer, longest_common_prefix};
+use completion::{longest_common_prefix, Candidate, Completer};
+pub use config::{ColorMode, CompletionType, Config, EditMode, HistoryDuplicates};
+use edit::State;
+use highlight::Highlighter;
+use hint::Hinter;
 use history::{Direction, History};
-use line_buffer::{LineBuffer, MAX_LINE, WordAction};
 pub use keymap::{Anchor, At, CharSearch, Cmd, Movement, RepeatCount, Word};
-use keymap::EditState;
-use kill_ring::{Mode, KillRing};
-pub use config::{CompletionType, Config, EditMode, HistoryDuplicates};
-pub use consts::KeyPress;
+use keymap::{InputState, Refresher};
+pub use keys::KeyPress;
+use kill_ring::{KillRing, Mode};
+use line_buffer::WordAction;
 
 /// The error type for I/O and Linux Syscalls (Errno)
 pub type Result<T> = result::Result<T, error::ReadlineError>;
 
-// Represent the state during line editing.
-struct State<'out, 'prompt> {
-    out: &'out mut Write,
-    prompt: &'prompt str, // Prompt to display
-    prompt_size: Position, // Prompt Unicode width and height
-    line: LineBuffer, // Edited line buffer
-    cursor: Position, // Cursor position (relative to the start of the prompt for `row`)
-    cols: usize, // Number of columns in terminal
-    old_rows: usize, // Number of rows used so far (from start of prompt to end of input)
-    history_index: usize, // The history index we are currently editing
-    snapshot: LineBuffer, // Current edited line before history browsing/completion
-    term: Terminal, // terminal
-    edit_state: EditState,
-}
-
-#[derive(Copy, Clone, Debug, Default)]
-struct Position {
-    col: usize,
-    row: usize,
-}
-
-impl<'out, 'prompt> State<'out, 'prompt> {
-    fn new(out: &'out mut Write,
-           term: Terminal,
-           config: &Config,
-           prompt: &'prompt str,
-           history_index: usize,
-           custom_bindings: Rc<RefCell<HashMap<KeyPress, Cmd>>>)
-           -> State<'out, 'prompt> {
-        let capacity = MAX_LINE;
-        let cols = term.get_columns();
-        let prompt_size = calculate_position(prompt, Position::default(), cols);
-        State {
-            out: out,
-            prompt: prompt,
-            prompt_size: prompt_size,
-            line: LineBuffer::with_capacity(capacity),
-            cursor: prompt_size,
-            cols: cols,
-            old_rows: prompt_size.row,
-            history_index: history_index,
-            snapshot: LineBuffer::with_capacity(capacity),
-            term: term,
-            edit_state: EditState::new(config, custom_bindings),
-        }
-    }
-
-    fn next_cmd<R: RawReader>(&mut self, rdr: &mut R) -> Result<Cmd> {
-        loop {
-            let rc = self.edit_state.next_cmd(rdr);
-            if rc.is_err() && self.term.sigwinch() {
-                self.update_columns();
-                try!(self.refresh_line());
-                continue;
-            }
-            return rc;
-        }
-    }
-
-    fn snapshot(&mut self) {
-        mem::swap(&mut self.line, &mut self.snapshot);
-    }
-
-    fn backup(&mut self) {
-        self.snapshot.backup(&self.line);
-    }
-
-    /// Rewrite the currently edited line accordingly to the buffer content,
-    /// cursor position, and number of columns of the terminal.
-    fn refresh_line(&mut self) -> Result<()> {
-        let prompt_size = self.prompt_size;
-        self.refresh(self.prompt, prompt_size)
-    }
-
-    fn refresh_prompt_and_line(&mut self, prompt: &str) -> Result<()> {
-        let prompt_size = calculate_position(prompt, Position::default(), self.cols);
-        self.refresh(prompt, prompt_size)
-    }
-
-    #[cfg(unix)]
-    fn refresh(&mut self, prompt: &str, prompt_size: Position) -> Result<()> {
-        use std::fmt::Write;
-
-        // calculate the position of the end of the input line
-        let end_pos = calculate_position(&self.line, prompt_size, self.cols);
-        // calculate the desired position of the cursor
-        let cursor = calculate_position(&self.line[..self.line.pos()], prompt_size, self.cols);
-
-        let mut ab = String::new();
-
-        let cursor_row_movement = self.old_rows - self.cursor.row;
-        // move the cursor down as required
-        if cursor_row_movement > 0 {
-            write!(ab, "\x1b[{}B", cursor_row_movement).unwrap();
-        }
-        // clear old rows
-        for _ in 0..self.old_rows {
-            ab.push_str("\r\x1b[0K\x1b[1A");
-        }
-        // clear the line
-        ab.push_str("\r\x1b[0K");
-
-        // display the prompt
-        ab.push_str(prompt);
-        // display the input line
-        ab.push_str(&self.line);
-        // we have to generate our own newline on line wrap
-        if end_pos.col == 0 && end_pos.row > 0 {
-            ab.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!(ab, "\x1b[{}A", cursor_row_movement).unwrap();
-        }
-        // position the cursor within the line
-        if cursor.col > 0 {
-            write!(ab, "\r\x1b[{}C", cursor.col).unwrap();
-        } else {
-            ab.push('\r');
-        }
-
-        self.cursor = cursor;
-        self.old_rows = end_pos.row;
-
-        write_and_flush(self.out, ab.as_bytes())
-    }
-
-    #[cfg(windows)]
-    fn refresh(&mut self, prompt: &str, prompt_size: Position) -> Result<()> {
-        // calculate the position of the end of the input line
-        let end_pos = calculate_position(&self.line, prompt_size, self.cols);
-        // calculate the desired position of the cursor
-        let cursor = calculate_position(&self.line[..self.line.pos()], prompt_size, self.cols);
-
-        // position at the start of the prompt, clear to end of previous input
-        let mut info = try!(self.term.get_console_screen_buffer_info());
-        info.dwCursorPosition.X = 0;
-        info.dwCursorPosition.Y -= self.cursor.row as i16;
-        try!(self.term
-                 .set_console_cursor_position(info.dwCursorPosition));
-        let mut _count = 0;
-        try!(self.term
-                 .fill_console_output_character((info.dwSize.X * (self.old_rows as i16 + 1)) as
-                                                u32,
-                                                info.dwCursorPosition));
-        let mut ab = String::new();
-        // display the prompt
-        ab.push_str(prompt); // TODO handle ansi escape code (SetConsoleTextAttribute)
-        // display the input line
-        ab.push_str(&self.line);
-        try!(write_and_flush(self.out, ab.as_bytes()));
-
-        // position the cursor
-        let mut info = try!(self.term.get_console_screen_buffer_info());
-        info.dwCursorPosition.X = cursor.col as i16;
-        info.dwCursorPosition.Y -= (end_pos.row - cursor.row) as i16;
-        try!(self.term
-                 .set_console_cursor_position(info.dwCursorPosition));
-
-        self.cursor = cursor;
-        self.old_rows = end_pos.row;
-
-        Ok(())
-    }
-
-    fn update_columns(&mut self) {
-        self.cols = self.term.get_columns();
-    }
-}
-
-impl<'out, 'prompt> fmt::Debug for State<'out, 'prompt> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_struct("State")
-            .field("prompt", &self.prompt)
-            .field("prompt_size", &self.prompt_size)
-            .field("buf", &self.line)
-            .field("cursor", &self.cursor)
-            .field("cols", &self.cols)
-            .field("old_rows", &self.old_rows)
-            .field("history_index", &self.history_index)
-            .field("snapshot", &self.snapshot)
-            .finish()
-    }
-}
-
-fn write_and_flush(w: &mut Write, buf: &[u8]) -> Result<()> {
-    try!(w.write_all(buf));
-    try!(w.flush());
-    Ok(())
-}
-
-/// Beep, used for completion when there is nothing to complete or when all
-/// the choices were already shown.
-fn beep() -> Result<()> {
-    write_and_flush(&mut io::stderr(), b"\x07") // TODO bell-style
-}
-
-/// Calculate the number of columns and rows used to display `s` on a `cols` width terminal
-/// starting at `orig`.
-/// Control characters are treated as having zero width.
-/// Characters with 2 column width are correctly handled (not splitted).
-#[allow(if_same_then_else)]
-fn calculate_position(s: &str, orig: Position, cols: usize) -> Position {
-    let mut pos = orig;
-    let mut esc_seq = 0;
-    for c in s.chars() {
-        let cw = if esc_seq == 1 {
-            if c == '[' {
-                // CSI
-                esc_seq = 2;
-            } else {
-                // two-character sequence
-                esc_seq = 0;
-            }
-            None
-        } else if esc_seq == 2 {
-            if c == ';' || (c >= '0' && c <= '9') {
-            } else if c == 'm' {
-                // last
-                esc_seq = 0;
-            } else {
-                // not supported
-                esc_seq = 0;
-            }
-            None
-        } else if c == '\x1b' {
-            esc_seq = 1;
-            None
-        } else if c == '\n' {
-            pos.col = 0;
-            pos.row += 1;
-            None
-        } else {
-            c.width()
-        };
-        if let Some(cw) = cw {
-            pos.col += cw;
-            if pos.col > cols {
-                pos.row += 1;
-                pos.col = cw;
-            }
-        }
-    }
-    if pos.col == cols {
-        pos.col = 0;
-        pos.row += 1;
-    }
-    pos
-}
-
-/// Insert the character `ch` at cursor current position.
-fn edit_insert(s: &mut State, ch: char, n: RepeatCount) -> Result<()> {
-    if let Some(push) = s.line.insert(ch, n) {
-        if push {
-            if n == 1 && s.cursor.col + ch.width().unwrap_or(0) < s.cols {
-                // Avoid a full update of the line in the trivial case.
-                let cursor = calculate_position(&s.line[..s.line.pos()], s.prompt_size, s.cols);
-                s.cursor = cursor;
-                write_and_flush(s.out, ch.to_utf8().as_bytes())
-            } else {
-                s.refresh_line()
-            }
-        } else {
-            s.refresh_line()
-        }
-    } else {
-        Ok(())
-    }
-}
-
-/// Replace a single (or n) character(s) under the cursor (Vi mode)
-fn edit_replace_char(s: &mut State, ch: char, n: RepeatCount) -> Result<()> {
-    if let Some(chars) = s.line.delete(n) {
-        let count = chars.graphemes(true).count();
-        s.line.insert(ch, count);
-        s.line.move_backward(1);
-        s.refresh_line()
-    } else {
-        Ok(())
-    }
-}
-
-// Yank/paste `text` at current position.
-fn edit_yank(s: &mut State, text: &str, anchor: Anchor, n: RepeatCount) -> Result<()> {
-    if let Anchor::After = anchor {
-        s.line.move_forward(1);
-    }
-    if s.line.yank(text, n).is_some() {
-        if !s.edit_state.is_emacs_mode() {
-            s.line.move_backward(1);
-        }
-        s.refresh_line()
-    } else {
-        Ok(())
-    }
-}
-
-// Delete previously yanked text and yank/paste `text` at current position.
-fn edit_yank_pop(s: &mut State, yank_size: usize, text: &str) -> Result<()> {
-    s.line.yank_pop(yank_size, text);
-    edit_yank(s, text, Anchor::Before, 1)
-}
-
-/// Move cursor on the left.
-fn edit_move_backward(s: &mut State, n: RepeatCount) -> Result<()> {
-    if s.line.move_backward(n) {
-        s.refresh_line()
-    } else {
-        Ok(())
-    }
-}
-
-/// Move cursor on the right.
-fn edit_move_forward(s: &mut State, n: RepeatCount) -> Result<()> {
-    if s.line.move_forward(n) {
-        s.refresh_line()
-    } else {
-        Ok(())
-    }
-}
-
-/// Move cursor to the start of the line.
-fn edit_move_home(s: &mut State) -> Result<()> {
-    if s.line.move_home() {
-        s.refresh_line()
-    } else {
-        Ok(())
-    }
-}
-
-/// Move cursor to the end of the line.
-fn edit_move_end(s: &mut State) -> Result<()> {
-    if s.line.move_end() {
-        s.refresh_line()
-    } else {
-        Ok(())
-    }
-}
-
-/// Delete the character at the right of the cursor without altering the cursor
-/// position. Basically this is what happens with the "Delete" keyboard key.
-fn edit_delete(s: &mut State, n: RepeatCount) -> Result<()> {
-    if s.line.delete(n).is_some() {
-        s.refresh_line()
-    } else {
-        Ok(())
-    }
-}
-
-/// Backspace implementation.
-fn edit_backspace(s: &mut State, n: RepeatCount) -> Result<()> {
-    if s.line.backspace(n).is_some() {
-        s.refresh_line()
-    } else {
-        Ok(())
-    }
-}
-
-/// Kill the text from point to the end of the line.
-fn edit_kill_line(s: &mut State) -> Result<Option<String>> {
-    if let Some(text) = s.line.kill_line() {
-        try!(s.refresh_line());
-        Ok(Some(text))
-    } else {
-        Ok(None)
-    }
-}
-
-/// Kill backward from point to the beginning of the line.
-fn edit_discard_line(s: &mut State) -> Result<Option<String>> {
-    if let Some(text) = s.line.discard_line() {
-        try!(s.refresh_line());
-        Ok(Some(text))
-    } else {
-        Ok(None)
-    }
-}
-
-/// Exchange the char before cursor with the character at cursor.
-fn edit_transpose_chars(s: &mut State) -> Result<()> {
-    if s.line.transpose_chars() {
-        s.refresh_line()
-    } else {
-        Ok(())
-    }
-}
-
-fn edit_move_to_prev_word(s: &mut State, word_def: Word, n: RepeatCount) -> Result<()> {
-    if s.line.move_to_prev_word(word_def, n) {
-        s.refresh_line()
-    } else {
-        Ok(())
-    }
-}
-
-/// Delete the previous word, maintaining the cursor at the start of the
-/// current word.
-fn edit_delete_prev_word(s: &mut State, word_def: Word, n: RepeatCount) -> Result<Option<String>> {
-    if let Some(text) = s.line.delete_prev_word(word_def, n) {
-        try!(s.refresh_line());
-        Ok(Some(text))
-    } else {
-        Ok(None)
-    }
-}
-
-fn edit_move_to_next_word(s: &mut State, at: At, word_def: Word, n: RepeatCount) -> Result<()> {
-    if s.line.move_to_next_word(at, word_def, n) {
-        s.refresh_line()
-    } else {
-        Ok(())
-    }
-}
-
-fn edit_move_to(s: &mut State, cs: CharSearch, n: RepeatCount) -> Result<()> {
-    if s.line.move_to(cs, n) {
-        s.refresh_line()
-    } else {
-        Ok(())
-    }
-}
-
-/// Kill from the cursor to the end of the current word, or, if between words, to the end of the next word.
-fn edit_delete_word(s: &mut State,
-                    at: At,
-                    word_def: Word,
-                    n: RepeatCount)
-                    -> Result<Option<String>> {
-    if let Some(text) = s.line.delete_word(at, word_def, n) {
-        try!(s.refresh_line());
-        Ok(Some(text))
-    } else {
-        Ok(None)
-    }
-}
-
-fn edit_delete_to(s: &mut State, cs: CharSearch, n: RepeatCount) -> Result<Option<String>> {
-    if let Some(text) = s.line.delete_to(cs, n) {
-        try!(s.refresh_line());
-        Ok(Some(text))
-    } else {
-        Ok(None)
-    }
-}
-
-fn edit_word(s: &mut State, a: WordAction) -> Result<()> {
-    if s.line.edit_word(a) {
-        s.refresh_line()
-    } else {
-        Ok(())
-    }
-}
-
-fn edit_transpose_words(s: &mut State, n: RepeatCount) -> Result<()> {
-    if s.line.transpose_words(n) {
-        s.refresh_line()
-    } else {
-        Ok(())
-    }
-}
-
-/// Substitute the currently edited line with the next or previous history
-/// entry.
-fn edit_history_next(s: &mut State, history: &History, prev: bool) -> Result<()> {
-    if history.is_empty() {
-        return Ok(());
-    }
-    if s.history_index == history.len() {
-        if prev {
-            // Save the current edited line before to overwrite it
-            s.snapshot();
-        } else {
-            return Ok(());
-        }
-    } else if s.history_index == 0 && prev {
-        return Ok(());
-    }
-    if prev {
-        s.history_index -= 1;
-    } else {
-        s.history_index += 1;
-    }
-    if s.history_index < history.len() {
-        let buf = history.get(s.history_index).unwrap();
-        s.line.update(buf, buf.len());
-    } else {
-        // Restore current edited line
-        s.snapshot();
-    }
-    s.refresh_line()
-}
-
-fn edit_history_search(s: &mut State, history: &History, dir: Direction) -> Result<()> {
-    if history.is_empty() {
-        return beep();
-    }
-    if s.history_index == history.len() && dir == Direction::Forward {
-        return beep();
-    } else if s.history_index == 0 && dir == Direction::Reverse {
-        return beep();
-    }
-    if dir == Direction::Reverse {
-        s.history_index -= 1;
-    } else {
-        s.history_index += 1;
-    }
-    if let Some(history_index) =
-        history.starts_with(&s.line.as_str()[..s.line.pos()], s.history_index, dir) {
-        s.history_index = history_index;
-        let buf = history.get(history_index).unwrap();
-        s.line.update(buf, buf.len());
-        s.refresh_line()
-    } else {
-        beep()
-    }
-}
-
-/// Substitute the currently edited line with the first/last history entry.
-fn edit_history(s: &mut State, history: &History, first: bool) -> Result<()> {
-    if history.is_empty() {
-        return Ok(());
-    }
-    if s.history_index == history.len() {
-        if first {
-            // Save the current edited line before to overwrite it
-            s.snapshot();
-        } else {
-            return Ok(());
-        }
-    } else if s.history_index == 0 && first {
-        return Ok(());
-    }
-    if first {
-        s.history_index = 0;
-        let buf = history.get(s.history_index).unwrap();
-        s.line.update(buf, buf.len());
-    } else {
-        s.history_index = history.len();
-        // Restore current edited line
-        s.snapshot();
-    }
-    s.refresh_line()
-}
-
 /// Completes the line/word
-fn complete_line<R: RawReader>(rdr: &mut R,
-                               s: &mut State,
-                               completer: &Completer,
-                               config: &Config)
-                               -> Result<Option<Cmd>> {
+fn complete_line<R: RawReader, C: Completer>(
+    rdr: &mut R,
+    s: &mut State,
+    input_state: &mut InputState,
+    completer: &C,
+    highlighter: Option<&Highlighter>,
+    config: &Config,
+) -> Result<Option<Cmd>> {
     // get a list of completions
     let (start, candidates) = try!(completer.complete(&s.line, s.line.pos()));
     // if no completions, we are done
     if candidates.is_empty() {
-        try!(beep());
+        try!(s.out.beep());
         Ok(None)
     } else if CompletionType::Circular == config.completion_type() {
-        // Save the current edited line before to overwrite it
-        s.backup();
+        let mark = s.changes.borrow_mut().begin();
+        // Save the current edited line before overwriting it
+        let backup = s.line.as_str().to_owned();
+        let backup_pos = s.line.pos();
         let mut cmd;
         let mut i = 0;
         loop {
             // Show completion or original buffer
             if i < candidates.len() {
-                completer.update(&mut s.line, start, &candidates[i]);
+                let candidate = candidates[i].replacement();
+                // TODO we can't highlight the line buffer directly
+                /*let candidate = if let Some(highlighter) = s.highlighter {
+                    highlighter.highlight_candidate(candidate, CompletionType::Circular)
+                } else {
+                    Borrowed(candidate)
+                };*/
+                completer.update(&mut s.line, start, candidate);
                 try!(s.refresh_line());
             } else {
                 // Restore current edited line
-                s.snapshot();
+                s.line.update(&backup, backup_pos);
                 try!(s.refresh_line());
-                s.snapshot();
             }
 
-            cmd = try!(s.next_cmd(rdr));
+            cmd = try!(s.next_cmd(input_state, rdr, true));
             match cmd {
                 Cmd::Complete => {
                     i = (i + 1) % (candidates.len() + 1); // Circular
                     if i == candidates.len() {
-                        try!(beep());
+                        try!(s.out.beep());
                     }
                 }
                 Cmd::Abort => {
                     // Re-show original buffer
-                    s.snapshot();
                     if i < candidates.len() {
+                        s.line.update(&backup, backup_pos);
                         try!(s.refresh_line());
                     }
+                    s.changes.borrow_mut().truncate(mark);
                     return Ok(None);
                 }
                 _ => {
-                    if i == candidates.len() {
-                        s.snapshot();
-                    }
+                    s.changes.borrow_mut().end();
                     break;
                 }
             }
         }
         Ok(Some(cmd))
     } else if CompletionType::List == config.completion_type() {
-        // beep if ambiguous
-        if candidates.len() > 1 {
-            try!(beep());
-        }
         if let Some(lcp) = longest_common_prefix(&candidates) {
-            // if we can extend the item, extend it and return to main loop
+            // if we can extend the item, extend it
             if lcp.len() > s.line.pos() - start {
                 completer.update(&mut s.line, start, lcp);
                 try!(s.refresh_line());
-                return Ok(None);
             }
         }
+        // beep if ambiguous
+        if candidates.len() > 1 {
+            try!(s.out.beep());
+        } else {
+            return Ok(None);
+        }
         // we can't complete any further, wait for second tab
-        let mut cmd = try!(s.next_cmd(rdr));
+        let mut cmd = try!(s.next_cmd(input_state, rdr, true));
         // if any character other than tab, pass it to the main loop
         if cmd != Cmd::Complete {
             return Ok(Some(cmd));
         }
         // move cursor to EOL to avoid overwriting the command line
         let save_pos = s.line.pos();
-        try!(edit_move_end(s));
+        try!(s.edit_move_end());
         s.line.set_pos(save_pos);
         // we got a second tab, maybe show list of possible completions
         let show_completions = if candidates.len() > config.completion_prompt_limit() {
             let msg = format!("\nDisplay all {} possibilities? (y or n)", candidates.len());
-            try!(write_and_flush(s.out, msg.as_bytes()));
+            try!(s.out.write_and_flush(msg.as_bytes()));
             s.old_rows += 1;
-            while cmd != Cmd::SelfInsert(1, 'y') && cmd != Cmd::SelfInsert(1, 'Y') &&
-                  cmd != Cmd::SelfInsert(1, 'n') &&
-                  cmd != Cmd::SelfInsert(1, 'N') &&
-                  cmd != Cmd::Kill(Movement::BackwardChar(1)) {
-                cmd = try!(s.next_cmd(rdr));
+            while cmd != Cmd::SelfInsert(1, 'y')
+                && cmd != Cmd::SelfInsert(1, 'Y')
+                && cmd != Cmd::SelfInsert(1, 'n')
+                && cmd != Cmd::SelfInsert(1, 'N')
+                && cmd != Cmd::Kill(Movement::BackwardChar(1))
+            {
+                cmd = try!(s.next_cmd(input_state, rdr, false));
             }
             match cmd {
-                Cmd::SelfInsert(1, 'y') |
-                Cmd::SelfInsert(1, 'Y') => true,
+                Cmd::SelfInsert(1, 'y') | Cmd::SelfInsert(1, 'Y') => true,
                 _ => false,
             }
         } else {
             true
         };
         if show_completions {
-            page_completions(rdr, s, &candidates)
+            page_completions(rdr, s, input_state, highlighter, &candidates)
         } else {
             try!(s.refresh_line());
             Ok(None)
@@ -725,60 +199,71 @@
     }
 }
 
-fn page_completions<R: RawReader>(rdr: &mut R,
-                                  s: &mut State,
-                                  candidates: &[String])
-                                  -> Result<Option<Cmd>> {
+fn page_completions<R: RawReader, C: Candidate>(
+    rdr: &mut R,
+    s: &mut State,
+    input_state: &mut InputState,
+    highlighter: Option<&Highlighter>,
+    candidates: &[C],
+) -> Result<Option<Cmd>> {
     use std::cmp;
 
     let min_col_pad = 2;
-    let max_width = cmp::min(s.cols,
-                             candidates
-                                 .into_iter()
-                                 .map(|s| s.as_str().width())
-                                 .max()
-                                 .unwrap() + min_col_pad);
-    let num_cols = s.cols / max_width;
+    let cols = s.out.get_columns();
+    let max_width = cmp::min(
+        cols,
+        candidates
+            .into_iter()
+            .map(|s| s.display().width())
+            .max()
+            .unwrap()
+            + min_col_pad,
+    );
+    let num_cols = cols / max_width;
 
-    let mut pause_row = s.term.get_rows() - 1;
+    let mut pause_row = s.out.get_rows() - 1;
     let num_rows = (candidates.len() + num_cols - 1) / num_cols;
     let mut ab = String::new();
     for row in 0..num_rows {
         if row == pause_row {
-            try!(write_and_flush(s.out, b"\n--More--"));
+            try!(s.out.write_and_flush(b"\n--More--"));
             let mut cmd = Cmd::Noop;
-            while cmd != Cmd::SelfInsert(1, 'y') && cmd != Cmd::SelfInsert(1_, 'Y') &&
-                  cmd != Cmd::SelfInsert(1, 'n') &&
-                  cmd != Cmd::SelfInsert(1_, 'N') &&
-                  cmd != Cmd::SelfInsert(1, 'q') &&
-                  cmd != Cmd::SelfInsert(1, 'Q') &&
-                  cmd != Cmd::SelfInsert(1, ' ') &&
-                  cmd != Cmd::Kill(Movement::BackwardChar(1)) &&
-                  cmd != Cmd::AcceptLine {
-                cmd = try!(s.next_cmd(rdr));
+            while cmd != Cmd::SelfInsert(1, 'y')
+                && cmd != Cmd::SelfInsert(1, 'Y')
+                && cmd != Cmd::SelfInsert(1, 'n')
+                && cmd != Cmd::SelfInsert(1, 'N')
+                && cmd != Cmd::SelfInsert(1, 'q')
+                && cmd != Cmd::SelfInsert(1, 'Q')
+                && cmd != Cmd::SelfInsert(1, ' ')
+                && cmd != Cmd::Kill(Movement::BackwardChar(1))
+                && cmd != Cmd::AcceptLine
+            {
+                cmd = try!(s.next_cmd(input_state, rdr, false));
             }
             match cmd {
-                Cmd::SelfInsert(1, 'y') |
-                Cmd::SelfInsert(1, 'Y') |
-                Cmd::SelfInsert(1, ' ') => {
-                    pause_row += s.term.get_rows() - 1;
+                Cmd::SelfInsert(1, 'y') | Cmd::SelfInsert(1, 'Y') | Cmd::SelfInsert(1, ' ') => {
+                    pause_row += s.out.get_rows() - 1;
                 }
                 Cmd::AcceptLine => {
                     pause_row += 1;
                 }
                 _ => break,
             }
-            try!(write_and_flush(s.out, b"\n"));
+            try!(s.out.write_and_flush(b"\n"));
         } else {
-            try!(write_and_flush(s.out, b"\n"));
+            try!(s.out.write_and_flush(b"\n"));
         }
         ab.clear();
         for col in 0..num_cols {
             let i = (col * num_rows) + row;
             if i < candidates.len() {
-                let candidate = &candidates[i];
-                ab.push_str(candidate);
-                let width = candidate.as_str().width();
+                let candidate = &candidates[i].display();
+                let width = candidate.width();
+                if let Some(highlighter) = highlighter {
+                    ab.push_str(&highlighter.highlight_candidate(candidate, CompletionType::List));
+                } else {
+                    ab.push_str(candidate);
+                }
                 if ((col + 1) * num_rows) + row < candidates.len() {
                     for _ in width..max_width {
                         ab.push(' ');
@@ -786,23 +271,27 @@
                 }
             }
         }
-        try!(write_and_flush(s.out, ab.as_bytes()));
+        try!(s.out.write_and_flush(ab.as_bytes()));
     }
-    try!(write_and_flush(s.out, b"\n"));
+    try!(s.out.write_and_flush(b"\n"));
     try!(s.refresh_line());
     Ok(None)
 }
 
 /// Incremental search
-fn reverse_incremental_search<R: RawReader>(rdr: &mut R,
-                                            s: &mut State,
-                                            history: &History)
-                                            -> Result<Option<Cmd>> {
+fn reverse_incremental_search<R: RawReader>(
+    rdr: &mut R,
+    s: &mut State,
+    input_state: &mut InputState,
+    history: &History,
+) -> Result<Option<Cmd>> {
     if history.is_empty() {
         return Ok(None);
     }
-    // Save the current edited line (and cursor position) before to overwrite it
-    s.snapshot();
+    let mark = s.changes.borrow_mut().begin();
+    // Save the current edited line (and cursor position) before overwriting it
+    let backup = s.line.as_str().to_owned();
+    let backup_pos = s.line.pos();
 
     let mut search_buf = String::new();
     let mut history_idx = history.len() - 1;
@@ -819,7 +308,7 @@
         };
         try!(s.refresh_prompt_and_line(&prompt));
 
-        cmd = try!(s.next_cmd(rdr));
+        cmd = try!(s.next_cmd(input_state, rdr, true));
         if let Cmd::SelfInsert(_, c) = cmd {
             search_buf.push(c);
         } else {
@@ -848,10 +337,15 @@
                 }
                 Cmd::Abort => {
                     // Restore current edited line (before search)
-                    s.snapshot();
+                    s.line.update(&backup, backup_pos);
                     try!(s.refresh_line());
+                    s.changes.borrow_mut().truncate(mark);
                     return Ok(None);
                 }
+                Cmd::Move(_) => {
+                    try!(s.refresh_line()); // restore prompt
+                    break;
+                }
                 _ => break,
             }
         }
@@ -866,43 +360,69 @@
             _ => false,
         };
     }
+    s.changes.borrow_mut().end();
     Ok(Some(cmd))
 }
 
 /// Handles reading and editting the readline buffer.
 /// It will also handle special inputs in an appropriate fashion
 /// (e.g., C-c will exit readline)
-#[allow(let_unit_value)]
-fn readline_edit<C: Completer>(prompt: &str,
-                               editor: &mut Editor<C>,
-                               original_mode: tty::Mode)
-                               -> Result<String> {
-    let completer = editor.completer.as_ref().map(|c| c as &Completer);
+fn readline_edit<H: Helper>(
+    prompt: &str,
+    initial: Option<(&str, &str)>,
+    editor: &mut Editor<H>,
+    original_mode: &tty::Mode,
+) -> Result<String> {
+    let completer = editor.helper.as_ref();
+    let hinter = editor.helper.as_ref().map(|h| h as &Hinter);
+    let highlighter = if editor.term.colors_enabled() {
+        editor.helper.as_ref().map(|h| h as &Highlighter)
+    } else {
+        None
+    };
 
     let mut stdout = editor.term.create_writer();
 
-    editor.kill_ring.reset();
-    let mut s = State::new(&mut stdout,
-                           editor.term.clone(),
-                           &editor.config,
-                           prompt,
-                           editor.history.len(),
-                           editor.custom_bindings.clone());
+    editor.reset_kill_ring(); // TODO recreate a new kill ring vs Arc<Mutex<KillRing>>
+    let mut s = State::new(
+        &mut stdout,
+        prompt,
+        editor.history.len(),
+        hinter,
+        highlighter,
+    );
+    let mut input_state = InputState::new(&editor.config, Arc::clone(&editor.custom_bindings));
+
+    s.line.set_delete_listener(editor.kill_ring.clone());
+    s.line.set_change_listener(s.changes.clone());
+
+    if let Some((left, right)) = initial {
+        s.line
+            .update((left.to_owned() + right).as_ref(), left.len());
+    }
+
     try!(s.refresh_line());
 
-    let mut rdr = try!(s.term.create_reader(&editor.config));
+    let mut rdr = try!(editor.term.create_reader(&editor.config));
 
     loop {
-        let rc = s.next_cmd(&mut rdr);
+        let rc = s.next_cmd(&mut input_state, &mut rdr, false);
         let mut cmd = try!(rc);
 
         if cmd.should_reset_kill_ring() {
-            editor.kill_ring.reset();
+            editor.reset_kill_ring();
         }
 
         // autocomplete
         if cmd == Cmd::Complete && completer.is_some() {
-            let next = try!(complete_line(&mut rdr, &mut s, completer.unwrap(), &editor.config));
+            let next = try!(complete_line(
+                &mut rdr,
+                &mut s,
+                &mut input_state,
+                completer.unwrap(),
+                highlighter,
+                &editor.config,
+            ));
             if next.is_some() {
                 cmd = next.unwrap();
             } else {
@@ -911,16 +431,21 @@
         }
 
         if let Cmd::SelfInsert(n, c) = cmd {
-            try!(edit_insert(&mut s, c, n));
+            try!(s.edit_insert(c, n));
             continue;
         } else if let Cmd::Insert(n, text) = cmd {
-            try!(edit_yank(&mut s, &text, Anchor::Before, n));
+            try!(s.edit_yank(&input_state, &text, Anchor::Before, n));
             continue;
         }
 
         if cmd == Cmd::ReverseSearchHistory {
             // Search history backward
-            let next = try!(reverse_incremental_search(&mut rdr, &mut s, &editor.history));
+            let next = try!(reverse_incremental_search(
+                &mut rdr,
+                &mut s,
+                &mut input_state,
+                &editor.history,
+            ));
             if next.is_some() {
                 cmd = next.unwrap();
             } else {
@@ -931,164 +456,151 @@
         match cmd {
             Cmd::Move(Movement::BeginningOfLine) => {
                 // Move to the beginning of line.
-                try!(edit_move_home(&mut s))
+                try!(s.edit_move_home())
             }
             Cmd::Move(Movement::ViFirstPrint) => {
-                try!(edit_move_home(&mut s));
-                try!(edit_move_to_next_word(&mut s, At::Start, Word::Big, 1))
+                try!(s.edit_move_home());
+                try!(s.edit_move_to_next_word(At::Start, Word::Big, 1))
             }
             Cmd::Move(Movement::BackwardChar(n)) => {
                 // Move back a character.
-                try!(edit_move_backward(&mut s, n))
+                try!(s.edit_move_backward(n))
             }
-            Cmd::Kill(Movement::ForwardChar(n)) => {
-                // Delete (forward) one character at point.
-                try!(edit_delete(&mut s, n))
+            Cmd::ReplaceChar(n, c) => try!(s.edit_replace_char(c, n)),
+            Cmd::Replace(mvt, text) => {
+                try!(s.edit_kill(&mvt));
+                if let Some(text) = text {
+                    try!(s.edit_insert_text(&text))
+                }
             }
-            Cmd::Replace(n, c) => {
-                try!(edit_replace_char(&mut s, c, n));
+            Cmd::Overwrite(c) => {
+                try!(s.edit_overwrite_char(c));
             }
             Cmd::EndOfFile => {
-                if !s.edit_state.is_emacs_mode() && !s.line.is_empty() {
-                    try!(edit_move_end(&mut s));
+                if !input_state.is_emacs_mode() && !s.line.is_empty() {
+                    try!(s.edit_move_end());
                     break;
                 } else if s.line.is_empty() {
                     return Err(error::ReadlineError::Eof);
                 } else {
-                    try!(edit_delete(&mut s, 1))
+                    try!(s.edit_delete(1))
                 }
             }
             Cmd::Move(Movement::EndOfLine) => {
                 // Move to the end of line.
-                try!(edit_move_end(&mut s))
+                try!(s.edit_move_end())
             }
             Cmd::Move(Movement::ForwardChar(n)) => {
                 // Move forward a character.
-                try!(edit_move_forward(&mut s, n))
-            }
-            Cmd::Kill(Movement::BackwardChar(n)) => {
-                // Delete one character backward.
-                try!(edit_backspace(&mut s, n))
-            }
-            Cmd::Kill(Movement::EndOfLine) => {
-                // Kill the text from point to the end of the line.
-                if let Some(text) = try!(edit_kill_line(&mut s)) {
-                    editor.kill_ring.kill(&text, Mode::Append)
-                }
-            }
-            Cmd::Kill(Movement::WholeLine) => {
-                try!(edit_move_home(&mut s));
-                if let Some(text) = try!(edit_kill_line(&mut s)) {
-                    editor.kill_ring.kill(&text, Mode::Append)
-                }
+                try!(s.edit_move_forward(n))
             }
             Cmd::ClearScreen => {
                 // Clear the screen leaving the current line at the top of the screen.
-                try!(s.term.clear_screen(&mut s.out));
+                try!(s.out.clear_screen());
                 try!(s.refresh_line())
             }
             Cmd::NextHistory => {
                 // Fetch the next command from the history list.
-                try!(edit_history_next(&mut s, &editor.history, false))
+                try!(s.edit_history_next(&editor.history, false))
             }
             Cmd::PreviousHistory => {
                 // Fetch the previous command from the history list.
-                try!(edit_history_next(&mut s, &editor.history, true))
+                try!(s.edit_history_next(&editor.history, true))
             }
             Cmd::HistorySearchBackward => {
-                try!(edit_history_search(&mut s, &editor.history, Direction::Reverse))
+                try!(s.edit_history_search(&editor.history, Direction::Reverse))
             }
             Cmd::HistorySearchForward => {
-                try!(edit_history_search(&mut s, &editor.history, Direction::Forward))
+                try!(s.edit_history_search(&editor.history, Direction::Forward))
             }
             Cmd::TransposeChars => {
                 // Exchange the char before cursor with the character at cursor.
-                try!(edit_transpose_chars(&mut s))
-            }
-            Cmd::Kill(Movement::BeginningOfLine) => {
-                // Kill backward from point to the beginning of the line.
-                if let Some(text) = try!(edit_discard_line(&mut s)) {
-                    editor.kill_ring.kill(&text, Mode::Prepend)
-                }
+                try!(s.edit_transpose_chars())
             }
             #[cfg(unix)]
             Cmd::QuotedInsert => {
                 // Quoted insert
                 let c = try!(rdr.next_char());
-                try!(edit_insert(&mut s, c, 1)) // FIXME
+                try!(s.edit_insert(c, 1)) // FIXME
             }
             Cmd::Yank(n, anchor) => {
                 // retrieve (yank) last item killed
-                if let Some(text) = editor.kill_ring.yank() {
-                    try!(edit_yank(&mut s, text, anchor, n))
+                let mut kill_ring = editor.kill_ring.lock().unwrap();
+                if let Some(text) = kill_ring.yank() {
+                    try!(s.edit_yank(&input_state, text, anchor, n))
                 }
             }
-            Cmd::ViYankTo(mvt) => {
+            Cmd::ViYankTo(ref mvt) => {
                 if let Some(text) = s.line.copy(mvt) {
-                    editor.kill_ring.kill(&text, Mode::Append)
+                    let mut kill_ring = editor.kill_ring.lock().unwrap();
+                    kill_ring.kill(&text, Mode::Append)
                 }
             }
             // TODO CTRL-_ // undo
             Cmd::AcceptLine => {
-                // Accept the line regardless of where the cursor is.
-                try!(edit_move_end(&mut s));
-                break;
-            }
-            Cmd::Kill(Movement::BackwardWord(n, word_def)) => {
-                // kill one word backward (until start of word)
-                if let Some(text) = try!(edit_delete_prev_word(&mut s, word_def, n)) {
-                    editor.kill_ring.kill(&text, Mode::Prepend)
+                #[cfg(test)]
+                {
+                    editor.term.cursor = s.cursor.col;
                 }
+                // Accept the line regardless of where the cursor is.
+                try!(s.edit_move_end());
+                if s.hinter.is_some() {
+                    // Force a refresh without hints to leave the previous
+                    // line as the user typed it after a newline.
+                    s.hinter = None;
+                    try!(s.refresh_line());
+                }
+                break;
             }
             Cmd::BeginningOfHistory => {
                 // move to first entry in history
-                try!(edit_history(&mut s, &editor.history, true))
+                try!(s.edit_history(&editor.history, true))
             }
             Cmd::EndOfHistory => {
                 // move to last entry in history
-                try!(edit_history(&mut s, &editor.history, false))
+                try!(s.edit_history(&editor.history, false))
             }
             Cmd::Move(Movement::BackwardWord(n, word_def)) => {
                 // move backwards one word
-                try!(edit_move_to_prev_word(&mut s, word_def, n))
+                try!(s.edit_move_to_prev_word(word_def, n))
             }
             Cmd::CapitalizeWord => {
                 // capitalize word after point
-                try!(edit_word(&mut s, WordAction::CAPITALIZE))
+                try!(s.edit_word(WordAction::CAPITALIZE))
             }
-            Cmd::Kill(Movement::ForwardWord(n, at, word_def)) => {
-                // kill one word forward (until start/end of word)
-                if let Some(text) = try!(edit_delete_word(&mut s, at, word_def, n)) {
-                    editor.kill_ring.kill(&text, Mode::Append)
-                }
+            Cmd::Kill(ref mvt) => {
+                try!(s.edit_kill(mvt));
             }
             Cmd::Move(Movement::ForwardWord(n, at, word_def)) => {
                 // move forwards one word
-                try!(edit_move_to_next_word(&mut s, at, word_def, n))
+                try!(s.edit_move_to_next_word(at, word_def, n))
             }
             Cmd::DowncaseWord => {
                 // lowercase word after point
-                try!(edit_word(&mut s, WordAction::LOWERCASE))
+                try!(s.edit_word(WordAction::LOWERCASE))
             }
             Cmd::TransposeWords(n) => {
                 // transpose words
-                try!(edit_transpose_words(&mut s, n))
+                try!(s.edit_transpose_words(n))
             }
             Cmd::UpcaseWord => {
                 // uppercase word after point
-                try!(edit_word(&mut s, WordAction::UPPERCASE))
+                try!(s.edit_word(WordAction::UPPERCASE))
             }
             Cmd::YankPop => {
                 // yank-pop
-                if let Some((yank_size, text)) = editor.kill_ring.yank_pop() {
-                    try!(edit_yank_pop(&mut s, yank_size, text))
+                let mut kill_ring = editor.kill_ring.lock().unwrap();
+                if let Some((yank_size, text)) = kill_ring.yank_pop() {
+                    try!(s.edit_yank_pop(yank_size, text))
                 }
             }
-            Cmd::Move(Movement::ViCharSearch(n, cs)) => try!(edit_move_to(&mut s, cs, n)),
-            Cmd::Kill(Movement::ViCharSearch(n, cs)) => {
-                if let Some(text) = try!(edit_delete_to(&mut s, cs, n)) {
-                    editor.kill_ring.kill(&text, Mode::Append)
+            Cmd::Move(Movement::ViCharSearch(n, cs)) => try!(s.edit_move_to(cs, n)),
+            Cmd::Undo(n) => {
+                s.line.remove_change_listener();
+                if s.changes.borrow_mut().undo(&mut s.line, n) {
+                    try!(s.refresh_line());
                 }
+                s.line.set_change_listener(s.changes.clone());
             }
             Cmd::Interrupt => {
                 return Err(error::ReadlineError::Interrupted);
@@ -1097,7 +609,7 @@
             Cmd::Suspend => {
                 try!(original_mode.disable_raw_mode());
                 try!(tty::suspend());
-                try!(s.term.enable_raw_mode()); // TODO original_mode may have changed
+                try!(editor.term.enable_raw_mode()); // TODO original_mode may have changed
                 try!(s.refresh_line());
                 continue;
             }
@@ -1107,13 +619,16 @@
             }
         }
     }
+    if cfg!(windows) {
+        let _ = original_mode; // silent warning
+    }
     Ok(s.line.into_string())
 }
 
-struct Guard(tty::Mode);
+struct Guard<'m>(&'m tty::Mode);
 
 #[allow(unused_must_use)]
-impl Drop for Guard {
+impl<'m> Drop for Guard<'m> {
     fn drop(&mut self) {
         let Guard(mode) = *self;
         mode.disable_raw_mode();
@@ -1122,12 +637,25 @@
 
 /// Readline method that will enable RAW mode, call the `readline_edit()`
 /// method and disable raw mode
-fn readline_raw<C: Completer>(prompt: &str, editor: &mut Editor<C>) -> Result<String> {
+fn readline_raw<H: Helper>(
+    prompt: &str,
+    initial: Option<(&str, &str)>,
+    editor: &mut Editor<H>,
+) -> Result<String> {
     let original_mode = try!(editor.term.enable_raw_mode());
-    let guard = Guard(original_mode);
-    let user_input = readline_edit(prompt, editor, original_mode);
+    let guard = Guard(&original_mode);
+    let user_input = readline_edit(prompt, initial, editor, &original_mode);
+    if editor.config.auto_add_history() {
+        if let Ok(ref line) = user_input {
+            editor.add_history_entry(line.as_ref());
+        }
+    }
     drop(guard); // try!(disable_raw_mode(original_mode));
-    println!("");
+    editor
+        .term
+        .create_writer()
+        .write_and_flush(b"\n")
+        .unwrap();
     user_input
 }
 
@@ -1140,40 +668,78 @@
     }
 }
 
-/// Line editor
-pub struct Editor<C: Completer> {
-    term: Terminal,
-    history: History,
-    completer: Option<C>,
-    kill_ring: KillRing,
-    config: Config,
-    custom_bindings: Rc<RefCell<HashMap<KeyPress, Cmd>>>,
+/// Syntax specific helper.
+///
+/// TODO Tokenizer/parser used for both completion, suggestion, highlighting.
+/// (parse current line once)
+pub trait Helper
+where
+    Self: Completer,
+    Self: Hinter,
+    Self: Highlighter,
+{
 }
 
-impl<C: Completer> Editor<C> {
-    pub fn new() -> Editor<C> {
+impl Helper for () {}
+
+/// Line editor
+pub struct Editor<H: Helper> {
+    term: Terminal,
+    history: History,
+    helper: Option<H>,
+    kill_ring: Arc<Mutex<KillRing>>,
+    config: Config,
+    custom_bindings: Arc<RwLock<HashMap<KeyPress, Cmd>>>,
+}
+
+//#[allow(clippy::new_without_default)]
+impl<H: Helper> Editor<H> {
+    /// Create an editor with the default configuration
+    pub fn new() -> Editor<H> {
         Self::with_config(Config::default())
     }
 
-    pub fn with_config(config: Config) -> Editor<C> {
-        let term = Terminal::new();
+    /// Create an editor with a specific configuration.
+    pub fn with_config(config: Config) -> Editor<H> {
+        let term = Terminal::new(config.color_mode(), config.output_stream());
         Editor {
-            term: term,
+            term,
             history: History::with_config(config),
-            completer: None,
-            kill_ring: KillRing::new(60),
-            config: config,
-            custom_bindings: Rc::new(RefCell::new(HashMap::new())),
+            helper: None,
+            kill_ring: Arc::new(Mutex::new(KillRing::new(60))),
+            config,
+            custom_bindings: Arc::new(RwLock::new(HashMap::new())),
         }
     }
 
-    /// This method will read a line from STDIN and will display a `prompt`
+    /// This method will read a line from STDIN and will display a `prompt`.
+    ///
+    /// It uses terminal-style interaction if `stdin` is connected to a
+    /// terminal.
+    /// Otherwise (e.g., if `stdin` is a pipe or the terminal is not supported),
+    /// it uses file-style interaction.
     pub fn readline(&mut self, prompt: &str) -> Result<String> {
+        self.readline_with(prompt, None)
+    }
+
+    /// This function behaves in the exact same manner as `readline`, except
+    /// that it pre-populates the input area.
+    ///
+    /// The text that resides in the input area is given as a 2-tuple.
+    /// The string on the left of the tuple is what will appear to the left of
+    /// the cursor and the string on the right is what will appear to the
+    /// right of the cursor.
+    pub fn readline_with_initial(&mut self, prompt: &str, initial: (&str, &str)) -> Result<String> {
+        self.readline_with(prompt, Some(initial))
+    }
+
+    fn readline_with(&mut self, prompt: &str, initial: Option<(&str, &str)>) -> Result<String> {
         if self.term.is_unsupported() {
             debug!(target: "rustyline", "unsupported terminal");
             // Write prompt and flush it to stdout
             let mut stdout = io::stdout();
-            try!(write_and_flush(&mut stdout, prompt.as_bytes()));
+            try!(stdout.write_all(prompt.as_bytes()));
+            try!(stdout.flush());
 
             readline_direct()
         } else if !self.term.is_stdin_tty() {
@@ -1181,7 +747,7 @@
             // Not a tty: read from file / pipe.
             readline_direct()
         } else {
-            readline_raw(prompt, self)
+            readline_raw(prompt, initial, self)
         }
     }
 
@@ -1189,39 +755,58 @@
     pub fn load_history<P: AsRef<Path> + ?Sized>(&mut self, path: &P) -> Result<()> {
         self.history.load(path)
     }
+
     /// Save the history in the specified file.
     pub fn save_history<P: AsRef<Path> + ?Sized>(&self, path: &P) -> Result<()> {
         self.history.save(path)
     }
+
     /// Add a new entry in the history.
     pub fn add_history_entry<S: AsRef<str> + Into<String>>(&mut self, line: S) -> bool {
         self.history.add(line)
     }
+
     /// Clear history.
     pub fn clear_history(&mut self) {
         self.history.clear()
     }
+
     /// Return a mutable reference to the history object.
-    pub fn get_history(&mut self) -> &mut History {
+    pub fn history_mut(&mut self) -> &mut History {
         &mut self.history
     }
+
     /// Return an immutable reference to the history object.
-    pub fn get_history_const(&self) -> &History {
+    pub fn history(&self) -> &History {
         &self.history
     }
 
-    /// Register a callback function to be called for tab-completion.
-    pub fn set_completer(&mut self, completer: Option<C>) {
-        self.completer = completer;
+    /// Register a callback function to be called for tab-completion
+    /// or to show hints to the user at the right of the prompt.
+    pub fn set_helper(&mut self, helper: Option<H>) {
+        self.helper = helper;
+    }
+
+    /// Return a mutable reference to the helper.
+    pub fn helper_mut(&mut self) -> Option<&mut H> {
+        self.helper.as_mut()
+    }
+
+    /// Return an immutable reference to the helper.
+    pub fn helper(&self) -> Option<&H> {
+        self.helper.as_ref()
     }
 
     /// Bind a sequence to a command.
     pub fn bind_sequence(&mut self, key_seq: KeyPress, cmd: Cmd) -> Option<Cmd> {
-        self.custom_bindings.borrow_mut().insert(key_seq, cmd)
+        let mut bindings = self.custom_bindings.write().unwrap();
+        bindings.insert(key_seq, cmd)
     }
+
     /// Remove a binding for the given sequence.
     pub fn unbind_sequence(&mut self, key_seq: KeyPress) -> Option<Cmd> {
-        self.custom_bindings.borrow_mut().remove(&key_seq)
+        let mut bindings = self.custom_bindings.write().unwrap();
+        bindings.remove(&key_seq)
     }
 
     /// ```
@@ -1230,23 +815,54 @@
     ///     match readline {
     ///         Ok(line) => {
     ///             println!("Line: {}", line);
-    ///         },
+    ///         }
     ///         Err(err) => {
     ///             println!("Error: {:?}", err);
-    ///             break
+    ///             break;
     ///         }
     ///     }
     /// }
     /// ```
-    pub fn iter<'a>(&'a mut self, prompt: &'a str) -> Iter<C> {
+    pub fn iter<'a>(&'a mut self, prompt: &'a str) -> Iter<H> {
         Iter {
             editor: self,
-            prompt: prompt,
+            prompt,
         }
     }
+
+    fn reset_kill_ring(&self) {
+        let mut kill_ring = self.kill_ring.lock().unwrap();
+        kill_ring.reset();
+    }
 }
 
-impl<C: Completer> fmt::Debug for Editor<C> {
+impl<H: Helper> config::Configurer for Editor<H> {
+    fn config_mut(&mut self) -> &mut Config {
+        &mut self.config
+    }
+
+    fn set_max_history_size(&mut self, max_size: usize) {
+        self.config_mut().set_max_history_size(max_size);
+        self.history.set_max_len(max_size);
+    }
+
+    fn set_history_ignore_dups(&mut self, yes: bool) {
+        self.config_mut().set_history_ignore_dups(yes);
+        self.history.ignore_dups = yes;
+    }
+
+    fn set_history_ignore_space(&mut self, yes: bool) {
+        self.config_mut().set_history_ignore_space(yes);
+        self.history.ignore_space = yes;
+    }
+
+    fn set_color_mode(&mut self, color_mode: ColorMode) {
+        self.config_mut().set_color_mode(color_mode);
+        self.term.color_mode = color_mode;
+    }
+}
+
+impl<H: Helper> fmt::Debug for Editor<H> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.debug_struct("Editor")
             .field("term", &self.term)
@@ -1255,201 +871,85 @@
     }
 }
 
-pub struct Iter<'a, C: Completer>
-    where C: 'a
+/// Edited lines iterator
+pub struct Iter<'a, H: Helper>
+where
+    H: 'a,
 {
-    editor: &'a mut Editor<C>,
+    editor: &'a mut Editor<H>,
     prompt: &'a str,
 }
 
-impl<'a, C: Completer> Iterator for Iter<'a, C> {
+impl<'a, H: Helper> Iterator for Iter<'a, H> {
     type Item = Result<String>;
 
     fn next(&mut self) -> Option<Result<String>> {
         let readline = self.editor.readline(self.prompt);
         match readline {
-            Ok(l) => {
-                self.editor.add_history_entry(l.as_ref()); // TODO Validate
-                Some(Ok(l))
-            }
+            Ok(l) => Some(Ok(l)),
             Err(error::ReadlineError::Eof) => None,
             e @ Err(_) => Some(e),
         }
     }
 }
 
-#[cfg(test)]
-mod test {
-    use std::cell::RefCell;
-    use std::collections::HashMap;
-    use std::io::Write;
-    use std::rc::Rc;
-    use line_buffer::LineBuffer;
-    use history::History;
-    use completion::Completer;
-    use config::Config;
-    use consts::KeyPress;
-    use keymap::{Cmd, EditState};
-    use super::{Editor, Position, Result, State};
-    use tty::{Terminal, Term};
-
-    fn init_state<'out>(out: &'out mut Write,
-                        line: &str,
-                        pos: usize,
-                        cols: usize)
-                        -> State<'out, 'static> {
-        let term = Terminal::new();
-        let config = Config::default();
-        State {
-            out: out,
-            prompt: "",
-            prompt_size: Position::default(),
-            line: LineBuffer::init(line, pos),
-            cursor: Position::default(),
-            cols: cols,
-            old_rows: 0,
-            history_index: 0,
-            snapshot: LineBuffer::with_capacity(100),
-            term: term,
-            edit_state: EditState::new(&config, Rc::new(RefCell::new(HashMap::new()))),
+enum StdStream {
+    Stdout(io::Stdout),
+    Stderr(io::Stderr),
+}
+impl StdStream {
+    fn from_stream_type(t: config::OutputStreamType) -> StdStream {
+        match t {
+            config::OutputStreamType::Stderr => StdStream::Stderr(io::stderr()),
+            config::OutputStreamType::Stdout => StdStream::Stdout(io::stdout()),
         }
     }
-
-    fn init_editor(keys: &[KeyPress]) -> Editor<()> {
-        let mut editor = Editor::<()>::new();
-        editor.term.keys.extend(keys.iter().cloned());
-        editor
-    }
-
-    #[test]
-    fn edit_history_next() {
-        let mut out = ::std::io::sink();
-        let line = "current edited line";
-        let mut s = init_state(&mut out, line, 6, 80);
-        let mut history = History::new();
-        history.add("line0");
-        history.add("line1");
-        s.history_index = history.len();
-
-        for _ in 0..2 {
-            super::edit_history_next(&mut s, &history, false).unwrap();
-            assert_eq!(line, s.line.as_str());
-        }
-
-        super::edit_history_next(&mut s, &history, true).unwrap();
-        assert_eq!(line, s.snapshot.as_str());
-        assert_eq!(1, s.history_index);
-        assert_eq!("line1", s.line.as_str());
-
-        for _ in 0..2 {
-            super::edit_history_next(&mut s, &history, true).unwrap();
-            assert_eq!(line, s.snapshot.as_str());
-            assert_eq!(0, s.history_index);
-            assert_eq!("line0", s.line.as_str());
-        }
-
-        super::edit_history_next(&mut s, &history, false).unwrap();
-        assert_eq!(line, s.snapshot.as_str());
-        assert_eq!(1, s.history_index);
-        assert_eq!("line1", s.line.as_str());
-
-        super::edit_history_next(&mut s, &history, false).unwrap();
-        // assert_eq!(line, s.snapshot);
-        assert_eq!(2, s.history_index);
-        assert_eq!(line, s.line.as_str());
-    }
-
-    struct SimpleCompleter;
-    impl Completer for SimpleCompleter {
-        fn complete(&self, line: &str, _pos: usize) -> Result<(usize, Vec<String>)> {
-            Ok((0, vec![line.to_string() + "t"]))
-        }
-    }
-
-    #[test]
-    fn complete_line() {
-        let mut out = ::std::io::sink();
-        let mut s = init_state(&mut out, "rus", 3, 80);
-        let keys = &[KeyPress::Enter];
-        let mut rdr = keys.iter();
-        let completer = SimpleCompleter;
-        let cmd = super::complete_line(&mut rdr, &mut s, &completer, &Config::default()).unwrap();
-        assert_eq!(Some(Cmd::AcceptLine), cmd);
-        assert_eq!("rust", s.line.as_str());
-        assert_eq!(4, s.line.pos());
-    }
-
-    #[test]
-    fn prompt_with_ansi_escape_codes() {
-        let pos = super::calculate_position("\x1b[1;32m>>\x1b[0m ", Position::default(), 80);
-        assert_eq!(3, pos.col);
-        assert_eq!(0, pos.row);
-    }
-
-    fn assert_line(keys: &[KeyPress], expected_line: &str) {
-        let mut editor = init_editor(keys);
-        let actual_line = editor.readline(&">>").unwrap();
-        assert_eq!(expected_line, actual_line);
-    }
-
-    #[test]
-    fn delete_key() {
-        assert_line(&[KeyPress::Char('a'), KeyPress::Delete, KeyPress::Enter],
-                    "a");
-        assert_line(&[KeyPress::Char('a'),
-                      KeyPress::Left,
-                      KeyPress::Delete,
-                      KeyPress::Enter],
-                    "");
-    }
-
-    #[test]
-    fn down_key() {
-        assert_line(&[KeyPress::Down, KeyPress::Enter], "");
-    }
-
-    #[test]
-    fn end_key() {
-        assert_line(&[KeyPress::End, KeyPress::Enter], "");
-    }
-
-    #[test]
-    fn home_key() {
-        assert_line(&[KeyPress::Home, KeyPress::Enter], "");
-    }
-
-    #[test]
-    fn left_key() {
-        assert_line(&[KeyPress::Left, KeyPress::Enter], "");
-    }
-
-    #[test]
-    fn meta_backspace_key() {
-        assert_line(&[KeyPress::Meta('\x08'), KeyPress::Enter], "");
-    }
-
-    #[test]
-    fn page_down_key() {
-        assert_line(&[KeyPress::PageDown, KeyPress::Enter], "");
-    }
-
-    #[test]
-    fn page_up_key() {
-        assert_line(&[KeyPress::PageUp, KeyPress::Enter], "");
-    }
-
-    #[test]
-    fn right_key() {
-        assert_line(&[KeyPress::Right, KeyPress::Enter], "");
-    }
-
-    #[test]
-    fn up_key() {
-        assert_line(&[KeyPress::Up, KeyPress::Enter], "");
-    }
-
-    #[test]
-    fn unknown_esc_key() {
-        assert_line(&[KeyPress::UnknownEscSeq, KeyPress::Enter], "");
-    }
 }
+#[cfg(unix)]
+impl std::os::unix::io::AsRawFd for StdStream {
+    fn as_raw_fd(&self) -> std::os::unix::io::RawFd {
+        match self {
+            StdStream::Stdout(e) => e.as_raw_fd(),
+            StdStream::Stderr(e) => e.as_raw_fd(),
+        }
+    }
+}
+impl io::Write for StdStream {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        match self {
+            StdStream::Stdout(ref mut e) => e.write(buf),
+            StdStream::Stderr(ref mut e) => e.write(buf),
+        }
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        match self {
+            StdStream::Stdout(ref mut e) => e.flush(),
+            StdStream::Stderr(ref mut e) => e.flush(),
+        }
+    }
+
+    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
+        match self {
+            StdStream::Stdout(ref mut e) => e.write_all(buf),
+            StdStream::Stderr(ref mut e) => e.write_all(buf),
+        }
+    }
+
+    fn write_fmt(&mut self, fmt: std::fmt::Arguments) -> io::Result<()> {
+        match self {
+            StdStream::Stdout(ref mut e) => e.write_fmt(fmt),
+            StdStream::Stderr(ref mut e) => e.write_fmt(fmt),
+        }
+    }
+
+    fn by_ref(&mut self) -> &mut StdStream {
+        self
+    }
+}
+
+#[cfg(test)]
+#[macro_use]
+extern crate assert_matches;
+#[cfg(test)]
+mod test;
diff --git a/src/line_buffer.rs b/src/line_buffer.rs
index 80699e2..de80a55 100644
--- a/src/line_buffer.rs
+++ b/src/line_buffer.rs
@@ -1,22 +1,69 @@
 //! Line buffer with current cursor position
-use std::iter;
-use std::ops::{Deref, Range};
-use unicode_segmentation::UnicodeSegmentation;
 use keymap::{At, CharSearch, Movement, RepeatCount, Word};
+use std::cell::RefCell;
+use std::fmt;
+use std::iter;
+use std::ops::{Deref, Index, Range};
+use std::rc::Rc;
+use std::string::Drain;
+use std::sync::{Arc, Mutex};
+use unicode_segmentation::UnicodeSegmentation;
 
 /// Maximum buffer size for the line read
-pub static MAX_LINE: usize = 4096;
+pub(crate) static MAX_LINE: usize = 4096;
 
+/// Word's case change
+#[derive(Clone, Copy)]
 pub enum WordAction {
     CAPITALIZE,
     LOWERCASE,
     UPPERCASE,
 }
 
-#[derive(Debug)]
+/// Delete (kill) direction
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub(crate) enum Direction {
+    Forward,
+    Backward,
+}
+
+impl Default for Direction {
+    fn default() -> Direction {
+        Direction::Forward
+    }
+}
+
+/// Listener to be notified when some text is deleted.
+pub(crate) trait DeleteListener {
+    fn start_killing(&mut self);
+    fn delete(&mut self, idx: usize, string: &str, dir: Direction);
+    fn stop_killing(&mut self);
+}
+
+/// Listener to be notified when the line is modified.
+pub(crate) trait ChangeListener: DeleteListener {
+    fn insert_char(&mut self, idx: usize, c: char);
+    fn insert_str(&mut self, idx: usize, string: &str);
+    fn replace(&mut self, idx: usize, old: &str, new: &str);
+}
+
+/// Represent the current input (text and cursor position).
+///
+/// The methods do text manipulations or/and cursor movements.
 pub struct LineBuffer {
-    buf: String, // Edited line buffer
-    pos: usize, // Current cursor position (byte position)
+    buf: String, // Edited line buffer (rl_line_buffer)
+    pos: usize,  // Current cursor position (byte position) (rl_point)
+    dl: Option<Arc<Mutex<DeleteListener>>>,
+    cl: Option<Rc<RefCell<ChangeListener>>>,
+}
+
+impl fmt::Debug for LineBuffer {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("LineBuffer")
+            .field("buf", &self.buf)
+            .field("pos", &self.pos)
+            .finish()
+    }
 }
 
 impl LineBuffer {
@@ -25,17 +72,36 @@
         LineBuffer {
             buf: String::with_capacity(capacity),
             pos: 0,
+            dl: None,
+            cl: None,
         }
     }
 
     #[cfg(test)]
-    pub fn init(line: &str, pos: usize) -> LineBuffer {
+    pub(crate) fn init(
+        line: &str,
+        pos: usize,
+        cl: Option<Rc<RefCell<ChangeListener>>>,
+    ) -> LineBuffer {
         let mut lb = Self::with_capacity(MAX_LINE);
         assert!(lb.insert_str(0, line));
         lb.set_pos(pos);
+        lb.cl = cl;
         lb
     }
 
+    pub(crate) fn set_delete_listener(&mut self, dl: Arc<Mutex<DeleteListener>>) {
+        self.dl = Some(dl);
+    }
+
+    pub(crate) fn set_change_listener(&mut self, dl: Rc<RefCell<ChangeListener>>) {
+        self.cl = Some(dl);
+    }
+
+    pub(crate) fn remove_change_listener(&mut self) {
+        self.cl = None;
+    }
+
     /// Extracts a string slice containing the entire buffer.
     pub fn as_str(&self) -> &str {
         &self.buf
@@ -50,6 +116,8 @@
     pub fn pos(&self) -> usize {
         self.pos
     }
+
+    /// Set cursor position (byte position)
     pub fn set_pos(&mut self, pos: usize) {
         assert!(pos <= self.buf.len());
         self.pos = pos;
@@ -59,6 +127,7 @@
     pub fn len(&self) -> usize {
         self.buf.len()
     }
+
     /// Returns `true` if this buffer has a length of zero.
     pub fn is_empty(&self) -> bool {
         self.buf.is_empty()
@@ -67,30 +136,24 @@
     /// Set line content (`buf`) and cursor position (`pos`).
     pub fn update(&mut self, buf: &str, pos: usize) {
         assert!(pos <= buf.len());
-        self.buf.clear();
+        let end = self.len();
+        self.drain(0..end, Direction::default());
         let max = self.buf.capacity();
         if buf.len() > max {
-            self.buf.push_str(&buf[..max]);
+            self.insert_str(0, &buf[..max]);
             if pos > max {
                 self.pos = max;
             } else {
                 self.pos = pos;
             }
         } else {
-            self.buf.push_str(buf);
+            self.insert_str(0, buf);
             self.pos = pos;
         }
     }
 
-    /// Backup `src`
-    pub fn backup(&mut self, src: &LineBuffer) {
-        self.buf.clear();
-        self.buf.push_str(&src.buf);
-        self.pos = src.pos;
-    }
-
     /// Returns the character at current cursor position.
-    fn grapheme_at_cursor(&self) -> Option<&str> {
+    pub(crate) fn grapheme_at_cursor(&self) -> Option<&str> {
         if self.pos == self.buf.len() {
             None
         } else {
@@ -98,7 +161,9 @@
         }
     }
 
-    fn next_pos(&self, n: RepeatCount) -> Option<usize> {
+    /// Returns the position of the character just after the current cursor
+    /// position.
+    pub fn next_pos(&self, n: RepeatCount) -> Option<usize> {
         if self.pos == self.buf.len() {
             return None;
         }
@@ -108,7 +173,9 @@
             .last()
             .map(|(i, s)| i + self.pos + s.len())
     }
-    /// Returns the position of the character just before the current cursor position.
+
+    /// Returns the position of the character just before the current cursor
+    /// position.
     fn prev_pos(&self, n: RepeatCount) -> Option<usize> {
         if self.pos == 0 {
             return None;
@@ -131,13 +198,11 @@
             return None;
         }
         let push = self.pos == self.buf.len();
-        if push {
-            self.buf.reserve(shift);
-            for _ in 0..n {
-                self.buf.push(ch);
-            }
-        } else if n == 1 {
+        if n == 1 {
             self.buf.insert(self.pos, ch);
+            for cl in &self.cl {
+                cl.borrow_mut().insert_char(self.pos, ch);
+            }
         } else {
             let text = iter::repeat(ch).take(n).collect::<String>();
             let pos = self.pos;
@@ -156,14 +221,11 @@
             return None;
         }
         let push = self.pos == self.buf.len();
-        if push {
-            self.buf.reserve(shift);
-            for _ in 0..n {
-                self.buf.push_str(text);
-            }
+        let pos = self.pos;
+        if n == 1 {
+            self.insert_str(pos, text);
         } else {
             let text = iter::repeat(text).take(n).collect::<String>();
-            let pos = self.pos;
             self.insert_str(pos, &text);
         }
         self.pos += shift;
@@ -172,7 +234,9 @@
 
     /// Delete previously yanked text and yank/paste `text` at current position.
     pub fn yank_pop(&mut self, yank_size: usize, text: &str) -> Option<bool> {
-        self.buf.drain((self.pos - yank_size)..self.pos);
+        let end = self.pos;
+        let start = end - yank_size;
+        self.drain(start..end, Direction::default());
         self.pos -= yank_size;
         self.yank(text, 1)
     }
@@ -219,13 +283,17 @@
         }
     }
 
-    /// Delete the character at the right of the cursor without altering the cursor
-    /// position. Basically this is what happens with the "Delete" keyboard key.
+    /// Delete the character at the right of the cursor without altering the
+    /// cursor position. Basically this is what happens with the "Delete"
+    /// keyboard key.
     /// Return the number of characters deleted.
     pub fn delete(&mut self, n: RepeatCount) -> Option<String> {
         match self.next_pos(n) {
             Some(pos) => {
-                let chars = self.buf.drain(self.pos..pos).collect::<String>();
+                let start = self.pos;
+                let chars = self
+                    .drain(start..pos, Direction::Forward)
+                    .collect::<String>();
                 Some(chars)
             }
             None => None,
@@ -234,35 +302,39 @@
 
     /// Delete the character at the left of the cursor.
     /// Basically that is what happens with the "Backspace" keyboard key.
-    pub fn backspace(&mut self, n: RepeatCount) -> Option<String> {
+    pub fn backspace(&mut self, n: RepeatCount) -> bool {
         match self.prev_pos(n) {
             Some(pos) => {
-                let chars = self.buf.drain(pos..self.pos).collect::<String>();
+                let end = self.pos;
+                self.drain(pos..end, Direction::Backward);
                 self.pos = pos;
-                Some(chars)
+                true
             }
-            None => None,
+            None => false,
         }
     }
 
     /// Kill the text from point to the end of the line.
-    pub fn kill_line(&mut self) -> Option<String> {
+    pub fn kill_line(&mut self) -> bool {
         if !self.buf.is_empty() && self.pos < self.buf.len() {
-            let text = self.buf.drain(self.pos..).collect();
-            Some(text)
+            let start = self.pos;
+            let end = self.buf.len();
+            self.drain(start..end, Direction::Forward);
+            true
         } else {
-            None
+            false
         }
     }
 
     /// Kill backward from point to the beginning of the line.
-    pub fn discard_line(&mut self) -> Option<String> {
+    pub fn discard_line(&mut self) -> bool {
         if self.pos > 0 && !self.buf.is_empty() {
-            let text = self.buf.drain(..self.pos).collect();
+            let end = self.pos;
+            self.drain(0..end, Direction::Backward);
             self.pos = 0;
-            Some(text)
+            true
         } else {
-            None
+            false
         }
     }
 
@@ -289,27 +361,22 @@
         let mut sow = 0;
         let mut gis = self.buf[..pos].grapheme_indices(true).rev();
         'outer: for _ in 0..n {
+            sow = 0;
             let mut gj = gis.next();
             'inner: loop {
-                match gj {
-                    Some((j, y)) => {
-                        let gi = gis.next();
-                        match gi {
-                            Some((_, x)) => {
-                                if is_start_of_word(word_def, x, y) {
-                                    sow = j;
-                                    break 'inner;
-                                }
-                                gj = gi;
-                            }
-                            None => {
-                                break 'outer;
-                            }
+                if let Some((j, y)) = gj {
+                    let gi = gis.next();
+                    if let Some((_, x)) = gi {
+                        if is_start_of_word(word_def, x, y) {
+                            sow = j;
+                            break 'inner;
                         }
-                    }
-                    None => {
+                        gj = gi;
+                    } else {
                         break 'outer;
                     }
+                } else {
+                    break 'outer;
                 }
             }
         }
@@ -328,13 +395,14 @@
 
     /// Delete the previous word, maintaining the cursor at the start of the
     /// current word.
-    pub fn delete_prev_word(&mut self, word_def: Word, n: RepeatCount) -> Option<String> {
+    pub fn delete_prev_word(&mut self, word_def: Word, n: RepeatCount) -> bool {
         if let Some(pos) = self.prev_word_pos(self.pos, word_def, n) {
-            let word = self.buf.drain(pos..self.pos).collect();
+            let end = self.pos;
+            self.drain(pos..end, Direction::Backward);
             self.pos = pos;
-            Some(word)
+            true
         } else {
-            None
+            false
         }
     }
 
@@ -344,41 +412,36 @@
         }
         let mut wp = 0;
         let mut gis = self.buf[pos..].grapheme_indices(true);
-        let mut gi = if at != At::Start {
+        let mut gi = if at == At::BeforeEnd {
             // TODO Validate
             gis.next()
         } else {
             None
         };
         'outer: for _ in 0..n {
+            wp = 0;
             gi = gis.next();
             'inner: loop {
-                match gi {
-                    Some((i, x)) => {
-                        let gj = gis.next();
-                        match gj {
-                            Some((j, y)) => {
-                                if at == At::Start && is_start_of_word(word_def, x, y) {
-                                    wp = j;
-                                    break 'inner;
-                                } else if at != At::Start && is_end_of_word(word_def, x, y) {
-                                    if word_def == Word::Emacs || at == At::AfterEnd {
-                                        wp = j;
-                                    } else {
-                                        wp = i;
-                                    }
-                                    break 'inner;
-                                }
-                                gi = gj;
+                if let Some((i, x)) = gi {
+                    let gj = gis.next();
+                    if let Some((j, y)) = gj {
+                        if at == At::Start && is_start_of_word(word_def, x, y) {
+                            wp = j;
+                            break 'inner;
+                        } else if at != At::Start && is_end_of_word(word_def, x, y) {
+                            if word_def == Word::Emacs || at == At::AfterEnd {
+                                wp = j;
+                            } else {
+                                wp = i;
                             }
-                            None => {
-                                break 'outer;
-                            }
+                            break 'inner;
                         }
-                    }
-                    None => {
+                        gi = gj;
+                    } else {
                         break 'outer;
                     }
+                } else {
+                    break 'outer;
                 }
             }
         }
@@ -406,21 +469,17 @@
         }
     }
 
-    fn search_char_pos(&self, cs: &CharSearch, n: RepeatCount) -> Option<usize> {
+    fn search_char_pos(&self, cs: CharSearch, n: RepeatCount) -> Option<usize> {
         let mut shift = 0;
-        let search_result = match *cs {
-            CharSearch::Backward(c) |
-            CharSearch::BackwardAfter(c) => {
-                self.buf[..self.pos]
-                    .char_indices()
-                    .rev()
-                    .filter(|&(_, ch)| ch == c)
-                    .take(n)
-                    .last()
-                    .map(|(i, _)| i)
-            }
-            CharSearch::Forward(c) |
-            CharSearch::ForwardBefore(c) => {
+        let search_result = match cs {
+            CharSearch::Backward(c) | CharSearch::BackwardAfter(c) => self.buf[..self.pos]
+                .char_indices()
+                .rev()
+                .filter(|&(_, ch)| ch == c)
+                .take(n)
+                .last()
+                .map(|(i, _)| i),
+            CharSearch::Forward(c) | CharSearch::ForwardBefore(c) => {
                 if let Some(cc) = self.grapheme_at_cursor() {
                     shift = self.pos + cc.len();
                     if shift < self.buf.len() {
@@ -439,26 +498,27 @@
             }
         };
         if let Some(pos) = search_result {
-            Some(match *cs {
-                     CharSearch::Backward(_) => pos,
-                     CharSearch::BackwardAfter(c) => pos + c.len_utf8(),
-                     CharSearch::Forward(_) => shift + pos,
-                     CharSearch::ForwardBefore(_) => {
-                         shift + pos -
-                         self.buf[..shift + pos]
-                             .chars()
-                             .next_back()
-                             .unwrap()
-                             .len_utf8()
-                     }
-                 })
+            Some(match cs {
+                CharSearch::Backward(_) => pos,
+                CharSearch::BackwardAfter(c) => pos + c.len_utf8(),
+                CharSearch::Forward(_) => shift + pos,
+                CharSearch::ForwardBefore(_) => {
+                    shift + pos - self.buf[..shift + pos]
+                        .chars()
+                        .next_back()
+                        .unwrap()
+                        .len_utf8()
+                }
+            })
         } else {
             None
         }
     }
 
+    /// Move cursor to the matching character position.
+    /// Return `true` when the search succeeds.
     pub fn move_to(&mut self, cs: CharSearch, n: RepeatCount) -> bool {
-        if let Some(pos) = self.search_char_pos(&cs, n) {
+        if let Some(pos) = self.search_char_pos(cs, n) {
             self.pos = pos;
             true
         } else {
@@ -468,34 +528,40 @@
 
     /// Kill from the cursor to the end of the current word,
     /// or, if between words, to the end of the next word.
-    pub fn delete_word(&mut self, at: At, word_def: Word, n: RepeatCount) -> Option<String> {
+    pub fn delete_word(&mut self, at: At, word_def: Word, n: RepeatCount) -> bool {
         if let Some(pos) = self.next_word_pos(self.pos, at, word_def, n) {
-            let word = self.buf.drain(self.pos..pos).collect();
-            Some(word)
+            let start = self.pos;
+            self.drain(start..pos, Direction::Forward);
+            true
         } else {
-            None
+            false
         }
     }
 
-    pub fn delete_to(&mut self, cs: CharSearch, n: RepeatCount) -> Option<String> {
+    pub fn delete_to(&mut self, cs: CharSearch, n: RepeatCount) -> bool {
         let search_result = match cs {
-            CharSearch::ForwardBefore(c) => self.search_char_pos(&CharSearch::Forward(c), n),
-            _ => self.search_char_pos(&cs, n),
+            CharSearch::ForwardBefore(c) => self.search_char_pos(CharSearch::Forward(c), n),
+            _ => self.search_char_pos(cs, n),
         };
         if let Some(pos) = search_result {
-            let chunk = match cs {
-                CharSearch::Backward(_) |
-                CharSearch::BackwardAfter(_) => {
+            match cs {
+                CharSearch::Backward(_) | CharSearch::BackwardAfter(_) => {
                     let end = self.pos;
                     self.pos = pos;
-                    self.buf.drain(pos..end).collect()
+                    self.drain(pos..end, Direction::Backward);
                 }
-                CharSearch::ForwardBefore(_) => self.buf.drain(self.pos..pos).collect(),
-                CharSearch::Forward(c) => self.buf.drain(self.pos..pos + c.len_utf8()).collect(),
+                CharSearch::ForwardBefore(_) => {
+                    let start = self.pos;
+                    self.drain(start..pos, Direction::Forward);
+                }
+                CharSearch::Forward(c) => {
+                    let start = self.pos;
+                    self.drain(start..pos + c.len_utf8(), Direction::Forward);
+                }
             };
-            Some(chunk)
+            true
         } else {
-            None
+            false
         }
     }
 
@@ -510,6 +576,7 @@
             .next()
             .map(|i| i + self.pos)
     }
+
     /// Alter the next word.
     pub fn edit_word(&mut self, a: WordAction) -> bool {
         if let Some(start) = self.skip_whitespace() {
@@ -517,7 +584,9 @@
                 if start == end {
                     return false;
                 }
-                let word = self.buf.drain(start..end).collect::<String>();
+                let word = self
+                    .drain(start..end, Direction::default())
+                    .collect::<String>();
                 let result = match a {
                     WordAction::CAPITALIZE => {
                         let ch = (&word).graphemes(true).next().unwrap();
@@ -550,12 +619,14 @@
             return false;
         }
 
-        let w1 = self.buf[w1_beg..w1_end].to_string();
+        let w1 = self.buf[w1_beg..w1_end].to_owned();
 
-        let w2 = self.buf.drain(w2_beg..w2_end).collect::<String>();
+        let w2 = self
+            .drain(w2_beg..w2_end, Direction::default())
+            .collect::<String>();
         self.insert_str(w2_beg, &w1);
 
-        self.buf.drain(w1_beg..w1_end);
+        self.drain(w1_beg..w1_end, Direction::default());
         self.insert_str(w1_beg, &w2);
 
         self.pos = w2_end;
@@ -566,32 +637,67 @@
     /// and positions the cursor to the end of text.
     pub fn replace(&mut self, range: Range<usize>, text: &str) {
         let start = range.start;
+        for cl in &self.cl {
+            cl.borrow_mut()
+                .replace(start, self.buf.index(range.clone()), text);
+        }
         self.buf.drain(range);
-        self.insert_str(start, text);
+        if start == self.buf.len() {
+            self.buf.push_str(text);
+        } else {
+            self.buf.insert_str(start, text);
+        }
         self.pos = start + text.len();
     }
 
-    fn insert_str(&mut self, idx: usize, s: &str) -> bool {
+    /// Insert the `s`tring at the specified position.
+    /// Return `true` if the text has been inserted at the end of the line.
+    pub fn insert_str(&mut self, idx: usize, s: &str) -> bool {
+        for cl in &self.cl {
+            cl.borrow_mut().insert_str(idx, s);
+        }
         if idx == self.buf.len() {
             self.buf.push_str(s);
             true
         } else {
-            insert_str(&mut self.buf, idx, s);
+            self.buf.insert_str(idx, s);
             false
         }
     }
 
-    pub fn copy(&self, mvt: Movement) -> Option<String> {
+    /// Remove the specified `range` in the line.
+    pub fn delete_range(&mut self, range: Range<usize>) {
+        self.set_pos(range.start);
+        self.drain(range, Direction::default());
+    }
+
+    fn drain(&mut self, range: Range<usize>, dir: Direction) -> Drain {
+        for dl in &self.dl {
+            let mut lock = dl.try_lock();
+            if let Ok(mut dl) = lock {
+                dl.delete(range.start, &self.buf[range.start..range.end], dir);
+            }
+        }
+        for cl in &self.cl {
+            cl.borrow_mut()
+                .delete(range.start, &self.buf[range.start..range.end], dir);
+        }
+        self.buf.drain(range)
+    }
+
+    /// Return the content between current cursor position and `mvt` position.
+    /// Return `None` when the buffer is empty or when the movement fails.
+    pub fn copy(&self, mvt: &Movement) -> Option<String> {
         if self.is_empty() {
             return None;
         }
-        match mvt {
+        match *mvt {
             Movement::WholeLine => Some(self.buf.clone()),
             Movement::BeginningOfLine => {
                 if self.pos == 0 {
                     None
                 } else {
-                    Some(self.buf[..self.pos].to_string())
+                    Some(self.buf[..self.pos].to_owned())
                 }
             }
             Movement::ViFirstPrint => {
@@ -607,59 +713,111 @@
                 if self.pos == self.buf.len() {
                     None
                 } else {
-                    Some(self.buf[self.pos..].to_string())
+                    Some(self.buf[self.pos..].to_owned())
                 }
             }
             Movement::BackwardWord(n, word_def) => {
                 if let Some(pos) = self.prev_word_pos(self.pos, word_def, n) {
-                    Some(self.buf[pos..self.pos].to_string())
+                    Some(self.buf[pos..self.pos].to_owned())
                 } else {
                     None
                 }
             }
             Movement::ForwardWord(n, at, word_def) => {
                 if let Some(pos) = self.next_word_pos(self.pos, at, word_def, n) {
-                    Some(self.buf[self.pos..pos].to_string())
+                    Some(self.buf[self.pos..pos].to_owned())
                 } else {
                     None
                 }
             }
             Movement::ViCharSearch(n, cs) => {
                 let search_result = match cs {
-                    CharSearch::ForwardBefore(c) => {
-                        self.search_char_pos(&CharSearch::Forward(c), n)
-                    }
-                    _ => self.search_char_pos(&cs, n),
+                    CharSearch::ForwardBefore(c) => self.search_char_pos(CharSearch::Forward(c), n),
+                    _ => self.search_char_pos(cs, n),
                 };
                 if let Some(pos) = search_result {
                     Some(match cs {
-                             CharSearch::Backward(_) |
-                             CharSearch::BackwardAfter(_) => self.buf[pos..self.pos].to_string(),
-                             CharSearch::ForwardBefore(_) => self.buf[self.pos..pos].to_string(),
-                             CharSearch::Forward(c) => {
-                                 self.buf[self.pos..pos + c.len_utf8()].to_string()
-                             }
-                         })
+                        CharSearch::Backward(_) | CharSearch::BackwardAfter(_) => {
+                            self.buf[pos..self.pos].to_owned()
+                        }
+                        CharSearch::ForwardBefore(_) => self.buf[self.pos..pos].to_owned(),
+                        CharSearch::Forward(c) => self.buf[self.pos..pos + c.len_utf8()].to_owned(),
+                    })
                 } else {
                     None
                 }
             }
             Movement::BackwardChar(n) => {
                 if let Some(pos) = self.prev_pos(n) {
-                    Some(self.buf[pos..self.pos].to_string())
+                    Some(self.buf[pos..self.pos].to_owned())
                 } else {
                     None
                 }
             }
             Movement::ForwardChar(n) => {
                 if let Some(pos) = self.next_pos(n) {
-                    Some(self.buf[self.pos..pos].to_string())
+                    Some(self.buf[self.pos..pos].to_owned())
                 } else {
                     None
                 }
             }
         }
     }
+
+    pub fn kill(&mut self, mvt: &Movement) -> bool {
+        let notify = match *mvt {
+            Movement::ForwardChar(_) => false,
+            Movement::BackwardChar(_) => false,
+            _ => true,
+        };
+        if notify {
+            if let Some(dl) = self.dl.as_ref() {
+                let mut dl = dl.lock().unwrap();
+                dl.start_killing()
+            }
+        }
+        let killed = match *mvt {
+            Movement::ForwardChar(n) => {
+                // Delete (forward) `n` characters at point.
+                self.delete(n).is_some()
+            }
+            Movement::BackwardChar(n) => {
+                // Delete `n` characters backward.
+                self.backspace(n)
+            }
+            Movement::EndOfLine => {
+                // Kill the text from point to the end of the line.
+                self.kill_line()
+            }
+            Movement::WholeLine => {
+                self.move_home();
+                self.kill_line()
+            }
+            Movement::BeginningOfLine => {
+                // Kill backward from point to the beginning of the line.
+                self.discard_line()
+            }
+            Movement::BackwardWord(n, word_def) => {
+                // kill `n` words backward (until start of word)
+                self.delete_prev_word(word_def, n)
+            }
+            Movement::ForwardWord(n, at, word_def) => {
+                // kill `n` words forward (until start/end of word)
+                self.delete_word(at, word_def, n)
+            }
+            Movement::ViCharSearch(n, cs) => self.delete_to(cs, n),
+            Movement::ViFirstPrint => {
+                false // TODO
+            }
+        };
+        if notify {
+            if let Some(dl) = self.dl.as_ref() {
+                let mut dl = dl.lock().unwrap();
+                dl.stop_killing()
+            }
+        }
+        killed
+    }
 }
 
 impl Deref for LineBuffer {
@@ -670,73 +828,89 @@
     }
 }
 
-fn insert_str(buf: &mut String, idx: usize, s: &str) {
-    use std::ptr;
-
-    let len = buf.len();
-    assert!(idx <= len);
-    assert!(buf.is_char_boundary(idx));
-    let amt = s.len();
-    buf.reserve(amt);
-
-    unsafe {
-        let v = buf.as_mut_vec();
-        ptr::copy(v.as_ptr().offset(idx as isize),
-                  v.as_mut_ptr().offset((idx + amt) as isize),
-                  len - idx);
-        ptr::copy_nonoverlapping(s.as_ptr(), v.as_mut_ptr().offset(idx as isize), amt);
-        v.set_len(len + amt);
-    }
-}
-
 fn is_start_of_word(word_def: Word, previous: &str, grapheme: &str) -> bool {
-    (!is_word_char(word_def, previous) && is_word_char(word_def, grapheme)) ||
-    (word_def == Word::Vi && !is_other_char(previous) && is_other_char(grapheme))
+    (!is_word_char(word_def, previous) && is_word_char(word_def, grapheme))
+        || (word_def == Word::Vi && !is_other_char(previous) && is_other_char(grapheme))
 }
 fn is_end_of_word(word_def: Word, grapheme: &str, next: &str) -> bool {
-    (!is_word_char(word_def, next) && is_word_char(word_def, grapheme)) ||
-    (word_def == Word::Vi && !is_other_char(next) && is_other_char(grapheme))
+    (!is_word_char(word_def, next) && is_word_char(word_def, grapheme))
+        || (word_def == Word::Vi && !is_other_char(next) && is_other_char(grapheme))
 }
 
 fn is_word_char(word_def: Word, grapheme: &str) -> bool {
     match word_def {
         Word::Emacs => grapheme.chars().all(|c| c.is_alphanumeric()),
         Word::Vi => is_vi_word_char(grapheme),
-        Word::Big => !grapheme.chars().all(|c| c.is_whitespace()),
+        Word::Big => !grapheme.chars().any(|c| c.is_whitespace()),
     }
 }
 fn is_vi_word_char(grapheme: &str) -> bool {
     grapheme.chars().all(|c| c.is_alphanumeric()) || grapheme == "_"
 }
 fn is_other_char(grapheme: &str) -> bool {
-    !(grapheme.chars().all(|c| c.is_whitespace()) || is_vi_word_char(grapheme))
+    !(grapheme.chars().any(|c| c.is_whitespace()) || is_vi_word_char(grapheme))
 }
 
 #[cfg(test)]
 mod test {
+    use super::{ChangeListener, DeleteListener, Direction, LineBuffer, WordAction, MAX_LINE};
     use keymap::{At, CharSearch, Word};
-    use super::{LineBuffer, MAX_LINE, WordAction};
+    use std::cell::RefCell;
+    use std::rc::Rc;
+
+    struct Listener {
+        deleted_str: Option<String>,
+    }
+
+    impl Listener {
+        fn new() -> Rc<RefCell<Listener>> {
+            let l = Listener { deleted_str: None };
+            Rc::new(RefCell::new(l))
+        }
+
+        fn assert_deleted_str_eq(&self, expected: &str) {
+            let actual = self.deleted_str.as_ref().expect("no deleted string");
+            assert_eq!(expected, actual)
+        }
+    }
+
+    impl DeleteListener for Listener {
+        fn start_killing(&mut self) {}
+
+        fn delete(&mut self, _: usize, string: &str, _: Direction) {
+            self.deleted_str = Some(string.to_owned());
+        }
+
+        fn stop_killing(&mut self) {}
+    }
+    impl ChangeListener for Listener {
+        fn insert_char(&mut self, _: usize, _: char) {}
+
+        fn insert_str(&mut self, _: usize, _: &str) {}
+
+        fn replace(&mut self, _: usize, _: &str, _: &str) {}
+    }
 
     #[test]
     fn next_pos() {
-        let s = LineBuffer::init("ö̲g̈", 0);
+        let s = LineBuffer::init("ö̲g̈", 0, None);
         assert_eq!(7, s.len());
         let pos = s.next_pos(1);
         assert_eq!(Some(4), pos);
 
-        let s = LineBuffer::init("ö̲g̈", 4);
+        let s = LineBuffer::init("ö̲g̈", 4, None);
         let pos = s.next_pos(1);
         assert_eq!(Some(7), pos);
     }
 
     #[test]
     fn prev_pos() {
-        let s = LineBuffer::init("ö̲g̈", 4);
+        let s = LineBuffer::init("ö̲g̈", 4, None);
         assert_eq!(7, s.len());
         let pos = s.prev_pos(1);
         assert_eq!(Some(0), pos);
 
-        let s = LineBuffer::init("ö̲g̈", 7);
+        let s = LineBuffer::init("ö̲g̈", 7, None);
         let pos = s.prev_pos(1);
         assert_eq!(Some(4), pos);
     }
@@ -763,7 +937,7 @@
 
     #[test]
     fn yank_after() {
-        let mut s = LineBuffer::init("αß", 2);
+        let mut s = LineBuffer::init("αß", 2, None);
         s.move_forward(1);
         let ok = s.yank("γδε", 1);
         assert_eq!(Some(true), ok);
@@ -773,7 +947,7 @@
 
     #[test]
     fn yank_before() {
-        let mut s = LineBuffer::init("αε", 2);
+        let mut s = LineBuffer::init("αε", 2, None);
         let ok = s.yank("ßγδ", 1);
         assert_eq!(Some(false), ok);
         assert_eq!("αßγδε", s.buf);
@@ -782,7 +956,7 @@
 
     #[test]
     fn moves() {
-        let mut s = LineBuffer::init("αß", 4);
+        let mut s = LineBuffer::init("αß", 4, None);
         let ok = s.move_backward(1);
         assert_eq!("αß", s.buf);
         assert_eq!(2, s.pos);
@@ -806,7 +980,7 @@
 
     #[test]
     fn move_grapheme() {
-        let mut s = LineBuffer::init("ag̈", 4);
+        let mut s = LineBuffer::init("ag̈", 4, None);
         assert_eq!(4, s.len());
         let ok = s.move_backward(1);
         assert_eq!(true, ok);
@@ -819,36 +993,41 @@
 
     #[test]
     fn delete() {
-        let mut s = LineBuffer::init("αß", 2);
+        let cl = Listener::new();
+        let mut s = LineBuffer::init("αß", 2, Some(cl.clone()));
         let chars = s.delete(1);
         assert_eq!("α", s.buf);
         assert_eq!(2, s.pos);
-        assert_eq!(Some("ß".to_string()), chars);
+        assert_eq!(Some("ß".to_owned()), chars);
 
-        let chars = s.backspace(1);
+        let ok = s.backspace(1);
         assert_eq!("", s.buf);
         assert_eq!(0, s.pos);
-        assert_eq!(Some("α".to_string()), chars);
+        assert_eq!(true, ok);
+        cl.borrow().assert_deleted_str_eq("α");
     }
 
     #[test]
     fn kill() {
-        let mut s = LineBuffer::init("αßγδε", 6);
-        let text = s.kill_line();
+        let cl = Listener::new();
+        let mut s = LineBuffer::init("αßγδε", 6, Some(cl.clone()));
+        let ok = s.kill_line();
         assert_eq!("αßγ", s.buf);
         assert_eq!(6, s.pos);
-        assert_eq!(Some("δε".to_string()), text);
+        assert_eq!(true, ok);
+        cl.borrow().assert_deleted_str_eq("δε");
 
         s.pos = 4;
-        let text = s.discard_line();
+        let ok = s.discard_line();
         assert_eq!("γ", s.buf);
         assert_eq!(0, s.pos);
-        assert_eq!(Some("αß".to_string()), text);
+        assert_eq!(true, ok);
+        cl.borrow().assert_deleted_str_eq("αß");
     }
 
     #[test]
     fn transpose() {
-        let mut s = LineBuffer::init("aßc", 1);
+        let mut s = LineBuffer::init("aßc", 1, None);
         let ok = s.transpose_chars();
         assert_eq!("ßac", s.buf);
         assert_eq!(3, s.pos);
@@ -871,16 +1050,26 @@
 
     #[test]
     fn move_to_prev_word() {
-        let mut s = LineBuffer::init("a ß  c", 6);
+        let mut s = LineBuffer::init("a ß  c", 6, None); // before 'c'
         let ok = s.move_to_prev_word(Word::Emacs, 1);
         assert_eq!("a ß  c", s.buf);
-        assert_eq!(2, s.pos);
-        assert_eq!(true, ok);
+        assert_eq!(2, s.pos); // before 'ß'
+        assert!(true, ok);
+
+        assert!(s.move_end()); // after 'c'
+        assert_eq!(7, s.pos);
+        let ok = s.move_to_prev_word(Word::Emacs, 1);
+        assert!(true, ok);
+        assert_eq!(6, s.pos); // before 'c'
+
+        let ok = s.move_to_prev_word(Word::Emacs, 2);
+        assert!(true, ok);
+        assert_eq!(0, s.pos);
     }
 
     #[test]
     fn move_to_prev_vi_word() {
-        let mut s = LineBuffer::init("alpha ,beta/rho; mu", 19);
+        let mut s = LineBuffer::init("alpha ,beta/rho; mu", 19, None);
         let ok = s.move_to_prev_word(Word::Vi, 1);
         assert!(ok);
         assert_eq!(17, s.pos);
@@ -908,7 +1097,7 @@
 
     #[test]
     fn move_to_prev_big_word() {
-        let mut s = LineBuffer::init("alpha ,beta/rho; mu", 19);
+        let mut s = LineBuffer::init("alpha ,beta/rho; mu", 19, None);
         let ok = s.move_to_prev_word(Word::Big, 1);
         assert!(ok);
         assert_eq!(17, s.pos);
@@ -924,17 +1113,17 @@
 
     #[test]
     fn move_to_forward() {
-        let mut s = LineBuffer::init("αßγδε", 2);
+        let mut s = LineBuffer::init("αßγδε", 2, None);
         let ok = s.move_to(CharSearch::ForwardBefore('ε'), 1);
         assert_eq!(true, ok);
         assert_eq!(6, s.pos);
 
-        let mut s = LineBuffer::init("αßγδε", 2);
+        let mut s = LineBuffer::init("αßγδε", 2, None);
         let ok = s.move_to(CharSearch::Forward('ε'), 1);
         assert_eq!(true, ok);
         assert_eq!(8, s.pos);
 
-        let mut s = LineBuffer::init("αßγδε", 2);
+        let mut s = LineBuffer::init("αßγδε", 2, None);
         let ok = s.move_to(CharSearch::Forward('ε'), 10);
         assert_eq!(true, ok);
         assert_eq!(8, s.pos);
@@ -942,12 +1131,12 @@
 
     #[test]
     fn move_to_backward() {
-        let mut s = LineBuffer::init("αßγδε", 8);
+        let mut s = LineBuffer::init("αßγδε", 8, None);
         let ok = s.move_to(CharSearch::BackwardAfter('ß'), 1);
         assert_eq!(true, ok);
         assert_eq!(4, s.pos);
 
-        let mut s = LineBuffer::init("αßγδε", 8);
+        let mut s = LineBuffer::init("αßγδε", 8, None);
         let ok = s.move_to(CharSearch::Backward('ß'), 1);
         assert_eq!(true, ok);
         assert_eq!(2, s.pos);
@@ -955,25 +1144,40 @@
 
     #[test]
     fn delete_prev_word() {
-        let mut s = LineBuffer::init("a ß  c", 6);
-        let text = s.delete_prev_word(Word::Big, 1);
+        let cl = Listener::new();
+        let mut s = LineBuffer::init("a ß  c", 6, Some(cl.clone()));
+        let ok = s.delete_prev_word(Word::Big, 1);
         assert_eq!("a c", s.buf);
         assert_eq!(2, s.pos);
-        assert_eq!(Some("ß  ".to_string()), text);
+        assert_eq!(true, ok);
+        cl.borrow().assert_deleted_str_eq("ß  ");
     }
 
     #[test]
     fn move_to_next_word() {
-        let mut s = LineBuffer::init("a ß  c", 1);
+        let mut s = LineBuffer::init("a ß  c", 1, None); // after 'a'
         let ok = s.move_to_next_word(At::AfterEnd, Word::Emacs, 1);
         assert_eq!("a ß  c", s.buf);
-        assert_eq!(4, s.pos);
         assert_eq!(true, ok);
+        assert_eq!(4, s.pos); // after 'ß'
+
+        let ok = s.move_to_next_word(At::AfterEnd, Word::Emacs, 1);
+        assert_eq!(true, ok);
+        assert_eq!(7, s.pos); // after 'c'
+
+        s.move_home();
+        let ok = s.move_to_next_word(At::AfterEnd, Word::Emacs, 1);
+        assert_eq!(true, ok);
+        assert_eq!(1, s.pos); // after 'a'
+
+        let ok = s.move_to_next_word(At::AfterEnd, Word::Emacs, 2);
+        assert_eq!(true, ok);
+        assert_eq!(7, s.pos); // after 'c'
     }
 
     #[test]
     fn move_to_end_of_word() {
-        let mut s = LineBuffer::init("a ßeta  c", 1);
+        let mut s = LineBuffer::init("a ßeta  c", 1, None);
         let ok = s.move_to_next_word(At::BeforeEnd, Word::Vi, 1);
         assert_eq!("a ßeta  c", s.buf);
         assert_eq!(6, s.pos);
@@ -982,7 +1186,7 @@
 
     #[test]
     fn move_to_end_of_vi_word() {
-        let mut s = LineBuffer::init("alpha ,beta/rho; mu", 0);
+        let mut s = LineBuffer::init("alpha ,beta/rho; mu", 0, None);
         let ok = s.move_to_next_word(At::BeforeEnd, Word::Vi, 1);
         assert!(ok);
         assert_eq!(4, s.pos);
@@ -1010,7 +1214,7 @@
 
     #[test]
     fn move_to_end_of_big_word() {
-        let mut s = LineBuffer::init("alpha ,beta/rho; mu", 0);
+        let mut s = LineBuffer::init("alpha ,beta/rho; mu", 0, None);
         let ok = s.move_to_next_word(At::BeforeEnd, Word::Big, 1);
         assert!(ok);
         assert_eq!(4, s.pos);
@@ -1026,7 +1230,7 @@
 
     #[test]
     fn move_to_start_of_word() {
-        let mut s = LineBuffer::init("a ß  c", 2);
+        let mut s = LineBuffer::init("a ß  c", 2, None);
         let ok = s.move_to_next_word(At::Start, Word::Emacs, 1);
         assert_eq!("a ß  c", s.buf);
         assert_eq!(6, s.pos);
@@ -1035,7 +1239,7 @@
 
     #[test]
     fn move_to_start_of_vi_word() {
-        let mut s = LineBuffer::init("alpha ,beta/rho; mu", 0);
+        let mut s = LineBuffer::init("alpha ,beta/rho; mu", 0, None);
         let ok = s.move_to_next_word(At::Start, Word::Vi, 1);
         assert!(ok);
         assert_eq!(6, s.pos);
@@ -1063,7 +1267,7 @@
 
     #[test]
     fn move_to_start_of_big_word() {
-        let mut s = LineBuffer::init("alpha ,beta/rho; mu", 0);
+        let mut s = LineBuffer::init("alpha ,beta/rho; mu", 0, None);
         let ok = s.move_to_next_word(At::Start, Word::Big, 1);
         assert!(ok);
         assert_eq!(6, s.pos);
@@ -1079,76 +1283,87 @@
 
     #[test]
     fn delete_word() {
-        let mut s = LineBuffer::init("a ß  c", 1);
-        let text = s.delete_word(At::AfterEnd, Word::Emacs, 1);
+        let cl = Listener::new();
+        let mut s = LineBuffer::init("a ß  c", 1, Some(cl.clone()));
+        let ok = s.delete_word(At::AfterEnd, Word::Emacs, 1);
         assert_eq!("a  c", s.buf);
         assert_eq!(1, s.pos);
-        assert_eq!(Some(" ß".to_string()), text);
+        assert_eq!(true, ok);
+        cl.borrow().assert_deleted_str_eq(" ß");
 
-        let mut s = LineBuffer::init("test", 0);
-        let text = s.delete_word(At::AfterEnd, Word::Vi, 1);
+        let mut s = LineBuffer::init("test", 0, Some(cl.clone()));
+        let ok = s.delete_word(At::AfterEnd, Word::Vi, 1);
         assert_eq!("", s.buf);
         assert_eq!(0, s.pos);
-        assert_eq!(Some("test".to_string()), text);
+        assert_eq!(true, ok);
+        cl.borrow().assert_deleted_str_eq("test");
     }
 
     #[test]
     fn delete_til_start_of_word() {
-        let mut s = LineBuffer::init("a ß  c", 2);
-        let text = s.delete_word(At::Start, Word::Emacs, 1);
+        let cl = Listener::new();
+        let mut s = LineBuffer::init("a ß  c", 2, Some(cl.clone()));
+        let ok = s.delete_word(At::Start, Word::Emacs, 1);
         assert_eq!("a c", s.buf);
         assert_eq!(2, s.pos);
-        assert_eq!(Some("ß  ".to_string()), text);
+        assert_eq!(true, ok);
+        cl.borrow().assert_deleted_str_eq("ß  ");
     }
 
     #[test]
     fn delete_to_forward() {
-        let mut s = LineBuffer::init("αßγδε", 2);
-        let text = s.delete_to(CharSearch::ForwardBefore('ε'), 1);
-        assert_eq!(Some("ßγδ".to_string()), text);
+        let cl = Listener::new();
+        let mut s = LineBuffer::init("αßγδε", 2, Some(cl.clone()));
+        let ok = s.delete_to(CharSearch::ForwardBefore('ε'), 1);
+        assert_eq!(true, ok);
+        cl.borrow().assert_deleted_str_eq("ßγδ");
         assert_eq!("αε", s.buf);
         assert_eq!(2, s.pos);
 
-        let mut s = LineBuffer::init("αßγδε", 2);
-        let text = s.delete_to(CharSearch::Forward('ε'), 1);
-        assert_eq!(Some("ßγδε".to_string()), text);
+        let mut s = LineBuffer::init("αßγδε", 2, Some(cl.clone()));
+        let ok = s.delete_to(CharSearch::Forward('ε'), 1);
+        assert_eq!(true, ok);
+        cl.borrow().assert_deleted_str_eq("ßγδε");
         assert_eq!("α", s.buf);
         assert_eq!(2, s.pos);
     }
 
     #[test]
     fn delete_to_backward() {
-        let mut s = LineBuffer::init("αßγδε", 8);
-        let text = s.delete_to(CharSearch::BackwardAfter('α'), 1);
-        assert_eq!(Some("ßγδ".to_string()), text);
+        let cl = Listener::new();
+        let mut s = LineBuffer::init("αßγδε", 8, Some(cl.clone()));
+        let ok = s.delete_to(CharSearch::BackwardAfter('α'), 1);
+        assert_eq!(true, ok);
+        cl.borrow().assert_deleted_str_eq("ßγδ");
         assert_eq!("αε", s.buf);
         assert_eq!(2, s.pos);
 
-        let mut s = LineBuffer::init("αßγδε", 8);
-        let text = s.delete_to(CharSearch::Backward('ß'), 1);
-        assert_eq!(Some("ßγδ".to_string()), text);
+        let mut s = LineBuffer::init("αßγδε", 8, Some(cl.clone()));
+        let ok = s.delete_to(CharSearch::Backward('ß'), 1);
+        assert_eq!(true, ok);
+        cl.borrow().assert_deleted_str_eq("ßγδ");
         assert_eq!("αε", s.buf);
         assert_eq!(2, s.pos);
     }
 
     #[test]
     fn edit_word() {
-        let mut s = LineBuffer::init("a ßeta  c", 1);
+        let mut s = LineBuffer::init("a ßeta  c", 1, None);
         assert!(s.edit_word(WordAction::UPPERCASE));
         assert_eq!("a SSETA  c", s.buf);
         assert_eq!(7, s.pos);
 
-        let mut s = LineBuffer::init("a ßetA  c", 1);
+        let mut s = LineBuffer::init("a ßetA  c", 1, None);
         assert!(s.edit_word(WordAction::LOWERCASE));
         assert_eq!("a ßeta  c", s.buf);
         assert_eq!(7, s.pos);
 
-        let mut s = LineBuffer::init("a ßETA  c", 1);
+        let mut s = LineBuffer::init("a ßETA  c", 1, None);
         assert!(s.edit_word(WordAction::CAPITALIZE));
         assert_eq!("a SSeta  c", s.buf);
         assert_eq!(7, s.pos);
 
-        let mut s = LineBuffer::init("test", 1);
+        let mut s = LineBuffer::init("test", 1, None);
         assert!(s.edit_word(WordAction::CAPITALIZE));
         assert_eq!("tEst", s.buf);
         assert_eq!(4, s.pos);
@@ -1156,20 +1371,20 @@
 
     #[test]
     fn transpose_words() {
-        let mut s = LineBuffer::init("ßeta / δelta__", 15);
+        let mut s = LineBuffer::init("ßeta / δelta__", 15, None);
         assert!(s.transpose_words(1));
         assert_eq!("δelta__ / ßeta", s.buf);
         assert_eq!(16, s.pos);
 
-        let mut s = LineBuffer::init("ßeta / δelta", 14);
+        let mut s = LineBuffer::init("ßeta / δelta", 14, None);
         assert!(s.transpose_words(1));
         assert_eq!("δelta / ßeta", s.buf);
         assert_eq!(14, s.pos);
 
-        let mut s = LineBuffer::init(" / δelta", 8);
+        let mut s = LineBuffer::init(" / δelta", 8, None);
         assert!(!s.transpose_words(1));
 
-        let mut s = LineBuffer::init("ßeta / __", 9);
+        let mut s = LineBuffer::init("ßeta / __", 9, None);
         assert!(!s.transpose_words(1));
     }
 }
diff --git a/src/test/common.rs b/src/test/common.rs
new file mode 100644
index 0000000..29bde74
--- /dev/null
+++ b/src/test/common.rs
@@ -0,0 +1,401 @@
+///! Basic commands tests.
+use super::{assert_cursor, assert_line, assert_line_with_initial, init_editor};
+use config::EditMode;
+use error::ReadlineError;
+use keys::KeyPress;
+
+#[test]
+fn home_key() {
+    for mode in &[EditMode::Emacs, EditMode::Vi] {
+        assert_cursor(
+            *mode,
+            ("", ""),
+            &[KeyPress::Home, KeyPress::Enter],
+            ("", ""),
+        );
+        assert_cursor(
+            *mode,
+            ("Hi", ""),
+            &[KeyPress::Home, KeyPress::Enter],
+            ("", "Hi"),
+        );
+        if *mode == EditMode::Vi {
+            // vi command mode
+            assert_cursor(
+                *mode,
+                ("Hi", ""),
+                &[KeyPress::Esc, KeyPress::Home, KeyPress::Enter],
+                ("", "Hi"),
+            );
+        }
+    }
+}
+
+#[test]
+fn end_key() {
+    for mode in &[EditMode::Emacs, EditMode::Vi] {
+        assert_cursor(*mode, ("", ""), &[KeyPress::End, KeyPress::Enter], ("", ""));
+        assert_cursor(
+            *mode,
+            ("H", "i"),
+            &[KeyPress::End, KeyPress::Enter],
+            ("Hi", ""),
+        );
+        assert_cursor(
+            *mode,
+            ("", "Hi"),
+            &[KeyPress::End, KeyPress::Enter],
+            ("Hi", ""),
+        );
+        if *mode == EditMode::Vi {
+            // vi command mode
+            assert_cursor(
+                *mode,
+                ("", "Hi"),
+                &[KeyPress::Esc, KeyPress::End, KeyPress::Enter],
+                ("Hi", ""),
+            );
+        }
+    }
+}
+
+#[test]
+fn left_key() {
+    for mode in &[EditMode::Emacs, EditMode::Vi] {
+        assert_cursor(
+            *mode,
+            ("Hi", ""),
+            &[KeyPress::Left, KeyPress::Enter],
+            ("H", "i"),
+        );
+        assert_cursor(
+            *mode,
+            ("H", "i"),
+            &[KeyPress::Left, KeyPress::Enter],
+            ("", "Hi"),
+        );
+        assert_cursor(
+            *mode,
+            ("", "Hi"),
+            &[KeyPress::Left, KeyPress::Enter],
+            ("", "Hi"),
+        );
+        if *mode == EditMode::Vi {
+            // vi command mode
+            assert_cursor(
+                *mode,
+                ("Bye", ""),
+                &[KeyPress::Esc, KeyPress::Left, KeyPress::Enter],
+                ("B", "ye"),
+            );
+        }
+    }
+}
+
+#[test]
+fn right_key() {
+    for mode in &[EditMode::Emacs, EditMode::Vi] {
+        assert_cursor(
+            *mode,
+            ("", ""),
+            &[KeyPress::Right, KeyPress::Enter],
+            ("", ""),
+        );
+        assert_cursor(
+            *mode,
+            ("", "Hi"),
+            &[KeyPress::Right, KeyPress::Enter],
+            ("H", "i"),
+        );
+        assert_cursor(
+            *mode,
+            ("B", "ye"),
+            &[KeyPress::Right, KeyPress::Enter],
+            ("By", "e"),
+        );
+        assert_cursor(
+            *mode,
+            ("H", "i"),
+            &[KeyPress::Right, KeyPress::Enter],
+            ("Hi", ""),
+        );
+        if *mode == EditMode::Vi {
+            // vi command mode
+            assert_cursor(
+                *mode,
+                ("", "Hi"),
+                &[KeyPress::Esc, KeyPress::Right, KeyPress::Enter],
+                ("H", "i"),
+            );
+        }
+    }
+}
+
+#[test]
+fn enter_key() {
+    for mode in &[EditMode::Emacs, EditMode::Vi] {
+        assert_line(*mode, &[KeyPress::Enter], "");
+        assert_line(*mode, &[KeyPress::Char('a'), KeyPress::Enter], "a");
+        assert_line_with_initial(*mode, ("Hi", ""), &[KeyPress::Enter], "Hi");
+        assert_line_with_initial(*mode, ("", "Hi"), &[KeyPress::Enter], "Hi");
+        assert_line_with_initial(*mode, ("H", "i"), &[KeyPress::Enter], "Hi");
+        if *mode == EditMode::Vi {
+            // vi command mode
+            assert_line(*mode, &[KeyPress::Esc, KeyPress::Enter], "");
+            assert_line(
+                *mode,
+                &[KeyPress::Char('a'), KeyPress::Esc, KeyPress::Enter],
+                "a",
+            );
+            assert_line_with_initial(*mode, ("Hi", ""), &[KeyPress::Esc, KeyPress::Enter], "Hi");
+            assert_line_with_initial(*mode, ("", "Hi"), &[KeyPress::Esc, KeyPress::Enter], "Hi");
+            assert_line_with_initial(*mode, ("H", "i"), &[KeyPress::Esc, KeyPress::Enter], "Hi");
+        }
+    }
+}
+
+#[test]
+fn newline_key() {
+    for mode in &[EditMode::Emacs, EditMode::Vi] {
+        assert_line(*mode, &[KeyPress::Ctrl('J')], "");
+        assert_line(*mode, &[KeyPress::Char('a'), KeyPress::Ctrl('J')], "a");
+        if *mode == EditMode::Vi {
+            // vi command mode
+            assert_line(*mode, &[KeyPress::Esc, KeyPress::Ctrl('J')], "");
+            assert_line(
+                *mode,
+                &[KeyPress::Char('a'), KeyPress::Esc, KeyPress::Ctrl('J')],
+                "a",
+            );
+        }
+    }
+}
+
+#[test]
+fn eof_key() {
+    for mode in &[EditMode::Emacs, EditMode::Vi] {
+        let mut editor = init_editor(*mode, &[KeyPress::Ctrl('D')]);
+        let err = editor.readline(">>");
+        assert_matches!(err, Err(ReadlineError::Eof));
+    }
+    assert_line(
+        EditMode::Emacs,
+        &[KeyPress::Char('a'), KeyPress::Ctrl('D'), KeyPress::Enter],
+        "a",
+    );
+    assert_line(
+        EditMode::Vi,
+        &[KeyPress::Char('a'), KeyPress::Ctrl('D')],
+        "a",
+    );
+    assert_line(
+        EditMode::Vi,
+        &[KeyPress::Char('a'), KeyPress::Esc, KeyPress::Ctrl('D')],
+        "a",
+    );
+    assert_line_with_initial(
+        EditMode::Emacs,
+        ("", "Hi"),
+        &[KeyPress::Ctrl('D'), KeyPress::Enter],
+        "i",
+    );
+    assert_line_with_initial(EditMode::Vi, ("", "Hi"), &[KeyPress::Ctrl('D')], "Hi");
+    assert_line_with_initial(
+        EditMode::Vi,
+        ("", "Hi"),
+        &[KeyPress::Esc, KeyPress::Ctrl('D')],
+        "Hi",
+    );
+}
+
+#[test]
+fn interrupt_key() {
+    for mode in &[EditMode::Emacs, EditMode::Vi] {
+        let mut editor = init_editor(*mode, &[KeyPress::Ctrl('C')]);
+        let err = editor.readline(">>");
+        assert_matches!(err, Err(ReadlineError::Interrupted));
+
+        let mut editor = init_editor(*mode, &[KeyPress::Ctrl('C')]);
+        let err = editor.readline_with_initial(">>", ("Hi", ""));
+        assert_matches!(err, Err(ReadlineError::Interrupted));
+        if *mode == EditMode::Vi {
+            // vi command mode
+            let mut editor = init_editor(*mode, &[KeyPress::Esc, KeyPress::Ctrl('C')]);
+            let err = editor.readline_with_initial(">>", ("Hi", ""));
+            assert_matches!(err, Err(ReadlineError::Interrupted));
+        }
+    }
+}
+
+#[test]
+fn delete_key() {
+    for mode in &[EditMode::Emacs, EditMode::Vi] {
+        assert_cursor(
+            *mode,
+            ("a", ""),
+            &[KeyPress::Delete, KeyPress::Enter],
+            ("a", ""),
+        );
+        assert_cursor(
+            *mode,
+            ("", "a"),
+            &[KeyPress::Delete, KeyPress::Enter],
+            ("", ""),
+        );
+        if *mode == EditMode::Vi {
+            // vi command mode
+            assert_cursor(
+                *mode,
+                ("", "a"),
+                &[KeyPress::Esc, KeyPress::Delete, KeyPress::Enter],
+                ("", ""),
+            );
+        }
+    }
+}
+
+#[test]
+fn ctrl_t() {
+    for mode in &[EditMode::Emacs, EditMode::Vi] {
+        assert_cursor(
+            *mode,
+            ("a", "b"),
+            &[KeyPress::Ctrl('T'), KeyPress::Enter],
+            ("ba", ""),
+        );
+        assert_cursor(
+            *mode,
+            ("ab", "cd"),
+            &[KeyPress::Ctrl('T'), KeyPress::Enter],
+            ("acb", "d"),
+        );
+        if *mode == EditMode::Vi {
+            // vi command mode
+            assert_cursor(
+                *mode,
+                ("ab", ""),
+                &[KeyPress::Esc, KeyPress::Ctrl('T'), KeyPress::Enter],
+                ("ba", ""),
+            );
+        }
+    }
+}
+
+#[test]
+fn ctrl_u() {
+    for mode in &[EditMode::Emacs, EditMode::Vi] {
+        assert_cursor(
+            *mode,
+            ("start of line ", "end"),
+            &[KeyPress::Ctrl('U'), KeyPress::Enter],
+            ("", "end"),
+        );
+        assert_cursor(
+            *mode,
+            ("", "end"),
+            &[KeyPress::Ctrl('U'), KeyPress::Enter],
+            ("", "end"),
+        );
+        if *mode == EditMode::Vi {
+            // vi command mode
+            assert_cursor(
+                *mode,
+                ("start of line ", "end"),
+                &[KeyPress::Esc, KeyPress::Ctrl('U'), KeyPress::Enter],
+                ("", " end"),
+            );
+        }
+    }
+}
+
+#[cfg(unix)]
+#[test]
+fn ctrl_v() {
+    for mode in &[EditMode::Emacs, EditMode::Vi] {
+        assert_cursor(
+            *mode,
+            ("", ""),
+            &[KeyPress::Ctrl('V'), KeyPress::Char('\t'), KeyPress::Enter],
+            ("\t", ""),
+        );
+        if *mode == EditMode::Vi {
+            // vi command mode
+            assert_cursor(
+                *mode,
+                ("", ""),
+                &[
+                    KeyPress::Esc,
+                    KeyPress::Ctrl('V'),
+                    KeyPress::Char('\t'),
+                    KeyPress::Enter,
+                ],
+                ("\t", ""),
+            );
+        }
+    }
+}
+
+#[test]
+fn ctrl_w() {
+    for mode in &[EditMode::Emacs, EditMode::Vi] {
+        assert_cursor(
+            *mode,
+            ("Hello, ", "world"),
+            &[KeyPress::Ctrl('W'), KeyPress::Enter],
+            ("", "world"),
+        );
+        assert_cursor(
+            *mode,
+            ("Hello, world.", ""),
+            &[KeyPress::Ctrl('W'), KeyPress::Enter],
+            ("Hello, ", ""),
+        );
+        if *mode == EditMode::Vi {
+            // vi command mode
+            assert_cursor(
+                *mode,
+                ("Hello, world.", ""),
+                &[KeyPress::Esc, KeyPress::Ctrl('W'), KeyPress::Enter],
+                ("Hello, ", "."),
+            );
+        }
+    }
+}
+
+#[test]
+fn ctrl_y() {
+    for mode in &[EditMode::Emacs /* FIXME, EditMode::Vi */] {
+        assert_cursor(
+            *mode,
+            ("Hello, ", "world"),
+            &[KeyPress::Ctrl('W'), KeyPress::Ctrl('Y'), KeyPress::Enter],
+            ("Hello, ", "world"),
+        );
+    }
+}
+
+#[test]
+fn ctrl__() {
+    for mode in &[EditMode::Emacs, EditMode::Vi] {
+        assert_cursor(
+            *mode,
+            ("Hello, ", "world"),
+            &[KeyPress::Ctrl('W'), KeyPress::Ctrl('_'), KeyPress::Enter],
+            ("Hello, ", "world"),
+        );
+        if *mode == EditMode::Vi {
+            // vi command mode
+            assert_cursor(
+                *mode,
+                ("Hello, ", "world"),
+                &[
+                    KeyPress::Esc,
+                    KeyPress::Ctrl('W'),
+                    KeyPress::Ctrl('_'),
+                    KeyPress::Enter,
+                ],
+                ("Hello,", " world"),
+            );
+        }
+    }
+}
diff --git a/src/test/emacs.rs b/src/test/emacs.rs
new file mode 100644
index 0000000..a4c738e
--- /dev/null
+++ b/src/test/emacs.rs
@@ -0,0 +1,378 @@
+//! Emacs specific key bindings
+use super::{assert_cursor, assert_history};
+use config::EditMode;
+use keys::KeyPress;
+
+#[test]
+fn ctrl_a() {
+    assert_cursor(
+        EditMode::Emacs,
+        ("Hi", ""),
+        &[KeyPress::Ctrl('A'), KeyPress::Enter],
+        ("", "Hi"),
+    );
+}
+
+#[test]
+fn ctrl_e() {
+    assert_cursor(
+        EditMode::Emacs,
+        ("", "Hi"),
+        &[KeyPress::Ctrl('E'), KeyPress::Enter],
+        ("Hi", ""),
+    );
+}
+
+#[test]
+fn ctrl_b() {
+    assert_cursor(
+        EditMode::Emacs,
+        ("Hi", ""),
+        &[KeyPress::Ctrl('B'), KeyPress::Enter],
+        ("H", "i"),
+    );
+    assert_cursor(
+        EditMode::Emacs,
+        ("Hi", ""),
+        &[KeyPress::Meta('2'), KeyPress::Ctrl('B'), KeyPress::Enter],
+        ("", "Hi"),
+    );
+    assert_cursor(
+        EditMode::Emacs,
+        ("", "Hi"),
+        &[
+            KeyPress::Meta('-'),
+            KeyPress::Meta('2'),
+            KeyPress::Ctrl('B'),
+            KeyPress::Enter,
+        ],
+        ("Hi", ""),
+    );
+}
+
+#[test]
+fn ctrl_f() {
+    assert_cursor(
+        EditMode::Emacs,
+        ("", "Hi"),
+        &[KeyPress::Ctrl('F'), KeyPress::Enter],
+        ("H", "i"),
+    );
+    assert_cursor(
+        EditMode::Emacs,
+        ("", "Hi"),
+        &[KeyPress::Meta('2'), KeyPress::Ctrl('F'), KeyPress::Enter],
+        ("Hi", ""),
+    );
+    assert_cursor(
+        EditMode::Emacs,
+        ("Hi", ""),
+        &[
+            KeyPress::Meta('-'),
+            KeyPress::Meta('2'),
+            KeyPress::Ctrl('F'),
+            KeyPress::Enter,
+        ],
+        ("", "Hi"),
+    );
+}
+
+#[test]
+fn ctrl_h() {
+    assert_cursor(
+        EditMode::Emacs,
+        ("Hi", ""),
+        &[KeyPress::Ctrl('H'), KeyPress::Enter],
+        ("H", ""),
+    );
+    assert_cursor(
+        EditMode::Emacs,
+        ("Hi", ""),
+        &[KeyPress::Meta('2'), KeyPress::Ctrl('H'), KeyPress::Enter],
+        ("", ""),
+    );
+    assert_cursor(
+        EditMode::Emacs,
+        ("", "Hi"),
+        &[
+            KeyPress::Meta('-'),
+            KeyPress::Meta('2'),
+            KeyPress::Ctrl('H'),
+            KeyPress::Enter,
+        ],
+        ("", ""),
+    );
+}
+
+#[test]
+fn backspace() {
+    assert_cursor(
+        EditMode::Emacs,
+        ("", ""),
+        &[KeyPress::Backspace, KeyPress::Enter],
+        ("", ""),
+    );
+    assert_cursor(
+        EditMode::Emacs,
+        ("Hi", ""),
+        &[KeyPress::Backspace, KeyPress::Enter],
+        ("H", ""),
+    );
+    assert_cursor(
+        EditMode::Emacs,
+        ("", "Hi"),
+        &[KeyPress::Backspace, KeyPress::Enter],
+        ("", "Hi"),
+    );
+}
+
+#[test]
+fn ctrl_k() {
+    assert_cursor(
+        EditMode::Emacs,
+        ("Hi", ""),
+        &[KeyPress::Ctrl('K'), KeyPress::Enter],
+        ("Hi", ""),
+    );
+    assert_cursor(
+        EditMode::Emacs,
+        ("", "Hi"),
+        &[KeyPress::Ctrl('K'), KeyPress::Enter],
+        ("", ""),
+    );
+    assert_cursor(
+        EditMode::Emacs,
+        ("B", "ye"),
+        &[KeyPress::Ctrl('K'), KeyPress::Enter],
+        ("B", ""),
+    );
+}
+
+#[test]
+fn ctrl_n() {
+    assert_history(
+        EditMode::Emacs,
+        &["line1", "line2"],
+        &[
+            KeyPress::Ctrl('P'),
+            KeyPress::Ctrl('P'),
+            KeyPress::Ctrl('N'),
+            KeyPress::Enter,
+        ],
+        ("line2", ""),
+    );
+}
+
+#[test]
+fn ctrl_p() {
+    assert_history(
+        EditMode::Emacs,
+        &["line1"],
+        &[KeyPress::Ctrl('P'), KeyPress::Enter],
+        ("line1", ""),
+    );
+}
+
+#[test]
+fn ctrl_t() {
+    /* FIXME
+    assert_cursor(
+        ("ab", "cd"),
+        &[KeyPress::Meta('2'), KeyPress::Ctrl('T'), KeyPress::Enter],
+        ("acdb", ""),
+    );*/
+}
+
+#[test]
+fn ctrl_x_ctrl_u() {
+    assert_cursor(
+        EditMode::Emacs,
+        ("Hello, ", "world"),
+        &[
+            KeyPress::Ctrl('W'),
+            KeyPress::Ctrl('X'),
+            KeyPress::Ctrl('U'),
+            KeyPress::Enter,
+        ],
+        ("Hello, ", "world"),
+    );
+}
+
+#[test]
+fn meta_b() {
+    assert_cursor(
+        EditMode::Emacs,
+        ("Hello, world!", ""),
+        &[KeyPress::Meta('B'), KeyPress::Enter],
+        ("Hello, ", "world!"),
+    );
+    assert_cursor(
+        EditMode::Emacs,
+        ("Hello, world!", ""),
+        &[KeyPress::Meta('2'), KeyPress::Meta('B'), KeyPress::Enter],
+        ("", "Hello, world!"),
+    );
+    assert_cursor(
+        EditMode::Emacs,
+        ("", "Hello, world!"),
+        &[KeyPress::Meta('-'), KeyPress::Meta('B'), KeyPress::Enter],
+        ("Hello", ", world!"),
+    );
+}
+
+#[test]
+fn meta_f() {
+    assert_cursor(
+        EditMode::Emacs,
+        ("", "Hello, world!"),
+        &[KeyPress::Meta('F'), KeyPress::Enter],
+        ("Hello", ", world!"),
+    );
+    assert_cursor(
+        EditMode::Emacs,
+        ("", "Hello, world!"),
+        &[KeyPress::Meta('2'), KeyPress::Meta('F'), KeyPress::Enter],
+        ("Hello, world", "!"),
+    );
+    assert_cursor(
+        EditMode::Emacs,
+        ("Hello, world!", ""),
+        &[KeyPress::Meta('-'), KeyPress::Meta('F'), KeyPress::Enter],
+        ("Hello, ", "world!"),
+    );
+}
+
+#[test]
+fn meta_c() {
+    assert_cursor(
+        EditMode::Emacs,
+        ("hi", ""),
+        &[KeyPress::Meta('C'), KeyPress::Enter],
+        ("hi", ""),
+    );
+    assert_cursor(
+        EditMode::Emacs,
+        ("", "hi"),
+        &[KeyPress::Meta('C'), KeyPress::Enter],
+        ("Hi", ""),
+    );
+    /* FIXME
+    assert_cursor(
+        ("", "hi test"),
+        &[KeyPress::Meta('2'), KeyPress::Meta('C'), KeyPress::Enter],
+        ("Hi Test", ""),
+    );*/
+}
+
+#[test]
+fn meta_l() {
+    assert_cursor(
+        EditMode::Emacs,
+        ("Hi", ""),
+        &[KeyPress::Meta('L'), KeyPress::Enter],
+        ("Hi", ""),
+    );
+    assert_cursor(
+        EditMode::Emacs,
+        ("", "HI"),
+        &[KeyPress::Meta('L'), KeyPress::Enter],
+        ("hi", ""),
+    );
+    /* FIXME
+    assert_cursor(
+        ("", "HI TEST"),
+        &[KeyPress::Meta('2'), KeyPress::Meta('L'), KeyPress::Enter],
+        ("hi test", ""),
+    );*/
+}
+
+#[test]
+fn meta_u() {
+    assert_cursor(
+        EditMode::Emacs,
+        ("hi", ""),
+        &[KeyPress::Meta('U'), KeyPress::Enter],
+        ("hi", ""),
+    );
+    assert_cursor(
+        EditMode::Emacs,
+        ("", "hi"),
+        &[KeyPress::Meta('U'), KeyPress::Enter],
+        ("HI", ""),
+    );
+    /* FIXME
+    assert_cursor(
+        ("", "hi test"),
+        &[KeyPress::Meta('2'), KeyPress::Meta('U'), KeyPress::Enter],
+        ("HI TEST", ""),
+    );*/
+}
+
+#[test]
+fn meta_d() {
+    assert_cursor(
+        EditMode::Emacs,
+        ("Hello", ", world!"),
+        &[KeyPress::Meta('D'), KeyPress::Enter],
+        ("Hello", "!"),
+    );
+    assert_cursor(
+        EditMode::Emacs,
+        ("Hello", ", world!"),
+        &[KeyPress::Meta('2'), KeyPress::Meta('D'), KeyPress::Enter],
+        ("Hello", ""),
+    );
+}
+
+#[test]
+fn meta_t() {
+    assert_cursor(
+        EditMode::Emacs,
+        ("Hello", ", world!"),
+        &[KeyPress::Meta('T'), KeyPress::Enter],
+        ("world, Hello", "!"),
+    );
+    /* FIXME
+    assert_cursor(
+        ("One Two", " Three Four"),
+        &[KeyPress::Meta('T'), KeyPress::Enter],
+        ("One Four Three Two", ""),
+    );*/
+}
+
+#[test]
+fn meta_y() {
+    assert_cursor(
+        EditMode::Emacs,
+        ("Hello, world", "!"),
+        &[
+            KeyPress::Ctrl('W'),
+            KeyPress::Left,
+            KeyPress::Ctrl('W'),
+            KeyPress::Ctrl('Y'),
+            KeyPress::Meta('Y'),
+            KeyPress::Enter,
+        ],
+        ("world", " !"),
+    );
+}
+
+#[test]
+fn meta_backspace() {
+    assert_cursor(
+        EditMode::Emacs,
+        ("Hello, wor", "ld!"),
+        &[KeyPress::Meta('\x08'), KeyPress::Enter],
+        ("Hello, ", "ld!"),
+    );
+}
+
+#[test]
+fn meta_digit() {
+    assert_cursor(
+        EditMode::Emacs,
+        ("", ""),
+        &[KeyPress::Meta('3'), KeyPress::Char('h'), KeyPress::Enter],
+        ("hhh", ""),
+    );
+}
diff --git a/src/test/history.rs b/src/test/history.rs
new file mode 100644
index 0000000..dc3f8f0
--- /dev/null
+++ b/src/test/history.rs
@@ -0,0 +1,206 @@
+//! History related commands tests
+use super::assert_history;
+use config::EditMode;
+use keys::KeyPress;
+
+#[test]
+fn down_key() {
+    for mode in &[EditMode::Emacs, EditMode::Vi] {
+        assert_history(
+            *mode,
+            &["line1"],
+            &[KeyPress::Down, KeyPress::Enter],
+            ("", ""),
+        );
+        assert_history(
+            *mode,
+            &["line1", "line2"],
+            &[KeyPress::Up, KeyPress::Up, KeyPress::Down, KeyPress::Enter],
+            ("line2", ""),
+        );
+        assert_history(
+            *mode,
+            &["line1"],
+            &[
+                KeyPress::Char('a'),
+                KeyPress::Up,
+                KeyPress::Down, // restore original line
+                KeyPress::Enter,
+            ],
+            ("a", ""),
+        );
+        assert_history(
+            *mode,
+            &["line1"],
+            &[
+                KeyPress::Char('a'),
+                KeyPress::Down, // noop
+                KeyPress::Enter,
+            ],
+            ("a", ""),
+        );
+    }
+}
+
+#[test]
+fn up_key() {
+    for mode in &[EditMode::Emacs, EditMode::Vi] {
+        assert_history(*mode, &[], &[KeyPress::Up, KeyPress::Enter], ("", ""));
+        assert_history(
+            *mode,
+            &["line1"],
+            &[KeyPress::Up, KeyPress::Enter],
+            ("line1", ""),
+        );
+        assert_history(
+            *mode,
+            &["line1", "line2"],
+            &[KeyPress::Up, KeyPress::Up, KeyPress::Enter],
+            ("line1", ""),
+        );
+    }
+}
+
+#[test]
+fn ctrl_r() {
+    for mode in &[EditMode::Emacs, EditMode::Vi] {
+        assert_history(
+            *mode,
+            &[],
+            &[KeyPress::Ctrl('R'), KeyPress::Char('o'), KeyPress::Enter],
+            ("o", ""),
+        );
+        assert_history(
+            *mode,
+            &["rustc", "cargo"],
+            &[
+                KeyPress::Ctrl('R'),
+                KeyPress::Char('o'),
+                KeyPress::Right, // just to assert cursor pos
+                KeyPress::Enter,
+            ],
+            ("cargo", ""),
+        );
+        assert_history(
+            *mode,
+            &["rustc", "cargo"],
+            &[
+                KeyPress::Ctrl('R'),
+                KeyPress::Char('u'),
+                KeyPress::Right, // just to assert cursor pos
+                KeyPress::Enter,
+            ],
+            ("ru", "stc"),
+        );
+        assert_history(
+            *mode,
+            &["rustc", "cargo"],
+            &[
+                KeyPress::Ctrl('R'),
+                KeyPress::Char('r'),
+                KeyPress::Char('u'),
+                KeyPress::Right, // just to assert cursor pos
+                KeyPress::Enter,
+            ],
+            ("r", "ustc"),
+        );
+        assert_history(
+            *mode,
+            &["rustc", "cargo"],
+            &[
+                KeyPress::Ctrl('R'),
+                KeyPress::Char('r'),
+                KeyPress::Ctrl('R'),
+                KeyPress::Right, // just to assert cursor pos
+                KeyPress::Enter,
+            ],
+            ("r", "ustc"),
+        );
+        assert_history(
+            *mode,
+            &["rustc", "cargo"],
+            &[
+                KeyPress::Ctrl('R'),
+                KeyPress::Char('r'),
+                KeyPress::Char('z'), // no match
+                KeyPress::Right,     // just to assert cursor pos
+                KeyPress::Enter,
+            ],
+            ("car", "go"),
+        );
+        assert_history(
+            EditMode::Emacs,
+            &["rustc", "cargo"],
+            &[
+                KeyPress::Char('a'),
+                KeyPress::Ctrl('R'),
+                KeyPress::Char('r'),
+                KeyPress::Ctrl('G'), // abort (FIXME: doesn't work with vi mode)
+                KeyPress::Enter,
+            ],
+            ("a", ""),
+        );
+    }
+}
+
+#[test]
+fn ctrl_s() {
+    for mode in &[EditMode::Emacs, EditMode::Vi] {
+        assert_history(
+            *mode,
+            &["rustc", "cargo"],
+            &[
+                KeyPress::Ctrl('R'),
+                KeyPress::Char('r'),
+                KeyPress::Ctrl('R'),
+                KeyPress::Ctrl('S'),
+                KeyPress::Right, // just to assert cursor pos
+                KeyPress::Enter,
+            ],
+            ("car", "go"),
+        );
+    }
+}
+
+#[test]
+fn meta_lt() {
+    assert_history(
+        EditMode::Emacs,
+        &[""],
+        &[KeyPress::Meta('<'), KeyPress::Enter],
+        ("", ""),
+    );
+    assert_history(
+        EditMode::Emacs,
+        &["rustc", "cargo"],
+        &[KeyPress::Meta('<'), KeyPress::Enter],
+        ("rustc", ""),
+    );
+}
+
+#[test]
+fn meta_gt() {
+    assert_history(
+        EditMode::Emacs,
+        &[""],
+        &[KeyPress::Meta('>'), KeyPress::Enter],
+        ("", ""),
+    );
+    assert_history(
+        EditMode::Emacs,
+        &["rustc", "cargo"],
+        &[KeyPress::Meta('<'), KeyPress::Meta('>'), KeyPress::Enter],
+        ("", ""),
+    );
+    assert_history(
+        EditMode::Emacs,
+        &["rustc", "cargo"],
+        &[
+            KeyPress::Char('a'),
+            KeyPress::Meta('<'),
+            KeyPress::Meta('>'), // restore original line
+            KeyPress::Enter,
+        ],
+        ("a", ""),
+    );
+}
diff --git a/src/test/mod.rs b/src/test/mod.rs
new file mode 100644
index 0000000..53ac34c
--- /dev/null
+++ b/src/test/mod.rs
@@ -0,0 +1,112 @@
+use std::collections::HashMap;
+use std::sync::{Arc, RwLock};
+
+use super::{Editor, Result, StdStream};
+use completion::Completer;
+use config::{Config, EditMode, OutputStreamType};
+use edit::init_state;
+use keymap::{Cmd, InputState};
+use keys::KeyPress;
+use tty::Sink;
+
+mod common;
+mod emacs;
+mod history;
+mod vi_cmd;
+mod vi_insert;
+
+fn init_editor(mode: EditMode, keys: &[KeyPress]) -> Editor<()> {
+    let config = Config::builder().edit_mode(mode).build();
+    let mut editor = Editor::<()>::with_config(config);
+    editor.term.keys.extend(keys.iter().cloned());
+    editor
+}
+
+struct SimpleCompleter;
+impl Completer for SimpleCompleter {
+    type Candidate = String;
+
+    fn complete(&self, line: &str, _pos: usize) -> Result<(usize, Vec<String>)> {
+        Ok((0, vec![line.to_owned() + "t"]))
+    }
+}
+
+#[test]
+fn complete_line() {
+    let mut out = Sink::new();
+    let mut s = init_state(&mut out, "rus", 3);
+    let config = Config::default();
+    let mut input_state = InputState::new(&config, Arc::new(RwLock::new(HashMap::new())));
+    let keys = &[KeyPress::Enter];
+    let mut rdr = keys.iter();
+    let completer = SimpleCompleter;
+    let cmd = super::complete_line(
+        &mut rdr,
+        &mut s,
+        &mut input_state,
+        &completer,
+        None,
+        &Config::default(),
+    )
+    .unwrap();
+    assert_eq!(Some(Cmd::AcceptLine), cmd);
+    assert_eq!("rust", s.line.as_str());
+    assert_eq!(4, s.line.pos());
+}
+
+// `keys`: keys to press
+// `expected_line`: line after enter key
+fn assert_line(mode: EditMode, keys: &[KeyPress], expected_line: &str) {
+    let mut editor = init_editor(mode, keys);
+    let actual_line = editor.readline(">>").unwrap();
+    assert_eq!(expected_line, actual_line);
+}
+
+// `initial`: line status before `keys` pressed: strings before and after cursor
+// `keys`: keys to press
+// `expected_line`: line after enter key
+fn assert_line_with_initial(
+    mode: EditMode,
+    initial: (&str, &str),
+    keys: &[KeyPress],
+    expected_line: &str,
+) {
+    let mut editor = init_editor(mode, keys);
+    let actual_line = editor.readline_with_initial(">>", initial).unwrap();
+    assert_eq!(expected_line, actual_line);
+}
+
+// `initial`: line status before `keys` pressed: strings before and after cursor
+// `keys`: keys to press
+// `expected`: line status before enter key: strings before and after cursor
+fn assert_cursor(mode: EditMode, initial: (&str, &str), keys: &[KeyPress], expected: (&str, &str)) {
+    let mut editor = init_editor(mode, keys);
+    let actual_line = editor.readline_with_initial("", initial).unwrap();
+    assert_eq!(expected.0.to_owned() + expected.1, actual_line);
+    assert_eq!(expected.0.len(), editor.term.cursor);
+}
+
+// `entries`: history entries before `keys` pressed
+// `keys`: keys to press
+// `expected`: line status before enter key: strings before and after cursor
+fn assert_history(mode: EditMode, entries: &[&str], keys: &[KeyPress], expected: (&str, &str)) {
+    let mut editor = init_editor(mode, keys);
+    for entry in entries {
+        editor.history.add(*entry);
+    }
+    let actual_line = editor.readline("").unwrap();
+    assert_eq!(expected.0.to_owned() + expected.1, actual_line);
+    assert_eq!(expected.0.len(), editor.term.cursor);
+}
+
+#[test]
+fn unknown_esc_key() {
+    for mode in &[EditMode::Emacs, EditMode::Vi] {
+        assert_line(*mode, &[KeyPress::UnknownEscSeq, KeyPress::Enter], "");
+    }
+}
+
+#[test]
+fn from_stream_type() {
+    StdStream::from_stream_type(OutputStreamType::Stdout);
+}
diff --git a/src/test/vi_cmd.rs b/src/test/vi_cmd.rs
new file mode 100644
index 0000000..d8ec793
--- /dev/null
+++ b/src/test/vi_cmd.rs
@@ -0,0 +1,611 @@
+//! Vi command mode specific key bindings
+use super::{assert_cursor, assert_history};
+use config::EditMode;
+use keys::KeyPress;
+
+#[test]
+fn dollar() {
+    assert_cursor(
+        EditMode::Vi,
+        ("", "Hi"),
+        &[KeyPress::Esc, KeyPress::Char('$'), KeyPress::Enter],
+        ("Hi", ""), // FIXME
+    );
+}
+
+/*#[test]
+fn dot() {
+    // TODO
+}*/
+
+#[test]
+fn semi_colon() {
+    assert_cursor(
+        EditMode::Vi,
+        ("", "Hello, world!"),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('f'),
+            KeyPress::Char('o'),
+            KeyPress::Char(';'),
+            KeyPress::Enter,
+        ],
+        ("Hello, w", "orld!"),
+    );
+}
+
+#[test]
+fn comma() {
+    assert_cursor(
+        EditMode::Vi,
+        ("Hello, w", "orld!"),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('f'),
+            KeyPress::Char('l'),
+            KeyPress::Char(','),
+            KeyPress::Enter,
+        ],
+        ("Hel", "lo, world!"),
+    );
+}
+
+#[test]
+fn zero() {
+    assert_cursor(
+        EditMode::Vi,
+        ("Hi", ""),
+        &[KeyPress::Esc, KeyPress::Char('0'), KeyPress::Enter],
+        ("", "Hi"),
+    );
+}
+
+#[test]
+fn caret() {
+    assert_cursor(
+        EditMode::Vi,
+        (" Hi", ""),
+        &[KeyPress::Esc, KeyPress::Char('^'), KeyPress::Enter],
+        (" ", "Hi"),
+    );
+}
+
+#[test]
+fn a() {
+    assert_cursor(
+        EditMode::Vi,
+        ("B", "e"),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('a'),
+            KeyPress::Char('y'),
+            KeyPress::Enter,
+        ],
+        ("By", "e"),
+    );
+}
+
+#[test]
+fn uppercase_a() {
+    assert_cursor(
+        EditMode::Vi,
+        ("", "By"),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('A'),
+            KeyPress::Char('e'),
+            KeyPress::Enter,
+        ],
+        ("Bye", ""),
+    );
+}
+
+#[test]
+fn b() {
+    assert_cursor(
+        EditMode::Vi,
+        ("Hello, world!", ""),
+        &[KeyPress::Esc, KeyPress::Char('b'), KeyPress::Enter],
+        ("Hello, ", "world!"),
+    );
+    assert_cursor(
+        EditMode::Vi,
+        ("Hello, world!", ""),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('2'),
+            KeyPress::Char('b'),
+            KeyPress::Enter,
+        ],
+        ("Hello", ", world!"),
+    );
+}
+
+#[test]
+fn uppercase_b() {
+    assert_cursor(
+        EditMode::Vi,
+        ("Hello, world!", ""),
+        &[KeyPress::Esc, KeyPress::Char('B'), KeyPress::Enter],
+        ("Hello, ", "world!"),
+    );
+    assert_cursor(
+        EditMode::Vi,
+        ("Hello, world!", ""),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('2'),
+            KeyPress::Char('B'),
+            KeyPress::Enter,
+        ],
+        ("", "Hello, world!"),
+    );
+}
+
+#[test]
+fn uppercase_c() {
+    assert_cursor(
+        EditMode::Vi,
+        ("Hello, w", "orld!"),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('C'),
+            KeyPress::Char('i'),
+            KeyPress::Enter,
+        ],
+        ("Hello, i", ""),
+    );
+}
+
+#[test]
+fn ctrl_k() {
+    for key in &[KeyPress::Char('D'), KeyPress::Ctrl('K')] {
+        assert_cursor(
+            EditMode::Vi,
+            ("Hi", ""),
+            &[KeyPress::Esc, *key, KeyPress::Enter],
+            ("H", ""),
+        );
+        assert_cursor(
+            EditMode::Vi,
+            ("", "Hi"),
+            &[KeyPress::Esc, *key, KeyPress::Enter],
+            ("", ""),
+        );
+        assert_cursor(
+            EditMode::Vi,
+            ("By", "e"),
+            &[KeyPress::Esc, *key, KeyPress::Enter],
+            ("B", ""),
+        );
+    }
+}
+
+#[test]
+fn e() {
+    assert_cursor(
+        EditMode::Vi,
+        ("", "Hello, world!"),
+        &[KeyPress::Esc, KeyPress::Char('e'), KeyPress::Enter],
+        ("Hell", "o, world!"),
+    );
+    assert_cursor(
+        EditMode::Vi,
+        ("", "Hello, world!"),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('2'),
+            KeyPress::Char('e'),
+            KeyPress::Enter,
+        ],
+        ("Hello, worl", "d!"),
+    );
+}
+
+#[test]
+fn uppercase_e() {
+    assert_cursor(
+        EditMode::Vi,
+        ("", "Hello, world!"),
+        &[KeyPress::Esc, KeyPress::Char('E'), KeyPress::Enter],
+        ("Hello", ", world!"),
+    );
+    assert_cursor(
+        EditMode::Vi,
+        ("", "Hello, world!"),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('2'),
+            KeyPress::Char('E'),
+            KeyPress::Enter,
+        ],
+        ("Hello, world", "!"),
+    );
+}
+
+#[test]
+fn f() {
+    assert_cursor(
+        EditMode::Vi,
+        ("", "Hello, world!"),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('f'),
+            KeyPress::Char('r'),
+            KeyPress::Enter,
+        ],
+        ("Hello, wo", "rld!"),
+    );
+    assert_cursor(
+        EditMode::Vi,
+        ("", "Hello, world!"),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('3'),
+            KeyPress::Char('f'),
+            KeyPress::Char('l'),
+            KeyPress::Enter,
+        ],
+        ("Hello, wor", "ld!"),
+    );
+}
+
+#[test]
+fn uppercase_f() {
+    assert_cursor(
+        EditMode::Vi,
+        ("Hello, world!", ""),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('F'),
+            KeyPress::Char('r'),
+            KeyPress::Enter,
+        ],
+        ("Hello, wo", "rld!"),
+    );
+    assert_cursor(
+        EditMode::Vi,
+        ("Hello, world!", ""),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('3'),
+            KeyPress::Char('F'),
+            KeyPress::Char('l'),
+            KeyPress::Enter,
+        ],
+        ("He", "llo, world!"),
+    );
+}
+
+#[test]
+fn i() {
+    assert_cursor(
+        EditMode::Vi,
+        ("Be", ""),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('i'),
+            KeyPress::Char('y'),
+            KeyPress::Enter,
+        ],
+        ("By", "e"),
+    );
+}
+
+#[test]
+fn uppercase_i() {
+    assert_cursor(
+        EditMode::Vi,
+        ("Be", ""),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('I'),
+            KeyPress::Char('y'),
+            KeyPress::Enter,
+        ],
+        ("y", "Be"),
+    );
+}
+
+#[test]
+fn u() {
+    assert_cursor(
+        EditMode::Vi,
+        ("Hello, ", "world"),
+        &[
+            KeyPress::Esc,
+            KeyPress::Ctrl('W'),
+            KeyPress::Char('u'),
+            KeyPress::Enter,
+        ],
+        ("Hello,", " world"),
+    );
+}
+
+#[test]
+fn w() {
+    assert_cursor(
+        EditMode::Vi,
+        ("", "Hello, world!"),
+        &[KeyPress::Esc, KeyPress::Char('w'), KeyPress::Enter],
+        ("Hello", ", world!"),
+    );
+    assert_cursor(
+        EditMode::Vi,
+        ("", "Hello, world!"),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('2'),
+            KeyPress::Char('w'),
+            KeyPress::Enter,
+        ],
+        ("Hello, ", "world!"),
+    );
+}
+
+#[test]
+fn uppercase_w() {
+    assert_cursor(
+        EditMode::Vi,
+        ("", "Hello, world!"),
+        &[KeyPress::Esc, KeyPress::Char('W'), KeyPress::Enter],
+        ("Hello, ", "world!"),
+    );
+    assert_cursor(
+        EditMode::Vi,
+        ("", "Hello, world!"),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('2'),
+            KeyPress::Char('W'),
+            KeyPress::Enter,
+        ],
+        ("Hello, world", "!"),
+    );
+}
+
+#[test]
+fn x() {
+    assert_cursor(
+        EditMode::Vi,
+        ("", "a"),
+        &[KeyPress::Esc, KeyPress::Char('x'), KeyPress::Enter],
+        ("", ""),
+    );
+}
+
+#[test]
+fn uppercase_x() {
+    assert_cursor(
+        EditMode::Vi,
+        ("Hi", ""),
+        &[KeyPress::Esc, KeyPress::Char('X'), KeyPress::Enter],
+        ("", "i"),
+    );
+}
+
+#[test]
+fn h() {
+    for key in &[
+        KeyPress::Char('h'),
+        KeyPress::Ctrl('H'),
+        KeyPress::Backspace,
+    ] {
+        assert_cursor(
+            EditMode::Vi,
+            ("Bye", ""),
+            &[KeyPress::Esc, *key, KeyPress::Enter],
+            ("B", "ye"),
+        );
+        assert_cursor(
+            EditMode::Vi,
+            ("Bye", ""),
+            &[KeyPress::Esc, KeyPress::Char('2'), *key, KeyPress::Enter],
+            ("", "Bye"),
+        );
+    }
+}
+
+#[test]
+fn l() {
+    for key in &[KeyPress::Char('l'), KeyPress::Char(' ')] {
+        assert_cursor(
+            EditMode::Vi,
+            ("", "Hi"),
+            &[KeyPress::Esc, *key, KeyPress::Enter],
+            ("H", "i"),
+        );
+        assert_cursor(
+            EditMode::Vi,
+            ("", "Hi"),
+            &[KeyPress::Esc, KeyPress::Char('2'), *key, KeyPress::Enter],
+            ("Hi", ""),
+        );
+    }
+}
+
+#[test]
+fn j() {
+    for key in &[
+        KeyPress::Char('j'),
+        KeyPress::Char('+'),
+        KeyPress::Ctrl('N'),
+    ] {
+        assert_history(
+            EditMode::Vi,
+            &["line1", "line2"],
+            &[
+                KeyPress::Esc,
+                KeyPress::Ctrl('P'),
+                KeyPress::Ctrl('P'),
+                *key,
+                KeyPress::Enter,
+            ],
+            ("line2", ""),
+        );
+    }
+}
+
+#[test]
+fn k() {
+    for key in &[
+        KeyPress::Char('k'),
+        KeyPress::Char('-'),
+        KeyPress::Ctrl('P'),
+    ] {
+        assert_history(
+            EditMode::Vi,
+            &["line1"],
+            &[KeyPress::Esc, *key, KeyPress::Enter],
+            ("line1", ""),
+        );
+    }
+}
+
+#[test]
+fn p() {
+    assert_cursor(
+        EditMode::Vi,
+        ("Hello, ", "world"),
+        &[
+            KeyPress::Esc,
+            KeyPress::Ctrl('W'),
+            KeyPress::Char('p'),
+            KeyPress::Enter,
+        ],
+        (" Hello", ",world"),
+    );
+}
+
+#[test]
+fn uppercase_p() {
+    assert_cursor(
+        EditMode::Vi,
+        ("Hello, ", "world"),
+        &[
+            KeyPress::Esc,
+            KeyPress::Ctrl('W'),
+            KeyPress::Char('P'),
+            KeyPress::Enter,
+        ],
+        ("Hello", ", world"),
+    );
+}
+
+#[test]
+fn r() {
+    assert_cursor(
+        EditMode::Vi,
+        ("Hi", ", world!"),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('r'),
+            KeyPress::Char('o'),
+            KeyPress::Enter,
+        ],
+        ("H", "o, world!"),
+    );
+    assert_cursor(
+        EditMode::Vi,
+        ("He", "llo, world!"),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('4'),
+            KeyPress::Char('r'),
+            KeyPress::Char('i'),
+            KeyPress::Enter,
+        ],
+        ("Hiii", "i, world!"),
+    );
+}
+
+#[test]
+fn s() {
+    assert_cursor(
+        EditMode::Vi,
+        ("Hi", ", world!"),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('s'),
+            KeyPress::Char('o'),
+            KeyPress::Enter,
+        ],
+        ("Ho", ", world!"),
+    );
+    assert_cursor(
+        EditMode::Vi,
+        ("He", "llo, world!"),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('4'),
+            KeyPress::Char('s'),
+            KeyPress::Char('i'),
+            KeyPress::Enter,
+        ],
+        ("Hi", ", world!"),
+    );
+}
+
+#[test]
+fn uppercase_s() {
+    assert_cursor(
+        EditMode::Vi,
+        ("Hello, ", "world"),
+        &[KeyPress::Esc, KeyPress::Char('S'), KeyPress::Enter],
+        ("", ""),
+    );
+}
+
+#[test]
+fn t() {
+    assert_cursor(
+        EditMode::Vi,
+        ("", "Hello, world!"),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('t'),
+            KeyPress::Char('r'),
+            KeyPress::Enter,
+        ],
+        ("Hello, w", "orld!"),
+    );
+    assert_cursor(
+        EditMode::Vi,
+        ("", "Hello, world!"),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('3'),
+            KeyPress::Char('t'),
+            KeyPress::Char('l'),
+            KeyPress::Enter,
+        ],
+        ("Hello, wo", "rld!"),
+    );
+}
+
+#[test]
+fn uppercase_t() {
+    assert_cursor(
+        EditMode::Vi,
+        ("Hello, world!", ""),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('T'),
+            KeyPress::Char('r'),
+            KeyPress::Enter,
+        ],
+        ("Hello, wor", "ld!"),
+    );
+    assert_cursor(
+        EditMode::Vi,
+        ("Hello, world!", ""),
+        &[
+            KeyPress::Esc,
+            KeyPress::Char('3'),
+            KeyPress::Char('T'),
+            KeyPress::Char('l'),
+            KeyPress::Enter,
+        ],
+        ("Hel", "lo, world!"),
+    );
+}
diff --git a/src/test/vi_insert.rs b/src/test/vi_insert.rs
new file mode 100644
index 0000000..fa3c881
--- /dev/null
+++ b/src/test/vi_insert.rs
@@ -0,0 +1,56 @@
+//! Vi insert mode specific key bindings
+use super::assert_cursor;
+use config::EditMode;
+use keys::KeyPress;
+
+#[test]
+fn insert_mode_by_default() {
+    assert_cursor(
+        EditMode::Vi,
+        ("", ""),
+        &[KeyPress::Char('a'), KeyPress::Enter],
+        ("a", ""),
+    );
+}
+
+#[test]
+fn ctrl_h() {
+    assert_cursor(
+        EditMode::Vi,
+        ("Hi", ""),
+        &[KeyPress::Ctrl('H'), KeyPress::Enter],
+        ("H", ""),
+    );
+}
+
+#[test]
+fn backspace() {
+    assert_cursor(
+        EditMode::Vi,
+        ("", ""),
+        &[KeyPress::Backspace, KeyPress::Enter],
+        ("", ""),
+    );
+    assert_cursor(
+        EditMode::Vi,
+        ("Hi", ""),
+        &[KeyPress::Backspace, KeyPress::Enter],
+        ("H", ""),
+    );
+    assert_cursor(
+        EditMode::Vi,
+        ("", "Hi"),
+        &[KeyPress::Backspace, KeyPress::Enter],
+        ("", "Hi"),
+    );
+}
+
+#[test]
+fn esc() {
+    assert_cursor(
+        EditMode::Vi,
+        ("", ""),
+        &[KeyPress::Char('a'), KeyPress::Esc, KeyPress::Enter],
+        ("", "a"),
+    );
+}
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)
     }
 }
diff --git a/src/tty/mod.rs b/src/tty/mod.rs
index f7ce051..48f917c 100644
--- a/src/tty/mod.rs
+++ b/src/tty/mod.rs
@@ -1,49 +1,202 @@
 //! This module implements and describes common TTY methods & traits
-use std::io::Write;
+use std::io::{self, Write};
+use unicode_segmentation::UnicodeSegmentation;
+use unicode_width::UnicodeWidthStr;
+
+use config::{ColorMode, Config, OutputStreamType};
+use highlight::Highlighter;
+use keys::KeyPress;
+use line_buffer::LineBuffer;
 use Result;
-use config::Config;
-use consts::KeyPress;
 
 /// Terminal state
-pub trait RawMode: Copy + Sized {
+pub trait RawMode: Sized {
     /// Disable RAW mode for the terminal.
     fn disable_raw_mode(&self) -> Result<()>;
 }
 
 /// Translate bytes read from stdin to keys.
-pub trait RawReader: Sized {
+pub trait RawReader {
     /// Blocking read of key pressed.
-    fn next_key(&mut self) -> Result<KeyPress>;
+    fn next_key(&mut self, single_esc_abort: bool) -> Result<KeyPress>;
     /// For CTRL-V support
     #[cfg(unix)]
     fn next_char(&mut self) -> Result<char>;
 }
 
-/// Terminal contract
-pub trait Term: Clone {
-    type Reader: RawReader;
-    type Writer: Write;
-    type Mode: RawMode;
+#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
+pub struct Position {
+    pub col: usize,
+    pub row: usize,
+}
 
-    fn new() -> Self;
-    /// Check if current terminal can provide a rich line-editing user interface.
-    fn is_unsupported(&self) -> bool;
-    /// check if stdin is connected to a terminal.
-    fn is_stdin_tty(&self) -> bool;
+/// Display prompt, line and cursor in terminal output
+pub trait Renderer {
+    fn move_cursor(&mut self, old: Position, new: Position) -> Result<()>;
+
+    /// 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)>;
+
+    /// 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;
+
+    fn write_and_flush(&mut self, buf: &[u8]) -> Result<()>;
+
+    /// Beep, used for completion when there is nothing to complete or when all
+    /// the choices were already shown.
+    fn beep(&mut self) -> Result<()> {
+        // TODO bell-style
+        try!(io::stderr().write_all(b"\x07"));
+        try!(io::stderr().flush());
+        Ok(())
+    }
+
+    /// Clear the screen. Used to handle ctrl+l
+    fn clear_screen(&mut self) -> Result<()>;
+
+    /// Check if a SIGWINCH signal has been received
+    fn sigwinch(&self) -> bool;
+    /// Update the number of columns/rows in the current terminal.
+    fn update_size(&mut self);
     /// Get the number of columns in the current terminal.
     fn get_columns(&self) -> usize;
     /// Get the number of rows in the current terminal.
     fn get_rows(&self) -> usize;
-    /// Check if a SIGWINCH signal has been received
-    fn sigwinch(&self) -> bool;
+}
+
+impl<'a, R: Renderer + ?Sized> Renderer for &'a mut R {
+    fn move_cursor(&mut self, old: Position, new: Position) -> Result<()> {
+        (**self).move_cursor(old, new)
+    }
+
+    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)> {
+        (**self).refresh_line(
+            prompt,
+            prompt_size,
+            line,
+            hint,
+            current_row,
+            old_rows,
+            highlighter,
+        )
+    }
+
+    fn calculate_position(&self, s: &str, orig: Position) -> Position {
+        (**self).calculate_position(s, orig)
+    }
+
+    fn write_and_flush(&mut self, buf: &[u8]) -> Result<()> {
+        (**self).write_and_flush(buf)
+    }
+
+    fn beep(&mut self) -> Result<()> {
+        (**self).beep()
+    }
+
+    fn clear_screen(&mut self) -> Result<()> {
+        (**self).clear_screen()
+    }
+
+    fn sigwinch(&self) -> bool {
+        (**self).sigwinch()
+    }
+
+    fn update_size(&mut self) {
+        (**self).update_size()
+    }
+
+    fn get_columns(&self) -> usize {
+        (**self).get_columns()
+    }
+
+    fn get_rows(&self) -> usize {
+        (**self).get_rows()
+    }
+}
+
+/// Terminal contract
+pub trait Term {
+    type Reader: RawReader; // rl_instream
+    type Writer: Renderer; // rl_outstream
+    type Mode: RawMode;
+
+    fn new(color_mode: ColorMode, stream: OutputStreamType) -> Self;
+    /// Check if current terminal can provide a rich line-editing user
+    /// interface.
+    fn is_unsupported(&self) -> bool;
+    /// check if stdin is connected to a terminal.
+    fn is_stdin_tty(&self) -> bool;
+    /// Check if output supports colors.
+    fn colors_enabled(&self) -> bool;
     /// Enable RAW mode for the terminal.
-    fn enable_raw_mode(&self) -> Result<Self::Mode>;
+    fn enable_raw_mode(&mut self) -> Result<Self::Mode>;
     /// Create a RAW reader
     fn create_reader(&self, config: &Config) -> Result<Self::Reader>;
     /// Create a writer
     fn create_writer(&self) -> Self::Writer;
-    /// Clear the screen. Used to handle ctrl+l
-    fn clear_screen(&mut self, w: &mut Write) -> Result<()>;
+}
+
+fn truncate(text: &str, col: usize, max_col: usize) -> &str {
+    let mut col = col;
+    let mut esc_seq = 0;
+    let mut end = text.len();
+    for (i, s) in text.grapheme_indices(true) {
+        col += width(s, &mut esc_seq);
+        if col > max_col {
+            end = i;
+            break;
+        }
+    }
+    &text[..end]
+}
+
+fn width(s: &str, esc_seq: &mut u8) -> usize {
+    if *esc_seq == 1 {
+        if s == "[" {
+            // CSI
+            *esc_seq = 2;
+        } else {
+            // two-character sequence
+            *esc_seq = 0;
+        }
+        0
+    } else if *esc_seq == 2 {
+        if s == ";" || (s.as_bytes()[0] >= b'0' && s.as_bytes()[0] <= b'9') {
+        /*} else if s == "m" {
+            // last
+            *esc_seq = 0;*/
+        } else {
+            // not supported
+            *esc_seq = 0;
+        }
+        0
+    } else if s == "\x1b" {
+        *esc_seq = 1;
+        0
+    } else if s == "\n" {
+        0
+    } else {
+        s.width()
+    }
 }
 
 // If on Windows platform import Windows TTY module
diff --git a/src/tty/test.rs b/src/tty/test.rs
index 8813fa5..8ea87a4 100644
--- a/src/tty/test.rs
+++ b/src/tty/test.rs
@@ -1,17 +1,15 @@
 //! Tests specific definitions
-use std::io::{self, Sink, Write};
 use std::iter::IntoIterator;
 use std::slice::Iter;
 use std::vec::IntoIter;
 
-#[cfg(windows)]
-use winapi;
-
-use config::Config;
-use consts::KeyPress;
+use super::{truncate, Position, RawMode, RawReader, Renderer, Term};
+use config::{ColorMode, Config, OutputStreamType};
 use error::ReadlineError;
+use highlight::Highlighter;
+use keys::KeyPress;
+use line_buffer::LineBuffer;
 use Result;
-use super::{RawMode, RawReader, Term};
 
 pub type Mode = ();
 
@@ -22,12 +20,13 @@
 }
 
 impl<'a> RawReader for Iter<'a, KeyPress> {
-    fn next_key(&mut self) -> Result<KeyPress> {
+    fn next_key(&mut self, _: bool) -> Result<KeyPress> {
         match self.next() {
             Some(key) => Ok(*key),
             None => Err(ReadlineError::Eof),
         }
     }
+
     #[cfg(unix)]
     fn next_char(&mut self) -> Result<char> {
         unimplemented!();
@@ -35,114 +34,135 @@
 }
 
 impl RawReader for IntoIter<KeyPress> {
-    fn next_key(&mut self) -> Result<KeyPress> {
+    fn next_key(&mut self, _: bool) -> Result<KeyPress> {
         match self.next() {
             Some(key) => Ok(key),
             None => Err(ReadlineError::Eof),
         }
     }
+
     #[cfg(unix)]
     fn next_char(&mut self) -> Result<char> {
-        unimplemented!();
+        match self.next() {
+            Some(KeyPress::Char(c)) => Ok(c),
+            None => Err(ReadlineError::Eof),
+            _ => unimplemented!(),
+        }
+    }
+}
+
+pub struct Sink {}
+
+impl Sink {
+    pub fn new() -> Sink {
+        Sink {}
+    }
+}
+
+impl Renderer for Sink {
+    fn move_cursor(&mut self, _: Position, _: Position) -> Result<()> {
+        Ok(())
+    }
+
+    fn refresh_line(
+        &mut self,
+        _: &str,
+        prompt_size: Position,
+        line: &LineBuffer,
+        hint: Option<String>,
+        _: usize,
+        _: usize,
+        _: Option<&Highlighter>,
+    ) -> Result<(Position, Position)> {
+        let cursor = self.calculate_position(&line[..line.pos()], prompt_size);
+        if let Some(hint) = hint {
+            truncate(&hint, 0, 80);
+        }
+        let end = self.calculate_position(&line, prompt_size);
+        Ok((cursor, end))
+    }
+
+    fn calculate_position(&self, s: &str, orig: Position) -> Position {
+        let mut pos = orig;
+        pos.col += s.len();
+        pos
+    }
+
+    fn write_and_flush(&mut self, _: &[u8]) -> Result<()> {
+        Ok(())
+    }
+
+    fn beep(&mut self) -> Result<()> {
+        Ok(())
+    }
+
+    fn clear_screen(&mut self) -> Result<()> {
+        Ok(())
+    }
+
+    fn sigwinch(&self) -> bool {
+        false
+    }
+
+    fn update_size(&mut self) {}
+
+    fn get_columns(&self) -> usize {
+        80
+    }
+
+    fn get_rows(&self) -> usize {
+        24
     }
 }
 
 pub type Terminal = DummyTerminal;
 
-#[derive(Clone,Debug)]
+#[derive(Clone, Debug)]
 pub struct DummyTerminal {
     pub keys: Vec<KeyPress>,
-}
-
-impl DummyTerminal {
-    #[cfg(windows)]
-    pub fn get_console_screen_buffer_info(&self) -> Result<winapi::CONSOLE_SCREEN_BUFFER_INFO> {
-        let dw_size = winapi::COORD { X: 80, Y: 24 };
-        let dw_cursor_osition = winapi::COORD { X: 0, Y: 0 };
-        let sr_window = winapi::SMALL_RECT {
-            Left: 0,
-            Top: 0,
-            Right: 0,
-            Bottom: 0,
-        };
-        let info = winapi::CONSOLE_SCREEN_BUFFER_INFO {
-            dwSize: dw_size,
-            dwCursorPosition: dw_cursor_osition,
-            wAttributes: 0,
-            srWindow: sr_window,
-            dwMaximumWindowSize: dw_size,
-        };
-        Ok(info)
-    }
-
-    #[cfg(windows)]
-    pub fn set_console_cursor_position(&mut self, _: winapi::COORD) -> Result<()> {
-        Ok(())
-    }
-
-    #[cfg(windows)]
-    pub fn fill_console_output_character(&mut self,
-                                         _: winapi::DWORD,
-                                         _: winapi::COORD)
-                                         -> Result<()> {
-        Ok(())
-    }
+    pub cursor: usize, // cursor position before last command
+    pub color_mode: ColorMode,
 }
 
 impl Term for DummyTerminal {
+    type Mode = Mode;
     type Reader = IntoIter<KeyPress>;
     type Writer = Sink;
-    type Mode = Mode;
 
-    fn new() -> DummyTerminal {
-        DummyTerminal { keys: Vec::new() }
+    fn new(color_mode: ColorMode, _stream: OutputStreamType) -> DummyTerminal {
+        DummyTerminal {
+            keys: Vec::new(),
+            cursor: 0,
+            color_mode: color_mode,
+        }
     }
 
     // Init checks:
 
-    /// 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 {
         true
     }
 
-    // Interactive loop:
-
-    /// Get the number of columns in the current terminal.
-    fn get_columns(&self) -> usize {
-        80
-    }
-
-    /// Get the number of rows in the current terminal.
-    fn get_rows(&self) -> usize {
-        24
-    }
-
-    /// Check if a SIGWINCH signal has been received
-    fn sigwinch(&self) -> bool {
+    fn colors_enabled(&self) -> bool {
         false
     }
 
-    fn enable_raw_mode(&self) -> Result<Mode> {
+    // Interactive loop:
+
+    fn enable_raw_mode(&mut self) -> Result<Mode> {
         Ok(())
     }
 
-    /// Create a RAW reader
     fn create_reader(&self, _: &Config) -> Result<IntoIter<KeyPress>> {
         Ok(self.keys.clone().into_iter())
     }
 
     fn create_writer(&self) -> Sink {
-        io::sink()
-    }
-
-    /// Clear the screen. Used to handle ctrl+l
-    fn clear_screen(&mut self, _: &mut Write) -> Result<()> {
-        Ok(())
+        Sink {}
     }
 }
 
diff --git a/src/tty/unix.rs b/src/tty/unix.rs
index 17a439e..ffcbc97 100644
--- a/src/tty/unix.rs
+++ b/src/tty/unix.rs
@@ -1,33 +1,44 @@
 //! Unix specific definitions
 use std;
-use std::io::{self, Read, Stdout, Write};
+use std::io::{self, Read, Write};
+use std::os::unix::io::AsRawFd;
 use std::sync;
 use std::sync::atomic;
+
 use libc;
 use nix;
-use nix::poll;
+use nix::poll::{self, EventFlags};
 use nix::sys::signal;
 use nix::sys::termios;
+use nix::sys::termios::SetArg;
+use unicode_segmentation::UnicodeSegmentation;
+use utf8parse::{Parser, Receiver};
 
-use char_iter;
-use config::Config;
-use consts::{self, KeyPress};
-use Result;
+use super::{truncate, width, Position, RawMode, RawReader, Renderer, Term};
+use config::{ColorMode, Config, OutputStreamType};
 use error;
-use super::{RawMode, RawReader, Term};
+use highlight::Highlighter;
+use keys::{self, KeyPress};
+use line_buffer::LineBuffer;
+use Result;
+use StdStream;
 
 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;
 
 /// Unsupported Terminals that don't support RAW mode
 static UNSUPPORTED_TERM: [&'static str; 3] = ["dumb", "cons25", "emacs"];
 
-fn get_win_size() -> (usize, usize) {
+//#[allow(clippy::identity_conversion)]
+fn get_win_size<T: AsRawFd + ?Sized>(fileno: &T) -> (usize, usize) {
     use std::mem::zeroed;
 
     unsafe {
         let mut size: libc::winsize = zeroed();
-        match libc::ioctl(STDOUT_FILENO, libc::TIOCGWINSZ, &mut size) {
+        // https://github.com/rust-lang/libc/pull/704
+        // FIXME: ".into()" used as a temporary fix for a libc bug
+        match libc::ioctl(fileno.as_raw_fd(), libc::TIOCGWINSZ.into(), &mut size) {
             0 => (size.ws_col as usize, size.ws_row as usize), // TODO getCursorPosition
             _ => (80, 24),
         }
@@ -37,7 +48,6 @@
 /// Check TERM environment variable to see if current term is in our
 /// unsupported list
 fn is_unsupported_term() -> bool {
-    use std::ascii::AsciiExt;
     match std::env::var("TERM") {
         Ok(term) => {
             for iter in &UNSUPPORTED_TERM {
@@ -51,7 +61,6 @@
     }
 }
 
-
 /// Return whether or not STDIN, STDOUT or STDERR is a TTY
 fn is_a_tty(fd: libc::c_int) -> bool {
     unsafe { libc::isatty(fd) != 0 }
@@ -62,7 +71,7 @@
 impl RawMode for Mode {
     /// Disable RAW mode for the terminal.
     fn disable_raw_mode(&self) -> Result<()> {
-        try!(termios::tcsetattr(STDIN_FILENO, termios::TCSADRAIN, self));
+        try!(termios::tcsetattr(STDIN_FILENO, SetArg::TCSADRAIN, self));
         Ok(())
     }
 }
@@ -75,13 +84,17 @@
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         loop {
             let res = unsafe {
-                libc::read(STDIN_FILENO,
-                           buf.as_mut_ptr() as *mut libc::c_void,
-                           buf.len() as libc::size_t)
+                libc::read(
+                    STDIN_FILENO,
+                    buf.as_mut_ptr() as *mut libc::c_void,
+                    buf.len() as libc::size_t,
+                )
             };
             if res == -1 {
                 let error = io::Error::last_os_error();
-                if error.kind() != io::ErrorKind::Interrupted {
+                if error.kind() != io::ErrorKind::Interrupted
+                    || SIGWINCH.load(atomic::Ordering::Relaxed)
+                {
                     return Err(error);
                 }
             } else {
@@ -93,110 +106,237 @@
 
 /// Console input reader
 pub struct PosixRawReader {
-    chars: char_iter::Chars<StdinRaw>,
+    stdin: StdinRaw,
     timeout_ms: i32,
+    buf: [u8; 1],
+    parser: Parser,
+    receiver: Utf8,
+}
+
+struct Utf8 {
+    c: Option<char>,
+    valid: bool,
 }
 
 impl PosixRawReader {
-    pub fn new(config: &Config) -> Result<PosixRawReader> {
-        let stdin = StdinRaw {};
+    fn new(config: &Config) -> Result<PosixRawReader> {
         Ok(PosixRawReader {
-               chars: char_iter::chars(stdin),
-               timeout_ms: config.keyseq_timeout(),
-           })
+            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);
+            // 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)
+                }
+                _ => {
+                    // 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 {
+            // 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: 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{:?}{:?}{:?}", seq1, seq2, seq3);
+                    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 {
-                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);
+                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
                 }
-                   })
-            }
-        } 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);
-                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
-                   _ => {
-                debug!(target: "rustyline", "unsupported esc sequence: M-{:?}", seq1);
-                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
+            }
+        })
+    }
 }
 
 impl RawReader for PosixRawReader {
-    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 {
-            let mut fds =
-                [poll::PollFd::new(STDIN_FILENO, poll::POLLIN, poll::EventFlags::empty())];
-            match poll::poll(&mut fds, self.timeout_ms) {
+            let timeout_ms = if single_esc_abort && self.timeout_ms == -1 {
+                0
+            } else {
+                self.timeout_ms
+            };
+            let mut fds = [poll::PollFd::new(STDIN_FILENO, EventFlags::POLLIN)];
+            match poll::poll(&mut fds, timeout_ms) {
                 Ok(n) if n == 0 => {
                     // single escape
                 }
@@ -213,22 +353,240 @@
     }
 
     fn next_char(&mut self) -> Result<char> {
-        match self.chars.next() {
-            Some(c) => Ok(try!(c)),
-            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 Receiver for Utf8 {
+    /// Called whenever a codepoint is parsed successfully
+    fn codepoint(&mut self, c: char) {
+        self.c = Some(c);
+        self.valid = true;
+    }
+
+    /// Called when an invalid_sequence is detected
+    fn invalid_sequence(&mut self) {
+        self.c = None;
+        self.valid = false;
+    }
+}
+
+/// Console output writer
+pub struct PosixRenderer {
+    out: StdStream,
+    cols: usize, // Number of columns in terminal
+    buffer: String,
+}
+
+impl PosixRenderer {
+    fn new(stream_type: OutputStreamType) -> PosixRenderer {
+        let out = StdStream::from_stream_type(stream_type);
+        let (cols, _) = get_win_size(&out);
+        PosixRenderer {
+            out,
+            cols,
+            buffer: String::with_capacity(1024),
+        }
+    }
+}
+
+impl Renderer for PosixRenderer {
+    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())
+    }
+
+    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))
+    }
+
+    fn write_and_flush(&mut self, buf: &[u8]) -> Result<()> {
+        try!(self.out.write_all(buf));
+        try!(self.out.flush());
+        Ok(())
+    }
+
+    /// Control characters are treated as having zero width.
+    /// Characters with 2 column width are correctly handled (not splitted).
+    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
+    }
+
+    /// 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 {
+        SIGWINCH.compare_and_swap(true, false, atomic::Ordering::SeqCst)
+    }
+
+    /// Try to update the number of columns in the current terminal,
+    fn update_size(&mut self) {
+        let (cols, _) = get_win_size(&self.out);
+        self.cols = cols;
+    }
+
+    fn get_columns(&self) -> usize {
+        self.cols
+    }
+
+    /// 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(&self.out);
+        rows
+    }
+}
 
 static SIGWINCH_ONCE: sync::Once = sync::ONCE_INIT;
-static SIGWINCH: atomic::AtomicBool = atomic::ATOMIC_BOOL_INIT;
+static SIGWINCH: atomic::AtomicBool = atomic::AtomicBool::new(false);
 
 fn install_sigwinch_handler() {
     SIGWINCH_ONCE.call_once(|| unsafe {
-        let sigwinch = signal::SigAction::new(signal::SigHandler::Handler(sigwinch_handler),
-                                              signal::SaFlags::empty(),
-                                              signal::SigSet::empty());
+        let sigwinch = signal::SigAction::new(
+            signal::SigHandler::Handler(sigwinch_handler),
+            signal::SaFlags::empty(),
+            signal::SigSet::empty(),
+        );
         let _ = signal::sigaction(signal::SIGWINCH, &sigwinch);
     });
 }
@@ -240,23 +598,33 @@
 
 pub type Terminal = PosixTerminal;
 
-#[derive(Clone,Debug)]
+#[derive(Clone, Debug)]
 pub struct PosixTerminal {
     unsupported: bool,
     stdin_isatty: bool,
+    stdstream_isatty: bool,
+    pub(crate) color_mode: ColorMode,
+    stream_type: OutputStreamType,
 }
 
 impl Term for PosixTerminal {
-    type Reader = PosixRawReader;
-    type Writer = Stdout;
     type Mode = Mode;
+    type Reader = PosixRawReader;
+    type Writer = PosixRenderer;
 
-    fn new() -> PosixTerminal {
+    fn new(color_mode: ColorMode, stream_type: OutputStreamType) -> PosixTerminal {
         let term = PosixTerminal {
             unsupported: is_unsupported_term(),
             stdin_isatty: is_a_tty(STDIN_FILENO),
+            stdstream_isatty: is_a_tty(if stream_type == OutputStreamType::Stdout {
+                STDOUT_FILENO
+            } else {
+                STDERR_FILENO
+            }),
+            color_mode,
+            stream_type,
         };
-        if !term.unsupported && term.stdin_isatty && is_a_tty(STDOUT_FILENO) {
+        if !term.unsupported && term.stdin_isatty && term.stdstream_isatty {
             install_sigwinch_handler();
         }
         term
@@ -264,7 +632,8 @@
 
     // Init checks:
 
-    /// Check if current terminal can provide a rich line-editing user interface.
+    /// Check if current terminal can provide a rich line-editing user
+    /// interface.
     fn is_unsupported(&self) -> bool {
         self.unsupported
     }
@@ -274,42 +643,44 @@
         self.stdin_isatty
     }
 
+    /// Check if output supports colors.
+    fn colors_enabled(&self) -> bool {
+        match self.color_mode {
+            ColorMode::Enabled => self.stdstream_isatty,
+            ColorMode::Forced => true,
+            ColorMode::Disabled => false,
+        }
+    }
+
     // Interactive loop:
 
-    /// 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
-    }
-
-    /// 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
-    }
-
-    fn enable_raw_mode(&self) -> Result<Mode> {
+    fn enable_raw_mode(&mut self) -> Result<Mode> {
         use nix::errno::Errno::ENOTTY;
-        use nix::sys::termios::{BRKINT, CS8, ECHO, ICANON, ICRNL, IEXTEN, INPCK, ISIG, ISTRIP,
-                                IXON, /* OPOST, */ VMIN, VTIME};
+        use nix::sys::termios::{ControlFlags, InputFlags, LocalFlags, SpecialCharacterIndices};
         if !self.stdin_isatty {
             try!(Err(nix::Error::from_errno(ENOTTY)));
         }
         let original_mode = try!(termios::tcgetattr(STDIN_FILENO));
-        let mut raw = original_mode;
+        let mut raw = original_mode.clone();
         // disable BREAK interrupt, CR to NL conversion on input,
         // input parity check, strip high bit (bit 8), output flow control
-        raw.c_iflag &= !(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+        raw.input_flags &= !(InputFlags::BRKINT
+            | InputFlags::ICRNL
+            | InputFlags::INPCK
+            | InputFlags::ISTRIP
+            | InputFlags::IXON);
         // we don't want raw output, it turns newlines into straight linefeeds
-        // raw.c_oflag = raw.c_oflag & !(OPOST); // disable all output processing
-        raw.c_cflag |= CS8; // character-size mark (8 bits)
+        // disable all output processing
+        // raw.c_oflag = raw.c_oflag & !(OutputFlags::OPOST);
+
+        // character-size mark (8 bits)
+        raw.control_flags |= ControlFlags::CS8;
         // disable echoing, canonical mode, extended input processing and signals
-        raw.c_lflag &= !(ECHO | ICANON | IEXTEN | ISIG);
-        raw.c_cc[VMIN] = 1; // One character-at-a-time input
-        raw.c_cc[VTIME] = 0; // with blocking read
-        try!(termios::tcsetattr(STDIN_FILENO, termios::TCSADRAIN, &raw));
+        raw.local_flags &=
+            !(LocalFlags::ECHO | LocalFlags::ICANON | LocalFlags::IEXTEN | LocalFlags::ISIG);
+        raw.control_chars[SpecialCharacterIndices::VMIN as usize] = 1; // One character-at-a-time input
+        raw.control_chars[SpecialCharacterIndices::VTIME as usize] = 0; // with blocking read
+        try!(termios::tcsetattr(STDIN_FILENO, SetArg::TCSADRAIN, &raw));
         Ok(original_mode)
     }
 
@@ -318,33 +689,32 @@
         PosixRawReader::new(config)
     }
 
-    fn create_writer(&self) -> Stdout {
-        io::stdout()
-    }
-
-    /// Check if a SIGWINCH signal has been received
-    fn sigwinch(&self) -> bool {
-        SIGWINCH.compare_and_swap(true, false, atomic::Ordering::SeqCst)
-    }
-
-    /// 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(())
+    fn create_writer(&self) -> PosixRenderer {
+        PosixRenderer::new(self.stream_type)
     }
 }
 
 #[cfg(unix)]
 pub fn suspend() -> Result<()> {
-    // For macos:
-    try!(signal::kill(nix::unistd::getppid(), signal::SIGTSTP));
-    try!(signal::kill(nix::unistd::getpid(), signal::SIGTSTP));
+    use nix::unistd::Pid;
+    // suspend the whole process group
+    try!(signal::kill(Pid::from_raw(0), signal::SIGTSTP));
     Ok(())
 }
 
-#[cfg(all(unix,test))]
+#[cfg(all(unix, test))]
 mod test {
+    use super::{Position, Renderer};
+    use std::io::{self, Stdout};
+
+    #[test]
+    fn prompt_with_ansi_escape_codes() {
+        let out = io::stdout();
+        let pos = out.calculate_position("\x1b[1;32m>>\x1b[0m ", Position::default(), 80);
+        assert_eq!(3, pos.col);
+        assert_eq!(0, pos.row);
+    }
+
     #[test]
     fn test_unsupported_term() {
         ::std::env::set_var("TERM", "xterm");
diff --git a/src/tty/windows.rs b/src/tty/windows.rs
index 7b73e2f..afe70ce 100644
--- a/src/tty/windows.rs
+++ b/src/tty/windows.rs
@@ -1,184 +1,420 @@
 //! Windows specific definitions
-use std::io::{self, Stdout, Write};
+use std::io::{self, Write};
 use std::mem;
 use std::sync::atomic;
 
-use kernel32;
-use winapi;
+use unicode_width::UnicodeWidthChar;
+use winapi::shared::minwindef::{DWORD, WORD};
+use winapi::um::winnt::{CHAR, HANDLE};
+use winapi::um::{consoleapi, handleapi, processenv, winbase, wincon, winuser};
 
-use config::Config;
-use consts::{self, KeyPress};
+use super::{truncate, Position, RawMode, RawReader, Renderer, Term};
+use config::OutputStreamType;
+use config::{ColorMode, Config};
 use error;
+use highlight::Highlighter;
+use keys::{self, KeyPress};
+use line_buffer::LineBuffer;
 use Result;
-use super::{RawMode, RawReader, Term};
+use StdStream;
 
-const STDIN_FILENO: winapi::DWORD = winapi::STD_INPUT_HANDLE;
-const STDOUT_FILENO: winapi::DWORD = winapi::STD_OUTPUT_HANDLE;
+const STDIN_FILENO: DWORD = winbase::STD_INPUT_HANDLE;
+const STDOUT_FILENO: DWORD = winbase::STD_OUTPUT_HANDLE;
+const STDERR_FILENO: DWORD = winbase::STD_ERROR_HANDLE;
 
-fn get_std_handle(fd: winapi::DWORD) -> Result<winapi::HANDLE> {
-    let handle = unsafe { kernel32::GetStdHandle(fd) };
-    if handle == winapi::INVALID_HANDLE_VALUE {
+fn get_std_handle(fd: DWORD) -> Result<HANDLE> {
+    let handle = unsafe { processenv::GetStdHandle(fd) };
+    if handle == handleapi::INVALID_HANDLE_VALUE {
         try!(Err(io::Error::last_os_error()));
     } else if handle.is_null() {
-        try!(Err(io::Error::new(io::ErrorKind::Other,
-                                "no stdio handle available for this process")));
+        try!(Err(io::Error::new(
+            io::ErrorKind::Other,
+            "no stdio handle available for this process",
+        ),));
     }
     Ok(handle)
 }
 
 #[macro_export]
 macro_rules! check {
-    ($funcall:expr) => {
-        {
+    ($funcall:expr) => {{
         let rc = unsafe { $funcall };
         if rc == 0 {
             try!(Err(io::Error::last_os_error()));
         }
         rc
-        }
-    };
+    }};
 }
 
-fn get_win_size(handle: winapi::HANDLE) -> (usize, usize) {
+fn get_win_size(handle: HANDLE) -> (usize, usize) {
     let mut info = unsafe { mem::zeroed() };
-    match unsafe { kernel32::GetConsoleScreenBufferInfo(handle, &mut info) } {
+    match unsafe { wincon::GetConsoleScreenBufferInfo(handle, &mut info) } {
         0 => (80, 24),
-        _ => (info.dwSize.X as usize, (1 + info.srWindow.Bottom - info.srWindow.Top) as usize),
+        _ => (
+            info.dwSize.X as usize,
+            (1 + info.srWindow.Bottom - info.srWindow.Top) as usize,
+        ), // (info.srWindow.Right - info.srWindow.Left + 1)
     }
 }
 
-fn get_console_mode(handle: winapi::HANDLE) -> Result<winapi::DWORD> {
+fn get_console_mode(handle: HANDLE) -> Result<DWORD> {
     let mut original_mode = 0;
-    check!(kernel32::GetConsoleMode(handle, &mut original_mode));
+    check!(consoleapi::GetConsoleMode(handle, &mut original_mode));
     Ok(original_mode)
 }
 
 pub type Mode = ConsoleMode;
 
-#[derive(Clone,Copy,Debug)]
+#[derive(Clone, Copy, Debug)]
 pub struct ConsoleMode {
-    original_mode: winapi::DWORD,
-    stdin_handle: winapi::HANDLE,
+    original_stdin_mode: DWORD,
+    stdin_handle: HANDLE,
+    original_stdstream_mode: Option<DWORD>,
+    stdstream_handle: HANDLE,
 }
 
 impl RawMode for Mode {
     /// Disable RAW mode for the terminal.
     fn disable_raw_mode(&self) -> Result<()> {
-        check!(kernel32::SetConsoleMode(self.stdin_handle, self.original_mode));
+        check!(consoleapi::SetConsoleMode(
+            self.stdin_handle,
+            self.original_stdin_mode,
+        ));
+        if let Some(original_stdstream_mode) = self.original_stdstream_mode {
+            check!(consoleapi::SetConsoleMode(
+                self.stdstream_handle,
+                original_stdstream_mode,
+            ));
+        }
         Ok(())
     }
 }
 
 /// Console input reader
 pub struct ConsoleRawReader {
-    handle: winapi::HANDLE,
-    buf: Option<u16>,
+    handle: HANDLE,
 }
 
 impl ConsoleRawReader {
-    pub fn new() -> Result<ConsoleRawReader> {
+    pub fn new(stream: OutputStreamType) -> Result<ConsoleRawReader> {
         let handle = try!(get_std_handle(STDIN_FILENO));
-        Ok(ConsoleRawReader {
-               handle: handle,
-               buf: None,
-           })
+        Ok(ConsoleRawReader { handle })
     }
 }
 
 impl RawReader for ConsoleRawReader {
-    fn next_key(&mut self) -> Result<KeyPress> {
+    fn next_key(&mut self, _: bool) -> Result<KeyPress> {
         use std::char::decode_utf16;
-        // use winapi::{LEFT_ALT_PRESSED, LEFT_CTRL_PRESSED, RIGHT_ALT_PRESSED, RIGHT_CTRL_PRESSED};
-        use winapi::{LEFT_ALT_PRESSED, RIGHT_ALT_PRESSED};
+        use winapi::um::wincon::{
+            LEFT_ALT_PRESSED, LEFT_CTRL_PRESSED, RIGHT_ALT_PRESSED, RIGHT_CTRL_PRESSED,
+            SHIFT_PRESSED,
+        };
 
-        let mut rec: winapi::INPUT_RECORD = unsafe { mem::zeroed() };
+        let mut rec: wincon::INPUT_RECORD = unsafe { mem::zeroed() };
         let mut count = 0;
+        let mut surrogate = 0;
         loop {
             // TODO GetNumberOfConsoleInputEvents
-            check!(kernel32::ReadConsoleInputW(self.handle,
-                                               &mut rec,
-                                               1 as winapi::DWORD,
-                                               &mut count));
+            check!(consoleapi::ReadConsoleInputW(
+                self.handle,
+                &mut rec,
+                1 as DWORD,
+                &mut count,
+            ));
 
-            if rec.EventType == winapi::WINDOW_BUFFER_SIZE_EVENT {
+            if rec.EventType == wincon::WINDOW_BUFFER_SIZE_EVENT {
                 SIGWINCH.store(true, atomic::Ordering::SeqCst);
                 debug!(target: "rustyline", "SIGWINCH");
-                return Err(error::ReadlineError::WindowResize);
-            } else if rec.EventType != winapi::KEY_EVENT {
+                return Err(error::ReadlineError::WindowResize); // sigwinch + err => err ignored
+            } else if rec.EventType != wincon::KEY_EVENT {
                 continue;
             }
-            let key_event = unsafe { rec.KeyEvent() };
+            let key_event = unsafe { rec.Event.KeyEvent() };
             // writeln!(io::stderr(), "key_event: {:?}", key_event).unwrap();
-            if key_event.bKeyDown == 0 &&
-               key_event.wVirtualKeyCode != winapi::VK_MENU as winapi::WORD {
+            if key_event.bKeyDown == 0 && key_event.wVirtualKeyCode != winuser::VK_MENU as WORD {
                 continue;
             }
+            // key_event.wRepeatCount seems to be always set to 1 (maybe because we only
+            // read one character at a time)
 
-            // let alt_gr = key_event.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED) != 0;
+            let alt_gr = key_event.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED)
+                == (LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED);
             let alt = key_event.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED) != 0;
-            // let ctrl = key_event.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) != 0;
-            let meta = alt;
+            let ctrl = key_event.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) != 0;
+            let meta = alt && !alt_gr;
+            let shift = key_event.dwControlKeyState & SHIFT_PRESSED != 0;
 
-            let utf16 = key_event.UnicodeChar;
+            let utf16 = unsafe { *key_event.uChar.UnicodeChar() };
             if utf16 == 0 {
                 match key_event.wVirtualKeyCode as i32 {
-                    winapi::VK_LEFT => return Ok(KeyPress::Left),
-                    winapi::VK_RIGHT => return Ok(KeyPress::Right),
-                    winapi::VK_UP => return Ok(KeyPress::Up),
-                    winapi::VK_DOWN => return Ok(KeyPress::Down),
-                    winapi::VK_DELETE => return Ok(KeyPress::Delete),
-                    winapi::VK_HOME => return Ok(KeyPress::Home),
-                    winapi::VK_END => return Ok(KeyPress::End),
-                    winapi::VK_PRIOR => return Ok(KeyPress::PageUp),
-                    winapi::VK_NEXT => return Ok(KeyPress::PageDown),
+                    winuser::VK_LEFT => {
+                        return Ok(if ctrl {
+                            KeyPress::ControlLeft
+                        } else if shift {
+                            KeyPress::ShiftLeft
+                        } else {
+                            KeyPress::Left
+                        })
+                    }
+                    winuser::VK_RIGHT => {
+                        return Ok(if ctrl {
+                            KeyPress::ControlRight
+                        } else if shift {
+                            KeyPress::ShiftRight
+                        } else {
+                            KeyPress::Right
+                        })
+                    }
+                    winuser::VK_UP => {
+                        return Ok(if ctrl {
+                            KeyPress::ControlUp
+                        } else if shift {
+                            KeyPress::ShiftUp
+                        } else {
+                            KeyPress::Up
+                        })
+                    }
+                    winuser::VK_DOWN => {
+                        return Ok(if ctrl {
+                            KeyPress::ControlDown
+                        } else if shift {
+                            KeyPress::ShiftDown
+                        } else {
+                            KeyPress::Down
+                        })
+                    }
+                    winuser::VK_DELETE => return Ok(KeyPress::Delete),
+                    winuser::VK_HOME => return Ok(KeyPress::Home),
+                    winuser::VK_END => return Ok(KeyPress::End),
+                    winuser::VK_PRIOR => return Ok(KeyPress::PageUp),
+                    winuser::VK_NEXT => return Ok(KeyPress::PageDown),
+                    winuser::VK_INSERT => return Ok(KeyPress::Insert),
+                    winuser::VK_F1 => return Ok(KeyPress::F(1)),
+                    winuser::VK_F2 => return Ok(KeyPress::F(2)),
+                    winuser::VK_F3 => return Ok(KeyPress::F(3)),
+                    winuser::VK_F4 => return Ok(KeyPress::F(4)),
+                    winuser::VK_F5 => return Ok(KeyPress::F(5)),
+                    winuser::VK_F6 => return Ok(KeyPress::F(6)),
+                    winuser::VK_F7 => return Ok(KeyPress::F(7)),
+                    winuser::VK_F8 => return Ok(KeyPress::F(8)),
+                    winuser::VK_F9 => return Ok(KeyPress::F(9)),
+                    winuser::VK_F10 => return Ok(KeyPress::F(10)),
+                    winuser::VK_F11 => return Ok(KeyPress::F(11)),
+                    winuser::VK_F12 => return Ok(KeyPress::F(12)),
+                    // winuser::VK_BACK is correctly handled because the key_event.UnicodeChar is
+                    // also set.
                     _ => continue,
                 };
             } 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 = utf16;
+                    continue;
+                }
+                let orc = if surrogate == 0 {
+                    decode_utf16(Some(utf16)).next()
+                } else {
+                    decode_utf16([surrogate, utf16].iter().cloned()).next()
+                };
                 if orc.is_none() {
                     return Err(error::ReadlineError::Eof);
                 }
                 let c = try!(orc.unwrap());
                 if meta {
-                    return Ok(match c {
-                                  '-' => KeyPress::Meta('-'),
-                                  '0'...'9' => KeyPress::Meta(c),
-                                  '<' => 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'),
-                                  _ => {
-                        debug!(target: "rustyline", "unsupported esc sequence: M-{:?}", c);
-                        KeyPress::UnknownEscSeq
-                    }
-                              });
+                    return Ok(KeyPress::Meta(c));
                 } else {
-                    return Ok(consts::char_to_key_press(c));
+                    let mut key = keys::char_to_key_press(c);
+                    if key == KeyPress::Tab && shift {
+                        key = KeyPress::BackTab;
+                    } else if key == KeyPress::Char(' ') && ctrl {
+                        key = KeyPress::Ctrl(' ');
+                    }
+                    return Ok(key);
                 }
             }
         }
     }
 }
 
-impl Iterator for ConsoleRawReader {
-    type Item = u16;
+pub struct ConsoleRenderer {
+    out: StdStream,
+    handle: HANDLE,
+    cols: usize, // Number of columns in terminal
+    buffer: String,
+}
 
-    fn next(&mut self) -> Option<u16> {
-        let buf = self.buf;
-        self.buf = None;
-        buf
+impl ConsoleRenderer {
+    fn new(handle: HANDLE, stream_type: OutputStreamType) -> ConsoleRenderer {
+        // Multi line editing is enabled by ENABLE_WRAP_AT_EOL_OUTPUT mode
+        let (cols, _) = get_win_size(handle);
+        ConsoleRenderer {
+            out: StdStream::from_stream_type(stream_type),
+            handle,
+            cols,
+            buffer: String::with_capacity(1024),
+        }
+    }
+
+    fn get_console_screen_buffer_info(&self) -> Result<wincon::CONSOLE_SCREEN_BUFFER_INFO> {
+        let mut info = unsafe { mem::zeroed() };
+        check!(wincon::GetConsoleScreenBufferInfo(self.handle, &mut info));
+        Ok(info)
+    }
+
+    fn set_console_cursor_position(&mut self, pos: wincon::COORD) -> Result<()> {
+        check!(wincon::SetConsoleCursorPosition(self.handle, pos));
+        Ok(())
+    }
+
+    fn clear(&mut self, length: DWORD, pos: wincon::COORD) -> Result<()> {
+        let mut _count = 0;
+        check!(wincon::FillConsoleOutputCharacterA(
+            self.handle,
+            ' ' as CHAR,
+            length,
+            pos,
+            &mut _count,
+        ));
+        Ok(())
+    }
+}
+
+impl Renderer for ConsoleRenderer {
+    fn move_cursor(&mut self, old: Position, new: Position) -> Result<()> {
+        let mut info = try!(self.get_console_screen_buffer_info());
+        if new.row > old.row {
+            info.dwCursorPosition.Y += (new.row - old.row) as i16;
+        } else {
+            info.dwCursorPosition.Y -= (old.row - new.row) as i16;
+        }
+        if new.col > old.col {
+            info.dwCursorPosition.X += (new.col - old.col) as i16;
+        } else {
+            info.dwCursorPosition.X -= (old.col - new.col) as i16;
+        }
+        self.set_console_cursor_position(info.dwCursorPosition)
+    }
+
+    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)> {
+        // 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);
+
+        // position at the start of the prompt, clear to end of previous input
+        let mut info = try!(self.get_console_screen_buffer_info());
+        info.dwCursorPosition.X = 0;
+        info.dwCursorPosition.Y -= current_row as i16;
+        try!(self.set_console_cursor_position(info.dwCursorPosition));
+        try!(self.clear(
+            (info.dwSize.X * (old_rows as i16 + 1)) as DWORD,
+            info.dwCursorPosition,
+        ));
+        self.buffer.clear();
+        if let Some(highlighter) = highlighter {
+            // TODO handle ansi escape code (SetConsoleTextAttribute)
+            // 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);
+            }
+        }
+        try!(self.out.write_all(self.buffer.as_bytes()));
+        try!(self.out.flush());
+
+        // position the cursor
+        let mut info = try!(self.get_console_screen_buffer_info());
+        info.dwCursorPosition.X = cursor.col as i16;
+        info.dwCursorPosition.Y -= (end_pos.row - cursor.row) as i16;
+        try!(self.set_console_cursor_position(info.dwCursorPosition));
+        Ok((cursor, end_pos))
+    }
+
+    fn write_and_flush(&mut self, buf: &[u8]) -> Result<()> {
+        try!(self.out.write_all(buf));
+        try!(self.out.flush());
+        Ok(())
+    }
+
+    /// Characters with 2 column width are correctly handled (not splitted).
+    fn calculate_position(&self, s: &str, orig: Position) -> Position {
+        let mut pos = orig;
+        for c in s.chars() {
+            let cw = if c == '\n' {
+                pos.col = 0;
+                pos.row += 1;
+                None
+            } else {
+                c.width()
+            };
+            if let Some(cw) = cw {
+                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
+    }
+
+    /// Clear the screen. Used to handle ctrl+l
+    fn clear_screen(&mut self) -> Result<()> {
+        let info = try!(self.get_console_screen_buffer_info());
+        let coord = wincon::COORD { X: 0, Y: 0 };
+        check!(wincon::SetConsoleCursorPosition(self.handle, coord));
+        let n = info.dwSize.X as DWORD * info.dwSize.Y as DWORD;
+        self.clear(n, coord)
+    }
+
+    fn sigwinch(&self) -> bool {
+        SIGWINCH.compare_and_swap(true, false, atomic::Ordering::SeqCst)
+    }
+
+    /// Try to get the number of columns in the current terminal,
+    /// or assume 80 if it fails.
+    fn update_size(&mut self) {
+        let (cols, _) = get_win_size(self.handle);
+        self.cols = cols;
+    }
+
+    fn get_columns(&self) -> usize {
+        self.cols
+    }
+
+    /// 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(self.handle);
+        rows
     }
 }
 
@@ -186,45 +422,25 @@
 
 pub type Terminal = Console;
 
-#[derive(Clone,Debug)]
+#[derive(Clone, Debug)]
 pub struct Console {
     stdin_isatty: bool,
-    stdin_handle: winapi::HANDLE,
-    stdout_handle: winapi::HANDLE,
+    stdin_handle: HANDLE,
+    stdstream_isatty: bool,
+    stdstream_handle: HANDLE,
+    pub(crate) color_mode: ColorMode,
+    ansi_colors_supported: bool,
+    stream_type: OutputStreamType,
 }
 
-impl Console {
-    pub fn get_console_screen_buffer_info(&self) -> Result<winapi::CONSOLE_SCREEN_BUFFER_INFO> {
-        let mut info = unsafe { mem::zeroed() };
-        check!(kernel32::GetConsoleScreenBufferInfo(self.stdout_handle, &mut info));
-        Ok(info)
-    }
-
-    pub fn set_console_cursor_position(&mut self, pos: winapi::COORD) -> Result<()> {
-        check!(kernel32::SetConsoleCursorPosition(self.stdout_handle, pos));
-        Ok(())
-    }
-
-    pub fn fill_console_output_character(&mut self,
-                                         length: winapi::DWORD,
-                                         pos: winapi::COORD)
-                                         -> Result<()> {
-        let mut _count = 0;
-        check!(kernel32::FillConsoleOutputCharacterA(self.stdout_handle,
-                                                     ' ' as winapi::CHAR,
-                                                     length,
-                                                     pos,
-                                                     &mut _count));
-        Ok(())
-    }
-}
+impl Console {}
 
 impl Term for Console {
-    type Reader = ConsoleRawReader;
-    type Writer = Stdout;
     type Mode = Mode;
+    type Reader = ConsoleRawReader;
+    type Writer = ConsoleRenderer;
 
-    fn new() -> Console {
+    fn new(color_mode: ColorMode, stream_type: OutputStreamType) -> Console {
         use std::ptr;
         let stdin_handle = get_std_handle(STDIN_FILENO);
         let stdin_isatty = match stdin_handle {
@@ -235,11 +451,27 @@
             Err(_) => false,
         };
 
-        let stdout_handle = get_std_handle(STDOUT_FILENO).unwrap_or(ptr::null_mut());
+        let stdstream_handle = get_std_handle(if stream_type == OutputStreamType::Stdout {
+            STDOUT_FILENO
+        } else {
+            STDERR_FILENO
+        });
+        let stdstream_isatty = match stdstream_handle {
+            Ok(handle) => {
+                // If this function doesn't fail then fd is a TTY
+                get_console_mode(handle).is_ok()
+            }
+            Err(_) => false,
+        };
+
         Console {
-            stdin_isatty: stdin_isatty,
+            stdin_isatty,
             stdin_handle: stdin_handle.unwrap_or(ptr::null_mut()),
-            stdout_handle: stdout_handle,
+            stdstream_isatty,
+            stdstream_handle: stdstream_handle.unwrap_or(ptr::null_mut()),
+            color_mode,
+            ansi_colors_supported: false,
+            stream_type,
         }
     }
 
@@ -252,71 +484,66 @@
         self.stdin_isatty
     }
 
+    fn colors_enabled(&self) -> bool {
+        // TODO ANSI Colors & Windows <10
+        match self.color_mode {
+            ColorMode::Enabled => self.stdstream_isatty && self.ansi_colors_supported,
+            ColorMode::Forced => true,
+            ColorMode::Disabled => false,
+        }
+    }
+
     // pub fn install_sigwinch_handler(&mut self) {
     // See ReadConsoleInputW && WINDOW_BUFFER_SIZE_EVENT
     // }
 
-    /// 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(self.stdout_handle);
-        cols
-    }
-
-    /// 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(self.stdout_handle);
-        rows
-    }
-
     /// Enable RAW mode for the terminal.
-    fn enable_raw_mode(&self) -> Result<Mode> {
+    fn enable_raw_mode(&mut self) -> Result<Mode> {
         if !self.stdin_isatty {
-            try!(Err(io::Error::new(io::ErrorKind::Other,
-                                    "no stdio handle available for this process")));
+            try!(Err(io::Error::new(
+                io::ErrorKind::Other,
+                "no stdio handle available for this process",
+            ),));
         }
-        let original_mode = try!(get_console_mode(self.stdin_handle));
+        let original_stdin_mode = try!(get_console_mode(self.stdin_handle));
         // Disable these modes
-        let raw = original_mode &
-                  !(winapi::wincon::ENABLE_LINE_INPUT | winapi::wincon::ENABLE_ECHO_INPUT |
-                    winapi::wincon::ENABLE_PROCESSED_INPUT);
+        let mut raw = original_stdin_mode & !(wincon::ENABLE_LINE_INPUT
+            | wincon::ENABLE_ECHO_INPUT
+            | wincon::ENABLE_PROCESSED_INPUT);
         // Enable these modes
-        let raw = raw | winapi::wincon::ENABLE_EXTENDED_FLAGS;
-        let raw = raw | winapi::wincon::ENABLE_INSERT_MODE;
-        let raw = raw | winapi::wincon::ENABLE_QUICK_EDIT_MODE;
-        let raw = raw | winapi::wincon::ENABLE_WINDOW_INPUT;
-        check!(kernel32::SetConsoleMode(self.stdin_handle, raw));
+        raw |= wincon::ENABLE_EXTENDED_FLAGS;
+        raw |= wincon::ENABLE_INSERT_MODE;
+        raw |= wincon::ENABLE_QUICK_EDIT_MODE;
+        raw |= wincon::ENABLE_WINDOW_INPUT;
+        check!(consoleapi::SetConsoleMode(self.stdin_handle, raw));
+
+        let original_stdstream_mode = if self.stdstream_isatty {
+            let original_stdstream_mode = try!(get_console_mode(self.stdstream_handle));
+            // To enable ANSI colors (Windows 10 only):
+            // https://docs.microsoft.com/en-us/windows/console/setconsolemode
+            if original_stdstream_mode & wincon::ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0 {
+                let raw = original_stdstream_mode | wincon::ENABLE_VIRTUAL_TERMINAL_PROCESSING;
+                self.ansi_colors_supported =
+                    unsafe { consoleapi::SetConsoleMode(self.stdstream_handle, raw) != 0 };
+            }
+            Some(original_stdstream_mode)
+        } else {
+            None
+        };
+
         Ok(Mode {
-               original_mode: original_mode,
-               stdin_handle: self.stdin_handle,
-           })
+            original_stdin_mode,
+            stdin_handle: self.stdin_handle,
+            original_stdstream_mode,
+            stdstream_handle: self.stdstream_handle,
+        })
     }
 
     fn create_reader(&self, _: &Config) -> Result<ConsoleRawReader> {
-        ConsoleRawReader::new()
+        ConsoleRawReader::new(self.stream_type)
     }
 
-    fn create_writer(&self) -> Stdout {
-        io::stdout()
-    }
-
-    fn sigwinch(&self) -> bool {
-        SIGWINCH.compare_and_swap(true, false, atomic::Ordering::SeqCst)
-    }
-
-    /// Clear the screen. Used to handle ctrl+l
-    fn clear_screen(&mut self, _: &mut Write) -> Result<()> {
-        let info = try!(self.get_console_screen_buffer_info());
-        let coord = winapi::COORD { X: 0, Y: 0 };
-        check!(kernel32::SetConsoleCursorPosition(self.stdout_handle, coord));
-        let mut _count = 0;
-        let n = info.dwSize.X as winapi::DWORD * info.dwSize.Y as winapi::DWORD;
-        check!(kernel32::FillConsoleOutputCharacterA(self.stdout_handle,
-                                                     ' ' as winapi::CHAR,
-                                                     n,
-                                                     coord,
-                                                     &mut _count));
-        Ok(())
+    fn create_writer(&self) -> ConsoleRenderer {
+        ConsoleRenderer::new(self.stdstream_handle, self.stream_type)
     }
 }
diff --git a/src/undo.rs b/src/undo.rs
new file mode 100644
index 0000000..7f7c9ab
--- /dev/null
+++ b/src/undo.rs
@@ -0,0 +1,471 @@
+//! Undo API
+use std::fmt::Debug;
+
+use keymap::RepeatCount;
+use line_buffer::{ChangeListener, DeleteListener, Direction, LineBuffer};
+use unicode_segmentation::UnicodeSegmentation;
+
+enum Change {
+    Begin,
+    End,
+    Insert {
+        idx: usize,
+        text: String,
+    }, // QuotedInsert, SelfInsert, Yank
+    Delete {
+        idx: usize,
+        text: String,
+    }, /* BackwardDeleteChar, BackwardKillWord, DeleteChar,
+        * KillLine, KillWholeLine, KillWord,
+        * UnixLikeDiscard, ViDeleteTo */
+    Replace {
+        idx: usize,
+        old: String,
+        new: String,
+    }, /* CapitalizeWord, Complete, DowncaseWord, Replace, TransposeChars, TransposeWords,
+        * UpcaseWord, YankPop */
+}
+
+impl Change {
+    fn undo(&self, line: &mut LineBuffer) {
+        match *self {
+            Change::Begin | Change::End => {
+                unreachable!();
+            }
+            Change::Insert { idx, ref text } => {
+                line.delete_range(idx..idx + text.len());
+            }
+            Change::Delete { idx, ref text } => {
+                line.insert_str(idx, text);
+                line.set_pos(idx + text.len());
+            }
+            Change::Replace {
+                idx,
+                ref old,
+                ref new,
+            } => {
+                line.replace(idx..idx + new.len(), old);
+            }
+        }
+    }
+
+    #[cfg(test)]
+    fn redo(&self, line: &mut LineBuffer) {
+        match *self {
+            Change::Begin | Change::End => {
+                unreachable!();
+            }
+            Change::Insert { idx, ref text } => {
+                line.insert_str(idx, text);
+            }
+            Change::Delete { idx, ref text } => {
+                line.delete_range(idx..idx + text.len());
+            }
+            Change::Replace {
+                idx,
+                ref old,
+                ref new,
+            } => {
+                line.replace(idx..idx + old.len(), new);
+            }
+        }
+    }
+
+    fn insert_seq(&self, indx: usize) -> bool {
+        if let Change::Insert { idx, ref text } = *self {
+            idx + text.len() == indx
+        } else {
+            false
+        }
+    }
+
+    fn delete_seq(&self, indx: usize, len: usize) -> bool {
+        if let Change::Delete { idx, .. } = *self {
+            // delete or backspace
+            idx == indx || idx == indx + len
+        } else {
+            false
+        }
+    }
+
+    fn replace_seq(&self, indx: usize) -> bool {
+        if let Change::Replace { idx, ref new, .. } = *self {
+            idx + new.len() == indx
+        } else {
+            false
+        }
+    }
+}
+
+pub struct Changeset {
+    undo_group_level: u32,
+    undos: Vec<Change>, // undoable changes
+    redos: Vec<Change>, // undone changes, redoable
+}
+
+impl Changeset {
+    pub fn new() -> Changeset {
+        Changeset {
+            undo_group_level: 0,
+            undos: Vec::new(),
+            redos: Vec::new(),
+        }
+    }
+
+    pub fn begin(&mut self) -> usize {
+        debug!(target: "rustyline", "Changeset::begin");
+        self.redos.clear();
+        let mark = self.undos.len();
+        self.undos.push(Change::Begin);
+        self.undo_group_level += 1;
+        mark
+    }
+
+    pub fn end(&mut self) {
+        debug!(target: "rustyline", "Changeset::end");
+        self.redos.clear();
+        while self.undo_group_level > 0 {
+            self.undo_group_level -= 1;
+            if let Some(&Change::Begin) = self.undos.last() {
+                // emtpy Begin..End
+                self.undos.pop();
+            } else {
+                self.undos.push(Change::End);
+            }
+        }
+    }
+
+    fn insert_char(idx: usize, c: char) -> Change {
+        let mut text = String::new();
+        text.push(c);
+        Change::Insert { idx, text }
+    }
+
+    pub fn insert(&mut self, idx: usize, c: char) {
+        debug!(target: "rustyline", "Changeset::insert({}, {:?})", idx, c);
+        self.redos.clear();
+        if !c.is_alphanumeric() || !self.undos.last().map_or(false, |lc| lc.insert_seq(idx)) {
+            self.undos.push(Self::insert_char(idx, c));
+            return;
+        }
+        // merge consecutive char insertions when char is alphanumeric
+        let mut last_change = self.undos.pop().unwrap();
+        if let Change::Insert { ref mut text, .. } = last_change {
+            text.push(c);
+        } else {
+            unreachable!();
+        }
+        self.undos.push(last_change);
+    }
+
+    pub fn insert_str<S: AsRef<str> + Into<String> + Debug>(&mut self, idx: usize, string: S) {
+        debug!(target: "rustyline", "Changeset::insert_str({}, {:?})", idx, string);
+        self.redos.clear();
+        if string.as_ref().is_empty() {
+            return;
+        }
+        self.undos.push(Change::Insert {
+            idx,
+            text: string.into(),
+        });
+    }
+
+    pub fn delete<S: AsRef<str> + Into<String> + Debug>(&mut self, indx: usize, string: S) {
+        debug!(target: "rustyline", "Changeset::delete({}, {:?})", indx, string);
+        self.redos.clear();
+        if string.as_ref().is_empty() {
+            return;
+        }
+
+        if !Self::single_char(string.as_ref()) || !self
+            .undos
+            .last()
+            .map_or(false, |lc| lc.delete_seq(indx, string.as_ref().len()))
+        {
+            self.undos.push(Change::Delete {
+                idx: indx,
+                text: string.into(),
+            });
+            return;
+        }
+        // merge consecutive char deletions when char is alphanumeric
+        let mut last_change = self.undos.pop().unwrap();
+        if let Change::Delete {
+            ref mut idx,
+            ref mut text,
+        } = last_change
+        {
+            if *idx == indx {
+                text.push_str(string.as_ref());
+            } else {
+                text.insert_str(0, string.as_ref());
+                *idx = indx;
+            }
+        } else {
+            unreachable!();
+        }
+        self.undos.push(last_change);
+    }
+
+    fn single_char(s: &str) -> bool {
+        let mut graphemes = s.graphemes(true);
+        graphemes.next().map_or(false, |grapheme| {
+            grapheme.chars().all(|c| c.is_alphanumeric())
+        }) && graphemes.next().is_none()
+    }
+
+    pub fn replace<S: AsRef<str> + Into<String> + Debug>(&mut self, indx: usize, old_: S, new_: S) {
+        debug!(target: "rustyline", "Changeset::replace({}, {:?}, {:?})", indx, old_, new_);
+        self.redos.clear();
+
+        if !self.undos.last().map_or(false, |lc| lc.replace_seq(indx)) {
+            self.undos.push(Change::Replace {
+                idx: indx,
+                old: old_.into(),
+                new: new_.into(),
+            });
+            return;
+        }
+
+        // merge consecutive char replacements
+        let mut last_change = self.undos.pop().unwrap();
+        if let Change::Replace {
+            ref mut old,
+            ref mut new,
+            ..
+        } = last_change
+        {
+            old.push_str(old_.as_ref());
+            new.push_str(new_.as_ref());
+        } else {
+            unreachable!();
+        }
+        self.undos.push(last_change);
+    }
+
+    pub fn undo(&mut self, line: &mut LineBuffer, n: RepeatCount) -> bool {
+        debug!(target: "rustyline", "Changeset::undo");
+        let mut count = 0;
+        let mut waiting_for_begin = 0;
+        let mut undone = false;
+        loop {
+            if let Some(change) = self.undos.pop() {
+                match change {
+                    Change::Begin => {
+                        waiting_for_begin -= 1;
+                    }
+                    Change::End => {
+                        waiting_for_begin += 1;
+                    }
+                    _ => {
+                        change.undo(line);
+                        undone = true;
+                    }
+                };
+                self.redos.push(change);
+            } else {
+                break;
+            }
+            if waiting_for_begin <= 0 {
+                count += 1;
+                if count >= n {
+                    break;
+                }
+            }
+        }
+        undone
+    }
+
+    pub fn truncate(&mut self, len: usize) {
+        debug!(target: "rustyline", "Changeset::truncate({})", len);
+        self.undos.truncate(len);
+    }
+
+    #[cfg(test)]
+    pub fn redo(&mut self, line: &mut LineBuffer) -> bool {
+        let mut waiting_for_end = 0;
+        let mut redone = false;
+        loop {
+            if let Some(change) = self.redos.pop() {
+                match change {
+                    Change::Begin => {
+                        waiting_for_end += 1;
+                    }
+                    Change::End => {
+                        waiting_for_end -= 1;
+                    }
+                    _ => {
+                        change.redo(line);
+                        redone = true;
+                    }
+                };
+                self.undos.push(change);
+            } else {
+                break;
+            }
+            if waiting_for_end <= 0 {
+                break;
+            }
+        }
+        redone
+    }
+
+    pub fn last_insert(&self) -> Option<String> {
+        for change in self.undos.iter().rev() {
+            match change {
+                Change::Insert { ref text, .. } => return Some(text.to_owned()),
+                Change::Replace { ref new, .. } => return Some(new.to_owned()),
+                Change::End => {
+                    continue;
+                }
+                _ => {
+                    return None;
+                }
+            }
+        }
+        None
+    }
+}
+
+impl DeleteListener for Changeset {
+    fn start_killing(&mut self) {}
+
+    fn delete(&mut self, idx: usize, string: &str, _: Direction) {
+        self.delete(idx, string);
+    }
+
+    fn stop_killing(&mut self) {}
+}
+impl ChangeListener for Changeset {
+    fn insert_char(&mut self, idx: usize, c: char) {
+        self.insert(idx, c);
+    }
+
+    fn insert_str(&mut self, idx: usize, string: &str) {
+        self.insert_str(idx, string);
+    }
+
+    fn replace(&mut self, idx: usize, old: &str, new: &str) {
+        self.replace(idx, old, new);
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::Changeset;
+    use line_buffer::LineBuffer;
+
+    #[test]
+    fn test_insert_chars() {
+        let mut cs = Changeset::new();
+        cs.insert(0, 'H');
+        cs.insert(1, 'i');
+        assert_eq!(1, cs.undos.len());
+        assert_eq!(0, cs.redos.len());
+        cs.insert(0, ' ');
+        assert_eq!(2, cs.undos.len());
+    }
+
+    #[test]
+    fn test_insert_strings() {
+        let mut cs = Changeset::new();
+        cs.insert_str(0, "Hello");
+        cs.insert_str(5, ", ");
+        assert_eq!(2, cs.undos.len());
+        assert_eq!(0, cs.redos.len());
+    }
+
+    #[test]
+    fn test_undo_insert() {
+        let mut buf = LineBuffer::init("", 0, None);
+        buf.insert_str(0, "Hello");
+        buf.insert_str(5, ", world!");
+        let mut cs = Changeset::new();
+        assert_eq!(buf.as_str(), "Hello, world!");
+
+        cs.insert_str(5, ", world!");
+
+        cs.undo(&mut buf, 1);
+        assert_eq!(0, cs.undos.len());
+        assert_eq!(1, cs.redos.len());
+        assert_eq!(buf.as_str(), "Hello");
+
+        cs.redo(&mut buf);
+        assert_eq!(1, cs.undos.len());
+        assert_eq!(0, cs.redos.len());
+        assert_eq!(buf.as_str(), "Hello, world!");
+    }
+
+    #[test]
+    fn test_undo_delete() {
+        let mut buf = LineBuffer::init("", 0, None);
+        buf.insert_str(0, "Hello");
+        let mut cs = Changeset::new();
+        assert_eq!(buf.as_str(), "Hello");
+
+        cs.delete(5, ", world!");
+
+        cs.undo(&mut buf, 1);
+        assert_eq!(buf.as_str(), "Hello, world!");
+
+        cs.redo(&mut buf);
+        assert_eq!(buf.as_str(), "Hello");
+    }
+
+    #[test]
+    fn test_delete_chars() {
+        let mut buf = LineBuffer::init("", 0, None);
+        buf.insert_str(0, "Hlo");
+
+        let mut cs = Changeset::new();
+        cs.delete(1, "e");
+        cs.delete(1, "l");
+        assert_eq!(1, cs.undos.len());
+
+        cs.undo(&mut buf, 1);
+        assert_eq!(buf.as_str(), "Hello");
+    }
+
+    #[test]
+    fn test_backspace_chars() {
+        let mut buf = LineBuffer::init("", 0, None);
+        buf.insert_str(0, "Hlo");
+
+        let mut cs = Changeset::new();
+        cs.delete(2, "l");
+        cs.delete(1, "e");
+        assert_eq!(1, cs.undos.len());
+
+        cs.undo(&mut buf, 1);
+        assert_eq!(buf.as_str(), "Hello");
+    }
+
+    #[test]
+    fn test_undo_replace() {
+        let mut buf = LineBuffer::init("", 0, None);
+        buf.insert_str(0, "Hello, world!");
+        let mut cs = Changeset::new();
+        assert_eq!(buf.as_str(), "Hello, world!");
+
+        buf.replace(1..5, "i");
+        assert_eq!(buf.as_str(), "Hi, world!");
+        cs.replace(1, "ello", "i");
+
+        cs.undo(&mut buf, 1);
+        assert_eq!(buf.as_str(), "Hello, world!");
+
+        cs.redo(&mut buf);
+        assert_eq!(buf.as_str(), "Hi, world!");
+    }
+
+    #[test]
+    fn test_last_insert() {
+        let mut cs = Changeset::new();
+        cs.begin();
+        cs.delete(0, "Hello");
+        cs.insert_str(0, "Bye");
+        cs.end();
+        let insert = cs.last_insert();
+        assert_eq!(Some("Bye".to_owned()), insert);
+    }
+}
