{-# 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 :: String -> IO String
getDefault String
"XDG_DATA_HOME" = String -> IO String
userRelative (String -> IO String) -> String -> IO String
forall a b. (a -> b) -> a -> b
$ String
".local" String -> String -> String
</> String
"share"
getDefault String
"XDG_CONFIG_HOME" = String -> IO String
userRelative (String -> IO String) -> String -> IO String
forall a b. (a -> b) -> a -> b
$ String
".config"
getDefault String
"XDG_CACHE_HOME" = String -> IO String
userRelative (String -> IO String) -> String -> IO String
forall a b. (a -> b) -> a -> b
$ String
".cache"
getDefault String
"XDG_DATA_DIRS" = String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> IO String) -> String -> IO String
forall a b. (a -> b) -> a -> b
$ String
"/usr/local/share:/usr/share"
getDefault String
"XDG_CONFIG_DIRS" = String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> IO String) -> String -> IO String
forall a b. (a -> b) -> a -> b
$ String
"/etc/xdg"
getDefault String
_ = String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> IO String) -> String -> IO String
forall a b. (a -> b) -> a -> b
$ String
""
#endif
getUserDataDir :: String -> IO FilePath
getUserDataDir :: String -> IO String
getUserDataDir = String -> String -> IO String
singleDir String
"XDG_DATA_HOME"
getUserConfigDir :: String -> IO FilePath
getUserConfigDir :: String -> IO String
getUserConfigDir = String -> String -> IO String
singleDir String
"XDG_CONFIG_HOME"
getUserCacheDir :: String -> IO FilePath
getUserCacheDir :: String -> IO String
getUserCacheDir = String -> String -> IO String
singleDir String
"XDG_CACHE_HOME"
getSystemDataDirs :: String -> IO [FilePath]
getSystemDataDirs :: String -> IO [String]
getSystemDataDirs = String -> String -> IO [String]
multiDirs String
"XDG_DATA_DIRS"
getSystemConfigDirs :: String -> IO [FilePath]
getSystemConfigDirs :: String -> IO [String]
getSystemConfigDirs = String -> String -> IO [String]
multiDirs String
"XDG_CONFIG_DIRS"
getAllDataDirs :: String -> IO [FilePath]
getAllDataDirs :: String -> IO [String]
getAllDataDirs String
a = (String -> [String] -> [String])
-> IO String -> IO [String] -> IO [String]
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (:) (String -> IO String
getUserDataDir String
a) (String -> IO [String]
getSystemDataDirs String
a)
getAllConfigDirs :: String -> IO [FilePath]
getAllConfigDirs :: String -> IO [String]
getAllConfigDirs String
a = (String -> [String] -> [String])
-> IO String -> IO [String] -> IO [String]
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (:) (String -> IO String
getUserConfigDir String
a) (String -> IO [String]
getSystemConfigDirs String
a)
getUserDataFile :: String -> String -> IO FilePath
getUserDataFile :: String -> String -> IO String
getUserDataFile String
a String
f = (String -> String) -> IO String -> IO String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String -> String -> String
</> String
f) (IO String -> IO String) -> IO String -> IO String
forall a b. (a -> b) -> a -> b
$ String -> IO String
getUserDataDir String
a
getUserConfigFile :: String -> String -> IO FilePath
getUserConfigFile :: String -> String -> IO String
getUserConfigFile String
a String
f = (String -> String) -> IO String -> IO String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String -> String -> String
</> String
f) (IO String -> IO String) -> IO String -> IO String
forall a b. (a -> b) -> a -> b
$ String -> IO String
getUserConfigDir String
a
getUserCacheFile :: String -> String -> IO FilePath
getUserCacheFile :: String -> String -> IO String
getUserCacheFile String
a String
f = (String -> String) -> IO String -> IO String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String -> String -> String
</> String
f) (IO String -> IO String) -> IO String -> IO String
forall a b. (a -> b) -> a -> b
$ String -> IO String
getUserCacheDir String
a
getSystemDataFiles :: String -> String -> IO [FilePath]
getSystemDataFiles :: String -> String -> IO [String]
getSystemDataFiles String
a String
f = ([String] -> [String]) -> IO [String] -> IO [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String -> String -> String
</> String
f)) (IO [String] -> IO [String]) -> IO [String] -> IO [String]
forall a b. (a -> b) -> a -> b
$ String -> IO [String]
getSystemDataDirs String
a
getSystemConfigFiles :: String -> String -> IO [FilePath]
getSystemConfigFiles :: String -> String -> IO [String]
getSystemConfigFiles String
a String
f = ([String] -> [String]) -> IO [String] -> IO [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String -> String -> String
</> String
f)) (IO [String] -> IO [String]) -> IO [String] -> IO [String]
forall a b. (a -> b) -> a -> b
$ String -> IO [String]
getSystemConfigDirs String
a
getAllDataFiles :: String -> String -> IO [FilePath]
getAllDataFiles :: String -> String -> IO [String]
getAllDataFiles String
a String
f = ([String] -> [String]) -> IO [String] -> IO [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String -> String -> String
</> String
f)) (IO [String] -> IO [String]) -> IO [String] -> IO [String]
forall a b. (a -> b) -> a -> b
$ String -> IO [String]
getAllDataDirs String
a
getAllConfigFiles :: String -> String -> IO [FilePath]
getAllConfigFiles :: String -> String -> IO [String]
getAllConfigFiles String
a String
f = ([String] -> [String]) -> IO [String] -> IO [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String -> String -> String
</> String
f)) (IO [String] -> IO [String]) -> IO [String] -> IO [String]
forall a b. (a -> b) -> a -> b
$ String -> IO [String]
getAllConfigDirs String
a
singleDir :: String -> String -> IO FilePath
singleDir :: String -> String -> IO String
singleDir String
key String
app = String -> IO String
envLookup String
key IO String -> (String -> IO String) -> IO String
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> IO String) -> (String -> String) -> String -> IO String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> String -> String
</> String
app)
multiDirs :: String -> String -> IO [FilePath]
multiDirs :: String -> String -> IO [String]
multiDirs String
key String
app = String -> IO String
envLookup String
key IO String -> (String -> IO [String]) -> IO [String]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [String] -> IO [String]
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> IO [String])
-> (String -> [String]) -> String -> IO [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String -> String -> String
</> String
app) ([String] -> [String])
-> (String -> [String]) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
splitSearchPath
envLookup :: String -> IO String
envLookup :: String -> IO String
envLookup String
key = do [(String, String)]
env <- IO [(String, String)]
getEnvironment
case String -> [(String, String)] -> Maybe String
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
key [(String, String)]
env of
Just String
val -> String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return String
val
Maybe String
Nothing -> String -> IO String
getDefault String
key
userRelative :: FilePath -> IO FilePath
userRelative :: String -> IO String
userRelative String
p = IO String
getHomeDirectory IO String -> (String -> IO String) -> IO String
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> IO String) -> (String -> String) -> String -> IO String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> String -> String
</> String
p)