Vi first print
diff --git a/src/keymap.rs b/src/keymap.rs
index e97fbb0..004cb67 100644
--- a/src/keymap.rs
+++ b/src/keymap.rs
@@ -40,6 +40,7 @@
     Unknown,
     UpcaseWord,
     ViCharSearch(RepeatCount, CharSearch),
+    ViFirstPrint,
     ViYankTo(Movement),
     Yank(RepeatCount, Anchor),
     YankPop,
@@ -301,8 +302,8 @@
             KeyPress::End => Cmd::EndOfLine,
             KeyPress::Char('.') => self.last_cmd.clone(), // vi-redo
             // TODO KeyPress::Char('%') => Cmd::???, Move to the corresponding opening/closing bracket
-            KeyPress::Char('0') => Cmd::BeginningOfLine, // vi-zero: Vi move to the beginning of line.
-            KeyPress::Char('^') => Cmd::BeginningOfLine, // vi-first-print TODO Move to the first non-blank character of line.
+            KeyPress::Char('0') => Cmd::BeginningOfLine,
+            KeyPress::Char('^') => Cmd::ViFirstPrint,
             KeyPress::Char('a') => {
                 // vi-append-mode: Vi enter insert mode after the cursor.
                 self.insert = true;
diff --git a/src/lib.rs b/src/lib.rs
index 83e9626..cd038b3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -895,6 +895,11 @@
                 // Move to the beginning of line.
                 try!(edit_move_home(&mut s))
             }
+            Cmd::ViFirstPrint => {
+                editor.kill_ring.reset();
+                try!(edit_move_home(&mut s));
+                try!(edit_move_to_next_word(&mut s, At::Start, Word::Big, 1))
+            }
             Cmd::BackwardChar(n) => {
                 editor.kill_ring.reset();
                 // Move back a character.