diff --git a/example-configs/yi-vim-colemak.hs b/example-configs/yi-vim-colemak.hs
--- a/example-configs/yi-vim-colemak.hs
+++ b/example-configs/yi-vim-colemak.hs
@@ -1,6 +1,5 @@
 {-# LANGUAGE OverloadedStrings #-}
 
-import qualified Data.Text as T
 import           Yi hiding (super)
 import qualified Yi.Keymap.Vim as V2
 import qualified Yi.Keymap.Vim.Common as V2
@@ -14,11 +13,6 @@
     defaultKm = myKeymapSet,
     configCheckExternalChangesObsessively = False
 }
-
-defaultSearchKeymap :: Keymap
-defaultSearchKeymap = do
-    Event (KASCII c) [] <- anyEvent
-    write . isearchAddE $ T.singleton c
 
 myKeymapSet :: KeymapSet
 myKeymapSet = V2.mkKeymapSet $ V2.defVimConfig `override` \super this ->
diff --git a/example-configs/yi-vim.hs b/example-configs/yi-vim.hs
--- a/example-configs/yi-vim.hs
+++ b/example-configs/yi-vim.hs
@@ -1,7 +1,6 @@
 {-# LANGUAGE OverloadedStrings #-}
 
 import           Data.Monoid
-import qualified Data.Text as T
 import           Yi hiding (super)
 import qualified Yi.Keymap.Vim as V2
 import qualified Yi.Keymap.Vim.Common as V2
@@ -15,11 +14,6 @@
     defaultKm = myKeymapSet,
     configCheckExternalChangesObsessively = False
 }
-
-defaultSearchKeymap :: Keymap
-defaultSearchKeymap = do
-    Event (KASCII c) [] <- anyEvent
-    write (isearchAddE $ T.singleton c)
 
 myKeymapSet :: KeymapSet
 myKeymapSet = V2.mkKeymapSet $ V2.defVimConfig `override` \super this ->
diff --git a/src/library/Parser/Incremental.hs b/src/library/Parser/Incremental.hs
--- a/src/library/Parser/Incremental.hs
+++ b/src/library/Parser/Incremental.hs
@@ -1,4 +1,7 @@
-{-# LANGUAGE GADTs, RankNTypes, ScopedTypeVariables, TypeOperators #-}
+{-# LANGUAGE GADTs               #-}
+{-# LANGUAGE RankNTypes          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeOperators       #-}
 
 -- TODO:
 -- better interface
@@ -14,18 +17,9 @@
                            evalL'
                           ) where
 
-import Control.Applicative
-import Data.Tree
-
--- Local versions of our Control.Arrow friends (also make sure they are lazy enough)
-first :: forall t t1 t2. (t -> t2) -> (t, t1) -> (t2, t1)
-first f ~(a,b) = (f a,b)
-
-second :: forall t t1 t2. (t1 -> t2) -> (t, t1) -> (t, t2)
-second f ~(a,b) = (a,f b)
-
-(***) :: forall t t1 t2 t3. (t -> t2) -> (t1 -> t3) -> (t, t1) -> (t2, t3)
-(f *** g) ~(a,b) = (f a,g b)
+import Control.Arrow       (first, second, (***))
+import Control.Applicative (Alternative ((<|>), empty), Applicative ((<*>), pure))
+import Data.Tree           (Tree (Node))
 
 data a :< b = (:<) {top :: a, _rest :: b}
 infixr :<
diff --git a/src/library/System/CanonicalizePath.hs b/src/library/System/CanonicalizePath.hs
--- a/src/library/System/CanonicalizePath.hs
+++ b/src/library/System/CanonicalizePath.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE CPP #-}
+{-# LANGUAGE CPP               #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
@@ -16,19 +16,22 @@
   , replaceShorthands
   ) where
 
+
 #ifdef mingw32_HOST_OS
-import qualified System.Win32 as Win32
-import           System.FilePath (normalise)
+import           System.FilePath          (normalise)
+import qualified System.Win32             as Win32
 #endif
-import           Control.Applicative
-import           Control.Exc          (ignoringException)
-import           Control.Monad
-import           Data.List.Split     (splitOneOf)
-import           Data.Monoid
-import qualified Data.Text as T
-import           System.Directory    (getCurrentDirectory)
-import           System.FilePath     ((</>), isDrive, isAbsolute, takeDirectory, pathSeparator, pathSeparators)
-import           System.PosixCompat.Files  (readSymbolicLink)
+
+import           Control.Applicative      ((<$>))
+import           Control.Exc              (ignoringException)
+import           Control.Monad            (foldM)
+import           Data.List.Split          (splitOneOf)
+import           Data.Monoid              ((<>))
+import qualified Data.Text                as T (Text, empty, splitOn)
+import           System.Directory         (getCurrentDirectory)
+import           System.FilePath          (isAbsolute, isDrive, pathSeparator,
+                                           pathSeparators, takeDirectory, (</>))
+import           System.PosixCompat.Files (readSymbolicLink)
 
 -- | Removes `/./` `//` and `/../` sequences from path,
 -- doesn't follow symlinks
diff --git a/src/library/System/FriendlyPath.hs b/src/library/System/FriendlyPath.hs
--- a/src/library/System/FriendlyPath.hs
+++ b/src/library/System/FriendlyPath.hs
@@ -4,11 +4,12 @@
   , isAbsolute'
   ) where
 
-import Control.Applicative
-import System.FilePath
+import Control.Applicative     ((<$>))
+import System.CanonicalizePath (canonicalizePath)
+import System.Directory        (getHomeDirectory)
+import System.FilePath         (isAbsolute, normalise, pathSeparator)
 import System.PosixCompat.User (getUserEntryForName, homeDirectory)
-import System.CanonicalizePath
-import System.Directory hiding (canonicalizePath)
+
 
 -- canonicalizePath follows symlinks, and does not work if the directory does not exist.
 
diff --git a/src/library/Yi/Boot/Internal.hs b/src/library/Yi/Boot/Internal.hs
--- a/src/library/Yi/Boot/Internal.hs
+++ b/src/library/Yi/Boot/Internal.hs
@@ -12,11 +12,11 @@
 module Yi.Boot.Internal where
 
 import Config.Dyre.Relaunch (relaunchWithBinaryState)
-import Control.Monad.Base (liftBase)
-import Control.Monad.State (get)
-import Yi.Types (withEditor)
-import Yi.Keymap (YiM, withUI)
-import Yi.UI.Common (end)
+import Control.Monad.Base   (liftBase)
+import Control.Monad.State  (get)
+import Yi.Keymap            (YiM, withUI)
+import Yi.Types             (withEditor)
+import Yi.UI.Common         (end)
 
 -- | "reloads" the configuration
 --
diff --git a/src/library/Yi/Buffer/Adjusted.hs b/src/library/Yi/Buffer/Adjusted.hs
--- a/src/library/Yi/Buffer/Adjusted.hs
+++ b/src/library/Yi/Buffer/Adjusted.hs
@@ -23,24 +23,15 @@
     , module Yi.Buffer
     ) where
 
-import Control.Applicative
-import Control.Monad
-
-import Yi.Buffer hiding
-    ( bdeleteB
-    , insertB
-    , insertN
-    , insertNAt
-    , deleteB
-    , deleteN
-    , deleteNAt
-    , deleteRegionB
-    , deleteRegionWithStyleB
-    )
-import qualified Yi.Buffer as B
-import Yi.Misc
-import Yi.Utils
-import qualified Yi.Rope as R
+import           Control.Applicative ((<$>))
+import           Control.Monad       (forM_, when)
+import           Yi.Buffer           hiding (bdeleteB, insertB, insertN, insertNAt
+                                            , deleteB, deleteN, deleteNAt
+                                            , deleteRegionB, deleteRegionWithStyleB)
+import qualified Yi.Buffer           as B (deleteN, insertB, insertNAt)
+import           Yi.Misc             (adjBlock)
+import qualified Yi.Rope             as R (YiString, countNewLines, length, take)
+import           Yi.Utils            (SemiNum ((~-)))
 
 insertNAt :: R.YiString -> Point -> BufferM ()
 insertNAt rope point | R.countNewLines rope > 0 = B.insertNAt rope point
diff --git a/src/library/Yi/Buffer/HighLevel.hs b/src/library/Yi/Buffer/HighLevel.hs
--- a/src/library/Yi/Buffer/HighLevel.hs
+++ b/src/library/Yi/Buffer/HighLevel.hs
@@ -1,7 +1,7 @@
-{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE LambdaCase        #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
-{-# LANGUAGE MultiWayIf #-}
+{-# LANGUAGE MultiWayIf        #-}
 
 -- |
 -- Module      :  Yi.Buffer.HighLevel
@@ -17,6 +17,7 @@
     , atEol
     , atLastLine
     , atSol
+    , atSof
     , bdeleteB
     , bdeleteLineB
     , bkillWordB
@@ -64,14 +65,19 @@
     , modifyExtendedSelectionB
     , moveNonspaceOrSol
     , movePercentageFileB
+    , moveToMTB
     , moveToEol
     , moveToSol
     , moveXorEol
     , moveXorSol
+    , nextCExc
+    , nextCInc
     , nextCInLineExc
     , nextCInLineInc
     , nextNParagraphs
     , nextWordB
+    , prevCExc
+    , prevCInc
     , prevCInLineExc
     , prevCInLineInc
     , prevNParagraphs
@@ -111,37 +117,50 @@
     , upScreensB
     , vimScrollB
     , vimScrollByB
+    , markWord
     ) where
 
-import           Control.Applicative
-import           Control.Lens hiding ((-~), (+~), re, transform)
-import           Control.Lens.Cons (_last)
-import           Control.Monad
+import           Control.Applicative      (Applicative ((<*>)), (<$>))
+import           Control.Lens             (assign, over, use, (%=), (.=))
+import           Control.Lens.Cons        (_last)
+import           Control.Monad            (forM, forM_, liftM, replicateM_, unless, void, when)
 import           Control.Monad.RWS.Strict (ask)
-import           Control.Monad.State hiding (forM, forM_, sequence_)
-import           Data.Char (isDigit, isHexDigit, isOctDigit,
-                            toUpper, isUpper, toLower, isSpace)
-import           Data.List (sort, intersperse)
-import           Data.Maybe (fromMaybe, listToMaybe, catMaybes, fromJust)
-import           Data.Monoid
-import qualified Data.Text as T
-import           Data.Time (UTCTime)
-import           Data.Tuple (swap)
-import           Numeric (showOct, showHex, readOct, readHex)
-import           Yi.Buffer.Basic
+import           Control.Monad.State      (gets)
+import           Data.Char                (isDigit, isHexDigit, isOctDigit, isSpace, isUpper, toLower, toUpper)
+import           Data.List                (intersperse, sort)
+import           Data.Maybe               (catMaybes, fromMaybe, listToMaybe)
+import           Data.Monoid              (Monoid (mempty), (<>))
+import qualified Data.Text                as T (Text, toLower, toUpper, unpack)
+import           Data.Time                (UTCTime)
+import           Data.Tuple               (swap)
+import           Numeric                  (readHex, readOct, showHex, showOct)
+import           Yi.Buffer.Basic          (Direction (..), Mark, Point (..), Size (Size))
 import           Yi.Buffer.Misc
 import           Yi.Buffer.Normal
 import           Yi.Buffer.Region
-import           Yi.Config.Misc (ScrollStyle(SingleLine))
-import           Yi.Rope (YiString)
-import qualified Yi.Rope as R
-import           Yi.String
-import           Yi.Utils
-import           Yi.Window
+import           Yi.Config.Misc           (ScrollStyle (SingleLine))
+import           Yi.Rope                  (YiString)
+import qualified Yi.Rope                  as R
+import           Yi.String                (capitalizeFirst, fillText, isBlank, mapLines, onLines, overInit)
+import           Yi.Utils                 (SemiNum ((+~), (-~)))
+import           Yi.Window                (Window (actualLines, width, wkey))
 
 -- ---------------------------------------------------------------------
 -- Movement operations
 
+
+-- | Move point between the middle, top and bottom of the screen
+-- If the point stays at the middle, it'll be gone to the top
+-- else if the point stays at the top, it'll be gone to the bottom
+-- else it'll be gone to the middle
+moveToMTB :: BufferM ()
+moveToMTB = (==) <$> curLn <*> screenMidLn >>= \case
+    True -> downFromTosB 0
+    _    -> (==) <$> curLn <*> screenTopLn >>= \case
+                True -> upFromBosB 0
+                _    -> downFromTosB =<< (-) <$> screenMidLn <*> screenTopLn
+
+
 -- | Move point to start of line
 moveToSol :: BufferM ()
 moveToSol = maybeMoveB Line Backward
@@ -282,11 +301,18 @@
 -- @goUnmatchedB Forward '{' '}'@
 -- Move to the next unmatched '}'
 goUnmatchedB :: Direction -> Char -> Char -> BufferM ()
-goUnmatchedB dir cStart' cStop' = stepB >> readB >>= go (0::Int)
-  where go opened c | c == cStop && opened == 0 = return ()
-                    | c == cStop                = stepB >> readB >>= go (opened-1)
-                    | c == cStart               = stepB >> readB >>= go (opened+1)
-                    | otherwise                 = stepB >> readB >>= go opened
+goUnmatchedB dir cStart' cStop' = getLineAndCol >>= \position ->
+    stepB >> readB >>= go position (0::Int)
+    where
+        go pos opened c
+           | c == cStop && opened == 0 = return ()
+           | c == cStop       = goIfNotEofSof pos (opened-1)
+           | c == cStart      = goIfNotEofSof pos (opened+1)
+           | otherwise        = goIfNotEofSof pos  opened
+        goIfNotEofSof pos opened = atEof >>= \eof -> atSof >>= \sof ->
+            if not eof && not sof
+                then stepB >> readB >>= go pos opened
+                else gotoLn (fst pos) >> moveToColB (snd pos)
         (stepB, cStart, cStop) | dir == Forward = (rightB, cStart', cStop')
                                | otherwise      = (leftB, cStop', cStart')
 
@@ -326,13 +352,6 @@
 readLnB :: BufferM YiString
 readLnB = readUnitB Line
 
-readCharB :: BufferM (Maybe Char)
-readCharB = fmap R.head (readUnitB Character)
-
--- | Read from point to end of line
-readRestOfLnB :: BufferM YiString
-readRestOfLnB = readRegionB =<< regionOfPartB Line Forward
-
 -- | Read from point to beginning of line
 readPreviousOfLnB :: BufferM YiString
 readPreviousOfLnB = readRegionB =<< regionOfPartB Line Backward
@@ -348,14 +367,6 @@
          else do p <- pointB
                  return $ Point (fromPoint p - 1)
 
--- | Get the next point, unless at the end of the file
-nextPointB :: BufferM Point
-nextPointB = do
-  eof <- atEof
-  if eof then pointB
-         else do p <- pointB
-                 return $ Point (fromPoint p + 1)
-
 -- | Reads in word at point.
 readCurrentWordB :: BufferM YiString
 readCurrentWordB = readUnitB unitWord
@@ -394,20 +405,23 @@
   c <- curCol
   reg <- regionOfB Line
   text <- readRegionB reg
-  let r = deleteSpaces c text
+  let (r, jb) = deleteSpaces c text
   modifyRegionB (const r) reg
-  -- If we only deleted before point, move back that many characters
-  -- too or it feels weird.
-  case u of
-    Just _ -> moveToColB (c - (R.length text - R.length r))
-    Nothing -> return ()
+  -- Jump backwards to where the now-deleted spaces have started so
+  -- it's consistent and feels natural instead of leaving us somewhere
+  -- in the text.
+  moveToColB $ c - jb
   where
-    deleteSpaces :: Int -> R.YiString -> R.YiString
+    deleteSpaces :: Int -> R.YiString -> (R.YiString, Int)
     deleteSpaces c l =
       let (f, b) = R.splitAt c l
-      in R.dropWhileEnd isSpace f <> case u of
-        Nothing -> R.dropWhile isSpace b
-        Just _ -> b
+          f' = R.dropWhileEnd isSpace f
+          cleaned = f' <> case u of
+            Nothing -> R.dropWhile isSpace b
+            Just _ -> b
+      -- We only want to jump back the number of spaces before the
+      -- point, not the total number of characters we're removing.
+      in (cleaned, R.length f - R.length f')
 
 ----------------------------------------
 -- Transform operations
@@ -424,11 +438,6 @@
 capitaliseWordB :: BufferM ()
 capitaliseWordB = transformB capitalizeFirst unitWord Forward
 
--- | switch the case of the letter under the cursor
-switchCaseCharB :: BufferM ()
-switchCaseCharB =
-  transformB (R.withText $ T.map switchCaseChar) Character Forward
-
 switchCaseChar :: Char -> Char
 switchCaseChar c = if isUpper c then toLower c else toUpper c
 
@@ -436,14 +445,6 @@
 deleteToEol :: BufferM ()
 deleteToEol = deleteRegionB =<< regionOfPartB Line Forward
 
--- | Delete whole line moving to the next line
-deleteLineForward :: BufferM ()
-deleteLineForward =
-  do moveToSol   -- Move to the start of the line
-     deleteToEol -- Delete the rest of the line not including the newline char
-     deleteN 1   -- Delete the newline character
-
-
 -- | Transpose two characters, (the Emacs C-t action)
 swapB :: BufferM ()
 swapB = do eol <- atEol
@@ -545,15 +546,8 @@
 -- | Scroll by n screens (negative for up)
 scrollScreensB :: Int -> BufferM ()
 scrollScreensB n = do
-    h <- askWindow height
-    scrollB $ n * max 0 (h - 3) -- subtract some amount to get some overlap (emacs-like).
-
--- | Scroll according to function passed. The function takes the
--- | Window height in lines, its result is passed to scrollB
--- | (negative for up)
-scrollByB :: (Int -> Int) -> Int -> BufferM ()
-scrollByB f n = do h <- askWindow height
-                   scrollB $ n * f h
+    h <- askWindow actualLines
+    scrollB $ n * max 0 (h - 1) -- subtract some amount to get some overlap (emacs-like).
 
 -- | Same as scrollB, but also moves the cursor
 vimScrollB :: Int -> BufferM ()
@@ -562,14 +556,14 @@
 
 -- | Same as scrollByB, but also moves the cursor
 vimScrollByB :: (Int -> Int) -> Int -> BufferM ()
-vimScrollByB f n = do h <- askWindow height
+vimScrollByB f n = do h <- askWindow actualLines
                       vimScrollB $ n * f h
 
 -- | Move to middle line in screen
 scrollToCursorB :: BufferM ()
 scrollToCursorB = do
     MarkSet f i _ <- markLines
-    h <- askWindow height
+    h <- askWindow actualLines
     let m = f + (h `div` 2)
     scrollB $ i - m
 
@@ -680,7 +674,7 @@
   w <- ask
   f <- fromMark <$> askMarks
   moveTo =<< use (markPointA f)
-  replicateM_ (height w `div` 2) lineDown
+  replicateM_ (actualLines w `div` 2) lineDown
 
 pointInWindowB :: Point -> BufferM Bool
 pointInWindowB p = nearRegion p <$> winRegionB
@@ -718,10 +712,6 @@
   setSelectionMarkPointB $ regionStart region
   moveTo $ regionEnd region
 
--- | Extend the selection mark using the given region.
-extendSelectRegionB :: Region -> BufferM ()
-extendSelectRegionB region = (setSelectRegionB . unionRegion region) =<< getSelectRegionB
-
 ------------------------------------------
 -- Some line related movements/operations
 
@@ -774,13 +764,6 @@
 -- Some more utility functions involving
 -- regions (generally that which is selected)
 
--- | Uses a string modifying function to modify the current selection
--- Currently unsets the mark such that we have no selection, arguably
--- we could instead work out where the new positions should be
--- and move the mark and point accordingly.
-modifySelectionB :: (R.YiString -> R.YiString) -> BufferM ()
-modifySelectionB = modifyExtendedSelectionB Character
-
 modifyExtendedSelectionB :: TextUnit -> (R.YiString -> R.YiString) -> BufferM ()
 modifyExtendedSelectionB unit transform
     = modifyRegionB transform =<< unitWiseRegion unit =<< getSelectRegionB
@@ -824,34 +807,6 @@
     then unLineCommentSelectionB insPrefix delPrefix
     else linePrefixSelectionB insPrefix
 
--- | Justifies all the lines of the selection to be the same as
--- the top line.
--- NOTE: if the selection begins part way along a line, the other
--- lines will be justified only with respect to the part of the indentation
--- which is selected.
-justifySelectionWithTopB :: BufferM ()
-justifySelectionWithTopB =
-  modifySelectionB justifyLines
-  where
-
-  justifyLines :: R.YiString -> R.YiString
-  justifyLines input =
-    case R.lines input of
-      []           -> ""
-      [ one ]      -> one
-      (top : _)    -> mapLines justifyLine input
-        where
-          -- The indentation of the top line.
-          topIndent = R.takeWhile isSpace top
-
-          -- Justify a single line by removing its current indentation
-          -- and replacing it with that of the top line. Note that
-          -- this will work even if the indentation contains tab
-          -- characters.
-          justifyLine :: R.YiString -> R.YiString
-          justifyLine "" = ""
-          justifyLine l  = topIndent <> R.dropWhile isSpace l
-
 -- | Replace the contents of the buffer with some string
 replaceBufferContent :: YiString -> BufferM ()
 replaceBufferContent newvalue = do
@@ -1211,3 +1166,24 @@
                 void $ gotoLnFrom $ -1
                 moveToEol
                 lineMoveVisRelDown $ next - 1
+
+
+-- | Implements the same logic that emacs' `mark-word` does.
+-- Checks the mark point and moves it forth (or backward) for one word.
+markWord :: BufferM ()
+markWord = do
+    curPos <- pointB
+    curMark <- getSelectionMarkPointB
+    isVisible <- getVisibleSelection
+
+    savingPointB $ do
+        if not isVisible
+        then nextWordB
+        else do
+            moveTo curMark
+            if curMark < curPos
+            then prevWordB
+            else nextWordB
+
+        setVisibleSelection True
+        pointB >>= setSelectionMarkPointB
diff --git a/src/library/Yi/Buffer/Implementation.hs b/src/library/Yi/Buffer/Implementation.hs
--- a/src/library/Yi/Buffer/Implementation.hs
+++ b/src/library/Yi/Buffer/Implementation.hs
@@ -1,13 +1,12 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE CPP                       #-}
+{-# LANGUAGE DeriveDataTypeable        #-}
+{-# LANGUAGE DeriveGeneric             #-}
 {-# LANGUAGE ExistentialQuantification #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE PatternGuards #-}
-{-# LANGUAGE Rank2Types #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE FlexibleContexts          #-}
+{-# LANGUAGE FlexibleInstances         #-}
+{-# LANGUAGE PatternGuards             #-}
+{-# LANGUAGE Rank2Types                #-}
+{-# LANGUAGE TemplateHaskell           #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -65,52 +64,45 @@
   , mem
   ) where
 
-import           Control.Applicative
-import           Data.Array
-import           Data.Binary
-#if __GLASGOW_HASKELL__ < 708
-import           Data.DeriveTH
-#else
-import           GHC.Generics (Generic)
-#endif
-import           Data.Function
-import           Data.List (groupBy)
-import qualified Data.Map as M
-import           Data.Maybe
-import           Data.Monoid
-import           Yi.Rope (YiString)
-import qualified Yi.Rope as R
-import qualified Data.Set as Set
-import           Data.Typeable
-import           Yi.Buffer.Basic
-import           Yi.Regex
-import           Yi.Region
-import           Yi.Style
+import           GHC.Generics        (Generic)
+
+import           Control.Applicative (Applicative ((<*>), pure), (<$>))
+import           Data.Array          ((!))
+import           Data.Binary         (Binary (..))
+import           Data.Function       (on)
+import           Data.List           (groupBy)
+import qualified Data.Map            as M (Map, delete, empty, findMax, insert, lookup, map, maxViewWithKey)
+import           Data.Maybe          (fromMaybe)
+import           Data.Monoid         (Monoid (mconcat, mempty))
+import qualified Data.Set            as Set (Set, delete, empty, filter, insert, map, toList)
+import           Data.Typeable       (Typeable)
+import           Yi.Buffer.Basic     (Direction (..), Mark (..), WindowRef, reverseDir)
+import           Yi.Regex            (RegexLike (matchAll), SearchExp, searchRegex)
+import           Yi.Region           (Region (..), fmapRegion, mkRegion, nearRegion, regionSize)
+import           Yi.Rope             (YiString)
+import qualified Yi.Rope             as R
+import           Yi.Style            (StyleName, UIStyle (hintStyle, strongHintStyle))
 import           Yi.Syntax
-import           Yi.Utils
+import           Yi.Utils            (SemiNum ((+~), (~-)), makeLensesWithSuffix, mapAdjust')
 
-data MarkValue = MarkValue { markPoint :: !Point
+
+data MarkValue = MarkValue { markPoint   :: !Point
                            , markGravity :: !Direction}
-               deriving (Ord, Eq, Show, Typeable)
+               deriving (Ord, Eq, Show, Typeable, Generic)
 
 makeLensesWithSuffix "AA" ''MarkValue
 
-#if __GLASGOW_HASKELL__ < 708
-$(derive makeBinary ''MarkValue)
-#else
-deriving instance Generic MarkValue
 instance Binary MarkValue
-#endif
 
 type Marks = M.Map Mark MarkValue
 
 data HLState syntax = forall cache. HLState !(Highlighter cache syntax) !cache
 
 data Overlay = Overlay
-    { overlayOwner :: R.YiString
-    , _overlayBegin :: MarkValue
-    , _overlayEnd :: MarkValue
-    , _overlayStyle :: StyleName
+    { overlayOwner      :: R.YiString
+    , overlayBegin     :: MarkValue
+    , overlayEnd       :: MarkValue
+    , overlayStyle     :: StyleName
     , overlayAnnotation :: R.YiString
     }
 
@@ -128,11 +120,11 @@
             ]
 
 data BufferImpl syntax = FBufferData
-    { mem        :: !YiString -- ^ buffer text
-    , marks      :: !Marks -- ^ Marks for this buffer
-    , markNames  :: !(M.Map String Mark)
-    , hlCache    :: !(HLState syntax) -- ^ syntax highlighting state
-    , overlays   :: !(Set.Set Overlay)
+    { mem         :: !YiString -- ^ buffer text
+    , marks       :: !Marks -- ^ Marks for this buffer
+    , markNames   :: !(M.Map String Mark)
+    , hlCache     :: !(HLState syntax) -- ^ syntax highlighting state
+    , overlays    :: !(Set.Set Overlay)
     -- ^ set of (non overlapping) visual overlay regions
     , dirtyOffset :: !Point
     -- ^ Lowest modified offset since last recomputation of syntax
@@ -155,20 +147,23 @@
 -- Note that the update direction is only a hint for moving the cursor
 -- (mainly for undo purposes); the insertions and deletions are always
 -- applied Forward.
-data Update = Insert {updatePoint :: !Point, updateDirection :: !Direction, insertUpdateString :: !YiString}
-            | Delete {updatePoint :: !Point, updateDirection :: !Direction, deleteUpdateString :: !YiString}
-              -- Note that keeping the text does not cost much: we keep the updates in the undo list;
-              -- if it's a "Delete" it means we have just inserted the text in the buffer, so the update shares
-              -- the data with the buffer. If it's an "Insert" we have to keep the data any way.
-
-              deriving (Show, Typeable)
+--
+-- Note that keeping the text does not cost much: we keep the updates in the undo list;
+-- if it's a "Delete" it means we have just inserted the text in the buffer, so the update shares
+-- the data with the buffer. If it's an "Insert" we have to keep the data any way.
+data Update
+    = Insert
+    { updatePoint :: !Point
+    , updateDirection :: !Direction
+    , _insertUpdateString :: !YiString
+    }
+    | Delete
+    { updatePoint :: !Point
+    , updateDirection :: !Direction
+    , _deleteUpdateString :: !YiString
+    } deriving (Show, Typeable, Generic)
 
-#if __GLASGOW_HASKELL__ < 708
-$(derive makeBinary ''Update)
-#else
-deriving instance Generic Update
 instance Binary Update
-#endif
 
 updateIsDelete :: Update -> Bool
 updateIsDelete Delete {} = True
@@ -183,12 +178,8 @@
 
 data UIUpdate = TextUpdate !Update
               | StyleUpdate !Point !Size
-#if __GLASGOW_HASKELL__ < 708
-$(derive makeBinary ''UIUpdate)
-#else
-deriving instance Generic UIUpdate
+    deriving (Generic)
 instance Binary UIUpdate
-#endif
 
 --------------------------------------------------
 -- Low-level primitives.
diff --git a/src/library/Yi/Buffer/Indent.hs b/src/library/Yi/Buffer/Indent.hs
--- a/src/library/Yi/Buffer/Indent.hs
+++ b/src/library/Yi/Buffer/Indent.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE LambdaCase        #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
@@ -31,20 +31,20 @@
     , tabB
     ) where
 
-import           Control.Applicative
-import           Control.Monad (when)
-import           Data.Char
-import           Data.List (sort, nub)
-import           Data.Monoid
-import           Yi.Buffer.Basic
-import           Yi.Buffer.HighLevel
+import           Control.Applicative ((<$>))
+import           Control.Monad       ()
+import           Data.Char           (isSpace)
+import           Data.List           (nub, sort)
+import           Data.Monoid         ((<>))
+import           Yi.Buffer.Basic     (Direction (..))
+import           Yi.Buffer.HighLevel (firstNonSpaceB, getNextLineB, getNextNonBlankLineB, moveToSol, readLnB)
 import           Yi.Buffer.Misc
-import           Yi.Buffer.Normal
-import           Yi.Buffer.Region
-import           Yi.Buffer.TextUnit
-import           Yi.Rope (YiString)
-import qualified Yi.Rope as R
-import           Yi.String
+import           Yi.Buffer.Normal    ()
+import           Yi.Buffer.Region    (Region (regionStart), mkRegion, modifyRegionB, readRegionB)
+import           Yi.Buffer.TextUnit  (regionWithTwoMovesB)
+import           Yi.Rope             (YiString)
+import qualified Yi.Rope             as R
+import           Yi.String           (mapLines)
 
 {- |
   Return either a \t or the number of spaces specified by tabSize in the
@@ -357,12 +357,13 @@
 shiftIndentOfRegionB :: Int -> Region -> BufferM ()
 shiftIndentOfRegionB shiftCount region = do
     is <- indentSettingsB
-    let i :: R.YiString -> R.YiString
-        i = indentString is shiftCount `unless` R.null
-    modifyRegionB (mapLines i) region
+    let indentFn :: R.YiString -> R.YiString
+        indentFn line = if not (R.null line) && line /= "\n"
+            then indentString is shiftCount line
+            else line
+    modifyRegionB (mapLines indentFn) region
     moveTo $ regionStart region
     firstNonSpaceB
-  where (f `unless` c) x = if c x then x else f x
 
 -- | Return the number of spaces at the beginning of the line, up to
 -- the point.
diff --git a/src/library/Yi/Buffer/Misc.hs b/src/library/Yi/Buffer/Misc.hs
--- a/src/library/Yi/Buffer/Misc.hs
+++ b/src/library/Yi/Buffer/Misc.hs
@@ -1,18 +1,18 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE DeriveFoldable #-}
-{-# LANGUAGE DeriveFunctor #-}
-{-# LANGUAGE DeriveTraversable #-}
-{-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE CPP                        #-}
+{-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE DeriveFoldable             #-}
+{-# LANGUAGE DeriveFunctor              #-}
+{-# LANGUAGE DeriveTraversable          #-}
+{-# LANGUAGE ExistentialQuantification  #-}
+{-# LANGUAGE FlexibleContexts           #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE ImpredicativeTypes #-}
-{-# LANGUAGE LambdaCase #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE TemplateHaskell #-}
-{-# LANGUAGE TupleSections #-}
-{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE ImpredicativeTypes         #-}
+{-# LANGUAGE LambdaCase                 #-}
+{-# LANGUAGE OverloadedStrings          #-}
+{-# LANGUAGE ScopedTypeVariables        #-}
+{-# LANGUAGE StandaloneDeriving         #-}
+{-# LANGUAGE TemplateHaskell            #-}
+{-# LANGUAGE TupleSections              #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
@@ -35,6 +35,9 @@
   , runBuffer
   , runBufferFull
   , runBufferDummyWindow
+  , screenTopLn
+  , screenMidLn
+  , screenBotLn
   , curLn
   , curCol
   , colOf
@@ -53,8 +56,9 @@
   , lineUp
   , lineDown
   , newB
-  , MarkValue(..)
-  , Overlay (overlayAnnotation)
+  , MarkValue (..)
+  , Overlay
+      (overlayAnnotation, overlayBegin, overlayEnd, overlayOwner, overlayStyle)
   , mkOverlay
   , gotoLn
   , gotoLnFrom
@@ -86,6 +90,7 @@
   , modifyMarkB
   , newMarkB
   , deleteMarkB
+  , getVisibleSelection
   , setVisibleSelection
   , isUnchangedBuffer
   , setAnyMode
@@ -136,6 +141,7 @@
   , modeToggleCommentSelectionA
   , modeGetStrokesA
   , modeOnLoadA
+  , modeGotoDeclarationA
   , modeModeLineA
   , AnyMode (..)
   , IndentBehaviour (..)
@@ -166,7 +172,7 @@
   , miniIdentString
   , identA
   , directoryContentA
-  , BufferId(..)
+  , BufferId (..)
   , file
   , lastSyncTimeA
   , replaceCharB
@@ -188,39 +194,45 @@
   , encodingConverterNameA
   ) where
 
-import           Control.Applicative
-import           Control.Lens hiding ((+~), Action, reversed, at, act)
-import           Control.Monad.RWS.Strict hiding (mapM_, mapM, get, put,
-                                                  forM_, forM)
-import           Data.Binary
-import           Data.Char(ord)
-import           Data.Default
-import           Data.Foldable
-import           Data.Function hiding ((.), id)
-import qualified Data.Map as M
-import           Data.Maybe
-import qualified Data.Set as Set
-import qualified Data.Text as T
-import qualified Data.Text.Encoding as E
-import           Data.Time
-import           Data.Traversable
-import           Data.DynamicState.Serializable
-import           Numeric(showHex)
-import           Prelude hiding (foldr, mapM, notElem)
-import           System.FilePath
-import           Yi.Buffer.Basic
+import           Prelude                        hiding (foldr, mapM, notElem)
+
+import           Control.Applicative            (Applicative ((*>), (<*>), pure), (<$>))
+import           Control.Lens                   (Lens', assign, lens, use, uses, view, (%=), (%~), (.=), (^.))
+import           Control.Monad.RWS.Strict       (Endo (Endo, appEndo),
+                                                 MonadReader (ask), MonadState,
+                                                 MonadWriter (tell),
+                                                 Monoid (mconcat, mempty), asks,
+                                                 gets, join, modify,
+                                                 replicateM_, runRWS, void,
+                                                 when, (<>))
+import           Data.Binary                    (Binary (..), Get)
+import           Data.Char                      (ord)
+import           Data.Default                   (Default (def))
+import           Data.DynamicState.Serializable (getDyn, putDyn)
+import           Data.Foldable                  (Foldable (foldr), forM_, notElem)
+import qualified Data.Map                       as M (Map, empty, insert, lookup)
+import           Data.Maybe                     (fromMaybe, isNothing)
+import qualified Data.Set                       as Set (Set)
+import qualified Data.Text                      as T (Text, concat, justifyRight, pack, snoc, unpack)
+import qualified Data.Text.Encoding             as E (decodeUtf8, encodeUtf8)
+import           Data.Time                      (UTCTime (UTCTime))
+import           Data.Traversable               (Traversable (mapM), forM)
+import           Numeric                        (showHex)
+import           System.FilePath                (joinPath, splitPath)
+import           Yi.Buffer.Basic                (BufferRef, Point (..), Size (Size), WindowRef)
 import           Yi.Buffer.Implementation
 import           Yi.Buffer.Undo
-import           Yi.Interact as I
-import           Yi.Monad
-import           Yi.Region
-import           Yi.Rope (YiString)
-import qualified Yi.Rope as R
-import           Yi.Syntax
+import           Yi.Interact                    as I (P (End))
+import           Yi.Monad                       (getsAndModify)
+import           Yi.Region                      (Region, mkRegion)
+import           Yi.Rope                        (YiString)
+import qualified Yi.Rope                        as R
+import           Yi.Syntax                      (ExtHL (ExtHL), Stroke, noHighlighter)
 import           Yi.Types
-import           Yi.Utils
-import           Yi.Window
+import           Yi.Utils                       (SemiNum ((+~)), makeClassyWithSuffix, makeLensesWithSuffix)
+import           Yi.Window                      (Window (width, wkey, actualLines), dummyWindow)
 
+
 -- In addition to Buffer's text, this manages (among others):
 --  * Log of updates mades
 --  * Undo
@@ -727,6 +739,29 @@
     p <- pointB
     queryBuffer (lineAt p)
 
+
+-- | Top line of the screen
+screenTopLn :: BufferM Int
+screenTopLn = do
+    p <- use . markPointA =<< fromMark <$> askMarks
+    queryBuffer (lineAt p)
+
+
+-- | Middle line of the screen
+screenMidLn :: BufferM Int
+screenMidLn = (+) <$> screenTopLn <*> (div <$> screenLines <*> pure 2)
+
+
+-- | Bottom line of the screen
+screenBotLn :: BufferM Int
+screenBotLn = (+) <$> screenTopLn <*> screenLines
+
+
+-- | Amount of lines in the screen
+screenLines :: BufferM Int
+screenLines = pred <$> askWindow actualLines
+
+
 -- | Return line numbers of marks
 markLines :: BufferM (MarkSet Int)
 markLines = mapM getLn =<< askMarks
@@ -823,6 +858,10 @@
 -- | Highlight the selection
 setVisibleSelection :: Bool -> BufferM ()
 setVisibleSelection = assign highlightSelectionA
+
+-- | Whether the selection is highlighted
+getVisibleSelection :: BufferM Bool
+getVisibleSelection = use highlightSelectionA
 
 getInsMark :: BufferM Mark
 getInsMark = insMark <$> askMarks
diff --git a/src/library/Yi/Buffer/Normal.hs b/src/library/Yi/Buffer/Normal.hs
--- a/src/library/Yi/Buffer/Normal.hs
+++ b/src/library/Yi/Buffer/Normal.hs
@@ -6,48 +6,67 @@
 --  * the textual units they work on
 --  * the direction towards which they operate (if applicable)
 
-module Yi.Buffer.Normal (TextUnit(Character, Line, VLine, Document, GenUnit),
-                         outsideUnit,
-                         leftBoundaryUnit,
-                         unitWord,
-                         unitViWord,
-                         unitViWORD,
-                         unitViWordAnyBnd,
-                         unitViWORDAnyBnd,
-                         unitViWordOnLine,
-                         unitViWORDOnLine,
-                         unitDelimited,
-                         unitSentence, unitEmacsParagraph, unitParagraph,
-                         isAnySep, unitSep, unitSepThisLine, isWordChar,
+module Yi.Buffer.Normal ( TextUnit(Character, Line, VLine, Document, GenUnit)
+                        , isAnySep
+                        , isWordChar
+                        , leftBoundaryUnit
+                        , outsideUnit
+                        , unitDelimited
+                        , unitEmacsParagraph
+                        , unitParagraph
+                        , unitSentence
+                        , unitSep
+                        , unitSepThisLine
+                        , unitViWORD
+                        , unitViWORDAnyBnd
+                        , unitViWORDOnLine
+                        , unitViWord
+                        , unitViWordAnyBnd
+                        , unitViWordOnLine
+                        , unitWord
                          -- TextUnit is exported abstract intentionally:
                          -- we'd like to move more units to the GenUnit format.
-                         moveB, maybeMoveB,
-                         transformB, transposeB,
-                         regionOfB, regionOfNonEmptyB, regionOfPartB,
-                         regionOfPartNonEmptyB, regionOfPartNonEmptyAtB,
-                         readPrevUnitB, readUnitB,
-                         untilB, doUntilB_, untilB_, whileB, doIfCharB,
-                         atBoundaryB,
-                         numberOfB,
-                         deleteB, genMaybeMoveB,
-                         genMoveB, BoundarySide(..), genAtBoundaryB,
-                         genEnclosingUnit, genUnitBoundary,
-                         checkPeekB
-                         , RegionStyle(..)
-                         , mkRegionOfStyleB
-                         , convertRegionToStyleB
-                         , unitWiseRegion
-                         , extendRegionToBoundaries
-                         , getRegionStyle
-                         , putRegionStyle
-                         ) where
+                        , atBoundaryB
+                        , deleteB
+                        , doIfCharB
+                        , doUntilB_
+                        , genMaybeMoveB
+                        , genMoveB
+                        , maybeMoveB
+                        , moveB
+                        , numberOfB
+                        , readPrevUnitB
+                        , readUnitB
+                        , regionOfB
+                        , regionOfNonEmptyB
+                        , regionOfPartB
+                        , regionOfPartNonEmptyAtB
+                        , regionOfPartNonEmptyB
+                        , transformB
+                        , transposeB
+                        , untilB
+                        , untilB_
+                        , whileB
+                        , BoundarySide(..)
+                        , checkPeekB
+                        , genAtBoundaryB
+                        , genEnclosingUnit
+                        , genUnitBoundary
+                        , RegionStyle(..)
+                        , convertRegionToStyleB
+                        , extendRegionToBoundaries
+                        , getRegionStyle
+                        , mkRegionOfStyleB
+                        , putRegionStyle
+                        , unitWiseRegion
+                        ) where
 
-import Data.List (sort)
-import Yi.Buffer.Basic
-import Yi.Buffer.Misc
-import Yi.Buffer.Region
-import Yi.Buffer.TextUnit
-import Yi.Types (RegionStyle(..))
+import           Data.List          (sort)
+import           Yi.Buffer.Basic    (Direction (Backward, Forward), Point)
+import           Yi.Buffer.Misc     (BufferM, getBufferDyn, moveTo, pointB, putBufferDyn, savingPointB)
+import           Yi.Buffer.Region   (Region (..), inclusiveRegionB, mkRegion, mkRegion')
+import           Yi.Buffer.TextUnit
+import           Yi.Types           (RegionStyle (..))
 
 getRegionStyle :: BufferM RegionStyle
 getRegionStyle = getBufferDyn
diff --git a/src/library/Yi/Buffer/Region.hs b/src/library/Yi/Buffer/Region.hs
--- a/src/library/Yi/Buffer/Region.hs
+++ b/src/library/Yi/Buffer/Region.hs
@@ -11,8 +11,7 @@
 -- This module defines buffer operation on regions
 
 module Yi.Buffer.Region
-  (
-   module Yi.Region
+  ( module Yi.Region
   , swapRegionsB
   , deleteRegionB
   , replaceRegionB
@@ -24,21 +23,22 @@
   , blockifyRegion
   , joinLinesB
   , concatLinesB
-  )
-where
+  ) where
 
-import           Control.Applicative
-import           Control.Monad
-import           Data.Char (isSpace)
-import           Data.Monoid (mconcat)
-import           Data.List (sort)
+import           Control.Applicative (Applicative ((<*>), pure), (<$>))
+import           Control.Monad       (when)
+import           Data.Char           (isSpace)
+import           Data.List           (sort)
+import           Data.Monoid         (mconcat)
 import           Yi.Buffer.Misc
 import           Yi.Region
-import           Yi.Rope (YiString)
-import qualified Yi.Rope as R
-import           Yi.String (overInit)
-import           Yi.Utils
-import           Yi.Window (winRegion)
+import           Yi.Rope             (YiString)
+import qualified Yi.Rope             as R (YiString, cons, dropWhile, filter, lines, map, null)
+import           Yi.String           (overInit)
+import           Yi.Utils            (SemiNum ((~-)))
+import           Yi.Window           (winRegion)
+
+
 
 winRegionB :: BufferM Region
 winRegionB = askWindow winRegion
diff --git a/src/library/Yi/Buffer/TextUnit.hs b/src/library/Yi/Buffer/TextUnit.hs
--- a/src/library/Yi/Buffer/TextUnit.hs
+++ b/src/library/Yi/Buffer/TextUnit.hs
@@ -41,23 +41,27 @@
     , deleteUnitB
     ) where
 
-import           Control.Applicative
-import           Control.Monad
-import           Data.Char
-import           Data.Typeable
-import           Yi.Buffer.Basic
+
+import           Control.Applicative (Applicative ((<*>)), (<$>))
+import           Control.Monad       (void, when, (<=<))
+import           Data.Char           (GeneralCategory (LineSeparator, ParagraphSeparator, Space),
+                                      generalCategory, isAlphaNum, isSeparator, isSpace)
+import           Data.Typeable       (Typeable)
+import           Yi.Buffer.Basic     (Direction (..), Point (Point), mayReverse, reverseDir)
 import           Yi.Buffer.Misc
 import           Yi.Buffer.Region
-import           Yi.Rope (YiString)
-import qualified Yi.Rope as R
+import           Yi.Rope             (YiString)
+import qualified Yi.Rope             as R (head, reverse, tail, toString)
 
+
+
 -- | Designate a given "unit" of text.
 data TextUnit = Character -- ^ a single character
               | Line  -- ^ a line of text (between newlines)
               | VLine -- ^ a "vertical" line of text (area of text between two characters at the same column number)
               | Document -- ^ the whole document
               | GenUnit {genEnclosingUnit :: TextUnit,
-                         genUnitBoundary :: Direction -> BufferM Bool}
+                         genUnitBoundary  :: Direction -> BufferM Bool}
       -- there could be more text units, like Page, Searched, etc. it's probably a good
       -- idea to use GenUnit though.
                 deriving Typeable
diff --git a/src/library/Yi/Buffer/Undo.hs b/src/library/Yi/Buffer/Undo.hs
--- a/src/library/Yi/Buffer/Undo.hs
+++ b/src/library/Yi/Buffer/Undo.hs
@@ -1,4 +1,6 @@
-{-# LANGUAGE TemplateHaskell, CPP, StandaloneDeriving, DeriveGeneric #-}
+{-# LANGUAGE CPP                #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE TemplateHaskell    #-}
 
 -- | An implementation of restricted, linear undo, as described in:
 --
@@ -53,36 +55,24 @@
   , Change(AtomicChange, InteractivePoint)
    ) where
 
-import Data.Binary
-#if __GLASGOW_HASKELL__ < 708
-import Data.DeriveTH
-#else
-import GHC.Generics (Generic)
-#endif
-import Yi.Buffer.Implementation
+import           GHC.Generics             (Generic)
 
+import           Data.Binary              (Binary (..))
+import           Yi.Buffer.Implementation
+
 data Change = SavedFilePoint
             | InteractivePoint
             | AtomicChange !Update
 -- !!! It's very important that the updates are forced, otherwise
 -- !!! we'll keep a full copy of the buffer state for each update
 -- !!! (thunk) put in the URList.
-            deriving (Show)
-#if __GLASGOW_HASKELL__ < 708
-$(derive makeBinary ''Change)
-#else
-deriving instance Generic Change
+            deriving (Show, Generic)
 instance Binary Change
-#endif
+
 -- | A URList consists of an undo and a redo list.
 data URList = URList ![Change] ![Change]
-            deriving (Show)
-#if __GLASGOW_HASKELL__ < 708
-$(derive makeBinary ''URList)
-#else
-deriving instance Generic URList
+            deriving (Show, Generic)
 instance Binary URList
-#endif
 
 -- | A new empty 'URList'.
 -- Notice we must have a saved file point as this is when we assume we are
diff --git a/src/library/Yi/Char/Unicode.hs b/src/library/Yi/Char/Unicode.hs
--- a/src/library/Yi/Char/Unicode.hs
+++ b/src/library/Yi/Char/Unicode.hs
@@ -1,7 +1,8 @@
 module Yi.Char.Unicode (greek, symbols, subscripts, superscripts, checkAmbs, disamb) where
 
-import Data.List (isPrefixOf)
-import Control.Applicative
+import Control.Applicative (Applicative (pure))
+import Data.List           (isPrefixOf)
+
 {-# ANN module "HLint: ignore Use string literal" #-}
 
 greek :: [(String, String)]
diff --git a/src/library/Yi/Command.hs b/src/library/Yi/Command.hs
--- a/src/library/Yi/Command.hs
+++ b/src/library/Yi/Command.hs
@@ -1,7 +1,7 @@
-{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveDataTypeable         #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE OverloadedStrings          #-}
+{-# LANGUAGE TypeOperators              #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -15,29 +15,30 @@
 
 module Yi.Command where
 
-import           Control.Applicative
-import           Control.Exception(SomeException)
-import           Control.Lens
-import           Control.Monad
-import           Control.Monad.Base
-import           Data.Binary
-import           Data.Default
-import qualified Data.Text as T
-import           Data.Typeable
-import           System.Exit (ExitCode(..))
-import           Yi.Buffer
-import           Yi.Core (startSubprocess)
-import           Yi.Types (YiVariable)
+import           Control.Applicative ((<$>))
+import           Control.Exception   (SomeException)
+import           Control.Lens        (assign)
+import           Control.Monad       (void)
+import           Control.Monad.Base  (liftBase)
+import           Data.Binary         (Binary)
+import           Data.Default        (Default)
+import qualified Data.Text           as T (Text, init, last, pack, unpack)
+import           Data.Typeable       (Typeable)
+import           System.Exit         (ExitCode (..))
+import           Yi.Buffer           (BufferId (MemBuffer), BufferRef, identA, setMode)
+import           Yi.Core             (startSubprocess)
 import           Yi.Editor
-import           Yi.Keymap
+import           Yi.Keymap           (YiM, withUI)
 import           Yi.MiniBuffer
-import qualified Yi.Mode.Compilation as Compilation
-import qualified Yi.Mode.Interactive as Interactive
-import           Yi.Monad
-import           Yi.Process
-import qualified Yi.Rope as R
-import           Yi.UI.Common
-import           Yi.Utils
+import qualified Yi.Mode.Compilation as Compilation (mode)
+import qualified Yi.Mode.Interactive as Interactive (spawnProcess)
+import           Yi.Monad            (maybeM)
+import           Yi.Process          (runShellCommand, shellFileName)
+import qualified Yi.Rope             as R (fromString)
+import           Yi.Types            (YiVariable)
+import           Yi.UI.Common        (reloadProject)
+import           Yi.Utils            (io)
+
 
 ---------------------------
 -- | Changing the buffer name quite useful if you have
diff --git a/src/library/Yi/Command/Help.hs b/src/library/Yi/Command/Help.hs
--- a/src/library/Yi/Command/Help.hs
+++ b/src/library/Yi/Command/Help.hs
@@ -1,5 +1,5 @@
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE OverloadedStrings          #-}
 -- |
 -- Module      :  Yi.Command.Help
@@ -21,19 +21,20 @@
 
 module Yi.Command.Help(displayHelpFor) where
 
-import           Control.Applicative
-import           Data.Binary
-import           Data.Default
-import           Data.Typeable
-import           Yi.Buffer
+import           Control.Applicative ((<$>))
+import           Data.Binary         (Binary)
+import           Data.Default        (Default)
+import qualified Data.Text           as T (Text, pack, unlines, unpack)
+import           Data.Typeable       (Typeable)
+import           Yi.Buffer           (BufferId (MemBuffer), BufferRef)
 import           Yi.Editor
-import           Yi.Monad
-import qualified Yi.Rope as R
-import qualified Data.Text as T
-import           Yi.Eval (getAllNamesInScope, describeNamedAction)
-import           Yi.Keymap
-import           Yi.Types(YiVariable)
+import           Yi.Eval             (describeNamedAction, getAllNamesInScope)
+import           Yi.Keymap           (YiM)
+import           Yi.Monad            (maybeM)
+import qualified Yi.Rope             as R (fromText)
+import           Yi.Types            (YiVariable)
 
+
 -- | Displays help for a given name, or help index, if no name is given
 displayHelpFor :: T.Text -> YiM ()
 displayHelpFor name = helpFor name >>= displayHelpBuffer
@@ -41,7 +42,7 @@
 -- | Finds help text to display, given a command argument
 helpFor :: T.Text -> YiM T.Text
 helpFor ""    = (T.unlines . map T.pack) <$> getAllNamesInScope
-helpFor name  = T.pack    <$> describeNamedAction (T.unpack name)          
+helpFor name  = T.pack    <$> describeNamedAction (T.unpack name)
 
 -- * To make help buffer unique:
 -- | Dynamic YiVariable to store the help buffer reference.
diff --git a/src/library/Yi/Completion.hs b/src/library/Yi/Completion.hs
--- a/src/library/Yi/Completion.hs
+++ b/src/library/Yi/Completion.hs
@@ -21,15 +21,16 @@
   )
 where
 
-import           Control.Applicative
-import           Data.List
-import           Data.Maybe
-import           Data.Monoid
-import           Data.Function (on)
-import qualified Data.Text as T
-import           Yi.Editor (EditorM, printMsg, printMsgs)
-import           Yi.String (commonTPrefix', showT)
-import           Yi.Utils
+import           Control.Applicative ((<$>))
+import           Data.Function       (on)
+import           Data.List           (find, nub)
+import           Data.Maybe          (catMaybes)
+import           Data.Monoid         ((<>))
+import qualified Data.Text           as T (Text, breakOn, isPrefixOf, length, null, tails, toCaseFold)
+import           Yi.Editor           (EditorM, printMsg, printMsgs)
+import           Yi.String           (commonTPrefix', showT)
+import           Yi.Utils            (commonPrefix)
+
 
 -------------------------------------------
 -- General completion
diff --git a/src/library/Yi/Config.hs b/src/library/Yi/Config.hs
--- a/src/library/Yi/Config.hs
+++ b/src/library/Yi/Config.hs
@@ -15,11 +15,11 @@
                  , configStyle, configFundamentalMode, configTopLevelKeymap
                  ) where
 
-import Data.Prototype
-import Yi.Style
-import Yi.Types (Config(..), UIConfig(..), UIBoot, CursorStyle(..),
-                 Keymap, extractTopKeymap, AnyMode)
+import Data.Prototype (extractValue)
 import Yi.Config.Lens
+import Yi.Style       (UIStyle)
+import Yi.Types       (AnyMode, Config (..), CursorStyle (..), Keymap,
+                       UIBoot, UIConfig (..), extractTopKeymap)
 
 configStyle :: UIConfig -> UIStyle
 configStyle = extractValue . configTheme
diff --git a/src/library/Yi/Config/Default.hs b/src/library/Yi/Config/Default.hs
--- a/src/library/Yi/Config/Default.hs
+++ b/src/library/Yi/Config/Default.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE CPP #-}
+{-# LANGUAGE CPP               #-}
 {-# LANGUAGE OverloadedStrings #-}
 
 module Yi.Config.Default ( defaultConfig, availableFrontends, defaultEmacsConfig
@@ -6,43 +6,46 @@
                          , toEmacsStyleConfig, toCuaStyleConfig) where
 
 import           Control.Applicative
-import           Control.Lens hiding (Action)
+import           Control.Lens        ((.~), (^.), use)
 import           Control.Monad
 import           Data.Default
 import qualified Data.HashMap.Strict as HM
-import qualified Data.Map as M
+import qualified Data.Map            as M
 import           Data.Monoid
 import           Paths_yi
 import           System.FilePath
 
 import           Yi.Buffer
-import           Yi.Command (cabalBuildE, cabalConfigureE, grepFind, makeBuild,
-                             reloadProjectE, searchSources, shell)
+import           Yi.Command          (cabalBuildE, cabalConfigureE, grepFind,
+                                      makeBuild, reloadProjectE, searchSources,
+                                      shell)
 import           Yi.Config
 import           Yi.Config.Misc
-import           Yi.Core (errorEditor, quitEditor)
+import           Yi.Core             (errorEditor, quitEditor)
 import           Yi.Editor
-import           Yi.Eval(publishedActions)
+import           Yi.Eval             (publishedActions)
 import           Yi.File
-import           Yi.IReader (saveAsNewArticle)
-import qualified Yi.Interact as I
+import qualified Yi.Interact         as I
+import           Yi.IReader          (saveAsNewArticle)
 import           Yi.Keymap
-import qualified Yi.Keymap.Cua  as Cua
-import qualified Yi.Keymap.Emacs  as Emacs
+import qualified Yi.Keymap.Cua       as Cua
+import qualified Yi.Keymap.Emacs     as Emacs
 import           Yi.Keymap.Keys
-import qualified Yi.Keymap.Vim  as Vim
+import qualified Yi.Keymap.Vim       as Vim
 import           Yi.Layout
-import qualified Yi.Mode.Abella as Abella
-import qualified Yi.Mode.Haskell as Haskell
-import           Yi.Mode.IReader (ireaderMode, ireadMode)
-import qualified Yi.Mode.JavaScript as JS
-import qualified Yi.Mode.Latex as Latex
+import qualified Yi.Mode.Abella      as Abella
+import qualified Yi.Mode.Haskell     as Haskell
+import           Yi.Mode.IReader     (ireadMode, ireaderMode)
+import qualified Yi.Mode.JavaScript  as JS
+import qualified Yi.Mode.Latex       as Latex
 import           Yi.Modes
-import qualified Yi.Rope as R
+import qualified Yi.Rope             as R
 import           Yi.Search
 import           Yi.Style.Library
 import qualified Yi.UI.Batch
 import           Yi.Utils
+
+import           Yi.Types            ()
 
 #ifdef FRONTEND_VTY
 import qualified Graphics.Vty.Config as Vty
diff --git a/src/library/Yi/Config/Lens.hs b/src/library/Yi/Config/Lens.hs
--- a/src/library/Yi/Config/Lens.hs
+++ b/src/library/Yi/Config/Lens.hs
@@ -13,11 +13,11 @@
 
 module Yi.Config.Lens where
 
-import Yi.Types (Config(..), UIConfig(..), YiConfigVariable)
-import Yi.Utils (makeLensesWithSuffix)
-import Control.Lens
+import Control.Lens      (Lens)
+import Data.Default      (Default (def))
 import Data.DynamicState (_dyn)
-import Data.Default
+import Yi.Types          (Config (..), UIConfig (..), YiConfigVariable)
+import Yi.Utils          (makeLensesWithSuffix)
 
 makeLensesWithSuffix "A" ''Config
 makeLensesWithSuffix "A" ''UIConfig
diff --git a/src/library/Yi/Config/Simple.hs b/src/library/Yi/Config/Simple.hs
--- a/src/library/Yi/Config/Simple.hs
+++ b/src/library/Yi/Config/Simple.hs
@@ -60,7 +60,9 @@
   modifyModeByName,
   -- * Evaluation of commands
   evaluator,
+#ifdef HINT
   ghciEvaluator,
+#endif
   publishedActionsEvaluator,
   publishAction,
   publishedActions,
@@ -119,7 +121,7 @@
  ) where
 
 import           Control.Applicative
-import           Control.Lens hiding (Action)
+import           Control.Lens (Lens', (.=), (%=), (%~), use, lens)
 import           Control.Monad.State hiding (modify, get)
 import           Data.Maybe(mapMaybe)
 import qualified Data.Text as T
diff --git a/src/library/Yi/Config/Simple/Types.hs b/src/library/Yi/Config/Simple/Types.hs
--- a/src/library/Yi/Config/Simple/Types.hs
+++ b/src/library/Yi/Config/Simple/Types.hs
@@ -1,16 +1,16 @@
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE Rank2Types #-}
+{-# LANGUAGE Rank2Types                 #-}
 
 -- | exports from "Yi.Config.Simple" which are useful to \"core yi\" rather than just config files.
 module Yi.Config.Simple.Types
  where
 
-import Control.Monad.State hiding (modify, get)
-import Control.Monad.Base
-import Control.Applicative
-import Control.Lens
-import Yi.Config
-import Yi.Types
+import Control.Applicative (Applicative)
+import Control.Lens        (Lens')
+import Control.Monad.Base  (MonadBase)
+import Control.Monad.State (MonadState, StateT)
+import Yi.Config           (Config, configVariable)
+import Yi.Types            (YiConfigVariable)
 
 -- | The configuration monad. Run it with 'configMain'.
 newtype ConfigM a = ConfigM {
diff --git a/src/library/Yi/Core.hs b/src/library/Yi/Core.hs
--- a/src/library/Yi/Core.hs
+++ b/src/library/Yi/Core.hs
@@ -1,7 +1,7 @@
-{-# LANGUAGE LambdaCase #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE Rank2Types #-}
-{-# LANGUAGE RecursiveDo #-}
+{-# LANGUAGE LambdaCase          #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE Rank2Types          #-}
+{-# LANGUAGE RecursiveDo         #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
@@ -44,53 +44,59 @@
   , forkAction
   ) where
 
-import           Control.Applicative
-import           Control.Concurrent
-import           Control.Exc
-import           Control.Exception
-import           Control.Lens hiding (Action,act,acts)
-import           Control.Monad hiding (mapM_,forM_,forM)
-import           Control.Monad.Base
-import           Control.Monad.Error ()
-import           Control.Monad.Reader hiding (mapM_,forM_,forM)
-import qualified Data.DelayList as DelayList
-import           Data.Foldable
-import           Data.List (partition)
-import           Data.List.NonEmpty (NonEmpty(..))
-import qualified Data.List.PointedList.Circular as PL
-import           Data.List.Split (splitOn)
-import qualified Data.Map as M
-import           Data.Maybe
-import           Data.Monoid
-import qualified Data.Text as T
-import           Data.Time
-import           Data.Time.Clock.POSIX
-import           Data.Traversable
-import           GHC.Conc (labelThread)
-import           Prelude hiding (elem,or,mapM_)
-import           System.Directory (doesFileExist)
-import           System.Exit
-import           System.IO (Handle, hWaitForInput, hPutStr)
-import           System.PosixCompat.Files
-import           System.Process (terminateProcess, getProcessExitCode,
-                                 ProcessHandle, readProcessWithExitCode)
+import           Prelude                        hiding (elem, mapM_, or)
+
+import           Control.Applicative            (Applicative (pure), (<$>))
+import           Control.Concurrent             (ThreadId, forkIO, forkOS,
+                                                 modifyMVar, modifyMVar_,
+                                                 newMVar, readMVar, threadDelay)
+import           Control.Exc                    (ignoringException)
+import           Control.Exception              (SomeException, handle)
+import           Control.Lens                   (assign, mapped, use, uses,
+                                                 view, (%=), (%~), (&), (.=),
+                                                 (.~), (^.))
+import           Control.Monad                  (forever, void, when)
+import           Control.Monad.Base             (MonadBase (liftBase))
+import           Control.Monad.Error            ()
+import           Control.Monad.Reader           (MonadReader (ask), ReaderT (runReaderT), asks)
+import qualified Data.DelayList                 as DelayList (decrease, insert)
+import           Data.Foldable                  (Foldable (foldMap), elem, find, forM_, mapM_, or, toList)
+import           Data.List                      (partition)
+import           Data.List.NonEmpty             (NonEmpty (..))
+import qualified Data.List.PointedList.Circular as PL (PointedList (_focus), length)
+import           Data.List.Split                (splitOn)
+import qualified Data.Map                       as M (assocs, delete, empty, fromList, insert, member)
+import           Data.Maybe                     (fromMaybe, isNothing)
+import           Data.Monoid                    (First (First, getFirst), (<>))
+import qualified Data.Text                      as T (Text, pack, unwords)
+import           Data.Time                      (getCurrentTime)
+import           Data.Time.Clock.POSIX          (posixSecondsToUTCTime)
+import           Data.Traversable               (forM)
+import           GHC.Conc                       (labelThread)
+import           System.Directory               (doesFileExist)
+import           System.Exit                    (ExitCode)
+import           System.IO                      (Handle, hPutStr, hWaitForInput)
+import           System.PosixCompat.Files       (getFileStatus, modificationTime)
+import           System.Process                 (ProcessHandle,
+                                                 getProcessExitCode,
+                                                 readProcessWithExitCode,
+                                                 terminateProcess)
 import           Yi.Buffer
 import           Yi.Config
-import           Yi.Debug
+import           Yi.Debug                       (logPutStrLn)
 import           Yi.Editor
 import           Yi.Keymap
 import           Yi.Keymap.Keys
-import           Yi.KillRing (krEndCmd)
-import           Yi.Monad
-import           Yi.Process (createSubprocess, readAvailable,
-                             SubprocessId, SubprocessInfo(..))
-import qualified Yi.Rope as R
-import           Yi.String
-import           Yi.Style (errorStyle, strongHintStyle)
-import qualified Yi.UI.Common as UI
-import           Yi.Utils
-import           Yi.Window (dummyWindow, bufkey, wkey, winRegion, isMini)
-import           Yi.PersistentState (loadPersistentState, savePersistentState)
+import           Yi.KillRing                    (krEndCmd)
+import           Yi.Monad                       (gets)
+import           Yi.PersistentState             (loadPersistentState, savePersistentState)
+import           Yi.Process
+import qualified Yi.Rope                        as R (YiString, fromString, readFile)
+import           Yi.String                      (chomp, showT)
+import           Yi.Style                       (errorStyle, strongHintStyle)
+import qualified Yi.UI.Common                   as UI (UI (end, layout, main, refresh, suspend, userForceRefresh))
+import           Yi.Utils                       (io)
+import           Yi.Window                      (bufkey, dummyWindow, isMini, winRegion, wkey)
 
 -- | Make an action suitable for an interactive run.
 -- UI will be refreshed.
diff --git a/src/library/Yi/Debug.hs b/src/library/Yi/Debug.hs
--- a/src/library/Yi/Debug.hs
+++ b/src/library/Yi/Debug.hs
@@ -1,5 +1,6 @@
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE CPP               #-}
+{-# LANGUAGE FlexibleContexts  #-}
+{-# LANGUAGE LambdaCase        #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
@@ -15,16 +16,23 @@
 module Yi.Debug ( initDebug, trace, traceM, traceM_, logPutStrLn
                 , logError, logStream, Yi.Debug.error ) where
 
-import           Control.Concurrent
-import           Control.Monad.Base
-import           Data.IORef
-import           Data.Monoid
-import qualified Data.Text as T
-import           Data.Time
-import           GHC.Conc (labelThread)
-import           System.IO
-import           System.IO.Unsafe (unsafePerformIO)
-import           System.Locale
+import Control.Concurrent
+    ( dupChan, getChanContents, forkIO, myThreadId, Chan )
+import Control.Monad.Base ( liftBase, MonadBase )
+import Data.IORef ( readIORef, writeIORef, IORef, newIORef )
+import Data.Monoid ( (<>) )
+import qualified Data.Text as T ( pack, snoc, unpack, Text )
+import GHC.Conc ( labelThread )
+import System.IO
+    ( hFlush, hPutStrLn, IOMode(WriteMode), openFile, Handle )
+import System.IO.Unsafe ( unsafePerformIO )
+
+#if __GLASGOW_HASKELL__ < 710
+import Data.Time (formatTime, getCurrentTime)
+import System.Locale (defaultTimeLocale)
+#else
+import Data.Time (formatTime, getCurrentTime, defaultTimeLocale)
+#endif
 
 dbgHandle :: IORef (Maybe Handle)
 dbgHandle = unsafePerformIO $ newIORef Nothing
diff --git a/src/library/Yi/Dired.hs b/src/library/Yi/Dired.hs
--- a/src/library/Yi/Dired.hs
+++ b/src/library/Yi/Dired.hs
@@ -1,10 +1,9 @@
-{-# LANGUAGE CPP #-}
+{-# LANGUAGE CPP                #-}
 {-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE DeriveGeneric #-}
-{-# LANGUAGE LambdaCase #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE LambdaCase         #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE TemplateHaskell    #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 {-|
@@ -44,93 +43,115 @@
   , editFile
   ) where
 
-import           Control.Category ((>>>))
-import           Control.Applicative
-import           Control.Exc
-import           Control.Lens hiding (act, op, pre)
-import           Control.Monad.Reader hiding (mapM)
-import           Data.Binary
-import           Data.Char (toLower)
-import           Data.Default
-import           Data.Maybe
-#if __GLASGOW_HASKELL__ < 708
-import           Data.DeriveTH
-#else
-import           GHC.Generics (Generic)
-#endif
-import           Data.Foldable (find)
-import           Data.List hiding (find, maximum, concat)
-import qualified Data.Map as M
-import           Data.Monoid
-import qualified Data.Text as T
-import           Data.Time
-import           Data.Time.Clock.POSIX
-import           Data.Typeable
-import           System.CanonicalizePath (canonicalizePath)
-import           System.Directory hiding (canonicalizePath)
-import           System.FilePath
-import           System.FriendlyPath
-import           System.Locale
-import           System.PosixCompat.Files
-import           System.PosixCompat.Types
-import           System.PosixCompat.User
-import           Text.Printf
+import           GHC.Generics             (Generic)
+
+import           Control.Applicative      ((<$>), (<|>))
+import           Control.Category         ((>>>))
+import           Control.Exc              (orException, printingException)
+import           Control.Lens             (assign, makeLenses, use, (%~), (&), (.=), (.~), (^.))
+import           Control.Monad.Reader     (asks, foldM, liftM, unless, void, when)
+import           Data.Binary              (Binary)
+import           Data.Char                (toLower)
+import           Data.Default             (Default, def)
+import           Data.Foldable            (find, foldl')
+import           Data.List                (any, elem, sum, transpose)
+import qualified Data.Map                 as M (Map, assocs, delete, empty,
+                                                findWithDefault, fromList,
+                                                insert, keys, lookup, map,
+                                                mapKeys, union, (!))
+import           Data.Maybe               (fromMaybe)
+import           Data.Monoid              (mempty, (<>))
+import qualified Data.Text                as T (Text, pack, unpack)
+import           Data.Time.Clock.POSIX    (posixSecondsToUTCTime)
+import           Data.Typeable            (Typeable)
+import           System.CanonicalizePath  (canonicalizePath)
+import           System.Directory         (copyFile, createDirectoryIfMissing,
+                                           doesDirectoryExist, doesFileExist,
+                                           getDirectoryContents, getPermissions,
+                                           removeDirectoryRecursive, writable)
+import           System.FilePath          (dropTrailingPathSeparator,
+                                           equalFilePath, isAbsolute,
+                                           takeDirectory, takeFileName, (</>))
+import           System.FriendlyPath      (userToCanonPath)
+import           System.PosixCompat.Files (FileStatus, fileExist, fileGroup,
+                                           fileMode, fileOwner, fileSize,
+                                           getSymbolicLinkStatus,
+                                           groupExecuteMode, groupReadMode,
+                                           groupWriteMode, isBlockDevice,
+                                           isCharacterDevice, isDirectory,
+                                           isNamedPipe, isRegularFile, isSocket,
+                                           isSymbolicLink, linkCount,
+                                           modificationTime, otherExecuteMode,
+                                           otherReadMode, otherWriteMode,
+                                           ownerExecuteMode, ownerReadMode,
+                                           ownerWriteMode, readSymbolicLink,
+                                           readSymbolicLink, removeLink, rename,
+                                           unionFileModes)
+import           System.PosixCompat.Types (FileMode, GroupID, UserID)
+import           System.PosixCompat.User  (GroupEntry, GroupEntry (..),
+                                           UserEntry (..), getAllGroupEntries,
+                                           getAllUserEntries,
+                                           getGroupEntryForID,
+                                           getUserEntryForID, groupID, userID)
+import           Text.Printf              (printf)
 import           Yi.Buffer
-import           Yi.Config
-import           Yi.Core
-import           Yi.Types (YiVariable)
+import           Yi.Config                (modeTable)
+import           Yi.Core                  (errorEditor)
 import           Yi.Editor
-import           Yi.Keymap
+import           Yi.Keymap                (Keymap, YiM, topKeymapA)
 import           Yi.Keymap.Keys
-import           Yi.MiniBuffer (spawnMinibufferE, withMinibufferFree, noHint,
-                                withMinibuffer)
-import           Yi.Misc (getFolder, promptFile)
-import           Yi.Monad
-import           Yi.Regex
-import qualified Yi.Rope as R
-import           Yi.String (showT)
+import           Yi.MiniBuffer            (noHint, spawnMinibufferE, withMinibuffer, withMinibufferFree)
+import           Yi.Misc                  (getFolder, promptFile)
+import           Yi.Monad                 (gets)
+import           Yi.Regex                 (AllTextSubmatches (..), (=~))
+import qualified Yi.Rope                  as R
+import           Yi.String                (showT)
 import           Yi.Style
-import           Yi.Utils
+import           Yi.Types                 (YiVariable, yiConfig)
+import           Yi.Utils                 (io, makeLensesWithSuffix)
 
+
+#if __GLASGOW_HASKELL__ < 710
+import System.Locale (defaultTimeLocale)
+import Data.Time     (UTCTime, formatTime, getCurrentTime)
+#else
+import Data.Time     (UTCTime, formatTime, getCurrentTime, defaultTimeLocale)
+#endif
+
 -- Have no idea how to keep track of this state better, so here it is ...
 data DiredOpState = DiredOpState
     { _diredOpSucCnt :: !Int -- ^ keep track of the num of successful operations
     , _diredOpForAll :: Bool -- ^ if True, DOChoice will be bypassed
-    }
-    deriving (Show, Eq, Typeable)
+    } deriving (Show, Eq, Typeable, Generic)
 
 instance Default DiredOpState where
     def = DiredOpState { _diredOpSucCnt = 0, _diredOpForAll = False }
 
-#if __GLASGOW_HASKELL__ < 708
-$(derive makeBinary ''DiredOpState)
-#else
-deriving instance Generic DiredOpState
 instance Binary DiredOpState
-#endif
 
 instance YiVariable DiredOpState
 
 makeLenses ''DiredOpState
 
-data DiredFileInfo = DiredFileInfo {  permString :: R.YiString
-                                    , numLinks :: Integer
-                                    , owner :: R.YiString
-                                    , grp :: R.YiString
-                                    , sizeInBytes :: Integer
-                                    , modificationTimeString :: R.YiString
-                                 }
-                deriving (Show, Eq, Typeable)
+data DiredFileInfo = DiredFileInfo
+    { permString             :: R.YiString
+    , numLinks               :: Integer
+    , owner                  :: R.YiString
+    , grp                    :: R.YiString
+    , sizeInBytes            :: Integer
+    , modificationTimeString :: R.YiString
+    } deriving (Show, Eq, Typeable, Generic)
 
-data DiredEntry = DiredFile DiredFileInfo
-                | DiredDir DiredFileInfo
-                | DiredSymLink DiredFileInfo R.YiString
-                | DiredSocket DiredFileInfo
-                | DiredBlockDevice DiredFileInfo
-                | DiredCharacterDevice DiredFileInfo
-                | DiredNamedPipe DiredFileInfo
-                | DiredNoInfo
-                deriving (Show, Eq, Typeable)
+data DiredEntry
+    = DiredFile DiredFileInfo
+    | DiredDir DiredFileInfo
+    | DiredSymLink DiredFileInfo R.YiString
+    | DiredSocket DiredFileInfo
+    | DiredBlockDevice DiredFileInfo
+    | DiredCharacterDevice DiredFileInfo
+    | DiredNamedPipe DiredFileInfo
+    | DiredNoInfo
+    deriving (Show, Eq, Typeable, Generic)
 
 -- | Alias serving as documentation of some arguments. We keep most
 -- paths as 'R.YiString' for the sole reason that we'll have to render
@@ -141,28 +162,23 @@
 type DiredEntries = M.Map DiredFilePath DiredEntry
 
 data DiredState = DiredState
-  { diredPath :: FilePath -- ^ The full path to the directory being viewed
-    -- FIXME Choose better data structure for Marks...
-   , diredMarks :: M.Map FilePath Char
-     -- ^ Map values are just leafnames, not full paths
-   , diredEntries :: DiredEntries
-     -- ^ keys are just leafnames, not full paths
-   , diredFilePoints :: [(Point,Point,FilePath)]
-     -- ^ position in the buffer where filename is
-   , diredNameCol :: Int
-     -- ^ position on line where filename is (all pointA are this col)
-   , diredCurrFile :: FilePath
-     -- ^ keep the position of pointer (for refreshing dired buffer)
-  } deriving (Show, Eq, Typeable)
+    { diredPath        :: FilePath -- ^ The full path to the directory being viewed
+     -- FIXME Choose better data structure for Marks...
+    , diredMarks      :: M.Map FilePath Char
+      -- ^ Map values are just leafnames, not full paths
+    , diredEntries    :: DiredEntries
+      -- ^ keys are just leafnames, not full paths
+    , diredFilePoints :: [(Point,Point,FilePath)]
+      -- ^ position in the buffer where filename is
+    , diredNameCol    :: Int
+      -- ^ position on line where filename is (all pointA are this col)
+    , diredCurrFile   :: FilePath
+      -- ^ keep the position of pointer (for refreshing dired buffer)
+    } deriving (Show, Eq, Typeable, Generic)
 
 makeLensesWithSuffix "A" ''DiredState
 
-#if __GLASGOW_HASKELL__ < 708
-$(derive makeBinary ''DiredState)
-#else
-deriving instance Generic DiredState
 instance Binary DiredState
-#endif
 
 instance Default DiredState where
     def = DiredState { diredPath       = mempty
@@ -175,15 +191,8 @@
 
 instance YiVariable DiredState
 
-#if __GLASGOW_HASKELL__ < 708
-$(derive makeBinary ''DiredEntry)
-$(derive makeBinary ''DiredFileInfo)
-#else
-deriving instance Generic DiredEntry
-deriving instance Generic DiredFileInfo
 instance Binary DiredEntry
 instance Binary DiredFileInfo
-#endif
 
 -- | If file exists, read contents of file into a new buffer, otherwise
 -- creating a new empty buffer. Replace the current window with a new
@@ -465,7 +474,7 @@
 diredDoMarkedDel :: YiM ()
 diredDoMarkedDel = do
   dir <- currentDir
-  fs <- markedFiles (`Data.List.elem` "D")
+  fs <- markedFiles (== 'D')
   askDelFiles dir fs
 
 diredKeymap :: Keymap -> Keymap
@@ -730,6 +739,7 @@
     where
     strIfSet s mode = if fm == (fm `unionFileModes` mode) then s else "-"
 
+
 shortCalendarTimeToString :: UTCTime -> String
 shortCalendarTimeToString = formatTime defaultTimeLocale "%b %d %H:%M"
 
@@ -965,7 +975,7 @@
 diredRename :: YiM ()
 diredRename = do
   dir <- currentDir
-  fs <- markedFiles (`Data.List.elem` "*")
+  fs <- markedFiles (== '*')
   if null fs then do maybefile <- withCurrentBuffer fileFromPoint
                      case maybefile of
                        Just (fn, de) -> askRenameFiles dir [(fn, de)]
@@ -975,7 +985,7 @@
 diredCopy :: YiM ()
 diredCopy = do
   dir <- currentDir
-  fs <- markedFiles (`Data.List.elem` "*")
+  fs <- markedFiles (== '*')
   if null fs then do maybefile <- withCurrentBuffer fileFromPoint
                      case maybefile of
                        Just (fn, de) -> askCopyFiles dir [(fn, de)]
diff --git a/src/library/Yi/Editor.hs b/src/library/Yi/Editor.hs
--- a/src/library/Yi/Editor.hs
+++ b/src/library/Yi/Editor.hs
@@ -1,6 +1,6 @@
-{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE LambdaCase        #-}
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TemplateHaskell   #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
@@ -14,7 +14,7 @@
 -- The top level editor state, and operations on it. This is inside an
 -- internal module for easy re-export with Yi.Types bits.
 
-module Yi.Editor ( Editor(..), EditorM(..), MonadEditor(..)
+module Yi.Editor ( Editor(..), EditorM, MonadEditor(..)
                  , runEditor
                  , acceptedInputsOtherWindow
                  , addJumpAtE
@@ -51,6 +51,7 @@
                  , layoutManagerPreviousVariantE
                  , layoutManagersNextE
                  , layoutManagersPreviousE
+                 , maxStatusHeightA
                  , moveTabE
                  , moveWinNextE
                  , moveWinPrevE
@@ -61,6 +62,7 @@
                  , newWindowE
                  , nextTabE
                  , nextWinE
+                 , onCloseActionsA
                  , pendingEventsA
                  , prevWinE
                  , previousTabE
@@ -95,42 +97,52 @@
                  , withWindowE
                  ) where
 
-import           Control.Applicative
-import           Control.Lens
-import           Control.Monad
-import           Control.Monad.Reader hiding (mapM, forM_ )
-import           Control.Monad.State hiding (get, put, mapM, forM_)
-import           Data.Binary
-import           Data.Default
-import qualified Data.DelayList as DelayList
-import           Data.DynamicState.Serializable
-import           Data.Foldable hiding (forM_)
-import           Data.List (delete, (\\))
-import           Data.List.NonEmpty (fromList, NonEmpty(..), nub)
-import qualified Data.List.NonEmpty as NE
-import qualified Data.List.PointedList as PL (atEnd, moveTo)
-import qualified Data.List.PointedList.Circular as PL
-import qualified Data.Map as M
-import           Data.Maybe
-import qualified Data.Monoid as Mon
-import           Data.Semigroup
-import qualified Data.Text as T
-import           Prelude hiding (foldl,concatMap,foldr,all)
-import           System.FilePath (splitPath)
+import           Prelude                        hiding (all, concatMap, foldl, foldr)
+
+import           Control.Applicative            ((<$>), (<*>))
+import           Control.Lens                   (Lens', assign, lens, mapped,
+                                                 use, uses, view, (%=), (%~),
+                                                 (&), (.~), (^.))
+import           Control.Monad                  (forM_)
+import           Control.Monad.Reader           (MonadReader (ask), asks, liftM,
+                                                 unless, when)
+import           Control.Monad.State            (gets, modify)
+import           Data.Binary                    (Binary, get, put)
+import           Data.Default                   (Default, def)
+import qualified Data.DelayList                 as DelayList (insert)
+import           Data.DynamicState.Serializable (getDyn, putDyn)
+import           Data.Foldable                  (Foldable (foldl, foldr), all, concatMap, toList)
+import           Data.List                      (delete, (\\))
+import           Data.List.NonEmpty             (NonEmpty (..), fromList, nub)
+import qualified Data.List.NonEmpty             as NE (filter, head, length, toList, (<|))
+import qualified Data.List.PointedList          as PL (atEnd, moveTo)
+import qualified Data.List.PointedList.Circular as PL (PointedList (..), delete,
+                                                       deleteLeft, deleteOthers,
+                                                       deleteRight, focus,
+                                                       insertLeft, insertRight,
+                                                       length, next, previous,
+                                                       singleton, _focus)
+import qualified Data.Map                       as M (delete, elems, empty,
+                                                      insert, lookup, singleton, (!))
+import           Data.Maybe                     (fromJust, fromMaybe, isNothing)
+import qualified Data.Monoid                    as Mon ((<>))
+import           Data.Semigroup                 (mempty, (<>))
+import qualified Data.Text                      as T (Text, null, pack, unlines, unpack, unwords)
+import           System.FilePath                (splitPath)
 import           Yi.Buffer
 import           Yi.Config
-import           Yi.Interact as I
-import           Yi.JumpList
-import           Yi.KillRing
+import           Yi.Interact                    as I (accepted, mkAutomaton)
+import           Yi.JumpList                    (Jump (..), JumpList, addJump, jumpBack, jumpForward)
+import           Yi.KillRing                    (krEmpty, krGet, krPut, krSet)
 import           Yi.Layout
-import           Yi.Monad
-import           Yi.Rope (YiString, fromText, empty)
-import qualified Yi.Rope as R
-import           Yi.String
-import           Yi.Style (defaultStyle)
+import           Yi.Monad                       (getsAndModify)
+import           Yi.Rope                        (YiString, empty, fromText)
+import qualified Yi.Rope                        as R (YiString, fromText, snoc)
+import           Yi.String                      (listify)
+import           Yi.Style                       (defaultStyle)
 import           Yi.Tab
 import           Yi.Types
-import           Yi.Utils hiding ((+~))
+import           Yi.Utils
 import           Yi.Window
 
 instance Binary Editor where
@@ -333,13 +345,6 @@
     [] -> fail ("Buffer not found: " ++ T.unpack bufName)
     b:_ -> return b
 
--- | Make all buffers visible by splitting the current window list.
--- FIXME: rename to displayAllBuffersE; make sure buffers are not open twice.
-openAllBuffersE :: EditorM ()
-openAllBuffersE = do
-  bs <- gets bufferSet
-  forM_ bs $ ((%=) windowsA . PL.insertRight =<<) . newWindowE False . bkey
-
 ------------------------------------------------------------------------
 -- | Perform action with any given buffer, using the last window that
 -- was used for that buffer.
@@ -497,10 +502,6 @@
   w & bufkeyA .~ bk
     & bufAccessListA %~ forceFold1 . (bufkey w:) . filter (bk /=)
 
--- | Attach the specified buffer to some other window than the current one
-switchToBufferOtherWindowE :: BufferRef -> EditorM ()
-switchToBufferOtherWindowE b = shiftOtherWindow >> switchToBufferE b
-
 -- | Switch to the buffer specified as parameter. If the buffer name
 -- is empty, switch to the next buffer.
 switchToBufferWithNameE :: T.Text -> EditorM ()
@@ -524,9 +525,8 @@
 -- | Close current buffer and window, unless it's the last one.
 closeBufferAndWindowE :: EditorM ()
 closeBufferAndWindowE = do
-  -- Fetch the current buffer *before* closing the window. Required
-  -- for the onCloseBufferE actions to work as expected by the
-  -- minibuffer. The tryCloseE, since it uses tabsA, will have the
+  -- Fetch the current buffer *before* closing the window.
+  -- The tryCloseE, since it uses tabsA, will have the
   -- current buffer "fixed" to the buffer of the window that is
   -- brought into focus. If the current buffer is accessed after the
   -- tryCloseE then the current buffer may not be the same as the
@@ -579,12 +579,6 @@
   -- make sure we do not hold to old versions by seqing the length.
   in NE.length newBufferStack `seq` new & bufferStackA .~ newBufferStack)
 
--- | Counterpart of fixCurrentBufferA_: fix the current window to point to the
--- right buffer.
-fixCurrentWindowE :: EditorM ()
-fixCurrentWindowE =
-  gets currentBuffer >>= \b -> windowsA . PL.focus . bufkeyA .= b
-
 withWindowE :: Window -> BufferM a -> EditorM a
 withWindowE w = withGivenBufferAndWindow w (bufkey w)
 
@@ -754,23 +748,6 @@
   b <- stringToNewBuffer (MemBuffer "keybindings") (fromText $ T.unlines ai)
   w <- newWindowE False b
   windowsA %= PL.insertRight w
-
--- | Defines an action to be executed when the current buffer is closed.
---
--- Used by the minibuffer to assure the focus is restored to the
--- buffer that spawned the minibuffer.
---
--- todo: These actions are not restored on reload.
---
--- todo: These actions should probably be very careful at what they
--- do.
---
--- TODO: All in all, this is a very ugly way to achieve the purpose.
--- The nice way to proceed is to somehow attach the miniwindow to the
--- window that has spawned it.
-onCloseBufferE :: BufferRef -> EditorM () -> EditorM ()
-onCloseBufferE b a =
-  onCloseActionsA %= M.insertWith' (\_ old_a -> old_a >> a) b a
 
 addJumpHereE :: EditorM ()
 addJumpHereE = addJumpAtE =<< withCurrentBuffer pointB
diff --git a/src/library/Yi/Eval.hs b/src/library/Yi/Eval.hs
--- a/src/library/Yi/Eval.hs
+++ b/src/library/Yi/Eval.hs
@@ -1,9 +1,9 @@
-{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE CPP                        #-}
+{-# LANGUAGE DeriveDataTypeable         #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE LambdaCase #-}
-{-# LANGUAGE TemplateHaskell #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE LambdaCase                 #-}
+{-# LANGUAGE OverloadedStrings          #-}
+{-# LANGUAGE TemplateHaskell            #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -24,7 +24,9 @@
         Evaluator(..),
         evaluator,
         -- ** Standard evaluators
+#ifdef HINT
         ghciEvaluator,
+#endif
         publishedActionsEvaluator,
         publishedActions,
         publishAction,
@@ -34,41 +36,86 @@
         consoleKeymap
 ) where
 
-import           Control.Applicative ((<$>), (<*>))
-import           Control.Concurrent
-import           Control.Monad.Catch (try)
-import           Control.Lens hiding (Action)
-import           Control.Monad hiding (mapM_)
-import           Control.Monad.Base
-import           Control.Monad.Trans (lift)
-import           Data.Array
-import           Data.Binary
-import           Data.Default
-import           Data.Foldable (mapM_)
+import Prelude hiding (mapM_)
+
+import Control.Applicative ( (<$>), (<*>) )
+import Control.Lens ( (^.), (<&>), (.=), (%=) )
+import Control.Monad (when)
+import Data.Array ( elems )
+import Data.Binary ( Binary )
+import Data.Default ( Default, def )
+import Data.Foldable ( mapM_ )
 import qualified Data.HashMap.Strict as M
-import           Data.List
-import           Data.Monoid
-import           Data.Typeable
+    ( HashMap, insert, lookup, empty, keys )
+import Data.Monoid ( mempty, Monoid, (<>) )
+import Data.Typeable ( Typeable )
+#ifdef HINT
+import Control.Concurrent
+    ( takeMVar, putMVar, newEmptyMVar, MVar, forkIO )
+import Control.Monad
+    ( Monad((>>), (>>=), return), void, forever )
+import Control.Monad.Base ( MonadBase )
+import Control.Monad.Catch ( try )
+import Control.Monad.Trans ( lift )
+import Data.Binary ( get, put )
+import Data.List ( sort )
 import qualified Language.Haskell.Interpreter as LHI
-import           Prelude hiding (error, mapM_)
-import           System.Directory (doesFileExist)
-import           Text.Read (readMaybe)
-import           Yi.Boot.Internal (reload)
-import           Yi.Buffer
-import           Yi.Config.Simple.Types
-import           Yi.Core (errorEditor, runAction)
-import           Yi.Types (YiVariable,YiConfigVariable)
-import           Yi.Editor
-import           Yi.File
-import           Yi.Hooks
-import           Yi.Keymap
-import           Yi.Keymap.Keys
-import qualified Yi.Paths (getEvaluatorContextFilename)
-import           Yi.Regex
+    ( typeOf,
+      setImportsQ,
+      searchPath,
+      set,
+      runInterpreter,
+      ModuleElem(Data, Class, Fun),
+      getModuleExports,
+      as,
+      loadModules,
+      languageExtensions,
+      OptionVal((:=)),
+      InterpreterError,
+      Extension(OverloadedStrings, NoImplicitPrelude),
+      setTopLevelModules,
+      interpret )
+import System.Directory ( doesFileExist )
+import Yi.Boot.Internal ( reload )
+import Yi.Core ( errorEditor )
+import Yi.Editor
+    ( getEditorDyn,
+      putEditorDyn,
+      MonadEditor)
+import qualified Yi.Paths ( getEvaluatorContextFilename )
+import Yi.String ( showT )
+import Yi.Utils ( io )
+#endif
+import Text.Read ( readMaybe )
+import Yi.Buffer
+    ( gotoLn,
+      moveXorEol,
+      BufferM,
+      readLnB,
+      pointB,
+      botB,
+      insertN,
+      getBookmarkB,
+      markPointA )
+import Yi.Config.Simple.Types ( customVariable, Field, ConfigM )
+import Yi.Core ( runAction )
+import Yi.Types ( YiVariable, YiConfigVariable )
+import Yi.Editor
+    ( printMsg,
+      askCfg,
+      withCurrentBuffer,
+      withCurrentBuffer )
+import Yi.File ( openingNewFile )
+import Yi.Hooks ( runHook )
+import Yi.Keymap
+    ( YiM, Action, YiAction, makeAction, Keymap, write )
+import Yi.Keymap.Keys ( event, Event(..), Key(KEnter) )
+import Yi.Regex ( Regex, makeRegex, matchOnceText )
 import qualified Yi.Rope as R
-import           Yi.String
-import           Yi.Utils
+    ( toString, YiString, splitAt, length )
+import Yi.Utils ( makeLensesWithSuffix )
 
+
 -- TODO: should we be sticking Text here?
 
 -- | Runs the action, as written by the user.
@@ -112,7 +159,6 @@
 evaluator :: Field Evaluator
 evaluator = customVariable
 
-instance Default Evaluator where def = ghciEvaluator
 instance YiConfigVariable Evaluator
 
 -- * Evaluator based on GHCi
@@ -130,6 +176,7 @@
     def = HelpCache M.empty
 instance YiVariable HelpCache
 
+#ifdef HINT
 type HintRequest = (String, MVar (Either LHI.InterpreterError Action))
 newtype HintThreadVar = HintThreadVar (Maybe (MVar HintRequest))
   deriving (Typeable, Default)
@@ -245,6 +292,8 @@
                        Just description -> return description
       return $ name ++ " :: " ++ description
 
+#endif
+
 -- * 'PublishedActions' evaluator
 
 newtype PublishedActions = PublishedActions {
@@ -345,3 +394,10 @@
         bm <- getBookmarkB "errorInsert"
         markPointA bm .= pt
       execEditorAction . R.toString $ takeCommand x
+
+instance Default Evaluator where
+#ifdef HINT
+    def = ghciEvaluator
+#else
+    def = publishedActionsEvaluator
+#endif
diff --git a/src/library/Yi/Event.hs b/src/library/Yi/Event.hs
--- a/src/library/Yi/Event.hs
+++ b/src/library/Yi/Event.hs
@@ -7,9 +7,9 @@
      eventToChar
     ) where
 
-import Data.Bits
-import Data.Char (chr,ord)
-import Data.Monoid
+import Data.Bits   (setBit)
+import Data.Char   (chr, ord)
+import Data.Monoid (mappend)
 
 data Modifier = MShift | MCtrl | MMeta | MSuper | MHyper
                 deriving (Show,Eq,Ord)
diff --git a/src/library/Yi/File.hs b/src/library/Yi/File.hs
--- a/src/library/Yi/File.hs
+++ b/src/library/Yi/File.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE LambdaCase #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE LambdaCase         #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE TemplateHaskell    #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -33,28 +33,28 @@
   preSaveHooks
  ) where
 
-import           Control.Applicative
-import           Control.Lens hiding (act, Action)
-import           Control.Monad (filterM, when, void)
-import           Control.Monad.Base
-import           Data.Default
-import           Data.Monoid
-import qualified Data.Text as T
-import           Data.Typeable
-import           Data.Time
-import           System.Directory
-import           System.FriendlyPath
+import           Control.Applicative    ((<$>))
+import           Control.Lens           (assign, makeLenses, use, view, (^.))
+import           Control.Monad          (filterM, void, when)
+import           Control.Monad.Base     (liftBase)
+import           Data.Default           (Default, def)
+import           Data.Monoid            ((<>))
+import qualified Data.Text              as T (Text, append, cons, pack, unpack)
+import           Data.Time              (getCurrentTime)
+import           Data.Typeable          (Typeable)
+import           System.Directory       (doesDirectoryExist, doesFileExist)
+import           System.FriendlyPath    (userToCanonPath)
 import           Yi.Buffer
-import           Yi.Config.Simple.Types (customVariable, Field)
-import           Yi.Core
-import           Yi.Dired
+import           Yi.Config.Simple.Types (Field, customVariable)
+import           Yi.Core                (errorEditor, runAction)
+import           Yi.Dired               (editFile)
 import           Yi.Editor
-import           Yi.Keymap
-import           Yi.Monad
-import qualified Yi.Rope as R
-import           Yi.String
+import           Yi.Keymap              ()
+import           Yi.Monad               (gets)
+import qualified Yi.Rope                as R (readFile, writeFile, writeFileUsingText)
+import           Yi.String              (showT)
 import           Yi.Types
-import           Yi.Utils
+import           Yi.Utils               (io)
 
 newtype PreSaveHooks = PreSaveHooks { _unPreSaveHooks :: [Action] }
     deriving Typeable
diff --git a/src/library/Yi/History.hs b/src/library/Yi/History.hs
--- a/src/library/Yi/History.hs
+++ b/src/library/Yi/History.hs
@@ -1,8 +1,8 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE Rank2Types #-}
+{-# LANGUAGE CPP                 #-}
+{-# LANGUAGE DeriveDataTypeable  #-}
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE Rank2Types          #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
@@ -17,20 +17,20 @@
 
 module Yi.History where
 
-import           Control.Applicative
-import           Control.Lens
-import           Data.Binary
-import           Data.Default
-import           Data.List
-import qualified Data.Map as M
-import           Data.Monoid
-import qualified Data.Text as T
-import qualified Data.Text.Encoding as E
-import           Data.Typeable
-import           Yi.Buffer
+import           Control.Applicative (liftA3, (<$>))
+import           Control.Lens        (Lens', lens, set, (^.))
+import           Data.Binary         (Binary, get, put)
+import           Data.Default        (Default, def)
+import           Data.List           (nub)
+import qualified Data.Map            as M (Map, findWithDefault, insert, mapKeys)
+import           Data.Monoid         (mempty, (<>))
+import qualified Data.Text           as T (Text, isPrefixOf, null, pack, unpack)
+import qualified Data.Text.Encoding  as E (decodeUtf8, encodeUtf8)
+import           Data.Typeable       (Typeable)
+import           Yi.Buffer           (elemsB, replaceBufferContent)
 import           Yi.Editor
-import qualified Yi.Rope as R
-import           Yi.Types (YiVariable)
+import qualified Yi.Rope             as R (fromText, toText)
+import           Yi.Types            (YiVariable)
 
 newtype Histories = Histories (M.Map T.Text History)
                   deriving (Show, Eq, Typeable)
@@ -42,9 +42,9 @@
 instance Default Histories where
   def = Histories def
 
-data History = History { _historyCurrent :: Int
+data History = History { _historyCurrent  :: Int
                        , _historyContents :: [T.Text]
-                       , _historyPrefix :: T.Text
+                       , _historyPrefix   :: T.Text
                        } deriving (Show, Eq, Typeable)
 
 instance Default History where
diff --git a/src/library/Yi/Hoogle.hs b/src/library/Yi/Hoogle.hs
--- a/src/library/Yi/Hoogle.hs
+++ b/src/library/Yi/Hoogle.hs
@@ -13,19 +13,19 @@
 
 module Yi.Hoogle where
 
-import           Control.Applicative
-import           Control.Arrow ((&&&))
-import           Data.Char (isUpper)
-import           Data.List (nub)
-import qualified Data.Text as T
-import           System.Exit (ExitCode(ExitFailure))
-import           Yi.Buffer
-import           Yi.Editor
-import           Yi.Keymap
-import           Yi.Process (runProgCommand)
-import qualified Yi.Rope as R
-import           Yi.String (showT)
-import           Yi.Utils
+import           Control.Applicative ((<$>))
+import           Control.Arrow       ((&&&))
+import           Data.Char           (isUpper)
+import           Data.List           (nub)
+import qualified Data.Text           as T (isInfixOf, lines, pack)
+import           System.Exit         (ExitCode (ExitFailure))
+import           Yi.Buffer           (readRegionB, regionOfB, replaceRegionB, unitWord)
+import           Yi.Editor           (printMsgs, withCurrentBuffer)
+import           Yi.Keymap           (YiM)
+import           Yi.Process          (runProgCommand)
+import qualified Yi.Rope             as R (YiString, fromText, head, null, toString, toText, words)
+import           Yi.String           (showT)
+import           Yi.Utils            (io)
 
 -- | Remove anything starting with uppercase letter. These denote
 -- either module names or types.
diff --git a/src/library/Yi/Hooks.hs b/src/library/Yi/Hooks.hs
--- a/src/library/Yi/Hooks.hs
+++ b/src/library/Yi/Hooks.hs
@@ -55,6 +55,7 @@
 
 See "Yi.Eval" for a real example of hooks.
 -}
+
 module Yi.Hooks(
   -- * Convenience function 'runHook'
   runHook,
@@ -65,12 +66,12 @@
  )
   where
 
-import Control.Lens
-import Yi.Config
-import Yi.Editor
-import Yi.Keymap
-import Yi.Config.Simple.Types(customVariable, Field)
-import Yi.Types (YiConfigVariable)
+import Control.Lens           ((^.))
+import Yi.Config              (configVariable)
+import Yi.Config.Simple.Types (Field, customVariable)
+import Yi.Editor              (EditorM, askCfg)
+import Yi.Keymap              (YiM)
+import Yi.Types               (YiConfigVariable)
 
 -- | Looks up the configured value for the hook, and runs it. The
 -- argument to 'runHook' will typically be a record accessor. See
diff --git a/src/library/Yi/IReader.hs b/src/library/Yi/IReader.hs
--- a/src/library/Yi/IReader.hs
+++ b/src/library/Yi/IReader.hs
@@ -20,23 +20,26 @@
 
 module Yi.IReader where
 
-import           Control.Exception
-import           Control.Monad
-import           Data.Functor ( (<$>) )
-import           Data.Binary
-import qualified Data.ByteString.Char8 as B (pack, unpack, readFile, ByteString)
+import           Control.Exception          (SomeException, catch)
+import           Control.Monad              (join, void)
+import           Data.Binary                (Binary, decode, encodeFile)
+import qualified Data.ByteString.Char8      as B (ByteString, pack, readFile, unpack)
 import qualified Data.ByteString.Lazy.Char8 as BL (fromChunks)
-import           Data.Default
-import           Data.Sequence as S
-import           Data.Typeable
-import           Yi.Buffer.HighLevel (replaceBufferContent, topB)
-import           Yi.Buffer.Misc (getBufferDyn, putBufferDyn, elemsB)
-import           Yi.Editor (withCurrentBuffer)
-import           Yi.Keymap (YiM)
-import           Yi.Paths (getArticleDbFilename)
-import qualified Yi.Rope as R
-import           Yi.Utils
-import           Yi.Types (YiVariable)
+import           Data.Default               (Default, def)
+import           Data.Functor               ((<$>))
+import           Data.Sequence              as S (Seq, ViewL (EmptyL, (:<)),
+                                                  ViewR ((:>)), empty, length,
+                                                  null, splitAt, viewl, viewr,
+                                                  (<|), (><), (|>))
+import           Data.Typeable              (Typeable)
+import           Yi.Buffer.HighLevel        (replaceBufferContent, topB)
+import           Yi.Buffer.Misc             (elemsB, getBufferDyn, putBufferDyn)
+import           Yi.Editor                  (withCurrentBuffer)
+import           Yi.Keymap                  (YiM)
+import           Yi.Paths                   (getArticleDbFilename)
+import qualified Yi.Rope                    as R (fromString, toString)
+import           Yi.Types                   (YiVariable)
+import           Yi.Utils                   (io)
 
 -- | TODO: Why 'B.ByteString'?
 type Article = B.ByteString
diff --git a/src/library/Yi/IncrementalParse.hs b/src/library/Yi/IncrementalParse.hs
--- a/src/library/Yi/IncrementalParse.hs
+++ b/src/library/Yi/IncrementalParse.hs
@@ -2,9 +2,13 @@
 
 module Yi.IncrementalParse (recoverWith, symbol, eof, lookNext, testNext,
                             State, P, Parser(..), AlexState (..), scanner) where
-import Parser.Incremental hiding (run)
-import Yi.Lexer.Alex (AlexState (..))
-import Yi.Syntax
+
+import           Parser.Incremental (Parser (..), Process, eof, evalL, evalR,
+                                     lookNext, mkProcess, pushEof, pushSyms,
+                                     recoverWith, symbol, testNext)
+
+import           Yi.Lexer.Alex      (AlexState (..))
+import           Yi.Syntax          (Scanner (..))
 
 type P s a = Parser s a
 
diff --git a/src/library/Yi/Interact.hs b/src/library/Yi/Interact.hs
--- a/src/library/Yi/Interact.hs
+++ b/src/library/Yi/Interact.hs
@@ -1,9 +1,9 @@
-{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FlexibleInstances      #-}
 {-# LANGUAGE FunctionalDependencies #-}
-{-# LANGUAGE GADTs #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE GADTs                  #-}
+{-# LANGUAGE OverloadedStrings      #-}
+{-# LANGUAGE ScopedTypeVariables    #-}
+{-# LANGUAGE UndecidableInstances   #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 {-|
@@ -66,14 +66,14 @@
      accepted
     ) where
 
-import           Control.Applicative
-import           Control.Arrow (first)
-import           Control.Lens
-import           Control.Monad.State hiding ( get, mapM )
-import           Data.Function (on)
-import           Data.List (groupBy)
-import           Data.Monoid
-import qualified Data.Text as T
+import           Control.Applicative (Alternative ((<|>), empty), Applicative ((<*>), pure))
+import           Control.Arrow       (first)
+import           Control.Lens        (Field1 (_1), Field2 (_2), view)
+import           Control.Monad.State (MonadPlus (..), MonadTrans (lift), StateT)
+import           Data.Function       (on)
+import           Data.List           (groupBy)
+import           Data.Monoid         (Monoid (mappend, mempty))
+import qualified Data.Text           as T (Text, append, pack)
 
 ------------------------------------------------
 -- Classes
diff --git a/src/library/Yi/JumpList.hs b/src/library/Yi/JumpList.hs
--- a/src/library/Yi/JumpList.hs
+++ b/src/library/Yi/JumpList.hs
@@ -1,4 +1,6 @@
-{-# LANGUAGE TemplateHaskell, CPP, StandaloneDeriving, DeriveGeneric #-}
+{-# LANGUAGE CPP                #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE TemplateHaskell    #-}
 
 module Yi.JumpList
     ( JumpList
@@ -8,30 +10,21 @@
     , jumpForward
     ) where
 
-import Yi.Buffer.Basic
+import           GHC.Generics          (Generic)
 
-import Data.Binary
-#if __GLASGOW_HASKELL__ < 708
-import Data.DeriveTH
-#else
-import GHC.Generics (Generic)
-#endif
+import           Data.Binary           (Binary)
+import           Data.List.PointedList as PL (PointedList (..), next, previous)
+import           Yi.Buffer.Basic       (BufferRef, Mark)
 
-import Data.List.PointedList as PL
 
 type JumpList = Maybe (PL.PointedList Jump)
 
 data Jump = Jump {
-        jumpMark :: Mark
+        jumpMark      :: Mark
       , jumpBufferRef :: BufferRef
-    }
+    } deriving (Generic)
 
-#if __GLASGOW_HASKELL__ < 708
-$(derive makeBinary ''Jump)
-#else
-deriving instance Generic Jump
 instance Binary Jump
-#endif
 
 instance Show Jump where
     show (Jump mark bufref) = "<Jump " ++ show mark ++ " " ++ show bufref ++ ">"
diff --git a/src/library/Yi/Keymap.hs b/src/library/Yi/Keymap.hs
--- a/src/library/Yi/Keymap.hs
+++ b/src/library/Yi/Keymap.hs
@@ -1,14 +1,14 @@
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE ExistentialQuantification #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE ExistentialQuantification  #-}
+{-# LANGUAGE FlexibleContexts           #-}
+{-# LANGUAGE FlexibleInstances          #-}
+{-# LANGUAGE FunctionalDependencies     #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE Rank2Types #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE TemplateHaskell #-}
-{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE MultiParamTypeClasses      #-}
+{-# LANGUAGE Rank2Types                 #-}
+{-# LANGUAGE StandaloneDeriving         #-}
+{-# LANGUAGE TemplateHaskell            #-}
+{-# LANGUAGE TypeSynonymInstances       #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -59,16 +59,16 @@
     , yiVarA
     ) where
 
-import           Control.Exception
-import           Control.Monad.Reader hiding (mapM_)
-import           Control.Monad.State hiding (mapM_)
-import           Yi.Buffer
-import qualified Yi.Editor as Editor
-import qualified Yi.Interact as I
-import           Yi.Monad
+import           Control.Exception    (Exception, catch, catchJust)
+import           Control.Monad.Reader (ReaderT (ReaderT, runReaderT))
+import           Control.Monad.State  (gets)
+import           Yi.Buffer            ()
+import qualified Yi.Editor            as Editor (currentBuffer, findBuffer)
+import qualified Yi.Interact          as I (MonadInteract, write)
+import           Yi.Monad             (with)
 import           Yi.Types
-import           Yi.UI.Common
-import           Yi.Utils
+import           Yi.UI.Common         (UI)
+import           Yi.Utils             (io, makeLensesWithSuffix)
 
 
 -----------------------
diff --git a/src/library/Yi/Keymap/Completion.hs b/src/library/Yi/Keymap/Completion.hs
--- a/src/library/Yi/Keymap/Completion.hs
+++ b/src/library/Yi/Keymap/Completion.hs
@@ -6,7 +6,7 @@
    where
 
 import Control.Arrow (first)
-import Data.List
+import Data.List     (find, groupBy, intercalate, sortBy)
 
 -- inside a completion tree, the a's must be unique on each level
 
diff --git a/src/library/Yi/Keymap/Cua.hs b/src/library/Yi/Keymap/Cua.hs
--- a/src/library/Yi/Keymap/Cua.hs
+++ b/src/library/Yi/Keymap/Cua.hs
@@ -18,21 +18,21 @@
                      , del
                      ) where
 
-import           Control.Applicative
-import           Control.Lens hiding (act)
-import           Control.Monad
-import qualified Data.Text as T
+import           Control.Applicative   (Alternative ((<|>)), (<$>))
+import           Control.Lens          (assign, use)
+import           Control.Monad         (unless, when)
+import qualified Data.Text             as T (drop, take)
 import           Yi.Buffer
 import           Yi.Editor
-import           Yi.File
-import           Yi.Keymap
-import           Yi.Keymap.Emacs.Utils
+import           Yi.File               (fwriteE)
+import           Yi.Keymap             (Keymap, KeymapSet, YiM, modelessKeymapSet, write)
+import           Yi.Keymap.Emacs.Utils (askQuitEditor, findFile, isearchKeymap)
 import           Yi.Keymap.Keys
-import           Yi.MiniBuffer
-import           Yi.Misc (adjBlock, selectAll)
-import           Yi.Rectangle
-import qualified Yi.Rope as R
-import           Yi.String
+import           Yi.MiniBuffer         (commentRegion)
+import           Yi.Misc               (adjBlock, selectAll)
+import           Yi.Rectangle          (getRectangle, killRectangle, yankRectangle)
+import qualified Yi.Rope               as R (YiString, length, singleton, withText)
+import           Yi.String             (lines', unlines')
 
 customizedCuaKeymapSet :: Keymap -> KeymapSet
 customizedCuaKeymapSet userKeymap =
diff --git a/src/library/Yi/Keymap/Emacs.hs b/src/library/Yi/Keymap/Emacs.hs
--- a/src/library/Yi/Keymap/Emacs.hs
+++ b/src/library/Yi/Keymap/Emacs.hs
@@ -1,8 +1,8 @@
-{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleContexts  #-}
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE TemplateHaskell #-}
-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE UnicodeSyntax #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE TypeOperators     #-}
+{-# LANGUAGE LambdaCase        #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -26,35 +26,30 @@
                        , completionCaseSensitive
                        ) where
 
-import Control.Applicative
-import Control.Lens
-import Control.Monad
-import Data.Char
-import Data.Maybe
-import Data.Prototype
-import Data.Text ()
+import Control.Applicative      (Alternative ((<|>), empty, some))
+import Control.Lens             (assign, makeLenses, (%=))
+import Control.Monad            (replicateM_, unless, void)
+import Control.Monad.State      (gets)
+import Data.Char                (digitToInt, isDigit)
+import Data.Maybe               (fromMaybe)
+import Data.Prototype           (Proto (Proto), extractValue)
+import Data.Text                ()
 import Yi.Buffer
-import Yi.Command (shellCommandE)
-import Yi.Core (closeWindowEmacs, runAction, suspendEditor,
-                userForceRefresh, withSyntax)
-import Yi.Dired
+import Yi.Command               (shellCommandE)
+import Yi.Core
+import Yi.Dired                 (dired)
 import Yi.Editor
-import Yi.File
-import Yi.Keymap
+import Yi.File                  (fwriteE, fwriteToE)
+import Yi.Keymap                (Keymap, KeymapSet, YiAction (..), YiM, modelessKeymapSet, write)
 import Yi.Keymap.Emacs.KillRing
 import Yi.Keymap.Emacs.Utils
-  (askQuitEditor, evalRegionE, executeExtendedCommandE, findFile,
-   findFileNewTab, promptFile, insertNextC, isearchKeymap, killBufferE,
-   queryReplaceE, readUniversalArg, scrollDownE, scrollUpE, switchBufferE,
-   askSaveEditor, argToInt, promptTag, justOneSep, joinLinesE, countWordsRegion,
-   findFileReadOnly)
 import Yi.Keymap.Keys
 import Yi.MiniBuffer
-import Yi.Misc (adjBlock, adjIndent, selectAll, placeMark)
-import Yi.Mode.Buffers ( listBuffers )
+import Yi.Misc                  (adjBlock, adjIndent, placeMark, selectAll)
+import Yi.Mode.Buffers          (listBuffers)
 import Yi.Rectangle
-import Yi.Search (isearchFinishWithE, resetRegexE)
-import Yi.TextCompletion
+import Yi.Search                (isearchFinishWithE, resetRegexE, getRegexE)
+import Yi.TextCompletion        (resetComplete, wordComplete')
 
 data ModeMap = ModeMap { _eKeymap :: Keymap
                        , _completionCaseSensitive :: Bool
@@ -98,8 +93,13 @@
 
 -- | Wrapper around 'moveE' which also cancels incremental search. See
 -- issue #499 for details.
-moveE ∷ TextUnit → Direction → EditorM ()
-moveE u d = isearchFinishWithE resetRegexE >> withCurrentBuffer (moveB u d)
+moveE :: TextUnit -> Direction -> EditorM ()
+moveE u d = do
+  getRegexE >>= \case
+    -- let's check whether searching is in progress (issues #738, #610)
+    Nothing -> return ()
+    _ -> isearchFinishWithE resetRegexE
+  withCurrentBuffer (moveB u d)
 
 emacsKeys :: Maybe Int -> Keymap
 emacsKeys univArg =
@@ -107,14 +107,12 @@
            spec KTab            ?>>! adjIndent IncreaseCycle
          , shift (spec KTab)    ?>>! adjIndent DecreaseCycle
          , spec KEnter          ?>>! repeatingArg newlineB
-         , spec KDel            ?>>! repeatingArg (blockKillring >> deleteB')
-         , spec KBS             ?>>! repeatingArg (blockKillring >>
-                                                    adjBlock (-1) >>
-                                                    bdeleteB)
+         , spec KDel            ?>>! deleteRegionOr deleteForward
+         , spec KBS             ?>>! deleteRegionOr deleteBack
          , spec KHome           ?>>! repeatingArg moveToSol
          , spec KEnd            ?>>! repeatingArg moveToEol
-         , spec KLeft           ?>>! repeatingArg leftB
-         , spec KRight          ?>>! repeatingArg rightB
+         , spec KLeft           ?>>! repeatingArg $ moveE Character Backward
+         , spec KRight          ?>>! repeatingArg $ moveE Character Forward
          , spec KUp             ?>>! repeatingArg $ moveE VLine Backward
          , spec KDown           ?>>! repeatingArg $ moveE VLine Forward
          , spec KPageDown       ?>>! repeatingArg downScreenB
@@ -137,10 +135,10 @@
          , ctrlCh '/'           ?>>! repeatingArg undoB
          , ctrlCh '_'           ?>>! repeatingArg undoB
          , ctrlCh 'a'           ?>>! repeatingArg (maybeMoveB Line Backward)
-         , ctrlCh 'b'           ?>>! repeatingArg leftB
-         , ctrlCh 'd'           ?>>! repeatingArg (blockKillring >> deleteB')
+         , ctrlCh 'b'           ?>>! repeatingArg $ moveE Character Backward
+         , ctrlCh 'd'           ?>>! deleteForward
          , ctrlCh 'e'           ?>>! repeatingArg (maybeMoveB Line Forward)
-         , ctrlCh 'f'           ?>>! repeatingArg rightB
+         , ctrlCh 'f'           ?>>! repeatingArg $ moveE Character Forward
          , ctrlCh 'g'           ?>>! setVisibleSelection False
          , ctrlCh 'h'           ?>> char 'b' ?>>! acceptedInputsOtherWindow
          , ctrlCh 'i'           ?>>! adjIndent IncreaseOnly
@@ -203,6 +201,7 @@
          , metaCh 'l'           ?>>! repeatingArg lowercaseWordB
          , metaCh 'm'           ?>>! firstNonSpaceB
          , metaCh 'q'           ?>>! withSyntax modePrettify
+         , metaCh 'r'           ?>>! repeatingArg moveToMTB
          , metaCh 'u'           ?>>! repeatingArg uppercaseWordB
          , metaCh 't'           ?>>! repeatingArg (transposeB unitWord Forward)
          , metaCh 'w'           ?>>! killRingSaveE
@@ -213,6 +212,7 @@
          , metaCh '}'           ?>>! repeatingArg (nextNParagraphs 1)
          , metaCh '='           ?>>! countWordsRegion
          , metaCh '\\'          ?>>! deleteHorizontalSpaceB univArg
+         , metaCh '@'           ?>>! repeatingArg markWord
 
          -- Other meta key-bindings
          , meta (spec KBS)      ?>>! repeatingArg bkillWordB
@@ -234,6 +234,21 @@
   withIntArg :: YiAction (m ()) () => (Int -> m ()) -> YiM ()
   withIntArg cmd = withUnivArg $ \arg -> cmd (fromMaybe 1 arg)
 
+  deleteBack :: YiM ()
+  deleteBack = repeatingArg $ blockKillring >> adjBlock (-1) >> bdeleteB
+
+  deleteForward :: YiM ()
+  deleteForward = repeatingArg $ blockKillring >> deleteB'
+
+  -- Deletes current region if any, otherwise executes the given
+  -- action.
+  deleteRegionOr :: (Show a, YiAction (m a) a) => m a -> YiM ()
+  deleteRegionOr f = do
+    b <- gets currentBuffer
+    r <- withGivenBuffer b getSelectRegionB
+    if regionSize r == 0
+      then runAction $ makeAction f
+      else withGivenBuffer b $ deleteRegionB r
 
   ctrlC = choice [ ctrlCh 'c' ?>>! commentRegion ]
 
diff --git a/src/library/Yi/Keymap/Emacs/KillRing.hs b/src/library/Yi/Keymap/Emacs/KillRing.hs
--- a/src/library/Yi/Keymap/Emacs/KillRing.hs
+++ b/src/library/Yi/Keymap/Emacs/KillRing.hs
@@ -9,15 +9,14 @@
 
 module Yi.Keymap.Emacs.KillRing where
 
-import           Control.Lens
-import           Control.Monad (replicateM_)
-import           Data.List.NonEmpty
-import           Prelude hiding (tail, head)
+import           Control.Lens       (assign, use, uses, (%=), (.=))
+import           Control.Monad      (replicateM_)
+import           Data.List.NonEmpty (NonEmpty ((:|)))
 import           Yi.Buffer
-import           Yi.Editor
-import           Yi.Keymap
-import           Yi.KillRing
-import qualified Yi.Rope as R
+import           Yi.Editor          (EditorM, killringA, withCurrentBuffer)
+import           Yi.Keymap          (YiM)
+import           Yi.KillRing        (Killring (_krContents), krKilled, krPut)
+import qualified Yi.Rope            as R (YiString)
 
 -- * Killring actions
 
diff --git a/src/library/Yi/Keymap/Emacs/Utils.hs b/src/library/Yi/Keymap/Emacs/Utils.hs
--- a/src/library/Yi/Keymap/Emacs/Utils.hs
+++ b/src/library/Yi/Keymap/Emacs/Utils.hs
@@ -1,11 +1,11 @@
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE LambdaCase            #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE OverloadedStrings     #-}
+{-# LANGUAGE ScopedTypeVariables   #-}
+{-# LANGUAGE TypeOperators         #-}
+{-# LANGUAGE UndecidableInstances  #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -50,34 +50,34 @@
   )
 where
 
-import           Control.Applicative
-import           Control.Lens hiding (re,act)
-import           Control.Monad
-import           Control.Monad.Base()
-import           Data.List ((\\))
-import           Data.Maybe (fromMaybe)
-import           Data.Monoid
-import qualified Data.Text as T
-import           System.FilePath (takeDirectory, takeFileName, (</>))
+import           Control.Applicative (Alternative ((<|>), many, some), Applicative (pure), optional, (<$>))
+import           Control.Lens        (use, (.=))
+import           Control.Monad       (filterM, replicateM_, void)
+import           Control.Monad.Base  ()
+import           Data.List           ((\\))
+import           Data.Maybe          (fromMaybe)
+import           Data.Monoid         ((<>))
+import qualified Data.Text           as T (Text, concat, null, pack, singleton, snoc, unpack, unwords)
+import           System.FilePath     (takeDirectory, takeFileName, (</>))
 import           System.FriendlyPath ()
 import           Yi.Buffer
-import           Yi.Command (cabalConfigureE, cabalBuildE, reloadProjectE)
-import           Yi.Core (quitEditor)
+import           Yi.Command          (cabalBuildE, cabalConfigureE, reloadProjectE)
+import           Yi.Core             (quitEditor)
 import           Yi.Editor
-import           Yi.Eval
-import           Yi.File
-import           Yi.Keymap
+import           Yi.Eval             (execEditorAction, getAllNamesInScope)
+import           Yi.File             (deservesSave, editFile, fwriteBufferE, openingNewFile)
+import           Yi.Keymap           (Keymap, KeymapM, YiM, write)
 import           Yi.Keymap.Keys
 import           Yi.MiniBuffer
-import           Yi.Misc (promptFile)
-import           Yi.Monad
-import           Yi.Rectangle
-import           Yi.Regex
-import qualified Yi.Rope as R
+import           Yi.Misc             (promptFile)
+import           Yi.Monad            (gets)
+import           Yi.Rectangle        (getRectangle)
+import           Yi.Regex            (makeSearchOptsM)
+import qualified Yi.Rope             as R (countNewLines, fromText, length, replicateChar, toText, words)
 import           Yi.Search
-import           Yi.String
+import           Yi.String           (showT)
 import           Yi.Tag
-import           Yi.Utils
+import           Yi.Utils            (io)
 
 type UnivArgument = Maybe Int
 
@@ -315,7 +315,7 @@
 
 -- | If on separators (space, tab, unicode seps), reduce multiple
 -- separators to just a single separator (or however many given
--- through 'UniversalArgument').
+-- through 'UnivArgument').
 --
 -- If we aren't looking at a separator, insert a single space. This is
 -- like emacs ‘just-one-space’ but doesn't deal with negative argument
diff --git a/src/library/Yi/Keymap/Keys.hs b/src/library/Yi/Keymap/Keys.hs
--- a/src/library/Yi/Keymap/Keys.hs
+++ b/src/library/Yi/Keymap/Keys.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleContexts  #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
@@ -23,16 +23,15 @@
      pString
     ) where
 
-import Prelude hiding (error)
+import Prelude       hiding (error)
 
 import Control.Monad (unless)
-import Data.Char
-import Data.List (sort, nub)
-
-import Yi.Event
-import Yi.Debug
-import Yi.Keymap
-import Yi.Interact hiding (write)
+import Data.Char     (isAlpha, isPrint, toUpper)
+import Data.List     (nub, sort)
+import Yi.Debug      (error)
+import Yi.Event      (Event (..), Key (..), Modifier (..), eventToChar, prettyEvent)
+import Yi.Interact   hiding (write)
+import Yi.Keymap     (Action, KeymapM, YiAction, write)
 
 printableChar :: (MonadInteract m w Event) => m Char
 printableChar = do
diff --git a/src/library/Yi/Keymap/Vim.hs b/src/library/Yi/Keymap/Vim.hs
--- a/src/library/Yi/Keymap/Vim.hs
+++ b/src/library/Yi/Keymap/Vim.hs
@@ -22,39 +22,39 @@
     , relayoutFromTo
     ) where
 
-import Control.Applicative
-import Data.Char (toUpper)
-import Data.List (find)
-import Data.Monoid
-import Data.Prototype
-import Yi.Buffer.Adjusted hiding (Insert)
+import Control.Applicative                    ((<$>))
+import Data.Char                              (toUpper)
+import Data.List                              (find)
+import Data.Monoid                            (Monoid (mempty), (<>))
+import Data.Prototype                         (Proto (Proto), extractValue)
+import Yi.Buffer.Adjusted                     (commitUpdateTransactionB, startUpdateTransactionB)
 import Yi.Editor
-import Yi.Event
-import Yi.Keymap
-import Yi.Keymap.Keys (anyEvent)
+import Yi.Event                               (Event (..), Key (KASCII), Modifier (MCtrl, MMeta))
+import Yi.Keymap                              (Keymap, KeymapM, KeymapSet, YiM, modelessKeymapSet, write)
+import Yi.Keymap.Keys                         (anyEvent)
 import Yi.Keymap.Vim.Common
-import Yi.Keymap.Vim.Digraph
-import Yi.Keymap.Vim.EventUtils
-import Yi.Keymap.Vim.Ex
-import Yi.Keymap.Vim.ExMap
-import Yi.Keymap.Vim.InsertMap
-import Yi.Keymap.Vim.NormalMap
-import Yi.Keymap.Vim.NormalOperatorPendingMap
-import Yi.Keymap.Vim.Operator
-import Yi.Keymap.Vim.ReplaceMap
-import Yi.Keymap.Vim.ReplaceSingleCharMap
-import Yi.Keymap.Vim.SearchMotionMap
+import Yi.Keymap.Vim.Digraph                  (defDigraphs)
+import Yi.Keymap.Vim.EventUtils               (eventToEventString, parseEvents)
+import Yi.Keymap.Vim.Ex                       (ExCommand, defExCommandParsers)
+import Yi.Keymap.Vim.ExMap                    (defExMap)
+import Yi.Keymap.Vim.InsertMap                (defInsertMap)
+import Yi.Keymap.Vim.NormalMap                (defNormalMap)
+import Yi.Keymap.Vim.NormalOperatorPendingMap (defNormalOperatorPendingMap)
+import Yi.Keymap.Vim.Operator                 (VimOperator (..), defOperators)
+import Yi.Keymap.Vim.ReplaceMap               (defReplaceMap)
+import Yi.Keymap.Vim.ReplaceSingleCharMap     (defReplaceSingleMap)
+import Yi.Keymap.Vim.SearchMotionMap          (defSearchMotionMap)
 import Yi.Keymap.Vim.StateUtils
-import Yi.Keymap.Vim.Utils
-import Yi.Keymap.Vim.VisualMap
+import Yi.Keymap.Vim.Utils                    (selectBinding, selectPureBinding)
+import Yi.Keymap.Vim.VisualMap                (defVisualMap)
 
 data VimConfig = VimConfig {
-    vimKeymap :: Keymap
-  , vimBindings :: [VimBinding]
-  , vimOperators :: [VimOperator]
+    vimKeymap           :: Keymap
+  , vimBindings         :: [VimBinding]
+  , vimOperators        :: [VimOperator]
   , vimExCommandParsers :: [EventString -> Maybe ExCommand]
-  , vimDigraphs :: [(String, Char)]
-  , vimRelayout :: Char -> Char
+  , vimDigraphs         :: [(String, Char)]
+  , vimRelayout         :: Char -> Char
   }
 
 mkKeymapSet :: Proto VimConfig -> KeymapSet
@@ -92,9 +92,6 @@
 -- which contains '.', which needs to eval things
 -- So as a workaround '.' just saves a string that needs eval in VimState
 -- and the actual evaluation happens in impureHandleEvent
---
--- TODO: pass through untouched 'EventString' to 'parseEvents' instead
--- of converting to 'String'.
 pureEval :: VimConfig -> EventString -> EditorM ()
 pureEval config = sequence_ . map (pureHandleEvent config) . parseEvents
 
@@ -155,7 +152,7 @@
             _ -> return ()
 
         performEvalIfNecessary config
-        updateModeIndicatorE prevMode
+        updateModeIndicatorE currentState
 
 performEvalIfNecessary :: VimConfig -> EditorM ()
 performEvalIfNecessary config = do
diff --git a/src/library/Yi/Keymap/Vim/Common.hs b/src/library/Yi/Keymap/Vim/Common.hs
--- a/src/library/Yi/Keymap/Vim/Common.hs
+++ b/src/library/Yi/Keymap/Vim/Common.hs
@@ -1,8 +1,7 @@
-{-# LANGUAGE CPP #-}
+{-# LANGUAGE CPP                #-}
 {-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE DeriveGeneric #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE TemplateHaskell    #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -30,28 +29,26 @@
     , lookupBestMatch, matchesString
     ) where
 
-import           Control.Applicative
-import           Control.Lens
-import           Data.Binary
-#if __GLASGOW_HASKELL__ < 708
-import           Data.DeriveTH
-#else
-import           GHC.Generics (Generic)
-#endif
-import           Data.Default
-import qualified Data.HashMap.Strict as HM
-import           Data.Monoid
-import           Data.String (IsString(..))
-import qualified Data.Text as T
-import qualified Data.Text.Encoding as E
-import           Data.Typeable
-import           Yi.Buffer.Adjusted hiding (Insert)
-import           Yi.Editor
-import           Yi.Keymap
-import           Yi.Keymap.Vim.MatchResult
-import           Yi.Rope (YiString)
-import           Yi.Types (YiVariable)
+import           GHC.Generics              (Generic)
 
+import           Control.Applicative       (Alternative ((<|>)), (<$>))
+import           Control.Lens              (makeLenses)
+import           Data.Binary               (Binary (..))
+import           Data.Default              (Default (..))
+import qualified Data.HashMap.Strict       as HM (HashMap)
+import           Data.Monoid               (Monoid (mappend, mempty), (<>))
+import           Data.String               (IsString (..))
+import qualified Data.Text                 as T (Text, isPrefixOf, pack)
+import qualified Data.Text.Encoding        as E (decodeUtf8, encodeUtf8)
+import           Data.Typeable             (Typeable)
+import           Yi.Buffer.Adjusted        (Direction, Point, RegionStyle)
+import           Yi.Editor                 (EditorM)
+import           Yi.Keymap                 (YiM)
+import           Yi.Keymap.Vim.MatchResult (MatchResult (..))
+import           Yi.Rope                   (YiString)
+import           Yi.Types                  (YiVariable)
+
+
 newtype EventString = Ev { _unEv :: T.Text } deriving (Show, Eq, Ord)
 
 instance IsString EventString where
@@ -96,71 +93,58 @@
 type RegisterName = Char
 type MacroName = Char
 
-data RepeatableAction = RepeatableAction {
-          raPreviousCount :: !Int
-        , raActionString :: !EventString
-    }
-    deriving (Typeable, Eq, Show)
+data RepeatableAction = RepeatableAction
+    { raPreviousCount :: !Int
+    , raActionString  :: !EventString
+    } deriving (Typeable, Eq, Show, Generic)
 
-data Register = Register {
-          regRegionStyle :: RegionStyle
-        , regContent :: YiString
-    }
+data Register = Register
+    { regRegionStyle :: RegionStyle
+    , regContent     :: YiString
+    } deriving (Generic)
 
-data VimMode = Normal
-             | NormalOperatorPending OperatorName
-             | Insert Char -- ^ char denotes how state got into insert mode ('i', 'a', etc.)
-             | Replace
-             | ReplaceSingleChar
-             | InsertNormal -- ^ after C-o
-             | InsertVisual -- ^ after C-o and one of v, V, C-v
-             | Visual RegionStyle
-             | Ex
-             | Search { previousMode :: VimMode, direction :: Direction }
-    deriving (Typeable, Eq, Show)
+data VimMode
+    = Normal
+    | NormalOperatorPending OperatorName
+    | Insert Char -- ^ char denotes how state got into insert mode ('i', 'a', etc.)
+    | Replace
+    | ReplaceSingleChar
+    | InsertNormal -- ^ after C-o
+    | InsertVisual -- ^ after C-o and one of v, V, C-v
+    | Visual RegionStyle
+    | Ex
+    | Search { previousMode :: VimMode, direction :: Direction }
+    deriving (Typeable, Eq, Show, Generic)
 
 data GotoCharCommand = GotoCharCommand !Char !Direction !RegionStyle
+    deriving (Generic)
 
-data VimState = VimState {
-          vsMode :: !VimMode
-        , vsCount :: !(Maybe Int)
-        , vsAccumulator :: !EventString -- ^ for repeat and potentially macros
-        , vsTextObjectAccumulator :: !EventString
-        , vsRegisterMap :: !(HM.HashMap RegisterName Register)
-        , vsActiveRegister :: !RegisterName
-        , vsRepeatableAction :: !(Maybe RepeatableAction)
-        , vsStringToEval :: !EventString -- ^ see Yi.Keymap.Vim.vimEval comment
-        , vsStickyEol :: !Bool -- ^ is set on $, allows j and k walk the right edge of lines
-        , vsOngoingInsertEvents :: !EventString
-        , vsLastGotoCharCommand :: !(Maybe GotoCharCommand)
-        , vsBindingAccumulator :: !EventString
-        , vsSecondaryCursors :: ![Point]
-        , vsPaste :: !Bool -- ^ like vim's :help paste
-        , vsCurrentMacroRecording :: !(Maybe (MacroName, EventString))
-    } deriving (Typeable)
+data VimState = VimState
+    { vsMode                  :: !VimMode
+    , vsCount                 :: !(Maybe Int)
+    , vsAccumulator           :: !EventString -- ^ for repeat and potentially macros
+    , vsTextObjectAccumulator :: !EventString
+    , vsRegisterMap           :: !(HM.HashMap RegisterName Register)
+    , vsActiveRegister        :: !RegisterName
+    , vsRepeatableAction      :: !(Maybe RepeatableAction)
+    , vsStringToEval          :: !EventString -- ^ see Yi.Keymap.Vim.vimEval comment
+    , vsStickyEol             :: !Bool -- ^ is set on $, allows j and k walk the right edge of lines
+    , vsOngoingInsertEvents   :: !EventString
+    , vsLastGotoCharCommand   :: !(Maybe GotoCharCommand)
+    , vsBindingAccumulator    :: !EventString
+    , vsSecondaryCursors      :: ![Point]
+    , vsPaste                 :: !Bool -- ^ like vim's :help paste
+    , vsCurrentMacroRecording :: !(Maybe (MacroName, EventString))
+    } deriving (Typeable, Generic)
 
-#if __GLASGOW_HASKELL__ < 708
-$(derive makeBinary ''RepeatableAction)
-$(derive makeBinary ''Register)
-$(derive makeBinary ''GotoCharCommand)
-#else
-deriving instance Generic RepeatableAction
-deriving instance Generic Register
-deriving instance Generic GotoCharCommand
 instance Binary RepeatableAction
 instance Binary Register
 instance Binary GotoCharCommand
-#endif
 
 instance Default VimMode where
     def = Normal
 
-#if __GLASGOW_HASKELL__ < 708
-$(derive makeBinary ''VimMode)
-#else
-deriving instance Generic VimMode
 instance Binary VimMode
-#endif
 
 instance Default VimState where
     def = VimState
@@ -180,12 +164,7 @@
             False -- :set paste
             Nothing -- current macro recording
 
-#if __GLASGOW_HASKELL__ < 708
-$(derive makeBinary ''VimState)
-#else
-deriving instance Generic VimState
 instance Binary VimState
-#endif
 
 instance YiVariable VimState
 
diff --git a/src/library/Yi/Keymap/Vim/Digraph.hs b/src/library/Yi/Keymap/Vim/Digraph.hs
--- a/src/library/Yi/Keymap/Vim/Digraph.hs
+++ b/src/library/Yi/Keymap/Vim/Digraph.hs
@@ -3,7 +3,7 @@
     , defDigraphs
     ) where
 
-import Control.Applicative
+import Control.Applicative (Alternative ((<|>)))
 
 charFromDigraph :: [(String, Char)] -> Char -> Char -> Maybe Char
 charFromDigraph digraphTable c1 c2 =
diff --git a/src/library/Yi/Keymap/Vim/Eval.hs b/src/library/Yi/Keymap/Vim/Eval.hs
--- a/src/library/Yi/Keymap/Vim/Eval.hs
+++ b/src/library/Yi/Keymap/Vim/Eval.hs
@@ -12,9 +12,9 @@
 
 module Yi.Keymap.Vim.Eval (scheduleActionStringForEval) where
 
-import Yi.Editor
-import Yi.Keymap.Vim.Common
-import Yi.Keymap.Vim.StateUtils
+import Yi.Editor                (EditorM)
+import Yi.Keymap.Vim.Common     (EventString, VimState (vsStringToEval))
+import Yi.Keymap.Vim.StateUtils (modifyStateE)
 
 scheduleActionStringForEval :: EventString -> EditorM ()
 scheduleActionStringForEval s = modifyStateE $ \st -> st { vsStringToEval = s }
diff --git a/src/library/Yi/Keymap/Vim/EventUtils.hs b/src/library/Yi/Keymap/Vim/EventUtils.hs
--- a/src/library/Yi/Keymap/Vim/EventUtils.hs
+++ b/src/library/Yi/Keymap/Vim/EventUtils.hs
@@ -17,16 +17,16 @@
   , splitCountedCommand
   ) where
 
-import           Data.Char (toUpper, isDigit)
-import           Data.List (foldl')
-import qualified Data.Map as M
-import           Data.Monoid
-import qualified Data.Text as T
-import           Data.Tuple (swap)
+import           Data.Char            (isDigit, toUpper)
+import           Data.List            (foldl')
+import qualified Data.Map             as M (Map, fromList, lookup)
+import           Data.Monoid          ((<>))
+import qualified Data.Text            as T (break, cons, null, pack, singleton, snoc, span, unpack)
+import           Data.Tuple           (swap)
 import           Yi.Event
-import           Yi.Keymap.Keys (char, spec, ctrl, meta)
-import           Yi.Keymap.Vim.Common
-import           Yi.String
+import           Yi.Keymap.Keys       (char, ctrl, meta, spec)
+import           Yi.Keymap.Vim.Common (EventString (Ev), RepeatableAction (RepeatableAction))
+import           Yi.String            (showT)
 
 specMap :: M.Map EventString Key
 specMap = M.fromList specList
diff --git a/src/library/Yi/Keymap/Vim/Ex.hs b/src/library/Yi/Keymap/Vim/Ex.hs
--- a/src/library/Yi/Keymap/Vim/Ex.hs
+++ b/src/library/Yi/Keymap/Vim/Ex.hs
@@ -15,30 +15,30 @@
     , defExCommandParsers
     ) where
 
-import           Yi.Keymap.Vim.Common
-import qualified Yi.Keymap.Vim.Ex.Commands.Buffer as Buffer
-import qualified Yi.Keymap.Vim.Ex.Commands.BufferDelete as BufferDelete
-import qualified Yi.Keymap.Vim.Ex.Commands.Buffers as Buffers
-import qualified Yi.Keymap.Vim.Ex.Commands.Cabal as Cabal
-import qualified Yi.Keymap.Vim.Ex.Commands.Delete as Delete
-import qualified Yi.Keymap.Vim.Ex.Commands.Edit as Edit
-import qualified Yi.Keymap.Vim.Ex.Commands.Global as Global
-import qualified Yi.Keymap.Vim.Ex.Commands.GotoLine as GotoLine
-import qualified Yi.Keymap.Vim.Ex.Commands.Help as Help
-import qualified Yi.Keymap.Vim.Ex.Commands.Make as Make
-import qualified Yi.Keymap.Vim.Ex.Commands.Nohl as Nohl
-import qualified Yi.Keymap.Vim.Ex.Commands.Paste as Paste
-import qualified Yi.Keymap.Vim.Ex.Commands.Quit as Quit
-import qualified Yi.Keymap.Vim.Ex.Commands.Reload as Reload
-import qualified Yi.Keymap.Vim.Ex.Commands.Shell as Shell
-import qualified Yi.Keymap.Vim.Ex.Commands.Sort as Sort
-import qualified Yi.Keymap.Vim.Ex.Commands.Substitute as Substitute
-import qualified Yi.Keymap.Vim.Ex.Commands.Tag as Tag
-import qualified Yi.Keymap.Vim.Ex.Commands.Undo as Undo
-import qualified Yi.Keymap.Vim.Ex.Commands.Write as Write
-import qualified Yi.Keymap.Vim.Ex.Commands.Yi as Yi
-import           Yi.Keymap.Vim.Ex.Eval
-import           Yi.Keymap.Vim.Ex.Types
+import           Yi.Keymap.Vim.Common                   (EventString)
+import qualified Yi.Keymap.Vim.Ex.Commands.Buffer       as Buffer (parse)
+import qualified Yi.Keymap.Vim.Ex.Commands.BufferDelete as BufferDelete (parse)
+import qualified Yi.Keymap.Vim.Ex.Commands.Buffers      as Buffers (parse)
+import qualified Yi.Keymap.Vim.Ex.Commands.Cabal        as Cabal (parse)
+import qualified Yi.Keymap.Vim.Ex.Commands.Delete       as Delete (parse)
+import qualified Yi.Keymap.Vim.Ex.Commands.Edit         as Edit (parse)
+import qualified Yi.Keymap.Vim.Ex.Commands.Global       as Global (parse)
+import qualified Yi.Keymap.Vim.Ex.Commands.GotoLine     as GotoLine (parse)
+import qualified Yi.Keymap.Vim.Ex.Commands.Help         as Help (parse)
+import qualified Yi.Keymap.Vim.Ex.Commands.Make         as Make (parse)
+import qualified Yi.Keymap.Vim.Ex.Commands.Nohl         as Nohl (parse)
+import qualified Yi.Keymap.Vim.Ex.Commands.Paste        as Paste (parse)
+import qualified Yi.Keymap.Vim.Ex.Commands.Quit         as Quit (parse)
+import qualified Yi.Keymap.Vim.Ex.Commands.Reload       as Reload (parse)
+import qualified Yi.Keymap.Vim.Ex.Commands.Shell        as Shell (parse)
+import qualified Yi.Keymap.Vim.Ex.Commands.Sort         as Sort (parse)
+import qualified Yi.Keymap.Vim.Ex.Commands.Substitute   as Substitute (parse)
+import qualified Yi.Keymap.Vim.Ex.Commands.Tag          as Tag (parse)
+import qualified Yi.Keymap.Vim.Ex.Commands.Undo         as Undo (parse)
+import qualified Yi.Keymap.Vim.Ex.Commands.Write        as Write (parse)
+import qualified Yi.Keymap.Vim.Ex.Commands.Yi           as Yi (parse)
+import           Yi.Keymap.Vim.Ex.Eval                  (exEvalE, exEvalY)
+import           Yi.Keymap.Vim.Ex.Types                 (ExCommand (..), evStringToExCommand)
 
 defExCommandParsers :: [EventString -> Maybe ExCommand]
 defExCommandParsers =
diff --git a/src/library/Yi/Keymap/Vim/Ex/Commands/Buffer.hs b/src/library/Yi/Keymap/Vim/Ex/Commands/Buffer.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Commands/Buffer.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Commands/Buffer.hs
@@ -12,18 +12,21 @@
 
 module Yi.Keymap.Vim.Ex.Commands.Buffer (parse) where
 
-import           Control.Applicative
-import           Control.Monad
-import           Control.Monad.State
-import qualified Data.Text as T
-import qualified Text.ParserCombinators.Parsec as P
-import           Yi.Buffer.Basic
-import           Yi.Buffer.Misc
+import           Control.Applicative              (Alternative ((<|>)), Applicative ((*>)), (<$>))
+import           Control.Monad                    (void)
+import           Control.Monad.State              (gets)
+import qualified Data.Text                        as T (pack)
+import qualified Text.ParserCombinators.Parsec    as P (GenParser, anyChar,
+                                                        digit, eof, many, many1,
+                                                        parse, space, string,
+                                                        try)
+import           Yi.Buffer.Basic                  (BufferRef (..))
+import           Yi.Buffer.Misc                   (bkey, isUnchangedBuffer)
 import           Yi.Editor
-import           Yi.Keymap
-import           Yi.Keymap.Vim.Common
-import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common
-import           Yi.Keymap.Vim.Ex.Types
+import           Yi.Keymap                        (Action (EditorA))
+import           Yi.Keymap.Vim.Common             (EventString)
+import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common (errorNoWrite, parseWithBangAndCount, pureExCommand)
+import           Yi.Keymap.Vim.Ex.Types           (ExCommand (cmdAction, cmdShow))
 
 parse :: EventString -> Maybe ExCommand
 parse = Common.parseWithBangAndCount nameParser $ \ _ bang mcount -> do
diff --git a/src/library/Yi/Keymap/Vim/Ex/Commands/BufferDelete.hs b/src/library/Yi/Keymap/Vim/Ex/Commands/BufferDelete.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Commands/BufferDelete.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Commands/BufferDelete.hs
@@ -10,15 +10,15 @@
 
 module Yi.Keymap.Vim.Ex.Commands.BufferDelete (parse) where
 
-import           Control.Applicative
-import           Control.Monad
-import           Data.Text ()
-import qualified Text.ParserCombinators.Parsec as P
-import           Yi.Editor
-import           Yi.Keymap
-import           Yi.Keymap.Vim.Common
-import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common
-import           Yi.Keymap.Vim.Ex.Types
+import           Control.Applicative              (Alternative ((<|>)))
+import           Control.Monad                    (void)
+import           Data.Text                        ()
+import qualified Text.ParserCombinators.Parsec    as P (string, try)
+import           Yi.Editor                        (closeBufferAndWindowE)
+import           Yi.Keymap                        (Action (EditorA))
+import           Yi.Keymap.Vim.Common             (EventString)
+import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common (parse, pureExCommand)
+import           Yi.Keymap.Vim.Ex.Types           (ExCommand (cmdAction, cmdShow))
 
 parse :: EventString -> Maybe ExCommand
 parse = Common.parse $ do
diff --git a/src/library/Yi/Keymap/Vim/Ex/Commands/Buffers.hs b/src/library/Yi/Keymap/Vim/Ex/Commands/Buffers.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Commands/Buffers.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Commands/Buffers.hs
@@ -11,21 +11,21 @@
 -- :buffers or :ls ex command to list buffers.
 module Yi.Keymap.Vim.Ex.Commands.Buffers (parse) where
 
-import           Control.Applicative
-import           Control.Lens
-import           Control.Monad
-import qualified Data.Map as M
-import qualified Data.Text as T
-import qualified Text.ParserCombinators.Parsec as P
-import           Yi.Buffer.Basic
-import           Yi.Buffer.Misc
+import           Control.Applicative              (Alternative ((<|>)))
+import           Control.Lens                     (view)
+import           Control.Monad                    (void)
+import qualified Data.Map                         as M (elems, mapWithKey)
+import qualified Data.Text                        as T (intercalate, pack, unlines)
+import qualified Text.ParserCombinators.Parsec    as P (string, try)
+import           Yi.Buffer.Basic                  (BufferRef (BufferRef))
+import           Yi.Buffer.Misc                   (BufferId (MemBuffer), identA)
 import           Yi.Editor
-import           Yi.Keymap
-import           Yi.Keymap.Vim.Common
-import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common
-import           Yi.Keymap.Vim.Ex.Types
-import           Yi.Monad
-import           Yi.Rope (fromText)
+import           Yi.Keymap                        (Action (EditorA))
+import           Yi.Keymap.Vim.Common             (EventString)
+import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common (parse, pureExCommand)
+import           Yi.Keymap.Vim.Ex.Types           (ExCommand (cmdAction, cmdShow))
+import           Yi.Monad                         (gets)
+import           Yi.Rope                          (fromText)
 
 parse :: EventString -> Maybe ExCommand
 parse = Common.parse $ do
diff --git a/src/library/Yi/Keymap/Vim/Ex/Commands/Cabal.hs b/src/library/Yi/Keymap/Vim/Ex/Commands/Cabal.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Commands/Cabal.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Commands/Cabal.hs
@@ -9,16 +9,16 @@
 
 module Yi.Keymap.Vim.Ex.Commands.Cabal (parse) where
 
-import           Control.Applicative
-import           Control.Monad
-import qualified Data.Text as T
-import qualified Text.ParserCombinators.Parsec as P
-import           Yi.Command
-import           Yi.Keymap
-import           Yi.Keymap.Vim.Common
-import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common
-import           Yi.Keymap.Vim.Ex.Types
-import           Yi.MiniBuffer
+import           Control.Applicative              (Alternative ((<|>)))
+import           Control.Monad                    (void)
+import qualified Data.Text                        as T (pack)
+import qualified Text.ParserCombinators.Parsec    as P (string, try)
+import           Yi.Command                       (cabalBuildE)
+import           Yi.Keymap                        (Action (YiA))
+import           Yi.Keymap.Vim.Common             (EventString)
+import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common (commandArgs, impureExCommand, parse)
+import           Yi.Keymap.Vim.Ex.Types           (ExCommand (cmdAction, cmdShow))
+import           Yi.MiniBuffer                    (CommandArguments (CommandArguments))
 
 -- TODO: Either hack Text into these parsec parsers or use Attoparsec.
 -- Attoparsec is faster anyway and backtracks by default so we may
diff --git a/src/library/Yi/Keymap/Vim/Ex/Commands/Common.hs b/src/library/Yi/Keymap/Vim/Ex/Commands/Common.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Commands/Common.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Commands/Common.hs
@@ -1,5 +1,5 @@
-{-# LANGUAGE LambdaCase #-}
-{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE LambdaCase          #-}
+{-# LANGUAGE OverloadedStrings   #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
@@ -30,25 +30,30 @@
     , needsSaving
     ) where
 
-import           Control.Applicative
-import           Control.Lens (use)
-import           Control.Monad
-import           Data.List.NonEmpty (NonEmpty(..))
-import           Data.Monoid
-import qualified Data.Text as T
-import           System.Directory
-import qualified Text.ParserCombinators.Parsec as P
-import           Text.Read (readMaybe)
+import           Control.Applicative           (Alternative ((<|>)), Applicative ((*>), (<*)), (<$>))
+import           Control.Lens                  (use)
+import           Control.Monad                 (void, (>=>))
+import           Data.List.NonEmpty            (NonEmpty (..))
+import           Data.Monoid                   (Monoid (mconcat), (<>))
+import qualified Data.Text                     as T (Text, concat, cons, drop,
+                                                     isPrefixOf, length, pack,
+                                                     singleton, snoc, unpack)
+import           System.Directory              (getCurrentDirectory)
+import qualified Text.ParserCombinators.Parsec as P (GenParser, anyChar, char,
+                                                     digit, many, many1, noneOf,
+                                                     oneOf, optionMaybe, parse,
+                                                     space, string)
+import           Text.Read                     (readMaybe)
 import           Yi.Buffer
 import           Yi.Editor
-import           Yi.File
-import           Yi.Keymap
-import           Yi.Keymap.Vim.Common
-import           Yi.Keymap.Vim.Ex.Types
-import           Yi.Misc
-import           Yi.Monad
-import           Yi.Style (errorStyle)
-import           Yi.Utils
+import           Yi.File                       (deservesSave)
+import           Yi.Keymap                     (Action, YiM, readEditor)
+import           Yi.Keymap.Vim.Common          (EventString (Ev))
+import           Yi.Keymap.Vim.Ex.Types        (ExCommand (..))
+import           Yi.Misc                       (matchingFileNames)
+import           Yi.Monad                      (gets)
+import           Yi.Style                      (errorStyle)
+import           Yi.Utils                      (io)
 
 parse :: P.GenParser Char () ExCommand -> EventString -> Maybe ExCommand
 parse parser (Ev s) =
diff --git a/src/library/Yi/Keymap/Vim/Ex/Commands/Delete.hs b/src/library/Yi/Keymap/Vim/Ex/Commands/Delete.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Commands/Delete.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Commands/Delete.hs
@@ -10,15 +10,15 @@
 
 module Yi.Keymap.Vim.Ex.Commands.Delete (parse) where
 
-import           Control.Applicative
-import           Control.Monad
-import           Data.Text ()
-import qualified Text.ParserCombinators.Parsec as P
-import           Yi.Buffer.Adjusted hiding (Delete)
-import           Yi.Keymap
-import           Yi.Keymap.Vim.Common
-import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common
-import           Yi.Keymap.Vim.Ex.Types
+import           Control.Applicative              (Alternative ((<|>)))
+import           Control.Monad                    (void)
+import           Data.Text                        ()
+import qualified Text.ParserCombinators.Parsec    as P (string, try)
+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           Yi.Keymap.Vim.Ex.Types           (ExCommand (cmdAction, cmdShow))
 
 parse :: EventString -> Maybe ExCommand
 parse = Common.parse $ do
diff --git a/src/library/Yi/Keymap/Vim/Ex/Commands/Edit.hs b/src/library/Yi/Keymap/Vim/Ex/Commands/Edit.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Commands/Edit.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Commands/Edit.hs
@@ -12,16 +12,16 @@
 
 module Yi.Keymap.Vim.Ex.Commands.Edit (parse) where
 
-import           Control.Applicative
-import           Control.Monad
-import qualified Data.Text as T
-import qualified Text.ParserCombinators.Parsec as P
-import           Yi.Editor
-import           Yi.File
-import           Yi.Keymap
-import           Yi.Keymap.Vim.Common
-import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common
-import           Yi.Keymap.Vim.Ex.Types
+import           Control.Applicative              (Alternative ((<|>)), (<$>))
+import           Control.Monad                    (void, when)
+import qualified Data.Text                        as T (Text, append, pack, unpack)
+import qualified Text.ParserCombinators.Parsec    as P (anyChar, many, many1, space, string, try)
+import           Yi.Editor                        (MonadEditor (withEditor), newTabE)
+import           Yi.File                          (openNewFile)
+import           Yi.Keymap                        (Action (YiA))
+import           Yi.Keymap.Vim.Common             (EventString)
+import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common (filenameComplete, impureExCommand, parse)
+import           Yi.Keymap.Vim.Ex.Types           (ExCommand (cmdAction, cmdComplete, cmdShow))
 
 parse :: EventString -> Maybe ExCommand
 parse = Common.parse $ do
diff --git a/src/library/Yi/Keymap/Vim/Ex/Commands/Global.hs b/src/library/Yi/Keymap/Vim/Ex/Commands/Global.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Commands/Global.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Commands/Global.hs
@@ -10,22 +10,22 @@
 
 module Yi.Keymap.Vim.Ex.Commands.Global (parse) where
 
-import           Control.Applicative
-import           Control.Lens
-import           Control.Monad
-import           Data.Monoid
-import qualified Data.Text as T
-import qualified Text.ParserCombinators.Parsec as P
+import           Control.Applicative                  (Alternative ((<|>)), (<$>))
+import           Control.Lens                         (use)
+import           Control.Monad                        (forM_, void, when)
+import           Data.Monoid                          ((<>))
+import qualified Data.Text                            as T (Text, isInfixOf, pack, snoc)
+import qualified Text.ParserCombinators.Parsec        as P (anyChar, char, many, noneOf, string, try)
 import           Yi.Buffer.Adjusted
-import           Yi.Editor
-import           Yi.Keymap
-import           Yi.Keymap.Vim.Common
-import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common
-import qualified Yi.Keymap.Vim.Ex.Commands.Delete as Delete
-import qualified Yi.Keymap.Vim.Ex.Commands.Substitute as Substitute
-import           Yi.Keymap.Vim.Ex.Types
-import qualified Yi.Rope as R
-import           Yi.String (showT)
+import           Yi.Editor                            (withCurrentBuffer)
+import           Yi.Keymap                            (Action (BufferA, EditorA))
+import           Yi.Keymap.Vim.Common                 (EventString (Ev))
+import qualified Yi.Keymap.Vim.Ex.Commands.Common     as Common (parse, pureExCommand)
+import qualified Yi.Keymap.Vim.Ex.Commands.Delete     as Delete (parse)
+import qualified Yi.Keymap.Vim.Ex.Commands.Substitute as Substitute (parse)
+import           Yi.Keymap.Vim.Ex.Types               (ExCommand (cmdAction, cmdShow), evStringToExCommand)
+import qualified Yi.Rope                              as R (toText)
+import           Yi.String                            (showT)
 
 parse :: EventString -> Maybe ExCommand
 parse = Common.parse $ do
diff --git a/src/library/Yi/Keymap/Vim/Ex/Commands/GotoLine.hs b/src/library/Yi/Keymap/Vim/Ex/Commands/GotoLine.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Commands/GotoLine.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Commands/GotoLine.hs
@@ -9,13 +9,13 @@
 
 module Yi.Keymap.Vim.Ex.Commands.GotoLine (parse) where
 
-import           Data.Char (isDigit)
-import qualified Data.Text as T
-import           Yi.Buffer.Adjusted
-import           Yi.Keymap
-import           Yi.Keymap.Vim.Common
+import           Data.Char                        (isDigit)
+import qualified Data.Text                        as T (all, null, unpack)
+import           Yi.Buffer.Adjusted               (firstNonSpaceB, gotoLn)
+import           Yi.Keymap                        (Action (BufferA))
+import           Yi.Keymap.Vim.Common             (EventString (Ev))
 import           Yi.Keymap.Vim.Ex.Commands.Common (pureExCommand)
-import           Yi.Keymap.Vim.Ex.Types
+import           Yi.Keymap.Vim.Ex.Types           (ExCommand (cmdAction, cmdShow))
 
 parse :: EventString -> Maybe ExCommand
 parse (Ev s) = if not (T.null s) && T.all isDigit s
diff --git a/src/library/Yi/Keymap/Vim/Ex/Commands/Help.hs b/src/library/Yi/Keymap/Vim/Ex/Commands/Help.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Commands/Help.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Commands/Help.hs
@@ -11,15 +11,15 @@
 
 module Yi.Keymap.Vim.Ex.Commands.Help (parse) where
 
-import           Control.Monad
-import           Control.Applicative
-import           Yi.Command.Help (displayHelpFor)
-import qualified Data.Text as T
-import qualified Text.ParserCombinators.Parsec as P
-import           Yi.Keymap
-import           Yi.Keymap.Vim.Common
-import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common
-import           Yi.Keymap.Vim.Ex.Types
+import           Control.Applicative              ((<$>))
+import           Control.Monad                    (void)
+import qualified Data.Text                        as T (append, pack)
+import qualified Text.ParserCombinators.Parsec    as P (anyChar, many1, option, space, string, try)
+import           Yi.Command.Help                  (displayHelpFor)
+import           Yi.Keymap                        (Action (YiA))
+import           Yi.Keymap.Vim.Common             (EventString)
+import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common (impureExCommand, parse)
+import           Yi.Keymap.Vim.Ex.Types           (ExCommand (cmdAction, cmdShow))
 
 parse :: EventString -> Maybe ExCommand
 parse = Common.parse $ do
diff --git a/src/library/Yi/Keymap/Vim/Ex/Commands/Make.hs b/src/library/Yi/Keymap/Vim/Ex/Commands/Make.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Commands/Make.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Commands/Make.hs
@@ -9,15 +9,15 @@
 
 module Yi.Keymap.Vim.Ex.Commands.Make (parse) where
 
-import           Control.Applicative
-import qualified Data.Text as T
-import qualified Text.ParserCombinators.Parsec as P
-import           Yi.Command
-import           Yi.Keymap
-import           Yi.Keymap.Vim.Common
-import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common
-import           Yi.Keymap.Vim.Ex.Types
-import           Yi.MiniBuffer
+import           Control.Applicative              (Applicative ((*>)))
+import qualified Data.Text                        as T (pack)
+import qualified Text.ParserCombinators.Parsec    as P (string)
+import           Yi.Command                       (makeBuildE)
+import           Yi.Keymap                        (Action (YiA))
+import           Yi.Keymap.Vim.Common             (EventString)
+import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common (commandArgs, impureExCommand, parse)
+import           Yi.Keymap.Vim.Ex.Types           (ExCommand (cmdAction, cmdShow))
+import           Yi.MiniBuffer                    (CommandArguments (CommandArguments))
 
 parse :: EventString -> Maybe ExCommand
 parse = Common.parse $ do
diff --git a/src/library/Yi/Keymap/Vim/Ex/Commands/Nohl.hs b/src/library/Yi/Keymap/Vim/Ex/Commands/Nohl.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Commands/Nohl.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Commands/Nohl.hs
@@ -10,12 +10,12 @@
 
 module Yi.Keymap.Vim.Ex.Commands.Nohl (parse) where
 
-import Data.Text ()
-import Yi.Keymap
-import Yi.Keymap.Vim.Common
-import Yi.Keymap.Vim.Ex.Commands.Common (pureExCommand)
-import Yi.Keymap.Vim.Ex.Types
-import Yi.Search
+import           Data.Text                        ()
+import           Yi.Keymap                        (Action (EditorA))
+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"
diff --git a/src/library/Yi/Keymap/Vim/Ex/Commands/Paste.hs b/src/library/Yi/Keymap/Vim/Ex/Commands/Paste.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Commands/Paste.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Commands/Paste.hs
@@ -12,15 +12,15 @@
 
 module Yi.Keymap.Vim.Ex.Commands.Paste (parse) where
 
-import Control.Applicative
-import Data.Monoid
-import Yi.Editor
-import Yi.Keymap
-import Yi.Keymap.Vim.Common
-import Yi.Keymap.Vim.Ex.Commands.Common hiding (parse)
-import Yi.Keymap.Vim.Ex.Types
-import Yi.Keymap.Vim.StateUtils
-import Yi.String (showT)
+import           Control.Applicative              ((<$>))
+import           Data.Monoid                      ((<>))
+import           Yi.Editor                        (getEditorDyn, printMsg)
+import           Yi.Keymap                        (Action (EditorA))
+import           Yi.Keymap.Vim.Common             (EventString, VimState (vsPaste))
+import           Yi.Keymap.Vim.Ex.Commands.Common (BoolOptionAction (..), parseBoolOption)
+import           Yi.Keymap.Vim.Ex.Types           (ExCommand)
+import           Yi.Keymap.Vim.StateUtils         (modifyStateE)
+import           Yi.String                        (showT)
 
 parse :: EventString -> Maybe ExCommand
 parse = parseBoolOption "paste" action
diff --git a/src/library/Yi/Keymap/Vim/Ex/Commands/Quit.hs b/src/library/Yi/Keymap/Vim/Ex/Commands/Quit.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Commands/Quit.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Commands/Quit.hs
@@ -1,6 +1,6 @@
-{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE LambdaCase        #-}
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE TupleSections #-}
+{-# LANGUAGE TupleSections     #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -14,25 +14,25 @@
 
 module Yi.Keymap.Vim.Ex.Commands.Quit (parse) where
 
-import           Control.Applicative
-import           Control.Lens
-import           Control.Monad
-import           Data.Foldable (find)
-import qualified Data.List.PointedList.Circular as PL
-import           Data.Monoid
-import qualified Data.Text as T
-import qualified Text.ParserCombinators.Parsec as P
-import           Yi.Buffer
-import           Yi.Core (quitEditor, errorEditor, closeWindow)
+import           Control.Applicative              (Alternative ((<|>)), (<$>))
+import           Control.Lens                     (use, uses)
+import           Control.Monad                    (void, when)
+import           Data.Foldable                    (find)
+import qualified Data.List.PointedList.Circular   as PL (length)
+import           Data.Monoid                      ((<>))
+import qualified Data.Text                        as T (append)
+import qualified Text.ParserCombinators.Parsec    as P (char, choice, many, string, try)
+import           Yi.Buffer                        (bkey, file)
+import           Yi.Core                          (closeWindow, errorEditor, quitEditor)
 import           Yi.Editor
-import           Yi.File
-import           Yi.Keymap
-import           Yi.Keymap.Vim.Common
-import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common
-import           Yi.Keymap.Vim.Ex.Types
-import           Yi.Monad
-import           Yi.String (showT)
-import           Yi.Window (bufkey)
+import           Yi.File                          (deservesSave, fwriteAllY, viWrite)
+import           Yi.Keymap                        (Action (YiA), YiM, readEditor)
+import           Yi.Keymap.Vim.Common             (EventString)
+import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common (impureExCommand, needsSaving, parse)
+import           Yi.Keymap.Vim.Ex.Types           (ExCommand (cmdAction, cmdShow))
+import           Yi.Monad                         (gets)
+import           Yi.String                        (showT)
+import           Yi.Window                        (bufkey)
 
 
 parse :: EventString -> Maybe ExCommand
diff --git a/src/library/Yi/Keymap/Vim/Ex/Commands/Reload.hs b/src/library/Yi/Keymap/Vim/Ex/Commands/Reload.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Commands/Reload.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Commands/Reload.hs
@@ -10,12 +10,12 @@
 
 module Yi.Keymap.Vim.Ex.Commands.Reload (parse) where
 
-import Data.Text ()
-import Yi.Boot.Internal (reload)
-import Yi.Keymap
-import Yi.Keymap.Vim.Common
+import Data.Text                        ()
+import Yi.Boot.Internal                 (reload)
+import Yi.Keymap                        (Action (YiA))
+import Yi.Keymap.Vim.Common             (EventString)
 import Yi.Keymap.Vim.Ex.Commands.Common (impureExCommand)
-import Yi.Keymap.Vim.Ex.Types
+import Yi.Keymap.Vim.Ex.Types           (ExCommand (cmdAction, cmdShow))
 
 parse :: EventString -> Maybe ExCommand
 parse "reload" = Just $ impureExCommand {
diff --git a/src/library/Yi/Keymap/Vim/Ex/Commands/Shell.hs b/src/library/Yi/Keymap/Vim/Ex/Commands/Shell.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Commands/Shell.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Commands/Shell.hs
@@ -9,15 +9,15 @@
 
 module Yi.Keymap.Vim.Ex.Commands.Shell (parse) where
 
-import           Control.Applicative
-import           Control.Monad
-import qualified Data.Text as T
-import qualified Text.ParserCombinators.Parsec as P
-import           Yi.Command
-import           Yi.Keymap
-import           Yi.Keymap.Vim.Common
-import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common
-import           Yi.Keymap.Vim.Ex.Types
+import           Control.Applicative              ((<$>))
+import           Control.Monad                    (void)
+import qualified Data.Text                        as T (pack)
+import qualified Text.ParserCombinators.Parsec    as P (char, many1, noneOf)
+import           Yi.Command                       (buildRun)
+import           Yi.Keymap                        (Action (YiA))
+import           Yi.Keymap.Vim.Common             (EventString)
+import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common (commandArgs, impureExCommand, parse)
+import           Yi.Keymap.Vim.Ex.Types           (ExCommand (cmdAction, cmdShow))
 
 parse :: EventString -> Maybe ExCommand
 parse = Common.parse $ do
diff --git a/src/library/Yi/Keymap/Vim/Ex/Commands/Sort.hs b/src/library/Yi/Keymap/Vim/Ex/Commands/Sort.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Commands/Sort.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Commands/Sort.hs
@@ -10,13 +10,13 @@
 
 module Yi.Keymap.Vim.Ex.Commands.Sort (parse) where
 
-import           Control.Monad
-import qualified Text.ParserCombinators.Parsec as P
+import           Control.Monad                    (void)
+import qualified Text.ParserCombinators.Parsec    as P (string)
 import           Yi.Buffer
-import           Yi.Keymap
-import           Yi.Keymap.Vim.Common
-import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common
-import           Yi.Keymap.Vim.Ex.Types
+import           Yi.Keymap                        (Action (BufferA))
+import           Yi.Keymap.Vim.Common             (EventString)
+import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common (parse, parseRange, pureExCommand)
+import           Yi.Keymap.Vim.Ex.Types           (ExCommand (cmdAction, cmdComplete, cmdShow))
 
 parse :: EventString -> Maybe ExCommand
 parse = Common.parse $ do
diff --git a/src/library/Yi/Keymap/Vim/Ex/Commands/Substitute.hs b/src/library/Yi/Keymap/Vim/Ex/Commands/Substitute.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Commands/Substitute.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Commands/Substitute.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE LambdaCase        #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
@@ -11,20 +11,21 @@
 
 module Yi.Keymap.Vim.Ex.Commands.Substitute (parse) where
 
-import           Control.Applicative
-import           Control.Monad
-import           Data.Monoid
-import qualified Data.Text as T
-import qualified Text.ParserCombinators.Parsec as P
-import           Yi.Buffer.Adjusted hiding (Delete)
-import           Yi.Editor
-import           Yi.MiniBuffer
-import           Yi.Keymap
-import           Yi.Keymap.Keys
-import           Yi.Keymap.Vim.Common
-import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common
-import           Yi.Keymap.Vim.Ex.Types
-import qualified Yi.Rope as R
+import           Control.Applicative              (Alternative ((<|>)), (<$>))
+import           Control.Monad                    (void)
+import           Data.Monoid                      ((<>))
+import qualified Data.Text                        as T (cons, snoc)
+import qualified Text.ParserCombinators.Parsec    as P (char, many, noneOf, oneOf, string, try)
+import           Yi.Buffer.Adjusted
+import           Yi.Editor                        (EditorM, closeBufferAndWindowE, printMsg, withCurrentBuffer)
+import           Yi.Keymap                        (Action (EditorA), Keymap)
+import           Yi.Keymap.Keys                   (char, choice, (?>>!))
+import           Yi.Keymap.Vim.Common             (EventString)
+import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common (parse, pureExCommand)
+import           Yi.Keymap.Vim.Ex.Types           (ExCommand (cmdAction, cmdShow))
+import           Yi.MiniBuffer                    (spawnMinibufferE)
+import           Yi.Regex                         (makeSearchOptsM)
+import qualified Yi.Rope                          as R (YiString, fromString, length, null, toText, toString)
 import           Yi.Search
 
 parse :: EventString -> Maybe ExCommand
@@ -54,9 +55,11 @@
               <>       (if caseInsensitive then "i" else "")
               <>       (if global then "g" else "")
   , cmdAction = EditorA $ do
+        let opts = QuoteRegex : if caseInsensitive then [IgnoreCase] else []
         regex <- if R.null from
                     then getRegexE
-                    else return . Just . makeSimpleSearch $ from
+                    else return . (either (const Nothing) Just) 
+                            . makeSearchOptsM opts . R.toString $ from
         case regex of
             Nothing -> printMsg "No previous search pattern"
             Just regex' -> if confirm
diff --git a/src/library/Yi/Keymap/Vim/Ex/Commands/Tag.hs b/src/library/Yi/Keymap/Vim/Ex/Commands/Tag.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Commands/Tag.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Commands/Tag.hs
@@ -10,17 +10,19 @@
 
 module Yi.Keymap.Vim.Ex.Commands.Tag (parse) where
 
-import           Control.Applicative
-import           Control.Monad
-import           Data.Monoid
-import qualified Data.Text as T
-import qualified Text.ParserCombinators.Parsec as P
-import           Yi.Keymap
-import           Yi.Keymap.Vim.Common
-import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common
-import           Yi.Keymap.Vim.Ex.Types
-import           Yi.Keymap.Vim.Tag
-import           Yi.Tag
+import           Control.Applicative              (Alternative ((<|>)), (<$>))
+import           Control.Monad                    (void)
+import           Data.Monoid                      ((<>))
+import qualified Data.Text                        as T (pack)
+import qualified Text.ParserCombinators.Parsec    as P (GenParser, anyChar, eof,
+                                                        many1, optionMaybe,
+                                                        space, string)
+import           Yi.Keymap                        (Action (YiA))
+import           Yi.Keymap.Vim.Common             (EventString)
+import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common (impureExCommand, parse)
+import           Yi.Keymap.Vim.Ex.Types           (ExCommand (cmdAction, cmdComplete, cmdShow))
+import           Yi.Keymap.Vim.Tag                (completeVimTag, gotoTag, nextTag, unpopTag)
+import           Yi.Tag                           (Tag (Tag))
 
 parse :: EventString -> Maybe ExCommand
 parse = Common.parse $ do
diff --git a/src/library/Yi/Keymap/Vim/Ex/Commands/Undo.hs b/src/library/Yi/Keymap/Vim/Ex/Commands/Undo.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Commands/Undo.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Commands/Undo.hs
@@ -10,11 +10,11 @@
 
 module Yi.Keymap.Vim.Ex.Commands.Undo (parse) where
 
-import           Yi.Buffer.Adjusted
-import           Yi.Keymap
-import           Yi.Keymap.Vim.Common
+import           Yi.Buffer.Adjusted               (redoB, undoB)
+import           Yi.Keymap                        (Action (BufferA))
+import           Yi.Keymap.Vim.Common             (EventString (Ev))
 import           Yi.Keymap.Vim.Ex.Commands.Common (pureExCommand)
-import           Yi.Keymap.Vim.Ex.Types
+import           Yi.Keymap.Vim.Ex.Types           (ExCommand (cmdAction, cmdComplete, cmdShow))
 
 parse :: EventString -> Maybe ExCommand
 parse (Ev s) | s `elem` ["u", "undo"] =  
diff --git a/src/library/Yi/Keymap/Vim/Ex/Commands/Write.hs b/src/library/Yi/Keymap/Vim/Ex/Commands/Write.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Commands/Write.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Commands/Write.hs
@@ -10,18 +10,18 @@
 
 module Yi.Keymap.Vim.Ex.Commands.Write (parse) where
 
-import           Control.Applicative
-import           Control.Monad
-import           Data.Monoid
-import qualified Data.Text as T
-import qualified Text.ParserCombinators.Parsec as P
-import           Yi.Buffer
-import           Yi.Editor
-import           Yi.File
-import           Yi.Keymap
-import           Yi.Keymap.Vim.Common
-import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common
-import           Yi.Keymap.Vim.Ex.Types
+import           Control.Applicative              (Alternative ((<|>)), Applicative ((*>)), (<$>))
+import           Control.Monad                    (void, when)
+import           Data.Monoid                      ((<>))
+import qualified Data.Text                        as T (Text, pack)
+import qualified Text.ParserCombinators.Parsec    as P (anyChar, many, many1, space, string, try)
+import           Yi.Buffer                        (BufferRef)
+import           Yi.Editor                        (printMsg)
+import           Yi.File                          (fwriteBufferE, viWrite, viWriteTo)
+import           Yi.Keymap                        (Action (YiA), YiM)
+import           Yi.Keymap.Vim.Common             (EventString)
+import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common (forAllBuffers, impureExCommand, needsSaving, parse)
+import           Yi.Keymap.Vim.Ex.Types           (ExCommand (cmdAction, cmdShow))
 
 parse :: EventString -> Maybe ExCommand
 parse = Common.parse $
diff --git a/src/library/Yi/Keymap/Vim/Ex/Commands/Yi.hs b/src/library/Yi/Keymap/Vim/Ex/Commands/Yi.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Commands/Yi.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Commands/Yi.hs
@@ -10,14 +10,14 @@
 
 module Yi.Keymap.Vim.Ex.Commands.Yi (parse) where
 
-import           Control.Monad
-import qualified Data.Text as T
-import qualified Text.ParserCombinators.Parsec as P
-import           Yi.Eval (execEditorAction)
-import           Yi.Keymap
-import           Yi.Keymap.Vim.Common
-import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common
-import           Yi.Keymap.Vim.Ex.Types
+import           Control.Monad                    (void)
+import qualified Data.Text                        as T (pack)
+import qualified Text.ParserCombinators.Parsec    as P (anyChar, many1, space, string)
+import           Yi.Eval                          (execEditorAction)
+import           Yi.Keymap                        (Action (YiA))
+import           Yi.Keymap.Vim.Common             (EventString)
+import qualified Yi.Keymap.Vim.Ex.Commands.Common as Common (impureExCommand, parse)
+import           Yi.Keymap.Vim.Ex.Types           (ExCommand (cmdAction, cmdShow))
 
 parse :: EventString -> Maybe ExCommand
 parse = Common.parse $ do
diff --git a/src/library/Yi/Keymap/Vim/Ex/Eval.hs b/src/library/Yi/Keymap/Vim/Ex/Eval.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Eval.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Eval.hs
@@ -13,13 +13,13 @@
     , exEvalY
     ) where
 
-import           Control.Monad
-import           Data.Monoid
-import qualified Data.Text as T
-import           Yi.Editor
-import           Yi.Keymap
-import           Yi.Keymap.Vim.Common
-import           Yi.Keymap.Vim.Ex.Types
+import           Control.Monad          (void)
+import           Data.Monoid            ((<>))
+import qualified Data.Text              as T (unpack)
+import           Yi.Editor              (EditorM, MonadEditor (withEditor), withCurrentBuffer)
+import           Yi.Keymap              (Action (BufferA, EditorA, YiA), YiM)
+import           Yi.Keymap.Vim.Common   (EventString (_unEv))
+import           Yi.Keymap.Vim.Ex.Types (ExCommand (cmdAction), evStringToExCommand)
 
 exEvalE :: [EventString -> Maybe ExCommand] -> EventString -> EditorM ()
 exEvalE cmds cmdString = evalHelper id (const $ error msg) cmds cmdString
diff --git a/src/library/Yi/Keymap/Vim/Ex/Types.hs b/src/library/Yi/Keymap/Vim/Ex/Types.hs
--- a/src/library/Yi/Keymap/Vim/Ex/Types.hs
+++ b/src/library/Yi/Keymap/Vim/Ex/Types.hs
@@ -9,10 +9,10 @@
 
 module Yi.Keymap.Vim.Ex.Types where
 
-import Data.Maybe
-import Data.Text (Text, unpack)
-import Yi.Keymap
-import Yi.Keymap.Vim.Common
+import Data.Maybe           (listToMaybe, mapMaybe)
+import Data.Text            (Text, unpack)
+import Yi.Keymap            (Action, YiM)
+import Yi.Keymap.Vim.Common (EventString)
 
 data ExCommand = ExCommand {
     cmdComplete :: YiM [Text]
diff --git a/src/library/Yi/Keymap/Vim/ExMap.hs b/src/library/Yi/Keymap/Vim/ExMap.hs
--- a/src/library/Yi/Keymap/Vim/ExMap.hs
+++ b/src/library/Yi/Keymap/Vim/ExMap.hs
@@ -12,23 +12,23 @@
 
 module Yi.Keymap.Vim.ExMap (defExMap) where
 
-import           Control.Applicative
-import           Control.Monad (when)
-import           Data.Char (isSpace)
-import           Data.Maybe (fromJust)
-import           Data.Monoid
-import qualified Data.Text as T
-import           System.FilePath (isPathSeparator)
-import           Yi.Buffer.Adjusted hiding (Insert)
+import           Control.Applicative      ((<$), (<$>))
+import           Control.Monad            (when)
+import           Data.Char                (isSpace)
+import           Data.Maybe               (fromJust)
+import           Data.Monoid              ((<>))
+import qualified Data.Text                as T (Text, drop, head, length, split, unwords)
+import           System.FilePath          (isPathSeparator)
+import           Yi.Buffer.Adjusted       hiding (Insert)
 import           Yi.Editor
-import           Yi.History
-import           Yi.Keymap
+import           Yi.History               (historyDown, historyFinish, historyPrefixSet, historyUp)
+import           Yi.Keymap                (YiM)
 import           Yi.Keymap.Vim.Common
 import           Yi.Keymap.Vim.Ex
-import           Yi.Keymap.Vim.StateUtils
-import           Yi.Keymap.Vim.Utils
-import qualified Yi.Rope as R
-import           Yi.String
+import           Yi.Keymap.Vim.StateUtils (modifyStateE, resetCountE, switchModeE)
+import           Yi.Keymap.Vim.Utils      (matchFromBool)
+import qualified Yi.Rope                  as R (fromText, toText)
+import           Yi.String                (commonTPrefix')
 
 defExMap :: [EventString -> Maybe ExCommand] -> [VimBinding]
 defExMap cmdParsers =
diff --git a/src/library/Yi/Keymap/Vim/InsertMap.hs b/src/library/Yi/Keymap/Vim/InsertMap.hs
--- a/src/library/Yi/Keymap/Vim/InsertMap.hs
+++ b/src/library/Yi/Keymap/Vim/InsertMap.hs
@@ -10,27 +10,28 @@
 
 module Yi.Keymap.Vim.InsertMap (defInsertMap) where
 
-import           Control.Applicative
-import           Control.Lens
-import           Control.Monad
-import           Data.Char (isDigit)
-import           Data.List.NonEmpty hiding (drop, span, dropWhile)
-import           Data.Monoid
-import qualified Data.Text as T
-import           Prelude hiding (head)
-import qualified Yi.Buffer as B
-import           Yi.Buffer.Adjusted as BA hiding (Insert)
-import           Yi.Editor
-import           Yi.Event
+import           Prelude                  hiding (head)
+
+import           Control.Applicative      ((<$))
+import           Control.Lens             (use)
+import           Control.Monad            (forM, liftM2, replicateM_, void, when)
+import           Data.Char                (isDigit)
+import           Data.List.NonEmpty       (NonEmpty (..), head, toList)
+import           Data.Monoid              (Monoid (mempty), (<>))
+import qualified Data.Text                as T (pack, unpack)
+import qualified Yi.Buffer                as B (bdeleteB, deleteB, deleteRegionB, insertB, insertN)
+import           Yi.Buffer.Adjusted       as BA hiding (Insert)
+import           Yi.Editor                (EditorM, getEditorDyn, withCurrentBuffer)
+import           Yi.Event                 (Event)
 import           Yi.Keymap.Vim.Common
-import           Yi.Keymap.Vim.Digraph
-import           Yi.Keymap.Vim.EventUtils
-import           Yi.Keymap.Vim.Motion
+import           Yi.Keymap.Vim.Digraph    (charFromDigraph)
+import           Yi.Keymap.Vim.EventUtils (eventToEventString, parseEvents)
+import           Yi.Keymap.Vim.Motion     (Move (Move), stringToMove)
 import           Yi.Keymap.Vim.StateUtils
-import           Yi.Keymap.Vim.Utils
-import           Yi.Monad
-import qualified Yi.Rope as R
-import           Yi.TextCompletion (completeWordB, CompletionScope(..))
+import           Yi.Keymap.Vim.Utils      (selectBinding, selectPureBinding)
+import           Yi.Monad                 (whenM)
+import qualified Yi.Rope                  as R (fromString, fromText)
+import           Yi.TextCompletion        (CompletionScope (..), completeWordB)
 
 defInsertMap :: [(String, Char)] -> [VimBinding]
 defInsertMap digraphs =
@@ -53,7 +54,7 @@
         when (count > 1) $ do
             inputEvents <- fmap (parseEvents . vsOngoingInsertEvents) getEditorDyn
             replicateM_ (count - 1) $ do
-                when (starter `elem` "Oo") $ withCurrentBuffer $ insertB '\n'
+                when (starter `elem` ['O', 'o']) $ withCurrentBuffer $ insertB '\n'
                 replay digraphs inputEvents
         modifyStateE $ \s -> s { vsOngoingInsertEvents = mempty }
         withCurrentBuffer $ moveXorSol 1
@@ -152,7 +153,7 @@
 printableAction evs = do
     saveInsertEventStringE evs
     currentCursor <- withCurrentBuffer pointB
-    IndentSettings et ts sw <- withCurrentBuffer indentSettingsB
+    IndentSettings et _ sw <- withCurrentBuffer indentSettingsB
     secondaryCursors <- fmap vsSecondaryCursors getEditorDyn
     let allCursors = currentCursor :| secondaryCursors
     marks <- withCurrentBuffer $ forM' allCursors $ \cursor -> do
diff --git a/src/library/Yi/Keymap/Vim/MatchResult.hs b/src/library/Yi/Keymap/Vim/MatchResult.hs
--- a/src/library/Yi/Keymap/Vim/MatchResult.hs
+++ b/src/library/Yi/Keymap/Vim/MatchResult.hs
@@ -10,7 +10,7 @@
 
 module Yi.Keymap.Vim.MatchResult where
 
-import Control.Applicative
+import           Control.Applicative (Alternative ((<|>), empty), Applicative ((<*>), pure))
 
 data MatchResult a = NoMatch
                    | PartialMatch
diff --git a/src/library/Yi/Keymap/Vim/Motion.hs b/src/library/Yi/Keymap/Vim/Motion.hs
--- a/src/library/Yi/Keymap/Vim/Motion.hs
+++ b/src/library/Yi/Keymap/Vim/Motion.hs
@@ -49,16 +49,17 @@
     , changeMoveStyle
     ) where
 
-import           Control.Applicative
-import           Control.Lens
-import           Control.Monad
-import           Data.Maybe (fromMaybe)
-import           Data.Monoid
-import qualified Data.Text as T
-import           Prelude hiding (repeat)
+import           Prelude                    hiding (repeat)
+
+import           Control.Applicative        (Alternative ((<|>)), Applicative ((<*>)), (<$>))
+import           Control.Lens               (Field3 (_3), over, use)
+import           Control.Monad              (replicateM_, void, when, (<=<))
+import           Data.Maybe                 (fromMaybe)
+import           Data.Monoid                ((<>))
+import qualified Data.Text                  as T (unpack)
 import           Yi.Buffer.Adjusted
-import           Yi.Keymap.Vim.Common
-import           Yi.Keymap.Vim.StyledRegion
+import           Yi.Keymap.Vim.Common       (EventString (_unEv), MatchResult (..), lookupBestMatch)
+import           Yi.Keymap.Vim.StyledRegion (StyledRegion (..), normalizeRegion)
 
 data Move = Move {
     moveStyle :: !RegionStyle
@@ -189,7 +190,7 @@
 withDefaultCount = over _3 (. fromMaybe 1)
 
 matchGotoMarkMove :: String -> MatchResult Move
-matchGotoMarkMove (m:_) | m `notElem` "'`" = NoMatch
+matchGotoMarkMove (m:_) | m `notElem` ['\'', '`'] = NoMatch
 matchGotoMarkMove (_:[]) = PartialMatch
 matchGotoMarkMove (m:c:[]) = WholeMatch $ Move style True action
     where style = if m == '`' then Inclusive else LineWise
@@ -201,9 +202,9 @@
 matchGotoMarkMove _ = NoMatch
 
 matchGotoCharMove :: String -> MatchResult Move
-matchGotoCharMove (m:[]) | m `elem` "fFtT" = PartialMatch
-matchGotoCharMove (m:"<lt>") | m `elem` "fFtT" = matchGotoCharMove (m:"<")
-matchGotoCharMove (m:c:[]) | m `elem` "fFtT" = WholeMatch $ Move style False action
+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) =
               case m of
                   'f' -> (Forward, Inclusive, nextCInLineInc c)
diff --git a/src/library/Yi/Keymap/Vim/NormalMap.hs b/src/library/Yi/Keymap/Vim/NormalMap.hs
--- a/src/library/Yi/Keymap/Vim/NormalMap.hs
+++ b/src/library/Yi/Keymap/Vim/NormalMap.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE LambdaCase        #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
@@ -11,46 +11,48 @@
 
 module Yi.Keymap.Vim.NormalMap (defNormalMap) where
 
-import           Control.Applicative
-import           Control.Lens hiding (re)
-import           Control.Monad
-import           Data.Char
-import           Data.HashMap.Strict (singleton, lookup)
-import           Data.List (group)
-import           Data.Maybe (fromMaybe)
-import           Data.Monoid
-import qualified Data.Text as T
-import           Prelude hiding (null, lookup)
-import           System.Directory (doesFileExist)
-import           System.FriendlyPath (expandTilda)
-import           Yi.Buffer.Adjusted hiding (Insert)
-import           Yi.Core (quitEditor, closeWindow)
+import           Prelude                    hiding (lookup)
+
+import           Control.Applicative        ((<$>))
+import           Control.Lens               (assign, use, (.=))
+import           Control.Monad              (replicateM_, unless, void, when)
+import           Data.Char                  (ord)
+import           Data.HashMap.Strict        (lookup, singleton)
+import           Data.List                  (group)
+import           Data.Maybe                 (fromMaybe)
+import           Data.Monoid                (Monoid (mempty), (<>))
+import qualified Data.Text                  as T (drop, empty, pack, replicate, unpack)
+import           System.Directory           (doesFileExist)
+import           System.FriendlyPath        (expandTilda)
+import           Yi.Buffer.Adjusted         hiding (Insert)
+import           Yi.Core                    (closeWindow, quitEditor)
 import           Yi.Editor
-import           Yi.Event
-import           Yi.File (openNewFile, fwriteE)
-import           Yi.History
-import           Yi.Keymap
-import           Yi.Keymap.Keys
+import           Yi.Event                   (Event (Event), Key (KASCII, KEnter, KEsc, KTab), Modifier (MCtrl))
+import           Yi.File                    (fwriteE, openNewFile)
+import           Yi.History                 (historyPrefixSet, historyStart)
+import           Yi.Keymap                  (YiM)
+import           Yi.Keymap.Keys             (char, ctrlCh, spec)
 import           Yi.Keymap.Vim.Common
-import           Yi.Keymap.Vim.Eval
-import           Yi.Keymap.Vim.Motion
-import           Yi.Keymap.Vim.Operator
-import           Yi.Keymap.Vim.Search
+import           Yi.Keymap.Vim.Eval         (scheduleActionStringForEval)
+import           Yi.Keymap.Vim.Motion       (CountedMove (CountedMove), regionOfMoveB, stringToMove)
+import           Yi.Keymap.Vim.Operator     (VimOperator (..), opChange, opDelete, opYank)
+import           Yi.Keymap.Vim.Search       (doVimSearch)
 import           Yi.Keymap.Vim.StateUtils
-import           Yi.Keymap.Vim.StyledRegion
-import           Yi.Keymap.Vim.Tag
+import           Yi.Keymap.Vim.StyledRegion (StyledRegion (StyledRegion), transformCharactersInLineN)
+import           Yi.Keymap.Vim.Tag          (gotoTag, popTag)
 import           Yi.Keymap.Vim.Utils
-import           Yi.MiniBuffer
-import           Yi.Misc
-import           Yi.Monad
-import           Yi.Regex (seInput, makeSearchOptsM)
-import qualified Yi.Rope as R
-import           Yi.Search (getRegexE, isearchInitE,
-                            setRegexE, makeSimpleSearch)
-import           Yi.String
-import           Yi.Tag (Tag(..))
-import           Yi.Utils (io)
+import           Yi.MiniBuffer              (spawnMinibufferE)
+import           Yi.Misc                    (printFileInfoE)
+import           Yi.Monad                   (maybeM, whenM)
+import           Yi.Regex                   (makeSearchOptsM, seInput)
+import qualified Yi.Rope                    as R (fromText, null, toString, toText)
+import           Yi.Search                  (getRegexE, isearchInitE, makeSimpleSearch, setRegexE)
+import           Yi.String                  (showT)
+import           Yi.Tag                     (Tag (..))
+import           Yi.Utils                   (io)
 
+data EOLStickiness = Sticky | NonSticky deriving Eq
+
 mkDigitBinding :: Char -> VimBinding
 mkDigitBinding c = mkBindingE Normal Continue (char c, return (), mutate)
   where
@@ -133,9 +135,9 @@
 
 finishingBingings :: [VimBinding]
 finishingBingings = fmap (mkStringBindingE Normal Finish)
-    [ ("x", cutCharE Forward =<< getCountE, resetCount)
-    , ("<Del>", cutCharE Forward =<< getCountE, resetCount)
-    , ("X", cutCharE Backward =<< getCountE, resetCount)
+    [ ("x", cutCharE Forward NonSticky =<< getCountE, resetCount)
+    , ("<Del>", cutCharE Forward NonSticky =<< getCountE, resetCount)
+    , ("X", cutCharE Backward NonSticky =<< getCountE, resetCount)
 
     , ("D",
         do region <- withCurrentBuffer $ regionWithTwoMovesB (return ()) moveToEol
@@ -213,7 +215,7 @@
     , ("i", return (), switchMode $ Insert 'i')
     , ("<Ins>", return (), switchMode $ Insert 'i')
     , ("I", withCurrentBuffer firstNonSpaceB, switchMode $ Insert 'I')
-    , ("a", withCurrentBuffer rightB, switchMode $ Insert 'a')
+    , ("a", withCurrentBuffer $ moveXorEol 1, switchMode $ Insert 'a')
     , ("A", withCurrentBuffer moveToEol, switchMode $ Insert 'A')
     , ("o", withCurrentBuffer $ do
           moveToEol
@@ -243,7 +245,7 @@
         do region <- withCurrentBuffer $ regionWithTwoMovesB (return ()) moveToEol
            void $ operatorApplyToRegionE opChange 1 $ StyledRegion Exclusive region
         , switchMode $ Insert 'C')
-    , (char 's', cutCharE Forward =<< getCountE, switchMode $ Insert 's')
+    , (char 's', cutCharE Forward Sticky =<< getCountE, switchMode $ Insert 's')
     , (char 'S',
         do region <- withCurrentBuffer $ regionWithTwoMovesB firstNonSpaceB moveToEol
            void $ operatorApplyToRegionE opDelete 1 $ StyledRegion Exclusive region
@@ -390,7 +392,7 @@
 
 searchBinding :: VimBinding
 searchBinding = VimBindingE (f . T.unpack . _unEv)
-    where f evs (VimState { vsMode = Normal }) | evs `elem` group "/?"
+    where f evs (VimState { vsMode = Normal }) | evs `elem` group ['/', '?']
             = WholeMatch $ do
                   state <- fmap vsMode getEditorDyn
                   let dir = if evs == "/" then Forward else Backward
@@ -435,8 +437,8 @@
     setVisibleSelection True
     pointB >>= setSelectionMarkPointB
 
-cutCharE :: Direction -> Int -> EditorM ()
-cutCharE dir count = do
+cutCharE :: Direction -> EOLStickiness -> Int -> EditorM ()
+cutCharE dir stickiness count = do
     r <- withCurrentBuffer $ do
         p0 <- pointB
         (if dir == Forward then moveXorEol else moveXorSol) count
@@ -444,7 +446,7 @@
         let region = mkRegion p0 p1
         rope <- readRegionB region
         deleteRegionB $ mkRegion p0 p1
-        leftOnEol
+        when (stickiness == NonSticky) leftOnEol
         return rope
     regName <- fmap vsActiveRegister getEditorDyn
     setRegisterE regName Inclusive r
@@ -452,7 +454,7 @@
 tabTraversalBinding :: VimBinding
 tabTraversalBinding = VimBindingE (f . T.unpack . _unEv)
     where f "g" (VimState { vsMode = Normal }) = PartialMatch
-          f ('g':c:[]) (VimState { vsMode = Normal }) | c `elem` "tT" = WholeMatch $ do
+          f ('g':c:[]) (VimState { vsMode = Normal }) | c `elem` ['t', 'T'] = WholeMatch $ do
               count <- getCountE
               replicateM_ count $ if c == 'T' then previousTabE else nextTabE
               resetCountE
diff --git a/src/library/Yi/Keymap/Vim/NormalOperatorPendingMap.hs b/src/library/Yi/Keymap/Vim/NormalOperatorPendingMap.hs
--- a/src/library/Yi/Keymap/Vim/NormalOperatorPendingMap.hs
+++ b/src/library/Yi/Keymap/Vim/NormalOperatorPendingMap.hs
@@ -11,23 +11,23 @@
 module Yi.Keymap.Vim.NormalOperatorPendingMap
        (defNormalOperatorPendingMap) where
 
-import           Control.Applicative
-import           Control.Monad
-import           Data.Char (isDigit)
-import           Data.List (isPrefixOf)
-import           Data.Maybe (fromMaybe, fromJust)
-import           Data.Monoid
-import qualified Data.Text as T
-import           Yi.Buffer.Adjusted hiding (Insert)
-import           Yi.Editor
-import           Yi.Keymap.Keys
+import           Control.Applicative        ((<$>))
+import           Control.Monad              (void, when)
+import           Data.Char                  (isDigit)
+import           Data.List                  (isPrefixOf)
+import           Data.Maybe                 (fromJust, fromMaybe)
+import           Data.Monoid                ((<>))
+import qualified Data.Text                  as T (init, last, pack, snoc, unpack)
+import           Yi.Buffer.Adjusted         hiding (Insert)
+import           Yi.Editor                  (getEditorDyn, withCurrentBuffer)
+import           Yi.Keymap.Keys             (Key (KEsc), spec)
 import           Yi.Keymap.Vim.Common
 import           Yi.Keymap.Vim.Motion
 import           Yi.Keymap.Vim.Operator
 import           Yi.Keymap.Vim.StateUtils
-import           Yi.Keymap.Vim.StyledRegion
+import           Yi.Keymap.Vim.StyledRegion (StyledRegion (..), normalizeRegion)
 import           Yi.Keymap.Vim.TextObject
-import           Yi.Keymap.Vim.Utils
+import           Yi.Keymap.Vim.Utils        (mkBindingE)
 
 defNormalOperatorPendingMap :: [VimOperator] -> [VimBinding]
 defNormalOperatorPendingMap operators = [textObject operators, escBinding]
@@ -165,7 +165,7 @@
     where go "" Nothing mods "0" = (Nothing, head mods, "0")
           go ds count mods (h:t) | isDigit h = go (ds <> [h]) count mods t
           go ds@(_:_) count mods s@(h:_) | not (isDigit h) = go [] (maybeMult count (Just (read ds))) mods s
-          go [] count mods (h:t) | h `elem` "vV" = go [] count ([h]:mods) t
+          go [] count mods (h:t) | h `elem` ['v', 'V'] = go [] count ([h]:mods) t
           go [] count mods s | "<C-v>" `isPrefixOf` s = go [] count ("<C-v>":mods) (drop 5 s)
           go [] count mods s = (count, head mods, s)
           go ds count mods [] = (maybeMult count (Just (read ds)), head mods, [])
diff --git a/src/library/Yi/Keymap/Vim/Operator.hs b/src/library/Yi/Keymap/Vim/Operator.hs
--- a/src/library/Yi/Keymap/Vim/Operator.hs
+++ b/src/library/Yi/Keymap/Vim/Operator.hs
@@ -23,24 +23,24 @@
     , lastCharForOperator
     ) where
 
-import           Control.Applicative ((<$>))
-import           Control.Monad
-import           Data.Char (toLower, toUpper, isSpace)
-import           Data.Foldable (find)
-import           Data.Maybe (fromJust)
-import           Data.Monoid
-import qualified Data.Text as T
-import           Yi.Buffer.Adjusted hiding (Insert)
-import           Yi.Editor
+import           Control.Applicative        ((<$>))
+import           Control.Monad              (when)
+import           Data.Char                  (isSpace, toLower, toUpper)
+import           Data.Foldable              (find)
+import           Data.Maybe                 (fromJust)
+import           Data.Monoid                ((<>))
+import qualified Data.Text                  as T (unpack)
+import           Yi.Buffer.Adjusted         hiding (Insert)
+import           Yi.Editor                  (EditorM, getEditorDyn, withCurrentBuffer)
 import           Yi.Keymap.Vim.Common
-import           Yi.Keymap.Vim.EventUtils
-import           Yi.Keymap.Vim.StateUtils
-import           Yi.Keymap.Vim.StyledRegion
-import           Yi.Keymap.Vim.TextObject
-import           Yi.Keymap.Vim.Utils
-import           Yi.Misc
-import           Yi.Rope (YiString)
-import qualified Yi.Rope as R
+import           Yi.Keymap.Vim.EventUtils   (eventToEventString, parseEvents)
+import           Yi.Keymap.Vim.StateUtils   (setRegisterE, switchModeE)
+import           Yi.Keymap.Vim.StyledRegion (StyledRegion (..), transformCharactersInRegionB)
+import           Yi.Keymap.Vim.TextObject   (CountedTextObject, regionOfTextObjectB)
+import           Yi.Keymap.Vim.Utils        (indentBlockRegionB)
+import           Yi.Misc                    (rot13Char)
+import           Yi.Rope                    (YiString)
+import qualified Yi.Rope                    as R
 
 data VimOperator = VimOperator {
     operatorName :: !OperatorName
diff --git a/src/library/Yi/Keymap/Vim/ReplaceMap.hs b/src/library/Yi/Keymap/Vim/ReplaceMap.hs
--- a/src/library/Yi/Keymap/Vim/ReplaceMap.hs
+++ b/src/library/Yi/Keymap/Vim/ReplaceMap.hs
@@ -10,16 +10,16 @@
 
 module Yi.Keymap.Vim.ReplaceMap (defReplaceMap) where
 
-import           Control.Monad
-import           Data.Monoid
-import qualified Data.Text as T
+import           Control.Monad            (replicateM_, when)
+import           Data.Monoid              (Monoid (mempty), (<>))
+import qualified Data.Text                as T (unpack)
 import           Yi.Buffer.Adjusted
-import           Yi.Editor
-import           Yi.Keymap.Keys
+import           Yi.Editor                (EditorM, getEditorDyn, withCurrentBuffer)
+import           Yi.Keymap.Keys           (Key (KEsc), ctrlCh, spec)
 import           Yi.Keymap.Vim.Common
-import           Yi.Keymap.Vim.EventUtils
+import           Yi.Keymap.Vim.EventUtils (eventToEventString, parseEvents)
 import           Yi.Keymap.Vim.StateUtils
-import           Yi.Keymap.Vim.Utils
+import           Yi.Keymap.Vim.Utils      (mkBindingE)
 
 defReplaceMap :: [VimBinding]
 defReplaceMap = specials <> [printable]
diff --git a/src/library/Yi/Keymap/Vim/ReplaceSingleCharMap.hs b/src/library/Yi/Keymap/Vim/ReplaceSingleCharMap.hs
--- a/src/library/Yi/Keymap/Vim/ReplaceSingleCharMap.hs
+++ b/src/library/Yi/Keymap/Vim/ReplaceSingleCharMap.hs
@@ -11,18 +11,16 @@
     ( defReplaceSingleMap
     ) where
 
-import           Control.Monad
-
-import           Data.Maybe (fromMaybe)
-
-import qualified Data.Text as T
+import           Control.Monad            (replicateM_, when)
+import           Data.Maybe               (fromMaybe)
+import qualified Data.Text                as T (unpack)
 import           Yi.Buffer.Adjusted
-import           Yi.Editor
-import           Yi.Keymap.Keys
+import           Yi.Editor                (getEditorDyn, withCurrentBuffer)
+import           Yi.Keymap.Keys           (Key (KEsc), spec)
 import           Yi.Keymap.Vim.Common
-import           Yi.Keymap.Vim.StateUtils
-import           Yi.Keymap.Vim.Utils
-import           Yi.Utils
+import           Yi.Keymap.Vim.StateUtils (resetCount, resetCountE, switchMode, switchModeE)
+import           Yi.Keymap.Vim.Utils      (mkBindingE)
+import           Yi.Utils                 (SemiNum ((~-)))
 
 defReplaceSingleMap :: [VimBinding]
 defReplaceSingleMap = [escBinding, actualReplaceBinding]
diff --git a/src/library/Yi/Keymap/Vim/Search.hs b/src/library/Yi/Keymap/Vim/Search.hs
--- a/src/library/Yi/Keymap/Vim/Search.hs
+++ b/src/library/Yi/Keymap/Vim/Search.hs
@@ -10,11 +10,11 @@
 
 module Yi.Keymap.Vim.Search (doVimSearch, continueVimSearch) where
 
-import Data.Maybe (listToMaybe)
-import Data.Text ()
+import Data.Maybe         (listToMaybe)
+import Data.Text          ()
 import Yi.Buffer.Adjusted
-import Yi.Editor
-import Yi.Search
+import Yi.Editor          (EditorM, printMsg, withCurrentBuffer)
+import Yi.Search          (SearchOption, getRegexE, searchInit)
 
 doVimSearch :: Maybe String -> [SearchOption] -> Direction -> EditorM ()
 doVimSearch Nothing _ dir = do
diff --git a/src/library/Yi/Keymap/Vim/SearchMotionMap.hs b/src/library/Yi/Keymap/Vim/SearchMotionMap.hs
--- a/src/library/Yi/Keymap/Vim/SearchMotionMap.hs
+++ b/src/library/Yi/Keymap/Vim/SearchMotionMap.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE LambdaCase        #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
@@ -11,18 +11,18 @@
 
 module Yi.Keymap.Vim.SearchMotionMap (defSearchMotionMap) where
 
-import           Control.Applicative
-import           Control.Monad
-import           Data.Maybe (fromMaybe)
-import qualified Data.Text as T
-import           Yi.Buffer.Adjusted
-import           Yi.Editor
-import           Yi.History
+import           Control.Applicative      ((<$))
+import           Control.Monad            (replicateM_)
+import           Data.Maybe               (fromMaybe)
+import qualified Data.Text                as T (pack, unpack)
+import           Yi.Buffer.Adjusted       (Direction (Backward, Forward), elemsB)
+import           Yi.Editor                (getEditorDyn, withCurrentBuffer)
+import           Yi.History               (historyFinish, historyPrefixSet)
 import           Yi.Keymap.Vim.Common
-import           Yi.Keymap.Vim.Search
-import           Yi.Keymap.Vim.StateUtils
-import           Yi.Keymap.Vim.Utils
-import qualified Yi.Rope as R
+import           Yi.Keymap.Vim.Search     (continueVimSearch)
+import           Yi.Keymap.Vim.StateUtils (getCountE, switchModeE)
+import           Yi.Keymap.Vim.Utils      (matchFromBool)
+import qualified Yi.Rope                  as R (toText)
 import           Yi.Search
 
 defSearchMotionMap :: [VimBinding]
diff --git a/src/library/Yi/Keymap/Vim/StateUtils.hs b/src/library/Yi/Keymap/Vim/StateUtils.hs
--- a/src/library/Yi/Keymap/Vim/StateUtils.hs
+++ b/src/library/Yi/Keymap/Vim/StateUtils.hs
@@ -34,20 +34,20 @@
     , resetActiveRegisterE
     ) where
 
-import           Control.Applicative
-import           Control.Monad
-import qualified Data.HashMap.Strict as HM
-import           Data.Maybe (fromMaybe)
-import           Data.Monoid
-import qualified Data.Text as T
-import           Yi.Buffer.Normal
-import           Yi.Editor
-import           Yi.Event
+import           Control.Applicative      ((<$>))
+import           Control.Monad            (when)
+import qualified Data.HashMap.Strict      as HM (insert, lookup)
+import           Data.Maybe               (fromMaybe, isJust)
+import           Data.Monoid              (Monoid (mempty), (<>))
+import qualified Data.Text                as T (null)
+import           Yi.Buffer.Normal         (RegionStyle (Block, LineWise))
+import           Yi.Editor                (EditorM, getEditorDyn, putEditorDyn, setStatus)
+import           Yi.Event                 (Event)
 import           Yi.Keymap.Vim.Common
 import           Yi.Keymap.Vim.EventUtils
-import           Yi.Rope (YiString)
-import           Yi.String (showT)
-import           Yi.Style (defaultStyle)
+import           Yi.Rope                  (YiString)
+import           Yi.String                (showT)
+import           Yi.Style                 (defaultStyle)
 
 switchMode :: VimMode -> VimState -> VimState
 switchMode mode state = state { vsMode = mode }
@@ -144,12 +144,16 @@
 setStickyEolE :: Bool -> EditorM ()
 setStickyEolE b = modifyStateE $ \s -> s { vsStickyEol = b }
 
-updateModeIndicatorE :: VimMode -> EditorM ()
-updateModeIndicatorE prevMode = do
+updateModeIndicatorE :: VimState -> EditorM ()
+updateModeIndicatorE prevState = do
   currentState <- getEditorDyn
-  let mode = vsMode currentState
+  let mode     = vsMode currentState
+      prevMode = vsMode prevState
       paste = vsPaste currentState
-  when (mode /= prevMode) $ do
+      isRecording   = isJust . vsCurrentMacroRecording $ currentState
+      prevRecording = isJust . vsCurrentMacroRecording $ prevState
+
+  when (mode /= prevMode || isRecording /= prevRecording) $ do
       let modeName = case mode of
             Insert _ -> "INSERT" <> if paste then " (paste) " else ""
             InsertNormal -> "(insert)"
@@ -159,9 +163,14 @@
             Visual LineWise -> "VISUAL LINE"
             Visual _ -> "VISUAL"
             _ -> ""
-          decoratedModeName = if T.null modeName
+
+          decoratedModeName' = if T.null modeName
                               then mempty
                               else "-- " <> modeName <> " --"
+          decoratedModeName = if isRecording
+                              then decoratedModeName' <> "recording"
+                              else decoratedModeName'
+
       setStatus ([decoratedModeName], defaultStyle)
 
 saveInsertEventStringE :: EventString -> EditorM ()
diff --git a/src/library/Yi/Keymap/Vim/StyledRegion.hs b/src/library/Yi/Keymap/Vim/StyledRegion.hs
--- a/src/library/Yi/Keymap/Vim/StyledRegion.hs
+++ b/src/library/Yi/Keymap/Vim/StyledRegion.hs
@@ -16,11 +16,11 @@
     , transformCharactersInLineN
     ) where
 
-import           Control.Monad
-import qualified Data.Text as T
+import           Control.Monad      (forM_)
+import qualified Data.Text          as T (map)
 import           Yi.Buffer.Adjusted
-import qualified Yi.Rope as R
-import           Yi.Utils
+import qualified Yi.Rope            as R (withText)
+import           Yi.Utils           (SemiNum ((-~)))
 
 data StyledRegion = StyledRegion !RegionStyle !Region
 
diff --git a/src/library/Yi/Keymap/Vim/Tag.hs b/src/library/Yi/Keymap/Vim/Tag.hs
--- a/src/library/Yi/Keymap/Vim/Tag.hs
+++ b/src/library/Yi/Keymap/Vim/Tag.hs
@@ -1,10 +1,10 @@
-{-# LANGUAGE CPP #-}
+{-# LANGUAGE CPP                #-}
 {-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE DeriveGeneric #-}
-{-# LANGUAGE LambdaCase #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE FlexibleContexts   #-}
+{-# LANGUAGE LambdaCase         #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE TemplateHaskell    #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -22,50 +22,42 @@
     , unpopTag
     ) where
 
-import           Control.Applicative
-import           Control.Lens (view)
-import           Control.Monad
-import           Data.Binary
-import           Data.Default
-#if __GLASGOW_HASKELL__ < 708
-import           Data.DeriveTH
-#else
 import           GHC.Generics (Generic)
-#endif
-import           Data.Maybe
-import           Data.Monoid
-import qualified Data.Text as T
-import           Data.Typeable
-import           System.Directory (doesFileExist)
-import           System.FilePath
-import           System.FriendlyPath
+
+import           Control.Applicative ((<$>))
+import           Control.Lens        (view)
+import           Control.Monad       (foldM, void)
+import           Data.Binary         (Binary (..))
+import           Data.Default        (Default (..))
+import           Data.Maybe          (maybeToList)
+import           Data.Monoid         ((<>))
+import qualified Data.Text           as T (Text)
+import           Data.Typeable       (Typeable)
+import           System.Directory    (doesFileExist)
+import           System.FilePath     (takeDirectory, (</>))
+import           System.FriendlyPath (userToCanonPath)
 import           Yi.Buffer
-import           Yi.Core (errorEditor)
-import           Yi.Types (YiVariable)
+import           Yi.Core             (errorEditor)
 import           Yi.Editor
-import           Yi.File
-import           Yi.Keymap
+import           Yi.File             (openingNewFile)
+import           Yi.Keymap           (YiM)
 import           Yi.Tag
-import           Yi.Utils
+import           Yi.Types            (YiVariable)
+import           Yi.Utils            (io)
 
 -- | List of tags and the file/line/char that they originate from.
 -- (the location that :tag or Ctrl-[ was called from).
-data VimTagStack = VimTagStack {
-        tagStackList :: [(Tag, Int, FilePath, Int, Int)]
-      , tagStackIndex :: Int }
-    deriving Typeable
+data VimTagStack = VimTagStack
+    { tagStackList :: [(Tag, Int, FilePath, Int, Int)]
+    , tagStackIndex :: Int
+    } deriving (Typeable, Generic)
 
 instance Default VimTagStack where
     def = VimTagStack [] 0
 
 instance YiVariable VimTagStack
 
-#if __GLASGOW_HASKELL__ < 708
-$(derive makeBinary ''VimTagStack)
-#else
-deriving instance Generic VimTagStack
 instance Binary VimTagStack
-#endif
 
 -- | Returns tag, tag index, filepath, line number, char number
 getTagList :: EditorM [(Tag, Int, FilePath, Int, Int)]
diff --git a/src/library/Yi/Keymap/Vim/TextObject.hs b/src/library/Yi/Keymap/Vim/TextObject.hs
--- a/src/library/Yi/Keymap/Vim/TextObject.hs
+++ b/src/library/Yi/Keymap/Vim/TextObject.hs
@@ -7,10 +7,9 @@
   , stringToTextObject
   ) where
 
-import Control.Monad
-
+import Control.Monad              (replicateM_, (<=<))
 import Yi.Buffer.Adjusted
-import Yi.Keymap.Vim.StyledRegion
+import Yi.Keymap.Vim.StyledRegion (StyledRegion (..), normalizeRegion)
 
 data TextObject = TextObject !RegionStyle !TextUnit
 data CountedTextObject = CountedTextObject !Int !TextObject
diff --git a/src/library/Yi/Keymap/Vim/Utils.hs b/src/library/Yi/Keymap/Vim/Utils.hs
--- a/src/library/Yi/Keymap/Vim/Utils.hs
+++ b/src/library/Yi/Keymap/Vim/Utils.hs
@@ -27,25 +27,25 @@
   , addVimJumpHereE
   ) where
 
-import           Control.Applicative
-import           Control.Lens hiding (snoc)
-import           Control.Monad
-import           Data.Char (isSpace)
-import           Data.Foldable (asum)
-import           Data.List (group)
-import qualified Data.Text as T
-import           Safe (headDef)
-import           Yi.Buffer.Adjusted hiding (Insert)
+import           Control.Applicative      ((<$), (<$>))
+import           Control.Lens             ((.=))
+import           Control.Monad            (forM_, void, when)
+import           Data.Char                (isSpace)
+import           Data.Foldable            (asum)
+import           Data.List                (group)
+import qualified Data.Text                as T (unpack)
+import           Safe                     (headDef)
+import           Yi.Buffer.Adjusted       hiding (Insert)
 import           Yi.Editor
-import           Yi.Event
-import           Yi.Keymap
+import           Yi.Event                 (Event)
+import           Yi.Keymap                (YiM)
 import           Yi.Keymap.Vim.Common
-import           Yi.Keymap.Vim.EventUtils
-import           Yi.Keymap.Vim.Motion
-import           Yi.Keymap.Vim.StateUtils
-import           Yi.Monad
-import           Yi.Rope (YiString, last, countNewLines)
-import qualified Yi.Rope as R
+import           Yi.Keymap.Vim.EventUtils (eventToEventString, splitCountedCommand)
+import           Yi.Keymap.Vim.Motion     (Move (Move), stringToMove)
+import           Yi.Keymap.Vim.StateUtils (getMaybeCountE, modifyStateE, resetCountE, setStickyEolE)
+import           Yi.Monad                 (whenM)
+import           Yi.Rope                  (YiString, countNewLines, last)
+import qualified Yi.Rope                  as R (replicateChar, snoc)
 
 -- 'mkBindingE' and 'mkBindingY' are helper functions for bindings
 -- where VimState mutation is not dependent on action performed
@@ -142,7 +142,7 @@
         when (evs `notElem` group "jk$") $ setStickyEolE False
 
         let m = head evs
-        when (m `elem` "fFtT") $ do
+        when (m `elem` ('f' : "FtT")) $ do
             let c = Prelude.last evs
                 (dir, style) =
                     case m of
@@ -169,21 +169,22 @@
   indentSettings <- indentSettingsB
   (start, lengths) <- shapeOfBlockRegionB reg
   moveTo start
-  forM_ (zip [1..] lengths) $ \(i, _) ->
+  forM_ (zip [1..] lengths) $ \(i, _) -> do
       whenM (not <$> atEol) $ do
         let w = shiftWidth indentSettings
         if count > 0
         then insertN $ R.replicateChar (count * w) ' '
-        else do
-            let go 0 = return ()
-                go n = do
-                    c <- readB
-                    when (c == ' ') $
-                        deleteN 1 >> go (n - 1)
-            go (abs count * w)
-        moveTo start
-        void $ lineMoveRel i
+        else go (abs count * w)
+      moveTo start
+      void $ lineMoveRel i
   moveTo start
+  where
+      go 0 = return ()
+      go n = do
+          c <- readB
+          when (c == ' ') $
+              deleteN 1 >> go (n - 1)
+
 
 pasteInclusiveB :: YiString -> RegionStyle -> BufferM ()
 pasteInclusiveB rope style = do
diff --git a/src/library/Yi/Keymap/Vim/VisualMap.hs b/src/library/Yi/Keymap/Vim/VisualMap.hs
--- a/src/library/Yi/Keymap/Vim/VisualMap.hs
+++ b/src/library/Yi/Keymap/Vim/VisualMap.hs
@@ -12,26 +12,26 @@
 
 module Yi.Keymap.Vim.VisualMap ( defVisualMap ) where
 
-import           Control.Applicative
-import           Control.Lens hiding ((-~), op)
-import           Control.Monad
-import           Data.Char (ord)
-import           Data.List (group)
-import           Data.Maybe (fromJust)
-import qualified Data.Text as T
-import           Yi.Buffer.Adjusted hiding (Insert)
+import           Control.Applicative        ((<$), (<$>))
+import           Control.Lens               ((.=))
+import           Control.Monad              (forM_, void)
+import           Data.Char                  (ord)
+import           Data.List                  (group)
+import           Data.Maybe                 (fromJust)
+import qualified Data.Text                  as T (unpack)
+import           Yi.Buffer.Adjusted         hiding (Insert)
 import           Yi.Editor
 import           Yi.Keymap.Vim.Common
-import           Yi.Keymap.Vim.Operator
+import           Yi.Keymap.Vim.Operator     (VimOperator (..), opDelete, stringToOperator)
 import           Yi.Keymap.Vim.StateUtils
-import           Yi.Keymap.Vim.StyledRegion
-import           Yi.Keymap.Vim.Tag
-import           Yi.Keymap.Vim.Utils
-import           Yi.MiniBuffer
-import           Yi.Monad
-import qualified Yi.Rope as R
-import           Yi.Tag
-import           Yi.Utils
+import           Yi.Keymap.Vim.StyledRegion (StyledRegion (StyledRegion), transformCharactersInRegionB)
+import           Yi.Keymap.Vim.Tag          (gotoTag)
+import           Yi.Keymap.Vim.Utils        (matchFromBool, mkChooseRegisterBinding, mkMotionBinding)
+import           Yi.MiniBuffer              (spawnMinibufferE)
+import           Yi.Monad                   (whenM)
+import qualified Yi.Rope                    as R (toText)
+import           Yi.Tag                     (Tag (Tag))
+import           Yi.Utils                   (SemiNum ((-~)))
 
 defVisualMap :: [VimOperator] -> [VimBinding]
 defVisualMap operators =
@@ -218,7 +218,7 @@
 
 switchEdgeBinding :: VimBinding
 switchEdgeBinding = VimBindingE (f . T.unpack . _unEv)
-    where f [c] (VimState { vsMode = (Visual _) }) | c `elem` "oO"
+    where f [c] (VimState { vsMode = (Visual _) }) | c `elem` ['o', 'O']
               = WholeMatch $ do
                   (Visual style) <- vsMode <$> getEditorDyn
                   withCurrentBuffer $ do
diff --git a/src/library/Yi/KillRing.hs b/src/library/Yi/KillRing.hs
--- a/src/library/Yi/KillRing.hs
+++ b/src/library/Yi/KillRing.hs
@@ -1,7 +1,5 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE DeriveGeneric #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE CPP                #-}
+{-# LANGUAGE TemplateHaskell    #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -26,21 +24,17 @@
                    )
     where
 
-import           Control.Applicative
-import           Control.Lens
-import           Data.Binary
-#if __GLASGOW_HASKELL__ < 708
-import           Data.DeriveTH
-#else
-import           GHC.Generics (Generic)
-#endif
-import           Data.List.NonEmpty hiding (length, drop)
-import           Data.Monoid
-import           Prelude hiding (head, tail, take)
-import           Yi.Buffer.Basic
-import qualified Yi.Rope as R
+import           Prelude             hiding (head, tail, take)
 
+import           Control.Applicative ((<$>), (<*>))
+import           Control.Lens        (makeLenses, (^.))
+import           Data.Binary         (Binary, get, put)
+import           Data.List.NonEmpty  (NonEmpty (..), head, take)
+import           Data.Monoid         (mempty, (<>))
+import           Yi.Buffer.Basic     (Direction (..))
+import qualified Yi.Rope             as R (YiString, length)
 
+
 data Killring = Killring { _krKilled :: Bool
                          , _krAccumulate :: Bool
                          , _krContents :: NonEmpty R.YiString
@@ -55,12 +49,6 @@
         in Killring <$> get <*> get <*> getNE <*> get
 
 makeLenses ''Killring
-
-#if __GLASGOW_HASKELL__ < 708
-$(derive makeBinary ''NonEmpty)
-#else
-deriving instance Generic Killring
-#endif
 
 maxDepth :: Int
 maxDepth = 10
diff --git a/src/library/Yi/Layout.hs b/src/library/Yi/Layout.hs
--- a/src/library/Yi/Layout.hs
+++ b/src/library/Yi/Layout.hs
@@ -1,5 +1,9 @@
-{-# LANGUAGE DeriveDataTypeable, ExistentialQuantification, DeriveFunctor, TupleSections, ViewPatterns #-}
-{-# LANGUAGE Rank2Types #-}
+{-# LANGUAGE DeriveDataTypeable        #-}
+{-# LANGUAGE DeriveFunctor             #-}
+{-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE Rank2Types                #-}
+{-# LANGUAGE TupleSections             #-}
+{-# LANGUAGE ViewPatterns              #-}
 {-# OPTIONS_GHC -funbox-strict-fields #-} -- we might as well unbox our Ints.
 
 -- | This module defines the layout manager interface (see 'LayoutManager'). To desgin a new layout manager, just make an instance of this class.
@@ -43,14 +47,14 @@
   )
  where
 
-import Control.Applicative
-import Control.Arrow (first)
-import Control.Lens hiding (set')
-import Data.Typeable
-import Data.Maybe
-import Data.Default
-import Data.List (mapAccumL, foldl')
-import qualified Control.Monad.State.Strict as Monad
+import           Control.Applicative        (pure, (<$>), (<*>), (<|>))
+import           Control.Arrow              (first)
+import           Control.Lens               (Lens', lens)
+import qualified Control.Monad.State.Strict as Monad (State, evalState, get, put)
+import           Data.Default               (Default, def)
+import           Data.List                  (foldl', mapAccumL)
+import           Data.Maybe                 (fromMaybe)
+import           Data.Typeable              (Typeable, cast, typeOf)
 
 -------------------------------- Some design notes ----------------------
 -- [Treatment of mini windows]
diff --git a/src/library/Yi/Main.hs b/src/library/Yi/Main.hs
--- a/src/library/Yi/Main.hs
+++ b/src/library/Yi/Main.hs
@@ -112,7 +112,7 @@
 do_args :: Config -> [String] -> Either Err (Config, ConsoleConfig)
 do_args cfg args =
     case getOpt (ReturnInOrder File) options args of
-        (os, [], []) -> foldM (getConfig shouldOpenInTabs) (cfg, defaultConsoleConfig) os
+        (os, [], []) -> foldM (getConfig shouldOpenInTabs) (cfg, defaultConsoleConfig) (reverse os)
         (_, _, errs) -> fail (concat errs)
     where
         shouldOpenInTabs = ("--" ++ openInTabsLong) `elem` args
diff --git a/src/library/Yi/MiniBuffer.hs b/src/library/Yi/MiniBuffer.hs
--- a/src/library/Yi/MiniBuffer.hs
+++ b/src/library/Yi/MiniBuffer.hs
@@ -1,14 +1,14 @@
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE EmptyDataDecls #-}
-{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE EmptyDataDecls             #-}
+{-# LANGUAGE FlexibleInstances          #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE LambdaCase #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE TypeSynonymInstances #-}
-{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE LambdaCase                 #-}
+{-# LANGUAGE MultiParamTypeClasses      #-}
+{-# LANGUAGE OverloadedStrings          #-}
+{-# LANGUAGE ScopedTypeVariables        #-}
+{-# LANGUAGE TypeOperators              #-}
+{-# LANGUAGE TypeSynonymInstances       #-}
+{-# LANGUAGE UndecidableInstances       #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -30,35 +30,36 @@
                      , commentRegion, promptingForBuffer, debugBufferContent
                      ) where
 
-import           Control.Applicative
-import           Control.Concurrent
-import           Control.Lens hiding (act)
-import           Control.Monad
-import           Data.Foldable (find, toList)
-import           Data.IORef
-import qualified Data.List.PointedList.Circular as PL
-import           Data.Maybe
-import           Data.Monoid (mempty)
-import           Data.Proxy
-import           Data.String (IsString)
-import qualified Data.Text as T
-import           Data.Typeable
-import           System.CanonicalizePath (replaceShorthands)
+import           Control.Applicative            ((<$>))
+import           Control.Concurrent             (threadDelay)
+import           Control.Lens                   (use, (%=))
+import           Control.Monad                  (forM, void, when, (<=<), (>=>))
+import           Data.Foldable                  (find, toList)
+import           Data.IORef                     (newIORef, readIORef, writeIORef)
+import qualified Data.List.PointedList.Circular as PL (find, insertRight)
+import           Data.Maybe                     (catMaybes, fromJust, fromMaybe)
+import           Data.Monoid                    (mempty)
+import           Data.Proxy                     (Proxy)
+import           Data.String                    (IsString)
+import qualified Data.Text                      as T (Text, append, head,
+                                                      isInfixOf, null, pack,
+                                                      snoc, unpack, words)
+import           Data.Typeable                  (Typeable)
+import           System.CanonicalizePath        (replaceShorthands)
 import           Yi.Buffer
-import           Yi.Completion (infixMatch, prefixMatch, containsMatch',
-                                completeInList, completeInList')
-import           Yi.Config
-import           Yi.Core
+import           Yi.Completion
+import           Yi.Config                      (modeTable)
+import           Yi.Core                        (forkAction, runAction)
 import           Yi.Editor
-import           Yi.History
+import           Yi.History                     (historyFinishGen, historyMove, historyStartGen)
 import           Yi.Keymap
 import           Yi.Keymap.Keys
-import           Yi.Monad
-import qualified Yi.Rope as R
-import           Yi.Style (defaultStyle)
-import           Yi.String (commonTPrefix)
-import           Yi.Utils
-import           Yi.Window (bufkey)
+import           Yi.Monad                       (gets)
+import qualified Yi.Rope                        as R (YiString, fromText, toText)
+import           Yi.String                      (commonTPrefix)
+import           Yi.Style                       (defaultStyle)
+import           Yi.Utils                       (io)
+import           Yi.Window                      (bufkey)
 
 -- | Prints out the rope of the current buffer as-is to stdout.
 --
diff --git a/src/library/Yi/Misc.hs b/src/library/Yi/Misc.hs
--- a/src/library/Yi/Misc.hs
+++ b/src/library/Yi/Misc.hs
@@ -1,7 +1,7 @@
-{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE LambdaCase        #-}
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE TupleSections #-}
-{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE TupleSections     #-}
+{-# LANGUAGE TypeOperators     #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -19,32 +19,32 @@
                , printFileInfoE, debugBufferContent
                ) where
 
-import           Control.Applicative
-import           Control.Lens (assign)
-import           Control.Monad ((>=>), filterM)
-import           Control.Monad.Base
-import           Data.Char (chr, isAlpha, isLower, isUpper, ord)
-import           Data.List ((\\))
-import           Data.Maybe (isNothing)
-import qualified Data.Text as T
-import           System.CanonicalizePath (canonicalizePath, replaceShorthands,
-                                          replaceShorthands)
-import           System.Directory (doesDirectoryExist, getDirectoryContents,
-                                   getCurrentDirectory, setCurrentDirectory)
-import           System.Environment (lookupEnv)
-import           System.FilePath (takeDirectory, (</>), takeFileName,
-                                  addTrailingPathSeparator,
-                                  hasTrailingPathSeparator)
-import           System.FriendlyPath (expandTilda, isAbsolute')
+import           Control.Applicative     ((<$>), (<*>))
+import           Control.Monad           (filterM, (>=>))
+import           Control.Monad.Base      (liftBase)
+import           Data.Char               (chr, isAlpha, isLower, isUpper, ord)
+import           Data.List               ((\\))
+import           Data.Maybe              (isNothing)
+import qualified Data.Text               as T (Text, append, concat, isPrefixOf,
+                                               pack, stripPrefix, unpack)
+import           System.CanonicalizePath (canonicalizePath, replaceShorthands, replaceShorthands)
+import           System.Directory        (doesDirectoryExist,
+                                          getCurrentDirectory,
+                                          getDirectoryContents,
+                                          setCurrentDirectory)
+import           System.Environment      (lookupEnv)
+import           System.FilePath         (addTrailingPathSeparator,
+                                          hasTrailingPathSeparator,
+                                          takeDirectory, takeFileName, (</>))
+import           System.FriendlyPath     (expandTilda, isAbsolute')
 import           Yi.Buffer
-import           Yi.Completion (completeInList')
-import           Yi.Editor
-import           Yi.Keymap
-import           Yi.MiniBuffer (withMinibufferGen, mkCompleteFn,
-                                debugBufferContent)
-import           Yi.Monad
-import qualified Yi.Rope as R
-import           Yi.Utils (io)
+import           Yi.Completion           (completeInList')
+import           Yi.Editor               (EditorM, printMsg, withCurrentBuffer)
+import           Yi.Keymap               (YiM)
+import           Yi.MiniBuffer           (debugBufferContent, mkCompleteFn, withMinibufferGen)
+import           Yi.Monad                (gets)
+import qualified Yi.Rope                 as R (fromText)
+import           Yi.Utils                (io)
 
 -- | Given a possible starting path (which if not given defaults to
 -- the current directory) and a fragment of a path we find all files
@@ -109,11 +109,12 @@
 
   return results
 
--- | Place mark at current point
+-- | Place mark at current point. If there's an existing mark at point
+-- already, deactivate mark.
 placeMark :: BufferM ()
-placeMark = do
-  assign highlightSelectionA True
-  pointB >>= setSelectionMarkPointB
+placeMark = (==) <$> pointB <*> getSelectionMarkPointB >>= \case
+  True -> setVisibleSelection False
+  False -> setVisibleSelection True >> pointB >>= setSelectionMarkPointB
 
 -- | Select the contents of the whole buffer
 selectAll :: BufferM ()
diff --git a/src/library/Yi/Mode/Abella.hs b/src/library/Yi/Mode/Abella.hs
--- a/src/library/Yi/Mode/Abella.hs
+++ b/src/library/Yi/Mode/Abella.hs
@@ -1,6 +1,6 @@
+{-# LANGUAGE DeriveDataTypeable         #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE OverloadedStrings          #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -23,26 +23,26 @@
   , abellaSend
   ) where
 
-import           Control.Applicative
-import           Control.Lens
-import           Control.Monad
-import           Data.Binary
-import           Data.Char (isSpace)
-import           Data.Default
-import           Data.Maybe (isJust)
-import qualified Data.Text as T
-import           Data.Typeable
+import           Control.Applicative (Applicative ((<*>)), (<$>))
+import           Control.Lens        (assign, use, (%~), (&), (.=), (.~))
+import           Control.Monad       (join, when)
+import           Data.Binary         (Binary)
+import           Data.Char           (isSpace)
+import           Data.Default        (Default)
+import           Data.Maybe          (isJust)
+import qualified Data.Text           as T (isInfixOf, snoc, unpack)
+import           Data.Typeable       (Typeable)
 import           Yi.Buffer
-import           Yi.Core (sendToProcess)
-import           Yi.Types (YiVariable)
+import           Yi.Core             (sendToProcess)
 import           Yi.Editor
-import           Yi.Keymap
-import           Yi.Keymap.Keys
-import qualified Yi.Lexer.Abella as Abella
-import           Yi.MiniBuffer (CommandArguments(..))
-import qualified Yi.Mode.Interactive as Interactive
-import           Yi.Modes (TokenBasedMode, styleMode, anyExtension)
-import qualified Yi.Rope as R
+import           Yi.Keymap           (YiM, topKeymapA)
+import           Yi.Keymap.Keys      (Event, choice, ctrlCh, (<||), (?*>>!))
+import qualified Yi.Lexer.Abella     as Abella (Token, lexer)
+import           Yi.MiniBuffer       (CommandArguments (..))
+import qualified Yi.Mode.Interactive as Interactive (spawnProcess)
+import           Yi.Modes            (TokenBasedMode, anyExtension, styleMode)
+import qualified Yi.Rope             as R (YiString, toText)
+import           Yi.Types            (YiVariable)
 
 abellaModeGen :: (Char -> [Event]) -> TokenBasedMode Abella.Token
 abellaModeGen abellaBinding = styleMode Abella.lexer
diff --git a/src/library/Yi/Mode/Buffers.hs b/src/library/Yi/Mode/Buffers.hs
--- a/src/library/Yi/Mode/Buffers.hs
+++ b/src/library/Yi/Mode/Buffers.hs
@@ -13,16 +13,16 @@
 module Yi.Mode.Buffers (listBuffers) where
 
 import           Control.Applicative ((<$>))
-import           Control.Category ((>>>))
-import           Control.Lens
-import           Data.List.NonEmpty (toList)
-import qualified Data.Text as T
-import           System.FilePath (takeFileName)
+import           Control.Category    ((>>>))
+import           Control.Lens        (assign, (%~), (.~))
+import           Data.List.NonEmpty  (toList)
+import qualified Data.Text           as T (intercalate, pack)
+import           System.FilePath     (takeFileName)
 import           Yi.Buffer
 import           Yi.Editor
-import           Yi.Keymap
+import           Yi.Keymap           (Keymap, YiM, topKeymapA)
 import           Yi.Keymap.Keys
-import qualified Yi.Rope as R
+import qualified Yi.Rope             as R (fromText, toString)
 
 -- | Retrieve buffer list and open a them in buffer mode using the
 -- 'bufferKeymap'.
diff --git a/src/library/Yi/Mode/Compilation.hs b/src/library/Yi/Mode/Compilation.hs
--- a/src/library/Yi/Mode/Compilation.hs
+++ b/src/library/Yi/Mode/Compilation.hs
@@ -11,18 +11,18 @@
 -- A 'Mode' for working with buffers showing the results of compilations.
 module Yi.Mode.Compilation where
 
-import           Control.Lens
-import           Data.Text ()
+import           Control.Lens         ((%~), (&), (.~))
+import           Data.Text            ()
 import           Yi.Buffer
-import           Yi.Core (withSyntax)
-import           Yi.Editor
-import           Yi.File (openingNewFile)
-import           Yi.Lexer.Alex (Tok(..), Posn(..))
-import qualified Yi.Lexer.Compilation as Compilation
-import           Yi.Keymap
-import           Yi.Keymap.Keys
-import           Yi.Modes (styleMode, TokenBasedMode)
-import qualified Yi.Syntax.OnlineTree as OnlineTree
+import           Yi.Core              (withSyntax)
+import           Yi.Editor            (shiftOtherWindow, withCurrentBuffer)
+import           Yi.File              (openingNewFile)
+import           Yi.Keymap            (Action (YiA), topKeymapA)
+import           Yi.Keymap.Keys       (Key (KEnter), spec, (<||), (?>>!))
+import           Yi.Lexer.Alex        (Posn (..), Tok (..))
+import qualified Yi.Lexer.Compilation as Compilation (Token (Report), lexer)
+import           Yi.Modes             (TokenBasedMode, styleMode)
+import qualified Yi.Syntax.OnlineTree as OnlineTree (tokAtOrBefore)
 
 mode :: TokenBasedMode Compilation.Token
 mode = styleMode Compilation.lexer
diff --git a/src/library/Yi/Mode/GHCi.hs b/src/library/Yi/Mode/GHCi.hs
--- a/src/library/Yi/Mode/GHCi.hs
+++ b/src/library/Yi/Mode/GHCi.hs
@@ -1,10 +1,9 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE CPP                        #-}
+{-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE DeriveGeneric              #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE OverloadedStrings          #-}
+{-# LANGUAGE TemplateHaskell            #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -18,26 +17,23 @@
 
 module Yi.Mode.GHCi where
 
-import           Control.Lens
-import           Data.Binary
-import           Data.Default
-#if __GLASGOW_HASKELL__ < 708
-import           Data.DeriveTH
-#else
 import           GHC.Generics (Generic)
-#endif
-import           Data.Text ()
-import qualified Data.Text as T
-import           Data.Typeable
+
+import           Control.Lens         (makeLenses, (%~), (&), (.~))
+import           Data.Binary          (Binary (..))
+import           Data.Default         (Default (..))
+import           Data.Text            ()
+import qualified Data.Text            as T (findIndex)
+import           Data.Typeable        (Typeable)
 import           Yi.Buffer
-import           Yi.Types (YiVariable)
-import           Yi.Keymap
-import           Yi.Keymap.Keys
-import           Yi.Lexer.Alex (Tok)
-import           Yi.Lexer.Compilation (Token())
-import qualified Yi.Mode.Interactive as I
-import qualified Yi.Rope as R
+import           Yi.Keymap            (YiM, topKeymapA)
+import           Yi.Keymap.Keys       (Key (KHome), important, spec, (?>>!))
+import           Yi.Lexer.Alex        (Tok)
+import           Yi.Lexer.Compilation (Token ())
+import qualified Yi.Mode.Interactive  as I (mode, spawnProcessMode)
+import qualified Yi.Rope              as R (toText)
 import           Yi.Syntax.OnlineTree (Tree)
+import           Yi.Types             (YiVariable)
 
 -- | The process name to use to spawn GHCi.
 data GhciProcessName = GhciProcessName
@@ -45,7 +41,7 @@
     -- ^ Command to run when spawning GHCi.
   , _ghciProcessArgs :: [String]
     -- ^ Args to pass to the process.
-  } deriving (Typeable, Show)
+  } deriving (Typeable, Show, Generic)
 
 -- | The process name defaults to @ghci@.
 instance Default GhciProcessName where
@@ -53,12 +49,7 @@
                         , _ghciProcessArgs = []
                         }
 
-#if __GLASGOW_HASKELL__ < 708
-$(derive makeBinary ''GhciProcessName)
-#else
-deriving instance Generic GhciProcessName
 instance Binary GhciProcessName
-#endif
 
 makeLenses ''GhciProcessName
 
diff --git a/src/library/Yi/Mode/Haskell.hs b/src/library/Yi/Mode/Haskell.hs
--- a/src/library/Yi/Mode/Haskell.hs
+++ b/src/library/Yi/Mode/Haskell.hs
@@ -1,6 +1,6 @@
-{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveDataTypeable         #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE OverloadedStrings          #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -30,46 +30,46 @@
    ghciSetProcessArgs
   ) where
 
-import           Control.Applicative
-import           Control.Lens
-import           Control.Monad hiding (forM_)
-import           Data.Binary
-import           Data.Default
-import           Data.Foldable
-import           Data.Maybe (listToMaybe, isJust)
-import           Data.Monoid
-import qualified Data.Text as T
-import           Data.Typeable
-import           Prelude hiding (and,error,elem,notElem,all,concatMap,exp)
-import           Text.Read (readMaybe)
+import           Prelude                   hiding (all, concatMap, elem, error, notElem, exp)
+
+import           Control.Applicative       (Applicative ((*>)), (<$>))
+import           Control.Lens              ((&), (.~), (^.))
+import           Control.Monad             (unless, void, when)
+import           Data.Binary               (Binary)
+import           Data.Default              (Default)
+import           Data.Foldable             (Foldable, all, concatMap, elem, forM_, notElem)
+import           Data.Maybe                (isJust, listToMaybe)
+import           Data.Monoid               ((<>))
+import qualified Data.Text                 as T (any, concat, drop, pack, unpack, unwords)
+import           Data.Typeable             (Typeable)
+import           Text.Read                 (readMaybe)
 import           Yi.Buffer
-import           Yi.Core (sendToProcess)
-import           Yi.Debug
-import           Yi.Types (YiVariable)
+import           Yi.Core                   (sendToProcess)
+import           Yi.Debug                  (error, trace)
 import           Yi.Editor
-import           Yi.File
-import qualified Yi.IncrementalParse as IncrParser
-import           Yi.Keymap
-import           Yi.Lexer.Alex (Tok(..), Posn(..), tokBegin, tokEnd,
-                                commonLexer, AlexState, lexScanner, CharScanner)
-import           Yi.Lexer.Haskell as Haskell
-import qualified Yi.Lexer.LiterateHaskell as LiterateHaskell
-import           Yi.MiniBuffer
-import qualified Yi.Mode.GHCi as GHCi
-import qualified Yi.Mode.Interactive as Interactive
-import           Yi.Modes (anyExtension, extensionOrContentsMatch)
-import           Yi.Monad
-import qualified Yi.Rope as R
-import           Yi.String
-import           Yi.Syntax
-import qualified Yi.Syntax.Driver as Driver
-import           Yi.Syntax.Haskell as Hask
-import           Yi.Syntax.Layout (State)
-import           Yi.Syntax.OnlineTree as OnlineTree
-import           Yi.Syntax.Paren as Paren
-import           Yi.Syntax.Strokes.Haskell as HS
+import           Yi.File                   (fwriteE)
+import qualified Yi.IncrementalParse       as IncrParser (State, scanner)
+import           Yi.Keymap                 (YiM)
+import           Yi.Lexer.Alex
+import           Yi.Lexer.Haskell          as Haskell
+import qualified Yi.Lexer.LiterateHaskell  as LiterateHaskell (HlState, alexScanToken, initState)
+import           Yi.MiniBuffer             (noHint, withMinibufferFree, withMinibufferGen)
+import qualified Yi.Mode.GHCi              as GHCi (ghciProcessArgs, ghciProcessName, spawnProcess)
+import qualified Yi.Mode.Interactive       as Interactive (queryReply)
+import           Yi.Modes                  (anyExtension, extensionOrContentsMatch)
+import           Yi.Monad                  (gets)
+import qualified Yi.Rope                   as R
+import           Yi.String                 (fillText, showT)
+import           Yi.Syntax                 (ExtHL (..), Scanner, skipScanner)
+import qualified Yi.Syntax.Driver          as Driver (mkHighlighter)
+import           Yi.Syntax.Haskell         as Hask
+import           Yi.Syntax.Layout          (State)
+import           Yi.Syntax.OnlineTree      as OnlineTree (Tree, manyToks)
+import           Yi.Syntax.Paren           as Paren
+import           Yi.Syntax.Strokes.Haskell as HS (getStrokes)
 import           Yi.Syntax.Tree
-import           Yi.Utils
+import           Yi.Types                  (YiVariable)
+import           Yi.Utils                  (groupBy')
 
 -- | General ‘template’ for actual Haskell modes.
 --
diff --git a/src/library/Yi/Mode/Haskell/Dollarify.hs b/src/library/Yi/Mode/Haskell/Dollarify.hs
--- a/src/library/Yi/Mode/Haskell/Dollarify.hs
+++ b/src/library/Yi/Mode/Haskell/Dollarify.hs
@@ -11,23 +11,22 @@
 
 module Yi.Mode.Haskell.Dollarify where
 
-import           Control.Applicative
-import           Control.Monad
-import           Data.Function (on)
-import           Data.List (sortBy)
-import           Data.Maybe (fromMaybe)
-import           Data.Monoid
-import           Data.Text ()
-import           Yi.Buffer hiding (Block)
-import           Yi.Debug
-import           Yi.Lexer.Alex (posnOfs, Tok(..))
-import           Yi.Lexer.Haskell (isComment, TT, Token(..))
-import qualified Yi.Rope as R
-import           Yi.String
-import qualified Yi.Syntax.Haskell as H (Tree, Exp(..))
-import           Yi.Syntax.Paren (Expr, Tree(..))
-import           Yi.Syntax.Tree (getAllSubTrees, getFirstOffset,
-                                 getLastOffset, getLastPath)
+import           Control.Applicative (Applicative ((<*>)), (<$>))
+import           Control.Monad       (unless)
+import           Data.Function       (on)
+import           Data.List           (sortBy)
+import           Data.Maybe          (fromMaybe)
+import           Data.Monoid         ((<>))
+import           Data.Text           ()
+import           Yi.Buffer           hiding (Block)
+import           Yi.Debug            (trace)
+import           Yi.Lexer.Alex       (Tok (..), posnOfs)
+import           Yi.Lexer.Haskell    (TT, Token (..), isComment)
+import qualified Yi.Rope             as R (YiString, null)
+import           Yi.String           (showT)
+import qualified Yi.Syntax.Haskell   as H (Exp (..), Tree)
+import           Yi.Syntax.Paren     (Expr, Tree (..))
+import           Yi.Syntax.Tree      (getAllSubTrees, getFirstOffset, getLastOffset, getLastPath)
 
 dollarify :: Tree TT -> BufferM ()
 dollarify t = maybe (return ()) dollarifyWithin . selectedTree [t] =<< getSelectRegionB
diff --git a/src/library/Yi/Mode/IReader.hs b/src/library/Yi/Mode/IReader.hs
--- a/src/library/Yi/Mode/IReader.hs
+++ b/src/library/Yi/Mode/IReader.hs
@@ -14,15 +14,15 @@
 
 module Yi.Mode.IReader where
 
-import Data.Text ()
-import Control.Lens
-import Data.Char (intToDigit)
+import Control.Lens   ((%~))
+import Data.Char      (intToDigit)
+import Data.Text      ()
 import Yi.Buffer.Misc
-import Yi.Editor
+import Yi.Editor      (printMsg, withCurrentBuffer)
 import Yi.IReader
-import Yi.Keymap
-import Yi.Keymap.Keys
-import Yi.Modes (anyExtension, fundamentalMode)
+import Yi.Keymap      (YiM, topKeymapA)
+import Yi.Keymap.Keys (choice, important, metaCh, (?>>!))
+import Yi.Modes       (anyExtension, fundamentalMode)
 
 abstract :: Mode syntax
 abstract = fundamentalMode { modeApplies = anyExtension ["irtxt"]
diff --git a/src/library/Yi/Mode/Interactive.hs b/src/library/Yi/Mode/Interactive.hs
--- a/src/library/Yi/Mode/Interactive.hs
+++ b/src/library/Yi/Mode/Interactive.hs
@@ -12,25 +12,25 @@
 
 module Yi.Mode.Interactive where
 
-import           Control.Applicative
-import           Control.Concurrent (threadDelay)
-import           Control.Lens
-import           Data.Monoid
-import qualified Data.Text as T
+import           Control.Applicative  ((<$>))
+import           Control.Concurrent   (threadDelay)
+import           Control.Lens         (use, (%~), (.=))
+import           Data.Monoid          ((<>))
+import qualified Data.Text            as T (Text)
 import           Yi.Buffer
-import           Yi.Core (sendToProcess, startSubprocess, withSyntax)
+import           Yi.Core              (sendToProcess, startSubprocess, withSyntax)
 import           Yi.Editor
-import           Yi.History
-import           Yi.Keymap
-import           Yi.Keymap.Keys
-import           Yi.Lexer.Alex (Tok)
+import           Yi.History           (historyFinishGen, historyMoveGen, historyStartGen)
+import           Yi.Keymap            (YiM, topKeymapA)
+import           Yi.Keymap.Keys       (Key (KEnter, KHome), char, choice, meta, spec, (<||), (?>>!))
+import           Yi.Lexer.Alex        (Tok)
 import           Yi.Lexer.Compilation (Token)
-import qualified Yi.Mode.Compilation as Compilation
-import           Yi.Modes
-import           Yi.Monad
-import qualified Yi.Rope as R
-import qualified Yi.Syntax.OnlineTree as OnlineTree
-import           Yi.Utils
+import qualified Yi.Mode.Compilation  as Compilation (mode)
+import           Yi.Modes             (lookupMode)
+import           Yi.Monad             (gets)
+import qualified Yi.Rope              as R (YiString, fromText, toString, toText)
+import qualified Yi.Syntax.OnlineTree as OnlineTree (Tree)
+import           Yi.Utils             (io)
 
 
 mode :: Mode (OnlineTree.Tree (Tok Token))
diff --git a/src/library/Yi/Mode/JavaScript.hs b/src/library/Yi/Mode/JavaScript.hs
--- a/src/library/Yi/Mode/JavaScript.hs
+++ b/src/library/Yi/Mode/JavaScript.hs
@@ -1,6 +1,6 @@
-{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveDataTypeable         #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE OverloadedStrings          #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -15,43 +15,39 @@
 
 module Yi.Mode.JavaScript (javaScriptMode, hooks) where
 
-import           Control.Applicative
-import           Control.Lens
+import           Control.Applicative       ((<$>))
+import           Control.Lens              ((%~))
 import           Control.Monad.Writer.Lazy (execWriter)
-import           Data.Binary
-import           Data.DList as D (toList)
-import           Data.Default
-import           Data.Foldable as F (toList)
-import           Data.List (nub)
-import           Data.Maybe (isJust)
-import           Data.Monoid
-import qualified Data.Text as T
-import           Data.Typeable
-import           System.FilePath.Posix (takeBaseName)
+import           Data.Binary               (Binary)
+import           Data.Default              (Default)
+import           Data.DList                as D (toList)
+import           Data.Foldable             as F (toList)
+import           Data.List                 (nub)
+import           Data.Maybe                (isJust)
+import           Data.Monoid               (Monoid (mempty), (<>))
+import qualified Data.Text                 as T (unlines)
+import           Data.Typeable             (Typeable)
+import           System.FilePath.Posix     (takeBaseName)
 import           Yi.Buffer
-import           Yi.Core (withSyntax)
-import           Yi.Types (YiVariable)
-import           Yi.Editor (withEditor, withOtherWindow, getEditorDyn,
-                            stringToNewBuffer , findBuffer, switchToBufferE,
-                            withCurrentBuffer, withGivenBuffer)
-import           Yi.Event (Key(..), Event(..))
-import           Yi.File (fwriteE)
-import           Yi.IncrementalParse (scanner)
-import           Yi.Interact (choice)
-import           Yi.Keymap (YiM, Action(..), topKeymapA)
-import           Yi.Keymap.Keys (ctrlCh, (?>>), (?>>!), important)
-import           Yi.Lexer.Alex (AlexState, Tok, lexScanner,
-                                commonLexer, CharScanner)
-import           Yi.Lexer.JavaScript (alexScanToken, TT, initState,
-                                      HlState, Token)
-import           Yi.Modes (anyExtension)
-import           Yi.Monad
-import qualified Yi.Rope as R
-import           Yi.String
-import           Yi.Syntax (ExtHL(..), mkHighlighter, Scanner)
-import           Yi.Syntax.JavaScript (Tree, parse, getStrokes)
-import           Yi.Syntax.Tree (getLastPath)
-import           Yi.Verifier.JavaScript (verify)
+import           Yi.Core                   (withSyntax)
+import           Yi.Editor
+import           Yi.Event                  (Event (..), Key (..))
+import           Yi.File                   (fwriteE)
+import           Yi.IncrementalParse       (scanner)
+import           Yi.Interact               (choice)
+import           Yi.Keymap                 (Action (..), YiM, topKeymapA)
+import           Yi.Keymap.Keys            (ctrlCh, important, (?>>), (?>>!))
+import           Yi.Lexer.Alex             (AlexState, CharScanner, Tok, commonLexer, lexScanner)
+import           Yi.Lexer.JavaScript       (HlState, TT, Token, alexScanToken, initState)
+import           Yi.Modes                  (anyExtension)
+import           Yi.Monad                  (gets)
+import qualified Yi.Rope                   as R (fromString, fromText)
+import           Yi.String                 (showT)
+import           Yi.Syntax                 (ExtHL (..), Scanner, mkHighlighter)
+import           Yi.Syntax.JavaScript      (Tree, getStrokes, parse)
+import           Yi.Syntax.Tree            (getLastPath)
+import           Yi.Types                  (YiVariable)
+import           Yi.Verifier.JavaScript    (verify)
 
 javaScriptAbstract :: Mode syntax
 javaScriptAbstract = emptyMode
diff --git a/src/library/Yi/Mode/Latex.hs b/src/library/Yi/Mode/Latex.hs
--- a/src/library/Yi/Mode/Latex.hs
+++ b/src/library/Yi/Mode/Latex.hs
@@ -12,18 +12,17 @@
 
 module Yi.Mode.Latex (latexMode3, latexMode2, fastMode) where
 
-import           Data.Text ()
+import           Data.Text            ()
 import           Yi.Buffer
-import qualified Yi.IncrementalParse as IncrParser
-import           Yi.Lexer.Alex (lexScanner, commonLexer, CharScanner,
-                                Tok, AlexState)
-import qualified Yi.Lexer.Latex as Latex
-import           Yi.Modes (anyExtension, fundamentalMode)
-import           Yi.Syntax
-import qualified Yi.Syntax.Driver as Driver
-import qualified Yi.Syntax.Latex as Latex
-import           Yi.Syntax.OnlineTree (manyToks, Tree)
-import           Yi.Syntax.Tree
+import qualified Yi.IncrementalParse  as IncrParser (scanner)
+import           Yi.Lexer.Alex        (AlexState, CharScanner, Tok, commonLexer, lexScanner)
+import qualified Yi.Lexer.Latex       as Latex (HlState, Token, alexScanToken, initState)
+import           Yi.Modes             (anyExtension, fundamentalMode)
+import           Yi.Syntax            (ExtHL (ExtHL), Scanner, mkHighlighter)
+import qualified Yi.Syntax.Driver     as Driver (mkHighlighter)
+import qualified Yi.Syntax.Latex      as Latex (TT, Tree, getStrokes, parse, tokenToStroke)
+import           Yi.Syntax.OnlineTree (Tree, manyToks)
+import           Yi.Syntax.Tree       (tokenBasedStrokes)
 
 abstract :: Mode syntax
 abstract = fundamentalMode
diff --git a/src/library/Yi/Modes.hs b/src/library/Yi/Modes.hs
--- a/src/library/Yi/Modes.hs
+++ b/src/library/Yi/Modes.hs
@@ -1,5 +1,5 @@
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE PackageImports #-}
+{-# LANGUAGE PackageImports    #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -21,43 +21,42 @@
                  gitCommitMode, rubyMode, styleMode
                 ) where
 
-import           Control.Applicative
-import           Control.Lens
-import           Data.List (isPrefixOf)
-import           Data.Maybe
-import           Data.Text ()
-import           System.FilePath
-import "regex-tdfa" Text.Regex.TDFA ((=~))
+import "regex-tdfa" Text.Regex.TDFA  ((=~))
+
+import           Control.Applicative ((<$>))
+import           Control.Lens        ((%~), (&), (.~), (^.))
+import           Data.List           (isPrefixOf)
+import           Data.Maybe          (fromMaybe)
+import           System.FilePath     (takeDirectory, takeExtension, takeFileName)
 import           Yi.Buffer
-import qualified Yi.IncrementalParse as IncrParser
-import           Yi.Keymap
+import qualified Yi.IncrementalParse  as IncrParser (scanner)
+import           Yi.Keymap            (YiM)
 import           Yi.Lexer.Alex
-import qualified Yi.Lexer.C          as C
-import qualified Yi.Lexer.Cabal      as Cabal
-import qualified Yi.Lexer.Clojure    as Clojure
-import qualified Yi.Lexer.Cplusplus  as Cplusplus
-import qualified Yi.Lexer.GNUMake    as GNUMake
-import qualified Yi.Lexer.GitCommit  as GitCommit
-import qualified Yi.Lexer.JSON       as JSON
-import qualified Yi.Lexer.Java       as Java
-import qualified Yi.Lexer.OCaml      as OCaml
-import qualified Yi.Lexer.ObjectiveC as ObjectiveC
-import qualified Yi.Lexer.Ott        as Ott
-import qualified Yi.Lexer.Perl       as Perl
-import qualified Yi.Lexer.Python     as Python
-import qualified Yi.Lexer.Ruby       as Ruby
-import qualified Yi.Lexer.SVNCommit  as SVNCommit
-import qualified Yi.Lexer.Srmc       as Srmc
-import qualified Yi.Lexer.Whitespace as Whitespace
-import           Yi.MiniBuffer
-import qualified Yi.Rope as R
-import           Yi.Style
-import           Yi.Syntax hiding (mkHighlighter)
-import           Yi.Syntax.Driver (mkHighlighter)
-import           Yi.Syntax.OnlineTree (manyToks, Tree)
-import           Yi.Syntax.Tree
-
-import Yi.Search (makeSimpleSearch)
+import qualified Yi.Lexer.C           as C (lexer)
+import qualified Yi.Lexer.Cabal       as Cabal (lexer)
+import qualified Yi.Lexer.Clojure     as Clojure (lexer)
+import qualified Yi.Lexer.Cplusplus   as Cplusplus (lexer)
+import qualified Yi.Lexer.GitCommit   as GitCommit (Token, lexer)
+import qualified Yi.Lexer.GNUMake     as GNUMake (lexer)
+import qualified Yi.Lexer.Java        as Java (lexer)
+import qualified Yi.Lexer.JSON        as JSON (lexer)
+import qualified Yi.Lexer.ObjectiveC  as ObjectiveC (lexer)
+import qualified Yi.Lexer.OCaml       as OCaml (Token, lexer)
+import qualified Yi.Lexer.Ott         as Ott (lexer)
+import qualified Yi.Lexer.Perl        as Perl (lexer)
+import qualified Yi.Lexer.Python      as Python (lexer)
+import qualified Yi.Lexer.Ruby        as Ruby (lexer)
+import qualified Yi.Lexer.Srmc        as Srmc (lexer)
+import qualified Yi.Lexer.SVNCommit   as SVNCommit (lexer)
+import qualified Yi.Lexer.Whitespace  as Whitespace (lexer)
+import           Yi.MiniBuffer        (anyModeByNameM)
+import qualified Yi.Rope              as R (YiString, toString)
+import           Yi.Search            (makeSimpleSearch)
+import           Yi.Style             (StyleName)
+import           Yi.Syntax            (ExtHL (ExtHL))
+import           Yi.Syntax.Driver     (mkHighlighter)
+import           Yi.Syntax.OnlineTree (Tree, manyToks)
+import           Yi.Syntax.Tree       (tokenBasedStrokes)
 
 type TokenBasedMode tok = Mode (Tree (Tok tok))
 type StyleBasedMode = TokenBasedMode StyleName
diff --git a/src/library/Yi/Monad.hs b/src/library/Yi/Monad.hs
--- a/src/library/Yi/Monad.hs
+++ b/src/library/Yi/Monad.hs
@@ -7,9 +7,9 @@
                  with,
                 ) where
 
-import Control.Monad.Reader
-import Control.Monad.State
-import Control.Monad.Base
+import Control.Monad.Base   (MonadBase, liftBase)
+import Control.Monad.Reader (MonadReader, ask)
+import Control.Monad.State  (MonadState, get, gets, put, when)
 
 -- | Combination of the Control.Monad.State 'modify' and 'gets'
 getsAndModify :: MonadState s m => (s -> (s,a)) -> m a
diff --git a/src/library/Yi/Paths.hs b/src/library/Yi/Paths.hs
--- a/src/library/Yi/Paths.hs
+++ b/src/library/Yi/Paths.hs
@@ -1,4 +1,6 @@
-{-# LANGUAGE NoMonomorphismRestriction, FlexibleContexts #-}
+{-# LANGUAGE FlexibleContexts          #-}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+
 module Yi.Paths ( getEvaluatorContextFilename
                 , getConfigFilename
                 , getConfigModules
@@ -10,13 +12,13 @@
                 , getDataPath
                 ) where
 
-import System.Directory(getAppUserDataDirectory, -- TODO: phase out in favour of xdg-dir
-                        doesDirectoryExist,
-                        createDirectoryIfMissing)
-import System.FilePath((</>))
-import Control.Monad (liftM)
-import Control.Monad.Base
-import qualified System.Environment.XDG.BaseDir as XDG
+import           Control.Monad                  (liftM)
+import           Control.Monad.Base             (MonadBase, liftBase)
+import           System.Directory               (createDirectoryIfMissing,
+                                                 doesDirectoryExist,
+                                                 getAppUserDataDirectory)
+import qualified System.Environment.XDG.BaseDir as XDG (getUserConfigDir, getUserDataDir)
+import           System.FilePath                ((</>))
 
 appUserDataCond ::(MonadBase IO m) => (String -> IO FilePath) -> m FilePath
 appUserDataCond dirQuery = liftBase $
diff --git a/src/library/Yi/PersistentState.hs b/src/library/Yi/PersistentState.hs
--- a/src/library/Yi/PersistentState.hs
+++ b/src/library/Yi/PersistentState.hs
@@ -1,13 +1,11 @@
-{-# LANGUAGE
-  TemplateHaskell,
-  ScopedTypeVariables,
-  NoMonomorphismRestriction,
-  Haskell2010,
-  GeneralizedNewtypeDeriving,
-  DeriveDataTypeable,
-  CPP,
-  StandaloneDeriving,
-  DeriveGeneric #-}
+{-# LANGUAGE CPP                        #-}
+{-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE DeriveGeneric              #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE Haskell2010                #-}
+{-# LANGUAGE NoMonomorphismRestriction  #-}
+{-# LANGUAGE ScopedTypeVariables        #-}
+{-# LANGUAGE TemplateHaskell            #-}
 
 -- | This module implements persistence across different Yi runs.
 --   It includes minibuffer command history, marks etc.
@@ -20,43 +18,34 @@
                           persistentSearch)
 where
 
-import Control.Monad
-import Data.Typeable
-import Data.Binary
-#if __GLASGOW_HASKELL__ < 708
-import Data.DeriveTH
-#else
 import GHC.Generics (Generic)
-#endif
-import Data.Default
-import System.Directory(doesFileExist)
-import qualified Data.Map as M
 
-import Control.Exc(ignoringException)
-import Control.Lens
-
-import Yi.Config.Simple.Types(customVariable, Field)
-import Yi.Editor
-import Yi.History
-import Yi.Keymap(YiM)
-import Yi.KillRing(Killring(..))
-import Yi.Paths(getPersistentStateFilename)
-import Yi.Regex(SearchExp(..))
-import Yi.Search.Internal (getRegexE, setRegexE)
-import Yi.Utils
-import Yi.Types (YiConfigVariable)
+import           Control.Exc            (ignoringException)
+import           Control.Lens           (assign, makeLenses, use)
+import           Control.Monad          (when)
+import           Data.Binary            (Binary, decodeFile, encodeFile)
+import           Data.Default           (Default, def)
+import qualified Data.Map               as M (map)
+import           Data.Typeable          (Typeable)
+import           System.Directory       (doesFileExist)
+import           Yi.Config.Simple.Types (Field, customVariable)
+import           Yi.Editor
+import           Yi.History             (Histories (..), History (..))
+import           Yi.Keymap              (YiM)
+import           Yi.KillRing            (Killring (..))
+import           Yi.Paths               (getPersistentStateFilename)
+import           Yi.Regex               (SearchExp (..))
+import           Yi.Search.Internal     (getRegexE, setRegexE)
+import           Yi.Types               (YiConfigVariable)
+import           Yi.Utils               (io)
 
-data PersistentState = PersistentState { histories     :: !Histories
-                                       , aKillring     :: !Killring
-                                       , aCurrentRegex :: Maybe SearchExp
-                                       }
+data PersistentState = PersistentState
+    { histories     :: !Histories
+    , aKillring     :: !Killring
+    , aCurrentRegex :: Maybe SearchExp
+    } deriving (Generic)
 
-#if __GLASGOW_HASKELL__ < 708
-$(derive makeBinary ''PersistentState)
-#else
-deriving instance Generic PersistentState
 instance Binary PersistentState
-#endif
 
 newtype MaxHistoryEntries = MaxHistoryEntries { _unMaxHistoryEntries :: Int }
   deriving(Typeable, Binary)
diff --git a/src/library/Yi/Process.hs b/src/library/Yi/Process.hs
--- a/src/library/Yi/Process.hs
+++ b/src/library/Yi/Process.hs
@@ -1,22 +1,22 @@
-{-# LANGUAGE CPP, ScopedTypeVariables #-}
+{-# LANGUAGE CPP                 #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
 module Yi.Process (runProgCommand, runShellCommand, shellFileName,
                    createSubprocess, readAvailable, SubprocessInfo(..), SubprocessId) where
 
-import System.Exit (ExitCode(ExitFailure))
-import System.Directory (findExecutable)
-import System.IO
-import System.Process
-import System.Environment ( getEnv )
-
-import Foreign.Marshal.Alloc(allocaBytes)
-import Foreign.C.String
-
-import Control.Exc(orException)
-import Yi.Buffer.Basic (BufferRef)
-import Yi.Monad
+import           Control.Exc           (orException)
+import           Foreign.C.String      (peekCStringLen)
+import           Foreign.Marshal.Alloc (allocaBytes)
+import           System.Directory      (findExecutable)
+import           System.Environment    (getEnv)
+import           System.Exit           (ExitCode (ExitFailure))
+import           System.IO             (BufferMode (NoBuffering), Handle, hGetBufNonBlocking, hSetBuffering)
+import           System.Process        (ProcessHandle, readProcessWithExitCode, runProcess)
+import           Yi.Buffer.Basic       (BufferRef)
+import           Yi.Monad              (repeatUntilM)
 
 #ifndef mingw32_HOST_OS
-import System.Posix.IO
+import System.Posix.IO (createPipe, fdToHandle)
 #endif
 
 runProgCommand :: String -> [String] -> IO (ExitCode,String,String)
@@ -74,8 +74,8 @@
     (inp,out,err,handle) <- runInteractiveProcess cmd args Nothing Nothing
     let separate = True
 #else
-    (inpReadFd,inpWriteFd) <- createPipe
-    (outReadFd,outWriteFd) <- createPipe
+    (inpReadFd,inpWriteFd) <- System.Posix.IO.createPipe
+    (outReadFd,outWriteFd) <- System.Posix.IO.createPipe
     [inpRead,inpWrite,outRead,outWrite] <- mapM fdToHandle [inpReadFd,inpWriteFd,outReadFd,outWriteFd]
 
     handle <- runProcess cmd args Nothing Nothing (Just inpRead) (Just outWrite) (Just outWrite)
@@ -92,11 +92,11 @@
 
 -- Read as much as possible from handle without blocking
 readAvailable :: Handle -> IO String
-readAvailable handle = fmap concat $ repeatUntilM $ read_chunk handle
+readAvailable handle = fmap concat $ repeatUntilM $ readChunk handle
 
 -- Read a chunk from a handle, bool indicates if there is potentially more data available
-read_chunk :: Handle -> IO (Bool,String)
-read_chunk handle = do
+readChunk :: Handle -> IO (Bool,String)
+readChunk handle = do
     let bufferSize = 1024
     allocaBytes bufferSize $ \buffer -> do
                  bytesRead <- hGetBufNonBlocking handle buffer bufferSize
diff --git a/src/library/Yi/Rectangle.hs b/src/library/Yi/Rectangle.hs
--- a/src/library/Yi/Rectangle.hs
+++ b/src/library/Yi/Rectangle.hs
@@ -13,16 +13,17 @@
 
 module Yi.Rectangle where
 
-import           Control.Applicative
-import           Control.Monad
-import           Data.List (sort, transpose)
-import           Data.Monoid
-import qualified Data.Text as T
-import "regex-tdfa" Text.Regex.TDFA
+import "regex-tdfa" Text.Regex.TDFA ( (=~), AllTextSubmatches(..) )
+
+import           Control.Applicative ((<$>))
+import           Control.Monad       (forM_)
+import           Data.List           (sort, transpose)
+import           Data.Monoid         ((<>))
+import qualified Data.Text           as T (Text, concat, justifyLeft, length, pack, unpack)
 import           Yi.Buffer
-import           Yi.Editor
-import qualified Yi.Rope as R
-import           Yi.String
+import           Yi.Editor           (EditorM, getRegE, setRegE, withCurrentBuffer)
+import qualified Yi.Rope             as R
+import           Yi.String           (lines', mapLines, unlines')
 
 alignRegion :: T.Text -> BufferM ()
 alignRegion str = do
diff --git a/src/library/Yi/Search.hs b/src/library/Yi/Search.hs
--- a/src/library/Yi/Search.hs
+++ b/src/library/Yi/Search.hs
@@ -1,7 +1,7 @@
-{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveDataTypeable         #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE LambdaCase #-}
-{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE LambdaCase                 #-}
+{-# LANGUAGE OverloadedStrings          #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -58,27 +58,27 @@
         qrFinish
                  ) where
 
-import           Control.Applicative
-import           Control.Lens hiding (re, from, to, act)
-import           Control.Monad
-import           Data.Binary
-import           Data.Char
-import           Data.Default
-import           Data.Maybe
-import           Data.Monoid
-import qualified Data.Text as T
-import qualified Data.Text.Encoding as E
-import           Data.Typeable
+import           Control.Applicative ((<$>))
+import           Control.Lens        (assign)
+import           Control.Monad       (void, when)
+import           Data.Binary         (Binary, get, put)
+import           Data.Char           (isAlpha, isUpper)
+import           Data.Default        (Default, def)
+import           Data.Maybe          (listToMaybe)
+import           Data.Monoid         ((<>))
+import qualified Data.Text           as T (Text, any, break, empty, length, null, takeWhile, unpack)
+import qualified Data.Text.Encoding  as E (decodeUtf8, encodeUtf8)
+import           Data.Typeable       (Typeable)
 import           Yi.Buffer
-import           Yi.Types (YiVariable)
 import           Yi.Editor
-import           Yi.History
+import           Yi.History          (historyFinishGen, historyMoveGen, historyStartGen)
 import           Yi.Regex
-import qualified Yi.Rope as R
-import           Yi.Search.Internal
-import           Yi.String (showT)
-import           Yi.Utils
-import           Yi.Window
+import qualified Yi.Rope             as R (YiString, null, toString, toText)
+import           Yi.Search.Internal  (getRegexE, resetRegexE, setRegexE)
+import           Yi.String           (showT)
+import           Yi.Types            (YiVariable)
+import           Yi.Utils            (fst3)
+import           Yi.Window           (Window)
 
 -- ---------------------------------------------------------------------
 --
@@ -387,7 +387,6 @@
     assign searchDirectionA dir
     if accept
        then do void act
-               withCurrentBuffer $ setSelectionMarkPointB $ regionStart p0
                printMsg "Quit"
        else do resetRegexE
                withCurrentBuffer $ moveTo $ regionStart p0
diff --git a/src/library/Yi/Search/Internal.hs b/src/library/Yi/Search/Internal.hs
--- a/src/library/Yi/Search/Internal.hs
+++ b/src/library/Yi/Search/Internal.hs
@@ -11,9 +11,9 @@
 
 module Yi.Search.Internal where
 
-import Control.Lens (assign, use)
-import Yi.Editor (EditorM, currentRegexA)
-import Yi.Regex (SearchExp)
+import           Control.Lens (assign, use)
+import           Yi.Editor    (EditorM, currentRegexA)
+import           Yi.Regex     (SearchExp)
 
 -- ---------------------------------------------------------------------
 -- Searching and substitutions with regular expressions
diff --git a/src/library/Yi/Snippets.hs b/src/library/Yi/Snippets.hs
--- a/src/library/Yi/Snippets.hs
+++ b/src/library/Yi/Snippets.hs
@@ -1,14 +1,13 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE DeriveGeneric #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE CPP                        #-}
+{-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE DeriveGeneric              #-}
+{-# LANGUAGE FlexibleContexts           #-}
+{-# LANGUAGE FlexibleInstances          #-}
+{-# LANGUAGE FunctionalDependencies     #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE LambdaCase #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE LambdaCase                 #-}
+{-# LANGUAGE OverloadedStrings          #-}
+{-# LANGUAGE TemplateHaskell            #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -20,31 +19,32 @@
 
 module Yi.Snippets where
 
-import           Control.Applicative
-import           Control.Arrow
-import           Control.Lens hiding (Action)
-import           Control.Monad
-import           Control.Monad.RWS hiding (mapM, mapM_, sequence, get, put)
-import           Data.Binary
-import           Data.Char (isSpace)
-import           Data.Default
-#if __GLASGOW_HASKELL__ < 708
-import           Data.DeriveTH
-#else
 import           GHC.Generics (Generic)
-#endif
-import           Data.Foldable (find)
-import           Data.List hiding (find, elem, concat, concatMap)
-import           Data.Maybe (catMaybes)
-import qualified Data.Text as T
-import           Data.Typeable
+
+import           Control.Applicative (some)
+import           Control.Arrow       (second)
+import           Control.Lens        (use, (.=))
+import           Control.Monad.RWS   (MonadPlus (mplus), MonadReader (ask),
+                                      MonadState, MonadTrans (..),
+                                      MonadWriter (tell),
+                                      Monoid (mappend, mempty), RWST, evalRWST,
+                                      filterM, forM, forM_, liftM, liftM2,
+                                      unless, when, (<>))
+import           Data.Binary         (Binary)
+import           Data.Char           (isSpace)
+import           Data.Default        (Default, def)
+import           Data.Foldable       (find)
+import           Data.List           (foldl', groupBy, intersperse, nub, sort)
+import           Data.Maybe          (catMaybes)
+import qualified Data.Text           as T (Text)
+import           Data.Typeable       (Typeable)
 import           Yi.Buffer
-import           Yi.Editor
-import           Yi.Keymap
+import           Yi.Editor           (withCurrentBuffer)
+import           Yi.Keymap           (Action)
 import           Yi.Keymap.Keys
-import qualified Yi.Rope as R
-import           Yi.TextCompletion
-import           Yi.Types (YiVariable)
+import qualified Yi.Rope             as R
+import           Yi.TextCompletion   (resetComplete, wordCompleteString')
+import           Yi.Types            (YiVariable)
 
 type SnippetCmd = RWST (Int, Int) [MarkInfo] () BufferM
 
@@ -61,14 +61,9 @@
               | DependentMarkInfo { userIndex :: !Int
                                   , startMark :: !Mark
                                   , endMark :: !Mark }
-  deriving (Eq, Show)
+  deriving (Eq, Show, Generic)
 
-#if __GLASGOW_HASKELL__ < 708
-$(derive makeBinary ''MarkInfo)
-#else
-deriving instance Generic MarkInfo
 instance Binary MarkInfo
-#endif
 
 newtype BufferMarks = BufferMarks { bufferMarks :: [MarkInfo] }
   deriving (Eq, Show, Monoid, Typeable, Binary)
diff --git a/src/library/Yi/Snippets/Haskell.hs b/src/library/Yi/Snippets/Haskell.hs
--- a/src/library/Yi/Snippets/Haskell.hs
+++ b/src/library/Yi/Snippets/Haskell.hs
@@ -1,4 +1,3 @@
-
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -10,8 +9,8 @@
 
 module Yi.Snippets.Haskell where
 
-import qualified Yi.Rope as R
-import           Yi.Snippets
+import qualified Yi.Rope     as R (singleton)
+import           Yi.Snippets (SnippetCmd, cursor, cursorWith, snippet, (&))
 
 hsFunction :: SnippetCmd ()
 hsFunction = snippet $
diff --git a/src/library/Yi/String.hs b/src/library/Yi/String.hs
--- a/src/library/Yi/String.hs
+++ b/src/library/Yi/String.hs
@@ -28,12 +28,15 @@
                   overInit, overTail
                  ) where
 
-import           Data.Char (toUpper, toLower, isSpace, isAlphaNum)
-import           Data.List (isSuffixOf)
-import           Data.Maybe (fromMaybe)
-import           Data.Monoid
-import qualified Data.Text as T
-import qualified Yi.Rope as R
+import           Data.Char   (isAlphaNum, isSpace, toLower, toUpper)
+import           Data.List   (isSuffixOf)
+import           Data.Maybe  (fromMaybe)
+import           Data.Monoid (mconcat, (<>))
+import qualified Data.Text   as T (Text, break, commonPrefixes, empty,
+                                   intercalate, pack, splitAt, splitOn, toUpper)
+import qualified Yi.Rope     as R (YiString, all, cons, head, init, intercalate,
+                                   last, length, lines', snoc, tail, unwords,
+                                   withText, words)
 
 -- | Helper that shows then packs the 'Text', for all those cases
 -- where we use 'show'.
diff --git a/src/library/Yi/Syntax/Driver.hs b/src/library/Yi/Syntax/Driver.hs
--- a/src/library/Yi/Syntax/Driver.hs
+++ b/src/library/Yi/Syntax/Driver.hs
@@ -5,13 +5,12 @@
 
 module Yi.Syntax.Driver where
 
-import qualified  Data.Map as M
-import Data.Map (Map)
-
-import Yi.Buffer.Basic(WindowRef)
-import Yi.Lexer.Alex (Tok)
-import Yi.Syntax hiding (Cache)
-import Yi.Syntax.Tree
+import           Data.Map        (Map)
+import qualified Data.Map        as M (Map, assocs, empty, findWithDefault, fromList)
+import           Yi.Buffer.Basic (WindowRef)
+import           Yi.Lexer.Alex   (Tok)
+import           Yi.Syntax       hiding (Cache)
+import           Yi.Syntax.Tree  (IsTree, fromNodeToFinal)
 
 type Path = [Int]
 
diff --git a/src/library/Yi/Syntax/Haskell.hs b/src/library/Yi/Syntax/Haskell.hs
--- a/src/library/Yi/Syntax/Haskell.hs
+++ b/src/library/Yi/Syntax/Haskell.hs
@@ -1,6 +1,6 @@
-{-# LANGUAGE DeriveFoldable #-}
+{-# LANGUAGE DeriveFoldable    #-}
 {-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeFamilies      #-}
 
 -- we have lots of parsers which don't want signatures; and we have
 -- uniplate patterns
@@ -29,17 +29,19 @@
                          , indentScanner
                          ) where
 
-import Control.Applicative
-import Data.Foldable hiding (elem, notElem)
-import Data.Maybe
-import Data.List ((\\))
-import Yi.IncrementalParse
-import Yi.Lexer.Alex
-import Yi.Lexer.Haskell
-import Yi.Syntax.Layout
-import Yi.Syntax.Tree
-import Yi.Syntax
-import Control.Arrow ((&&&))
+import           Control.Applicative (Alternative ((<|>), empty, many, some),
+                                      Applicative (..), optional, (<$>))
+import           Control.Arrow       ((&&&))
+import           Data.Foldable       (Foldable)
+import           Data.List           ((\\))
+import           Data.Maybe          (fromJust, isNothing)
+import           Yi.IncrementalParse
+import           Yi.Lexer.Alex       (Posn (Posn, posnOfs), Tok (Tok, tokT),
+                                      startPosn, tokBegin)
+import           Yi.Lexer.Haskell
+import           Yi.Syntax           (Scanner)
+import           Yi.Syntax.Layout    (State, layoutHandler)
+import           Yi.Syntax.Tree      (IsTree (emptyNode, uniplate), sepBy1)
 
 indentScanner :: Scanner (AlexState lexState) TT
               -> Scanner (Yi.Syntax.Layout.State Token lexState) TT
diff --git a/src/library/Yi/Syntax/JavaScript.hs b/src/library/Yi/Syntax/JavaScript.hs
--- a/src/library/Yi/Syntax/JavaScript.hs
+++ b/src/library/Yi/Syntax/JavaScript.hs
@@ -1,6 +1,6 @@
-{-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE DeriveFoldable #-}
+{-# LANGUAGE DeriveFoldable     #-}
+{-# LANGUAGE FlexibleInstances  #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -18,22 +18,21 @@
 module Yi.Syntax.JavaScript where
 
 import           Prelude hiding (elem,error,any,exp)
-import           Control.Applicative hiding (Const)
-import           Data.Data (Data)
-import           Data.Monoid
-import           Data.Foldable
-import           Data.Typeable
-import           Yi.Buffer.Basic (Point(..))
-import           Yi.IncrementalParse (P, eof, symbol, recoverWith)
-import           Yi.Lexer.Alex (Stroke, Tok(..), tokToSpan, tokFromT)
-import           Yi.Lexer.JavaScript (TT, Token(..), Reserved(..), Operator(..),
-                                      tokenToStyle, prefixOperators,
-                                      infixOperators, postfixOperators )
-import qualified Data.Text as T
-import           Yi.Debug hiding (error)
-import           Yi.String
-import           Yi.Style (errorStyle, StyleName)
-import           Yi.Syntax.Tree (IsTree(..), sepBy1, sepBy)
+
+import           Control.Applicative (Alternative ((<|>), many), Applicative ((<*), (<*>), pure), optional, (<$>))
+import           Data.Data           (Data)
+import           Data.Foldable       (Foldable (foldMap), any, elem, toList)
+import           Data.Monoid         (Endo (..), Monoid (mempty), (<>))
+import qualified Data.Text           as T (cons)
+import           Data.Typeable       (Typeable)
+import           Yi.Buffer.Basic     (Point (..))
+import           Yi.Debug            (trace)
+import           Yi.IncrementalParse (P, eof, recoverWith, symbol)
+import           Yi.Lexer.Alex       (Stroke, Tok (..), tokFromT, tokToSpan)
+import           Yi.Lexer.JavaScript
+import           Yi.String           (showT)
+import           Yi.Style            (StyleName, errorStyle)
+import           Yi.Syntax.Tree      (IsTree (..), sepBy, sepBy1)
 
 -- * Data types, classes and instances
 
diff --git a/src/library/Yi/Syntax/Latex.hs b/src/library/Yi/Syntax/Latex.hs
--- a/src/library/Yi/Syntax/Latex.hs
+++ b/src/library/Yi/Syntax/Latex.hs
@@ -1,5 +1,5 @@
-{-# LANGUAGE DeriveFunctor #-}
 {-# LANGUAGE DeriveFoldable #-}
+{-# LANGUAGE DeriveFunctor  #-}
 {-# OPTIONS_GHC -fno-warn-incomplete-patterns #-} -- uniplate patterns
 {-# OPTIONS_HADDOCK show-extensions #-}
 
@@ -14,16 +14,17 @@
 
 module Yi.Syntax.Latex where
 
-import Control.Applicative
-import Data.Foldable (Foldable, foldMap)
-import Data.Monoid
-import Data.Traversable
-import Yi.IncrementalParse
-import Yi.Lexer.Alex hiding (tokenToStyle)
-import Yi.Lexer.Latex
-import Yi.Style
-import Yi.Syntax
-import Yi.Syntax.Tree
+import           Control.Applicative (Alternative ((<|>), empty, many),
+                                      Applicative ((<*), (<*>), pure), (<$>))
+import           Data.Foldable       (Foldable, foldMap)
+import           Data.Monoid         (Endo (..), Monoid (mappend, mempty), (<>))
+import           Data.Traversable    (Traversable (sequenceA))
+import           Yi.IncrementalParse (P, eof, recoverWith, symbol)
+import           Yi.Lexer.Alex       hiding (tokenToStyle)
+import           Yi.Lexer.Latex      (Token (..), tokenToText)
+import           Yi.Style
+import           Yi.Syntax           (Point, Span)
+import           Yi.Syntax.Tree      (IsTree (emptyNode, uniplate))
 
 isNoise :: Token -> Bool
 isNoise Text = True
diff --git a/src/library/Yi/Syntax/Layout.hs b/src/library/Yi/Syntax/Layout.hs
--- a/src/library/Yi/Syntax/Layout.hs
+++ b/src/library/Yi/Syntax/Layout.hs
@@ -1,12 +1,14 @@
-{-# LANGUAGE PatternGuards, ScopedTypeVariables #-}
+{-# LANGUAGE PatternGuards       #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
 -- Note: If the first line of the file has wrong indentation, some of the
 -- code might be left outside of the blocks
 module Yi.Syntax.Layout (layoutHandler, State) where
 
-import Yi.Syntax
-import Yi.Lexer.Alex
-import Data.Maybe (isJust)
-import Data.List (find)
+import           Data.List     (find)
+import           Data.Maybe    (isJust)
+import           Yi.Lexer.Alex (AlexState (..), Posn (Posn), Tok (Tok, tokPosn, tokT), startPosn)
+import           Yi.Syntax     (Scanner (..))
 
 data BlockOpen t = Indent Int -- block opened because of indentation; parameter is the column of it.
                  | Paren t      -- block opened because of parentheses
diff --git a/src/library/Yi/Syntax/OnlineTree.hs b/src/library/Yi/Syntax/OnlineTree.hs
--- a/src/library/Yi/Syntax/OnlineTree.hs
+++ b/src/library/Yi/Syntax/OnlineTree.hs
@@ -1,5 +1,5 @@
-{-# LANGUAGE DeriveFoldable #-}
-{-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE DeriveFoldable    #-}
+{-# LANGUAGE DeriveFunctor     #-}
 {-# LANGUAGE DeriveTraversable #-}
 {-# OPTIONS_GHC -fno-warn-incomplete-patterns #-} -- uniplate patterns
 {-# OPTIONS_HADDOCK show-extensions #-}
@@ -16,12 +16,12 @@
 module Yi.Syntax.OnlineTree (Tree(..), manyToks,
                              tokAtOrBefore) where
 
-import Control.Applicative
-import Data.Foldable
-import Data.Traversable
-import Yi.IncrementalParse
-import Yi.Lexer.Alex
-import Yi.Syntax.Tree
+import Control.Applicative (Applicative ((<*>), pure), (<$>))
+import Data.Foldable       (Foldable)
+import Data.Traversable    (Traversable)
+import Yi.IncrementalParse (P, Parser (Look), symbol)
+import Yi.Lexer.Alex       (Tok)
+import Yi.Syntax.Tree      (IsTree (emptyNode, uniplate), tokAtOrBefore)
 
 data Tree a = Bin (Tree a) (Tree a)
             | Leaf a
diff --git a/src/library/Yi/Syntax/Paren.hs b/src/library/Yi/Syntax/Paren.hs
--- a/src/library/Yi/Syntax/Paren.hs
+++ b/src/library/Yi/Syntax/Paren.hs
@@ -1,5 +1,5 @@
 {-# LANGUAGE DeriveFoldable #-}
-{-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE DeriveFunctor  #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -13,19 +13,21 @@
 
 module Yi.Syntax.Paren where
 
-import Control.Applicative
-import Data.Foldable
-import Data.Maybe
-import Data.Monoid
-import Data.Traversable
 import Prelude hiding (elem)
-import Yi.IncrementalParse
-import Yi.Lexer.Alex hiding (tokenToStyle)
-import Yi.Lexer.Haskell
-import Yi.Style (hintStyle, errorStyle, StyleName)
-import Yi.Syntax
-import Yi.Syntax.Layout
-import Yi.Syntax.Tree
+
+import           Control.Applicative (Alternative ((<|>), many),
+                                      Applicative ((*>), (<*), (<*>)), (<$>))
+import           Data.Foldable       (Foldable (foldMap), elem, toList)
+import           Data.Maybe          (listToMaybe)
+import           Data.Monoid         (Endo (Endo, appEndo), Monoid (mappend), (<>))
+import           Data.Traversable    (Traversable (sequenceA))
+import           Yi.IncrementalParse (P, Parser, eof, lookNext, recoverWith, symbol)
+import           Yi.Lexer.Alex       hiding (tokenToStyle)
+import           Yi.Lexer.Haskell
+import           Yi.Style            (StyleName, errorStyle, hintStyle)
+import           Yi.Syntax           (Point, Scanner, Span)
+import           Yi.Syntax.Layout    (State, layoutHandler)
+import           Yi.Syntax.Tree
 
 indentScanner :: Scanner (AlexState lexState) TT
               -> Scanner (Yi.Syntax.Layout.State Token lexState) TT
diff --git a/src/library/Yi/Syntax/Strokes/Haskell.hs b/src/library/Yi/Syntax/Strokes/Haskell.hs
--- a/src/library/Yi/Syntax/Strokes/Haskell.hs
+++ b/src/library/Yi/Syntax/Strokes/Haskell.hs
@@ -14,19 +14,20 @@
 
 module Yi.Syntax.Strokes.Haskell (getStrokes, tokenToAnnot) where
 
-import Data.Foldable hiding (elem)
-import Data.Monoid
-import Data.Traversable
-import Prelude hiding (error,any,exp)
-import Yi.Debug
-import Yi.Lexer.Alex hiding (tokenToStyle)
-import Yi.Lexer.Haskell
-import Yi.Style
-import Yi.Syntax
-import Yi.Syntax.Haskell
-import Yi.Syntax.Tree (subtrees)
-import Yi.String (showT)
+import           Prelude           hiding (any, error, exp)
 
+import           Data.Foldable     (Foldable (foldMap), any)
+import           Data.Monoid       (Endo (..), Monoid (mappend), (<>))
+import           Data.Traversable  (Traversable (sequenceA))
+import           Yi.Debug          (error, trace)
+import           Yi.Lexer.Alex     (Posn (posnOfs), Stroke, Tok (tokPosn, tokT), tokToSpan)
+import           Yi.Lexer.Haskell
+import           Yi.String         (showT)
+import           Yi.Style
+import           Yi.Syntax         (Point, Span)
+import           Yi.Syntax.Haskell
+import           Yi.Syntax.Tree    (subtrees)
+
 -- TODO: (optimization) make sure we take in account the begin, so we
 -- don't return useless strokes
 getStrokes :: Point -> Point -> Point -> Tree TT -> [Stroke]
@@ -123,7 +124,8 @@
 isErr = isErrorTok . tokT
 
 isErrN :: (Foldable v) => v TT -> Bool
-isErrN t = any isErr t
+isErrN = any isErr
+--
 --         || not $ null $ isError' t
 
 errStyle :: TT -> Endo [Stroke]
diff --git a/src/library/Yi/Syntax/Tree.hs b/src/library/Yi/Syntax/Tree.hs
--- a/src/library/Yi/Syntax/Tree.hs
+++ b/src/library/Yi/Syntax/Tree.hs
@@ -1,7 +1,7 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE DeriveFoldable #-}
+{-# LANGUAGE CPP                 #-}
+{-# LANGUAGE DeriveFoldable      #-}
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE OverloadedStrings   #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
  -- the CPP seems to confuse GHC; we have uniplate patterns
@@ -30,19 +30,23 @@
 -- Some of this might be replaced by a generic package
 -- such as multirec, uniplace, emgm, ...
 
-import           Control.Applicative
-import           Control.Arrow (first)
-import           Data.Foldable
-import           Data.List.NonEmpty (NonEmpty(..))
-import qualified Data.List.NonEmpty as NE
-import           Data.Maybe
-import           Data.Monoid
-import           Prelude hiding (concatMap, error)
-import           Yi.Buffer.Basic
-import           Yi.Debug
-import           Yi.Lexer.Alex
-import           Yi.Region
-import           Yi.String
+import           Prelude             hiding (concatMap, error)
+
+import           Control.Applicative (Alternative ((<|>), many),
+                                      Applicative ((*>), (<*>), pure), (<$>))
+import           Control.Arrow       (first)
+import           Data.Foldable       (Foldable (foldMap), concatMap, toList)
+import           Data.List.NonEmpty  (NonEmpty (..))
+import qualified Data.List.NonEmpty  as NE (reverse, toList, (<|))
+import           Data.Maybe          (catMaybes, listToMaybe)
+import           Data.Monoid         (First (First, getFirst), Last (Last, getLast), (<>))
+import           Yi.Buffer.Basic     (Point)
+import           Yi.Debug            (error, trace)
+import           Yi.Lexer.Alex       (Posn (Posn, posnLine, posnOfs),
+                                      Tok (Tok, tokPosn), tokBegin, tokEnd)
+import           Yi.Region           (Region (regionEnd, regionStart),
+                                      includedRegion, mkRegion)
+import           Yi.String           (showT)
 
 #ifdef TESTING
 import           Test.QuickCheck
diff --git a/src/library/Yi/Tab.hs b/src/library/Yi/Tab.hs
--- a/src/library/Yi/Tab.hs
+++ b/src/library/Yi/Tab.hs
@@ -1,5 +1,5 @@
 {-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE Rank2Types #-}
+{-# LANGUAGE Rank2Types         #-}
 
 module Yi.Tab
  (
@@ -19,18 +19,18 @@
   makeTab1,
  )  where
 
-import Prelude hiding (foldr, foldl)
-import Control.Lens
-import qualified Data.Binary as Binary
-import Data.Default
-import Data.Typeable
-import Data.Foldable
-import qualified Data.List.PointedList as PL
-import Control.Applicative
+import           Prelude               hiding (foldl, foldr)
 
-import Yi.Buffer.Basic(WindowRef)
-import Yi.Layout
-import Yi.Window
+import           Control.Applicative   ((<$>), (<*>))
+import           Control.Lens          (Lens', lens, over, (^.))
+import qualified Data.Binary           as Binary (Binary, get, put)
+import           Data.Default          (def)
+import           Data.Foldable         (foldl, foldr, toList)
+import qualified Data.List.PointedList as PL (PointedList, singleton, _focus)
+import           Data.Typeable         (Typeable)
+import           Yi.Buffer.Basic       (WindowRef)
+import           Yi.Layout
+import           Yi.Window             (Window, isMini, wkey)
 
 type TabRef = Int
 
diff --git a/src/library/Yi/Tag.hs b/src/library/Yi/Tag.hs
--- a/src/library/Yi/Tag.hs
+++ b/src/library/Yi/Tag.hs
@@ -1,9 +1,9 @@
-{-# LANGUAGE CPP #-}
+{-# LANGUAGE CPP                #-}
 {-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE DeriveGeneric #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE FlexibleContexts   #-}
+{-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE TemplateHaskell    #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -22,7 +22,6 @@
               , hintTags
               , completeTag
               , Tag(..)
-              , mkTag
               , unTag'
               , TagTable(..)
               , getTags
@@ -31,33 +30,29 @@
               , tagsFileList
               ) where
 
-import           Control.Applicative
-import           Control.Lens
-import           Data.Binary
-import qualified Data.ByteString as BS
-import qualified Data.ByteString.UTF8 as BS8
-#if __GLASGOW_HASKELL__ < 708
-import           Data.DeriveTH
-#else
 import           GHC.Generics (Generic)
-#endif
-import           Data.Default
-import qualified Data.Foldable as F
-import           Data.List (isPrefixOf)
-import           Data.Map (Map, fromListWith, lookup, keys)
-import           Data.Maybe (mapMaybe)
-import qualified Data.Text as T
-import qualified Data.Text.Encoding as E
-import qualified Data.Trie as Trie
-import           Data.Typeable
-import           System.FilePath (takeFileName, takeDirectory, (</>))
-import           System.FriendlyPath
-import           Yi.Editor
+
+import           Control.Applicative    ((<$>))
+import           Control.Lens           (makeLenses)
+import           Data.Binary            (Binary, get, put)
+import qualified Data.ByteString        as BS (readFile)
+import           Data.Default           (Default, def)
+import qualified Data.Foldable          as F (concat)
+import           Data.Map               (Map, fromListWith, keys, lookup)
+import           Data.Maybe             (mapMaybe)
+import qualified Data.Text              as T (Text, append, isPrefixOf, lines, pack, unpack, words)
+import qualified Data.Text.Encoding     as E (decodeUtf8, encodeUtf8)
+import qualified Data.Text.Read         as R (decimal)
+import qualified Data.Trie              as Trie (Trie, certainSuffix, fromList, possibleSuffixes)
+import           Data.Typeable          (Typeable)
+import           System.FilePath        (takeDirectory, takeFileName, (</>))
+import           System.FriendlyPath    (expandTilda)
 import           Yi.Config.Simple.Types (Field, customVariable)
-import           Yi.Types (YiVariable, YiConfigVariable)
+import           Yi.Editor              (EditorM, getEditorDyn, putEditorDyn)
+import           Yi.Types               (YiConfigVariable, YiVariable)
 
 newtype TagsFileList  = TagsFileList { _unTagsFileList :: [FilePath] }
-    deriving Typeable
+    deriving (Typeable, Generic)
 
 instance Default TagsFileList where
     def = TagsFileList ["tags"]
@@ -69,7 +64,7 @@
 tagsFileList :: Field [FilePath]
 tagsFileList = customVariable . unTagsFileList
 
-newtype Tags  = Tags (Maybe TagTable) deriving Typeable
+newtype Tags = Tags (Maybe TagTable) deriving (Typeable, Generic)
 
 instance Default Tags where
     def = Tags Nothing
@@ -78,28 +73,25 @@
 
 newtype Tag = Tag { _unTag :: T.Text } deriving (Show, Eq, Ord)
 
--- | Helper
-mkTag :: String -> Tag
-mkTag = Tag . T.pack
-
-unTag' :: Tag -> String
-unTag' = T.unpack . _unTag
+unTag' :: Tag -> T.Text
+unTag' =  _unTag
 
 instance Binary Tag where
   put (Tag t) = put (E.encodeUtf8 t)
   get = Tag . E.decodeUtf8 <$> get
 
-data TagTable = TagTable { tagFileName :: FilePath
-                           -- ^ local name of the tag file
-                           -- TODO: reload if this file is changed
-                           , tagBaseDir :: FilePath
-                           -- ^ path to the tag file directory
-                           -- tags are relative to this path
-                           , tagFileMap :: Map Tag [(FilePath, Int)]
-                           -- ^ map from tags to files
-                           , tagTrie :: Trie.Trie
-                           -- ^ trie to speed up tag hinting
-                         } deriving Typeable
+data TagTable = TagTable
+    { tagFileName :: FilePath
+    -- ^ local name of the tag file
+    -- TODO: reload if this file is changed
+    , tagBaseDir :: FilePath
+    -- ^ path to the tag file directory
+    -- tags are relative to this path
+    , tagFileMap :: Map Tag [(FilePath, Int)]
+    -- ^ map from tags to files
+    , tagTrie :: Trie.Trie
+    -- ^ trie to speed up tag hinting
+    } deriving (Typeable, Generic)
 
 -- | Find the location of a tag using the tag table.
 -- Returns a full path and line number
@@ -110,20 +102,21 @@
 
 -- | Super simple parsing CTag format 1 parsing algorithm
 -- TODO: support search patterns in addition to lineno
-readCTags :: String -> Map Tag [(FilePath, Int)]
+readCTags :: T.Text -> Map Tag [(FilePath, Int)]
 readCTags =
-    fromListWith (++) . mapMaybe (parseTagLine . words) . lines
+    fromListWith (++) . mapMaybe (parseTagLine . T.words) . T.lines
     where parseTagLine (tag:tagfile:lineno:_) =
               -- remove ctag control lines
-              if "!_TAG_" `isPrefixOf` tag then Nothing
-              else Just (mkTag tag, [(tagfile, fst . head . reads $ lineno)])
+              if "!_TAG_" `T.isPrefixOf` tag then Nothing
+              else Just (Tag tag, [(T.unpack tagfile, getLineNumber lineno)])
+              where getLineNumber = (\(Right x) -> x) . fmap fst . R.decimal
           parseTagLine _ = Nothing
 
 -- | Read in a tag file from the system
 importTagTable :: FilePath -> IO TagTable
 importTagTable filename = do
   friendlyName <-  expandTilda filename
-  tagStr <- fmap BS8.toString $ BS.readFile friendlyName
+  tagStr <- E.decodeUtf8 <$> BS.readFile friendlyName
   let cts = readCTags tagStr
   return TagTable { tagFileName = takeFileName filename
                   , tagBaseDir  = takeDirectory filename
@@ -162,15 +155,6 @@
   Tags t <- getEditorDyn
   return t
 
-#if __GLASGOW_HASKELL__ < 708
-$(derive makeBinary ''Tags)
-$(derive makeBinary ''TagTable)
-$(derive makeBinary ''TagsFileList)
-#else
-deriving instance Generic Tags
-deriving instance Generic TagTable
-deriving instance Generic TagsFileList
 instance Binary Tags
 instance Binary TagTable
 instance Binary TagsFileList
-#endif
diff --git a/src/library/Yi/TextCompletion.hs b/src/library/Yi/TextCompletion.hs
--- a/src/library/Yi/TextCompletion.hs
+++ b/src/library/Yi/TextCompletion.hs
@@ -1,6 +1,6 @@
-{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveDataTypeable         #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE OverloadedStrings          #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -24,25 +24,25 @@
         CompletionScope(..)
 ) where
 
-import           Control.Applicative
-import           Control.Monad
-import           Data.Binary
-import           Data.Char
-import           Data.Default
-import           Data.Function (on)
-import           Data.List (findIndex)
-import           Data.List.NonEmpty (NonEmpty(..))
-import           Data.Maybe
-import qualified Data.Text as T
-import qualified Data.Text.Encoding as E
-import           Data.Typeable
+import           Control.Applicative ((<$>))
+import           Control.Monad       (forM)
+import           Data.Binary         (Binary, get, put)
+import           Data.Char           (GeneralCategory (..), generalCategory)
+import           Data.Default        (Default, def)
+import           Data.Function       (on)
+import           Data.List           (findIndex)
+import           Data.List.NonEmpty  (NonEmpty (..))
+import           Data.Maybe          (isJust)
+import qualified Data.Text           as T (Text, drop, groupBy, head, isPrefixOf, length, null)
+import qualified Data.Text.Encoding  as E (decodeUtf8, encodeUtf8)
+import           Data.Typeable       (Typeable)
 import           Yi.Buffer
-import           Yi.Completion
-import           Yi.Types (YiVariable)
+import           Yi.Completion       (completeInList, mkIsPrefixOf)
 import           Yi.Editor
-import           Yi.Keymap
-import qualified Yi.Rope as R
-import           Yi.Utils
+import           Yi.Keymap           (YiM)
+import qualified Yi.Rope             as R (fromText, toText)
+import           Yi.Types            (YiVariable)
+import           Yi.Utils            (nubSet)
 
 -- ---------------------------------------------------------------------
 -- | Word completion
diff --git a/src/library/Yi/Types.hs b/src/library/Yi/Types.hs
--- a/src/library/Yi/Types.hs
+++ b/src/library/Yi/Types.hs
@@ -1,15 +1,14 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE DeriveFoldable #-}
-{-# LANGUAGE DeriveFunctor #-}
-{-# LANGUAGE DeriveTraversable #-}
-{-# LANGUAGE ExistentialQuantification #-}
-{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE CPP                        #-}
+{-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE DeriveFoldable             #-}
+{-# LANGUAGE DeriveFunctor              #-}
+{-# LANGUAGE DeriveTraversable          #-}
+{-# LANGUAGE ExistentialQuantification  #-}
+{-# LANGUAGE FlexibleContexts           #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE LambdaCase #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE LambdaCase                 #-}
+{-# LANGUAGE MultiParamTypeClasses      #-}
+{-# LANGUAGE ScopedTypeVariables        #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -27,49 +26,51 @@
 
 module Yi.Types where
 
-import           Control.Applicative
-import           Control.Concurrent
-import           Control.Monad.Base
-import           Control.Monad.RWS.Strict (RWS, MonadWriter)
-import           Control.Monad.Reader
-import           Control.Monad.State
-import qualified Data.DynamicState as ConfigState
-import qualified Data.DynamicState.Serializable as DynamicState
-import           Data.Binary (Binary)
-import qualified Data.Binary as B
-import           Data.Default
-import qualified Data.DelayList as DelayList
-import           Data.Foldable
-import           Data.Function (on)
-import           Data.List.NonEmpty
-import           Data.List.PointedList
-import qualified Data.Map as M
-import qualified Data.Text as T
-import qualified Data.Text.Encoding as E
-import           Data.Time
-import           Data.Traversable
-import           Data.Typeable
-import           Data.Word
 #ifdef FRONTEND_VTY
-import qualified Graphics.Vty as Vty
+import qualified Graphics.Vty as Vty ()
 #endif
-import           Yi.Buffer.Basic (BufferRef, WindowRef)
+
+import           Control.Applicative            (Applicative, pure, (<$>), (<*>))
+import           Control.Concurrent             (MVar, modifyMVar, modifyMVar_, readMVar)
+import           Control.Monad.Base             (MonadBase, liftBase)
+import           Control.Monad.Reader           (MonadReader, ReaderT, ask, asks, runReaderT)
+import           Control.Monad.RWS.Strict       (MonadWriter, RWS, ap, liftM3, void)
+import           Control.Monad.State            (MonadState (..), State, forever, runState)
+import           Data.Binary                    (Binary)
+import qualified Data.Binary                    as B (get, put)
+import           Data.Default                   (Default, def)
+import qualified Data.DelayList                 as DelayList (DelayList)
+import qualified Data.DynamicState              as ConfigState (DynamicState)
+import qualified Data.DynamicState.Serializable as DynamicState (DynamicState)
+import           Data.Foldable                  (Foldable)
+import           Data.Function                  (on)
+import           Data.List.NonEmpty             (NonEmpty)
+import           Data.List.PointedList          (PointedList)
+import qualified Data.Map                       as M (Map)
+import qualified Data.Text                      as T (Text)
+import qualified Data.Text.Encoding             as E (decodeUtf8, encodeUtf8)
+import           Data.Time                      (UTCTime (..))
+import           Data.Traversable               (Traversable)
+import           Data.Typeable                  (Typeable)
+import           Data.Word                      (Word8)
+import qualified Graphics.Vty                   as Vty (Config)
+import           Yi.Buffer.Basic                (BufferRef, WindowRef)
 import           Yi.Buffer.Implementation
-import           Yi.Buffer.Undo
-import           Yi.Config.Misc
-import           Yi.Event
-import qualified Yi.Interact as I
-import           Yi.KillRing
-import           Yi.Layout
-import           Yi.Monad
-import           Yi.Process (SubprocessInfo, SubprocessId)
-import qualified Yi.Rope as R
-import           Yi.Style
-import           Yi.Style.Library
-import           Yi.Syntax
-import           Yi.Tab
-import           Yi.UI.Common
-import           Yi.Window
+import           Yi.Buffer.Undo                 (URList)
+import           Yi.Config.Misc                 (ScrollStyle)
+import           Yi.Event                       (Event)
+import qualified Yi.Interact                    as I (I, P (End))
+import           Yi.KillRing                    (Killring)
+import           Yi.Layout                      (AnyLayoutManager)
+import           Yi.Monad                       (getsAndModify)
+import           Yi.Process                     (SubprocessId, SubprocessInfo)
+import qualified Yi.Rope                        as R (ConverterName, YiString)
+import           Yi.Style                       (StyleName)
+import           Yi.Style.Library               (Theme)
+import           Yi.Syntax                      (ExtHL, Stroke)
+import           Yi.Tab                         (Tab)
+import           Yi.UI.Common                   (UI)
+import           Yi.Window                      (Window)
 
 
 -- Yi.Keymap
@@ -357,17 +358,11 @@
 
 newtype EditorM a = EditorM {fromEditorM :: ReaderT Config (State Editor) a}
     deriving (Monad, Applicative, MonadState Editor,
-              MonadReader Config, Functor)
+              MonadReader Config, Functor, Typeable)
 
 instance MonadEditor EditorM where
     askCfg = ask
     withEditor = id
-
-#if __GLASGOW_HASKELL__ < 708
-deriving instance Typeable1 EditorM
-#else
-deriving instance Typeable EditorM
-#endif
 
 class (Monad m, MonadState Editor m) => MonadEditor m where
   askCfg :: m Config
diff --git a/src/library/Yi/UI/Batch.hs b/src/library/Yi/UI/Batch.hs
--- a/src/library/Yi/UI/Batch.hs
+++ b/src/library/Yi/UI/Batch.hs
@@ -1,8 +1,8 @@
 
 module Yi.UI.Batch (start) where
 
-import Yi.UI.Common
-import Yi.Config
+import Yi.Config    (UIBoot)
+import Yi.UI.Common (dummyUI)
 
 -- | Initialise the ui
 start :: UIBoot
diff --git a/src/library/Yi/UI/SimpleLayout.hs b/src/library/Yi/UI/SimpleLayout.hs
--- a/src/library/Yi/UI/SimpleLayout.hs
+++ b/src/library/Yi/UI/SimpleLayout.hs
@@ -1,6 +1,7 @@
+{-# LANGUAGE BangPatterns      #-}
+{-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE BangPatterns #-}
-{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE ViewPatterns      #-}
 
 module Yi.UI.SimpleLayout
     ( Rect (..)
@@ -12,25 +13,23 @@
     , verticalOffsetsForWindows
     ) where
 
-import Prelude hiding (concatMap, mapM)
-
-import Control.Lens
-import Control.Monad.State (evalState, get, put)
-import Data.Foldable
-import Data.List (partition)
-import Data.Maybe (fromJust)
-import qualified Data.List.PointedList.Circular as PL
-import qualified Data.Map.Strict as M
-import Data.Monoid
-import qualified Data.Text as T
-import Data.Traversable (mapM)
-
+import           Prelude                        hiding (concatMap, mapM)
 
-import Yi.Buffer
-import Yi.Editor
-import qualified Yi.Rope as R
-import Yi.UI.Utils
-import Yi.Window
+import           Control.Lens                   (use, (.~))
+import           Control.Monad.State            (evalState, get, put)
+import           Data.Foldable                  (find, toList)
+import           Data.List                      (partition)
+import qualified Data.List.PointedList.Circular as PL (PointedList)
+import qualified Data.Map.Strict                as M (Map, fromList)
+import           Data.Maybe                     (fromJust)
+import           Data.Monoid                    ((<>))
+import qualified Data.Text                      as T (uncons)
+import           Data.Traversable               (mapM)
+import           Yi.Buffer
+import           Yi.Editor
+import qualified Yi.Rope                        as R (take, toString, toText)
+import           Yi.UI.Utils                    (arrangeItems)
+import           Yi.Window
 
 data Layout = Layout
     { tabbarRect :: !Rect
@@ -155,7 +154,7 @@
     ts <- fmap tabSize indentSettingsB
     text <- fmap (R.toText . R.take (w * h))
                  (streamB Forward (Point topLeft))
-    let go !x !y !wc !n t | x >= w = go (x - w) (y + 1) (wc + 1) n t
+    let go !x !y !wc !n t | x > w = go (x - w) (y + 1) (wc + 1) n t
         go _  !y !wc !n _ | y >= h = (Point (n - 1), wc)
         go !x !y !wc !n (T.uncons -> Just (c, t)) =
             case c of
diff --git a/src/library/Yi/UI/TabBar.hs b/src/library/Yi/UI/TabBar.hs
--- a/src/library/Yi/UI/TabBar.hs
+++ b/src/library/Yi/UI/TabBar.hs
@@ -11,15 +11,15 @@
 
 module Yi.UI.TabBar where
 
-import           Control.Applicative
-import           Control.Lens
-import qualified Data.List.PointedList.Circular as PL
-import qualified Data.Text as T
-import           System.FilePath
-import           Yi.Buffer (shortIdentString)
-import           Yi.Editor (Editor(..), commonNamePrefix, findBufferWith, tabsA)
-import           Yi.Tab
-import           Yi.Window
+import           Control.Applicative            ((<$>))
+import           Control.Lens                   ((^.))
+import qualified Data.List.PointedList.Circular as PL (PointedList (_focus), withFocus)
+import qualified Data.Text                      as T (Text, pack, unpack)
+import           System.FilePath                (isValid, splitPath)
+import           Yi.Buffer                      (shortIdentString)
+import           Yi.Editor                      (Editor (..), commonNamePrefix, findBufferWith, tabsA)
+import           Yi.Tab                         (tabWindowsA)
+import           Yi.Window                      (Window (bufkey))
 
 -- | A TabDescr describes the properties of a UI tab independent of
 -- the particular GUI in use.
diff --git a/src/library/Yi/UI/Utils.hs b/src/library/Yi/UI/Utils.hs
--- a/src/library/Yi/UI/Utils.hs
+++ b/src/library/Yi/UI/Utils.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE FlexibleContexts #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -11,24 +12,25 @@
 
 module Yi.UI.Utils where
 
-import           Control.Applicative
-import           Control.Arrow (second)
-import           Control.Lens
-import           Control.Monad.State (evalState,modify)
+import           Prelude                   hiding (mapM)
+
+import           Control.Applicative       ((<$>))
+import           Control.Arrow             (second)
+import           Control.Lens              (Traversable, use)
+import           Control.Monad.State       (evalState, modify)
 import           Control.Monad.State.Class (gets)
-import           Data.Foldable (maximumBy)
-import           Data.Function (on)
-import           Data.List (transpose)
-import           Data.List.Split (chunksOf)
-import           Data.Monoid
-import qualified Data.Text as T
-import           Data.Traversable (mapM)
-import           Prelude hiding (mapM)
+import           Data.Foldable             (maximumBy)
+import           Data.Function             (on)
+import           Data.List                 (transpose)
+import           Data.List.Split           (chunksOf)
+import           Data.Monoid               (Endo (appEndo))
+import qualified Data.Text                 as T (Text, null, pack, unpack)
+import           Data.Traversable          (mapM)
 import           Yi.Buffer
-import           Yi.String (padLeft)
-import           Yi.Style
-import           Yi.Syntax (Span(..))
-import           Yi.Window
+import           Yi.String                 (padLeft)
+import           Yi.Style                  (Attributes, StyleName, UIStyle (baseAttributes, selectedStyle))
+import           Yi.Syntax                 (Span (..))
+import           Yi.Window                 (Window (height, isMini))
 
 applyHeights :: Traversable t => [Int] -> t Window -> t Window
 applyHeights heights ws = evalState (mapM distribute ws) heights
diff --git a/src/library/Yi/UI/Vty.hs b/src/library/Yi/UI/Vty.hs
--- a/src/library/Yi/UI/Vty.hs
+++ b/src/library/Yi/UI/Vty.hs
@@ -16,37 +16,58 @@
     ( start
     ) where
 
-import Prelude hiding (error, concatMap, reverse)
-import Control.Applicative hiding ((<|>))
-import Control.Concurrent
-import Control.Exception
-import Control.Lens
-import Control.Monad
-import Data.Char
-import qualified Data.DList as D
-import Data.Foldable (toList, concatMap)
-import Data.IORef
-import qualified Data.List.PointedList.Circular as PL
-import qualified Data.Map.Strict as M
-import Data.Maybe
-import Data.Monoid
-import qualified Data.Text as T
-import qualified Graphics.Vty as Vty
-import GHC.Conc (labelThread)
+import           Prelude                        hiding (concatMap, error,
+                                                 reverse)
 
-import Yi.Buffer
-import Yi.Config
-import Yi.Debug
-import Yi.Editor
-import Yi.Event
-import Yi.Style
-import qualified Yi.UI.Common as Common
-import qualified Yi.UI.SimpleLayout as SL
-import Yi.UI.Vty.Conversions
-import Yi.UI.TabBar
-import Yi.UI.Utils
-import Yi.Window
+import           Control.Applicative            (Applicative ((<*>)), (<$>))
+import           Control.Concurrent             (MVar, forkIO, isEmptyChan,
+                                                 myThreadId, newEmptyMVar,
+                                                 readChan, takeMVar, tryPutMVar,
+                                                 tryTakeMVar)
+import           Control.Exception              (IOException, handle)
+import           Control.Lens                   (use)
+import           Control.Monad                  (void, when)
+import           Data.Char                      (chr, ord)
+import qualified Data.DList                     as D (empty, snoc, toList)
+import           Data.Foldable                  (concatMap, toList)
+import           Data.IORef                     (IORef, newIORef, readIORef, writeIORef)
+import qualified Data.List.PointedList.Circular as PL (PointedList (_focus), withFocus)
+import qualified Data.Map.Strict                as M ((!))
+import           Data.Maybe                     (maybeToList)
+import           Data.Monoid                    (Endo (appEndo), (<>))
+import qualified Data.Text                      as T (Text, cons, empty,
+                                                      justifyLeft, length, pack,
+                                                      singleton, snoc, take,
+                                                      unpack)
+import           GHC.Conc                       (labelThread)
+import qualified Graphics.Vty                   as Vty (Attr, Cursor (Cursor, NoCursor),
+                                                        Event (EvResize), Image,
+                                                        Input (_eventChannel),
+                                                        Output (displayBounds),
+                                                        Picture (picCursor), Vty (inputIface, outputIface, refresh, shutdown, update),
+                                                        bold, char, charFill,
+                                                        defAttr, emptyImage,
+                                                        horizCat, mkVty,
+                                                        picForLayers,
+                                                        reverseVideo, text',
+                                                        translate, underline,
+                                                        vertCat, withBackColor,
+                                                        withForeColor,
+                                                        withStyle, (<|>))
+import           Yi.Buffer
+import           Yi.Config
+import           Yi.Debug                       (logError, logPutStrLn)
+import           Yi.Editor
+import           Yi.Event                       (Event)
+import           Yi.Style
+import qualified Yi.UI.Common                   as Common
+import qualified Yi.UI.SimpleLayout             as SL
+import           Yi.UI.TabBar                   (TabDescr (TabDescr), tabBarDescr)
+import           Yi.UI.Utils                    (arrangeItems, attributesPictureAndSelB)
+import           Yi.UI.Vty.Conversions          (colorToAttr, fromVtyEvent)
+import           Yi.Window                      (Window (bufkey, isMini, wkey))
 
+
 data Rendered = Rendered
     { picture :: !Vty.Image
     , cursor  :: !(Maybe (Int,Int))
@@ -316,7 +337,7 @@
     lines' [] =  []
     lines' s  = case s' of
                   []          -> [l]
-                  ((_,x):s'') -> l : lines' s''
+                  ((_,_):s'') -> l : lines' s''
                 where
                 (l, s') = break ((== '\n') . fst) s
 
diff --git a/src/library/Yi/UI/Vty/Conversions.hs b/src/library/Yi/UI/Vty/Conversions.hs
--- a/src/library/Yi/UI/Vty/Conversions.hs
+++ b/src/library/Yi/UI/Vty/Conversions.hs
@@ -5,11 +5,15 @@
     , fromVtyMod
     ) where
 
-import Data.List (nub, sort)
-import qualified Graphics.Vty as Vty
-
-import qualified Yi.Event
-import qualified Yi.Style
+import           Data.List    (nub, sort)
+import qualified Graphics.Vty as Vty (Attr, Color, Event (EvKey), Key (KBS, KBackTab, KBegin, KCenter, KChar, KDel, KDown, KEnd, KEnter, KEsc, KFun, KHome, KIns, KLeft, KMenu, KPageDown, KPageUp, KPause, KPrtScr, KRight, KUp),
+                                      Modifier (..), black, blue, brightBlack,
+                                      brightBlue, brightCyan, brightGreen,
+                                      brightMagenta, brightRed, brightWhite,
+                                      brightYellow, cyan, green, magenta, red,
+                                      rgbColor, white, yellow)
+import qualified Yi.Event     (Event (..), Key (..), Modifier (MCtrl, MMeta, MShift))
+import qualified Yi.Style     (Color (..))
 
 fromVtyEvent :: Vty.Event -> Yi.Event.Event
 fromVtyEvent (Vty.EvKey Vty.KBackTab mods) =
diff --git a/src/library/Yi/Verifier/JavaScript.hs b/src/library/Yi/Verifier/JavaScript.hs
--- a/src/library/Yi/Verifier/JavaScript.hs
+++ b/src/library/Yi/Verifier/JavaScript.hs
@@ -1,4 +1,5 @@
-{-# LANGUAGE FlexibleInstances, FlexibleContexts #-}
+{-# LANGUAGE FlexibleContexts  #-}
+{-# LANGUAGE FlexibleInstances #-}
 
 -- TODO:
 -- ! User configuration.
@@ -6,15 +7,15 @@
 
 module Yi.Verifier.JavaScript where
 
-import Control.Monad.Writer.Lazy (Writer, MonadWriter, tell)
-import Control.Monad
-import Data.List (intercalate)
-import Data.Foldable (toList)
-import Data.Function (on)
-import qualified Data.DList as D
-import Yi.Lexer.Alex (Posn, Tok, tokT, tokPosn)
-import Yi.Lexer.JavaScript (Token(..), TT)
-import Yi.Syntax.JavaScript hiding (res)
+import           Control.Monad             (unless)
+import           Control.Monad.Writer.Lazy (MonadWriter, Writer, tell)
+import qualified Data.DList                as D (DList, singleton)
+import           Data.Foldable             (toList)
+import           Data.Function             (on)
+import           Data.List                 (intercalate)
+import           Yi.Lexer.Alex             (Posn, Tok, tokPosn, tokT)
+import           Yi.Lexer.JavaScript       (TT, Token (..))
+import           Yi.Syntax.JavaScript      hiding (res)
 
 
 -- * Types
diff --git a/src/library/Yi/Window.hs b/src/library/Yi/Window.hs
--- a/src/library/Yi/Window.hs
+++ b/src/library/Yi/Window.hs
@@ -1,5 +1,5 @@
 {-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TemplateHaskell    #-}
 {-# OPTIONS_HADDOCK show-extensions #-}
 
 -- |
@@ -13,14 +13,14 @@
 
 module Yi.Window where
 
-import Data.Binary
-import Data.Default
-import Data.Typeable
-import Control.Applicative
-import Yi.Buffer.Basic (BufferRef, WindowRef)
-import Yi.Region (Region,emptyRegion)
-import Yi.JumpList
-import Yi.Utils (makeLensesWithSuffix)
+import Control.Applicative (Applicative ((<*>)), (<$>))
+import Data.Binary         (Binary (..))
+import Data.Default        (Default (def))
+import Data.Typeable       (Typeable)
+import Yi.Buffer.Basic     (BufferRef, WindowRef)
+import Yi.JumpList         (JumpList)
+import Yi.Region           (Region, emptyRegion)
+import Yi.Utils            (makeLensesWithSuffix)
 
 ------------------------------------------------------------------------
 -- | A window onto a buffer.
diff --git a/src/tests/Generic/TestPureBufferManipulations.hs b/src/tests/Generic/TestPureBufferManipulations.hs
--- a/src/tests/Generic/TestPureBufferManipulations.hs
+++ b/src/tests/Generic/TestPureBufferManipulations.hs
@@ -154,7 +154,7 @@
 optionalSettingAction :: OptionalSetting -> EditorM ()
 optionalSettingAction (WindowSize w h) = 
     let region = mkSizeRegion (Point 0) (Size (w*h))
-    in currentWindowA %= (\w -> w { height = h, winRegion = region })
+    in currentWindowA %= (\w -> w { height = h, actualLines = h, winRegion = region })
 
 mkTestCase :: Config -> KeymapTest -> TestTree
 mkTestCase cf t = testCase (ktName t) $ do
diff --git a/src/tests/vimtests/change/s_eol.test b/src/tests/vimtests/change/s_eol.test
new file mode 100644
--- /dev/null
+++ b/src/tests/vimtests/change/s_eol.test
@@ -0,0 +1,12 @@
+-- Input
+(1,11)
+Lorem ipsum dolor sit amet
+abc def ghi
+qwe rty uiop
+-- Output
+(1,26)
+Lorem ipsum dolor sit amex
+abc def ghi
+qwe rty uiop
+-- Events
+$sx<Esc>
diff --git a/src/tests/vimtests/indent/7.test b/src/tests/vimtests/indent/7.test
new file mode 100644
--- /dev/null
+++ b/src/tests/vimtests/indent/7.test
@@ -0,0 +1,18 @@
+-- Input
+(1,1)
+    foo
+    bar
+
+    baz
+    123
+
+-- Output
+(1,9)
+        foo
+        bar
+
+        baz
+        123
+
+-- Events
+5>>
diff --git a/src/tests/vimtests/indent/8.test b/src/tests/vimtests/indent/8.test
new file mode 100644
--- /dev/null
+++ b/src/tests/vimtests/indent/8.test
@@ -0,0 +1,18 @@
+-- Input
+(1,1)
+        foo
+        bar
+
+        baz
+        123
+
+-- Output
+(1,5)
+    foo
+    bar
+
+    baz
+    123
+
+-- Events
+<lt>4j
diff --git a/src/tests/vimtests/insertion/a_on_empty_line.test b/src/tests/vimtests/insertion/a_on_empty_line.test
new file mode 100644
--- /dev/null
+++ b/src/tests/vimtests/insertion/a_on_empty_line.test
@@ -0,0 +1,12 @@
+-- Input
+(2,1)
+
+
+
+-- Output
+(2,1)
+
+q
+
+-- Events
+aq<Esc>
diff --git a/src/tests/vimtests/repeat/O1.test b/src/tests/vimtests/repeat/O1.test
deleted file mode 100644
--- a/src/tests/vimtests/repeat/O1.test
+++ /dev/null
@@ -1,17 +0,0 @@
--- Input
-(2,1)
-123
-456
-789
--- Output
-(7,3)
-123
-456
-abc
-abc
-abc
-abc
-abc
-789
--- Events
-2oabc<Esc>3.
diff --git a/src/tests/vimtests/visual/indent_11.test b/src/tests/vimtests/visual/indent_11.test
new file mode 100644
--- /dev/null
+++ b/src/tests/vimtests/visual/indent_11.test
@@ -0,0 +1,22 @@
+-- Input
+(1,1)
+
+def main():
+foo()
+bar()
+
+baz()
+quux()
+
+-- Output
+(3,5)
+
+def main():
+    foo()
+    bar()
+
+    baz()
+    quux()
+
+-- Events
+jjV}}>
diff --git a/src/tests/vimtests/visual/indent_12.test b/src/tests/vimtests/visual/indent_12.test
new file mode 100644
--- /dev/null
+++ b/src/tests/vimtests/visual/indent_12.test
@@ -0,0 +1,22 @@
+-- Input
+(1,1)
+
+def main():
+foo()
+bar()
+
+baz()
+quux()
+
+-- Output
+(3,1)
+
+def main():
+    foo()
+    bar()
+
+    baz()
+    quux()
+
+-- Events
+jj<C-v>}}>
diff --git a/src/tests/vimtests/visual/indent_13.test b/src/tests/vimtests/visual/indent_13.test
new file mode 100644
--- /dev/null
+++ b/src/tests/vimtests/visual/indent_13.test
@@ -0,0 +1,22 @@
+-- Input
+(1,1)
+
+def main():
+        foo()
+        bar()
+
+        baz()
+        quux()
+
+-- Output
+(3,1)
+
+def main():
+    foo()
+    bar()
+
+    baz()
+    quux()
+
+-- Events
+jj<C-v>}}<lt>
diff --git a/yi.cabal b/yi.cabal
--- a/yi.cabal
+++ b/yi.cabal
@@ -1,5 +1,5 @@
 name:           yi
-version:        0.11.2
+version:        0.12.0
 category:       Development, Editor
 synopsis:       The Haskell-Scriptable Editor
 description:
@@ -9,10 +9,10 @@
 license-file:   LICENSE
 author:         AUTHORS
 maintainer:     yi-devel@googlegroups.com
-homepage:       http://haskell.org/haskellwiki/Yi
+homepage:       https://yi-editor.github.io
 bug-reports:    https://github.com/yi-editor/yi/issues
-Cabal-Version:  >= 1.10
-tested-with:    GHC==7.8.3
+Cabal-Version:  >= 1.20
+tested-with:    GHC==7.8.4, GHC==7.10.1
 build-type:     Simple
 data-files:
   art/*.png
@@ -103,6 +103,13 @@
 flag testing
   Description: bake-in the self-checks
 
+flag hint
+  Default: False
+  -- TODO: figure out how to write this
+  -- if impl(ghc < 7.10.1)
+  --   Default: True
+  Description: Include hint (haskell interpreter) in yi
+
 library
   hs-source-dirs: src/library
   default-language: Haskell2010
@@ -113,6 +120,9 @@
   if flag(eventlog)
     CPP-options: -DEVENTLOG
 
+  if flag(hint)
+    CPP-options: -DHINT
+
   exposed-modules:
     Yi
     Yi.Boot
@@ -251,28 +261,26 @@
     Yi.Window
     Yi.Char.Unicode
 
-  if impl(ghc < 7.8)
-    build-depends: derive >=2.4 && <2.7, binary >= 0.5, tagged
-  else
-    build-depends: binary >= 0.7
+  if flag(hint)
+    build-depends: hint > 0.3.1
+
   build-depends:
     Cabal >= 1.10,
     array,
+    binary >= 0.7,
     containers,
     directory,
     process >= 1.0.1.1,
     old-locale,
     base >= 4 && < 5,
     bytestring >= 0.9.1 && < 0.11,
-    cautious-file >= 1.0.1,
     dynamic-state >= 0.1.0.5,
     data-default,
     lens >= 4.4.0.1,
     dlist >=0.4.1,
     dyre >=0.8.11,
-    filepath>=1.1 && <1.4,
+    filepath >= 1.1,
     hashable >=1.1.2.5,
-    hint > 0.3.1,
     mtl >= 0.1.0.1,
     parsec >= 3.0,
     pointedlist >= 0.5,
@@ -283,7 +291,6 @@
     template-haskell >= 2.4,
     text >= 1.1.1.3,
     time >= 1.1,
-    utf8-string >= 0.3.1,
     unix-compat >=0.1 && <0.5,
     unordered-containers >= 0.1.3 && < 0.3,
     xdg-basedir >= 0.2.1 && < 0.3,
