packages feed

msu-0.0.2: MSU/Xrandr/Parse.hs

module MSU.Xrandr.Parse where

import MSU.Display
import Text.Parsec
import Text.Parsec.String

parseXrandr :: String -> Either ParseError [Display]
parseXrandr = parse parseDisplays "xrandr --query"

parseDisplays :: Parser [Display]
parseDisplays = do
    string "Screen" >> ignoreLine

    manyTill parseDisplay eof

parseDisplay :: Parser Display
parseDisplay = do
    n <- manyTill anyToken space
    c <- string "connected" <|> string "disconnected"
    ignoreLine

    ms <- if c == "connected"
            then parseModeLines
            else skipModeLines

    return $ Display n ms

parseModeLines :: Parser [Mode]
parseModeLines = manyTill parseModeLine nextDisplay

skipModeLines :: Parser [Mode]
skipModeLines = ignoreLinesTill nextDisplay >> return []

parseModeLine :: Parser Mode
parseModeLine = do
    w <- spaces >> many digit
    h <- char 'x' >> many digit
    ignoreLine

    return $ Mode (read w) (read h)

nextDisplay :: Parser ()
nextDisplay = lookAhead $ try parseDisplay >> return ()

ignoreLinesTill :: Parser () -> Parser ()
ignoreLinesTill p = do
    _ <- manyTill ignoreLine $ p <|> eof
    return ()

ignoreLine :: Parser ()
ignoreLine = manyTill anyToken eol >> return ()

    where
        eol :: Parser Char
        eol = char '\n'