prompt-hs 1.0.0.0 → 1.0.1.0
raw patch · 3 files changed
+83/−2 lines, 3 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ System.Prompt: ($dminitialSelectionChooseable) :: (Chooseable a, Bounded a) => a
+ System.Prompt: ($dmuniverseChooseableNE) :: (Chooseable a, Bounded a, Enum a) => NonEmpty a
+ System.Prompt: promptYesNo :: forall result (requirement :: SRequirement) m. (result ~ PerRequirement requirement Bool, MonadIO m) => Requirement requirement -> Confirmation -> Text -> m result
+ System.Prompt: promptYesNoWithDefault :: MonadIO m => Confirmation -> Bool -> Text -> m Bool
- System.Prompt: initialSelectionChooseable :: (Chooseable a, Bounded a) => a
+ System.Prompt: initialSelectionChooseable :: Chooseable a => a
- System.Prompt: promptChoice :: (result ~ PerRequirement requirement a, Chooseable result, Eq result, MonadIO m) => Requirement requirement -> Confirmation -> Proxy a -> Text -> m result
+ System.Prompt: promptChoice :: forall result (requirement :: SRequirement) a m. (result ~ PerRequirement requirement a, Chooseable result, Eq result, MonadIO m) => Requirement requirement -> Confirmation -> Proxy a -> Text -> m result
- System.Prompt: promptText :: (result ~ PerRequirement requirement Text, MonadIO m) => Requirement requirement -> Confirmation -> Text -> m result
+ System.Prompt: promptText :: forall result (requirement :: SRequirement) m. (result ~ PerRequirement requirement Text, MonadIO m) => Requirement requirement -> Confirmation -> Text -> m result
- System.Prompt: type family PerRequirement (requirement :: SRequirement) (a :: Type)
+ System.Prompt: type family PerRequirement (requirement :: SRequirement) a
- System.Prompt: universeChooseableNE :: (Chooseable a, Bounded a, Enum a) => NonEmpty a
+ System.Prompt: universeChooseableNE :: Chooseable a => NonEmpty a
Files
- README.md +1/−0
- prompt-hs.cabal +1/−1
- src/System/Prompt.hs +81/−1
README.md view
@@ -2,6 +2,7 @@ A user-friendly, dependently-typed library for asking your users questions + [?style=flat-square&logo=nixos&logoColor=white&link=https://github.com/gchq/nix-bootstrap)](https://github.com/gchq/nix-bootstrap) ### Table of Contents
prompt-hs.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: prompt-hs-version: 1.0.0.0+version: 1.0.1.0 synopsis: A user-friendly, dependently-typed library for asking your users questions description: A library making use of the terminal package to prompt users for answers in a CLI context. .
src/System/Prompt.hs view
@@ -36,6 +36,8 @@ module System.Prompt ( -- * Actions promptText,+ promptYesNo,+ promptYesNoWithDefault, promptChoice, promptChoiceFromSet, @@ -68,7 +70,7 @@ Event (KeyEvent), Interrupt (Interrupt), Key (ArrowKey, BackspaceKey, CharKey, EnterKey, EscapeKey),- MonadColorPrinter (blue, cyan, foreground, magenta, yellow),+ MonadColorPrinter (blue, cyan, foreground, magenta, red, yellow), MonadFormattingPrinter (bold, italic), MonadInput, MonadMarkupPrinter (Attribute, resetAttributes, setAttribute),@@ -259,6 +261,42 @@ ptsRequirement = requirement } +-- | Ask the user to enter yes or no.+--+-- The answer is given as a Bool - True for yes, False for no.+--+-- > promptYesNo Required DontConfirm "Do you see light at the end of the road?"+promptYesNo ::+ (result ~ PerRequirement requirement Bool, MonadIO m) =>+ -- | May they skip the question?+ Requirement requirement ->+ -- | Should they be asked to confirm their answer after entering it?+ Confirmation ->+ -- | What should the prompt say? (appends [y/n]: automatically)+ Text ->+ m result+promptYesNo requirement confirmation prompt = promptYesNo' requirement confirmation (prompt <> " [y/n]:")++-- | Ask the user to enter yes or no. If they choose not to answer, use the default instead.+--+-- The answer is given as a Bool - True for yes, False for no.+--+-- > promptYesNo DontConfirm False "Do you see light at the end of the road?"+promptYesNoWithDefault ::+ (MonadIO m) =>+ -- | Should they be asked to confirm their answer after entering it?+ Confirmation ->+ -- | The default response+ Bool ->+ -- | What should the prompt say? (appends [y/n]: with capitalisation of the default automatically)+ Text ->+ m Bool+promptYesNoWithDefault confirmation def prompt = do+ let promptSuffix = if def then " [Y/n]:" else " [y/N]:"+ promptYesNo' Optional confirmation (prompt <> promptSuffix) >>= \case+ Just yesNo -> pure yesNo+ Nothing -> pure def+ initialPromptChoiceState :: (Chooseable (PerRequirement requirement a)) => Requirement requirement ->@@ -538,6 +576,48 @@ (Required, _) -> selection (Optional, True) -> Nothing (Optional, False) -> Just selection++-- | Internal handler for promptYesNo, without appending prompt.+promptYesNo' ::+ (result ~ PerRequirement requirement Bool, MonadIO m) =>+ -- | May they skip the question?+ Requirement requirement ->+ -- | Should they be asked to confirm their answer after entering it?+ Confirmation ->+ -- | What should the prompt say? (does not append [y/n]: automatically)+ Text ->+ m result+promptYesNo' requirement confirmation prompt = do+ response <- promptText requirement confirmation prompt+ case requirement of+ Required -> case parseYesNo response of+ Just yesNo -> pure yesNo+ Nothing -> do+ liftIO . withTerminal . runTerminalT $ putErrorLn "You must answer yes or no."+ promptYesNo' requirement confirmation prompt+ Optional ->+ case response of+ Just res -> case parseYesNo res of+ Just yesNo -> pure $ Just yesNo+ Nothing -> do+ liftIO . withTerminal . runTerminalT $ putErrorLn "Answer yes or no, or leave your answer blank to skip the question."+ promptYesNo' requirement confirmation prompt+ Nothing ->+ pure Nothing+ where+ parseYesNo :: Text -> Maybe Bool+ parseYesNo =+ \case+ "y" -> Just True+ "yes" -> Just True+ "n" -> Just False+ "no" -> Just False+ _ -> Nothing+ . T.toLower++-- | Outputs an error message+putErrorLn :: (MonadColorPrinter m, MonadFormattingPrinter m) => Text -> m ()+putErrorLn msg = withAttributes [foreground red, bold] (putTextLn msg) >> flush -- | Applies the given attributes to the terminal, runs the action, -- then resets the terminal's attributes.