diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -12,11 +12,11 @@
 
 with [stack](https://www.haskellstack.org/)
 
-    $ cabal install hfmt
+    $ stack install hfmt
 
 with [cabal](https://www.haskell.org/haskellwiki/Cabal/How_to_install_a_Cabal_package)
 
-    $ stack install hfmt
+    $ cabal install hfmt
 
 ## Usage
 
diff --git a/app/Actions.hs b/app/Actions.hs
--- a/app/Actions.hs
+++ b/app/Actions.hs
@@ -1,4 +1,6 @@
-module Actions (act) where
+module Actions
+  ( act
+  ) where
 
 import Language.Haskell.Format
 import OptionsParser
@@ -16,7 +18,8 @@
   return r
 act options r@(Reformat input source result) = act' (optAction options)
   where
-    act' PrintDiffs = when wasReformatted (printDiff input source result) >> return r
+    act' PrintDiffs =
+      when wasReformatted (printDiff input source result) >> return r
     act' PrintSources = undefined
     act' PrintFilePaths = when wasReformatted (print input) >> return r
     act' WriteSources = do
@@ -26,7 +29,8 @@
 
 sourceChangedOrHasSuggestions :: HaskellSource -> Reformatted -> Bool
 sourceChangedOrHasSuggestions source reformatted =
-  not (null (suggestions reformatted)) || source /= reformattedSource reformatted
+  not (null (suggestions reformatted)) ||
+  source /= reformattedSource reformatted
 
 printDiff :: InputFile -> HaskellSource -> Reformatted -> IO ()
 printDiff (InputFilePath path) source reformatted = do
diff --git a/app/Main.hs b/app/Main.hs
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -1,4 +1,6 @@
-module Main (main) where
+module Main
+  ( main
+  ) where
 
 import           Actions
 import           Language.Haskell.Format
@@ -28,7 +30,9 @@
 
 runFormatter :: Formatter -> Options -> IO Bool
 runFormatter formatter options =
-  anyStrict sourceChangedOrHasSuggestions (inputFiles >-> P.map reformat >-> P.mapM writeOutput)
+  anyStrict
+    sourceChangedOrHasSuggestions
+    (inputFiles >-> P.map reformat >-> P.mapM writeOutput)
   where
     anyStrict :: Monad m => (a -> Bool) -> Producer a m () -> m Bool
     anyStrict f = P.fold (\acc x -> acc || f x) False id
@@ -37,15 +41,18 @@
     writeOutput = Actions.act options
 
 readInputFiles :: Options -> Producer InputFileWithSource IO ()
-readInputFiles options = determineInputFilePaths (optPaths options) >-> P.mapM readInputFile
+readInputFiles options =
+  determineInputFilePaths (optPaths options) >-> P.mapM readInputFile
 
 determineInputFilePaths :: [FilePath] -> Producer InputFile IO ()
 determineInputFilePaths [] = enumeratePath "." >-> P.map InputFilePath
 determineInputFilePaths ["-"] = yield InputFromStdIn
-determineInputFilePaths paths = for (each paths) enumeratePath >-> P.map InputFilePath
+determineInputFilePaths paths =
+  for (each paths) enumeratePath >-> P.map InputFilePath
 
 readInputFile :: InputFile -> IO InputFileWithSource
-readInputFile (InputFilePath path) = InputFileWithSource (InputFilePath path) <$> readSource path
+readInputFile (InputFilePath path) =
+  InputFileWithSource (InputFilePath path) <$> readSource path
 readInputFile InputFromStdIn = InputFileWithSource InputFromStdIn <$> readStdin
 
 applyFormatter :: Formatter -> InputFileWithSource -> ReformatResult
@@ -62,4 +69,5 @@
 
 sourceChangedOrHasSuggestions :: ReformatResult -> Bool
 sourceChangedOrHasSuggestions (Reformat input source reformatted) =
-  not (null (suggestions reformatted)) || source /= reformattedSource reformatted
+  not (null (suggestions reformatted)) ||
+  source /= reformattedSource reformatted
diff --git a/app/OptionsParser.hs b/app/OptionsParser.hs
--- a/app/OptionsParser.hs
+++ b/app/OptionsParser.hs
@@ -1,4 +1,9 @@
-module OptionsParser (Options, optAction, optPaths, parser) where
+module OptionsParser
+  ( Options
+  , optAction
+  , optPaths
+  , parser
+  ) where
 
 import Types
 
@@ -10,14 +15,13 @@
 import Options.Applicative.Extra
 import Text.PrettyPrint.ANSI.Leijen hiding (empty, (<$>), (<>))
 
-data Options =
-       Options
-         { optPrintDiffs     :: Bool
-         , optPrintSources   :: Bool
-         , optPrintFilePaths :: Bool
-         , optWriteSources   :: Bool
-         , optPaths          :: [FilePath]
-         }
+data Options = Options
+  { optPrintDiffs     :: Bool
+  , optPrintSources   :: Bool
+  , optPrintFilePaths :: Bool
+  , optWriteSources   :: Bool
+  , optPaths          :: [FilePath]
+  }
 
 optAction :: Options -> Action
 optAction options
@@ -29,49 +33,53 @@
   | otherwise = PrintDiffs
 
 optionParser :: Parser Options
-optionParser = Options <$> switch
-                             (long "print-diffs" <>
-                              short 'd' <>
-                              help "If a file's formatting is different, print a diff.")
-                       <*> switch
-                             (long "print-sources" <>
-                              short 's' <>
-                              help "If a file's formatting is different, print its source.")
-                       <*> switch
-                             (long "print-paths" <>
-                              short 'l' <>
-                              help "If a file's formatting is different, print its path.")
-                       <*> switch
-                             (long "write-sources" <>
-                              short 'w' <>
-                              help "If a file's formatting is different, overwrite it.")
-                       <*> many pathOption
+optionParser =
+  Options <$>
+  switch
+    (long "print-diffs" <> short 'd' <>
+     help "If a file's formatting is different, print a diff.") <*>
+  switch
+    (long "print-sources" <> short 's' <>
+     help "If a file's formatting is different, print its source.") <*>
+  switch
+    (long "print-paths" <> short 'l' <>
+     help "If a file's formatting is different, print its path.") <*>
+  switch
+    (long "write-sources" <> short 'w' <>
+     help "If a file's formatting is different, overwrite it.") <*>
+  many pathOption
   where
     pathOption = strArgument (metavar "PATH" <> pathOptionHelp)
-    pathOptionHelp = helpDoc $ Just $
-      paragraph "Explicit paths to process." <> hardline
-      <> unorderdedList " - "
-           [ paragraph "A single '-' will process standard input."
-           , paragraph "Files will be processed directly."
-           , paragraph "Directories will be recursively searched for source files to process."
-           , paragraph
-               ".cabal files will be parsed and all specified source directories and files processed."
-           , paragraph
-               "If no paths are given, the current directory will be searched for .cabal files to process, if none are found the current directory will be recursively searched for source files to process."
-           ]
+    pathOptionHelp =
+      helpDoc $
+      Just $
+      paragraph "Explicit paths to process." <> hardline <>
+      unorderdedList
+        " - "
+        [ paragraph "A single '-' will process standard input."
+        , paragraph "Files will be processed directly."
+        , paragraph
+            "Directories will be recursively searched for source files to process."
+        , paragraph
+            ".cabal files will be parsed and all specified source directories and files processed."
+        , paragraph
+            "If no paths are given, the current directory will be searched for .cabal files to process, if none are found the current directory will be recursively searched for source files to process."
+        ]
 
 paragraph :: String -> Doc
 paragraph = mconcat . intersperse softline . map text . words
 
 unorderdedList :: String -> [Doc] -> Doc
-unorderdedList prefix = encloseSep (text prefix) mempty (text prefix) . map (hang 0)
+unorderdedList prefix =
+  encloseSep (text prefix) mempty (text prefix) . map (hang 0)
 
 optionParserInfo :: ParserInfo Options
-optionParserInfo = info (helper <*> optionParser)
-                     (fullDesc
-                      <> header "hfmt - format Haskell programs"
-                      <> progDesc
-                           "Operates on Haskell source files, reformatting them by applying suggestions from HLint, hindent, and stylish-haskell. Inspired by the gofmt utility.")
+optionParserInfo =
+  info
+    (helper <*> optionParser)
+    (fullDesc <> header "hfmt - format Haskell programs" <>
+     progDesc
+       "Operates on Haskell source files, reformatting them by applying suggestions from HLint, hindent, and stylish-haskell. Inspired by the gofmt utility.")
 
 parser :: ParserInfo Options
 parser = optionParserInfo
diff --git a/app/Types.hs b/app/Types.hs
--- a/app/Types.hs
+++ b/app/Types.hs
@@ -1,31 +1,39 @@
-module Types (
-    Action(..),
-    InputFile(..),
-    InputFileWithSource(..),
-    ErrorString,
-    ReformatResult(..),
-    HaskellSourceFilePath,
-    HaskellSource(..),
-    ) where
+module Types
+  ( Action(..)
+  , InputFile(..)
+  , InputFileWithSource(..)
+  , ErrorString
+  , ReformatResult(..)
+  , HaskellSourceFilePath
+  , HaskellSource(..)
+  ) where
 
 import Language.Haskell.Format
 import Language.Haskell.Source.Enumerator (HaskellSourceFilePath)
 
-data Action = PrintDiffs
-            | PrintSources
-            | PrintFilePaths
-            | WriteSources
+data Action
+  = PrintDiffs
+  | PrintSources
+  | PrintFilePaths
+  | WriteSources
 
-data InputFile = InputFilePath HaskellSourceFilePath
-               | InputFromStdIn
+data InputFile
+  = InputFilePath HaskellSourceFilePath
+  | InputFromStdIn
 
 instance Show InputFile where
   show (InputFilePath path) = path
-  show InputFromStdIn = "-"
+  show InputFromStdIn       = "-"
 
-data InputFileWithSource = InputFileWithSource InputFile HaskellSource
+data InputFileWithSource =
+  InputFileWithSource InputFile
+                      HaskellSource
 
 type ErrorString = String
 
-data ReformatResult = InvalidReformat InputFile ErrorString
-                    | Reformat InputFile HaskellSource Reformatted
+data ReformatResult
+  = InvalidReformat InputFile
+                    ErrorString
+  | Reformat InputFile
+             HaskellSource
+             Reformatted
diff --git a/hfmt.cabal b/hfmt.cabal
--- a/hfmt.cabal
+++ b/hfmt.cabal
@@ -1,5 +1,5 @@
 name:                hfmt
-version:             0.0.2.3
+version:             0.1.0
 synopsis:            Haskell source code formatter
 description:         Inspired by gofmt. Built using hlint, hindent, and stylish-haskell.
 license:             MIT
@@ -25,18 +25,25 @@
                      , Language.Haskell.Format.HIndent
                      , Language.Haskell.Format.HLint
                      , Language.Haskell.Format.Stylish
+                     , Path.Find
   GHC-Options:       -Wall
   Build-Depends:     base >= 4.8 && < 5
+                     , bytestring
                      , Cabal
                      , directory
+                     , exceptions
                      , filepath
                      , haskell-src-exts
-                     , hindent >= 4.5 , hindent < 5
-                     , hlint >= 1.9.13 , hlint < 2
+                     , hindent >= 5.0.0
+                     , hlint >= 1.9
                      , HUnit
+                     , path
+                     , path-io
                      , pipes
-                     , stylish-haskell >= 0.5 , stylish-haskell < 0.6
+                     , stylish-haskell >= 0.7
                      , text
+                     , transformers
+                     , yaml
 
 executable hfmt
   Hs-Source-Dirs:    app
diff --git a/src/Language/Haskell/Format.hs b/src/Language/Haskell/Format.hs
--- a/src/Language/Haskell/Format.hs
+++ b/src/Language/Haskell/Format.hs
@@ -1,16 +1,16 @@
-module Language.Haskell.Format (
-    autoSettings,
-    format,
-    formatters,
-    hlint,
-    hindent,
-    stylish,
-    Settings,
-    Formatter(..),
-    Suggestion(..),
-    HaskellSource(..),
-    Reformatted(..),
-    ) where
+module Language.Haskell.Format
+  ( autoSettings
+  , format
+  , formatters
+  , hlint
+  , hindent
+  , stylish
+  , Settings
+  , Formatter(..)
+  , Suggestion(..)
+  , HaskellSource(..)
+  , Reformatted(..)
+  ) where
 
 import           Language.Haskell.Format.Definitions
 import qualified Language.Haskell.Format.HIndent     as HIndent
@@ -20,7 +20,8 @@
 import           Control.Applicative
 import           Data.Maybe
 
-data Settings = Settings
+data Settings =
+  Settings
 
 autoSettings :: IO Settings
 autoSettings = return Settings
diff --git a/src/Language/Haskell/Format/Definitions.hs b/src/Language/Haskell/Format/Definitions.hs
--- a/src/Language/Haskell/Format/Definitions.hs
+++ b/src/Language/Haskell/Format/Definitions.hs
@@ -1,4 +1,9 @@
-module Language.Haskell.Format.Definitions (HaskellSource(..), Reformatted(..), Formatter(..), Suggestion(..)) where
+module Language.Haskell.Format.Definitions
+  ( HaskellSource(..)
+  , Reformatted(..)
+  , Formatter(..)
+  , Suggestion(..)
+  ) where
 
 import Control.Applicative
 import Control.Monad
@@ -6,26 +11,36 @@
 
 type ErrorString = String
 
-newtype HaskellSource = HaskellSource String
-  deriving Eq
+newtype HaskellSource =
+  HaskellSource String
+  deriving (Eq)
 
-newtype Suggestion = Suggestion String
+newtype Suggestion =
+  Suggestion String
 
 instance Show Suggestion where
   show (Suggestion text) = text
 
-data Reformatted = Reformatted { reformattedSource :: HaskellSource, suggestions :: [Suggestion] }
+data Reformatted = Reformatted
+  { reformattedSource :: HaskellSource
+  , suggestions       :: [Suggestion]
+  }
 
 instance Monoid Reformatted where
   mempty = Reformatted undefined []
-  (Reformatted _ suggestionsA) `mappend` (Reformatted sourceB suggestionsB) = Reformatted sourceB
-                                                                                (suggestionsA <> suggestionsB)
+  (Reformatted _ suggestionsA) `mappend` (Reformatted sourceB suggestionsB) =
+    Reformatted sourceB (suggestionsA <> suggestionsB)
 
-data Formatter = Formatter { unFormatter :: HaskellSource -> Either ErrorString Reformatted }
+newtype Formatter = Formatter
+  { unFormatter :: HaskellSource -> Either ErrorString Reformatted
+  }
 
 instance Monoid Formatter where
   mempty = Formatter (\source -> Right (Reformatted source []))
   (Formatter f) `mappend` (Formatter g) = Formatter (asReformatter g <=< f)
 
-asReformatter :: (HaskellSource -> Either ErrorString Reformatted) -> Reformatted -> Either ErrorString Reformatted
+asReformatter ::
+     (HaskellSource -> Either ErrorString Reformatted)
+  -> Reformatted
+  -> Either ErrorString Reformatted
 asReformatter formatter r = (r <>) <$> formatter (reformattedSource r)
diff --git a/src/Language/Haskell/Format/HIndent.hs b/src/Language/Haskell/Format/HIndent.hs
--- a/src/Language/Haskell/Format/HIndent.hs
+++ b/src/Language/Haskell/Format/HIndent.hs
@@ -1,28 +1,66 @@
-module Language.Haskell.Format.HIndent (autoSettings, formatter, defaultFormatter) where
+module Language.Haskell.Format.HIndent
+  ( autoSettings
+  , formatter
+  , defaultFormatter
+  ) where
 
-import Control.Applicative
-import Data.Maybe
-import Data.Text.Lazy                      as L
-import Data.Text.Lazy.Builder
-import HIndent
-import Language.Haskell.Exts.Extension     (Extension)
+import           Control.Applicative
+import           Data.ByteString.Builder
+import           Data.ByteString.Lazy                as L
+import           Data.Maybe
+import qualified Data.Text                           as Text
+import           Data.Text.Encoding                  as Encoding
+import           Data.Text.Lazy                      as TL
+import           Data.Text.Lazy.Builder
+import qualified Data.Yaml                           as Y
+import           HIndent
+import           HIndent.Types
+import           Language.Haskell.Exts.Extension     (Extension)
+import           Path
+import qualified Path.Find                           as Path
+import qualified Path.IO                             as Path
 
-import Language.Haskell.Format.Definitions
-import Language.Haskell.Format.Internal
+import           Language.Haskell.Format.Definitions
+import           Language.Haskell.Format.Internal
 
-data Settings = Settings Style (Maybe [Extension])
+data Settings =
+  Settings Config
+           (Maybe [Extension])
 
 defaultFormatter :: IO Formatter
 defaultFormatter = formatter <$> autoSettings
 
 autoSettings :: IO Settings
-autoSettings = return (Settings gibiansky Nothing)
+autoSettings = do
+  config <- getConfig
+  return (Settings config Nothing)
 
+-- | Read config from a config file, or return 'defaultConfig'.
+getConfig :: IO Config
+getConfig = do
+  cur <- Path.getCurrentDir
+  homeDir <- Path.getHomeDir
+  mfile <-
+    Path.findFileUp
+      cur
+      ((== ".hindent.yaml") . toFilePath . filename)
+      (Just homeDir)
+  case mfile of
+    Nothing -> return defaultConfig
+    Just file -> do
+      result <- Y.decodeFileEither (toFilePath file)
+      case result of
+        Left e       -> error (show e)
+        Right config -> return config
+
 formatter :: Settings -> Formatter
 formatter = mkFormatter . hindent
 
 hindent :: Settings -> HaskellSource -> Either String HaskellSource
-hindent (Settings style extensions) (HaskellSource source) =
-  HaskellSource . L.unpack . toLazyText <$> reformat style extensions sourceText
+hindent (Settings config extensions) (HaskellSource source) =
+  toHaskellSource <$> reformat config extensions Nothing sourceText
   where
-    sourceText = L.pack source
+    sourceText = Encoding.encodeUtf8 . Text.pack $ source
+    toHaskellSource =
+      HaskellSource .
+      Text.unpack . Encoding.decodeUtf8 . L.toStrict . toLazyByteString
diff --git a/src/Language/Haskell/Format/HLint.hs b/src/Language/Haskell/Format/HLint.hs
--- a/src/Language/Haskell/Format/HLint.hs
+++ b/src/Language/Haskell/Format/HLint.hs
@@ -1,40 +1,36 @@
-module Language.Haskell.Format.HLint (autoSettings, formatter, suggester) where
+module Language.Haskell.Format.HLint
+  ( autoSettings
+  , suggester
+  ) where
 
 import           Language.Haskell.Format.Definitions
 import           Language.Haskell.Format.Internal
 
 import           Control.Applicative
-import           Language.Haskell.Exts.Annotated     as Hse
+import           Language.Haskell.HLint3             (Classify, Hint,
+                                                      ParseError (..),
+                                                      ParseFlags, applyHints,
+                                                      parseModuleEx)
 import qualified Language.Haskell.HLint3             as HLint3
-
-formatter = undefined
+import           System.IO.Unsafe                    (unsafePerformIO)
 
-suggester :: (ParseMode, [HLint3.Classify], HLint3.Hint) -> Formatter
+suggester :: (ParseFlags, [Classify], Hint) -> Formatter
 suggester = mkSuggester . hlint
 
-hlint :: (ParseMode, [HLint3.Classify], HLint3.Hint) -> HaskellSource -> Either String [Suggestion]
-hlint (parseMode, classifications, hint) (HaskellSource source) =
-  getSuggestions <$> parseResultAsEither (parse source)
+hlint ::
+     (ParseFlags, [Classify], Hint)
+  -> HaskellSource
+  -> Either String [Suggestion]
+hlint (flags, classify, hint) (HaskellSource source) =
+  case unsafePerformIO (parseModuleEx flags filepath (Just source)) of
+    Right m         -> Right . map ideaToSuggestion . ideas $ m
+    Left parseError -> Left . parseErrorMessage $ parseError
   where
-    parse = Hse.parseFileContentsWithComments parseMode
-    getSuggestions moduleSource = map ideaToSuggestion $ HLint3.applyHints classifications hint
-                                                           [moduleSource]
-
-autoSettings :: IO (ParseMode, [HLint3.Classify], HLint3.Hint)
-autoSettings = do
-  (fixities, classify, hints) <- HLint3.findSettings (HLint3.readSettingsFile Nothing) Nothing
-  return
-    (HLint3.hseFlags (HLint3.parseFlagsAddFixities fixities HLint3.defaultParseFlags), classify, HLint3.resolveHints
-                                                                                                   hints)
+    filepath = ""
+    ideas m = applyHints classify hint [m]
 
-parseResultAsEither :: ParseResult a -> Either String a
-parseResultAsEither (ParseOk a) = Right a
-parseResultAsEither (ParseFailed loc error) =
-  Left ("Parse failed at " ++ location ++ ": " ++ error)
-  where
-    location = filename ++ " " ++ linecol
-    filename = "[" ++ srcFilename loc ++ "]"
-    linecol = "(" ++ show (srcLine loc) ++ ":" ++ show (srcColumn loc) ++ ")"
+autoSettings :: IO (ParseFlags, [Classify], Hint)
+autoSettings = HLint3.autoSettings
 
 ideaToSuggestion :: HLint3.Idea -> Suggestion
 ideaToSuggestion = Suggestion . show
diff --git a/src/Language/Haskell/Format/Internal.hs b/src/Language/Haskell/Format/Internal.hs
--- a/src/Language/Haskell/Format/Internal.hs
+++ b/src/Language/Haskell/Format/Internal.hs
@@ -1,4 +1,7 @@
-module Language.Haskell.Format.Internal (mkFormatter, mkSuggester) where
+module Language.Haskell.Format.Internal
+  ( mkFormatter
+  , mkSuggester
+  ) where
 
 import Language.Haskell.Format.Definitions
 
diff --git a/src/Language/Haskell/Format/Stylish.hs b/src/Language/Haskell/Format/Stylish.hs
--- a/src/Language/Haskell/Format/Stylish.hs
+++ b/src/Language/Haskell/Format/Stylish.hs
@@ -1,4 +1,7 @@
-module Language.Haskell.Format.Stylish (autoSettings, formatter) where
+module Language.Haskell.Format.Stylish
+  ( autoSettings
+  , formatter
+  ) where
 
 import Control.Applicative
 import Language.Haskell.Stylish            as Stylish
@@ -6,17 +9,20 @@
 import Language.Haskell.Format.Definitions
 import Language.Haskell.Format.Internal
 
-data Settings = Settings Stylish.Config
+newtype Settings =
+  Settings Stylish.Config
 
 autoSettings :: IO Settings
-autoSettings = Settings <$> Stylish.loadConfig (Stylish.makeVerbose False) Nothing
+autoSettings =
+  Settings <$> Stylish.loadConfig (Stylish.makeVerbose False) Nothing
 
 formatter :: Settings -> Formatter
 formatter = mkFormatter . stylish
 
 stylish :: Settings -> HaskellSource -> Either String HaskellSource
 stylish (Settings config) (HaskellSource source) =
-  HaskellSource . unlines <$> Stylish.runSteps extensions Nothing steps sourceLines
+  HaskellSource . unlines <$>
+  Stylish.runSteps extensions Nothing steps sourceLines
   where
     sourceLines = lines source
     extensions = Stylish.configLanguageExtensions config
diff --git a/src/Language/Haskell/Format/Utilities.hs b/src/Language/Haskell/Format/Utilities.hs
--- a/src/Language/Haskell/Format/Utilities.hs
+++ b/src/Language/Haskell/Format/Utilities.hs
@@ -1,4 +1,8 @@
-module Language.Haskell.Format.Utilities (wasReformatted, hunitTest, defaultFormatter) where
+module Language.Haskell.Format.Utilities
+  ( wasReformatted
+  , hunitTest
+  , defaultFormatter
+  ) where
 
 import           Language.Haskell.Format
 import           Language.Haskell.Format.Definitions
@@ -13,32 +17,36 @@
 
 type ErrorString = String
 
-data CheckResult = InvalidCheckResult ErrorString
-                 | CheckResult HaskellSource Reformatted
+data CheckResult
+  = InvalidCheckResult ErrorString
+  | CheckResult HaskellSource
+                Reformatted
 
 hunitTest :: FilePath -> Test
 hunitTest filepath = TestLabel filepath $ makeTestCase filepath
 
 makeTestCase :: FilePath -> Test
-makeTestCase filepath = TestCase $ do
-  formatter <- defaultFormatter
-  runEffect $ check formatter filepath >-> assertResults
+makeTestCase filepath =
+  TestCase $ do
+    formatter <- defaultFormatter
+    runEffect $ check formatter filepath >-> assertResults
 
 assertResults :: Consumer CheckResult IO ()
-assertResults = forever $ do
-  result <- await
-  case result of
-    (InvalidCheckResult errorString) -> lift $ assertFailure ("Error: " ++ errorString)
-    (CheckResult source reformatted) -> when (wasReformatted source reformatted) $ lift $ assertFailure
-                                                                                            ("Incorrect formatting: " ++ concatMap
-                                                                                                                           show
-                                                                                                                           (suggestions
-                                                                                                                              reformatted))
+assertResults =
+  forever $ do
+    result <- await
+    case result of
+      (InvalidCheckResult errorString) ->
+        lift $ assertFailure ("Error: " ++ errorString)
+      (CheckResult source reformatted) ->
+        when (wasReformatted source reformatted) $
+        lift $
+        assertFailure
+          ("Incorrect formatting: " ++ concatMap show (suggestions reformatted))
 
 check :: Formatter -> FilePath -> Producer CheckResult IO ()
-check formatter path = enumeratePath path >->
-                       P.mapM readSource >->
-                       P.map (checkFormatting formatter)
+check formatter path =
+  enumeratePath path >-> P.mapM readSource >-> P.map (checkFormatting formatter)
 
 readSource :: HaskellSourceFilePath -> IO HaskellSource
 readSource path = HaskellSource <$> readFile path
@@ -57,4 +65,5 @@
 
 wasReformatted :: HaskellSource -> Reformatted -> Bool
 wasReformatted source reformatted =
-  not (null (suggestions reformatted)) || source /= reformattedSource reformatted
+  not (null (suggestions reformatted)) ||
+  source /= reformattedSource reformatted
diff --git a/src/Language/Haskell/Source/Enumerator.hs b/src/Language/Haskell/Source/Enumerator.hs
--- a/src/Language/Haskell/Source/Enumerator.hs
+++ b/src/Language/Haskell/Source/Enumerator.hs
@@ -1,4 +1,7 @@
-module Language.Haskell.Source.Enumerator (enumeratePath, HaskellSourceFilePath) where
+module Language.Haskell.Source.Enumerator
+  ( enumeratePath
+  , HaskellSourceFilePath
+  ) where
 
 import           Control.Applicative
 import           Control.Monad
@@ -63,7 +66,8 @@
     else directory path
 
 getDirectoryContentsFullPaths :: FilePath -> IO [FilePath]
-getDirectoryContentsFullPaths path = mkFull . notHidden . notMeta <$> getDirectoryContents path
+getDirectoryContentsFullPaths path =
+  mkFull . notHidden . notMeta <$> getDirectoryContents path
   where
     mkFull = map (path </>)
     notHidden = filter (not . isPrefixOf ".")
@@ -84,8 +88,12 @@
 sourcePaths :: GenericPackageDescription -> [FilePath]
 sourcePaths pkg = nub $ concatMap ($ pkg) pathExtractors
   where
-    pathExtractors = [ maybe [] (hsSourceDirs . libBuildInfo . condTreeData) . condLibrary
-                     , concatMap (hsSourceDirs . buildInfo . condTreeData . snd) . condExecutables
-                     , concatMap (hsSourceDirs . testBuildInfo . condTreeData . snd) . condTestSuites
-                     , concatMap (hsSourceDirs . benchmarkBuildInfo . condTreeData . snd) . condBenchmarks
-                     ]
+    pathExtractors =
+      [ maybe [] (hsSourceDirs . libBuildInfo . condTreeData) . condLibrary
+      , concatMap (hsSourceDirs . buildInfo . condTreeData . snd) .
+        condExecutables
+      , concatMap (hsSourceDirs . testBuildInfo . condTreeData . snd) .
+        condTestSuites
+      , concatMap (hsSourceDirs . benchmarkBuildInfo . condTreeData . snd) .
+        condBenchmarks
+      ]
diff --git a/src/Path/Find.hs b/src/Path/Find.hs
new file mode 100644
--- /dev/null
+++ b/src/Path/Find.hs
@@ -0,0 +1,52 @@
+{-# LANGUAGE DataKinds #-}
+
+-- | Finding files.
+-- Lifted from Stack.
+module Path.Find
+  ( findFileUp
+  ) where
+
+import Control.Exception      (evaluate)
+import Control.Monad
+import Control.Monad.Catch
+import Control.Monad.IO.Class
+import Data.List
+import Path
+import Path.IO                hiding (findFiles)
+import System.IO.Error        (isPermissionError)
+
+-- | Find the location of a file matching the given predicate.
+findFileUp ::
+     (MonadIO m, MonadThrow m)
+  => Path Abs Dir -- ^ Start here.
+  -> (Path Abs File -> Bool) -- ^ Predicate to match the file.
+  -> Maybe (Path Abs Dir) -- ^ Do not ascend above this directory.
+  -> m (Maybe (Path Abs File)) -- ^ Absolute file path.
+findFileUp = findPathUp snd
+
+-- | Find the location of a directory matching the given predicate.
+findDirUp ::
+     (MonadIO m, MonadThrow m)
+  => Path Abs Dir -- ^ Start here.
+  -> (Path Abs Dir -> Bool) -- ^ Predicate to match the directory.
+  -> Maybe (Path Abs Dir) -- ^ Do not ascend above this directory.
+  -> m (Maybe (Path Abs Dir)) -- ^ Absolute directory path.
+findDirUp = findPathUp fst
+
+-- | Find the location of a path matching the given predicate.
+findPathUp ::
+     (MonadIO m, MonadThrow m)
+  => (([Path Abs Dir], [Path Abs File]) -> [Path Abs t])
+              -- ^ Choose path type from pair.
+  -> Path Abs Dir -- ^ Start here.
+  -> (Path Abs t -> Bool) -- ^ Predicate to match the path.
+  -> Maybe (Path Abs Dir) -- ^ Do not ascend above this directory.
+  -> m (Maybe (Path Abs t)) -- ^ Absolute path.
+findPathUp pathType dir p upperBound = do
+  entries <- listDir dir
+  case find p (pathType entries) of
+    Just path -> return (Just path)
+    Nothing
+      | Just dir == upperBound -> return Nothing
+      | parent dir == dir -> return Nothing
+      | otherwise -> findPathUp pathType (parent dir) p upperBound
diff --git a/test/pure/Spec.hs b/test/pure/Spec.hs
--- a/test/pure/Spec.hs
+++ b/test/pure/Spec.hs
@@ -1,4 +1,6 @@
-module Main where
+module Main
+  ( main
+  ) where
 
 import Test.Framework                 (defaultMain, testGroup)
 import Test.Framework.Providers.HUnit
diff --git a/test/self-formatting/Spec.hs b/test/self-formatting/Spec.hs
--- a/test/self-formatting/Spec.hs
+++ b/test/self-formatting/Spec.hs
@@ -1,4 +1,6 @@
-module Main where
+module Main
+  ( main
+  ) where
 
 import Language.Haskell.Format.Utilities
 
@@ -7,7 +9,9 @@
 import Test.HUnit                        hiding (Test)
 
 main :: IO ()
-main = defaultMain
-         [ testGroup "Check formatting of package sources"
-             (hUnitTestToTests $ hunitTest "hfmt.cabal")
-         ]
+main =
+  defaultMain
+    [ testGroup
+        "Check formatting of package sources"
+        (hUnitTestToTests $ hunitTest "hfmt.cabal")
+    ]
