anchor.diff:              | _ -> None, keyList
   
           let run = getCommand multiplier
  +
           let action =
  -            match keyList with
  -            | [ Movement m ] -> run Move m
  -            | [ FindChar m; c ] -> run Move (m c)
  -            | [ Action action; Movement m ] -> run action m
  -            | [ Action action; 'd' ] -> run action WholeLine
  -            | [ Action action; FindChar m; c ] -> run action (m c)
  -            | [ Action action; 'i'; BlockDelimiter c ] -> run action (InnerBlock c)
  -            | [ Action action; 'a'; BlockDelimiter c ] -> run action (ABlock c)
  -            | [ Action action ]  -> wait
  -            | [ Action action; _ ] -> wait
  -            | [ FindChar m ] -> wait
  -            | ['g'; 'd'] -> wait
  +            match state.mode, keyList with
  +            | InsertMode, [ "<esc>" ] -> run (SwitchMode NormalMode) Nothing
  +            | NormalMode, [ Movement m ] -> run Move m
  +            | NormalMode, [ FindChar m; c ] -> run Move (m c)
  +            | NormalMode, [ Action action; Movement m ] -> run action m
  +            | NormalMode, [ Action action; "d" ] -> run action WholeLine //TODO: this only applies for `dd`
  +            | NormalMode, [ Action action; FindChar m; c ] -> run action (m c)
  +            | NormalMode, [ Action action; "i"; BlockDelimiter c ] -> run action (InnerBlock c)
  +            | NormalMode, [ Action action; "a"; BlockDelimiter c ] -> run action (ABlock c)
  +            | NormalMode, [ Action action ]  -> wait
  +            | NormalMode, [ Action action; _ ] -> wait
  +            | NormalMode, [ FindChar m ] -> wait
  +            | NormalMode, [ ModeChange mode ] -> run (SwitchMode mode) Nothing
  +            | NormalMode, ["g"; "d"] -> wait
               | _ -> None
  -
  +        multiplier, action
  +
  +    let handleKeyPress (state:VimState) (keyPress:KeyDescriptor) (editorData:TextEditorData) =
  +        let newKeys =
  +            match keyPress.KeyChar with
  +            | 'q' -> []
  +            | c when keyPress.KeyChar <> '\000' -> state.keys @ [c |> string]
  +            | c when keyPress.KeyChar = '\000' ->
  +                match keyPress.SpecialKey with
  +                | SpecialKey.Escape -> 
  +                    state.keys @ ["<esc>"]
  +                | _ -> state.keys
  +            | _ -> state.keys
  +        
  +        let multiplier, action = parseKeys { state with keys=newKeys }
           match multiplier, action with
  -        | _, Some action' ->
  -            MonoDevelop.Core.LoggingService.LogDebug (sprintf "%A %A" keys action')
  -            if action'.commandType <> DoNothing then
  -                x.RunCommand action'
  -                keys.Clear()
  -            false
  -        | None, None -> base.KeyPress descriptor
  -        | _, _ -> false
  +        | _, Some action' when action'.commandType <> DoNothing->
  +            LoggingService.LogDebug (sprintf "%A %A" newKeys action')
  +            let newState = runCommand state editorData action'
  +            newState, true
  +        | None, None ->
  +            state, false
  +        | _, _ -> 
  +            state, false
  +
  +
  +    // TODO: how can I make this not mutable??
  +    let mutable vimState = { keys=[]; mode=NormalMode; desiredColumn=0; findChar=None }
  +
  +    override x.Initialize() =
  +        let editorData = x.Editor.GetContent<ITextEditorDataProvider>().GetTextEditorData()
  +        editorData.Caret.Mode <- CaretMode.Block
  +
  +    override x.KeyPress(descriptor:KeyDescriptor) =
  +        let editorData = x.Editor.GetContent<ITextEditorDataProvider>().GetTextEditorData()
  +        let state, handledKeyPress = handleKeyPress vimState descriptor editorData
  +        vimState <- state
  +        match handledKeyPress with
  +        | true -> false
  +        | false -> base.KeyPress descriptor
  
positive.code:     textObject: TextObject
  }
  
  module VimHelpers =
      let findCharForwardsOnLine (editor:TextEditorData) (line:DocumentLine) character =
          seq { editor.Caret.Offset+1 .. line.EndOffset }
          |> Seq.tryFind(fun index -> editor.Text.[index] = character)
  
      let findCharBackwardsOnLine (editor:TextEditorData) (line:DocumentLine) character =
          seq { editor.Caret.Offset-1 .. -1 .. line.Offset }
          |> Seq.tryFind(fun index -> editor.Text.[index] = character)
  
      let findCharForwards (editor:TextEditorData) character =
          seq { editor.Caret.Offset+1 .. editor.Text.Length }
          |> Seq.tryFind(fun index -> editor.Text.[index] = character)
  
      let findCharBackwards (editor:TextEditorData) character =
          seq { editor.Caret.Offset .. -1 .. 0 }
          |> Seq.tryFind(fun index -> editor.Text.[index] = character)
  
      let findCharRange (editor:TextEditorData) startChar endChar =
          findCharBackwards editor startChar, findCharForwards editor endChar
  
negative.code: 
      let (|Movement|_|) character =
          match character with
          | "h" -> Some Left
          | "j" -> Some Down
          | "k" -> Some Up
          | "l" -> Some Right
          | "$" -> Some EndOfLine
          | "^" -> Some StartOfLine
          | "0" -> Some StartOfLine
          | "_" -> Some FirstNonWhitespace
          | _ -> None
  
      let (|FindChar|_|) character =
          match character with
          | "f" -> Some ToCharInclusive
          | "F" -> Some ToCharInclusiveBackwards
          | "t" -> Some ToCharExclusive
          | "T" -> Some ToCharExclusiveBackwards
          | _ -> None
  
      let (|Action|_|) character =
          match character with
          | "d" -> Some Delete
          | "c" -> Some Change
          | "v" -> Some Visual
          | _ -> None
  
      let (|ModeChange|_|) character =
          match character with
          | "i" -> Some InsertMode
          | "v" -> Some VisualMode
          | _ -> None
  
      let getCommand (repeat: int option) commandType textObject =
          Some { repeat=(match repeat with | Some r -> r | None -> 1); commandType=commandType; textObject=textObject }
  
      let wait = getCommand (Some 1) DoNothing Nothing
  
      let parseKeys (state:VimState) =
          let keyList = state.keys// |> Seq.toList
          let multiplier, keyList =
              match keyList with
              | OneToNine d1 :: Digit d2 :: Digit d3 :: Digit d4 :: t -> Some(d1 * 1000 + d2 * 100 + d3 * 10 + d4), t
  