diff options
| author | Gregor Kleen <gkleen@yggdrasil.li> | 2016-05-07 23:28:18 +0200 |
|---|---|---|
| committer | Gregor Kleen <gkleen@yggdrasil.li> | 2016-05-07 23:28:18 +0200 |
| commit | 6ceaff1e8e111d6b025bd725ee93edb354c535f6 (patch) | |
| tree | 686da728bcc5793f174bd2fb5c8d288e655b16ca | |
| parent | 043d2266e791f86835e82b76426990dba3aed9a0 (diff) | |
| download | 2017-01-16_17:13:37-6ceaff1e8e111d6b025bd725ee93edb354c535f6.tar 2017-01-16_17:13:37-6ceaff1e8e111d6b025bd725ee93edb354c535f6.tar.gz 2017-01-16_17:13:37-6ceaff1e8e111d6b025bd725ee93edb354c535f6.tar.bz2 2017-01-16_17:13:37-6ceaff1e8e111d6b025bd725ee93edb354c535f6.tar.xz 2017-01-16_17:13:37-6ceaff1e8e111d6b025bd725ee93edb354c535f6.zip | |
command parsing with optparse-applicative
| -rw-r--r-- | sequence.cabal | 1 | ||||
| -rw-r--r-- | sequence.nix | 6 | ||||
| -rw-r--r-- | src/Command.hs | 25 | ||||
| -rw-r--r-- | src/Main.hs | 12 |
4 files changed, 29 insertions, 15 deletions
diff --git a/sequence.cabal b/sequence.cabal index 3d7ee92..f0e36c6 100644 --- a/sequence.cabal +++ b/sequence.cabal | |||
| @@ -29,5 +29,6 @@ executable sequence | |||
| 29 | , xdg-basedir | 29 | , xdg-basedir |
| 30 | , data-default-class | 30 | , data-default-class |
| 31 | , haskeline | 31 | , haskeline |
| 32 | , optparse-applicative | ||
| 32 | hs-source-dirs: src | 33 | hs-source-dirs: src |
| 33 | default-language: Haskell2010 \ No newline at end of file | 34 | default-language: Haskell2010 \ No newline at end of file |
diff --git a/sequence.nix b/sequence.nix index a66b771..700a6b4 100644 --- a/sequence.nix +++ b/sequence.nix | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | { mkDerivation, base, case-insensitive, containers | 1 | { mkDerivation, base, case-insensitive, containers |
| 2 | , data-default-class, haskeline, mtl, pqueue, stdenv, text | 2 | , data-default-class, haskeline, mtl, optparse-applicative, pqueue |
| 3 | , transformers, xdg-basedir | 3 | , stdenv, text, transformers, xdg-basedir |
| 4 | }: | 4 | }: |
| 5 | mkDerivation { | 5 | mkDerivation { |
| 6 | pname = "sequence"; | 6 | pname = "sequence"; |
| @@ -10,7 +10,7 @@ mkDerivation { | |||
| 10 | isExecutable = true; | 10 | isExecutable = true; |
| 11 | executableHaskellDepends = [ | 11 | executableHaskellDepends = [ |
| 12 | base case-insensitive containers data-default-class haskeline mtl | 12 | base case-insensitive containers data-default-class haskeline mtl |
| 13 | pqueue text transformers xdg-basedir | 13 | optparse-applicative pqueue text transformers xdg-basedir |
| 14 | ]; | 14 | ]; |
| 15 | description = "A tracker for combat sequences in Contact (a pen&paper rpg by Uhrwerk)"; | 15 | description = "A tracker for combat sequences in Contact (a pen&paper rpg by Uhrwerk)"; |
| 16 | license = stdenv.lib.licenses.gpl3; | 16 | license = stdenv.lib.licenses.gpl3; |
diff --git a/src/Command.hs b/src/Command.hs index 55f4466..4d85489 100644 --- a/src/Command.hs +++ b/src/Command.hs | |||
| @@ -5,13 +5,19 @@ module Command | |||
| 5 | , parseCmd | 5 | , parseCmd |
| 6 | ) where | 6 | ) where |
| 7 | 7 | ||
| 8 | import Options.Applicative | ||
| 9 | |||
| 8 | import Data.Char (isSpace) | 10 | import Data.Char (isSpace) |
| 9 | 11 | ||
| 10 | import Types | 12 | import Types |
| 11 | 13 | ||
| 12 | data Cmd = PerformAlt Alteration | 14 | data Cmd = PerformAlt Alteration |
| 15 | | ModifyTip SequenceValue | ||
| 16 | | OverrideTip SequenceValue | ||
| 17 | | ShowTip | ||
| 18 | | ShowHistory (Maybe Integer) | ||
| 19 | | Dump | ||
| 13 | | Quit | 20 | | Quit |
| 14 | | Step | ||
| 15 | | UnknownCommand String | 21 | | UnknownCommand String |
| 16 | | ParseError String | 22 | | ParseError String |
| 17 | | Empty | 23 | | Empty |
| @@ -24,7 +30,7 @@ isQuote, isEscape :: Char -> Bool | |||
| 24 | isQuote q = q `elem` quoteChars | 30 | isQuote q = q `elem` quoteChars |
| 25 | isEscape e = e `elem` escapeChars | 31 | isEscape e = e `elem` escapeChars |
| 26 | 32 | ||
| 27 | parseCmd :: SequenceM m => String -> m Cmd | 33 | parseCmd :: String -> Cmd |
| 28 | parseCmd = parseCmd' . split | 34 | parseCmd = parseCmd' . split |
| 29 | where | 35 | where |
| 30 | split :: String -> [String] | 36 | split :: String -> [String] |
| @@ -57,6 +63,15 @@ parseCmd = parseCmd' . split | |||
| 57 | , isEscape c = split' ws w q (Just c) cs -- Set escaped flag at unescaped escape char | 63 | , isEscape c = split' ws w q (Just c) cs -- Set escaped flag at unescaped escape char |
| 58 | | otherwise = split' ws (c : w) q Nothing cs -- Append to word | 64 | | otherwise = split' ws (c : w) q Nothing cs -- Append to word |
| 59 | 65 | ||
| 60 | parseCmd' :: SequenceM m => [String] -> m Cmd | 66 | parseCmd' :: [String] -> Cmd |
| 61 | parseCmd' [] = return Empty | 67 | parseCmd' [] = Empty |
| 62 | parseCmd' (cmd:args) = return $ UnknownCommand (show $ cmd:args) -- DEBUG | 68 | parseCmd' args = mapResult runParser |
| 69 | where | ||
| 70 | runParser = execParserPure (prefs $ showHelpOnError) (cmdParser `info` progDesc "sequence - A tracker for combat sequences in Contact (a pen&paper rpg by Uhrwerk)") args | ||
| 71 | mapResult (Success a) = a | ||
| 72 | mapResult (Failure help) = UnknownCommand . fst $ renderFailure help "" | ||
| 73 | mapResult (CompletionInvoked _ ) = ParseError "Completion triggered" | ||
| 74 | |||
| 75 | cmdParser :: Parser Cmd | ||
| 76 | cmdParser = hsubparser $ mconcat [ command "quit" $ pure Quit `info` progDesc "Exit gracefully" | ||
| 77 | ] | ||
diff --git a/src/Main.hs b/src/Main.hs index e6a3024..0088b7c 100644 --- a/src/Main.hs +++ b/src/Main.hs | |||
| @@ -35,18 +35,16 @@ main = do | |||
| 35 | runCli :: (MonadIO m, MonadException m) => SequenceT m () | 35 | runCli :: (MonadIO m, MonadException m) => SequenceT m () |
| 36 | runCli = do | 36 | runCli = do |
| 37 | input <- lift $ getInputLine "→ " | 37 | input <- lift $ getInputLine "→ " |
| 38 | cmnd <- maybe (return $ ParseError "Trying to parse EOF") parseCmd input | ||
| 39 | case input of | 38 | case input of |
| 40 | Nothing -> liftIO exitSuccess | 39 | Nothing -> liftIO exitSuccess |
| 41 | Just _ -> do | 40 | Just input' -> do |
| 42 | case cmnd of | 41 | case parseCmd input' of |
| 43 | UnknownCommand cmd -> do | 42 | UnknownCommand help -> do |
| 44 | lift . outputStrLn $ "Unknown command: »" <> cmd <> "«" | 43 | lift . outputStrLn $ help |
| 45 | ParseError err -> do | 44 | ParseError err -> do |
| 46 | lift . outputStrLn $ "Error parsing input »" <> (fromMaybe "" input) <> "«: " <> err | 45 | lift . outputStrLn $ "Error parsing input »" <> (fromMaybe "" input) <> "«: " <> err |
| 47 | Empty -> return () | 46 | Empty -> return () |
| 48 | 47 | ||
| 49 | Quit -> liftIO exitSuccess | 48 | Quit -> liftIO exitSuccess |
| 50 | PerformAlt alt -> apply' alt | 49 | _ -> undefined |
| 51 | Step -> undefined | ||
| 52 | runCli | 50 | runCli |
