diff --git a/src/Yi/Core.hs b/src/Yi/Core.hs
--- a/src/Yi/Core.hs
+++ b/src/Yi/Core.hs
@@ -41,7 +41,7 @@
   , runAction
   , withSyntax
   , focusAllSyntax
-  , forkAction
+  , onYiVar
   ) where
 
 import           Prelude                        hiding (elem, mapM_, or)
@@ -157,56 +157,6 @@
 
     UI.main ui -- transfer control to UI
 
--- | Runs a 'YiM' action in a separate thread.
---
--- Notes:
---
--- * It seems to work but I don't know why
---
--- * Maybe deadlocks?
---
--- * If you're outputting into the Yi window, you should really limit
--- the rate at which you do so: for example, the Pango front-end will
--- quite happily segfault/double-free if you output too fast.
---
--- I am exporting this for those adventurous to play with but I have
--- only discovered how to do this a night before the release so it's
--- rather experimental. A simple function that prints a message once a
--- second, 5 times, could be written like this:
---
--- @
--- printer :: YiM ThreadId
--- printer = do
---   mv <- io $ newMVar (0 :: Int)
---   forkAction (suicide mv) MustRefresh $ do
---     c <- io $ do
---       modifyMVar_ mv (return . succ)
---       tryReadMVar mv
---     case c of
---       Nothing -> printMsg "messaging unknown time"
---       Just x -> printMsg $ "message #" <> showT x
---   where
---     suicide mv = tryReadMVar mv >>= \case
---       Just i | i >= 5 -> return True
---       _ -> threadDelay 1000000 >> return False
--- @
-forkAction :: (YiAction a x, Show x)
-           => IO Bool
-              -- ^ runs after we insert the action: this may be a
-              -- thread delay or a thread suicide or whatever else;
-              -- when delay returns False, that's our signal to
-              -- terminate the thread.
-           -> IsRefreshNeeded
-              -- ^ should we refresh after each action
-           -> a
-              -- ^ The action to actually run
-           -> YiM ThreadId
-forkAction delay ref ym = onYiVar $ \yi yv -> do
-  let loop = do
-        yiOutput yi ref [makeAction ym]
-        delay >>= \b -> when b loop
-  t <- forkIO loop
-  return (yv, t)
 
 recoverMode :: [AnyMode] -> FBuffer -> FBuffer
 recoverMode tbl buffer  = case fromMaybe (AnyMode emptyMode) (find (\(AnyMode m) -> modeName m == oldName) tbl) of
diff --git a/src/Yi/MiniBuffer.hs b/src/Yi/MiniBuffer.hs
--- a/src/Yi/MiniBuffer.hs
+++ b/src/Yi/MiniBuffer.hs
@@ -27,14 +27,12 @@
                      , getAllModeNames, matchingBufferNames, anyModeByNameM
                      , anyModeName, (:::)(..), LineNumber, RegexTag
                      , FilePatternTag, ToKill, CommandArguments(..)
-                     , commentRegion, promptingForBuffer, debugBufferContent
+                     , commentRegion, promptingForBuffer
                      ) where
 
-import           Control.Concurrent             (threadDelay)
-import           Lens.Micro.Platform                   (use, (%=))
-import           Control.Monad                  (forM, void, when, (<=<), (>=>))
+import           Lens.Micro.Platform            (use, (%=))
+import           Control.Monad                  (forM, void, (<=<), (>=>))
 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.Proxy                     (Proxy)
@@ -47,7 +45,7 @@
 import           Yi.Buffer
 import           Yi.Completion
 import           Yi.Config                      (modeTable)
-import           Yi.Core                        (forkAction, runAction)
+import           Yi.Core                        (runAction)
 import           Yi.Editor
 import           Yi.History                     (historyFinishGen, historyMove, historyStartGen)
 import           Yi.Keymap
@@ -56,29 +54,7 @@
 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.
---
--- The only way to stop it is to close the buffer in question which
--- should free up the 'BufferRef'.
-debugBufferContent :: YiM ()
-debugBufferContent = promptingForBuffer "buffer to trace:"
-                     debugBufferContentUsing (\_ x -> x)
-
-debugBufferContentUsing :: BufferRef -> YiM ()
-debugBufferContentUsing b = do
-  mv <- io $ newIORef mempty
-  keepGoing <- io $ newIORef True
-  let delay = threadDelay 100000 >> readIORef keepGoing
-  void . forkAction delay NoNeedToRefresh $
-    findBuffer b >>= \case
-      Nothing -> io $ writeIORef keepGoing True
-      Just _ -> do
-        ns <- withGivenBuffer b elemsB :: YiM R.YiString
-        io $ readIORef mv >>= \c ->
-          when (c /= ns) (print ns >> void (writeIORef mv ns))
 
 -- | Prompts for a buffer name, turns it into a 'BufferRef' and passes
 -- it on to the handler function. Uses all known buffers for hinting.
diff --git a/src/Yi/Misc.hs b/src/Yi/Misc.hs
--- a/src/Yi/Misc.hs
+++ b/src/Yi/Misc.hs
@@ -19,9 +19,11 @@
                , printFileInfoE, debugBufferContent
                ) where
 
-import           Control.Monad           (filterM, (>=>))
+import           Control.Concurrent
+import           Control.Monad           (filterM, (>=>), when, void)
 import           Control.Monad.Base      (liftBase)
 import           Data.Char               (chr, isAlpha, isLower, isUpper, ord)
+import           Data.IORef
 import           Data.List               ((\\))
 import           Data.Maybe              (isNothing)
 import qualified Data.Text               as T (Text, append, concat, isPrefixOf,
@@ -38,11 +40,13 @@
 import           System.FriendlyPath     (expandTilda, isAbsolute')
 import           Yi.Buffer
 import           Yi.Completion           (completeInList')
-import           Yi.Editor               (EditorM, printMsg, withCurrentBuffer)
-import           Yi.Keymap               (YiM)
-import           Yi.MiniBuffer           (debugBufferContent, mkCompleteFn, withMinibufferGen)
+import           Yi.Core                 (onYiVar)
+import           Yi.Editor               (EditorM, printMsg, withCurrentBuffer, withGivenBuffer, findBuffer)
+import           Yi.Keymap               (YiM, makeAction, YiAction)
+import           Yi.MiniBuffer           (mkCompleteFn, withMinibufferGen, promptingForBuffer)
 import           Yi.Monad                (gets)
-import qualified Yi.Rope                 as R (fromText)
+import qualified Yi.Rope                 as R (fromText, YiString)
+import           Yi.Types                (IsRefreshNeeded(..), Yi(..))
 import           Yi.Utils                (io)
 
 -- | Given a possible starting path (which if not given defaults to
@@ -212,3 +216,75 @@
             , bufInfoPercent bufInfo
             , "]"
             ]
+
+-- | Runs a 'YiM' action in a separate thread.
+--
+-- Notes:
+--
+-- * It seems to work but I don't know why
+--
+-- * Maybe deadlocks?
+--
+-- * If you're outputting into the Yi window, you should really limit
+-- the rate at which you do so: for example, the Pango front-end will
+-- quite happily segfault/double-free if you output too fast.
+--
+-- I am exporting this for those adventurous to play with but I have
+-- only discovered how to do this a night before the release so it's
+-- rather experimental. A simple function that prints a message once a
+-- second, 5 times, could be written like this:
+--
+-- @
+-- printer :: YiM ThreadId
+-- printer = do
+--   mv <- io $ newMVar (0 :: Int)
+--   forkAction (suicide mv) MustRefresh $ do
+--     c <- io $ do
+--       modifyMVar_ mv (return . succ)
+--       tryReadMVar mv
+--     case c of
+--       Nothing -> printMsg "messaging unknown time"
+--       Just x -> printMsg $ "message #" <> showT x
+--   where
+--     suicide mv = tryReadMVar mv >>= \case
+--       Just i | i >= 5 -> return True
+--       _ -> threadDelay 1000000 >> return False
+-- @
+forkAction :: (YiAction a x, Show x)
+           => IO Bool
+              -- ^ runs after we insert the action: this may be a
+              -- thread delay or a thread suicide or whatever else;
+              -- when delay returns False, that's our signal to
+              -- terminate the thread.
+           -> IsRefreshNeeded
+              -- ^ should we refresh after each action
+           -> a
+              -- ^ The action to actually run
+           -> YiM ThreadId
+forkAction delay ref ym = onYiVar $ \yi yv -> do
+  let loop = do
+        yiOutput yi ref [makeAction ym]
+        delay >>= \b -> when b loop
+  t <- forkIO loop
+  return (yv, t)
+
+-- | Prints out the rope of the current buffer as-is to stdout.
+--
+-- The only way to stop it is to close the buffer in question which
+-- should free up the 'BufferRef'.
+debugBufferContent :: YiM ()
+debugBufferContent = promptingForBuffer "buffer to trace:"
+                     debugBufferContentUsing (\_ x -> x)
+
+debugBufferContentUsing :: BufferRef -> YiM ()
+debugBufferContentUsing b = do
+  mv <- io $ newIORef mempty
+  keepGoing <- io $ newIORef True
+  let delay = threadDelay 100000 >> readIORef keepGoing
+  void . forkAction delay NoNeedToRefresh $
+    findBuffer b >>= \case
+      Nothing -> io $ writeIORef keepGoing True
+      Just _ -> do
+        ns <- withGivenBuffer b elemsB :: YiM R.YiString
+        io $ readIORef mv >>= \c ->
+          when (c /= ns) (print ns >> void (writeIORef mv ns))
diff --git a/src/Yi/Snippets.hs b/src/Yi/Snippets.hs
deleted file mode 100644
--- a/src/Yi/Snippets.hs
+++ /dev/null
@@ -1,419 +0,0 @@
-{-# LANGUAGE CPP                        #-}
-{-# LANGUAGE DeriveDataTypeable         #-}
-{-# LANGUAGE DeriveGeneric              #-}
-{-# LANGUAGE FlexibleContexts           #-}
-{-# LANGUAGE FlexibleInstances          #-}
-{-# LANGUAGE FunctionalDependencies     #-}
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE LambdaCase                 #-}
-{-# LANGUAGE OverloadedStrings          #-}
-{-# LANGUAGE TemplateHaskell            #-}
-{-# OPTIONS_HADDOCK show-extensions #-}
-
--- |
--- Module      :  Yi.Snippets
--- License     :  GPL-2
--- Maintainer  :  yi-devel@googlegroups.com
--- Stability   :  experimental
--- Portability :  portable
-
-module Yi.Snippets where
-
-import           GHC.Generics (Generic)
-
-import           Control.Applicative (some)
-import           Control.Arrow       (second)
-import           Lens.Micro.Platform          (use, (.=))
-import           Control.Monad.RWS   (MonadPlus (mplus), MonadReader (ask),
-                                      MonadState, MonadTrans (..),
-                                      MonadWriter (tell), RWST, evalRWST,
-                                      filterM, forM, forM_, 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           (withCurrentBuffer)
-import           Yi.Keymap           (Action)
-import           Yi.Keymap.Keys
-import qualified Yi.Rope             as R
-import           Yi.TextCompletion   (resetComplete, wordCompleteString')
-import           Yi.Types            (YiVariable)
-
-type SnippetCmd = RWST (Int, Int) [MarkInfo] () BufferM
-
-data SnippetMark = SimpleMark !Int
-                 | ValuedMark !Int R.YiString
-                 | DependentMark !Int
-
-
-data MarkInfo = SimpleMarkInfo { userIndex :: !Int
-                               , startMark :: !Mark }
-              | ValuedMarkInfo { userIndex :: !Int
-                               , startMark :: !Mark
-                               , endMark :: !Mark }
-              | DependentMarkInfo { userIndex :: !Int
-                                  , startMark :: !Mark
-                                  , endMark :: !Mark }
-  deriving (Eq, Show, Generic)
-
-instance Binary MarkInfo
-
-newtype BufferMarks = BufferMarks { bufferMarks :: [MarkInfo] }
-  deriving (Eq, Show, Monoid, Typeable, Binary)
-
-newtype DependentMarks = DependentMarks { marks :: [[MarkInfo]] }
-  deriving (Eq, Show, Monoid, Typeable, Binary)
-
-instance Default BufferMarks where
-  def = BufferMarks []
-
-instance Default DependentMarks where
-  def = DependentMarks []
-
-instance YiVariable BufferMarks
-instance YiVariable DependentMarks
-
-instance Ord MarkInfo where
-  a `compare` b = userIndex a `compare` userIndex b
-
-cursor :: Int -> SnippetMark
-cursor = SimpleMark
-
-cursorWith :: Int -> R.YiString -> SnippetMark
-cursorWith = ValuedMark
-
-dep :: Int -> SnippetMark
-dep = DependentMark
-
-isDependentMark :: MarkInfo -> Bool
-isDependentMark (SimpleMarkInfo{})    = False
-isDependentMark (ValuedMarkInfo{})    = False
-isDependentMark (DependentMarkInfo{}) = True
-
-bufferMarkers :: MarkInfo -> [Mark]
-bufferMarkers (SimpleMarkInfo _ s) = [s]
-bufferMarkers m = [startMark m, endMark m]
-
--- used to translate a datatype into a snippet cmd for
--- freely combining data with '&'
-class MkSnippetCmd a b | a -> b where
-  mkSnippetCmd :: a -> SnippetCmd b
-
-instance MkSnippetCmd String () where
-  mkSnippetCmd = text . R.fromString
-
-instance MkSnippetCmd R.YiString () where
-  mkSnippetCmd = text
-
-instance MkSnippetCmd T.Text () where
-  mkSnippetCmd = text . R.fromText
-
-instance MkSnippetCmd (SnippetCmd a) a where
-  mkSnippetCmd = id
-
--- mkSnippetCmd for 'cursor...'-functions
-instance MkSnippetCmd SnippetMark () where
-  mkSnippetCmd (SimpleMark i) = do
-      mk <- mkMark
-      tell [SimpleMarkInfo i mk]
-
-  mkSnippetCmd (ValuedMark i str) = do
-      start <- mkMark
-      lift $ insertN str
-      end <- mkMark
-      tell [ValuedMarkInfo i start end]
-
-  mkSnippetCmd (DependentMark i) = do
-      start <- mkMark
-      end <- mkMark
-      tell [DependentMarkInfo i start end]
-
--- create a mark at current position
-mkMark :: MonadTrans t => t BufferM Mark
-mkMark = lift $ do p <- pointB
-                   newMarkB $ MarkValue p Backward
-
--- Indentation support has been temporarily removed
-text :: R.YiString -> SnippetCmd ()
-text txt = do
-  (_, indent) <- ask
-  indentSettings <- lift indentSettingsB
-  lift . foldl' (>>) (return ()) .
-      intersperse (newlineB >> indentToB indent) .
-      map (if expandTabs indentSettings
-           then insertN . expand indentSettings ""
-           else insertN) $ lines' txt
-  where
-    lines' txt' = case R.last txt' of
-      Just '\n' -> R.lines txt' <> [mempty]
-      _         -> R.lines txt
-
-    expand :: IndentSettings -> R.YiString -> R.YiString -> R.YiString
-    expand is str rst = case R.head rst of
-      Nothing -> R.reverse str
-      Just '\t' -> let t = R.replicateChar (tabSize is) ' ' <> str
-                   in expand is t (R.drop 1 rst)
-      Just s -> expand is (s `R.cons` str) rst
-
--- unfortunatelly data converted to snippets are no monads, but '&' is
--- very similar to '>>' and '&>' is similar to '>>=', since
--- SnippetCmd's can be used monadically
-infixr 5 &
-(&) :: (MkSnippetCmd a any , MkSnippetCmd b c) => a -> b -> SnippetCmd c
-str & rst = mkSnippetCmd str >> mkSnippetCmd rst
-
-(&>) :: (MkSnippetCmd a b, MkSnippetCmd c d) => a -> (b -> c) -> SnippetCmd d
-str &> rst = mkSnippetCmd str >>= mkSnippetCmd . rst
-
-runSnippet :: Bool -> SnippetCmd a -> BufferM a
-runSnippet deleteLast s = do
-    line <- lineOf =<< pointB
-    indent <- indentOfCurrentPosB
-    (a, markInfo) <- evalRWST s (line, indent) ()
-    unless (null markInfo) $ do
-        let newMarks = sort $ filter (not . isDependentMark) markInfo
-        let newDepMarks = filter (not . len1) $
-                            groupBy belongTogether $
-                              sort markInfo
-        getBufferDyn >>= putBufferDyn.(BufferMarks newMarks `mappend`)
-        unless (null newDepMarks) $
-            getBufferDyn >>= putBufferDyn.(DependentMarks newDepMarks `mappend`)
-        moveToNextBufferMark deleteLast
-    return a
-  where
-    len1 (_:[]) = True
-    len1 _      = False
-
-    belongTogether a b = userIndex a == userIndex b
-
-updateUpdatedMarks :: [Update] -> BufferM ()
-updateUpdatedMarks upds = findEditedMarks upds >>=
-                          mapM_ updateDependents
-
-findEditedMarks :: [Update] -> BufferM [MarkInfo]
-findEditedMarks upds = fmap (nub . concat) (mapM findEditedMarks' upds)
-  where
-    findEditedMarks' :: Update -> BufferM [MarkInfo]
-    findEditedMarks' upd = do
-        let p = updatePoint upd
-        ms <- return . nub . concat . marks =<< getBufferDyn
-        ms' <- forM ms $ \m ->do
-                 r <- adjMarkRegion m
-                 return $ if (updateIsDelete upd && p `nearRegion` r)
-                             || p `inRegion` r
-                          then Just m
-                          else Nothing
-        return . catMaybes $ ms'
-
-dependentSiblings :: MarkInfo -> [[MarkInfo]] -> [MarkInfo]
-dependentSiblings mark deps =
-  case find (elem mark) deps of
-    Nothing -> []
-    Just lst -> filter (not . (mark==)) lst
-
-updateDependents :: MarkInfo -> BufferM ()
-updateDependents m = getBufferDyn >>= updateDependents' m . marks
-
-updateDependents' :: MarkInfo -> [[MarkInfo]] -> BufferM ()
-updateDependents' mark deps =
-  case dependentSiblings mark deps of
-    []   -> return ()
-    deps' -> do
-      txt <- markText mark
-      forM_ deps' $ \d -> do
-        dTxt <- markText d
-        when (txt /= dTxt) $ setMarkText txt d
-
-markText :: MarkInfo -> BufferM R.YiString
-markText m = markRegion m >>= readRegionB
-
-setMarkText :: R.YiString -> MarkInfo -> BufferM ()
-setMarkText txt (SimpleMarkInfo _ start) = do
-  p <- use $ markPointA start
-  c <- readAtB p
-  if isSpace c
-    then insertNAt txt p
-    else do
-      r <- regionOfPartNonEmptyAtB unitViWordOnLine Forward p
-      modifyRegionB (const txt) r
-
-setMarkText txt mi = do
-    start <- use $ markPointA $ startMark mi
-    end   <- use $ markPointA $ endMark mi
-    let r = mkRegion start end
-    modifyRegionB (const txt) r
-    when (start == end) $
-      markPointA (endMark mi) .= end + Point (R.length txt)
-
-withSimpleRegion :: MarkInfo -> (Region -> BufferM Region) -> BufferM Region
-withSimpleRegion (SimpleMarkInfo _ s) f = do
-    p <- use $ markPointA s
-    c <- readAtB p
-    if isSpace c
-      then return $ mkRegion p p  -- return empty region
-      else f =<< regionOfPartNonEmptyAtB unitViWordOnLine Forward p
-withSimpleRegion r _ = error $ "withSimpleRegion: " <> show r
-
-markRegion :: MarkInfo -> BufferM Region
-markRegion m@SimpleMarkInfo{} = withSimpleRegion m $ \r -> do
-    os <- findOverlappingMarksWith safeMarkRegion concat True r m
-    rOs <- mapM safeMarkRegion os
-    return . mkRegion (regionStart r) $ foldl' minEnd (regionEnd r) rOs
-  where
-    minEnd end r = if regionEnd r < end
-                   then end
-                   else min end $ regionStart r
-
-markRegion m = liftM2 mkRegion
-                   (use $ markPointA $ startMark m)
-                   (use $ markPointA $ endMark m)
-
-safeMarkRegion :: MarkInfo -> BufferM Region
-safeMarkRegion m@(SimpleMarkInfo _ _) = withSimpleRegion m return
-safeMarkRegion m = markRegion m
-
-adjMarkRegion :: MarkInfo -> BufferM Region
-adjMarkRegion s@(SimpleMarkInfo _ _) = markRegion s
-
-adjMarkRegion m = do
-    s <- use $ markPointA $ startMark m
-    e <- use $ markPointA $ endMark m
-    c <- readAtB e
-    when (isWordChar c) $ do adjustEnding e
-                             repairOverlappings e
-    e' <- use $ markPointA $ endMark m
-    s' <- adjustStart s e'
-    return $ mkRegion s' e'
-  where
-    adjustEnding end = do
-        r' <- regionOfPartNonEmptyAtB unitViWordOnLine Forward end
-        markPointA (endMark m) .= (regionEnd r')
-
-    adjustStart s e = do
-        txt <- readRegionB (mkRegion s e)
-        let sP = s + (Point . R.length $ R.takeWhile isSpace txt)
-        when (sP > s) $
-            markPointA (startMark m) .= sP
-        return sP
-
-    -- test if we generated overlappings and repair
-    repairOverlappings origEnd = do overlappings <- allOverlappingMarks True m
-                                    unless (null overlappings) $
-                                        markPointA (endMark m) .= origEnd
-
-findOverlappingMarksWith :: (MarkInfo -> BufferM Region)
-                         -> ([[MarkInfo]] -> [MarkInfo])
-                         -> Bool -> Region -> MarkInfo -> BufferM [MarkInfo]
-findOverlappingMarksWith fMarkRegion flattenMarks border r m =
-  let markFilter = filter (m /=) . flattenMarks . marks
-      regOverlap = fmap (regionsOverlap border r) . fMarkRegion
-  in fmap markFilter getBufferDyn >>= filterM regOverlap
-
-findOverlappingMarks :: ([[MarkInfo]] -> [MarkInfo]) -> Bool -> Region ->
-                        MarkInfo -> BufferM [MarkInfo]
-findOverlappingMarks = findOverlappingMarksWith markRegion
-
-regionsOverlappingMarks :: Bool -> Region -> MarkInfo -> BufferM [MarkInfo]
-regionsOverlappingMarks = findOverlappingMarks concat
-
-overlappingMarks :: Bool -> Bool -> MarkInfo -> BufferM [MarkInfo]
-overlappingMarks border belongingTogether mark = do
-    r <- markRegion mark
-    findOverlappingMarks (if belongingTogether
-                          then dependentSiblings mark
-                          else concat)
-                         border
-                         r
-                         mark
-
-allOverlappingMarks :: Bool -> MarkInfo -> BufferM [MarkInfo]
-allOverlappingMarks border = overlappingMarks border False
-
-dependentOverlappingMarks :: Bool -> MarkInfo -> BufferM [MarkInfo]
-dependentOverlappingMarks border = overlappingMarks border True
-
-nextBufferMark :: Bool -> BufferM (Maybe MarkInfo)
-nextBufferMark deleteLast = do
-  BufferMarks ms <- getBufferDyn
-  if null ms
-    then return Nothing
-    else do
-      let mks = if deleteLast then const $ tail ms else (tail ms <>)
-      putBufferDyn . BufferMarks . mks $ [head ms]
-      return . Just $ head ms
-
-isDependentMarker :: (MonadState FBuffer m, Functor m) => Mark -> m Bool
-isDependentMarker bMark = do
-    DependentMarks ms <- getBufferDyn
-    return . elem bMark . concatMap bufferMarkers . concat $ ms
-
-safeDeleteMarkB :: Mark -> BufferM ()
-safeDeleteMarkB m = do
-    b <- isDependentMarker m
-    unless b (deleteMarkB m)
-
-moveToNextBufferMark :: Bool -> BufferM ()
-moveToNextBufferMark deleteLast = nextBufferMark deleteLast >>= \case
-  Just p  -> mv p
-  Nothing -> return ()
-  where
-    mv (SimpleMarkInfo _ m)   = do
-        moveTo =<< use (markPointA m)
-        when deleteLast $ safeDeleteMarkB m
-
-    mv (ValuedMarkInfo _ s e) = do
-        sp <- use $ markPointA s
-        ep <- use $ markPointA e
-        deleteRegionB (mkRegion sp ep)
-        moveTo sp
-        when deleteLast $ do
-            safeDeleteMarkB s
-            safeDeleteMarkB e
-
-    mv r = error $ "moveToNextBufferMark.mv: " <> show r
-
--- Keymap support
-
-newtype SupertabExt = Supertab (R.YiString -> Maybe (BufferM ()))
-
-instance Monoid SupertabExt where
-  mempty = Supertab $ const Nothing
-
-  (Supertab f) `mappend` (Supertab g) =
-    Supertab $ \s -> f s `mplus` g s
-
-superTab :: (MonadInteract m Action Event) => Bool -> SupertabExt -> m ()
-superTab caseSensitive (Supertab expander) =
-    some (spec KTab ?>>! doSuperTab) >> deprioritize >>! resetComplete
-  where
-    doSuperTab = do canExpand <- withCurrentBuffer $ do
-                                   sol <- atSol
-                                   ws  <- hasWhiteSpaceBefore
-                                   return $ sol || ws
-                    if canExpand
-                      then insertTab
-                      else runCompleter
-
-    insertTab = withCurrentBuffer $ mapM_ insertB =<< tabB
-
-    runCompleter = do w <- withCurrentBuffer readPrevWordB
-                      case expander w of
-                        Just cmd -> withCurrentBuffer $ bkillWordB >> cmd
-                        _        -> autoComplete
-
-    autoComplete = wordCompleteString' caseSensitive >>=
-                   withCurrentBuffer . (bkillWordB >>) . (insertN . R.fromText)
-
--- | Convert snippet description list into a SuperTab extension
-fromSnippets :: Bool -> [(R.YiString, SnippetCmd ())] -> SupertabExt
-fromSnippets deleteLast snippets =
-  Supertab $ \str -> lookup str $ map (second $ runSnippet deleteLast) snippets
-
-snippet :: MkSnippetCmd a b => a -> SnippetCmd b
-snippet = mkSnippetCmd
diff --git a/src/Yi/Snippets/Haskell.hs b/src/Yi/Snippets/Haskell.hs
deleted file mode 100644
--- a/src/Yi/Snippets/Haskell.hs
+++ /dev/null
@@ -1,22 +0,0 @@
-{-# OPTIONS_HADDOCK show-extensions #-}
-
--- |
--- Module      :  Yi.Snippets.Haskell
--- License     :  GPL-2
--- Maintainer  :  yi-devel@googlegroups.com
--- Stability   :  experimental
--- Portability :  portable
-
-module Yi.Snippets.Haskell where
-
-import qualified Yi.Rope     as R (singleton)
-import           Yi.Snippets (SnippetCmd, cursor, cursorWith, snippet, (&))
-
-hsFunction :: SnippetCmd ()
-hsFunction = snippet $
-  cursorWith 1 (R.singleton 'f') & " :: " & cursor 2 & "\n" &
-  cursor 3 & " = " & cursor 4 & "\n"
-
-hsClass :: SnippetCmd ()
-hsClass = snippet $
-  "class " & cursor 1 & " " & cursor 2 & " where\n  " & cursor 3
diff --git a/yi-core.cabal b/yi-core.cabal
--- a/yi-core.cabal
+++ b/yi-core.cabal
@@ -3,7 +3,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           yi-core
-version:        0.13.2
+version:        0.13.3
 synopsis:       Yi editor core library
 category:       Yi
 homepage:       https://github.com/yi-editor/yi#readme
@@ -151,8 +151,6 @@
       Yi.PersistentState
       Yi.Process
       Yi.Rectangle
-      Yi.Snippets
-      Yi.Snippets.Haskell
       Yi.Search
       Yi.Search.Internal
       Yi.String
