summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--README.markdown8
-rw-r--r--src/Language/Haskell/Stylish/Config.hs27
2 files changed, 27 insertions, 8 deletions
diff --git a/README.markdown b/README.markdown
index 9fc0b49..d05c0c6 100644
--- a/README.markdown
+++ b/README.markdown
@@ -78,11 +78,13 @@ The tool is customizable to some extent. It tries to find a config file in the
following order:
1. A file passed to the tool using the `-c/--config` argument
-2. `.stylish-haskell.yaml` in the current directory (useful for per-project
+2. `.stylish-haskell.yaml` in the current directory (useful for per-directory
settings)
-3. `.stylish-haskell.yaml` in your home directory (useful for user-wide
+3. `.stylish-haskell.yaml` in the nearest ancestor directory (useful for
+ per-project settings)
+4. `.stylish-haskell.yaml` in your home directory (useful for user-wide
settings)
-4. The default settings.
+5. The default settings.
Use `stylish-haskell --defaults > .stylish-haskell.yaml` to dump a
well-documented default configuration to a file, this way you can get started
diff --git a/src/Language/Haskell/Stylish/Config.hs b/src/Language/Haskell/Stylish/Config.hs
index 2593004..ad2ae61 100644
--- a/src/Language/Haskell/Stylish/Config.hs
+++ b/src/Language/Haskell/Stylish/Config.hs
@@ -16,12 +16,13 @@ import Data.Aeson (FromJSON (..))
import qualified Data.Aeson as A
import qualified Data.Aeson.Types as A
import qualified Data.ByteString as B
-import Data.List (intercalate)
+import Data.List (inits, intercalate)
import Data.Map (Map)
import qualified Data.Map as M
import Data.Yaml (decodeEither)
import System.Directory
-import System.FilePath ((</>))
+import System.FilePath (joinPath, splitPath,
+ (</>))
--------------------------------------------------------------------------------
@@ -71,16 +72,32 @@ defaultConfigFilePath = getDataFileName "data/stylish-haskell.yaml"
--------------------------------------------------------------------------------
configFilePath :: Verbose -> Maybe FilePath -> IO (Maybe FilePath)
configFilePath verbose userSpecified = do
- (current, currentE) <- check $ (</> configFileName) <$> getCurrentDirectory
- (home, homeE) <- check $ (</> configFileName) <$> getHomeDirectory
- (def, defE) <- check defaultConfigFilePath
+ (current, currentE) <- check $ (</> configFileName) <$>
+ getCurrentDirectory
+ (projectRoot, projectRootE) <- checkUntilFound =<< (map (</> configFileName))
+ <$> getAncestorDirectories
+ (home, homeE) <- check $ (</> configFileName) <$>
+ getHomeDirectory
+ (def, defE) <- check defaultConfigFilePath
return $ msum
[ userSpecified
, if currentE then Just current else Nothing
+ , if projectRootE then Just projectRoot else Nothing
, if homeE then Just home else Nothing
, if defE then Just def else Nothing
]
where
+ getAncestorDirectories :: IO [FilePath]
+ getAncestorDirectories = map joinPath . reverse . drop 2
+ . inits . splitPath <$> getCurrentDirectory
+
+ checkUntilFound :: [FilePath] -> IO (FilePath, Bool)
+ checkUntilFound [] = return ("", False)
+ checkUntilFound (f:fs) = do
+ res@(_, ex) <- check (return f)
+ if ex then return res else checkUntilFound fs
+
+ check :: IO FilePath -> IO (FilePath, Bool)
check fp = do
fp' <- fp
ex <- doesFileExist fp'