packages feed

tinyapp 0.1.0.2 → 0.2.0.0

raw patch · 4 files changed

+150/−7 lines, 4 filesdep +brickdep +mtldep +vtydep ~basePVP ok

version bump matches the API change (PVP)

Dependencies added: brick, mtl, vty

Dependency ranges changed: base

API changes (from Hackage documentation)

+ TinyApp.Interactive: Continue :: ContinueExit
+ TinyApp.Interactive: Exit :: ContinueExit
+ TinyApp.Interactive: KBS :: Key
+ TinyApp.Interactive: KBackTab :: Key
+ TinyApp.Interactive: KBegin :: Key
+ TinyApp.Interactive: KCenter :: Key
+ TinyApp.Interactive: KChar :: Char -> Key
+ TinyApp.Interactive: KDel :: Key
+ TinyApp.Interactive: KDown :: Key
+ TinyApp.Interactive: KDownLeft :: Key
+ TinyApp.Interactive: KDownRight :: Key
+ TinyApp.Interactive: KEnd :: Key
+ TinyApp.Interactive: KEnter :: Key
+ TinyApp.Interactive: KEsc :: Key
+ TinyApp.Interactive: KFun :: Int -> Key
+ TinyApp.Interactive: KHome :: Key
+ TinyApp.Interactive: KIns :: Key
+ TinyApp.Interactive: KLeft :: Key
+ TinyApp.Interactive: KMenu :: Key
+ TinyApp.Interactive: KPageDown :: Key
+ TinyApp.Interactive: KPageUp :: Key
+ TinyApp.Interactive: KPause :: Key
+ TinyApp.Interactive: KPrtScr :: Key
+ TinyApp.Interactive: KRight :: Key
+ TinyApp.Interactive: KUp :: Key
+ TinyApp.Interactive: KUpLeft :: Key
+ TinyApp.Interactive: KUpRight :: Key
+ TinyApp.Interactive: Key :: Key -> [Modifier] -> Event
+ TinyApp.Interactive: MAlt :: Modifier
+ TinyApp.Interactive: MCtrl :: Modifier
+ TinyApp.Interactive: MMeta :: Modifier
+ TinyApp.Interactive: MShift :: Modifier
+ TinyApp.Interactive: Sandbox :: state -> (state -> String) -> (Event -> state -> (state, ContinueExit)) -> Sandbox state
+ TinyApp.Interactive: [initialize] :: Sandbox state -> state
+ TinyApp.Interactive: [render] :: Sandbox state -> state -> String
+ TinyApp.Interactive: [update] :: Sandbox state -> Event -> state -> (state, ContinueExit)
+ TinyApp.Interactive: data ContinueExit
+ TinyApp.Interactive: data Event
+ TinyApp.Interactive: data Key
+ TinyApp.Interactive: data Modifier
+ TinyApp.Interactive: data Sandbox state
+ TinyApp.Interactive: instance GHC.Classes.Eq TinyApp.Interactive.ContinueExit
+ TinyApp.Interactive: instance GHC.Classes.Eq TinyApp.Interactive.Key
+ TinyApp.Interactive: instance GHC.Classes.Eq TinyApp.Interactive.Modifier
+ TinyApp.Interactive: instance GHC.Classes.Ord TinyApp.Interactive.Key
+ TinyApp.Interactive: instance GHC.Classes.Ord TinyApp.Interactive.Modifier
+ TinyApp.Interactive: instance GHC.Read.Read TinyApp.Interactive.Key
+ TinyApp.Interactive: instance GHC.Read.Read TinyApp.Interactive.Modifier
+ TinyApp.Interactive: instance GHC.Show.Show TinyApp.Interactive.ContinueExit
+ TinyApp.Interactive: instance GHC.Show.Show TinyApp.Interactive.Key
+ TinyApp.Interactive: instance GHC.Show.Show TinyApp.Interactive.Modifier
+ TinyApp.Interactive: runInteractive :: Sandbox s -> IO ()
+ TinyApp.Interactive: runInteractive' :: forall s. Sandbox s -> IO s

Files

CHANGELOG.md view
@@ -1,5 +1,9 @@ # Revision history for tinyapp +## 0.2.0.0 -- 2024-11-01++* Add support for interactive applications that renders text based on keystrokes. Great for small games.+ ## 0.1.0.0 -- 2024-07-18 -* First version.+* Add support for REPL applications.
+ src/TinyApp/Interactive.hs view
@@ -0,0 +1,135 @@+-- | Build interactice apps that reacts to each keystroke and renders text+-- Requires `ghc-options: -threaded`+module TinyApp.Interactive+  ( Event (..),+    Key (..),+    Modifier (..),+    Sandbox (..),+    ContinueExit (..),+    runInteractive,+    runInteractive',+  )+where++import Brick qualified as B+import Brick.Main qualified as BM+import Brick.Types qualified as BT+import Brick.Widgets.Core qualified as BWC+import Control.Monad+import Control.Monad.State+import Graphics.Vty qualified as V+import Graphics.Vty.Input.Events qualified as VE++-- | Representes keys that can be pressed+data Key+  = KEsc+  | KChar Char+  | KBS+  | KEnter+  | KLeft+  | KRight+  | KUp+  | KDown+  | KUpLeft+  | KUpRight+  | KDownLeft+  | KDownRight+  | KCenter+  | KFun Int+  | KBackTab+  | KPrtScr+  | KPause+  | KIns+  | KHome+  | KPageUp+  | KDel+  | KEnd+  | KPageDown+  | KBegin+  | KMenu+  deriving (Eq, Show, Read, Ord)++fromVKey :: V.Key -> Key+fromVKey V.KEsc = KEsc+fromVKey (V.KChar char) = KChar char+fromVKey V.KBS = KBS+fromVKey V.KEnter = KEnter+fromVKey V.KLeft = KLeft+fromVKey V.KRight = KRight+fromVKey V.KUp = KUp+fromVKey V.KDown = KDown+fromVKey V.KUpLeft = KUpLeft+fromVKey V.KUpRight = KUpRight+fromVKey V.KDownLeft = KDownLeft+fromVKey V.KDownRight = KDownRight+fromVKey V.KCenter = KCenter+fromVKey (V.KFun int) = KFun int+fromVKey V.KBackTab = KBackTab+fromVKey V.KPrtScr = KPrtScr+fromVKey V.KPause = KPause+fromVKey V.KIns = KIns+fromVKey V.KHome = KHome+fromVKey V.KPageUp = KPageUp+fromVKey V.KDel = KDel+fromVKey V.KEnd = KEnd+fromVKey V.KPageDown = KPageDown+fromVKey V.KBegin = KBegin+fromVKey V.KMenu = KMenu++-- | Modifiers keys+data Modifier = MShift | MCtrl | MMeta | MAlt+  deriving (Eq, Show, Read, Ord)++fromVModifier :: V.Modifier -> Modifier+fromVModifier V.MShift = MShift+fromVModifier V.MCtrl = MCtrl+fromVModifier V.MMeta = MMeta+fromVModifier V.MAlt = MAlt++-- | Event the application can receive+data Event = Key Key [Modifier]++-- | Signals whether the application should continue waiting input from the user or exit.+data ContinueExit = Continue | Exit+  deriving (Eq, Show)++-- | Defines an interactive application that is not allowed to perform arbitrary IO while executing.+data Sandbox state = Sandbox+  { -- | Initial state+    initialize :: state,+    -- | What to draw based on the current state.+    -- The screen is cleared between render calls. Usually use '\n' or *Prelude.unlines* to render multiple lines.+    render :: state -> String,+    -- | Process the event given the current state+    -- Returns the next state and whether to continue or not the program+    update :: Event -> state -> (state, ContinueExit)+  }++-- | Executes the application.+runInteractive :: Sandbox s -> IO ()+runInteractive = Control.Monad.void . runInteractive'++-- | Executes the application returning its final state.+runInteractive' :: forall s. Sandbox s -> IO s+runInteractive' config =+  let app :: BM.App s e ()+      app =+        BM.App+          { BM.appDraw = \s -> [BWC.str (config.render s)],+            BM.appChooseCursor = \_ _ -> Nothing,+            BM.appHandleEvent = \e -> do+              s <- get+              case e of+                BT.VtyEvent (VE.EvKey k ms) ->+                  case config.update (Key (fromVKey k) (map fromVModifier ms)) s of+                    (s', Continue) -> do+                      put s'+                    (s', Exit) -> do+                      put s'+                      BM.halt+                _ ->+                  return (),+            BM.appStartEvent = return (),+            BM.appAttrMap = \_ -> B.attrMap V.defAttr []+          }+   in BM.defaultMain app config.initialize
src/TinyApp/Repl.hs view
@@ -5,11 +5,11 @@ import Control.Monad import System.IO --- | Signals whether the REPL should continue asking input from the user or exit.+-- | Signals whether the application should continue asking input from the user or exit. data ContinueExit = Continue | Exit   deriving (Eq, Show) --- | Defines a REPL application that is not allows to perform arbitrary IO while executing.+-- | Defines a REPL application that is not allowed to perform arbitrary IO while executing. data Sandbox state = Sandbox   { -- | Initial state     initialize :: state,
tinyapp.cabal view
@@ -1,8 +1,8 @@ cabal-version:      3.0 name:               tinyapp-version:            0.1.0.2+version:            0.2.0.0 synopsis:           Library to build tiny apps in Haskell-description:        Library to build tiny apps in Haskell such a REPLs+description:        Library to build tiny apps in Haskell such a REPLs or text-based applications that reacts to keystrokes homepage:           https://github.com/bcardiff/haskell-tinyapp license:            MIT license-file:       LICENSE@@ -12,7 +12,7 @@ build-type:         Simple extra-doc-files:    CHANGELOG.md -- extra-source-files:-category:           REPL, Command Line+category:           REPL, tui, Command Line  common warnings     ghc-options: -Wall@@ -21,10 +21,14 @@     import:           warnings     exposed-modules:         TinyApp.Repl+        TinyApp.Interactive     -- other-modules:     -- other-extensions:     build-depends:-        base >=4.17.2.1 && <5.0+        base >=4.17.2.1 && <5.0,+        brick >= 2.4 && < 2.5,+        vty >= 6.2 && < 6.3,+        mtl >= 2.2.2 && < 2.3,     hs-source-dirs:   src     default-language: GHC2021     default-extensions: