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