diff --git a/rasa-ext-vim.cabal b/rasa-ext-vim.cabal
--- a/rasa-ext-vim.cabal
+++ b/rasa-ext-vim.cabal
@@ -1,38 +1,39 @@
-name:                rasa-ext-vim
-version:             0.1.0.0
-synopsis:            Rasa Ext for vim bindings
-description:         Rasa Ext for vim bindings
-homepage:            https://github.com/ChrisPenner/rasa/
-license:             MIT
-license-file:        LICENSE
-author:              Chris Penner
-maintainer:          christopher.penner@gmail.com
-copyright:           2016 Chris Penner
-category:            Extension
-build-type:          Simple
--- extra-source-files:
-cabal-version:       >=1.10
-
-library
-  hs-source-dirs:      src
-  exposed-modules:     Rasa.Ext.Vim
-  build-depends:       base >= 4.7 && < 5
-                     , rasa
-                     , rasa-ext-files
-                     , rasa-ext-cursors
-                     , rasa-ext-status-bar
-                     , text
-                     , yi-rope
-                     , text-lens
-                     , data-default
-                     , lens
-                     , mtl
-  default-language:    Haskell2010
+name: rasa-ext-vim
+version: 0.1.2
+cabal-version: >=1.10
+build-type: Simple
+license: MIT
+license-file: LICENSE
+copyright: 2016 Chris Penner
+maintainer: christopher.penner@gmail.com
+homepage: https://github.com/ChrisPenner/rasa/
+synopsis: Rasa Ext for vim bindings
+description:
+    Rasa Ext for vim bindings
+category: Extension
+author: Chris Penner
 
-  default-extensions:
+source-repository head
+    type: git
+    location: https://github.com/ChrisPenner/rasa
 
-  ghc-options:         -Wall
+library
+    exposed-modules:
+        Rasa.Ext.Vim
+    build-depends:
+        base >=4.8 && <5,
+        rasa >=0.1.6 && <0.2,
+        rasa-ext-files >=0.1.1 && <0.2,
+        rasa-ext-views >=0.1.1 && <0.2,
+        rasa-ext-cursors >=0.1.2 && <0.2,
+        rasa-ext-status-bar >=0.1.1 && <0.2,
+        text >=1.2.2.1 && <1.3,
+        yi-rope >=0.7.0.2 && <0.8,
+        text-lens >=0.1.0.0 && <0.2,
+        data-default >=0.7.1.1 && <0.8,
+        lens ==4.14.*,
+        mtl >=2.2.1 && <2.3
+    default-language: Haskell2010
+    hs-source-dirs: src
+    ghc-options: -Wall
 
-source-repository head
-  type:     git
-  location: https://github.com/ChrisPenner/rasa
diff --git a/src/Rasa/Ext/Vim.hs b/src/Rasa/Ext/Vim.hs
--- a/src/Rasa/Ext/Vim.hs
+++ b/src/Rasa/Ext/Vim.hs
@@ -1,107 +1,131 @@
-{-# Language OverloadedStrings #-}
+{-# Language OverloadedStrings, TemplateHaskell #-}
 module Rasa.Ext.Vim
   ( vim
   ) where
 
 import Rasa.Ext
+import Rasa.Ext.Views
 import Rasa.Ext.Files (save)
 import Rasa.Ext.Cursors
 import Rasa.Ext.StatusBar
 
+import Control.Monad (unless, void)
 import Control.Lens
-import Data.Text.Lens (packed)
 import Data.Default
 import Data.Typeable
-import qualified Data.Text as T
 import qualified Yi.Rope as Y
 
-data VimSt
+-- | A type representing the current mode of a buffer
+data VimMode
   = Normal
   | Insert
   deriving (Show, Typeable)
 
-instance Default VimSt where
+instance Default VimMode where
   def = Normal
 
--- | A helper to extract the vim state from the current buffer.
--- Specifying the type is what allows it to work.
-getVim :: BufAction VimSt
-getVim = use bufExt
+-- | A history of any keypresses which haven't matched a pattern
+newtype VimHist = VimHist
+  { _histKeys :: [Keypress]
+  } deriving (Show, Typeable)
+makeLenses ''VimHist
 
--- | A helper to set the current VimSt to the new mode
-setMode :: VimSt -> BufAction ()
-setMode vimst = bufExt .= vimst
+instance Default VimHist where
+  def = VimHist []
 
+-- | A hlens into vim's current mode.
+mode :: HasBuffer s => Lens' s VimMode
+mode = bufExt
+
+-- | A lens into the current unresolved keypress history
+hist :: HasBuffer s => Lens' s [Keypress]
+hist = bufExt.histKeys
+
 -- | The main export for the vim keybinding extension. Add this to your user config.
 --
 -- e.g.
 --
--- > rasa [keypressProvider] $ do
+-- > rasa $ do
 -- >    vim
 -- >    ...
-vim :: Scheduler ()
+vim :: Action ()
 vim = do
   -- Register to listen for keypresses
-  eventListener handleKeypress
+  void $ eventListener handleKeypress
   -- Set the status bar to the current mode before each render
-  beforeRender setStatus
+  void $ beforeRender setStatus
 
 -- | The event hook which listens for keypresses and responds appropriately
 handleKeypress :: Keypress -> Action ()
-handleKeypress keypress = do
-  focMode <- focusDo $ do
-    mode <- getVim
-    case mode of
-      Normal -> normal keypress
-      Insert -> insert keypress
-    return mode
-  global focMode keypress
+handleKeypress keypress = focusDo_ $ do
+    mode' <- use mode
+    preHist <- use hist
+    case mode' of
+      Normal -> normal $ preHist ++ [keypress]
+      Insert -> insert $ preHist ++ [keypress]
+    anyMode $ preHist ++ [keypress]
+    postHist <- use hist
+    -- If nothing changed than an action must have happened
+    unless (preHist /= postHist) (hist .= [])
 
--- | Sets the status bar to the current mode
+-- | Sets the status bar to the current mode and current VimHist
 setStatus :: Action ()
-setStatus = focusDo $ do
-  mode <- getVim
-  centerStatus $ show mode^.packed
+setStatus = void . focusDo $ do
+  modeDisp <- use (mode.to show.to Y.fromString)
+  histDisp <- use (hist.to show.to Y.fromString)
+  centerStatus modeDisp
+  rightStatus histDisp
 
 -- | Listeners for keypresses that run regardless of current mode.
-global :: VimSt -> Keypress -> Action ()
-global Normal (Keypress '+' _) = nextBuf
-global Normal (Keypress '-' _) = prevBuf
-global _ (Keypress 'c' [Ctrl]) = exit
-global _ _ = return ()
+anyMode :: [Keypress] -> BufAction ()
+anyMode [Keypress 'c' [Ctrl]] = liftAction exit
+anyMode _ = return ()
 
 -- | Listeners for keypresses when in 'Insert' mode
-insert :: Keypress -> BufAction ()
-insert Esc = setMode Normal
-insert BS = moveRangesByN (-1) >> delete
-insert Enter = insertText "\n"
-insert (Keypress c _) = insertText (T.singleton c) >> moveRangesByN 1
+insert :: [Keypress] -> BufAction ()
+insert [KEsc] = mode .= Normal
+
+insert [KBS] = moveRangesByN (-1) >> delete
+insert [KEnter] = insertText "\n"
+insert [Keypress c _] = insertText (Y.singleton c) >> moveRangesByN 1
 insert _ = return ()
 
 -- | Listeners for keypresses when in 'Normal' mode
-normal :: Keypress -> BufAction ()
-normal (Keypress 'i' _) = setMode Insert
-normal (Keypress 'I' _) = startOfLine >> setMode Insert
-normal (Keypress 'a' _) = moveRangesByN 1 >> setMode Insert
-normal (Keypress 'A' _) = endOfLine >> setMode Insert
-normal (Keypress '0' _) = startOfLine
-normal (Keypress '$' _) = endOfLine
-normal (Keypress 'g' _) = ranges .= [Range (Coord 0 0) (Coord 0 1)]
+normal :: [Keypress] -> BufAction ()
+normal [Keypress 'i' []] = mode .= Insert
+normal [Keypress 'I' []] = startOfLine >> mode .= Insert
+normal [Keypress 'a' []] = moveRangesByN 1 >> mode .= Insert
+normal [Keypress 'A' []] = endOfLine >> mode .= Insert
+normal [Keypress '0' []] = startOfLine
+normal [Keypress '$' []] = endOfLine
+normal [Keypress 'g' []] = hist <>= [Keypress 'g' []]
+normal [Keypress 'g' [], Keypress 'g' []] = ranges .= [Range (Coord 0 0) (Coord 0 1)]
 
-normal (Keypress 'G' _) = do
-  txt <- use rope
-  ranges .= [Range ((Offset $ Y.length txt - 1)^.asCoord txt) ((Offset $ Y.length txt)^.asCoord txt)]
+normal [Keypress '+' []] = liftAction nextBuf
+normal [Keypress '-' []] = liftAction prevBuf
+normal [Keypress 'w' [Ctrl]] = liftAction hSplit
+normal [Keypress 'v' [Ctrl]] = liftAction vSplit
+normal [Keypress 'o' [Ctrl]] = liftAction closeInactive
+normal [Keypress 'r' [Ctrl]] = liftAction rotate
+normal [KLeft] = liftAction focusViewLeft
+normal [KRight] = liftAction focusViewRight
+normal [KUp] = liftAction focusViewAbove
+normal [KDown] = liftAction focusViewBelow
 
-normal (Keypress 'o' _) = endOfLine >> insertText "\n" >> moveRangesByN 1 >> setMode Insert
-normal (Keypress 'O' _) = startOfLine >> insertText "\n" >> setMode Insert
-normal (Keypress 'h' _) = moveRangesByN (-1)
-normal (Keypress 'l' _) = moveRangesByN 1
-normal (Keypress 'k' _) = moveRangesByC $ Coord (-1) 0
-normal (Keypress 'K' _) = rangeDo_ $ addRange . moveRange (Coord (-1) 0)
-normal (Keypress 'j' _) = moveRangesByC $ Coord 1 0
-normal (Keypress 'J' _) = rangeDo_ $ addRange . moveRange (Coord 1 0)
-normal (Keypress 'w' _) = findNext " " >> moveRangesByC (Coord 0 1)
-normal (Keypress 'W' _) = rangeDo_ addCursor
+normal [Keypress 'G' []] = do
+  txt <- use text
+  ranges.= [Range ((Offset $ Y.length txt - 1)^.asCoord txt) ((Offset $ Y.length txt)^.asCoord txt)]
+
+normal [Keypress 'o' []] = endOfLine >> insertText "\n" >> moveRangesByN 1 >> mode .= Insert
+normal [Keypress 'O' []] = startOfLine >> insertText "\n" >> mode .= Insert
+normal [Keypress 'h' []] = moveRangesByN (-1)
+normal [Keypress 'l' []] = moveRangesByN 1
+normal [Keypress 'k' []] = moveRangesByC $ Coord (-1) 0
+normal [Keypress 'K' []] = rangeDo_ $ addRange . moveRange (Coord (-1) 0)
+normal [Keypress 'j' []] = moveRangesByC $ Coord 1 0
+normal [Keypress 'J' []] = rangeDo_ $ addRange . moveRange (Coord 1 0)
+normal [Keypress 'w' []] = findNext " " >> moveRangesByC (Coord 0 1)
+normal [Keypress 'W' []] = rangeDo_ addCursor
   where
     addCursor (Range _ end) = do
       next <- findNextFrom " " end
@@ -109,7 +133,8 @@
           newEnd = moveCursorByN 1 newStart
       addRange $ Range newStart newEnd
 
-normal (Keypress 'B' _) = rangeDo_ addCursor
+normal [Keypress 'b' []] = moveRangesByN (-1) >> findPrev " "
+normal [Keypress 'B' []] = rangeDo_ addCursor
   where
     addCursor (Range start _) = do
       next <- findPrevFrom " " start
@@ -117,13 +142,18 @@
           newEnd = moveCursorByN 1 newStart
       addRange $ Range newStart newEnd
 
-normal (Keypress 'b' _) = moveRangesByN (-1) >> findPrev " "
-normal (Keypress 'f' _) = findNext "f"
-normal (Keypress 'F' _) = findPrev "f"
-normal (Keypress 'X' _) = moveRangesByN (-1) >> delete
-normal (Keypress 'x' _) = delete
-normal (Keypress 's' [Ctrl]) = save
-normal (Keypress ';' _) = ranges <~ use (ranges.reversed.to (take 1))
+normal [Keypress 'f' []] = hist <>= [Keypress 'f' []]
+normal [Keypress 'f' [],Keypress x []] = findNext $ Y.singleton x
+normal [Keypress 't' []] = hist <>= [Keypress 't' []]
+normal [Keypress 't' [],Keypress x []] = findNext (Y.singleton x) >> moveRangesByN (-1)
+normal [Keypress 'T' []] = hist <>= [Keypress 'T' []]
+normal [Keypress 'T' [],Keypress x []] = findPrev (Y.singleton x)
+normal [Keypress 'F' []] = hist <>= [Keypress 'F' []]
+normal [Keypress 'F' [],Keypress x []] = findPrev (Y.singleton x) >> moveRangesByN (-1)
+normal [Keypress 'X' []] = moveRangesByN (-1) >> delete
+normal [Keypress 'x' []] = delete
+normal [Keypress 's' [Ctrl]] = save
+normal [Keypress ';' []] = ranges <~ use (ranges.reversed.to (take 1))
 normal _ = return ()
 
 -- | Move cursors to end of the line
@@ -133,4 +163,3 @@
 -- | Move cursors to start of the line
 startOfLine :: BufAction ()
 startOfLine = findPrev "\n"
-
