packages feed

brick 0.57.1 → 0.58

raw patch · 7 files changed

+147/−48 lines, 7 filesdep ~basePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base

API changes (from Hackage documentation)

+ Brick.Widgets.FileBrowser: actionFileBrowserBeginSearch :: FileBrowser n -> EventM n (FileBrowser n)
+ Brick.Widgets.FileBrowser: actionFileBrowserListBottom :: Ord n => FileBrowser n -> EventM n (FileBrowser n)
+ Brick.Widgets.FileBrowser: actionFileBrowserListHalfPageDown :: Ord n => FileBrowser n -> EventM n (FileBrowser n)
+ Brick.Widgets.FileBrowser: actionFileBrowserListHalfPageUp :: Ord n => FileBrowser n -> EventM n (FileBrowser n)
+ Brick.Widgets.FileBrowser: actionFileBrowserListNext :: Ord n => FileBrowser n -> EventM n (FileBrowser n)
+ Brick.Widgets.FileBrowser: actionFileBrowserListPageDown :: Ord n => FileBrowser n -> EventM n (FileBrowser n)
+ Brick.Widgets.FileBrowser: actionFileBrowserListPageUp :: Ord n => FileBrowser n -> EventM n (FileBrowser n)
+ Brick.Widgets.FileBrowser: actionFileBrowserListPrev :: Ord n => FileBrowser n -> EventM n (FileBrowser n)
+ Brick.Widgets.FileBrowser: actionFileBrowserListTop :: Ord n => FileBrowser n -> EventM n (FileBrowser n)
+ Brick.Widgets.FileBrowser: actionFileBrowserSelectCurrent :: FileBrowser n -> EventM n (FileBrowser n)
+ Brick.Widgets.FileBrowser: actionFileBrowserSelectEnter :: FileBrowser n -> EventM n (FileBrowser n)
- Brick.BorderMap: eBottomL :: forall a_acT2. Lens' (Edges a_acT2) a_acT2
+ Brick.BorderMap: eBottomL :: forall a_acT6. Lens' (Edges a_acT6) a_acT6
- Brick.BorderMap: eLeftL :: forall a_acT2. Lens' (Edges a_acT2) a_acT2
+ Brick.BorderMap: eLeftL :: forall a_acT6. Lens' (Edges a_acT6) a_acT6
- Brick.BorderMap: eRightL :: forall a_acT2. Lens' (Edges a_acT2) a_acT2
+ Brick.BorderMap: eRightL :: forall a_acT6. Lens' (Edges a_acT6) a_acT6
- Brick.BorderMap: eTopL :: forall a_acT2. Lens' (Edges a_acT2) a_acT2
+ Brick.BorderMap: eTopL :: forall a_acT6. Lens' (Edges a_acT6) a_acT6
- Brick.Types: bordersL :: forall n_axYn. Lens' (Result n_axYn) (BorderMap DynBorder)
+ Brick.Types: bordersL :: forall n_axYr. Lens' (Result n_axYr) (BorderMap DynBorder)
- Brick.Types: cursorLocationL :: forall n_awJM. Lens' (CursorLocation n_awJM) Location
+ Brick.Types: cursorLocationL :: forall n_awJQ. Lens' (CursorLocation n_awJQ) Location
- Brick.Types: cursorLocationNameL :: forall n_awJM n_ayBL. Lens (CursorLocation n_awJM) (CursorLocation n_ayBL) (Maybe n_awJM) (Maybe n_ayBL)
+ Brick.Types: cursorLocationNameL :: forall n_awJQ n_ayBP. Lens (CursorLocation n_awJQ) (CursorLocation n_ayBP) (Maybe n_awJQ) (Maybe n_ayBP)
- Brick.Types: cursorsL :: forall n_axYn. Lens' (Result n_axYn) [CursorLocation n_axYn]
+ Brick.Types: cursorsL :: forall n_axYr. Lens' (Result n_axYr) [CursorLocation n_axYr]
- Brick.Types: eBottomL :: forall a_acT2. Lens' (Edges a_acT2) a_acT2
+ Brick.Types: eBottomL :: forall a_acT6. Lens' (Edges a_acT6) a_acT6
- Brick.Types: eLeftL :: forall a_acT2. Lens' (Edges a_acT2) a_acT2
+ Brick.Types: eLeftL :: forall a_acT6. Lens' (Edges a_acT6) a_acT6
- Brick.Types: eRightL :: forall a_acT2. Lens' (Edges a_acT2) a_acT2
+ Brick.Types: eRightL :: forall a_acT6. Lens' (Edges a_acT6) a_acT6
- Brick.Types: eTopL :: forall a_acT2. Lens' (Edges a_acT2) a_acT2
+ Brick.Types: eTopL :: forall a_acT6. Lens' (Edges a_acT6) a_acT6
- Brick.Types: extentsL :: forall n_axYn. Lens' (Result n_axYn) [Extent n_axYn]
+ Brick.Types: extentsL :: forall n_axYr. Lens' (Result n_axYr) [Extent n_axYr]
- Brick.Types: imageL :: forall n_axYn. Lens' (Result n_axYn) Image
+ Brick.Types: imageL :: forall n_axYr. Lens' (Result n_axYr) Image
- Brick.Types: visibilityRequestsL :: forall n_axYn. Lens' (Result n_axYn) [VisibilityRequest]
+ Brick.Types: visibilityRequestsL :: forall n_axYr. Lens' (Result n_axYr) [VisibilityRequest]
- Brick.Widgets.Dialog: dialogButtonsL :: forall a_a18wU a_a18xy. Lens (Dialog a_a18wU) (Dialog a_a18xy) [(String, a_a18wU)] [(String, a_a18xy)]
+ Brick.Widgets.Dialog: dialogButtonsL :: forall a_a18wY a_a18xC. Lens (Dialog a_a18wY) (Dialog a_a18xC) [(String, a_a18wY)] [(String, a_a18xC)]
- Brick.Widgets.Dialog: dialogSelectedIndexL :: forall a_a18wU. Lens' (Dialog a_a18wU) (Maybe Int)
+ Brick.Widgets.Dialog: dialogSelectedIndexL :: forall a_a18wY. Lens' (Dialog a_a18wY) (Maybe Int)
- Brick.Widgets.Dialog: dialogTitleL :: forall a_a18wU. Lens' (Dialog a_a18wU) (Maybe String)
+ Brick.Widgets.Dialog: dialogTitleL :: forall a_a18wY. Lens' (Dialog a_a18wY) (Maybe String)
- Brick.Widgets.Dialog: dialogWidthL :: forall a_a18wU. Lens' (Dialog a_a18wU) Int
+ Brick.Widgets.Dialog: dialogWidthL :: forall a_a18wY. Lens' (Dialog a_a18wY) Int
- Brick.Widgets.Edit: editContentsL :: forall t_a13sp n_a13sq t_a13t4. Lens (Editor t_a13sp n_a13sq) (Editor t_a13t4 n_a13sq) (TextZipper t_a13sp) (TextZipper t_a13t4)
+ Brick.Widgets.Edit: editContentsL :: forall t_a13st n_a13su t_a13t8. Lens (Editor t_a13st n_a13su) (Editor t_a13t8 n_a13su) (TextZipper t_a13st) (TextZipper t_a13t8)
- Brick.Widgets.FileBrowser: fileBrowserEntryFilterL :: forall n_a1iBu. Lens' (FileBrowser n_a1iBu) (Maybe (FileInfo -> Bool))
+ Brick.Widgets.FileBrowser: fileBrowserEntryFilterL :: forall n_a1iFp. Lens' (FileBrowser n_a1iFp) (Maybe (FileInfo -> Bool))
- Brick.Widgets.FileBrowser: fileBrowserSelectableL :: forall n_a1iBu. Lens' (FileBrowser n_a1iBu) (FileInfo -> Bool)
+ Brick.Widgets.FileBrowser: fileBrowserSelectableL :: forall n_a1iFp. Lens' (FileBrowser n_a1iFp) (FileInfo -> Bool)
- Brick.Widgets.List: listElementsL :: forall n_a1duY t_a1duZ e_a1dv0 t_a1dJC e_a1dJD. Lens (GenericList n_a1duY t_a1duZ e_a1dv0) (GenericList n_a1duY t_a1dJC e_a1dJD) (t_a1duZ e_a1dv0) (t_a1dJC e_a1dJD)
+ Brick.Widgets.List: listElementsL :: forall n_a1dv2 t_a1dv3 e_a1dv4 t_a1dJG e_a1dJH. Lens (GenericList n_a1dv2 t_a1dv3 e_a1dv4) (GenericList n_a1dv2 t_a1dJG e_a1dJH) (t_a1dv3 e_a1dv4) (t_a1dJG e_a1dJH)
- Brick.Widgets.List: listItemHeightL :: forall n_a1duY t_a1duZ e_a1dv0. Lens' (GenericList n_a1duY t_a1duZ e_a1dv0) Int
+ Brick.Widgets.List: listItemHeightL :: forall n_a1dv2 t_a1dv3 e_a1dv4. Lens' (GenericList n_a1dv2 t_a1dv3 e_a1dv4) Int
- Brick.Widgets.List: listNameL :: forall n_a1duY t_a1duZ e_a1dv0 n_a1dJE. Lens (GenericList n_a1duY t_a1duZ e_a1dv0) (GenericList n_a1dJE t_a1duZ e_a1dv0) n_a1duY n_a1dJE
+ Brick.Widgets.List: listNameL :: forall n_a1dv2 t_a1dv3 e_a1dv4 n_a1dJI. Lens (GenericList n_a1dv2 t_a1dv3 e_a1dv4) (GenericList n_a1dJI t_a1dv3 e_a1dv4) n_a1dv2 n_a1dJI
- Brick.Widgets.List: listSelectedL :: forall n_a1duY t_a1duZ e_a1dv0. Lens' (GenericList n_a1duY t_a1duZ e_a1dv0) (Maybe Int)
+ Brick.Widgets.List: listSelectedL :: forall n_a1dv2 t_a1dv3 e_a1dv4. Lens' (GenericList n_a1dv2 t_a1dv3 e_a1dv4) (Maybe Int)

Files

CHANGELOG.md view
@@ -2,6 +2,30 @@ Brick changelog --------------- +0.58+----++Package changes:+ * Updated dependency constraints to build on GHC 9.0.1 (thanks Ondřej+   Súkup)++API changes:+ * The FileBrowser module now exports individual functions for+   each of the events that it handles. This allows end users to+   trigger the behaviors directly rather than relying on the built-in+   `handleFileBrowserEvent` function. The documentation has been updated+   to indicate which functions are triggered by each key event. (Thanks+   David B. Lamkins)++Other changes:+ * The `List` module's `listFindBy` function now attempts to find a+   match anywhere in the list rather than just somewhere between the+   cursor and the end of the list.+ * The `FileBrowser` now positions a cursor at the beginning of the+   selected entry when the file browser is focused. (thanks Mario Lang)+ * The user guide's viewport visibility example got an important+   syntactic fix. (thanks Mario Lang)+ 0.57.1 ------ 
README.md view
@@ -67,6 +67,7 @@ | [`wrapping-editor`](https://github.com/ta0kira/wrapping-editor) | An embeddable editor with support for Brick | | [`git-brunch`](https://github.com/andys8/git-brunch) | A git branch checkout utility | | [`hascard`](https://github.com/Yvee1/hascard) | A program for reviewing "flash card" notes |+| [`ttyme`](https://github.com/evuez/ttyme) | A TUI for [Harvest](https://www.getharvest.com/) |  These third-party packages also extend `brick`: 
brick.cabal view
@@ -1,5 +1,5 @@ name:                brick-version:             0.57.1+version:             0.58 synopsis:            A declarative terminal user interface library description:   Write terminal user interfaces (TUIs) painlessly with 'brick'! You@@ -113,7 +113,7 @@     Brick.Types.Internal     Brick.Widgets.Internal -  build-depends:       base <= 4.14.1.0,+  build-depends:       base <= 4.15,                        vty >= 5.31,                        transformers,                        data-clist >= 0.1,
docs/guide.rst view
@@ -1205,7 +1205,7 @@    -- Assuming that App uses 'Name' for its resource names:    data Name = Viewport1    let w = viewport Viewport1 Horizontal $-           (visible $ str "Hello," <+> (str " world!")+           (visible $ str "Hello,") <+> (str " world!")  This example requests that the ``Viewport1`` viewport be scrolled so that "Hello," is visible. We could extend this example with a value
src/Brick/Widgets/Core.hs view
@@ -862,7 +862,12 @@  -- | When rendering the specified widget, force all attribute lookups -- in the attribute map to use the value currently assigned to the--- specified attribute name.+-- specified attribute name. This means that the attribute lookups will+-- behave as if they all used the name specified here. That further+-- means that the resolved attribute will still inherit from its parent+-- entry in the attribute map as would normally be the case. If you+-- want to have more control over the resulting attribute, consider+-- 'modifyDefAttr'. forceAttr :: AttrName -> Widget n -> Widget n forceAttr an p =     Widget (hSize p) (vSize p) $ do
src/Brick/Widgets/FileBrowser.hs view
@@ -65,6 +65,19 @@   , updateFileBrowserSearch   , setFileBrowserEntryFilter +  -- * Actions+  , actionFileBrowserBeginSearch+  , actionFileBrowserSelectEnter+  , actionFileBrowserSelectCurrent+  , actionFileBrowserListPageUp+  , actionFileBrowserListPageDown+  , actionFileBrowserListHalfPageUp+  , actionFileBrowserListHalfPageDown+  , actionFileBrowserListTop+  , actionFileBrowserListBottom+  , actionFileBrowserListNext+  , actionFileBrowserListPrev+   -- * Handling events   , handleFileBrowserEvent   , maybeSelectCurrentEntry@@ -540,21 +553,81 @@ -- -- Events handled regardless of mode: ----- * @Enter@, @Space@: set the file browser's selected entry---   ('fileBrowserSelection') for use by the calling application,---   subject to 'fileBrowserSelectable'.--- * @Ctrl-n@: select the next entry--- * @Ctrl-p@: select the previous entry--- * 'List' navigation keys+-- * @Ctrl-b@: 'actionFileBrowserListPageUp'+-- * @Ctrl-f@: 'actionFileBrowserListPageDown'+-- * @Ctrl-d@: 'actionFileBrowserListHalfPageDown'+-- * @Ctrl-u@: 'actionFileBrowserListHalfPageUp'+-- * @g@: 'actionFileBrowserListTop'+-- * @G@: 'actionFileBrowserListBottom'+-- * @j@: 'actionFileBrowserListNext'+-- * @k@: 'actionFileBrowserListPrev'+-- * @Ctrl-n@: 'actionFileBrowserListNext'+-- * @Ctrl-p@: 'actionFileBrowserListPrev' -- -- Events handled only in normal mode: ----- * @/@: enter search mode+-- * @/@: 'actionFileBrowserBeginSearch'+-- * @Enter@: 'actionFileBrowserSelectEnter'+-- * @Space@: 'actionFileBrowserSelectCurrent' -- -- Events handled only in search mode: -- -- * @Esc@, @Ctrl-C@: cancel search mode -- * Text input: update search string++actionFileBrowserBeginSearch :: FileBrowser n -> EventM n (FileBrowser n)+actionFileBrowserBeginSearch b =+    return $ updateFileBrowserSearch (const $ Just "") b++actionFileBrowserSelectEnter :: FileBrowser n -> EventM n (FileBrowser n)+actionFileBrowserSelectEnter b =+    maybeSelectCurrentEntry b++actionFileBrowserSelectCurrent :: FileBrowser n -> EventM n (FileBrowser n)+actionFileBrowserSelectCurrent b =+    selectCurrentEntry b++actionFileBrowserListPageUp :: Ord n => FileBrowser n -> EventM n (FileBrowser n)+actionFileBrowserListPageUp b = do+    let old = b ^. fileBrowserEntriesL+    new <- listMovePageUp old+    return $ b & fileBrowserEntriesL .~ new++actionFileBrowserListPageDown :: Ord n => FileBrowser n -> EventM n (FileBrowser n)+actionFileBrowserListPageDown b = do+    let old = b ^. fileBrowserEntriesL+    new <- listMovePageDown old+    return $ b & fileBrowserEntriesL .~ new++actionFileBrowserListHalfPageUp :: Ord n => FileBrowser n -> EventM n (FileBrowser n)+actionFileBrowserListHalfPageUp b = do+    let old = b ^. fileBrowserEntriesL+    new <- listMoveByPages (-0.5::Double) old+    return $ b & fileBrowserEntriesL .~ new++actionFileBrowserListHalfPageDown :: Ord n => FileBrowser n -> EventM n (FileBrowser n)+actionFileBrowserListHalfPageDown b = do+    let old = b ^. fileBrowserEntriesL+    new <- listMoveByPages (0.5::Double) old+    return $ b & fileBrowserEntriesL .~ new++actionFileBrowserListTop :: Ord n => FileBrowser n -> EventM n (FileBrowser n)+actionFileBrowserListTop b =+    return $ b & fileBrowserEntriesL %~ listMoveTo 0++actionFileBrowserListBottom :: Ord n => FileBrowser n -> EventM n (FileBrowser n)+actionFileBrowserListBottom b = do+    let sz = length (listElements $ b^.fileBrowserEntriesL)+    return $ b & fileBrowserEntriesL %~ listMoveTo (sz - 1)++actionFileBrowserListNext :: Ord n => FileBrowser n -> EventM n (FileBrowser n)+actionFileBrowserListNext b =+    return $ b & fileBrowserEntriesL %~ listMoveBy 1++actionFileBrowserListPrev :: Ord n => FileBrowser n -> EventM n (FileBrowser n)+actionFileBrowserListPrev b =+    return $ b & fileBrowserEntriesL %~ listMoveBy (-1)+ handleFileBrowserEvent :: (Ord n) => Vty.Event -> FileBrowser n -> EventM n (FileBrowser n) handleFileBrowserEvent e b =     if fileBrowserIsSearching b@@ -587,48 +660,39 @@     case e of         Vty.EvKey (Vty.KChar '/') [] ->             -- Begin file search-            return $ updateFileBrowserSearch (const $ Just "") b+            actionFileBrowserBeginSearch b         Vty.EvKey Vty.KEnter [] ->             -- Select file or enter directory-            maybeSelectCurrentEntry b+            actionFileBrowserSelectEnter b         Vty.EvKey (Vty.KChar ' ') [] ->             -- Select entry-            selectCurrentEntry b+            actionFileBrowserSelectCurrent b         _ ->             handleFileBrowserEventCommon e b  handleFileBrowserEventCommon :: (Ord n) => Vty.Event -> FileBrowser n -> EventM n (FileBrowser n) handleFileBrowserEventCommon e b =     case e of-        Vty.EvKey (Vty.KChar 'b') [Vty.MCtrl] -> do-            let old = b ^. fileBrowserEntriesL-            new <- listMovePageUp old-            return $ b & fileBrowserEntriesL .~ new-        Vty.EvKey (Vty.KChar 'f') [Vty.MCtrl] -> do-            let old = b ^. fileBrowserEntriesL-            new <- listMovePageDown old-            return $ b & fileBrowserEntriesL .~ new-        Vty.EvKey (Vty.KChar 'd') [Vty.MCtrl] -> do-            let old = b ^. fileBrowserEntriesL-            new <- listMoveByPages (0.5::Double) old-            return $ b & fileBrowserEntriesL .~ new-        Vty.EvKey (Vty.KChar 'u') [Vty.MCtrl] -> do-            let old = b ^. fileBrowserEntriesL-            new <- listMoveByPages (-0.5::Double) old-            return $ b & fileBrowserEntriesL .~ new+        Vty.EvKey (Vty.KChar 'b') [Vty.MCtrl] ->+            actionFileBrowserListPageUp b+        Vty.EvKey (Vty.KChar 'f') [Vty.MCtrl] ->+            actionFileBrowserListPageDown b+        Vty.EvKey (Vty.KChar 'd') [Vty.MCtrl] ->+            actionFileBrowserListHalfPageDown b+        Vty.EvKey (Vty.KChar 'u') [Vty.MCtrl] ->+            actionFileBrowserListHalfPageUp b         Vty.EvKey (Vty.KChar 'g') [] ->-            return $ b & fileBrowserEntriesL %~ listMoveTo 0-        Vty.EvKey (Vty.KChar 'G') [] -> do-            let sz = length (listElements $ b^.fileBrowserEntriesL)-            return $ b & fileBrowserEntriesL %~ listMoveTo (sz - 1)+            actionFileBrowserListTop b+        Vty.EvKey (Vty.KChar 'G') [] ->+            actionFileBrowserListBottom b         Vty.EvKey (Vty.KChar 'j') [] ->-            return $ b & fileBrowserEntriesL %~ listMoveBy 1+            actionFileBrowserListNext b         Vty.EvKey (Vty.KChar 'k') [] ->-            return $ b & fileBrowserEntriesL %~ listMoveBy (-1)+            actionFileBrowserListPrev b         Vty.EvKey (Vty.KChar 'n') [Vty.MCtrl] ->-            return $ b & fileBrowserEntriesL %~ listMoveBy 1+            actionFileBrowserListNext b         Vty.EvKey (Vty.KChar 'p') [Vty.MCtrl] ->-            return $ b & fileBrowserEntriesL %~ listMoveBy (-1)+            actionFileBrowserListPrev b         _ ->             handleEventLensed b fileBrowserEntriesL handleListEvent e @@ -715,14 +779,14 @@      in withDefAttr fileBrowserAttr $        vBox [ withDefAttr fileBrowserCurrentDirectoryAttr cwdHeader-            , renderList (renderFileInfo foc maxFilenameLength (b^.fileBrowserSelectedFilesL))+            , renderList (renderFileInfo foc maxFilenameLength (b^.fileBrowserSelectedFilesL) (b^.fileBrowserNameL))                          foc (b^.fileBrowserEntriesL)             , maybeSearchInfo             , withDefAttr fileBrowserSelectionInfoAttr selInfo             ] -renderFileInfo :: Bool -> Int -> Set.Set String -> Bool -> FileInfo -> Widget n-renderFileInfo foc maxLen selFiles listSel info =+renderFileInfo :: Bool -> Int -> Set.Set String -> n -> Bool -> FileInfo -> Widget n+renderFileInfo foc maxLen selFiles n listSel info =     (if foc      then (if listSel then forceAttr listSelectedFocusedAttr                else if sel then forceAttr fileBrowserSelectedAttr else id)@@ -734,6 +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) $                str $ fileInfoSanitizedFilename info <> suffix)         suffix = (if fileInfoFileType info == Just Directory then "/" else "") <>                  (if sel then "*" else "")
src/Brick/Widgets/List.hs view
@@ -75,6 +75,7 @@  import Prelude hiding (reverse, splitAt) +import Control.Applicative ((<|>)) #if !MIN_VERSION_base(4,8,0) import Control.Applicative ((<$>), (<*>), pure) import Data.Foldable (Foldable, find, toList)@@ -574,10 +575,11 @@                   -> GenericList n t e listMoveToElement e = listFindBy (== e) . set listSelectedL Nothing --- | Set the selected index to the next element matching the--- predicate.  If there is no selected element, the search starts at--- the beginning.  If no matching element is found, leave the list--- unmodified.+-- | Starting from the currently-selected position, attempt to find+-- and select the next element matching the predicate. If there are no+-- matches for the remainder of the list or if the list has no selection+-- at all, the search starts at the beginning. If no matching element is+-- found anywhere in the list, leave the list unmodified. -- -- /O(n)/.  Only evaluates as much of the container as needed. listFindBy :: (Foldable t, Splittable t)@@ -586,9 +588,11 @@            -> GenericList n t e listFindBy test l =     let start = maybe 0 (+1) (l ^. listSelectedL)-        (_, t) = splitAt start (l ^. listElementsL)-        result = find (test . snd) . zip [0..] . toList $ t-    in maybe id (set listSelectedL . Just . (start +) . fst) result l+        (h, t) = splitAt start (l ^. listElementsL)+        tailResult = find (test . snd) . zip [start..] . toList $ t+        headResult = find (test . snd) . zip [0..] . toList $ h+        result = tailResult <|> headResult+    in maybe id (set listSelectedL . Just . fst) result l  -- | Return a list's selected element, if any. --