Module documentation for 0.58.1
brick is a Haskell terminal user interface (TUI) programming toolkit.
To use it, you write a pure function that describes how your user
interface should look based on your current application state and you
provide a state transformation function to handle events.
brick exposes a declarative API. Unlike most GUI toolkits which
require you to write a long and tedious sequence of “create a widget,
now bind an event handler”,
brick just requires you to describe your
interface using a set of declarative layout combinators.
Under the hood, this library builds upon vty, so some knowledge of Vty will be helpful in using this library.
Here’s an example interface (see
withBorderStyle unicode $ borderWithLabel (str "Hello!") $ (center (str "Left") <+> vBorder <+> center (str "Right"))
┌─────────Hello!─────────┐ │ │ │ │ │ │ │ Left │ Right │ │ │ │ │ │ │ └────────────────────────┘
To get an idea of what some people have done with
brick, take a look
at these projects. If you have made something and would like me to
include it, get in touch!
||An implementation of the Tetris game|
||A typing tutor|
||A client for Mattermost|
||A GHC profile viewer|
||A mouse-driven ASCII art drawing program|
||An interpreter for Joy|
||A command-line tool for managing kitchen recipes|
||A mail user agent|
||An implementation of the 2048 game|
||A Hoogle client|
||A file manager|
||Animated solutions to The Tower of Hanoi|
||A space-themed typing-tutor game|
||The card game|
||A Sudoku implementation|
||An interactive frontend to the Summoner tool|
||An embeddable editor with support for Brick|
||A git branch checkout utility|
||A program for reviewing “flash card” notes|
||A TUI for Harvest|
||A TUI for
These third-party packages also extend
||A widget for exploring a directory tree and selecting or flagging files and directories|
Release Announcements / News
Find out about
brick releases and other news on Twitter:
Check out the many demo programs to get a feel for different aspects of the library:
$ cabal new-build -f demos $ find dist-newstyle -type f -name \*-demo
To get started, see the user guide.
brick comes in a variety of forms:
- The official brick user guide
- Samuel Tay’s brick tutorial
- Haddock (all modules)
- Demo programs (Screenshots)
brick comes with a bunch of batteries included:
- Vertical and horizontal box layout widgets
- Basic single- and multi-line text editor widgets
- List widget
- Progress bar widget
- Simple dialog box widget
- Border-drawing widgets (put borders around or in between things)
- Generic scrollable viewports
- General-purpose layout control combinators
- Extensible widget-building API
- User-customizable attribute themes
- Type-safe, validated input form API (see the
- A filesystem browser for file and directory selection
- Borders can be configured to automatically connect!
brick-users Google Group / e-mail list is a place to discuss
library changes, give feedback, and ask questions. You can subscribe at:
There are some places were I have deliberately chosen to worry about
performance later for the sake of spending more time on the design
(and to wait on performance issues to arise first).
brick is also
something of an experimental project of mine and some aspects of the
design involve trade-offs that might not be right for your application.
Brick is not intended to be all things to all people; rather, I want it
to provide a good foundation for building complex terminal interfaces
in a declarative style to take away specific headaches of building,
modifying, and working with such interfaces, all while seeing how far we
can get with a pure function to specify the interface.
brick exports an extension API that makes it possible to make your own
packages and widgets. If you use that, you’ll also be helping to test
whether the exported interface is usable and complete!
Please file bug reports as GitHub issues. For best results:
Include the versions of relevant software packages: your terminal emulator,
vtywill be the most important ones.
Clearly describe the behavior you expected …
… and include a minimal demonstration program that exhibits the behavior you actually observed.
If you decide to contribute, that’s great! Here are some guidelines you should consider to make submitting patches easier for all concerned:
- If you want to take on big things, talk to me first; let’s have a design/vision discussion before you start coding. Create a GitHub issue and we can use that as the place to hash things out.
- Please make changes consistent with the conventions I’ve used in the codebase.
- Please adjust or provide Haddock and/or user guide documentation relevant to any changes you make.
- New commits should be
- Please do NOT include package version changes in your patches. Package version changes are only done at release time when the full scope of a release’s changes can be evaluated to determine the appropriate version change.
- Removed a defunct failing test from the List test suite
- Updated dependency constraints to build on GHC 9.0.1 (thanks Ondřej Súkup)
- 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
handleFileBrowserEventfunction. The documentation has been updated to indicate which functions are triggered by each key event. (Thanks David B. Lamkins)
listFindByfunction now attempts to find a match anywhere in the list rather than just somewhere between the cursor and the end of the list.
FileBrowsernow 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)
- Fixed a small space leak in the main rendering loop (#260)
TailDemobuilding on more versions of GHC
- Raised lower bound on
vtyto 5.31 to get the new
- Added support for the
strikethroughstyle in Brick theme customization files.
- Increased upper bound for
baseto support GHC 8.10.2 (thanks Ryan Scott)
Brick.Forms.updateFormStateto update the state contained within (and managed by) a Form. This function takes care of the details of updating the form fields themselves to be consistent with the change in underlying state.
- Added the overall window width (
windowWidth) and height (
Context, the rendering context type (thanks Tom McLaughlin)
brick-tail-demo, a demonstration program for writing a
tail-style output-following interface.
Brick.Widgets.ProgressBarso that it handles near-endpoint cases more naturally (fixes #281)
- Increased lower bound on
vtydependency to 5.29.
customMainnow restores the initial terminal input state on shutdown. This means that changes to the input state flags in the last
suspendAndResumebefore program exit are no longer propagated to the end user’s terminal environment (which could lead to broken or garbled terminal I/O).
Brick.Widgets.FileBrowser.maybeSelectCurrentEntry(thanks Róman Joost)
- Added handlers for the
Brick.Widgets.Edit.handleEditorEvent(thanks Róman Joost)
- Relaxed base bounds to allow building with GHC 8.10 (thanks Joshua Chia)
vLimitPercent: use correct horizontal size policy from child (thanks Janek Spaderna)
str: be more aggressive in determining how many characters to display (attempt to display as many zero-width characters as possible)
- Attribute map lookups now merge styles in addition to merging colors
txtWrapWithnow pads in the single-line case (see also
926d317c46b19d4e576748891a1702080287aa03, #234, and #263)
- EventM now provides a MonadFail instance
- EventM now provides MonadMask, MonadCatch, and MonadThrow instances (thanks Fraser Tweedale)
- The FileBrowser now has support for vi-style bindings in addition to
its previous bindings. New bindings include:
k: next/previous element
C-p: page down/up
C-u: half page down/up
g: select first entry
G: select last entry
- Added Brick.Focus.focusRingToList, which returns all of the elements in a focus ring as a list, starting with the focused entry and wrapping around (#257; thanks @4eUeP)
- Fix Brick.Widgets.FileBrowser.fileExtensionMatch to match directories and also match symlinks that link to directories (thanks @YVee1)
- Added demonstration program screenshot gallery (thanks @drola)
- Fixed a bug where a self-referential symlink would cause the file browser to get into a loop and ultimately crash. (Thanks Kevin Quick)
Brick.Focus.focusRingLengthto get the size of a focus ring. (Thanks Róman Joost)
- Updated Travis configuration and base dependency to support GHC 8.8.1. (thanks Brandon Hamilton)
writeBChanNonBlocking, which does a non-blocking write to a
BChanand returns whether the write succeeded. This required raising the STM lower bound to 2.4.3.
FileBrowsernow supports navigation of directories via symlinks, so
Enteron a symlink will descend into the target path of the symlink if that path is a directory. Part of this change is that the
FileInfotype got a new file,
fileInfoLinkTargetType, that indicates the type of file that the link points to, if any.
Editwidget now supports
EvPasteVty events by default, assuming UTF-8 encoding of pasted bytes. If pasted bytes are not UTF-8-decodable, the pastes will be ignored. In any case, users can still intercept
EvPasteevents as before and handle them as desired if the default behavior is not desirable.
txtWrapWithnow always pads its output to the available width to obey its
- userguide: update stale Result construction
- Added test case for List initial selection (thanks Fraser Tweedale)
- Fixed build on GHC 7.10 due to RULES pragma formatting issue (thanks Fraser Tweedale)
- Various CI-related fixes (thanks Fraser Tweedale)
Brick.Main.customMainso that it now takes an additional (first) argument: the initial
Vtyhandle to use. This lets the caller have more control over the terminal state when, for example, they have previously set up Vty to do other work before calling
Brick.Main.customMainWithVty. This function is the same as
customMainexcept that it also returns the final
Vtyhandle that it used internally without shutting that Vty handle down. This allows the caller to continue using the terminal without resetting it after
- The box combinators
hBoxgot GHC rewrite rules that will optimize away redundant boxes. This change improves performance for chains of
<=>as well as nested boxes using
vBox. Previously chains of e.g.
<+>produced binary trees of boxes that incurred more rendering overhead. Those are now optimized away.
- Data.Text.Markup: renamed
- List got a new
listFindByfunction (thanks Fraser Tweedale). This function uses a predicate to find a matching element in the list and move the cursor to that item.
- Data.Text.Markup got a new
Brick.Markupnow properly renders empty lines in markup (#209)
Listtype got its container type generalized thanks to a lot of work by Fraser Tweedale. Note that this change is backwards-compatible with older Brick programs that use the
List. Thanks to this work, the
Listnow supports both
Data.Sequenceas its container types out of the box and can be extended to support other sequence types with some simple type class instances. In addition, property tests are provided for
Listand its asymptotics are noted in the documentation. Along the way, various bugs in some of the list movement functions got fixed to bring them in line with the advertised behavior in the documentation. Thanks, Fraser!
- The FileBrowser module got the ability to select multiple files
(#204). This means that the
fileBrowserSelectionfunction now returns a list of
FileInforather than at most one via
Maybe. The module also now uses a new attribute,
fileBrowserSelectedAttr, to indicate entries that are currently selected (in addition to displaying an asterisk after their filenames). Lastly, the file size and type fields of
FileInfohave been replaced with a new type,
FileInfonow carries an
Either IOException FileStatus. As part of that safety improvement,
setWorkingDirectorynow no longer clobbers the entire entry listing if any of the listings fail to stat. In addition, the FileBrowser now uses the correct file stat routines to deal with symbolic links.
- Added lower bound on
directory(thanks Fraser Tweedale)
Test suite changes:
- Test suite now propagates success/failure to exit status (thanks Fraser Tweedale)
- File browsers in search mode now terminate search mode when
Enteris pressed, resulting in better behavior.
Brick.Widgets.FileBrowser, which provides a filesystem browser for selecting files and directories. Read the Haddock module documentation and see the included demo program,
programs/FileBrowserDemo.hs, for information on using the new functionality.
suspendAndResumenow empties the rendering cache when returning to the rendering event loop. This ensures that the state returned by the
IOaction is rendered completely rather than relying on potentially stale cache entries.
- Forms: added
setFormFocusfunction to set focus for a form
Themetypes (thanks Fraser Tweedale)
- Lists now draw correctly without crashing due to a vector slice bounds check failure if their rendering area is too small (#195; thanks @andrevdm)
- Relaxed base bounds to support GHC 8.6 (thanks @maoe)
- Added towerHanoi to the featured projects list
- Support STM 2.5 by allowing for
radioCustomFieldto permit customization of characters used to draw selection state for such fields.
Brick.Formsgot a new field constructor,
listField, that provides a form field using a
List: added the
listMoveToElementfunction for changing the list selection to the specified element, if it exists.
- Now depends on vty >= 5.24.
viewport: fixed failable patterns for forward compatibility with GHC 8.6 (#183)
Readinstances for some types
- Brick.Widgets.Core: added new functions
vLimitPercent. These behave similarly to
vLimitexcept that instead of taking absolute numbers of columns or rows, they take percentages. (Thanks Roman Joost)
italickeyword is now supported in theme customization file style lists. This requires
vty >= 5.23.1
- Added support for parsing
#RRGGBBcolor values in theme customization files in addition to the color names already supported (thanks Brent Carmer). These values are mapped to the nearest reasonable entry in the 240-color space.
- Theme customization files can now use empty lists for style customization.
listMoveBynow automatically moves to the first or last position in the list if called when the list is non-empty but has no selected element (thanks Philip Kamenarsky)
Brick.Widgets.List.renderListWithIndexthat passes the index of each element to the item rendering function (thanks email@example.com)
- Fixed a bug where mouse-up events in viewports were not translated into the global coordinate space, unlike mouse-down events (#173)
- The Forms API got two new functions,
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,
- Raiseed upper bound to support GHC 8.4.2 (#171)
- Improved List accessor documentation (thanks liam firstname.lastname@example.org)
- Brick.Main now uses a Set instead a list to track invalidation requests to avoid duplicates.
- 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.hsfor a demonstraton. Also see the “Joinable Borders” section of the User Guide.
- Conditionally depend on semigroups for GHC before 8
- Added support for GHC 8.4.
- Updated travis build to test on all 8.x releases (thanks Peter Simons)
- Fixed a bug where the “reverseVideo” style could not be parsed in a theme customization when it was all lowercase (thanks Yuriy Lazarev)
- Guide: added more complete example of creating a default theme (thanks Mark Wales)
- Guide: added offset to Extent pattern matching (thanks Mark Wales)
- Core: vLimit and hLimit now bound sizes rather than setting them.
This was the original intention of these combinators. The change in
behavior means that now
vLimit Nmeans that at most
Nrows will be available; if the context has less, then the smaller constraint in the context is used instead. Programs affected by this behavior will be those that assume that
vLimitdoesn’t do this, but that should be very few or zero.
- Dialog: now arrow keys no longer wrap around available buttons but stop at rightmost or leftmost button to avoid confusion when attempting to tell which button is selected in two-button dialogs (thanks to Karl Ostmo for this change)
- Updated Haddocks for str/txt in Core to mention tab character considerations
- Forms: added support for external validation of form fields using
setFieldValid. See the Haddock, User Guide, and FormDemo.hs for details.
- Borders: removed all attribute names except
borderAttrto simplify border attribute assignment.
- Core: make all text wrap widgets Greedy horizontally
- Dialog: clarify purpose in documentation (w.r.t. #149)
- This release adds the new
Brick.Formsmodule, which provides an API for type-safe input forms with automatic rendering, event handling, and state management! See the Haddock and the “Input Forms” section of the Brick User Guide for information on this killer feature! Many thanks to Kevin Quick for feedback on this new functionality.
viewportnow implicitly causes generation of mouse events for the viewport when mouse mode is enabled. The mouse events are expressed in the coordinate system of the contents of the viewport. The consequence and intention of this change is to enable mouse event reporting for editors when clicks occur outside the known text area.
focusSetCurrentto make it easy to set the focus of a focus ring
Brick.Main: added a simple polymorphic
- Mixed-case color names like “brightBlue” can now be parsed in theme customization files.
- Added Ord instances for
BrickEvent(thanks Tom Sydney Kerckhove)
Brick.AttrMap: attribute name components are now exposed via the
attrNameComponentsfunction. Also added a Read instance for AttrName.
- This release adds user-customizable theme support. Please see the
“Attribute Themes” section of the User Guide for an introduction; see
the Haddock documentation for
Brick.Themesfor full details. Also, see the new
programs/ThemeDemo.hsfor a working demonstration.
- Brick.AttrMap.setDefault was renamed to setDefaultAttr.
- Added Brick.AttrMap.getDefaultAttr: get the default attribute from an attribute map.
- Added Brick.Widgets.Core.modifyDefAttr to modify the default attribute of the rendering context.
- Updated AttrDemo to show usage of modifyDefAttr.
- Brick.Widgets.Core: added
hyperlinkcombinator (thanks Getty Ritter for hyperlinking support)
- Updated AttrDemo to show how to use hyperlinking
- README: Added
hermsto featured projects
- Fixed haddock for listHandleEventVi.
- Added Brick.Widgets.List.handleListEventVi to add support for vi-style movements to lists (thanks Richard Alex Hofer)
- Added ListViDemo.hs to demonstrate the Vi-style handler for lists (thanks Richard Alex Hofer)
- List: added page movement functions
listMovePageDown(thanks Richard Alex Hofer)
- Fixed a spelling mistake in the AttrMap haddock (thanks Edward Betts)
- Minor documentation updates including a clarification for #135
- vBox/hBox: when there is leftover space and all elements are greedy, spread it amongst the elements as evenly as possible instead of assigning it all to the first element (fixes #133)
- Include Sam Tay’s brick tutorial files in extra-doc-files
- Added Brick.Widgets.Core.setAvailableSize to control rendering context size in cases where the screen size is too constraining (e.g. for a floating layer that might be bigger than the screen).
- Samuel Tay has contributed his wonderful Brick tutorial to this package in docs/samtay-tutorial.md. Thank you!
- getVtyHandle: always return a Vty handle rather than Maybe (Previously, in appStartEvent you’d get Nothing because Vty had not been initialized yet. This made various use cases impossible to satisfy because appStartEvent is a natural place to get initial terminal state from Vty. This change makes it so that a Vty handle is always available, even in appStartEvent.)
- txtWrapWith: added missing haddock
- Core: added txtWrapWith and strWrapWith functions to provide control over wrapping behavior by specifying custom wrapping settings.
- Updated TextWrapDemo.hs to demonstrate customizing wrapping settings.
- Upgrade to word-wrap 0.2
- Brick.Types.Internal: improve mouse constructor haddock
- Add a basic fill demonstration program (FillDemo.hs)
- str: fixed an IsString constraint confusion on GHC 7.10.1
- Added a dependency on “word-wrap” for text-wrapping.
- Added a new TextWrapDemo demo program to illustrate text wrapping support
- Brick.Widgets.Core: added new functions txtWrap and strWrap to do wrapping of long lines of text.
- Guide: fixed event type (#126)
- The editor content drawing function is now passed to renderEditor, not the constructor, to improve separation of presentation and representation concerns. The corresponding Editor drawing function lens and accessor were removed.
- Added a dependency on data-clist.
- Brick.Focus: removed the Functor instance for FocusRing.
- Brick.Focus: re-implemented FocusRing in terms of the circular list data structure from data-clist. In addition, this change introduced “focusRingModify”, which permits the user to use the data-clist API to directly manipulate the FocusRing’s internals. This way brick doesn’t have to re-invent the wheel on the focus ring behavior.
- Added programs/ReadmeDemo.hs and featured its output and code in the README to provide an early demonstration
- centerAbout now right- and bottom-pads its operand to behave consistently with h/vCenter
- Use Extra-Doc-Files instead of Data-Files for documentation files
- List: correctly update selected index in listInsert
- Update example program in brick.cabal (thanks @timbod7)
- Updated to depend on Vty 5.15.
- Updated to remove dependency on data-default.
- Discontinued support for GHC versions prior to 7.10.1.
- Removed Data.Default instances for AttrName, AttrMap, Result, and BorderStyle (use Monoid instances instead where possible).
- Added defaultBorderStyle :: BorderStyle.
- Added emptyResult :: Result n.
This release includes a breaking API change:
- Brick now uses bounded channels (Brick.BChan.BChan) for event communication rather than Control.Concurrent.Chan’s unbounded channels to improve memory consumption for programs with runaway event production (thanks Joshua Chia)
Other API changes:
- Brick.List got a new function, listModify, for modifying the selected element (thanks @diegospd)
- hBox and vBox now use the more efficient DList data structure when rendering to improve performance for boxes with many elements (thanks Mitsutoshi Aoe)
- viewport: do not cull cursor locations on empty viewport contents (fixes #105)
- User guide CounterEvent type fix (thanks @diegospd)
- List: fixed empty list validation in listReplace (thanks Joshua Chia)
- MouseDemo: add an editor and use mouse events to move the cursor
- MouseDemo: Enhance MouseDemo to show interaction between ‘clickable’ and viewports (thanks Kevin Quick)
- Editors now report mouse click events
- Rename TerminalLocation row/column fields to avoid commonplace name clashes; rename row/column to locationRow/locationColumn (fixes #96)
- Core: make cropToContext also crop extents (fixes #101)
- viewport: if the sub-widget is not rendered, also cull all extents and cursor locations
- User Guide updates: minor fixes, updates to content on custom widgets, wide character support, and examples (thanks email@example.com, Kevin Quick)
This release added support for wide characters. In particular, wide characters can now be entered into the text editor widget and used in ‘str’ and ‘txt’ widgets.
- Mouse mode is no longer enabled by default.
- customMain’s event channel parameter is now optional
- FocusRing now provides a Functor instance (thanks Ian Jeffries)
This release primarily adds support for mouse interaction. For details, see the Mouse Support section of the User Guide. This release also includes breaking API changes for the App type. Here’s a migration guide:
- Event handlers now take “BrickEvent n e” instead of “e”, where “e” was the custom event type used before this change. To recover your own custom events, pattern-match on “AppEvent”; to recover Vty input events, pattern-match on “VtyEvent”.
- appLiftVtyEvent went away and can just be removed from your App record constructor.
- If you aren’t using the custom event type or were just using Vty’s “Event” type as your App’s event type, you can set your event type to just “e” because you’ll now be able to get Vty events regardless of whether you use a custom event type.
- Added the Widget combinator “clickable” to indicate that a widget should generate mouse click events
- Added the Extent data type and the “reportExtent” widget combinator to report the positions and sizes of widgets
- Rendering “Result” values now include reported extents and update their offsets (adds “extents” field and “extentsL” lens)
- Added “lookupExtent”, “findClickedExtents”, and “clickedExtent” in EventM to find extents and check them for mouse clicks
- Removed appLiftVtyEvent. Instead of wrapping Vty’s events in your own type, you now get a “BrickEvent” that always contains Vty events but has the ability to embed your custom events. See the User Guide for details.
- Added demo program MouseDemo.hs
- Added demo program ProgressBarDemo.hs (thanks Kevin Quick)
- Added mapAttrname, mapAttrNames, and overrideAttr functions (thanks Kevin Quick)
- Make handleEventLensed polymorphic over event type to allow use with custom events (thanks Kevin Quick)
- Added Ord constraint to some library startup functions
- Added Show instance for Editor, List (fixes #63)
- Updated documentation to use new “resource name” terminology to reduce confusion and better explain the purpose of names.
- Updated user guide with sections on mouse support, the rendering cache, resource names, paste mode, and extents
- Depend on Vty 5.11.3 to get mouse mode support
- Added getVtyHandle in EventM for obtaining the current Vty context. It returns Nothing when calling the appStartEvent handler but after that a context is always available.
- Added a rendering cache. To use the rendering cache, use the ‘cached’ widget combinator. This causes drawings of the specified widget to re-use a cached rendering until the rendering cache is invalidated with ‘invalidateCacheEntry’ or ‘invalidateCache’. This change also includes programs/CacheDemo.hs. This change introduced an Ord constraint on the name type variable ‘n’.
- Added setTop and setLeft for setting viewport offsets directly in EventM.
- Dialog event handlers now support left and right arrow keys (thanks Grégoire Charvet)
- On resizes brick now draws the application twice before handling the resize event. This change makes it possible for event handlers to get the latest viewport states on a resize rather than getting the most recent (but stale) versions as before, at the cost of a second redraw.
- We now use the most recent rendering state when setting up event handler viewport data. This mostly won’t matter to anyone except in cases where a viewport name was expected to be in the viewport map but wasn’t due to using stale rendering state to set up EventM.
- Depend on text-zipper 0.7.1
- The editor widget state value is now polymorphic over the type of “string” value that can be edited, so you can now create editors over Text values as well as Strings. This is a breaking change but it only requires the addition of the string type variable to any uses of Editor. (thanks Jason Dagit and Getty Ritter)
- Added some missing Eq and Show instances (thanks Grégoire Charvet)
- The editor now binds Control-U to delete to beginning of line (thanks Hans-Peter Deifel)
- List: avoid runtime exception by ensuring item height is always at least 1
- Center: added layer-friendly centering functions centerLayer, hCenterLayer, and vCenterLayer.
- Dialog now uses new layer-friendly centering functions. This makes it possible to overlay a Dialog on top of your UI when you use a Dialog rendering as a separate layer.
- Updated the LayerDemo to demonstrate a centered layer.
- The renderer now uses a default Vty Picture background of spaces with the default attribute, rather than using ClearBackground (the Vty default). This is to compensate for an unexpected attribute behavior in Vty when ClearBackgrounds (see https://github.com/coreyoconnor/vty/issues/95)
NOTE: this release includes many API changes. Please see the “Widget Names” section of the Brick User Guide for details on the fundamentals!
- The “Name” type was removed. In its place we now have a name type
variable (“n”) attached to many types (including EventM,
CursorLocation, App, Editor, List, and FocusRing). This change makes
it possible to:
- Avoid runtime errors due to name typos
- Achieve compile-time guarantees about name matching and usage
- Force widget functions to be name-agnostic by being polymorphic in their name type
- Clean up focus handling by making it possible to pattern-match on cursor location names
- The EditDemo demonstration program was updated to use a FocusRing.
- Added the “Named” type class to Brick.Widgets.Core for types that store names. This type class is used to streamline the Focus interface; see Brick.Focus.withFocusRing and EditDemo.hs.
- The List and Editor types are now parameterized on names.
- The List widget is now focus-aware; its rendering function now takes
a boolean indicating whether it should be rendered with focus. The
List uses the following attributes now:
- When not focused, the cursor is rendered with listSelectedAttr.
- When focused, the cursor is rendered with listSelectedFocusedAttr.
- The Editor widget is now focus-aware; its rendering function now
takes a boolean indicating whether it should be rendered with focus.
The Editor uses the following attributes now:
- When not focused, the widget is rendered with editAttr.
- When focused, the widget is rendered with editFocusedAttr.
- The Dialog’s name constructor parameter and lens were removed.
- The ‘viewport’ function was modified to raise a runtime exception if the widget name it receives is used more than once during the rendering of a single frame.
- Many modules now use conditional imports to silence redundancy warnings on GHCs with newer Preludes (e.g. including Monoid, Foldable, Traversable, Applicative, etc.)
- Add missing Functor instance for Next type (thanks Markus Hauck)
- List: the list now properly renders when the available height is not a multiple of the item height. Previously the list size would decrease relative to the available height. Now the list renders enough items to fill the space even if the top-most or bottom-most item is partially visible, which is the expected behavior.
- Editor: the ‘editor’ initial content parameter is now correctly split on newlines to ensure that the underlying editor zipper is initialized properly. (fixes #56; thanks @listx)
- Added lower bound for microlens >= 0.3.0.0 to fix build failure due to Field1 not being defined (thanks Markus Hauck)
- Updated user guide and README to link to and mention microlens instead of lens
- Fixed a qualified import in the List demo to avoid ambiguity (thanks Alan Gilbert)
- Brick now uses the microlens family of packages instead of lens. This version of brick also depends on vty 5.5.0, which was modified to use microlens instead of lens. This change shouldn’t impact functionality but will greatly reduce build times.
- Fix negative cropping in hCenter, vCenter, and cropResultToContext (fixes #52)
- Remove unnecessary Eq constraint from listReplace (fixes #48; thanks sifmelcara)
- Mention Google Group in README
- Markup: make markup support multi-line strings (fixes #41)
- brick-edit-demo: support shift-tab to switch editors
- Core: improve box layout algorithm (when rendering boxes, track remaining space while rendering high-priority children to use successively more constrained primary dimensions)
- Core: make fixed padding take precedence over padded widgets (fixes #42) Prior to this commit, padding a widget meant that if there was room after rendering the widget, the specified amount of padding would be added. This meant that under tight layout constraints padding would disappear before a padded widget would. This is often a desirable outcome but it also led to unexpected behavior when adding padding to a widget that grows greedily: fixed padding would never show up because it was placed in a box adjacent to the widget in question, and boxes always render greedy children before fixed ones. As a result fixed padding would disappear under these conditions. Instead, in the case of fixed padding, since we often intend to guarantee that padding is present, all of the padding combinators have been modified so that when the padded widget is rendered with fixed padding in the amount V, the widget is given V fewer rows/columns when it is rendered so that the padding always has room.
- Fixed a bug in the ‘visible’ combinator: If the size of the visibility request was larger than the available space, then the rendering of a viewport was toggling between two states, one with aligning on the end of the visibility request, and another one aligning on the start. This commit fixes it so that a visibility request is always aligned on the start if not enough space is available. (thanks Thomas Strobel firstname.lastname@example.org)
- Honor multiple ‘visible’ markers in a single viewport with preference on the innermost request (thanks Thomas Strobel email@example.com)
- Added Brick.Widgets.Core.unsafeLookupViewport to make certain kinds of custom widget implementations easier when viewport states are needed (thanks Markus Hauck firstname.lastname@example.org)
- List: added listClear and listReverse functions (thanks Markus Hauck)
- List: Derive instances for Functor, Foldable, Traversable (thanks Markus Hauck)
- Hyperlink “Data.Text.Markup” inside Brick.Markup haddock (thanks Markus Hauck)
- Fix typo in ‘Attribute Management’ section of user guide (thanks Markus Hauck)
- EventM newtype again instances MonadIO (thanks Andrew Rademacher)
- Made EventM a newtype instead of a type alias
- List: listReplace now takes the new selected index and no longer does element diffing
- Removed the dependency on the Diff package
- Applied some hlint hints (thanks Markus Hauck email@example.com)
- Fixed a typo in the README (thanks Markus Hauck firstname.lastname@example.org)
- Improved the renderList documentation (thanks Profpatsch email@example.com)
- Types: added an explicit import of Applicative for older GHCs
- Fixed viewport behavior when the image in a viewport reduces its size enough to render the viewport offsets invalid. Before, this behavior caused a crash during image croppin in vty; now the behavior is handled sanely (fixes #22; reported by Hans-Peter Deifel)
- Improved the list demo by using characters instead of integers in the demo list and cleaned up item-adding code (thanks Jøhannes Lippmann firstname.lastname@example.org)
- Fixed size policy of lists so that rather than being Fixed/Fixed, they are Greedy/Greedy. This resolves issues that arise when the box layout widget renders a list widget alongside a Fixed/Fixed one. (Closes issue #17, thanks Karl Voelker)
- vScrollPage actually scrolls vertically now rather than horizontally (Thanks Hans-Peter Deifel email@example.com)
- Added top-level
Brickmodule that re-exports the most important modules in the library.
- Now instead of passing the item-drawing function to the
liststate constructor, it is passed to
renderListnow takes the row height of the list’s item widgets. The list item-drawing function must respect this in order for scrolling to work properly. This change made it possible to optimize the list so that it only draws widgets visible in the viewport rather than rendering all of the list’s items (even the ones off-screen). But to do this we must be able to tell in advance how high each one is, so we require this parameter. In addition this change means that lists no longer support items of different heights.
- The list now uses Data.Vector instead of [a] to store items; this permits efficient slicing so we can do the optimized rendering described above.
- Now instead of passing the item-drawing function to the
handleEventmethod now runs in
EventM. This permits event-handling code implemented in terms of
HandleEventto do get access to viewport state and to run IO code, making it just as powerful as code in the top-level
- Many types were moved from
Brick.Types, making the former module merely a home for
Widgetconstructors and combinators.
Widgetwas removed; this might be reinstated later, but this package provides enough
IsStringinstances that things can get confusing.
EventMis now reader monad over the most recent rendering pass’s viewport state, in addition to being a state monad over viewport requests for the renderer. Added the
lookupViewportfunction to provide access to the most recent viewport state. Exported the
Viewporttype and lenses.
- Now that
handleEventis now an
EventMaction, composition with
continueet al got a little messier when using lenses to update the application state. To help with this, there is now
- Lists now perform well with 10 items or a million (see above; fixes #7, thanks Simon Michael)
- Added more haddock notes to
Brick.Widgets.Coreabout growth policies.
- Forced evaluation of render states to address a space leak in the renderer (fixes #14, thanks Sebastian Reuße firstname.lastname@example.org)
- str: only reference string content that can be shown (eliminates a space leak, fixes #14, thanks Sebastian Reuße email@example.com)
- Added a makefile for the user guide.
- List: added support for Home and End keys (thanks Simon Michael)
- Viewports: when rendering viewports, scroll requests from
EventMare processed before visibility requests from the rendering process; this reverses this previous order of operations but permits user-supplied event handlers to reset viewports when desired.