{-# LANGUAGE CPP #-}
module System.Environment.XDG.BaseDir
( getUserDataDir
, getUserDataFile
, getUserConfigDir
, getUserConfigFile
, getUserCacheDir
, getUserCacheFile
, getSystemDataDirs
, getSystemDataFiles
, getSystemConfigDirs
, getSystemConfigFiles
, getAllDataDirs
, getAllDataFiles
, getAllConfigDirs
, getAllConfigFiles
) where
import Data.Maybe ( fromMaybe )
import System.FilePath ( (</>), splitSearchPath )
import System.Environment ( getEnvironment, getEnv )
import Control.Exception ( try )
import System.Directory ( getHomeDirectory )
import Control.Monad ( liftM2 )
#if defined(mingw32_HOST_OS) || defined(__MINGW32__)
getDefault "XDG_DATA_HOME" = getEnv "AppData"
getDefault "XDG_CONFIG_HOME" = userRelative $ "Local Settings"
getDefault "XDG_CACHE_HOME" = userRelative $ "Local Settings" </> "Cache"
getDefault "XDG_DATA_DIRS" = getEnv "ProgramFiles"
getDefault "XDG_CONFIG_DIRS" = getEnv "ProgramFiles"
getDefault _ = return ""
#else
getDefault :: [Char] -> IO [Char]
getDefault "XDG_DATA_HOME" = [Char] -> IO [Char]
userRelative ([Char] -> IO [Char]) -> [Char] -> IO [Char]
forall a b. (a -> b) -> a -> b
$ ".local" [Char] -> [Char] -> [Char]
</> "share"
getDefault "XDG_CONFIG_HOME" = [Char] -> IO [Char]
userRelative ([Char] -> IO [Char]) -> [Char] -> IO [Char]
forall a b. (a -> b) -> a -> b
$ ".config"
getDefault "XDG_CACHE_HOME" = [Char] -> IO [Char]
userRelative ([Char] -> IO [Char]) -> [Char] -> IO [Char]
forall a b. (a -> b) -> a -> b
$ ".cache"
getDefault "XDG_DATA_DIRS" = [Char] -> IO [Char]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Char] -> IO [Char]) -> [Char] -> IO [Char]
forall a b. (a -> b) -> a -> b
$ "/usr/local/share:/usr/share"
getDefault "XDG_CONFIG_DIRS" = [Char] -> IO [Char]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Char] -> IO [Char]) -> [Char] -> IO [Char]
forall a b. (a -> b) -> a -> b
$ "/etc/xdg"
getDefault _ = [Char] -> IO [Char]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Char] -> IO [Char]) -> [Char] -> IO [Char]
forall a b. (a -> b) -> a -> b
$ ""
#endif
getUserDataDir :: String -> IO FilePath
getUserDataDir :: [Char] -> IO [Char]
getUserDataDir = [Char] -> [Char] -> IO [Char]
singleDir "XDG_DATA_HOME"
getUserConfigDir :: String -> IO FilePath
getUserConfigDir :: [Char] -> IO [Char]
getUserConfigDir = [Char] -> [Char] -> IO [Char]
singleDir "XDG_CONFIG_HOME"
getUserCacheDir :: String -> IO FilePath
getUserCacheDir :: [Char] -> IO [Char]
getUserCacheDir = [Char] -> [Char] -> IO [Char]
singleDir "XDG_CACHE_HOME"
getSystemDataDirs :: String -> IO [FilePath]
getSystemDataDirs :: [Char] -> IO [[Char]]
getSystemDataDirs = [Char] -> [Char] -> IO [[Char]]
multiDirs "XDG_DATA_DIRS"
getSystemConfigDirs :: String -> IO [FilePath]
getSystemConfigDirs :: [Char] -> IO [[Char]]
getSystemConfigDirs = [Char] -> [Char] -> IO [[Char]]
multiDirs "XDG_CONFIG_DIRS"
getAllDataDirs :: String -> IO [FilePath]
getAllDataDirs :: [Char] -> IO [[Char]]
getAllDataDirs a :: [Char]
a = ([Char] -> [[Char]] -> [[Char]])
-> IO [Char] -> IO [[Char]] -> IO [[Char]]
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (:) ([Char] -> IO [Char]
getUserDataDir [Char]
a) ([Char] -> IO [[Char]]
getSystemDataDirs [Char]
a)
getAllConfigDirs :: String -> IO [FilePath]
getAllConfigDirs :: [Char] -> IO [[Char]]
getAllConfigDirs a :: [Char]
a = ([Char] -> [[Char]] -> [[Char]])
-> IO [Char] -> IO [[Char]] -> IO [[Char]]
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (:) ([Char] -> IO [Char]
getUserConfigDir [Char]
a) ([Char] -> IO [[Char]]
getSystemConfigDirs [Char]
a)
getUserDataFile :: String -> String -> IO FilePath
getUserDataFile :: [Char] -> [Char] -> IO [Char]
getUserDataFile a :: [Char]
a f :: [Char]
f = ([Char] -> [Char]) -> IO [Char] -> IO [Char]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([Char] -> [Char] -> [Char]
</> [Char]
f) (IO [Char] -> IO [Char]) -> IO [Char] -> IO [Char]
forall a b. (a -> b) -> a -> b
$ [Char] -> IO [Char]
getUserDataDir [Char]
a
getUserConfigFile :: String -> String -> IO FilePath
getUserConfigFile :: [Char] -> [Char] -> IO [Char]
getUserConfigFile a :: [Char]
a f :: [Char]
f = ([Char] -> [Char]) -> IO [Char] -> IO [Char]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([Char] -> [Char] -> [Char]
</> [Char]
f) (IO [Char] -> IO [Char]) -> IO [Char] -> IO [Char]
forall a b. (a -> b) -> a -> b
$ [Char] -> IO [Char]
getUserConfigDir [Char]
a
getUserCacheFile :: String -> String -> IO FilePath
getUserCacheFile :: [Char] -> [Char] -> IO [Char]
getUserCacheFile a :: [Char]
a f :: [Char]
f = ([Char] -> [Char]) -> IO [Char] -> IO [Char]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([Char] -> [Char] -> [Char]
</> [Char]
f) (IO [Char] -> IO [Char]) -> IO [Char] -> IO [Char]
forall a b. (a -> b) -> a -> b
$ [Char] -> IO [Char]
getUserCacheDir [Char]
a
getSystemDataFiles :: String -> String -> IO [FilePath]
getSystemDataFiles :: [Char] -> [Char] -> IO [[Char]]
getSystemDataFiles a :: [Char]
a f :: [Char]
f = ([[Char]] -> [[Char]]) -> IO [[Char]] -> IO [[Char]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([Char] -> [Char]) -> [[Char]] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ([Char] -> [Char] -> [Char]
</> [Char]
f)) (IO [[Char]] -> IO [[Char]]) -> IO [[Char]] -> IO [[Char]]
forall a b. (a -> b) -> a -> b
$ [Char] -> IO [[Char]]
getSystemDataDirs [Char]
a
getSystemConfigFiles :: String -> String -> IO [FilePath]
getSystemConfigFiles :: [Char] -> [Char] -> IO [[Char]]
getSystemConfigFiles a :: [Char]
a f :: [Char]
f = ([[Char]] -> [[Char]]) -> IO [[Char]] -> IO [[Char]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([Char] -> [Char]) -> [[Char]] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ([Char] -> [Char] -> [Char]
</> [Char]
f)) (IO [[Char]] -> IO [[Char]]) -> IO [[Char]] -> IO [[Char]]
forall a b. (a -> b) -> a -> b
$ [Char] -> IO [[Char]]
getSystemConfigDirs [Char]
a
getAllDataFiles :: String -> String -> IO [FilePath]
getAllDataFiles :: [Char] -> [Char] -> IO [[Char]]
getAllDataFiles a :: [Char]
a f :: [Char]
f = ([[Char]] -> [[Char]]) -> IO [[Char]] -> IO [[Char]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([Char] -> [Char]) -> [[Char]] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ([Char] -> [Char] -> [Char]
</> [Char]
f)) (IO [[Char]] -> IO [[Char]]) -> IO [[Char]] -> IO [[Char]]
forall a b. (a -> b) -> a -> b
$ [Char] -> IO [[Char]]
getAllDataDirs [Char]
a
getAllConfigFiles :: String -> String -> IO [FilePath]
getAllConfigFiles :: [Char] -> [Char] -> IO [[Char]]
getAllConfigFiles a :: [Char]
a f :: [Char]
f = ([[Char]] -> [[Char]]) -> IO [[Char]] -> IO [[Char]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([Char] -> [Char]) -> [[Char]] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ([Char] -> [Char] -> [Char]
</> [Char]
f)) (IO [[Char]] -> IO [[Char]]) -> IO [[Char]] -> IO [[Char]]
forall a b. (a -> b) -> a -> b
$ [Char] -> IO [[Char]]
getAllConfigDirs [Char]
a
singleDir :: String -> String -> IO FilePath
singleDir :: [Char] -> [Char] -> IO [Char]
singleDir key :: [Char]
key app :: [Char]
app = [Char] -> IO [Char]
envLookup [Char]
key IO [Char] -> ([Char] -> IO [Char]) -> IO [Char]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [Char] -> IO [Char]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Char] -> IO [Char]) -> ([Char] -> [Char]) -> [Char] -> IO [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char] -> [Char] -> [Char]
</> [Char]
app)
multiDirs :: String -> String -> IO [FilePath]
multiDirs :: [Char] -> [Char] -> IO [[Char]]
multiDirs key :: [Char]
key app :: [Char]
app = [Char] -> IO [Char]
envLookup [Char]
key IO [Char] -> ([Char] -> IO [[Char]]) -> IO [[Char]]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [[Char]] -> IO [[Char]]
forall (m :: * -> *) a. Monad m => a -> m a
return ([[Char]] -> IO [[Char]])
-> ([Char] -> [[Char]]) -> [Char] -> IO [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char] -> [Char]) -> [[Char]] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ([Char] -> [Char] -> [Char]
</> [Char]
app) ([[Char]] -> [[Char]])
-> ([Char] -> [[Char]]) -> [Char] -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> [[Char]]
splitSearchPath
envLookup :: String -> IO String
envLookup :: [Char] -> IO [Char]
envLookup key :: [Char]
key = do [([Char], [Char])]
env <- IO [([Char], [Char])]
getEnvironment
case [Char] -> [([Char], [Char])] -> Maybe [Char]
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup [Char]
key [([Char], [Char])]
env of
Just val :: [Char]
val -> [Char] -> IO [Char]
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
val
Nothing -> [Char] -> IO [Char]
getDefault [Char]
key
userRelative :: FilePath -> IO FilePath
userRelative :: [Char] -> IO [Char]
userRelative p :: [Char]
p = IO [Char]
getHomeDirectory IO [Char] -> ([Char] -> IO [Char]) -> IO [Char]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [Char] -> IO [Char]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Char] -> IO [Char]) -> ([Char] -> [Char]) -> [Char] -> IO [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char] -> [Char] -> [Char]
</> [Char]
p)