byline 1.1.1 → 1.1.2
raw patch · 13 files changed
+122/−65 lines, 13 filesdep ~haskelinedep ~mtldep ~optparse-applicativenew-component:exe:colorsPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: haskeline, mtl, optparse-applicative, relude, text
API changes (from Hackage documentation)
+ Byline: dull :: Color -> Color
+ Byline: vivid :: Color -> Color
+ Byline.Simulation: dull :: Color -> Color
+ Byline.Simulation: vivid :: Color -> Color
- Byline: bg :: Color -> Stylized Text
+ Byline: bg :: Color -> Stylized Text -> Stylized Text
- Byline: bold :: Stylized Text
+ Byline: bold :: Stylized Text -> Stylized Text
- Byline: fg :: Color -> Stylized Text
+ Byline: fg :: Color -> Stylized Text -> Stylized Text
- Byline: swapFgBg :: Stylized Text
+ Byline: swapFgBg :: Stylized Text -> Stylized Text
- Byline: underline :: Stylized Text
+ Byline: underline :: Stylized Text -> Stylized Text
- Byline.Simulation: bg :: Color -> Stylized Text
+ Byline.Simulation: bg :: Color -> Stylized Text -> Stylized Text
- Byline.Simulation: bold :: Stylized Text
+ Byline.Simulation: bold :: Stylized Text -> Stylized Text
- Byline.Simulation: fg :: Color -> Stylized Text
+ Byline.Simulation: fg :: Color -> Stylized Text -> Stylized Text
- Byline.Simulation: swapFgBg :: Stylized Text
+ Byline.Simulation: swapFgBg :: Stylized Text -> Stylized Text
- Byline.Simulation: underline :: Stylized Text
+ Byline.Simulation: underline :: Stylized Text -> Stylized Text
Files
- CHANGES.md +1/−0
- README.md +4/−4
- byline.cabal +17/−8
- examples/colors.hs +35/−0
- examples/demo.hs +3/−3
- examples/menu.hs +5/−5
- examples/simple.hs +7/−7
- src/Byline.hs +2/−0
- src/Byline/Internal/Color.hs +24/−12
- src/Byline/Internal/Stylized.hs +19/−21
- src/Byline/Internal/Types.hs +1/−1
- src/Byline/Shell.hs +1/−1
- test/Main.hs +3/−3
CHANGES.md view
@@ -12,6 +12,7 @@ - 1.1.0.1 (October 27, 2020): Limit `optparse-applicative` to 0.16.x - 1.1.1 (June 2, 2021): Build with GHC 9.0.1+ - 1.1.2 (January 20, 2023): Build with GHC 9.2.4 (thanks @Arraying) ## 1.0 (July 27, 2020)
README.md view
@@ -1,6 +1,6 @@ # Byline -[](https://github.com/pjones/byline/actions)+[](https://github.com/pjones/byline/actions) [](https://github.com/pjones/byline/releases) [](https://hackage.haskell.org/package/byline) @@ -20,13 +20,13 @@ ```haskell example :: MonadByline m => m Text example = do- sayLn ("Hey, I like " <> ("Haskell" <> fg magenta) <> "!")+ sayLn ("Hey, I like " <> ("Haskell" & fg magenta) <> "!") let question = "What's "- <> ("your" <> bold)+ <> ("your" & bold) <> " favorite "- <> ("language" <> fg green <> underline)+ <> ("language" & fg green & underline) <> "? " askLn question (Just "Haskell")
byline.cabal view
@@ -1,17 +1,17 @@ cabal-version: 2.2 name: byline-version: 1.1.1+version: 1.1.2 homepage: https://github.com/pjones/byline bug-reports: https://github.com/pjones/byline/issues license: BSD-2-Clause license-file: LICENSE author: Peter Jones <pjones@devalot.com> maintainer: Peter Jones <pjones@devalot.com>-copyright: Copyright: (c) 2015-2021 Peter J. Jones+copyright: Copyright: (c) 2015-2023 Peter J. Jones category: System, User Interfaces build-type: Simple stability: stable-tested-with: GHC ==8.8.4 || ==8.10.4 || ==9.0.1+tested-with: GHC ==8.10.7 || ==9.0.2 || ==9.2.5 synopsis: Library for creating command-line interfaces (colors, menus, etc.) @@ -101,12 +101,12 @@ , colour ^>=2.3 , exceptions >=0.8 && <0.11 , free ^>=5.1- , haskeline >=0.8 && <0.8.2- , mtl >=2.1 && <2.3- , optparse-applicative ^>=0.16- , relude >=0.6 && <1.1+ , haskeline >=0.8 && <0.8.3+ , mtl >=2.1 && <2.4+ , optparse-applicative ^>=0.17+ , relude >=0.6 && <1.2 , terminfo-hs >=0.1 && <0.3- , text >=0.11 && <1.3+ , text >=0.11 && <2.1 mixins: base hiding (Prelude),@@ -173,6 +173,15 @@ executable shell import: options, dependencies main-is: examples/shell.hs+ build-depends: byline++ if !flag(build-examples)+ buildable: False++--------------------------------------------------------------------------------+executable colors+ import: options, dependencies+ main-is: examples/colors.hs build-depends: byline if !flag(build-examples)
+ examples/colors.hs view
@@ -0,0 +1,35 @@+-- |+--+-- Copyright:+-- This file is part of the package byline. It is subject to the+-- license terms in the LICENSE file found in the top-level+-- directory of this distribution and at:+--+-- https://github.com/pjones/byline+--+-- No part of this package, including this file, may be copied,+-- modified, propagated, or distributed except according to the+-- terms contained in the LICENSE file.+--+-- License: BSD-2-Clause+module Main+ ( main,+ )+where++import Byline+import Control.Monad++-- | Simple example.+example :: MonadByline m => m ()+example = do+ let colors = [black, red, yellow, green, blue, cyan, magenta, white]+ let styles = [id, underline, bold, bold . underline]+ let intensity = [id, vivid]+ let fgbg = [id, swapFgBg]+ let mods = [ (text "byline" &) <$> [fb . fg (i c) . s | c <- colors] | fb <- fgbg, i <- intensity, s <- styles]+ mapM_ (sayLn . fold) mods++-- | Main.+main :: IO ()+main = Control.Monad.void (runBylineT example)
examples/demo.hs view
@@ -22,13 +22,13 @@ -- | Simple example. example :: MonadByline m => m Text example = do- sayLn ("Hey, I like " <> ("Haskell" <> fg magenta) <> "!")+ sayLn ("Hey, I like " <> ("Haskell" & fg magenta) <> "!") let question = "What's "- <> ("your" <> bold)+ <> ("your" & bold) <> " favorite "- <> ("language" <> fg green <> underline)+ <> ("language" & fg green & underline) <> "? " askLn question (Just "Haskell")
@@ -29,8 +29,8 @@ -- | How to display a menu item. instance ToStylizedText Item where toStylizedText item = case item of- Fruit name -> text name <> (" (fruit)" <> fg red)- Vegetable name -> text name <> (" (vegetable)" <> fg green)+ Fruit name -> text name <> (" (fruit)" & fg red)+ Vegetable name -> text name <> (" (vegetable)" & fg green) -- | The list of menu items. items :: NonEmpty Item@@ -46,10 +46,10 @@ main :: IO () main = do let menuConfig =- menuBanner ("Pick a snack: " <> bold) $+ menuBanner ("Pick a snack: " & bold) $ menu items- prompt = "Which snack? " <> bold <> fg yellow- onError = "Please pick a valid item!" <> fg red+ prompt = "Which snack? " & bold & fg yellow+ onError = "Please pick a valid item!" & bg (vivid red) -- Display the menu and get back the item the user selected. The -- user will be able to select an item using it's index, name, or
examples/simple.hs view
@@ -25,7 +25,7 @@ main = void $ runBylineT $ do -- Start with a simple message to standard output:- sayLn ("I can use " <> ("color" <> fg blue) <> "!")+ sayLn ("I can use " <> ("color" & fg blue) <> "!") -- When not using any stylized modifiers you can use the `text' -- helper function to avoid "Ambiguous type variable":@@ -34,26 +34,26 @@ -- Get user input with a stylized prompt: let question = "What's your favorite "- <> ("language" <> bold <> fg green)+ <> ("language" & bold & fg green) <> "? " language <- askLn question Nothing if Text.null language- then Exit.die ("Cat got your tongue?" <> fg magenta)- else sayLn ("I see, you like " <> (text language <> fg red) <> ".")+ then Exit.die ("Cat got your tongue?" & fg (vivid magenta))+ else sayLn ("I see, you like " <> (text language & fg red) <> ".") -- Keep prompting until a confirmation function indicates that the -- user's input is sufficient: let question = "What's your "- <> ("name" <> fg green <> underline)+ <> ("name" & fg green & underline) <> "? " name <- askUntil question Nothing (pure . atLeastThreeChars)- sayLn $ "Hey there " <> text name <> fg (rgb 108 113 196)+ sayLn $ "Hey there " <> text name & fg (rgb 108 113 196) -- | Example confirmation function that requires the input to be three -- or more characters long. atLeastThreeChars :: Text -> Either (Stylized Text) Text atLeastThreeChars input- | Text.length input < 3 = Left ("You can do better." <> bg red)+ | Text.length input < 3 = Left ("You can do better." & bg red) | otherwise = Right input
src/Byline.hs view
@@ -49,6 +49,8 @@ magenta, cyan, white,+ vivid,+ dull, rgb, ) where
src/Byline/Internal/Color.hs view
@@ -24,6 +24,8 @@ magenta, cyan, white,+ vivid,+ dull, rgb, colorAsANSI, colorAsIndex256,@@ -42,15 +44,25 @@ -- -- @since 1.0.0.0 black, red, green, yellow, blue, magenta, cyan, white :: Color-black = ColorCode ANSI.Black-red = ColorCode ANSI.Red-green = ColorCode ANSI.Green-yellow = ColorCode ANSI.Yellow-blue = ColorCode ANSI.Blue-magenta = ColorCode ANSI.Magenta-cyan = ColorCode ANSI.Cyan-white = ColorCode ANSI.White+black = ColorCode ANSI.Dull ANSI.Black+red = ColorCode ANSI.Dull ANSI.Red+green = ColorCode ANSI.Dull ANSI.Green+yellow = ColorCode ANSI.Dull ANSI.Yellow+blue = ColorCode ANSI.Dull ANSI.Blue+magenta = ColorCode ANSI.Dull ANSI.Magenta+cyan = ColorCode ANSI.Dull ANSI.Cyan+white = ColorCode ANSI.Dull ANSI.White +-- | Intensify an ANSI color.+vivid :: Color -> Color+vivid (ColorCode _ c) = ColorCode ANSI.Vivid c+vivid c = c++-- | Dull an ANSI color.+dull :: Color -> Color+dull (ColorCode _ c) = ColorCode ANSI.Dull c+dull c = c+ -- | Specify a color using a RGB triplet where each component is in -- the range @[0 .. 255]@. The actual rendered color will depend on -- the terminal.@@ -81,7 +93,7 @@ -- -- @since 1.0.0.0 colorAsANSI :: Color -> ANSI.Color-colorAsANSI (ColorCode c) = c+colorAsANSI (ColorCode _ c) = c colorAsANSI (ColorRGB c) = nearestColor c ansiColorLocations -- | Convert a Byline color to an index into a terminal 256-color palette.@@ -89,7 +101,7 @@ -- @since 1.0.0.0 colorAsIndex256 :: Color -> Word8 colorAsIndex256 = \case- ColorCode c -> ANSI.xtermSystem ANSI.Dull c+ ColorCode i c -> ANSI.xtermSystem i c ColorRGB c -> nearestColor c term256Locations -- | Convert a Byline color to a 'C.Colour'. If the color is@@ -97,9 +109,9 @@ -- instead. This allows the terminal to pick the color on its own. -- -- @since 1.0.0.0-colorAsRGB :: Color -> Either ANSI.Color (C.Colour Float)+colorAsRGB :: Color -> Either (ANSI.ColorIntensity, ANSI.Color) (C.Colour Float) colorAsRGB = \case- ColorCode c -> Left c+ ColorCode i c -> Left (i,c) ColorRGB (r, g, b) -> Right (C.sRGB24 r g b) -- | Find the nearest color given a full RGB color.
src/Byline/Internal/Stylized.hs view
@@ -43,8 +43,6 @@ data Stylized a = -- | Something to stylize. Stylized Modifier a- | -- | Modify the next stylized value.- StylizedMod Modifier | -- | Multiple stylized values. StylizedList [Stylized a] deriving (Show, Eq, Functor, Foldable, Traversable)@@ -53,15 +51,9 @@ instance Semigroup (Stylized a) where -- StylizedText on LHS. (<>) a@(Stylized _ _) b@(Stylized _ _) = StylizedList [a, b]- (<>) (Stylized m t) (StylizedMod m') = Stylized (m <> m') t (<>) a@(Stylized _ _) (StylizedList b) = StylizedList (a : b)- -- StylizedMod on LHS.- (<>) (StylizedMod m) (Stylized m' t) = Stylized (m <> m') t- (<>) (StylizedMod m) (StylizedMod m') = StylizedMod (m <> m')- (<>) m@(StylizedMod _) (StylizedList l) = StylizedList (map (m <>) l) -- StylizedList on LHS. (<>) (StylizedList l) t@(Stylized _ _) = StylizedList (l <> [t])- (<>) (StylizedList l) m@(StylizedMod _) = StylizedList (map (<> m) l) (<>) (StylizedList l) (StylizedList l') = StylizedList (l <> l') -- | @since 1.0.0.0@@ -100,32 +92,37 @@ -- @ -- -- @since 1.0.0.0-fg :: Color -> Stylized Text-fg c = StylizedMod (mempty {modColorFG = OnlyOne (Just c)})+fg :: Color -> Stylized Text -> Stylized Text+fg c (Stylized m t) = Stylized (m {modColorFG = OnlyOne (Just c)}) t+fg c (StylizedList l) = StylizedList (map (fg c) l) -- | Set the background color. -- -- @since 1.0.0.0-bg :: Color -> Stylized Text-bg c = StylizedMod (mempty {modColorBG = OnlyOne (Just c)})+bg :: Color -> Stylized Text -> Stylized Text+bg c (Stylized m t) = Stylized (m {modColorBG = OnlyOne (Just c)}) t+bg c (StylizedList l) = StylizedList (map (bg c) l) -- | Produce bold text. -- -- @since 1.0.0.0-bold :: Stylized Text-bold = StylizedMod (mempty {modBold = On})+bold :: Stylized Text -> Stylized Text+bold (Stylized m t) = Stylized (m {modBold = On}) t+bold (StylizedList l) = StylizedList (map bold l) -- | Produce underlined text. -- -- @since 1.0.0.0-underline :: Stylized Text-underline = StylizedMod (mempty {modUnderline = On})+underline :: Stylized Text -> Stylized Text+underline (Stylized m t) = Stylized (m {modUnderline = On}) t+underline (StylizedList l) = StylizedList (map underline l) -- | Produce swapped foreground/background text. -- -- @since 1.0.0.0-swapFgBg :: Stylized Text-swapFgBg = StylizedMod (mempty {modSwapFgBg = On})+swapFgBg :: Stylized Text -> Stylized Text+swapFgBg (Stylized m t) = Stylized (m {modSwapFgBg = On}) t+swapFgBg (StylizedList l) = StylizedList (map swapFgBg l) -- | How to render stylized text. --@@ -181,7 +178,6 @@ renderInstructions :: RenderMode -> Stylized Text -> [RenderInstruction] renderInstructions mode = \case Stylized m t -> renderMod mode (t, m)- StylizedMod _ -> [] StylizedList xs -> concatMap (renderInstructions mode) xs where renderMod :: RenderMode -> (Text, Modifier) -> [RenderInstruction]@@ -192,7 +188,9 @@ [RenderText t] Simple -> -- Terminal supports basic 16 colors.- let color l = ANSI.SetColor l ANSI.Dull . Color.colorAsANSI+ let color l c = case c of+ Color.ColorCode ai ac -> ANSI.SetColor l ai ac+ rgb -> ANSI.SetColor l ANSI.Dull (Color.colorAsANSI rgb) in renderToSGR t m color Term256 -> -- Terminal supports the 256-color palette.@@ -201,7 +199,7 @@ TermRGB -> -- Super terminal! let color l c = case Color.colorAsRGB c of- Left ac -> ANSI.SetColor l ANSI.Dull ac+ Left (ai,ac) -> ANSI.SetColor l ai ac Right rgb -> ANSI.SetRGBColor l rgb in renderToSGR t m color renderToSGR ::
src/Byline/Internal/Types.hs view
@@ -33,7 +33,7 @@ -- -- @since 1.0.0.0 data Color- = ColorCode ANSI.Color+ = ColorCode ANSI.ColorIntensity ANSI.Color | ColorRGB (Word8, Word8, Word8) deriving (Show, Eq)
src/Byline/Shell.hs view
@@ -144,7 +144,7 @@ then pure [] else case Atto.parseOnly go input of Left e -> do- sayLn (("invalid input" <> fg red) <> ": " <> text (toText e))+ sayLn (("invalid input" & fg red) <> ": " <> text (toText e)) pure [] Right ws -> pure ws
test/Main.hs view
@@ -23,13 +23,13 @@ example :: MonadByline m => m Text example = do- sayLn ("Hey, I like " <> ("Haskell" <> fg magenta) <> "!")+ sayLn ("Hey, I like " <> ("Haskell" & fg magenta) <> "!") let question = "What's "- <> ("your" <> bold)+ <> ("your" & bold) <> " favorite "- <> ("language" <> fg green <> underline)+ <> ("language" & fg (vivid green) & underline) <> "? " askLn question (Just "Haskell")