diff --git a/src/Yi/Keymap/Vim/Ex/Commands/Buffer.hs b/src/Yi/Keymap/Vim/Ex/Commands/Buffer.hs
--- a/src/Yi/Keymap/Vim/Ex/Commands/Buffer.hs
+++ b/src/Yi/Keymap/Vim/Ex/Commands/Buffer.hs
@@ -17,8 +17,7 @@
 import           Control.Monad.State              (gets)
 import qualified Data.Attoparsec.Text             as P (Parser, anyChar, choice,
                                                         digit, endOfInput, many', many1,
-                                                        parseOnly, space, string,
-                                                        try)
+                                                        parseOnly, space, string)
 import           Yi.Buffer.Basic                  (BufferRef (..))
 import qualified Data.Text                        as T (Text, pack, unpack)
 import           Yi.Buffer.Misc                   (bkey, isUnchangedBuffer)
diff --git a/src/Yi/Keymap/Vim/Ex/Commands/Common.hs b/src/Yi/Keymap/Vim/Ex/Commands/Common.hs
--- a/src/Yi/Keymap/Vim/Ex/Commands/Common.hs
+++ b/src/Yi/Keymap/Vim/Ex/Commands/Common.hs
@@ -109,9 +109,8 @@
 
 styleRange :: P.Parser (BufferM Region) -> P.Parser (BufferM Region)
 styleRange = fmap $ \regionB -> do
-    style <- getRegionStyle
     region <- regionB
-    convertRegionToStyleB region style
+    convertRegionToStyleB region LineWise
 
 parseFullRange :: P.Parser (BufferM Region)
 parseFullRange = P.char '%' *> return (regionOfB Document)
@@ -165,11 +164,11 @@
 -- | Parses .+-k
 parseCurrentLinePoint :: P.Parser (BufferM Point)
 parseCurrentLinePoint = do
-    void $ P.char '.'
-    relative <- P.option Nothing $ Just <$> do
-        c <- P.satisfy $ P.inClass "+-"
-        (i :: Int) <- read <$> P.many1 P.digit
-        return $ if c == '+' then i else -i
+    relative <- (Nothing <$ P.char '.' <|>) $
+      do () <$ P.char '.' <|> pure ()
+         c <- P.satisfy $ P.inClass "+-"
+         (i :: Int) <- read <$> P.many1 P.digit
+         return . Just $ if c == '+' then i else -i
     case relative of
         Nothing -> return $ pointB >>= solPointB
         Just offset -> return $ do
diff --git a/src/Yi/Keymap/Vim/Ex/Commands/Delete.hs b/src/Yi/Keymap/Vim/Ex/Commands/Delete.hs
--- a/src/Yi/Keymap/Vim/Ex/Commands/Delete.hs
+++ b/src/Yi/Keymap/Vim/Ex/Commands/Delete.hs
@@ -12,20 +12,24 @@
 
 import           Control.Applicative              (Alternative ((<|>)))
 import           Control.Monad                    (void)
+import qualified Data.Attoparsec.Text             as P (string, try, match)
+import           Data.Maybe                       (fromMaybe)
 import           Data.Text                        ()
-import qualified Data.Attoparsec.Text             as P (string, try)
+import           Data.Semigroup                   ((<>))
+import           Lens.Micro.Platform
 import           Yi.Buffer.Adjusted               hiding (Delete)
 import           Yi.Keymap                        (Action (BufferA))
 import           Yi.Keymap.Vim.Common             (EventString)
-import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common (parse, pureExCommand)
+import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common (parse, pureExCommand, parseRange)
 import           Yi.Keymap.Vim.Ex.Types           (ExCommand (cmdAction, cmdShow))
 
 parse :: EventString -> Maybe ExCommand
 parse = Common.parse $ do
+    (rangeText, rangeB) <- over _2 (fromMaybe currentLineRegionB) 
+      <$> P.match Common.parseRange
     void $ P.try ( P.string "delete") <|> P.string "d"
     return $ Common.pureExCommand {
-        cmdShow = "delete"
-      , cmdAction = BufferA $ do
-            deleteUnitB Line Forward
-            deleteN 1
+        cmdShow = rangeText <> "delete"
+      , cmdAction = BufferA $ deleteRegionB =<< rangeB
       }
+  where currentLineRegionB = flip convertRegionToStyleB LineWise =<< regionOfB Line
diff --git a/src/Yi/Keymap/Vim/Ex/Commands/Nohl.hs b/src/Yi/Keymap/Vim/Ex/Commands/Nohl.hs
--- a/src/Yi/Keymap/Vim/Ex/Commands/Nohl.hs
+++ b/src/Yi/Keymap/Vim/Ex/Commands/Nohl.hs
@@ -10,17 +10,17 @@
 
 module Yi.Keymap.Vim.Ex.Commands.Nohl (parse) where
 
-import           Data.Text                        ()
+import qualified Data.Text                        as T
 import           Yi.Keymap                        (Action (EditorA))
-import           Yi.Keymap.Vim.Common             (EventString)
+import           Yi.Keymap.Vim.Common             (EventString(..))
 import           Yi.Keymap.Vim.Ex.Commands.Common (pureExCommand)
 import           Yi.Keymap.Vim.Ex.Types           (ExCommand (cmdAction, cmdShow))
 import           Yi.Search                        (resetRegexE)
 
 parse :: EventString -> Maybe ExCommand
-parse s = if s == "nohl" || s == "nohlsearch"
-    then Just nohl
-    else Nothing
+parse (Ev s)
+  | T.isPrefixOf s "nohlsearch" && T.compareLength s 2 == GT = Just nohl
+  | otherwise                                                = Nothing
 
 nohl :: ExCommand
 nohl = pureExCommand {
diff --git a/src/Yi/Keymap/Vim/Ex/Commands/Quit.hs b/src/Yi/Keymap/Vim/Ex/Commands/Quit.hs
--- a/src/Yi/Keymap/Vim/Ex/Commands/Quit.hs
+++ b/src/Yi/Keymap/Vim/Ex/Commands/Quit.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE LambdaCase        #-}
 {-# LANGUAGE OverloadedStrings #-}
+{-# language RankNTypes #-}
 {-# LANGUAGE TupleSections     #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
@@ -15,8 +16,9 @@
 module Yi.Keymap.Vim.Ex.Commands.Quit (parse) where
 
 import           Control.Applicative              (Alternative ((<|>)))
-import           Lens.Micro.Platform              (use)
+import           Lens.Micro.Platform              (use, Getting)
 import           Control.Monad                    (void, when)
+import           Control.Monad.State.Class        (MonadState)
 import qualified Data.Attoparsec.Text             as P (char, choice, many', string, try)
 import           Data.Foldable                    (find)
 import qualified Data.List.PointedList.Circular   as PL (length)
@@ -34,8 +36,7 @@
 import           Yi.String                        (showT)
 import           Yi.Window                        (bufkey)
 
--- TODO wtf is the type of this function? It looks like it was introduced
--- in the migration to microlens
+uses :: forall a b f s. MonadState s f => Getting a s a -> (a -> b) -> f b
 uses l f = f <$> use l
 
 parse :: EventString -> Maybe ExCommand
diff --git a/src/Yi/Keymap/Vim/Ex/Commands/Registers.hs b/src/Yi/Keymap/Vim/Ex/Commands/Registers.hs
--- a/src/Yi/Keymap/Vim/Ex/Commands/Registers.hs
+++ b/src/Yi/Keymap/Vim/Ex/Commands/Registers.hs
@@ -8,7 +8,7 @@
 -- :reg[isters] ex command to list yanked texts.
 module Yi.Keymap.Vim.Ex.Commands.Registers (printRegisters, parse) where
 
-import           Control.Applicative              (Alternative ((<|>)), (<*))
+import           Control.Applicative              (Alternative ((<|>)))
 import           Control.Monad                    (void)
 import           Data.Monoid                      ((<>))
 import           Yi.Keymap                        (Action (EditorA))
@@ -48,7 +48,7 @@
 -- | See :help :registers on Vim
 parse :: EventString -> Maybe ExCommand
 parse = Common.parse $ do
-  P.string "reg" <* (     P.try (P.string "isters")
+  _ <- P.string "reg" <* (     P.try (P.string "isters")
                       <|> P.try (P.string "ister")
                       <|> P.try (P.string "iste")
                       <|> P.try (P.string "ist")
diff --git a/src/Yi/Keymap/Vim/Ex/Commands/Sort.hs b/src/Yi/Keymap/Vim/Ex/Commands/Sort.hs
--- a/src/Yi/Keymap/Vim/Ex/Commands/Sort.hs
+++ b/src/Yi/Keymap/Vim/Ex/Commands/Sort.hs
@@ -38,4 +38,4 @@
     region <- case r of
         Nothing -> regionOfB Document
         Just r' -> r'
-    sortLinesWithRegion region
+    sortLinesWithRegion region{regionEnd = regionEnd region - 1}
diff --git a/src/Yi/Keymap/Vim/Ex/Commands/Substitute.hs b/src/Yi/Keymap/Vim/Ex/Commands/Substitute.hs
--- a/src/Yi/Keymap/Vim/Ex/Commands/Substitute.hs
+++ b/src/Yi/Keymap/Vim/Ex/Commands/Substitute.hs
@@ -11,16 +11,16 @@
 
 module Yi.Keymap.Vim.Ex.Commands.Substitute (parse) where
 
-import           Control.Applicative              (Alternative ((<|>)))
+import           Control.Applicative              (Alternative)
 import           Control.Monad                    (void)
-import qualified Data.Attoparsec.Text             as P (char, inClass, many', match, option, 
-                                                        satisfy, string, try)
+import qualified Data.Attoparsec.Text             as P (char, inClass, many', match,
+                                                        satisfy, string, option,
+                                                        (<?>), Parser)
 import           Data.Maybe                       (fromMaybe)
 import           Data.Monoid                      ((<>))
 import qualified Data.Text                        as T (Text, cons, snoc)
 import           Lens.Micro.Platform              (over, _2)
 import           Yi.Buffer.Adjusted
-import           Yi.Buffer.Region                 (linesOfRegionB)
 import           Yi.Editor                        (EditorM, closeBufferAndWindowE, printMsg, withCurrentBuffer)
 import           Yi.Keymap                        (Action (EditorA), Keymap)
 import           Yi.Keymap.Keys                   (char, choice, (?>>!))
@@ -29,20 +29,26 @@
 import           Yi.Keymap.Vim.Ex.Types           (ExCommand (cmdAction, cmdShow))
 import           Yi.MiniBuffer                    (spawnMinibufferE)
 import           Yi.Regex                         (makeSearchOptsM)
-import           Yi.Region                        (Region)
 import qualified Yi.Rope                          as R (YiString, fromString, length, null, toText, toString)
 import           Yi.Search
 
+-- | Skip one or no occurrences of a given parser.
+skipOptional :: Alternative f => f a -> f ()
+skipOptional p = P.option () (() <$ p)
+{-# SPECIALIZE skipOptional :: P.Parser a -> P.Parser () #-}
+
 parse :: EventString -> Maybe ExCommand
 parse = Common.parse $ do
     (rangeText, rangeB) <- over _2 (fromMaybe $ regionOfB Line) <$> P.match Common.parseRange
-    void $ P.try (P.string "substitute") <|> P.string "s"
+    P.char 's' *> 
+      skipOptional (P.string "ub" *> skipOptional (P.string "stitute"))
+      P.<?> "substitute"
     delimiter <- P.satisfy (`elem` ("!@#$%^&*()[]{}<>/.,~';:?-=" :: String))
     from <- R.fromString <$> P.many' (P.satisfy (/= delimiter))
     void $ P.char delimiter
     to <- R.fromString <$> P.many' (P.satisfy (/= delimiter))
-    void $ P.char delimiter
-    flagChars <- P.many' (P.satisfy $ P.inClass "gic")
+    flagChars <- P.option "" $
+      P.char delimiter *> P.many' (P.satisfy $ P.inClass "gic")
     return $! substitute from to delimiter
         ('g' `elem` flagChars)
         ('i' `elem` flagChars)
@@ -61,9 +67,8 @@
               <>       (if caseInsensitive then "i" else "")
               <>       (if global then "g" else "")
   , cmdAction = EditorA $ do
-        let opts = QuoteRegex : if caseInsensitive then [IgnoreCase] else []
-        lines <- withCurrentBuffer $ regionB >>= linesOfRegionB
-        region <- withCurrentBuffer regionB
+        let opts = if caseInsensitive then [IgnoreCase] else []
+        lines' <- withCurrentBuffer $ regionB >>= linesOfRegionB
         regex <- if R.null from
                     then getRegexE
                     else return . (either (const Nothing) Just) 
@@ -71,33 +76,29 @@
         case regex of
             Nothing -> printMsg "No previous search pattern"
             Just regex' -> if confirm
-                then substituteConfirm regex' to global lines
+                then substituteConfirm regex' to global lines'
                 else withCurrentBuffer $ do
-                    -- We need to reverse the lines here so that replacing
+                    -- We need to reverse the lines' here so that replacing
                     -- does not effect the regions in question.
-                    mapM_ (void . searchAndRepRegion0 regex' to global) (reverse lines)
+                    mapM_ (void . searchAndRepRegion0 regex' to global) (reverse lines')
                     moveToSol
   }
 
 -- | Run substitution in confirm mode
 substituteConfirm :: SearchExp -> R.YiString -> Bool -> [Region] -> EditorM ()
-substituteConfirm regex to global lines = do
+substituteConfirm regex to global lines' = do
     -- TODO This highlights all matches, even in non-global mode
     -- and could potentially be classified as a bug. Fixing requires
     -- changing the regex highlighting api.
     setRegexE regex
-    regions <- withCurrentBuffer $ findMatches regex global lines
+    regions <- withCurrentBuffer $ findMatches regex global lines'
     substituteMatch to 0 False regions
 
 -- | All matches to replace under given flags
 findMatches :: SearchExp -> Bool -> [Region] -> BufferM [Region]
-findMatches regex global lines = do
+findMatches regex global lines' = do
     let f = if global then id else take 1
-    concat <$> mapM (fmap f . regexRegionB regex) lines
-
--- | Get regions corresponding to all lines
-lineRegions :: [Int] -> BufferM [Region]
-lineRegions = mapM $ \ln -> gotoLn ln >> regionOfB Line
+    concat <$> mapM (fmap f . regexRegionB regex) lines'
 
 -- | Offsets a region (to account for a region prior being modified)
 offsetRegion :: Int -> Region -> Region
diff --git a/src/Yi/Keymap/Vim/ExMap.hs b/src/Yi/Keymap/Vim/ExMap.hs
--- a/src/Yi/Keymap/Vim/ExMap.hs
+++ b/src/Yi/Keymap/Vim/ExMap.hs
@@ -16,28 +16,31 @@
 import           Data.Char                (isSpace)
 import           Data.Maybe               (fromJust)
 import           Data.Monoid              ((<>))
-import qualified Data.Text                as T (Text, drop, head, length, split, unwords)
+import qualified Data.Text                as T (Text, drop, head, length, split, unwords, map, unpack)
 import           System.FilePath          (isPathSeparator)
 import           Yi.Buffer.Adjusted       hiding (Insert)
 import           Yi.Editor
 import           Yi.History               (historyDown, historyFinish, historyPrefixSet, historyUp)
 import           Yi.Keymap                (YiM)
 import           Yi.Keymap.Vim.Common
+import           Yi.Keymap.Vim.Utils      (matchFromBool, selectBinding)
 import           Yi.Keymap.Vim.Ex
-import           Yi.Keymap.Vim.StateUtils (modifyStateE, resetCountE, switchModeE)
-import           Yi.Keymap.Vim.Utils      (matchFromBool)
+import           Yi.Keymap.Vim.StateUtils (modifyStateE, resetCountE, switchModeE, getRegisterE)
 import qualified Yi.Rope                  as R (fromText, toText)
 import           Yi.String                (commonTPrefix')
 
 defExMap :: [EventString -> Maybe ExCommand] -> [VimBinding]
-defExMap cmdParsers =
+defExMap cmdParsers = printable : specials cmdParsers
+
+specials :: [EventString -> Maybe ExCommand] -> [VimBinding]
+specials cmdParsers =
     [ exitBinding
     , completionBinding cmdParsers
     , finishBindingY cmdParsers
     , finishBindingE cmdParsers
     , failBindingE
     , historyBinding
-    , printable
+    , pasteRegisterBinding
     ]
 
 completionBinding :: [EventString -> Maybe ExCommand] -> VimBinding
@@ -140,11 +143,6 @@
                 return Drop
           f _ _ = NoMatch
 
-printable :: VimBinding
-printable = VimBindingE f
-    where f evs (VimState { vsMode = Ex }) = WholeMatch $ editAction evs
-          f _ _ = NoMatch
-
 historyBinding :: VimBinding
 historyBinding = VimBindingE f
     where f evs (VimState { vsMode = Ex }) | evs `elem` fmap fst binds
@@ -163,32 +161,65 @@
               , ("<C-n>", historyDown)
               ]
 
+-- <C-r>a pastes a content of regContent of 'a' Register to Ex buffer ('a' is forall)
+pasteRegisterBinding :: VimBinding
+pasteRegisterBinding = VimBindingE $ f . T.unpack . _unEv
+  where
+    f "<C-r>" (VimState { vsMode = Ex }) = PartialMatch
+    f ('<':'C':'-':'r':'>':regName:[]) vs@(VimState { vsMode = Ex }) =
+        WholeMatch $ pasteRegister regName vs
+    f _ _ = NoMatch
+
+    -- Paste a content to Ex buffer, and update vsOngoingInsertEvents of VimState
+    pasteRegister :: RegisterName -> VimState -> EditorM RepeatToken
+    pasteRegister registerName vs = do
+        -- Replace " to \NUL, because yi's default register is \NUL and Vim's default is "
+        let registerName' = if registerName == '"' then '\NUL' else registerName
+        mayRegisterVal <- fmap regContent <$> getRegisterE registerName'
+        case mayRegisterVal of
+            Nothing  -> return Drop
+            Just val -> do
+                withCurrentBuffer $ insertN . replaceCr $ val
+                -- putEditorDyn fixes that Ex mode never evaluate pasted command
+                -- If you remove this, tests/vimtests/ex/paste_register will failed
+                putEditorDyn vs { vsOngoingInsertEvents = Ev . R.toText $ val }
+                return Finish
+    -- Avoid putting EOL
+    replaceCr = let replacer '\n' = '\r'
+                    replacer x    = x
+                in R.fromText . T.map replacer . R.toText
+
+printable :: VimBinding
+printable = VimBindingE f
+    where f evs vs@(VimState { vsMode = Ex }) =
+            case selectBinding evs vs $ specials [] of
+                NoMatch -> WholeMatch $ editAction evs
+                _       -> NoMatch
+          f _ _ = NoMatch
+
 editAction :: EventString -> EditorM RepeatToken
 editAction (Ev evs) = do
   withCurrentBuffer $ case evs of
-      "<BS>"  -> bdeleteB
-      "<C-h>" -> bdeleteB
-      "<C-w>" -> do
-          r <- regionOfPartNonEmptyB unitViWordOnLine Backward
-          deleteRegionB r
-      "<C-r>" -> return () -- TODO
-      "<lt>" -> insertB '<'
-      "<Del>" -> deleteB Character Forward
-      "<C-d>" -> deleteB Character Forward
-      "<M-d>" -> deleteB unitWord Forward
-      "<Left>" -> moveXorSol 1
-      "<C-b>" -> moveXorSol 1
+      "<BS>"    -> bdeleteB
+      "<C-h>"   -> bdeleteB
+      "<C-w>"   -> regionOfPartNonEmptyB unitViWordOnLine Backward >>= deleteRegionB
+      "<lt>"    -> insertB '<'
+      "<Del>"   -> deleteB Character Forward
+      "<C-d>"   -> deleteB Character Forward
+      "<M-d>"   -> deleteB unitWord Forward
+      "<Left>"  -> moveXorSol 1
+      "<C-b>"   -> moveXorSol 1
       "<Right>" -> moveXorEol 1
-      "<C-f>" -> moveXorEol 1
-      "<Home>" -> moveToSol
-      "<C-a>" -> moveToSol
-      "<End>" -> moveToEol
-      "<C-e>" -> moveToEol
-      "<C-u>" -> moveToSol >> deleteToEol
-      "<C-k>" -> deleteToEol
-      evs' -> case T.length evs' of
-        1 -> insertB $ T.head evs'
-        _ -> error $ "Unhandled event " ++ show evs' ++ " in ex mode"
+      "<C-f>"   -> moveXorEol 1
+      "<Home>"  -> moveToSol
+      "<C-a>"   -> moveToSol
+      "<End>"   -> moveToEol
+      "<C-e>"   -> moveToEol
+      "<C-u>"   -> moveToSol >> deleteToEol
+      "<C-k>"   -> deleteToEol
+      _ -> case T.length evs of
+          1 -> insertB $ T.head evs
+          _ -> error $ "Unhandled event " ++ show evs ++ " in ex mode"
   command <- R.toText <$> withCurrentBuffer elemsB
   historyPrefixSet command
   modifyStateE $ \state -> state {
diff --git a/src/Yi/Keymap/Vim/Motion.hs b/src/Yi/Keymap/Vim/Motion.hs
--- a/src/Yi/Keymap/Vim/Motion.hs
+++ b/src/Yi/Keymap/Vim/Motion.hs
@@ -205,21 +205,20 @@
 matchGotoCharMove (m:[]) | m `elem` ('f' : "FtT") = PartialMatch
 matchGotoCharMove (m:"<lt>") | m `elem` ('f' : "FtT") = matchGotoCharMove (m:"<")
 matchGotoCharMove (m:c:[]) | m `elem` ('f' : "FtT") = WholeMatch $ Move style False action
-    where (dir, style, move) =
+    where (dir, style, move, offset) =
               case m of
-                  'f' -> (Forward, Inclusive, nextCInLineInc c)
-                  't' -> (Forward, Inclusive, nextCInLineExc c)
-                  'F' -> (Backward, Exclusive, prevCInLineInc c)
-                  'T' -> (Backward, Exclusive, prevCInLineExc c)
+                  'f' -> (Forward, Inclusive, nextCInLineInc c, pure ())
+                  't' -> (Forward, Inclusive, nextCInLineInc c, moveB Character Backward)
+                  'F' -> (Backward, Exclusive, prevCInLineInc c, pure ())
+                  'T' -> (Backward, Exclusive, prevCInLineInc c, moveB Character Forward)
                   _ -> error "can't happen"
           action mcount = do
                   let count = fromMaybe 1 mcount
                   p0 <- pointB
-                  replicateM_ (count - 1) $ do
-                      move
-                      moveB Character dir
+                  replicateM_ (count - 1) $ move
                   p1 <- pointB
                   move
                   p2 <- pointB
+                  offset
                   when (p1 == p2) $ moveTo p0
 matchGotoCharMove _ = NoMatch
diff --git a/src/Yi/Keymap/Vim/NormalMap.hs b/src/Yi/Keymap/Vim/NormalMap.hs
--- a/src/Yi/Keymap/Vim/NormalMap.hs
+++ b/src/Yi/Keymap/Vim/NormalMap.hs
@@ -232,15 +232,10 @@
     , ("v", enableVisualE Inclusive, resetCount . switchMode (Visual Inclusive))
     , ("V", enableVisualE LineWise, resetCount . switchMode (Visual LineWise))
     , ("<C-v>", enableVisualE Block, resetCount . switchMode (Visual Block))
-    ]
-
-nonrepeatableBindings :: [VimBinding]
-nonrepeatableBindings = fmap (mkBindingE Normal Drop)
-    [ (spec KEsc, return (), resetCount)
-    , (ctrlCh 'c', return (), resetCount)
-
+    ] ++ fmap (mkBindingE Normal Continue)
+    [
     -- Changing
-    , (char 'C',
+      (char 'C',
         do region <- withCurrentBuffer $ regionWithTwoMovesB (return ()) moveToEol
            void $ operatorApplyToRegionE opChange 1 $ StyledRegion Exclusive region
         , switchMode $ Insert 'C')
@@ -252,6 +247,13 @@
 
     -- Replacing
     , (char 'R', return (), switchMode Replace)
+    ]
+
+
+nonrepeatableBindings :: [VimBinding]
+nonrepeatableBindings = fmap (mkBindingE Normal Drop)
+    [ (spec KEsc, return (), resetCount)
+    , (ctrlCh 'c', return (), resetCount)
 
     -- Yanking
     , ( char 'Y'
diff --git a/src/Yi/Keymap/Vim/StateUtils.hs b/src/Yi/Keymap/Vim/StateUtils.hs
--- a/src/Yi/Keymap/Vim/StateUtils.hs
+++ b/src/Yi/Keymap/Vim/StateUtils.hs
@@ -91,7 +91,7 @@
 flushAccumulatorE = do
     accum <- vsAccumulator <$> getEditorDyn
     let repeatableAction = stringToRepeatableAction accum
-    modifyStateE $ \s ->
+    accum `seq` modifyStateE $ \s ->
         s { vsRepeatableAction = Just repeatableAction
           , vsAccumulator = mempty
           , vsCurrentMacroRecording = fmap (fmap (<> accum))
diff --git a/src/Yi/Keymap/Vim/VisualMap.hs b/src/Yi/Keymap/Vim/VisualMap.hs
--- a/src/Yi/Keymap/Vim/VisualMap.hs
+++ b/src/Yi/Keymap/Vim/VisualMap.hs
@@ -27,17 +27,17 @@
 import           Yi.Keymap.Vim.StyledRegion (StyledRegion (StyledRegion), transformCharactersInRegionB)
 import           Yi.Keymap.Vim.Tag          (gotoTag)
 import           Yi.Keymap.Vim.TextObject
-import           Yi.Keymap.Vim.Utils        (matchFromBool, mkChooseRegisterBinding, mkMotionBinding)
+import           Yi.Keymap.Vim.Utils        (matchFromBool, mkChooseRegisterBinding, mkMotionBinding, addNewLineIfNecessary)
 import           Yi.MiniBuffer              (spawnMinibufferE)
 import           Yi.Monad                   (whenM)
-import qualified Yi.Rope                    as R (toText)
+import qualified Yi.Rope                    as R (toText, countNewLines)
 import           Yi.Tag                     (Tag (Tag))
 import           Yi.Utils                   (SemiNum ((-~)))
 
 defVisualMap :: [VimOperator] -> [VimBinding]
 defVisualMap operators =
     [escBinding, motionBinding, textObjectBinding, changeVisualStyleBinding, setMarkBinding]
-    ++ [chooseRegisterBinding]
+    ++ [chooseRegisterBinding, pasteBinding]
     ++ operatorBindings operators ++ digitBindings ++ [replaceBinding, switchEdgeBinding]
     ++ [insertBinding, exBinding, shiftDBinding]
     ++ [tagJumpBinding]
@@ -234,6 +234,35 @@
                     return Finish
                 _ -> NoMatch
           f _ _ = NoMatch
+
+pasteBinding :: VimBinding
+pasteBinding = VimBindingE (f . T.unpack . _unEv)
+    where
+    f "p" (VimState { vsMode = (Visual style) }) = WholeMatch $ do
+        register <- getRegisterE . vsActiveRegister =<< getEditorDyn
+        case (register, style) of
+            (Just (Register _style rope), LineWise) -> withCurrentBuffer $ do
+                region <- regionOfSelectionB
+                _ <- deleteRegionWithStyleB region LineWise
+                insertRopeWithStyleB (addNewLineIfNecessary rope) LineWise
+            (Just (Register Block rope), Block) -> withCurrentBuffer $ do
+                here <- pointB
+                there <- getSelectionMarkPointB
+                (here', there') <- flipRectangleB here there
+                reg <- regionOfSelectionB
+                void $ deleteRegionWithStyleB reg Block
+                moveTo (minimum [here, there, here', there'])
+                insertRopeWithStyleB rope Block
+            (Just (Register _ rope), Block) ->
+                printMsg "Pasting non-block string into a block selection is not implemented"
+            (Just (Register _style rope), _) -> withCurrentBuffer $ do
+                region <- regionOfSelectionB
+                region' <- convertRegionToStyleB region Inclusive
+                replaceRegionB region' rope
+            _ -> pure ()
+        switchModeE Normal
+        return Finish
+    f _ _ = NoMatch
 
 switchEdgeBinding :: VimBinding
 switchEdgeBinding = VimBindingE (f . T.unpack . _unEv)
diff --git a/tests/Vim/TestExCommandParsers.hs b/tests/Vim/TestExCommandParsers.hs
--- a/tests/Vim/TestExCommandParsers.hs
+++ b/tests/Vim/TestExCommandParsers.hs
@@ -2,6 +2,7 @@
 module Vim.TestExCommandParsers (tests) where
 
 import           Control.Applicative
+import           Data.List (inits)
 import           Data.Maybe
 import           Data.Monoid
 import qualified Data.Text as T
@@ -14,6 +15,7 @@
 import qualified Yi.Keymap.Vim.Ex.Commands.BufferDelete as BufferDelete
 import qualified Yi.Keymap.Vim.Ex.Commands.Delete as Delete
 import qualified Yi.Keymap.Vim.Ex.Commands.Registers as Registers
+import qualified Yi.Keymap.Vim.Ex.Commands.Nohl as Nohl
 
 data CommandParser = CommandParser
     { cpDescription  :: String
@@ -110,6 +112,14 @@
           , "register"
           , "registers"
           ]
+          False
+          False
+          (pure "")
+
+    , CommandParser
+          "Nohl.parse"
+          (Nohl.parse . Ev . T.pack)
+          (drop 3 $ inits "nohlsearch")
           False
           False
           (pure "")
diff --git a/yi-keymap-vim.cabal b/yi-keymap-vim.cabal
--- a/yi-keymap-vim.cabal
+++ b/yi-keymap-vim.cabal
@@ -1,9 +1,9 @@
--- This file has been generated from package.yaml by hpack version 0.14.0.
+-- This file has been generated from package.yaml by hpack version 0.17.0.
 --
 -- see: https://github.com/sol/hpack
 
 name:           yi-keymap-vim
-version:        0.13.5
+version:        0.13.6
 synopsis:       Vim keymap for Yi editor
 category:       Yi
 homepage:       https://github.com/yi-editor/yi#readme
