diff --git a/examples/keys.rs b/examples/keys.rs
index 7619551b54ec7688c64fb8b3c43c0d86d8288914..87ef52fb434ed617088b38f100e1eda8c48b519e 100644
--- a/examples/keys.rs
+++ b/examples/keys.rs
@@ -20,6 +20,7 @@ fn main() {
             Key::Char('q') => break,
             Key::Char(c) => println!("{}", c),
             Key::Alt(c) => println!("^{}", c),
+            Key::Ctrl(c) => println!("*{}", c),
             Key::Left => println!("←"),
             Key::Right => println!("→"),
             Key::Up => println!("↑"),
diff --git a/src/control.rs b/src/control.rs
index 7d5a09fde6359c81f44e720d64a6f1883815e64c..7b65619dac93e07a72e36f7c64114de706fcf9fa 100644
--- a/src/control.rs
+++ b/src/control.rs
@@ -43,6 +43,9 @@ pub trait TermWrite {
     fn hide_cursor(&mut self) -> IoResult<usize> {
         self.csi(b"?25l")
     }
+
+    // TODO insert mode
+
     /// Reset the rendition mode.
     ///
     /// This will reset both the current style and color.
diff --git a/src/input.rs b/src/input.rs
index b6fddbe3614b0bff4fda5e8287859e1151e83483..b2f767112ed4512c124422572bb66a6e6967f9e7 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -17,10 +17,14 @@ pub enum Key {
     Up,
     /// Down arrow.
     Down,
-    /// Alt modified character.
-    Alt(char),
     /// Normal character.
     Char(char),
+    /// Alt modified character.
+    Alt(char),
+    /// Ctrl modified character.
+    ///
+    /// Note that certain keys may not be modifiable with `ctrl`, due to limitations of terminals.
+    Ctrl(char),
     /// Invalid character code.
     Invalid,
     // TODO handle errors better?
@@ -52,6 +56,10 @@ impl<I: Iterator<Item = Result<char, CharsError>>> Iterator for Keys<I> {
                 Some(Err(_)) | None => Key::Invalid,
             }),
             Some(Ok('\x7F')) => Some(Key::Backspace),
+            Some(Ok(c @ '\x10' ... '\x1A')) => Some(Key::Ctrl((c as u8 - 0x10 + b'p') as char)),
+            Some(Ok(c @ '\x01' ... '\x04')) => Some(Key::Ctrl((c as u8 - 0x1  + b'a') as char)),
+            Some(Ok(c @ '\x1C' ... '\x1F')) => Some(Key::Ctrl((c as u8 - 0x1C + b'4') as char)),
+            Some(Ok('\x06')) => Some(Key::Alt('f')),
             Some(Ok(c)) => Some(Key::Char(c)),
             None => None,
             Some(Err(_)) => Some(Key::Error),