{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TupleSections #-}
module IO.Keyboard.Parser where
import ClassyPrelude
import Data.Attoparsec.Text
import IO.Keyboard.Types
lexeme :: Parser a -> Parser a
lexeme p = skipSpace *> p <* skipSpace
commentP :: Parser ()
commentP = lexeme $ skipMany (char '#' *> manyTill anyChar endOfLine)
stripComments :: Parser a -> Parser a
stripComments p = lexeme $ commentP *> p <* commentP
word :: Parser Text
word = lexeme $ pack <$> many1 letter
keyP :: Parser Binding
keyP = lexeme $ BKey <$> (char '<' *> word <* char '>')
charP :: Parser Binding
charP = lexeme $ BChar <$> anyChar
bindingP :: Parser [Binding]
bindingP = lexeme $ (keyP <|> charP) `sepBy` char ','
line :: Parser [(Binding, Text)]
line =
stripComments $ do
name <- word
_ <- lexeme $ char '='
binds <- bindingP
pure $ (, name) <$> binds
bindingsP :: Parser Bindings
bindingsP = stripComments $ concat <$> many' line
bindings :: Text -> Either Text Bindings
bindings ini = first (const "Could not parse keyboard bindings.") (parseOnly bindingsP ini)