packages feed

brick 0.63 → 0.64

raw patch · 16 files changed

+162/−76 lines, 16 filesdep ~text-zipperdep ~vtyPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: text-zipper, vty

API changes (from Hackage documentation)

+ Brick.Main: continueWithoutRedraw :: s -> EventM n (Next s)
+ Brick.Types: [cursorLocationVisible] :: CursorLocation n -> !Bool
+ Brick.Widgets.Core: putCursor :: n -> Location -> Widget n -> Widget n
- Brick.Types: CursorLocation :: !Location -> !Maybe n -> CursorLocation n
+ Brick.Types: CursorLocation :: !Location -> !Maybe n -> !Bool -> CursorLocation n
- Brick.Types: bordersL :: forall n_axXs. Lens' (Result n_axXs) (BorderMap DynBorder)
+ Brick.Types: bordersL :: forall n_axZ5. Lens' (Result n_axZ5) (BorderMap DynBorder)
- Brick.Types: cursorLocationL :: forall n_awIU. Lens' (CursorLocation n_awIU) Location
+ Brick.Types: cursorLocationL :: forall n_awIW. Lens' (CursorLocation n_awIW) Location
- Brick.Types: cursorLocationNameL :: forall n_awIU n_ayB0. Lens (CursorLocation n_awIU) (CursorLocation n_ayB0) (Maybe n_awIU) (Maybe n_ayB0)
+ Brick.Types: cursorLocationNameL :: forall n_awIW n_ayCD. Lens (CursorLocation n_awIW) (CursorLocation n_ayCD) (Maybe n_awIW) (Maybe n_ayCD)
- Brick.Types: cursorsL :: forall n_axXs. Lens' (Result n_axXs) [CursorLocation n_axXs]
+ Brick.Types: cursorsL :: forall n_axZ5. Lens' (Result n_axZ5) [CursorLocation n_axZ5]
- Brick.Types: extentsL :: forall n_axXs. Lens' (Result n_axXs) [Extent n_axXs]
+ Brick.Types: extentsL :: forall n_axZ5. Lens' (Result n_axZ5) [Extent n_axZ5]
- Brick.Types: imageL :: forall n_axXs. Lens' (Result n_axXs) Image
+ Brick.Types: imageL :: forall n_axZ5. Lens' (Result n_axZ5) Image
- Brick.Types: visibilityRequestsL :: forall n_axXs. Lens' (Result n_axXs) [VisibilityRequest]
+ Brick.Types: visibilityRequestsL :: forall n_axZ5. Lens' (Result n_axZ5) [VisibilityRequest]
- Brick.Widgets.Dialog: dialogButtonsL :: forall a_a19Tc a_a19TQ. Lens (Dialog a_a19Tc) (Dialog a_a19TQ) [(String, a_a19Tc)] [(String, a_a19TQ)]
+ Brick.Widgets.Dialog: dialogButtonsL :: forall a_a1alG a_a1amk. Lens (Dialog a_a1alG) (Dialog a_a1amk) [(String, a_a1alG)] [(String, a_a1amk)]
- Brick.Widgets.Dialog: dialogSelectedIndexL :: forall a_a19Tc. Lens' (Dialog a_a19Tc) (Maybe Int)
+ Brick.Widgets.Dialog: dialogSelectedIndexL :: forall a_a1alG. Lens' (Dialog a_a1alG) (Maybe Int)
- Brick.Widgets.Dialog: dialogTitleL :: forall a_a19Tc. Lens' (Dialog a_a19Tc) (Maybe String)
+ Brick.Widgets.Dialog: dialogTitleL :: forall a_a1alG. Lens' (Dialog a_a1alG) (Maybe String)
- Brick.Widgets.Dialog: dialogWidthL :: forall a_a19Tc. Lens' (Dialog a_a19Tc) Int
+ Brick.Widgets.Dialog: dialogWidthL :: forall a_a1alG. Lens' (Dialog a_a1alG) Int
- Brick.Widgets.Edit: editContentsL :: forall t_a14oN n_a14oO t_a14ps. Lens (Editor t_a14oN n_a14oO) (Editor t_a14ps n_a14oO) (TextZipper t_a14oN) (TextZipper t_a14ps)
+ Brick.Widgets.Edit: editContentsL :: forall t_a14CC n_a14CD t_a14Dh. Lens (Editor t_a14CC n_a14CD) (Editor t_a14Dh n_a14CD) (TextZipper t_a14CC) (TextZipper t_a14Dh)
- Brick.Widgets.Edit: handleEditorEvent :: (DecodeUtf8 t, Eq t, Monoid t) => Event -> Editor t n -> EventM n (Editor t n)
+ Brick.Widgets.Edit: handleEditorEvent :: (DecodeUtf8 t, Eq t, GenericTextZipper t) => Event -> Editor t n -> EventM n (Editor t n)
- Brick.Widgets.FileBrowser: fileBrowserEntryFilterL :: forall n_a1k03. Lens' (FileBrowser n_a1k03) (Maybe (FileInfo -> Bool))
+ Brick.Widgets.FileBrowser: fileBrowserEntryFilterL :: forall n_a1kyM. Lens' (FileBrowser n_a1kyM) (Maybe (FileInfo -> Bool))
- Brick.Widgets.FileBrowser: fileBrowserSelectableL :: forall n_a1k03. Lens' (FileBrowser n_a1k03) (FileInfo -> Bool)
+ Brick.Widgets.FileBrowser: fileBrowserSelectableL :: forall n_a1kyM. Lens' (FileBrowser n_a1kyM) (FileInfo -> Bool)
- Brick.Widgets.List: listElementsL :: forall n_a1ePt t_a1ePu e_a1ePv t_a1f3A e_a1f3B. Lens (GenericList n_a1ePt t_a1ePu e_a1ePv) (GenericList n_a1ePt t_a1f3A e_a1f3B) (t_a1ePu e_a1ePv) (t_a1f3A e_a1f3B)
+ Brick.Widgets.List: listElementsL :: forall n_a1foc t_a1fod e_a1foe t_a1fCj e_a1fCk. Lens (GenericList n_a1foc t_a1fod e_a1foe) (GenericList n_a1foc t_a1fCj e_a1fCk) (t_a1fod e_a1foe) (t_a1fCj e_a1fCk)
- Brick.Widgets.List: listItemHeightL :: forall n_a1ePt t_a1ePu e_a1ePv. Lens' (GenericList n_a1ePt t_a1ePu e_a1ePv) Int
+ Brick.Widgets.List: listItemHeightL :: forall n_a1foc t_a1fod e_a1foe. Lens' (GenericList n_a1foc t_a1fod e_a1foe) Int
- Brick.Widgets.List: listNameL :: forall n_a1ePt t_a1ePu e_a1ePv n_a1f3C. Lens (GenericList n_a1ePt t_a1ePu e_a1ePv) (GenericList n_a1f3C t_a1ePu e_a1ePv) n_a1ePt n_a1f3C
+ Brick.Widgets.List: listNameL :: forall n_a1foc t_a1fod e_a1foe n_a1fCl. Lens (GenericList n_a1foc t_a1fod e_a1foe) (GenericList n_a1fCl t_a1fod e_a1foe) n_a1foc n_a1fCl
- Brick.Widgets.List: listSelectedL :: forall n_a1ePt t_a1ePu e_a1ePv. Lens' (GenericList n_a1ePt t_a1ePu e_a1ePv) (Maybe Int)
+ Brick.Widgets.List: listSelectedL :: forall n_a1foc t_a1fod e_a1foe. Lens' (GenericList n_a1foc t_a1fod e_a1foe) (Maybe Int)

Files

CHANGELOG.md view
@@ -2,6 +2,28 @@ Brick changelog --------------- +0.64+----++API changes:+ * Added `Brick.Main.continueWithoutRedraw`, an alternative to+   `Brick.Main.continue` that does not trigger a screen redraw. See the+   Haddock and User Guide for details.+ * Added `Brick.Widgets.Core.putCursor` to support Vty's new (as of+   5.33) API for placing cursors without visually representing+   them. This change also updated `Brick.Forms.renderCheckbox` and+   `Brick.Forms.renderRadio` to use `putCursor`.++Other improvements:+ * `Brick.Widgets.Edit` now supports a few more Emacs-style keybindings+   (thanks Mario Lang):+    * `M-b` and `M-f` to navigate by word+    * `C-b` and `C-f` for consistency+    * `M-d` to delete word under cursor+    * `C-t` to transpose previous character with current character+    * `M-<` and `M->` to goto-beginning-of-file and end of file,+      respectively+ 0.63 ---- @@ -501,14 +523,14 @@  * The Forms API got two new functions, `setFormConcat` and    `setFieldConcat`, used for controlling the previously hard-coded    concatenation behavior of form fields. These are optional and both-   concatentation settings default to their former hard-coded values,+   concatenation settings default to their former hard-coded values,    `vBox` (#172).  0.36.1 ------  Package changes:- * Raiseed upper bound to support GHC 8.4.2 (#171)+ * Raised upper bound to support GHC 8.4.2 (#171)  Other changes:  * Improved List accessor documentation (thanks liam <liam@magicseaweed.com>)@@ -522,7 +544,7 @@  * Dynamic border support: adjacent widgets that use borders can make    those borders seamlessly connect to each other! Thanks    so much to Daniel Wagner for this feature! Please see-   `programs/DynamicBorderDemo.hs` for a demonstraton. Also see the+   `programs/DynamicBorderDemo.hs` for a demonstration. Also see the    "Joinable Borders" section of the User Guide.  0.35.1
README.md view
@@ -76,6 +76,8 @@ | [`pboy`](https://github.com/2mol/pboy) | A tiny PDF organizer | | [`hyahtzee2`](https://github.com/DamienCassou/hyahtzee2#readme) | Famous Yahtzee dice game | | [`brewsage`](https://github.com/gerdreiss/brewsage#readme) | A TUI for Homebrew |+| [`sandwich`](https://codedownio.github.io/sandwich/) | A test framework with a TUI interface |+| [`youbrick`](https://github.com/florentc/youbrick) | A feed aggregator and launcher for Youtube channels |  These third-party packages also extend `brick`: 
brick.cabal view
@@ -1,5 +1,5 @@ name:                brick-version:             0.63+version:             0.64 synopsis:            A declarative terminal user interface library description:   Write terminal user interfaces (TUIs) painlessly with 'brick'! You@@ -115,7 +115,7 @@     Brick.Widgets.Internal    build-depends:       base < 4.16.0.0,-                       vty >= 5.31,+                       vty >= 5.33,                        transformers,                        data-clist >= 0.1,                        directory >= 1.2.5.0,@@ -131,7 +131,7 @@                        contravariant,                        stm >= 2.4.3,                        text,-                       text-zipper >= 0.7.1,+                       text-zipper >= 0.11,                        template-haskell,                        deepseq >= 1.3 && < 1.5,                        unix,
docs/guide.rst view
@@ -221,11 +221,18 @@ the corresponding types in ``App`` and ``EventM``.  The return value type ``Next s`` value describes what should happen-after the event handler is finished. We have three choices:+after the event handler is finished. We have four choices:  * ``Brick.Main.continue s``: continue executing the event loop with the   specified application state ``s`` as the next value. Commonly this is   where you'd modify the state based on the event and return it.+* ``Brick.Main.continueWithoutRedraw s``: continue executing the event+  loop with the specified application state ``s`` as the next value, but+  unlike ``continue``, do not redraw the screen using the new state.+  This is a faster version of ``continue`` since it doesn't redraw the+  screen; it just leaves up the previous screen contents. This function+  is only useful when you know that your state change won't cause+  anything on the screen to change. When in doubt, use ``continue``. * ``Brick.Main.halt s``: halt the event loop and return the final   application state value ``s``. This state value is returned to the   caller of ``defaultMain`` or ``customMain`` where it can be used prior@@ -533,7 +540,7 @@ appAttrMap: Managing Attributes ------------------------------- -In ``brick`` we use an *attribute map* to assign attibutes to elements+In ``brick`` we use an *attribute map* to assign attributes to elements of the interface. Rather than specifying specific attributes when drawing a widget (e.g. red-on-black text) we specify an *attribute name* that is an abstract name for the kind of thing we are drawing, e.g.@@ -784,7 +791,7 @@ follows:  * The application provides a default theme built in to the program.-* The application customizes the them by loading theme customizations+* The application customizes the theme by loading theme customizations   from a user-specified customization file. * The application can save new customizations to files for later   re-loading.@@ -934,12 +941,12 @@      mExtent <- Brick.Main.lookupExtent FooBox      case mExtent of        Nothing -> ...-       Just (Extent _ upperLeft (width, height) offset) -> ...+       Just (Extent _ upperLeft (width, height)) -> ...  Paste Support ============= -Some terminal emulators support "bracketed paste" support. This feature+Some terminal emulators support "bracketed paste" mode. This feature enables OS-level paste operations to send the pasted content as a single chunk of data and bypass the usual input processing that the application does. This enables more secure handling of pasted data since@@ -1352,7 +1359,7 @@ to initialize all of the form fields. Each form field will use the lens provided to extract the initial value from the ``UserInfo`` record, convert it into an appropriate state type for the field in question, and-later validate that state and convert it back into the approprate type+later validate that state and convert it back into the appropriate type for storage in ``UserInfo``.  The form value itself -- of type ``Form`` -- must be stored in your
programs/ReadmeDemo.hs view
@@ -1,9 +1,9 @@ module Main where -import Brick-import Brick.Widgets.Center-import Brick.Widgets.Border-import Brick.Widgets.Border.Style+import Brick (Widget, simpleMain, (<+>), str, withBorderStyle)+import Brick.Widgets.Center (center)+import Brick.Widgets.Border (borderWithLabel, vBorder)+import Brick.Widgets.Border.Style (unicode)  ui :: Widget () ui =
src/Brick/AttrMap.hs view
@@ -17,7 +17,7 @@ -- Attribute names are mapped to attributes, but some attributes may -- be partial (specify only a foreground or background color). When -- attribute name lookups occur, the attribute corresponding to a more--- specific name ('parent <> child' as above) is sucessively merged with+-- specific name ('parent <> child' as above) is successively merged with -- the parent attribute ('parent' as above) all the way to the "root" -- of the attribute map, the map's default attribute. In this way, more -- specific attributes inherit what they don't specify from more general
src/Brick/Focus.hs view
@@ -60,7 +60,7 @@               -> (Bool -> a -> b)               -- ^ A function that takes a value and its focus state.               -> a-              -- ^ The wiget state value that we need to check for focus.+              -- ^ The widget state value that we need to check for focus.               -> b               -- ^ The rest of the computation. withFocusRing ring f a = f (focusGetCurrent ring == Just (getName a)) a
src/Brick/Forms.hs view
@@ -124,12 +124,12 @@               -- ^ A validation function converting this field's state               -- into a value of your choosing. @Nothing@ indicates a               -- validation failure. For example, this might validate-              -- an 'Editor' state value by parsing its text contents s-              -- aan integer and return 'Maybe' 'Int'. This is for pure-              -- avalue validation; if additional validation is required-              -- a(e.g. via 'IO'), use this field's state value in an-              -- aexternal validation routine and use 'setFieldValid' to-              -- afeed the result back into the form.+              -- an 'Editor' state value by parsing its text contents as+              -- an integer and return 'Maybe' 'Int'. This is for pure+              -- value validation; if additional validation is required+              -- (e.g. via 'IO'), use this field's state value in an+              -- external validation routine and use 'setFieldValid' to+              -- feed the result back into the form.               , formFieldExternallyValid :: Bool               -- ^ Whether the field is valid according to an external               -- validation source. Defaults to always being 'True' and@@ -349,7 +349,7 @@ renderCheckbox :: Char -> Char -> Char -> T.Text -> n -> Bool -> Bool -> Widget n renderCheckbox lb check rb label n foc val =     let addAttr = if foc then withDefAttr focusedFormInputAttr else id-        csr = if foc then showCursor n (Location (1,0)) else id+        csr = if foc then putCursor n (Location (1,0)) else id     in clickable n $        addAttr $ csr $        (txt $ T.singleton lb <> (if val then T.singleton check else " ") <>@@ -478,7 +478,7 @@                   then withDefAttr focusedFormInputAttr                   else id         isSet = val == cur-        csr = if foc then showCursor name (Location (1,0)) else id+        csr = if foc then putCursor name (Location (1,0)) else id     in clickable name $        addAttr $ csr $        hBox [ txt $ T.singleton lb
src/Brick/Main.hs view
@@ -10,6 +10,7 @@    -- * Event handler functions   , continue+  , continueWithoutRedraw   , halt   , suspendAndResume   , lookupViewport@@ -114,7 +115,8 @@         -- ^ This function takes the current application state and an         -- event and returns an action to be taken and a corresponding         -- transformed application state. Possible options are-        -- 'continue', 'suspendAndResume', and 'halt'.+        -- 'continue', 'continueWithoutRedraw', 'suspendAndResume', and+        -- 'halt'.         , appStartEvent :: s -> EventM n s         -- ^ This function gets called once just prior to the first         -- drawing of your application. Here is where you can make@@ -191,8 +193,8 @@     let readEvent = case mUserChan of           Nothing -> readBChan brickChan           Just uc -> readBrickEvent brickChan uc-        runInner rs st = do-          (result, newRS) <- runVty vty readEvent app st (resetRenderState rs)+        runInner rs es draw st = do+          (result, newRS, newExtents) <- runVty vty readEvent app st (resetRenderState rs) es draw           case result of               SuspendAndResume act -> do                   killThread pid@@ -200,8 +202,10 @@               Halt s -> do                   killThread pid                   return $ InternalHalt s-              Continue s -> runInner newRS s-    runInner initialRS initialSt+              Continue s -> runInner newRS newExtents True s+              ContinueWithoutRedraw s ->+                  runInner newRS newExtents False s+    runInner initialRS mempty True initialSt  -- | The custom event loop entry point to use when the simpler ones -- don't permit enough control. Returns the final application state@@ -293,9 +297,14 @@        -> App s e n        -> s        -> RenderState n-       -> IO (Next s, RenderState n)-runVty vty readEvent app appState rs = do-    (firstRS, exts) <- renderApp vty app appState rs+       -> [Extent n]+       -> Bool+       -> IO (Next s, RenderState n, [Extent n])+runVty vty readEvent app appState rs prevExtents draw = do+    (firstRS, exts) <- case draw of+        True -> renderApp vty app appState rs+        False -> return (rs, prevExtents)+     e <- readEvent      (e', nextRS, nextExts) <- case e of@@ -361,10 +370,13 @@      (next, eState) <- runStateT (runReaderT (runEventM (appHandleEvent app appState e'))                                 eventRO) emptyES-    return (next, nextRS { rsScrollRequests = esScrollRequests eState-                         , renderCache = applyInvalidations (cacheInvalidateRequests eState) $-                                         renderCache nextRS-                         })+    return ( next+           , nextRS { rsScrollRequests = esScrollRequests eState+                    , renderCache = applyInvalidations (cacheInvalidateRequests eState) $+                                    renderCache nextRS+                    }+           , nextExts+           )  applyInvalidations :: (Ord n) => S.Set (CacheInvalidateRequest n) -> M.Map n v -> M.Map n v applyInvalidations ns cache =@@ -441,8 +453,11 @@                                         rs         picWithCursor = case theCursor of             Nothing -> pic { picCursor = NoCursor }-            Just cloc -> pic { picCursor = AbsoluteCursor (cloc^.locationColumnL)-                                                          (cloc^.locationRowL)+            Just cloc -> pic { picCursor = (if cursorLocationVisible cloc+                                            then AbsoluteCursor+                                            else PositionOnly True)+                                           (cloc^.locationColumnL)+                                           (cloc^.locationRowL)                              }      update vty picWithCursor@@ -529,6 +544,17 @@ -- state. continue :: s -> EventM n (Next s) continue = return . Continue++-- | Continue running the event loop with the specified application+-- state without redrawing the screen. This is faster than 'continue'+-- because it skips the redraw, but the drawback is that you need to+-- be really sure that you don't want a screen redraw. If your state+-- changed in a way that needs to be reflected on the screen, use+-- 'continue'. This function is for cases where you know that you did+-- something that won't have an impact on the screen state and you want+-- to save on redraw cost.+continueWithoutRedraw :: s -> EventM n (Next s)+continueWithoutRedraw = return . ContinueWithoutRedraw  -- | Halt the event loop and return the specified application state as -- the final state value.
src/Brick/Types/Internal.hs view
@@ -19,6 +19,7 @@   , CursorLocation(..)   , cursorLocationL   , cursorLocationNameL+  , cursorLocationVisibleL   , Context(..)   , EventState(..)   , EventRO(..)@@ -131,6 +132,7 @@  -- | The type of actions to take upon completion of an event handler. data Next a = Continue a+            | ContinueWithoutRedraw a             | SuspendAndResume (IO a)             | Halt a             deriving Functor@@ -164,6 +166,8 @@                    -- ^ The location                    , cursorLocationName :: !(Maybe n)                    -- ^ The name of the widget associated with the location+                   , cursorLocationVisible :: !Bool+                   -- ^ Whether the cursor should actually be visible                    }                    deriving (Read, Show, Generic, NFData) 
src/Brick/Widgets/Core.hs view
@@ -59,6 +59,7 @@    -- * Cursor placement   , showCursor+  , putCursor    -- * Naming   , Named(..)@@ -152,12 +153,14 @@ -- | When rendering the specified widget, use the specified border style -- for any border rendering. withBorderStyle :: BorderStyle -> Widget n -> Widget n-withBorderStyle bs p = Widget (hSize p) (vSize p) $ withReaderT (& ctxBorderStyleL .~ bs) (render p)+withBorderStyle bs p = Widget (hSize p) (vSize p) $+    withReaderT (ctxBorderStyleL .~ bs) (render p)  -- | When rendering the specified widget, create borders that respond -- dynamically to their neighbors to form seamless connections. joinBorders :: Widget n -> Widget n-joinBorders p = Widget (hSize p) (vSize p) $ withReaderT (& ctxDynBordersL .~ True) (render p)+joinBorders p = Widget (hSize p) (vSize p) $+    withReaderT (ctxDynBordersL .~ True) (render p)  -- | When rendering the specified widget, use static borders. This -- may be marginally faster, but will introduce a small gap between@@ -165,7 +168,8 @@ -- -- This is the default for backwards compatibility. separateBorders :: Widget n -> Widget n-separateBorders p = Widget (hSize p) (vSize p) $ withReaderT (&ctxDynBordersL .~ False) (render p)+separateBorders p = Widget (hSize p) (vSize p) $+    withReaderT (ctxDynBordersL .~ False) (render p)  -- | After the specified widget has been rendered, freeze its borders. A -- frozen border will not be affected by neighbors, nor will it affect@@ -339,7 +343,7 @@     Widget (hSize p) (vSize p) $ do         c <- getContext         let attr = attrMapLookup (c^.ctxAttrNameL) (c^.ctxAttrMapL) `V.withURL` url-        withReaderT (& ctxAttrMapL %~ setDefaultAttr attr) (render p)+        withReaderT (ctxAttrMapL %~ setDefaultAttr attr) (render p)  -- | Pad the specified widget on the left. If max padding is used, this -- grows greedily horizontally; otherwise it defers to the padded@@ -690,7 +694,7 @@ -- | Given borders that should be placed next to each other (the first argument -- on the right or bottom, and the second argument on the left or top), compute -- new borders and the rewrites that should be done along the edges of the two--- images to keep the image in synch with the border information.+-- images to keep the image in sync with the border information. -- -- The input borders are assumed to be disjoint. This property is not checked. catBorders@@ -836,17 +840,16 @@ withAttr :: AttrName -> Widget n -> Widget n withAttr an p =     Widget (hSize p) (vSize p) $-      withReaderT (& ctxAttrNameL .~ an) (render p)+      withReaderT (ctxAttrNameL .~ an) (render p)  -- | Update the attribute map while rendering the specified widget: set--- its new default attribute to the one that we get by looking up the--- specified attribute name in the map and then modifying it with the--- specified function.+-- its new default attribute to the one that we get by applying specified+-- function to the current default attribute. modifyDefAttr :: (V.Attr -> V.Attr) -> Widget n -> Widget n modifyDefAttr f p =     Widget (hSize p) (vSize p) $ do         c <- getContext-        withReaderT (& ctxAttrMapL %~ (setDefaultAttr (f $ getDefaultAttr (c^.ctxAttrMapL)))) (render p)+        withReaderT (ctxAttrMapL %~ (setDefaultAttr (f $ getDefaultAttr (c^.ctxAttrMapL)))) (render p)  -- | Update the attribute map while rendering the specified widget: set -- its new default attribute to the one that we get by looking up the@@ -855,14 +858,14 @@ withDefAttr an p =     Widget (hSize p) (vSize p) $ do         c <- getContext-        withReaderT (& ctxAttrMapL %~ (setDefaultAttr (attrMapLookup an (c^.ctxAttrMapL)))) (render p)+        withReaderT (ctxAttrMapL %~ (setDefaultAttr (attrMapLookup an (c^.ctxAttrMapL)))) (render p)  -- | When rendering the specified widget, update the attribute map with -- the specified transformation. updateAttrMap :: (AttrMap -> AttrMap) -> Widget n -> Widget n updateAttrMap f p =     Widget (hSize p) (vSize p) $-        withReaderT (& ctxAttrMapL %~ f) (render p)+        withReaderT (ctxAttrMapL %~ f) (render p)  -- | When rendering the specified widget, force all attribute lookups -- in the attribute map to use the value currently assigned to the@@ -876,7 +879,7 @@ forceAttr an p =     Widget (hSize p) (vSize p) $ do         c <- getContext-        withReaderT (& ctxAttrMapL .~ (forceAttrMap (attrMapLookup an (c^.ctxAttrMapL)))) (render p)+        withReaderT (ctxAttrMapL .~ (forceAttrMap (attrMapLookup an (c^.ctxAttrMapL)))) (render p)  -- | Override the lookup of 'targetName' to return the attribute value -- associated with 'fromName' when rendering the specified widget.@@ -991,32 +994,37 @@ -- | When rendering the specified widget, also register a cursor -- positioning request using the specified name and location. showCursor :: n -> Location -> Widget n -> Widget n-showCursor n cloc p =-    Widget (hSize p) (vSize p) $ do-      result <- render p-      return $ result & cursorsL %~ (CursorLocation cloc (Just n):)+showCursor n cloc p = Widget (hSize p) (vSize p) $+    (cursorsL %~ (CursorLocation cloc (Just n) True:)) <$> (render p) +-- | When rendering the specified widget, also register a cursor+-- positioning request using the specified name and location.+-- The cursor will only be positioned but not made visible.+putCursor :: n -> Location -> Widget n -> Widget n+putCursor n cloc p = Widget (hSize p) (vSize p) $+    (cursorsL %~ (CursorLocation cloc (Just n) False:)) <$> (render p)+ hRelease :: Widget n -> Maybe (Widget n) hRelease p =     case hSize p of         Fixed -> Just $ Widget Greedy (vSize p) $-                        withReaderT (& availWidthL .~ unrestricted) (render p)+                        withReaderT (availWidthL .~ unrestricted) (render p)         Greedy -> Nothing  vRelease :: Widget n -> Maybe (Widget n) vRelease p =     case vSize p of         Fixed -> Just $ Widget (hSize p) Greedy $-                        withReaderT (& availHeightL .~ unrestricted) (render p)+                        withReaderT (availHeightL .~ unrestricted) (render p)         Greedy -> Nothing  -- | If the specified resource name has an entry in the rendering cache, -- use the rendered version from the cache. If not, render the specified -- widget and update the cache with the result. ----- To ensure that mouse events are emitted correctly for cached widgets, --- in addition to the rendered widget, we also cache (the names of) --- any clickable extents that were rendered and restore that when utilizing+-- To ensure that mouse events are emitted correctly for cached widgets,+-- in addition to the rendered widget, we also cache (the names of) any+-- clickable extents that were rendered and restore that when utilizing -- the cache. -- -- See also 'invalidateCacheEntry'.@@ -1047,8 +1055,8 @@     cache <- lift $ gets (^.renderCacheL)     return $ M.lookup n cache -cacheUpdate :: (Ord n) => n -> ([n], Result n) -> RenderM n ()-cacheUpdate n r = lift $ modify (& renderCacheL %~ M.insert n r)+cacheUpdate :: Ord n => n -> ([n], Result n) -> RenderM n ()+cacheUpdate n r = lift $ modify (renderCacheL %~ M.insert n r)  -- | Render the specified widget in a named viewport with the -- specified type. This permits widgets to be scrolled without being@@ -1107,7 +1115,7 @@           doInsert (Just vp) = Just $ vp & vpSize .~ newSize           doInsert Nothing = Just newVp -      lift $ modify (& viewportMapL %~ (M.alter doInsert vpname))+      lift $ modify (viewportMapL %~ (M.alter doInsert vpname))        -- Then render the viewport content widget with the rendering       -- layout constraint released (but raise an exception if we are@@ -1148,7 +1156,7 @@                               Both -> scrollTo Horizontal rq (initialResult^.imageL) $                                       scrollTo Vertical rq (initialResult^.imageL) $                                       applyRequests rqs v-                  lift $ modify (& viewportMapL %~ (M.insert vpname updatedVp))+                  lift $ modify (viewportMapL %~ (M.insert vpname updatedVp))        -- If the sub-rendering requested visibility, update the scroll       -- state accordingly@@ -1162,7 +1170,7 @@                           Both -> scrollToView Horizontal rq $ scrollToView Vertical rq vp'                           Horizontal -> scrollToView typ rq vp'                           Vertical -> scrollToView typ rq vp'-                  lift $ modify (& viewportMapL %~ (M.insert vpname $ foldl updateVp vp rqs))+                  lift $ modify (viewportMapL %~ (M.insert vpname $ foldl updateVp vp rqs))        -- If the size of the rendering changes enough to make the       -- viewport offsets invalid, reset them@@ -1183,7 +1191,7 @@               Both -> fixLeft . fixTop               Horizontal -> fixLeft               Vertical -> fixTop-      lift $ modify (& viewportMapL %~ (M.insert vpname (updateVp vp)))+      lift $ modify (viewportMapL %~ (M.insert vpname (updateVp vp)))        -- Get the viewport state now that it has been updated.       mVpFinal <- lift $ gets (M.lookup vpname . (^.viewportMapL))
src/Brick/Widgets/Edit.hs view
@@ -52,6 +52,7 @@ import qualified Data.Text.Encoding as T import qualified Data.Text.Zipper as Z hiding ( textZipper ) import qualified Data.Text.Zipper.Generic as Z+import qualified Data.Text.Zipper.Generic.Words as Z  import Brick.Types import Brick.Widgets.Core@@ -59,12 +60,20 @@  -- | Editor state.  Editors support the following events by default: ----- * Ctrl-a: go to beginning of line--- * Ctrl-e: go to end of line+-- * Meta-<: go to beginning of file+-- * Meta->: go to end of file+-- * Ctrl-a, Home: go to beginning of line+-- * Ctrl-e, End: go to end of line -- * Ctrl-d, Del: delete character at cursor position+-- * Meta-d: delete word at cursor position -- * Backspace: delete character prior to cursor position -- * Ctrl-k: delete all from cursor to end of line -- * Ctrl-u: delete all from cursor to beginning of line+-- * Ctrl-t: transpose character before cursor with the one at cursor position+-- * Meta-b: move one word to the left+-- * Ctrl-b: move one character to the left+-- * Meta-f: move one word to the right+-- * Ctrl-f: move one character to the right -- * Arrow keys: move cursor -- * Enter: break the current line at the cursor position -- * Paste: Bracketed Pastes from the terminal will be pasted, provided@@ -105,7 +114,8 @@ instance DecodeUtf8 String where     decodeUtf8 bs = T.unpack <$> decodeUtf8 bs -handleEditorEvent :: (DecodeUtf8 t, Eq t, Monoid t) => Event -> Editor t n -> EventM n (Editor t n)+handleEditorEvent :: (DecodeUtf8 t, Eq t, Z.GenericTextZipper t)+                  => Event -> Editor t n -> EventM n (Editor t n) handleEditorEvent e ed =         let f = case e of                   EvPaste bs -> case decodeUtf8 bs of@@ -114,6 +124,7 @@                   EvKey (KChar 'a') [MCtrl] -> Z.gotoBOL                   EvKey (KChar 'e') [MCtrl] -> Z.gotoEOL                   EvKey (KChar 'd') [MCtrl] -> Z.deleteChar+                  EvKey (KChar 'd') [MMeta] -> Z.deleteWord                   EvKey (KChar 'k') [MCtrl] -> Z.killToEOL                   EvKey (KChar 'u') [MCtrl] -> Z.killToBOL                   EvKey KEnter [] -> Z.breakLine@@ -123,9 +134,16 @@                   EvKey KDown [] -> Z.moveDown                   EvKey KLeft [] -> Z.moveLeft                   EvKey KRight [] -> Z.moveRight+                  EvKey (KChar 'b') [MCtrl] -> Z.moveLeft+                  EvKey (KChar 'f') [MCtrl] -> Z.moveRight+                  EvKey (KChar 'b') [MMeta] -> Z.moveWordLeft+                  EvKey (KChar 'f') [MMeta] -> Z.moveWordRight                   EvKey KBS [] -> Z.deletePrevChar+                  EvKey (KChar 't') [MCtrl] -> Z.transposeChars                   EvKey KHome [] -> Z.gotoBOL                   EvKey KEnd [] -> Z.gotoEOL+                  EvKey (KChar '<') [MMeta] -> Z.gotoBOF+                  EvKey (KChar '>') [MMeta] -> Z.gotoEOF                   _ -> id         in return $ applyEdit f ed 
src/Brick/Widgets/FileBrowser.hs view
@@ -3,7 +3,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TupleSections #-}--- | This module provids a file browser widget that allows users to+-- | This module provides a file browser widget that allows users to -- navigate directory trees, search for files and directories, and -- select entries of interest. For a complete working demonstration of -- this module, see @programs/FileBrowserDemo.hs@.@@ -798,7 +798,7 @@         addAttr = maybe id (withDefAttr . attrForFileType) (fileInfoFileType info)         body = addAttr (hLimit (maxLen + 1) $                padRight Max $-               (if foc && listSel then showCursor n (Location (0,0)) else id) $+               (if foc && listSel then putCursor n (Location (0,0)) else id) $                str $ fileInfoSanitizedFilename info <> suffix)         suffix = (if fileInfoFileType info == Just Directory then "/" else "") <>                  (if sel then "*" else "")
src/Brick/Widgets/List.hs view
@@ -545,7 +545,7 @@ -- If @pos >= 0@, indexes from the start of the list (which gets -- evaluated up to the target index) ----- If @pos < 0@, indexes from the end of the list (which evalutes+-- If @pos < 0@, indexes from the end of the list (which evaluates -- 'length' of the list). -- -- Complexity: same as 'splitAt' for the container type.
src/Brick/Widgets/ProgressBar.hs view
@@ -10,7 +10,6 @@ where  import Lens.Micro ((^.))-import Data.List (splitAt) import Data.Maybe (fromMaybe) #if !(MIN_VERSION_base(4,11,0)) import Data.Monoid
tests/List.hs view
@@ -353,7 +353,7 @@  -- Laziness tests.  Here we create a custom container type -- that we use to ensure certain operations do not cause the--- whole container to be evaulated.+-- whole container to be evaluated. -- newtype L a = L [a]   deriving (Functor, Foldable, Traversable)