diff options
-rw-r--r-- | README.markdown | 8 | ||||
-rw-r--r-- | src/Language/Haskell/Stylish/Config.hs | 27 |
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' |