module Xmobar.System.Environment(expandEnv) where
import qualified Data.Maybe as M
import qualified System.Environment as E
expandEnv :: String -> IO String
expandEnv :: [Char] -> IO [Char]
expandEnv [Char]
"" = [Char] -> IO [Char]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
""
expandEnv (Char
c:[Char]
s) = case Char
c of
Char
'$' -> do
envVar <- [Char] -> Maybe [Char] -> [Char]
forall a. a -> Maybe a -> a
M.fromMaybe [Char]
"" (Maybe [Char] -> [Char]) -> IO (Maybe [Char]) -> IO [Char]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char] -> IO (Maybe [Char])
E.lookupEnv [Char]
e
remainder <- expandEnv s'
return $ envVar ++ remainder
where ([Char]
e, [Char]
s') = [Char] -> ([Char], [Char])
getVar [Char]
s
getVar :: [Char] -> ([Char], [Char])
getVar [Char]
"" = ([Char]
"", [Char]
"")
getVar (Char
'{':[Char]
s'') = ([Char] -> [Char] -> [Char]
forall {t :: * -> *} {a}. (Foldable t, Eq a) => t a -> [a] -> [a]
takeUntil [Char]
"}" [Char]
s'', Int -> [Char] -> [Char]
forall a. Int -> [a] -> [a]
drop Int
1 ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> [Char] -> [Char]
forall {t :: * -> *} {a}. (Foldable t, Eq a) => t a -> [a] -> [a]
dropUntil [Char]
"}" ([Char] -> [Char]) -> [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ [Char]
s'')
getVar [Char]
s'' = ([Char] -> [Char] -> [Char]
forall {t :: * -> *} {a}. (Foldable t, Eq a) => t a -> [a] -> [a]
takeUntil [Char]
filterstr [Char]
s'', [Char] -> [Char] -> [Char]
forall {t :: * -> *} {a}. (Foldable t, Eq a) => t a -> [a] -> [a]
dropUntil [Char]
filterstr [Char]
s'')
filterstr :: [Char]
filterstr = [Char]
",./? \t;:\"'~`!@#$%^&*()<>-+=\\|"
takeUntil :: t a -> [a] -> [a]
takeUntil t a
f = (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Bool -> Bool
not (Bool -> Bool) -> (a -> Bool) -> a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> t a -> Bool) -> t a -> a -> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> t a -> Bool
forall a. Eq a => a -> t a -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem t a
f)
dropUntil :: t a -> [a] -> [a]
dropUntil t a
f = (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Bool -> Bool
not (Bool -> Bool) -> (a -> Bool) -> a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> t a -> Bool) -> t a -> a -> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> t a -> Bool
forall a. Eq a => a -> t a -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem t a
f)
Char
'\\' -> case [Char]
s [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
== [Char]
"" of
Bool
True -> [Char] -> IO [Char]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return [Char]
"\\"
Bool
False -> do
remainder <- [Char] -> IO [Char]
expandEnv ([Char] -> IO [Char]) -> [Char] -> IO [Char]
forall a b. (a -> b) -> a -> b
$ Int -> [Char] -> [Char]
forall a. Int -> [a] -> [a]
drop Int
1 [Char]
s
return $ escString s ++ remainder
where escString :: [Char] -> [Char]
escString (Char
cc:[Char]
_) =
case Char
cc of
Char
't' -> [Char]
"\t"
Char
'n' -> [Char]
"\n"
Char
'$' -> [Char]
"$"
Char
_ -> [Char
cc]
escString [] = [Char]
""
Char
_ -> do
remainder <- [Char] -> IO [Char]
expandEnv [Char]
s
return $ c : remainder