brick 0.67 → 0.68
raw patch · 12 files changed
+210/−256 lines, 12 filesdep ~basedep ~microlensdep ~vtyPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base, microlens, vty
API changes (from Hackage documentation)
- Brick.Markup: (@?) :: Text -> AttrName -> Markup AttrName
- Brick.Markup: class GetAttr a
- Brick.Markup: data Markup a
- Brick.Markup: getAttr :: GetAttr a => a -> RenderM n Attr
- Brick.Markup: instance Brick.Markup.GetAttr Brick.AttrMap.AttrName
- Brick.Markup: instance Brick.Markup.GetAttr Graphics.Vty.Attributes.Attr
- Brick.Markup: markup :: (Eq a, GetAttr a) => Markup a -> Widget n
- Data.Text.Markup: (@@) :: Text -> a -> Markup a
- Data.Text.Markup: data Markup a
- Data.Text.Markup: fromList :: [(Text, a)] -> Markup a
- Data.Text.Markup: fromText :: Monoid a => Text -> Markup a
- Data.Text.Markup: instance GHC.Base.Monoid (Data.Text.Markup.Markup a)
- Data.Text.Markup: instance GHC.Base.Monoid a => Data.String.IsString (Data.Text.Markup.Markup a)
- Data.Text.Markup: instance GHC.Base.Semigroup (Data.Text.Markup.Markup a)
- Data.Text.Markup: instance GHC.Show.Show a => GHC.Show.Show (Data.Text.Markup.Markup a)
- Data.Text.Markup: isEmpty :: Markup a -> Bool
- Data.Text.Markup: markupSet :: Eq a => (Int, Int) -> a -> Markup a -> Markup a
- Data.Text.Markup: markupToList :: Eq a => Markup a -> [[(Text, a)]]
- Data.Text.Markup: toText :: Eq a => Markup a -> Text
- Brick.BorderMap: eBottomL :: forall a_acYZ. Lens' (Edges a_acYZ) a_acYZ
+ Brick.BorderMap: eBottomL :: forall a_acHl. Lens' (Edges a_acHl) a_acHl
- Brick.BorderMap: eLeftL :: forall a_acYZ. Lens' (Edges a_acYZ) a_acYZ
+ Brick.BorderMap: eLeftL :: forall a_acHl. Lens' (Edges a_acHl) a_acHl
- Brick.BorderMap: eRightL :: forall a_acYZ. Lens' (Edges a_acYZ) a_acYZ
+ Brick.BorderMap: eRightL :: forall a_acHl. Lens' (Edges a_acHl) a_acHl
- Brick.BorderMap: eTopL :: forall a_acYZ. Lens' (Edges a_acYZ) a_acYZ
+ Brick.BorderMap: eTopL :: forall a_acHl. Lens' (Edges a_acHl) a_acHl
- Brick.Types: availHeightL :: forall n_awOO. Lens' (Context n_awOO) Int
+ Brick.Types: availHeightL :: forall n_awxa. Lens' (Context n_awxa) Int
- Brick.Types: availWidthL :: forall n_awOO. Lens' (Context n_awOO) Int
+ Brick.Types: availWidthL :: forall n_awxa. Lens' (Context n_awxa) Int
- Brick.Types: bordersL :: forall n_awOS. Lens' (Result n_awOS) (BorderMap DynBorder)
+ Brick.Types: bordersL :: forall n_awxe. Lens' (Result n_awxe) (BorderMap DynBorder)
- Brick.Types: ctxAttrMapL :: forall n_awOO. Lens' (Context n_awOO) AttrMap
+ Brick.Types: ctxAttrMapL :: forall n_awxa. Lens' (Context n_awxa) AttrMap
- Brick.Types: ctxAttrNameL :: forall n_awOO. Lens' (Context n_awOO) AttrName
+ Brick.Types: ctxAttrNameL :: forall n_awxa. Lens' (Context n_awxa) AttrName
- Brick.Types: ctxBorderStyleL :: forall n_awOO. Lens' (Context n_awOO) BorderStyle
+ Brick.Types: ctxBorderStyleL :: forall n_awxa. Lens' (Context n_awxa) BorderStyle
- Brick.Types: ctxDynBordersL :: forall n_awOO. Lens' (Context n_awOO) Bool
+ Brick.Types: ctxDynBordersL :: forall n_awxa. Lens' (Context n_awxa) Bool
- Brick.Types: ctxHScrollBarOrientationL :: forall n_awOO. Lens' (Context n_awOO) (Maybe HScrollBarOrientation)
+ Brick.Types: ctxHScrollBarOrientationL :: forall n_awxa. Lens' (Context n_awxa) (Maybe HScrollBarOrientation)
- Brick.Types: ctxHScrollBarRendererL :: forall n_awOO. Lens' (Context n_awOO) (Maybe (ScrollbarRenderer n_awOO))
+ Brick.Types: ctxHScrollBarRendererL :: forall n_awxa. Lens' (Context n_awxa) (Maybe (ScrollbarRenderer n_awxa))
- Brick.Types: ctxVScrollBarOrientationL :: forall n_awOO. Lens' (Context n_awOO) (Maybe VScrollBarOrientation)
+ Brick.Types: ctxVScrollBarOrientationL :: forall n_awxa. Lens' (Context n_awxa) (Maybe VScrollBarOrientation)
- Brick.Types: ctxVScrollBarRendererL :: forall n_awOO. Lens' (Context n_awOO) (Maybe (ScrollbarRenderer n_awOO))
+ Brick.Types: ctxVScrollBarRendererL :: forall n_awxa. Lens' (Context n_awxa) (Maybe (ScrollbarRenderer n_awxa))
- Brick.Types: cursorLocationL :: forall n_awOT. Lens' (CursorLocation n_awOT) Location
+ Brick.Types: cursorLocationL :: forall n_awxf. Lens' (CursorLocation n_awxf) Location
- Brick.Types: cursorLocationNameL :: forall n_awOT n_ayWW. Lens (CursorLocation n_awOT) (CursorLocation n_ayWW) (Maybe n_awOT) (Maybe n_ayWW)
+ Brick.Types: cursorLocationNameL :: forall n_awxf n_ayFi. Lens (CursorLocation n_awxf) (CursorLocation n_ayFi) (Maybe n_awxf) (Maybe n_ayFi)
- Brick.Types: cursorsL :: forall n_awOS. Lens' (Result n_awOS) [CursorLocation n_awOS]
+ Brick.Types: cursorsL :: forall n_awxe. Lens' (Result n_awxe) [CursorLocation n_awxe]
- Brick.Types: eBottomL :: forall a_acYZ. Lens' (Edges a_acYZ) a_acYZ
+ Brick.Types: eBottomL :: forall a_acHl. Lens' (Edges a_acHl) a_acHl
- Brick.Types: eLeftL :: forall a_acYZ. Lens' (Edges a_acYZ) a_acYZ
+ Brick.Types: eLeftL :: forall a_acHl. Lens' (Edges a_acHl) a_acHl
- Brick.Types: eRightL :: forall a_acYZ. Lens' (Edges a_acYZ) a_acYZ
+ Brick.Types: eRightL :: forall a_acHl. Lens' (Edges a_acHl) a_acHl
- Brick.Types: eTopL :: forall a_acYZ. Lens' (Edges a_acYZ) a_acYZ
+ Brick.Types: eTopL :: forall a_acHl. Lens' (Edges a_acHl) a_acHl
- Brick.Types: extentsL :: forall n_awOS. Lens' (Result n_awOS) [Extent n_awOS]
+ Brick.Types: extentsL :: forall n_awxe. Lens' (Result n_awxe) [Extent n_awxe]
- Brick.Types: imageL :: forall n_awOS. Lens' (Result n_awOS) Image
+ Brick.Types: imageL :: forall n_awxe. Lens' (Result n_awxe) Image
- Brick.Types: visibilityRequestsL :: forall n_awOS. Lens' (Result n_awOS) [VisibilityRequest]
+ Brick.Types: visibilityRequestsL :: forall n_awxe. Lens' (Result n_awxe) [VisibilityRequest]
- Brick.Types: windowHeightL :: forall n_awOO. Lens' (Context n_awOO) Int
+ Brick.Types: windowHeightL :: forall n_awxa. Lens' (Context n_awxa) Int
- Brick.Types: windowWidthL :: forall n_awOO. Lens' (Context n_awOO) Int
+ Brick.Types: windowWidthL :: forall n_awxa. Lens' (Context n_awxa) Int
- Brick.Widgets.Dialog: dialogButtonsL :: forall a_a1f8F a_a1f9j. Lens (Dialog a_a1f8F) (Dialog a_a1f9j) [(String, a_a1f8F)] [(String, a_a1f9j)]
+ Brick.Widgets.Dialog: dialogButtonsL :: forall a_a1eOX a_a1ePB. Lens (Dialog a_a1eOX) (Dialog a_a1ePB) [(String, a_a1eOX)] [(String, a_a1ePB)]
- Brick.Widgets.Dialog: dialogSelectedIndexL :: forall a_a1f8F. Lens' (Dialog a_a1f8F) (Maybe Int)
+ Brick.Widgets.Dialog: dialogSelectedIndexL :: forall a_a1eOX. Lens' (Dialog a_a1eOX) (Maybe Int)
- Brick.Widgets.Dialog: dialogTitleL :: forall a_a1f8F. Lens' (Dialog a_a1f8F) (Maybe String)
+ Brick.Widgets.Dialog: dialogTitleL :: forall a_a1eOX. Lens' (Dialog a_a1eOX) (Maybe String)
- Brick.Widgets.Dialog: dialogWidthL :: forall a_a1f8F. Lens' (Dialog a_a1f8F) Int
+ Brick.Widgets.Dialog: dialogWidthL :: forall a_a1eOX. Lens' (Dialog a_a1eOX) Int
- Brick.Widgets.Edit: editContentsL :: forall t_a19pa n_a19pb t_a19pP. Lens (Editor t_a19pa n_a19pb) (Editor t_a19pP n_a19pb) (TextZipper t_a19pa) (TextZipper t_a19pP)
+ Brick.Widgets.Edit: editContentsL :: forall t_a195u n_a195v t_a1969. Lens (Editor t_a195u n_a195v) (Editor t_a1969 n_a195v) (TextZipper t_a195u) (TextZipper t_a1969)
- Brick.Widgets.FileBrowser: fileBrowserEntriesG :: forall n_a1pvT. SimpleGetter (FileBrowser n_a1pvT) (List n_a1pvT FileInfo)
+ Brick.Widgets.FileBrowser: fileBrowserEntriesG :: forall n_a1p9v. SimpleGetter (FileBrowser n_a1p9v) (List n_a1p9v FileInfo)
- Brick.Widgets.FileBrowser: fileBrowserEntryFilterG :: forall n_a1pvT. SimpleGetter (FileBrowser n_a1pvT) (Maybe (FileInfo -> Bool))
+ Brick.Widgets.FileBrowser: fileBrowserEntryFilterG :: forall n_a1p9v. SimpleGetter (FileBrowser n_a1p9v) (Maybe (FileInfo -> Bool))
- Brick.Widgets.FileBrowser: fileBrowserExceptionG :: forall n_a1pvT. SimpleGetter (FileBrowser n_a1pvT) (Maybe IOException)
+ Brick.Widgets.FileBrowser: fileBrowserExceptionG :: forall n_a1p9v. SimpleGetter (FileBrowser n_a1p9v) (Maybe IOException)
- Brick.Widgets.FileBrowser: fileBrowserLatestResultsG :: forall n_a1pvT. SimpleGetter (FileBrowser n_a1pvT) [FileInfo]
+ Brick.Widgets.FileBrowser: fileBrowserLatestResultsG :: forall n_a1p9v. SimpleGetter (FileBrowser n_a1p9v) [FileInfo]
- Brick.Widgets.FileBrowser: fileBrowserNameG :: forall n_a1pvT. SimpleGetter (FileBrowser n_a1pvT) n_a1pvT
+ Brick.Widgets.FileBrowser: fileBrowserNameG :: forall n_a1p9v. SimpleGetter (FileBrowser n_a1p9v) n_a1p9v
- Brick.Widgets.FileBrowser: fileBrowserSearchStringG :: forall n_a1pvT. SimpleGetter (FileBrowser n_a1pvT) (Maybe Text)
+ Brick.Widgets.FileBrowser: fileBrowserSearchStringG :: forall n_a1p9v. SimpleGetter (FileBrowser n_a1p9v) (Maybe Text)
- Brick.Widgets.FileBrowser: fileBrowserSelectableG :: forall n_a1pvT. SimpleGetter (FileBrowser n_a1pvT) (FileInfo -> Bool)
+ Brick.Widgets.FileBrowser: fileBrowserSelectableG :: forall n_a1p9v. SimpleGetter (FileBrowser n_a1p9v) (FileInfo -> Bool)
- Brick.Widgets.FileBrowser: fileBrowserSelectableL :: forall n_a1pvT. Lens' (FileBrowser n_a1pvT) (FileInfo -> Bool)
+ Brick.Widgets.FileBrowser: fileBrowserSelectableL :: forall n_a1p9v. Lens' (FileBrowser n_a1p9v) (FileInfo -> Bool)
- Brick.Widgets.FileBrowser: fileBrowserSelectedFilesG :: forall n_a1pvT. SimpleGetter (FileBrowser n_a1pvT) (Set String)
+ Brick.Widgets.FileBrowser: fileBrowserSelectedFilesG :: forall n_a1p9v. SimpleGetter (FileBrowser n_a1p9v) (Set String)
- Brick.Widgets.FileBrowser: fileBrowserWorkingDirectoryG :: forall n_a1pvT. SimpleGetter (FileBrowser n_a1pvT) FilePath
+ Brick.Widgets.FileBrowser: fileBrowserWorkingDirectoryG :: forall n_a1p9v. SimpleGetter (FileBrowser n_a1p9v) FilePath
- Brick.Widgets.List: listElementsL :: forall n_a1kk0 t_a1kk1 e_a1kk2 t_a1ky7 e_a1ky8. Lens (GenericList n_a1kk0 t_a1kk1 e_a1kk2) (GenericList n_a1kk0 t_a1ky7 e_a1ky8) (t_a1kk1 e_a1kk2) (t_a1ky7 e_a1ky8)
+ Brick.Widgets.List: listElementsL :: forall n_a1jXD t_a1jXE e_a1jXF t_a1kbJ e_a1kbK. Lens (GenericList n_a1jXD t_a1jXE e_a1jXF) (GenericList n_a1jXD t_a1kbJ e_a1kbK) (t_a1jXE e_a1jXF) (t_a1kbJ e_a1kbK)
- Brick.Widgets.List: listItemHeightL :: forall n_a1kk0 t_a1kk1 e_a1kk2. Lens' (GenericList n_a1kk0 t_a1kk1 e_a1kk2) Int
+ Brick.Widgets.List: listItemHeightL :: forall n_a1jXD t_a1jXE e_a1jXF. Lens' (GenericList n_a1jXD t_a1jXE e_a1jXF) Int
- Brick.Widgets.List: listNameL :: forall n_a1kk0 t_a1kk1 e_a1kk2 n_a1ky9. Lens (GenericList n_a1kk0 t_a1kk1 e_a1kk2) (GenericList n_a1ky9 t_a1kk1 e_a1kk2) n_a1kk0 n_a1ky9
+ Brick.Widgets.List: listNameL :: forall n_a1jXD t_a1jXE e_a1jXF n_a1kbL. Lens (GenericList n_a1jXD t_a1jXE e_a1jXF) (GenericList n_a1kbL t_a1jXE e_a1jXF) n_a1jXD n_a1kbL
- Brick.Widgets.List: listSelectedL :: forall n_a1kk0 t_a1kk1 e_a1kk2. Lens' (GenericList n_a1kk0 t_a1kk1 e_a1kk2) (Maybe Int)
+ Brick.Widgets.List: listSelectedL :: forall n_a1jXD t_a1jXE e_a1jXF. Lens' (GenericList n_a1jXD t_a1jXE e_a1jXF) (Maybe Int)
Files
- CHANGELOG.md +13/−0
- README.md +1/−0
- brick.cabal +1/−17
- docs/guide.rst +62/−18
- docs/programs-screenshots.md +0/−3
- docs/programs-screenshots/brick-markup-demo.png binary
- programs/MarkupDemo.hs +0/−48
- src/Brick/AttrMap.hs +1/−1
- src/Brick/Markup.hs +0/−60
- src/Brick/Types/TH.hs +1/−1
- src/Brick/Widgets/Core.hs +131/−23
- src/Data/Text/Markup.hs +0/−85
CHANGELOG.md view
@@ -2,6 +2,19 @@ Brick changelog --------------- +0.68+----++API changes:+ * Removed the "markup" feature, which included `Data.Text.Markup`,+ `Brick.Markup`, and `brick-markup-demo`. This feature never performed+ well and was awkward to use. I considered it experimental from the+ initial release of this library. Some recent incompatibilities with+ Vty changes made me realize that it was time to finally get rid of+ this. If this affects you, please let me know and I am happy to work+ with you to figure out an alternative. Granted, anyone is welcome to+ dig up the previous code and re-use it in their own projects!+ 0.67 ----
README.md view
@@ -81,6 +81,7 @@ | [`swarm`](https://github.com/byorgey/swarm/) | A 2D programming and resource gathering game | | [`hledger-ui`](https://github.com/simonmichael/hledger) | A terminal UI for the hledger accounting system. | | [`hledger-iadd`](http://github.com/rootzlevel/hledger-iadd) | An interactive terminal UI for adding hledger journal entries |+| [`wordle`](https://github.com/ivanjermakov/wordle) | An implementation of the Wordle game | These third-party packages also extend `brick`:
brick.cabal view
@@ -1,5 +1,5 @@ name: brick-version: 0.67+version: 0.68 synopsis: A declarative terminal user interface library description: Write terminal user interfaces (TUIs) painlessly with 'brick'! You@@ -60,7 +60,6 @@ docs/programs-screenshots/brick-layer-demo.png, docs/programs-screenshots/brick-list-demo.png, docs/programs-screenshots/brick-list-vi-demo.png,- docs/programs-screenshots/brick-markup-demo.png, docs/programs-screenshots/brick-mouse-demo.png, docs/programs-screenshots/brick-padding-demo.png, docs/programs-screenshots/brick-progressbar-demo.png,@@ -92,7 +91,6 @@ Brick.Focus Brick.Forms Brick.Main- Brick.Markup Brick.Themes Brick.Types Brick.Util@@ -107,7 +105,6 @@ Brick.Widgets.ProgressBar Brick.Widgets.Table Data.IMap- Data.Text.Markup other-modules: Brick.Types.Common Brick.Types.TH@@ -377,19 +374,6 @@ ghc-options: -threaded -Wall -Wcompat -O2 default-language: Haskell2010 main-is: AttrDemo.hs- build-depends: base,- brick,- vty,- text,- microlens--executable brick-markup-demo- if !flag(demos)- Buildable: False- hs-source-dirs: programs- ghc-options: -threaded -Wall -Wcompat -O2- default-language: Haskell2010- main-is: MarkupDemo.hs build-depends: base, brick, vty,
docs/guide.rst view
@@ -763,26 +763,70 @@ , (specificAttr, fg white) ] -Functions ``Brick.Util.fg`` and ``Brick.Util.bg`` specify-partial attributes, and map lookups start with the desired name-(``general/specific`` in this case) and walk up the name hierarchy (to-``general``), merging partial attribute settings as they go, letting-already-specified attribute settings take precedence. Finally, any-attribute settings not specified by map lookups fall back to the map's-*default attribute*, specified above as ``Graphics.Vty.defAttr``. In-this way, if you want everything in your application to have a ``blue``-background color, you only need to specify it *once*: in the attribute-map's default attribute. Any other attribute names can merely customize-the foreground color.+When drawing a widget, Brick keeps track of the current attribute it+is using to draw to the screen. The attribute it tracks is specified+by its *attribute name*, which is a hierarchical name referring to the+attribute in the attribute map. In the example above, the map contains+two attribute names: ``generalAttr`` and ``specificAttr``. Both names+are made up of segments: ``general`` is the first segment for both+names, and ``specific`` is the second segment for ``specificAttr``.+This tells Brick that ``specificAttr`` is a more specialized version+of ``generalAttr``. We'll see below how that affects the resulting+attributes that Brick uses. -In addition to using the attribute map provided by ``appAttrMap``,-the map can be customized on a per-widget basis by using the attribute-map combinators:+When it comes to drawing something on the screen with either of these+attributes, Brick looks up the desired attribute name in the map+and uses the result to draw to the screen. In the example above,+``withAttr`` is used to tell Brick that when drawing ``str "foobar"``,+the attribute ``specificAttr`` should be used. Brick looks that name+up in the attribute map and finds a match: an attribute with a white+foreground color. However, what happens next is important: Brick then+looks up the more general attribute name derived from ``specificAttr``,+which it gets by removing the last segment in the name, ``specific``.+The resulting name, ``general``, is then looked up. The new result is+then *merged* with the initial lookup, yielding an attribute with a+white foreground color and a blue background color. This happens because+the ``specificAttr`` entry did not specify a background color. If it+had, that would have been used instead. In this way, we can create+inheritance relationships between attributes, much the same way CSS+supports inheritance of styles based on rule specificity. -* ``Brick.Widgets.Core.updateAttrMap``-* ``Brick.Widgets.Core.forceAttr``-* ``Brick.Widgets.Core.withDefAttr``-* ``Brick.Widgets.Core.overrideAttr``+Brick uses Vty's attribute type, ``Attr``, which has three components:+foreground color, background color, and style. These three components+can be independently specified to have an explicit value, and any+component not explicitly specified can default to whatever the terminal+is currently using. Vty styles can be combined together, e.g. underline+and bold, so styles are cummulative.++What if a widget attempts to draw with an attribute name that is not+specified in the map at all? In that case, the attribute map's "default+attribute" is used. In the example above, the default attribute for the+map is Vty's ``defAttr`` value, which means that the terminal's default+colors and style should be used. But that attribute can be customized+as well, and any attribute map lookup results will get merged with the+default attribute for the map. So, for example, if you'd like your+entire application background to be blue unless otherwise specified, you+could create an attribute map as follows:++.. code:: haskell++ let myMap = attrMap (bg blue) [ ... ]++This way, we can avoid repeating the desired background color and all of+the other map entries can just set foreground colors and styles where+needed.++In addition to using the attribute map provided by ``appAttrMap``, the+map and attribute lookup behavior can be customized on a per-widget+basis by using various functions from ``Brick.Widgets.Core``:++* ``updateAttrMap`` -- allows transformations of the attribute map,+* ``forceAttr`` -- forces all attribute lookups to map to the value of+ the specified attribute name,+* ``withDefAttr`` -- changes the default attribute for the attribute map+ to the one with the specified name, and+* ``overrideAttr`` -- creates attribute map lookup synonyms between+ attribute names. Attribute Themes ================
docs/programs-screenshots.md view
@@ -42,9 +42,6 @@ ## [ListViDemo.hs](https://github.com/jtdaugherty/brick/blob/master/programs/ListViDemo.hs)  -## [MarkupDemo.hs](https://github.com/jtdaugherty/brick/blob/master/programs/MarkupDemo.hs)-- ## [MouseDemo.hs](https://github.com/jtdaugherty/brick/blob/master/programs/MouseDemo.hs) 
− docs/programs-screenshots/brick-markup-demo.png
binary file changed (12852 → absent bytes)
− programs/MarkupDemo.hs
@@ -1,48 +0,0 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE OverloadedStrings #-}-module Main where--#if !(MIN_VERSION_base(4,11,0))-import Data.Monoid ((<>))-#endif-import qualified Graphics.Vty as V--import Brick.Main (App(..), defaultMain, resizeOrQuit, neverShowCursor)-import Brick.Types- ( Widget- , Padding(..)- )-import Brick.Widgets.Core- ( (<=>)- , (<+>)- , padLeft- )-import Brick.Util (on, fg)-import Brick.Markup (markup, (@?))-import Brick.AttrMap (attrMap, AttrMap)-import Data.Text.Markup ((@@))--ui :: Widget ()-ui = (m1 <=> m2) <+> (padLeft (Pad 1) m3)- where- m1 = markup $ ("Hello" @@ fg V.blue) <> ", " <> ("world!" @@ fg V.red)- m2 = markup $ ("Hello" @? "keyword1") <> ", " <> ("world!" @? "keyword2")- m3 = markup $ ("Hello," @? "keyword1") <> "\n" <> ("world!" @? "keyword2")--theMap :: AttrMap-theMap = attrMap V.defAttr- [ ("keyword1", fg V.magenta)- , ("keyword2", V.white `on` V.blue)- ]--app :: App () e ()-app =- App { appDraw = const [ui]- , appHandleEvent = resizeOrQuit- , appAttrMap = const theMap- , appStartEvent = return- , appChooseCursor = neverShowCursor- }--main :: IO ()-main = defaultMain app ()
src/Brick/AttrMap.hs view
@@ -106,7 +106,7 @@ attrMap theDefault pairs = AttrMap theDefault (M.fromList pairs) -- | Create an attribute map in which all lookups map to the same--- attribute.+-- attribute. This is functionally equivalent to @AttrMap attr []@. forceAttrMap :: Attr -> AttrMap forceAttrMap = ForceAttr
− src/Brick/Markup.hs
@@ -1,60 +0,0 @@--- | This module provides an API for turning "markup" values into--- widgets. This module uses the "Data.Text.Markup" interface in this--- package to assign attributes to substrings in a text string; to--- manipulate markup using (for example) syntax highlighters, see that--- module.-module Brick.Markup- ( Markup- , markup- , (@?)- , GetAttr(..)- )-where--import Lens.Micro ((.~), (&), (^.))-import Control.Monad (forM)-import qualified Data.Text as T-import Data.Text.Markup--import Graphics.Vty (Attr, vertCat, horizCat, text', defAttr)--import Brick.AttrMap-import Brick.Types---- | A type class for types that provide access to an attribute in the--- rendering monad. You probably won't need to instance this.-class GetAttr a where- -- | Where to get the attribute for this attribute metadata.- getAttr :: a -> RenderM n Attr--instance GetAttr Attr where- getAttr a = do- c <- getContext- return $ mergeWithDefault a (c^.ctxAttrMapL)--instance GetAttr AttrName where- getAttr = lookupAttrName---- | Build a piece of markup from text with an assigned attribute name.--- When the markup is rendered, the attribute name will be looked up in--- the rendering context's 'AttrMap' to determine the attribute to use--- for this piece of text.-(@?) :: T.Text -> AttrName -> Markup AttrName-(@?) = (@@)---- | Build a widget from markup.-markup :: (Eq a, GetAttr a) => Markup a -> Widget n-markup m =- Widget Fixed Fixed $ do- let markupLines = markupToList m- mkLine pairs = do- is <- forM pairs $ \(t, aSrc) -> do- a <- getAttr aSrc- return $ text' a t- if null is- then do- def <- getAttr defAttr- return $ text' def $ T.singleton ' '- else return $ horizCat is- lineImgs <- mapM mkLine markupLines- return $ emptyResult & imageL .~ vertCat lineImgs
src/Brick/Types/TH.hs view
@@ -11,7 +11,7 @@ import Lens.Micro.TH (DefName(..), LensRules, makeLensesWith, lensRules, lensField) -- | A template haskell function to build lenses for a record type. This--- function differs from the 'Control.Lens.makeLenses' function in that+-- function differs from the 'Lens.Micro.TH.makeLenses' function in that -- it does not require the record fields to be prefixed with underscores -- and it adds an "L" suffix to lens names to make it clear that they -- are lenses.
src/Brick/Widgets/Core.hs view
@@ -373,7 +373,7 @@ hyperlink url p = Widget (hSize p) (vSize p) $ do c <- getContext- let attr = attrMapLookup (c^.ctxAttrNameL) (c^.ctxAttrMapL) `V.withURL` url+ let attr = (c^.attrL) `V.withURL` url withReaderT (ctxAttrMapL %~ setDefaultAttr attr) (render p) -- | Pad the specified widget on the left. If max padding is used, this@@ -861,38 +861,93 @@ withReaderT (\c -> c & availHeightL .~ h & availWidthL .~ w) $ render $ cropToContext p --- | When drawing the specified widget, set the current attribute used--- for drawing to the one with the specified name. Note that the widget--- may use further calls to 'withAttr' to override this; if you really--- want to prevent that, use 'forceAttr'. Attributes used this way still--- get merged hierarchically and still fall back to the attribute map's--- default attribute. If you want to change the default attribute, use--- 'withDefAttr'.+-- | When drawing the specified widget, set the attribute used for+-- drawing to the one with the specified name. Note that the widget+-- may use further calls to 'withAttr' to change the active drawing+-- attribute, so this only takes effect if nothing in the specified+-- widget invokes 'withAttr'. If you want to prevent that, use+-- 'forceAttr'. Attributes used this way still get merged hierarchically+-- and still fall back to the attribute map's default attribute. If you+-- want to change the default attribute, use 'withDefAttr'.+--+-- For example:+--+-- @+-- appAttrMap = attrMap (white `on` blue) [ ("highlight", fg yellow)+-- , ("warning", bg magenta)+-- ]+--+-- renderA :: (String, String) -> [Widget n]+-- renderA (a,b) = hBox [ str a+-- , str " is "+-- , withAttr "highlight" (str b)+-- ]+--+-- render1 = renderA ("Brick", "fun")+-- render2 = withAttr "warning" render1+-- @+--+-- In the example above, @render1@ will show @Brick is fun@ where the+-- first two words are white on a blue background and the last word+-- is yellow on a blue background. However, @render2@ will show the+-- first two words in white on magenta although the last word is still+-- rendered in yellow on blue. withAttr :: AttrName -> Widget n -> Widget n withAttr an p = Widget (hSize p) (vSize 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 applying specified--- function to the current default attribute.+-- the map's default attribute to the one that we get by applying the+-- specified function to the current map's default attribute. This is a+-- variant of 'withDefAttr'; see the latter for more information. 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) --- | 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.+-- | Update the attribute map used while rendering the specified+-- widget (and any sub-widgets): set its new *default* attribute+-- (i.e. the attribute components that will be applied if not+-- overridden by any more specific attributes) to the one that we get+-- by looking up the specified attribute name in the map.+--+-- For example:+--+-- @+-- ...+-- appAttrMap = attrMap (white `on` blue) [ ("highlight", fg yellow)+-- , ("warning", bg magenta)+-- , ("good", white `on` green) ]+-- ...+--+-- renderA :: (String, String) -> [Widget n]+-- renderA (a,b) = hBox [ withAttr "good" (str a)+-- , str " is "+-- , withAttr "highlight" (str b) ]+--+-- render1 = renderA ("Brick", "fun")+-- render2 = withDefAttr "warning" render1+-- @+--+-- In the above, render1 will show "Brick is fun" where the first word+-- is white on a green background, the middle word is white on a blue+-- background, and the last word is yellow on a blue background.+-- However, render2 will show the first word in the same colors but+-- the middle word will be shown in whatever the terminal's normal+-- foreground is on a magenta background, and the third word will be+-- yellow on a magenta background. withDefAttr :: AttrName -> Widget n -> Widget n withDefAttr an p = Widget (hSize p) (vSize p) $ do c <- getContext withReaderT (ctxAttrMapL %~ (setDefaultAttr (attrMapLookup an (c^.ctxAttrMapL)))) (render p) --- | When rendering the specified widget, update the attribute map with--- the specified transformation.+-- | While rendering the specified widget, use a transformed version+-- of the current attribute map. This is a very general function with+-- broad capabilities: you probably want a more specific function such+-- as 'withDefAttr' or 'withAttr'. updateAttrMap :: (AttrMap -> AttrMap) -> Widget n -> Widget n updateAttrMap f p = Widget (hSize p) (vSize p) $@@ -906,15 +961,58 @@ -- entry in the attribute map as would normally be the case. If you -- want to have more control over the resulting attribute, consider -- 'modifyDefAttr'.+--+-- For example:+--+-- @+-- ...+-- appAttrMap = attrMap (white `on` blue) [ ("highlight", fg yellow)+-- , ("notice", fg red) ]+-- ...+--+-- renderA :: (String, String) -> [Widget n]+-- renderA (a,b) = hBox [ withAttr "highlight" (str a)+-- , str " is "+-- , withAttr "highlight" (str b)+-- ]+--+-- render1 = renderA ("Brick", "fun")+-- render2 = forceAttr "notice" render1+-- @+--+-- In the above, render1 will show "Brick is fun" where the first and+-- last words are yellow on a blue background and the middle word is+-- white on a blue background. However, render2 will show all words+-- in red on a blue background. In both versions, the middle word+-- will be in white on a blue background. forceAttr :: AttrName -> Widget n -> Widget n forceAttr an p = Widget (hSize p) (vSize p) $ do c <- getContext 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.--- See also 'mapAttrName'.+-- | Override the lookup of the attribute name 'targetName' to return+-- the attribute value associated with 'fromName' when rendering the+-- specified widget.+--+-- For example:+--+-- @+-- appAttrMap = attrMap (white `on` blue) [ ("highlight", fg yellow)+-- , ("notice", fg red)+-- ]+--+-- renderA :: (String, String) -> [Widget n]+-- renderA (a, b) = str a <+> str " is " <+> withAttr "highlight" (str b)+--+-- render1 = withAttr "notice" $ renderA ("Brick", "fun")+-- render2 = overrideAttr "highlight" "notice" render1+-- @+--+-- In the example above, @render1@ will show @Brick is fun@ where the+-- first two words are red on a blue background, but @fun@ is yellow on+-- a blue background. However, @render2@ will show all three words in+-- red on a blue background. overrideAttr :: AttrName -> AttrName -> Widget n -> Widget n overrideAttr targetName fromName = updateAttrMap (mapAttrName fromName targetName)@@ -1097,8 +1195,13 @@ withReaderT (ctxVScrollBarOrientationL .~ Just orientation) (render w) -- | Enable scroll bar handles on all vertical scroll bars in the--- specified widget. This will only have an effect if 'withVScrollBars'--- is also called.+-- specified widget. Handles appear at the ends of the scroll bar,+-- representing the "handles" that are typically clickable in+-- graphical UIs to move the scroll bar incrementally. Vertical+-- scroll bars are also clickable if mouse mode is enabled and if+-- 'withClickableVScrollBars' is used.+--+-- This will only have an effect if 'withVScrollBars' is also called. withVScrollBarHandles :: Widget n -> Widget n withVScrollBarHandles w = Widget (hSize w) (vSize w) $@@ -1149,9 +1252,14 @@ Widget (hSize w) (vSize w) $ withReaderT (ctxVScrollBarClickableConstrL .~ Just f) (render w) --- | Enable scroll bar handles on all horizontal scroll bars in the--- specified widget. This will only have an effect if 'withHScrollBars'--- is also called.+-- | Enable scroll bar handles on all horizontal scroll bars in+-- the specified widget. Handles appear at the ends of the scroll+-- bar, representing the "handles" that are typically clickable in+-- graphical UIs to move the scroll bar incrementally. Horizontal+-- scroll bars are also clickable if mouse mode is enabled and if+-- 'withClickableHScrollBars' is used.+--+-- This will only have an effect if 'withHScrollBars' is also called. withHScrollBarHandles :: Widget n -> Widget n withHScrollBarHandles w = Widget (hSize w) (vSize w) $
− src/Data/Text/Markup.hs
@@ -1,85 +0,0 @@--- | This module provides an API for "marking up" text with arbitrary--- values. A piece of markup can then be converted to a list of pairs--- representing the sequences of characters assigned the same markup--- value.------ This interface is experimental. Don't use this for your full-file--- syntax highlighter just yet!-module Data.Text.Markup- ( Markup- , markupToList- , markupSet- , fromList- , fromText- , toText- , isEmpty- , (@@)- )-where--import qualified Data.Semigroup as Sem-import Data.String (IsString(..))-import qualified Data.Text as T---- | Markup with metadata type 'a' assigned to each character.-data Markup a = Markup [(Char, a)]- deriving Show--instance Sem.Semigroup (Markup a) where- (Markup t1) <> (Markup t2) = Markup (t1 `mappend` t2)--instance Monoid (Markup a) where- mempty = Markup mempty- mappend = (Sem.<>)--instance (Monoid a) => IsString (Markup a) where- fromString = fromText . T.pack---- | Build a piece of markup; assign the specified metadata to every--- character in the specified text.-(@@) :: T.Text -> a -> Markup a-t @@ val = Markup [(c, val) | c <- T.unpack t]---- | Build markup from text with the default metadata.-fromText :: (Monoid a) => T.Text -> Markup a-fromText = (@@ mempty)---- | Extract the text from markup, discarding the markup metadata.-toText :: (Eq a) => Markup a -> T.Text-toText = T.concat . (fst <$>) . concat . markupToList---- | Test whether the markup is empty.-isEmpty :: Markup a -> Bool-isEmpty (Markup ls) = null ls---- | Set the metadata for a range of character positions in a piece of--- markup. This is useful for, e.g., syntax highlighting.-markupSet :: (Eq a) => (Int, Int) -> a -> Markup a -> Markup a-markupSet (start, len) val m@(Markup l) = if start < 0 || start + len > length l- then m- else newM- where- newM = Markup $ theHead ++ theNewEntries ++ theTail- (theHead, theLongTail) = splitAt start l- (theOldEntries, theTail) = splitAt len theLongTail- theNewEntries = zip (fst <$> theOldEntries) (repeat val)---- | Convert markup to a list of lines. Each line is represented by a--- list of pairs in which each pair contains the longest subsequence of--- characters having the same metadata.-markupToList :: (Eq a) => Markup a -> [[(T.Text, a)]]-markupToList (Markup thePairs) = toList <$> toLines [] [] thePairs- where- toLines ls cur [] = ls ++ [cur]- toLines ls cur ((ch, val):rest)- | ch == '\n' = toLines (ls ++ [cur]) [] rest- | otherwise = toLines ls (cur ++ [(ch, val)]) rest-- toList [] = []- toList ((ch, val):rest) = (T.pack $ ch : (fst <$> matching), val) : toList remaining- where- (matching, remaining) = break (\(_, v) -> v /= val) rest---- | Convert a list of text and metadata pairs into markup.-fromList :: [(T.Text, a)] -> Markup a-fromList pairs = Markup $ concatMap (\(t, val) -> [(c, val) | c <- T.unpack t]) pairs