reflex-vty

Reflex FRP host and widgets for VTY applications

Stackage Nightly 2026-06-28:1.1.0.0
Latest on Hackage:1.1.0.0

See all snapshots reflex-vty appears in

BSD-3-Clause licensed by Obsidian Systems LLC
Maintained by [email protected]
This version can be pinned in stack with:reflex-vty-1.1.0.0@sha256:7fc01120ccfe48d48a1b4d8ddf2cb9599cf99d211b087bd2d47164f109d07927,5596

reflex-vty

Build terminal user interfaces with functional reactive programming.

reflex-vty provides a Reflex FRP host and a library of reactive widgets for Vty terminal applications: layout, text input and editing, boxes, scrolling, mouse support, focus management, and theming.

Haskell Hackage Github CI Obsidian BSD3 License

A minimal app

{-# LANGUAGE OverloadedStrings #-}
module Main where

import Reflex.Vty

main :: IO ()
main = mainWidget def $ do
  text "Hello, reflex-vty! Press Ctrl+C to quit."
  ctrlc

mainWidget takes a VtyAppConfig (def for the defaults) and runs a widget until the Event t () it returns fires. Here that is ctrlc, which fires when the user presses Ctrl+C. Docs are available on Hackage.

Features

  • Layout: arrange widgets into rows and columns (tile / grout) with fixed or proportional (stretch) size constraints.
  • Focus: tab-cycling focus management across the focusable widgets in a layout (tabNavigation).
  • Text: word-wrapped text display, rich text with per-span attributes, and single- or multi-line text input backed by a zipper that handles wide characters, tabs, and wrapping.
  • Inputs: clickable buttons, hyperlinks, and checkboxes.
  • Boxes: single, thick, double, rounded, ASCII, inner-half, and outer-half border styles, with optional titles and horizontal rules.
  • Scrolling: scrollable containers with programmatic scrolling, auto-scroll-to-bottom mode, and a visual scrollbar with four visibility modes (always, thumb-only, while-scrolling, hidden).
  • Split panes: fixed horizontal and vertical splits, plus a mouse-draggable splitter you can resize at runtime (splitVDrag).
  • Mouse: button clicks, drags (with from/to/button/modifier tracking), scroll-wheel events, and last-known mouse-position tracking.
  • Keyboard: individual key and key-combo events, plus input filtering.
  • Runtime: alternate-screen mode, terminal cursor control (shape, visibility, and position), bracketed paste, terminal focus tracking, resize, and POSIX signal handling.
  • Theming: a Theme record with presets (default, dark, charm, dracula, nord, zenburn, gruvbox). Widgets inherit the ambient theme and can override locally.
  • Declarative styling: Lip Gloss-inspired Style type with foreground/background colors, text attributes (bold/italic/underline/etc.), padding, margin, borders with per-side colors, width/height constraints, alignment, text transforms, tab expansion, inline mode, whitespace coloring, and border presets.
  • Color: RGB color type, operations (darken, lighten, complementary, mix, alpha), and gradients (Gradient1D, Gradient2D).
  • Compositing: Reflex.Vty.Canvas module with per-cell transparency for overlays and layered rendering.
  • Image composition: joinHorizontal/joinVertical/place utilities for composing rendered images.
  • Color profiles: automatic terminal color-capability detection (TrueColor/Ansi256/Ansi16/Ascii/NoTTY) with downsampling.

Run the bundled demo with cabal run example to see many of these in action: a text editor, a to-do list, scrollable text, clickable buttons, a live CPU-usage display with a true-color gradient bar, a scrollbar-modes demo, a terminal-cursor demo, and a little styling showcase featuring gradients, color operations, a canvas overlay, border presets, theming, and color-profile downsampling.

Example gallery

Each of these examples is a module in src-bin/Example/. You can run any of them with cabal run examples -- <name>.

spinner — an animated braille spinner
progress — a gradient-filled progress bar
stopwatch — a tick-driven count-up timer
timer — a count-down timer
textinput — a focused text-input field
pager — a scrollable text viewport
views — toggle between two views

More demos: full-screen canvas animations (the classic Doom fire, a plasma field, a starfield, an animated splash) live on the examples page.

Feature requests, pull requests, and other feedback are welcome and appreciated (see the contribution guide).

How to Build

With reflex-platform

Enter a nix-shell for the project:

git clone https://github.com/reflex-frp/reflex-vty.git
cd reflex-vty
nix-shell

From within the nix-shell you can:

  • Run the example: cabal run example
  • Load the library in the repl: cabal repl reflex-vty
  • Build the example executable: cabal build example
  • Build the docs: cabal haddock
  • Run ghcid for immediate compiler feedback when you save a .hs file: ghcid -c "cabal repl library:reflex-vty executable:example test:reflex-vty-test --ghc-options=-Wall" -o ghcid-output.txt
  • etc.
Selecting a compiler

nix-shell defaults to GHC 9.8. The other compilers defined in release.nix are ghc94, ghc96, and ghc98. To enter a shell with one of them, pass it as the compiler argument:

nix-shell --argstr compiler ghc96

If you were previously building with a different compiler, you may need to run cabal clean first.

With cabal

Please see the tested-with field of the cabal file for known-compatible versions of GHC.

From the reflex-vty project directory:

# nix-shell -p cabal-install binutils icu # for nix users
cabal build          # to build the library, example, and test suite
cabal repl           # to enter a multi-repl covering all components
cabal repl example   # to enter a repl for the example executable only

About Obsidian Systems

reflex-vty is built and maintained by Obsidian Systems. We provide frontier engineering for high-assurance systems: we build production software in Haskell and Nix, and we’re long-time stewards of open-source tooling like Obelisk, Reflex, and nix-thunk.

If you’re working with Reflex, terminal or web UIs in Haskell, or Nix and want a partner to help design, build, or ship it, we’d love to hear from you.

License

reflex-vty is released under the BSD-3-Clause License, © 2018 Obsidian Systems LLC.

Changes

Revision history for reflex-vty

1.1.0.0

  • Breaking change: reflex-vty now builds on Windows. OS signals are handled through a platform-agnostic type called AppSignal. This changes VtyApp’s signal argument (Event t AppSignal instead of Event t Signal (synonym for CInt)).

1.0.0.1

  • Add some more examples, especially of the new canvas features

1.0.0.0

  • Breaking change: Add HasColorProfile class (with colorProfile/localColorProfile and a ColorProfileReader transformer) to Reflex.Vty.Widget. Widgets can call colorProfile to make decisions based on terminal capability.
  • Breaking change: CheckboxConfig._checkboxConfig_attributes removed; checkbox reads from HasTheme.
  • Breaking change: HasDisplayRegion now has askViewport and localLayoutRegion methods, separating layout height (inflated inside scrollable) from viewport height (real terminal size). Rendering widgets use viewportWidth/viewportHeight; layout system uses displayWidth/displayHeight.
  • Breaking change: HasTheme now has a structured Theme record (in Reflex.Vty.Theme) instead of Behavior t V.Attr. Use themeAttr to get the V.Attr, or theme for the full record.
  • Breaking change: Reflex.Vty.Style.render border attr now inherits from the content baseAttr instead of transparentAttr, so borders pick up themed foreground/background unless withBorderForeground/withBorderBackground is explicitly set.
  • Breaking change: Reflex.Vty.Style re-exports color constants (red/yellow/white/etc.) from Reflex.Vty.
  • Breaking change: ScrollableConfig has a new field _scrollableConfig_scrollbarVisibility :: ScrollbarVisibility.
  • Breaking change: TextInputConfig has a new field, _textInputConfig_alignment :: TextAlignment, controlling how entered text is aligned within the input region. def uses TextAlignment_Left.
  • Breaking change: boxTitle now takes a Behavior t TextAlignment as its first argument, controlling title alignment within the top border. Pass pure TextAlignment_Center to preserve the old behavior. box and boxStatic are unchanged.
  • Breaking change: scrollable and scrollableText now require PerformEvent t m, TriggerEvent t m, and MonadIO (Performable m) constraints (needed for ScrollbarWhileScrolling debounce).
  • Breaking change: Reflex.Vty.Host.runVtyAppWithHandle, runVtyApp, and Reflex.Vty.Widget.mainWidget/mainWidgetWithHandle now take a VtyAppConfig as their first argument. Use def (a Default instance) or defaultVtyAppConfig for the defaults. _vtyConfig_eventQueueCapacity configures the bounded event-queue capacity used to backpressure fast external producers.
  • Breaking change: Reflex.Vty.Widget.Input.Mouse.Drag replaces the _drag_end :: Bool field with _drag_state :: DragState, where DragState is DragStart | Dragging | DragEnd. This distinguishes the start of a drag from its continuation (#87). Migrate _drag_end d to _drag_state d == DragEnd. The pure state machine is now exposed as stepDrag for testing.
  • Add Reflex.Vty.Canvas module: per-cell compositing with transparency. Canvas type (sparse Map of cells), placeCanvas, translate, stack, imageToCanvas/canvasToImage conversions.
  • Add Reflex.Vty.ColorProfile module: ColorProfile datatype (TrueColor/Ansi256/Ansi16/Ascii/NoTTY), detectColorProfile/colorProfileFromVty to read the terminal’s capability from vty handle, convertColor for downsampling, and applyProfile to downsample an entire V.Attr (resets colors/style to Default for Ascii/NoTTY).
  • Add Reflex.Vty.Color module: RGB color type with darken, lighten, complementary, mix, alpha operations; Gradient1D (n-stop linear interpolation) and Gradient2D (bilinear corner interpolation); toRGB/fromRGB conversions to/from vty Color.
  • Add Reflex.Vty.Style.mergeAttr: overlay one V.Attr on another, where SetTo fields take precedence and Default/KeepCurrent fall through.
  • Add Reflex.Vty.Style border presets: innerHalfBorder (▀▄▌▐), outerHalfBlockBorder (▔▁▏▕).
  • Add Reflex.Vty.Style image composition: joinHorizontal, joinVertical, placeHorizontal, placeVertical, place.
  • Add Reflex.Vty.Style setters: withTransform (text transform), withTabWidth (tab expansion), withMarginBackground (colored margin), withInline (skip margin/padding/border), withColorWhitespace (toggle fill coloring), withBorderTopForeground/withBorderBottomBackground/etc (per-side border colors, 8 setters).
  • Add Reflex.Vty.Style text utilities: truncateWith (ellipsis truncation respecting display width), textHeight, textSize.
  • Add Reflex.Vty.Style: Lip Gloss-inspired declarative styling.
  • Add Reflex.Vty.Theme.darkTheme.
  • Add Reflex.Vty.Theme presets: charmTheme, draculaTheme, nordTheme, zenburnTheme, gruvboxTheme.
  • Add Reflex.Vty.Widget.Box.alignText, a general-purpose text alignment function.
  • Add Reflex.Vty.Widget.Text.textWithAlignment, an alignable version of text. text is now a synonym for textWithAlignment TextAlignment_Left.
  • Add visual scrollbar to Reflex.Vty.Widget.Scroll.scrollable with four visibility modes: ScrollbarAlways (gutter + thumb), ScrollbarThumbOnly (thumb only), ScrollbarWhileScrolling (thumb appears while scrolling, hides via debounce), ScrollbarHidden. Default is ScrollbarThumbOnly. Controlled via _scrollableConfig_scrollbarVisibility on ScrollableConfig.
  • Change Reflex.Vty.Theme.darkTheme: specify colors directly (green on black) instead of using reverseVideo.
  • Fix Reflex.Vty.Style.measure: uses textWidth (wcwidth) and splits on newlines for correct multi-line and wide-character dimensions.
  • Fix Reflex.Vty.Style.render: now handles multi-line text via V.vertCat per-line rendering.
  • Fix Reflex.Vty.Widget.Input.link: now uses _theme_link on ambient themeAttr instead of V.defAttr to preserve themed background.
  • Fix Reflex.Vty.Widget.Text.richText: now merges config attrs on themeAttr via mergeAttr, so RichTextConfig def inherits the ambient theme.
  • Fix textButton centering: now uses textWithAlignment TextAlignment_Center.
  • Fix textInput cursor: uses _theme_textInputCursor instead of hardcoded reverseVideo.
  • Fix Data.Text.Zipper.displayLinesWithAlignment: the cursor is now rendered as a blank highlighted cell when it sits past the last character of a line or on an empty line.
  • Fix space leak in Reflex.Vty.Host.runVtyAppWithHandle: an application that fired external triggers (e.g. a hot performEventAsync callback) faster than the host could process would grow the host’s event channel without limit. The host now backpressures producers via a bounded, closeable event queue, and drains every available batch each frame (firing each in its own Reflex frame, redrawing once), so memory is bounded and no event occurrences are dropped. The bounded capacity is configurable via the new VtyAppConfig (see the breaking-change entry above; default 4096).
  • Behavior change: external event triggers (performEventAsync, newTriggerEvent, etc.) may now block when the host’s event queue is full, throttling a producer that fires faster than the host can process to the host’s own rate. This is the intended flow-control; shutdown closes the queue so any blocked producer is released.
  • Debounce terminal resize events (50ms) to reduce lag and flicker during window drag.
  • Enable terminal focus tracking mode by default. Add gainedFocus and lostFocus helpers to Reflex.Vty.Widget.
  • Enable bracketed paste by default. Add paste helper to Reflex.Vty.Widget. textInput now handles paste events.
  • Add mousePosition helper to Reflex.Vty.Widget.Input.Mouse — tracks last known mouse coordinates from click/release events. True hover (motion without button) deferred — requires terminal mode 1003 which vty does not expose.
  • Add terminal cursor control: CursorStyle, CursorVisibility, CursorState, and the HasCursor capability with setCursor/tellCursor helpers.
  • Add alternate screen support: ScreenMode, setScreenMode, and the HasScreenMode capability with tellScreenMode/enterAlternateScreen/exitAlternateScreen helpers. The host restores normal screen on shutdown.
  • Breaking change: VtyApp now takes a third argument, Event t Signal, exposing POSIX signals (SIGINT, SIGTERM, SIGHUP). SIGINT and SIGTERM automatically trigger clean shutdown, replacing the old Ctrl-C key detection.
  • Install POSIX signal handlers (SIGINT, SIGTERM, SIGHUP) in runVtyAppWithHandle. Add unix dependency.

0.6.2.1

  • Update dependency version bounds

0.6.2.0

0.6.1.1

  • Extend version bounds
  • Add support for GHC 9.8.4

0.6.1.0

  • Fix mouse input translation in scrollable elements

0.6.0.0

  • Breaking Change: Reflex.Vty.Widget.Scroll.scrollable’s type has changed. The child widget no longer has to return images (see captureImages below), but can return a value. Specifically, the child widget type has gone from m (Behavior t Image, Event t ()) to m (Event t (), a).
  • Breaking Change: Instance of HasImageWriter must now implement captureImages, a function that allows the Images produced by a widget to be intercepted and not rendered. This is used to implement scrollable.

0.5.2.1

  • Extend version bounds

0.5.2.0

  • Update to use latest version of vty (for cross-platform support)
  • Fix an issue where the cursor tag is not used for an empty string in displayLineWithAlignment

0.5.1.0

  • Change inputInFocusedRegion to filter mouse scroll wheel input based on if the region under than the mouse rather than using mouse drag tracking
  • Add MonadCatch, MonadThrow, and MonadMask instances (relies on reflex-0.9.2.0 or greater)

0.5.0.0

  • Breaking change:
    • scrollableText now takes a ScrollableConfiguration instead of just an Event t Int of lines to scroll by. Replacing a scrollableText myEvent invocation with scrollableText (def { _scrollableConfig_scrollBy = myEvent }) should recover the old behavior.
    • scrollableText now returns a Scrollable t instead of a Behavior (Int, Int). The second Int, representing the total number of lines, is part of the Scrollable record. The first Int, representing the current scroll position is replaced by the ScrollPos in the Scrollable output. ScrollPos is a new type that captures whether a scrollableText is scrolled to the very top, very bottom, or somewhere in between.
  • scrollableText can now be given a starting scroll position and an event that scrolls it to a particular position.
  • scrollableText can be configured to remain scrolled to the bottom on new output, either always or whenever the user is scrolled to the bottom and new output appears.
  • Added a new scrollable widget in Reflex.Vty.Widget.Scroll that allows vertical scrolling when an Image is taller than the widget’s height.
  • Add ctrlc, a convenience function that returns an event that fires when a Ctrl+c keypress is detected
  • Fix several issues with wide chars, cursor position and word wrapping in Zipper.hs
  • Add centerText function to Reflex.Vty.Widget.Box

0.4.1.1

  • Support ghc-9.6

0.4.1.0

  • Loosen version bounds and support GHC 9.4.4
  • Add MonadHold t (Performable m) and MonadFix (Performable m) instances to MonadVtyApp

0.4.0.0

  • Breaking Changes:
    • Added mouse tracking to the behavior of pane such that
      • Mouse actions that start outside of the region are not tracked
      • Mouse drag sequences that start OFF the region are NOT reported
      • Mouse drag sequences that start ON the region and drag off ARE reported
      • Introduce MonadHold constraint to pane
    • Added MonadHold constraint to several methods that use pane

0.3.1.1

  • Loosen version bounds and support GHC 9.4

0.3.1.0

  • Replace mempty with defAttr for Attr from Graphics.Vty to make it compatible with vty-5.34

0.3.0.0

  • Re-design textInput, TextInput and TextInputConfig.
    • Allows users to implement more complex behavior.
    • _textInputConfig_modify is now applied to the text-value of textInput after user input events such as mouse clicks and keyboard input. This may change the observable behavior.

0.2.0.1

  • Loosen version bounds on ref-tf and vty

0.2.0.0

  • Module Reorganization: The following modules have been added (and are all re-exported by Reflex.Vty):
    • Reflex.Vty.Widget.Box for all the box functions and datatypes
    • Reflex.Vty.Widget.Input.Mouse for clicking, dragging, and scrolling
    • Reflex.Vty.Widget.Split contains splitV, splitH, etc
    • Reflex.Vty.Widget.Text contains text rendering functions like text and display
  • Bugfixes:
    • Remove text-icu dependency and switch to wcwidth from vty package to compute character width in Data.Text.Zipper.
    • goToDisplayLinePosition in Data.Text.Zipper correctly accounts for character width now.
    • #37 Layout should support focus changes through nested layouts (thanks @pdlla for getting this started – see entry on Layout and Focus below).
    • Fix distribution of available space when it cannot be evenly distributed. Previously, all leftover space would be allocated to the first stretchable widget.
  • Breaking Changes:
    • Layout and focus have been substantially refactored to fix #37 and support a wider variety of layouts and focus switching requirements.
      • Added a new HasFocus class (the old one is now HasFocusReader) to produce focusable elements, and manage focus state. See the “Focus” section of the Reflex.Vty.Widget.Layout module documentation.
      • Layout no longer has any focus-tracking responsibility. See the “Layout” section of the Reflex.Vty.Widget.Layout module documentation.
      • tile no longer takes a configuration record and no longer requires that its child widget return a focus request event. Focus requests are instead handled using calls to requestFocus in the child widget.
      • Calls to fixed and stretch must now be replaced with tile . fixed and tile . stretch
      • stretch now takes a minimum size argument
      • Added flex which is equivalent to stretch 0
      • tabNavigation no longer returns an Event. Instead it calls requestFocus directly with the appropriate Refocus_Shift value.
      • Added axis (in HasLayout), a lower-level primitive which is used to implement row and col.
      • Added region (in HasLayout), which is used to claim screen real estate and used to implement tile and grout
      • Added grout, a container element that is not itself focusable (though its children can be)
    • Removed VtyWidget and replaced it with a number of separate classes and monad transformers
      • Replace HasDisplaySize with HasDisplayRegion which carries around a region instead of just a width and height. displayWidth and displayHeight are now functions implemented in terms of askRegion instead of class methods.
      • Add a DisplayRegion monad transformer
      • Rename ImageWriter to HasImageWriter
      • Introduce an ImageWriter monad transformer
      • Rename HasFocus to HasFocusReader
      • Introduce a FocusReader monad transformer
      • Replace HasVtyInput with HasInput
      • Introduce an Input monad transformer
      • Introduce HasTheme reader class to allow setting Vty attributes of all built-in widgets
      • Introduce ThemeReader monad transformer
    • Remove DynRegion and currentRegion. Use Dynamic t Region and current instead. This also changes the type of pane’s argument.
    • CheckboxConfig now has a field taking an Event to set the value of the checkbox.
    • checkbox now accepts keyboard input (spacebar to check and uncheck) and is displayed in bold when focused.
    • HasInput (formerly HasVtyInput) now has a method localInput for filtering the input a child widget may receive
    • HasImageWriter now has a method mapImages for transforming the images emitted by a child widget
    • boxTitle now takes a Behavior t Text as its title, instead of a plain Text
    • fill now takes a Behavior t Char instead of a Char
    • The following functions are no longer specialized to VtyWidget:
      • pane: Now requires HasInput t m, HasImageWriter t m, HasDisplayRegion t m, HasFocusReader t m
      • drag: Now requires HasInput
      • mouseDown: Now requires HasInput
      • mouseUp: Now requires HasInput
      • mouseScroll: Now requires HasInput
      • key: Now requires HasInput
      • keys: Now requires HasInput
      • keyCombo: Now requires HasInput
      • keyCombos: Now requires HasInput
      • splitV: Now requires HasDisplayRegion t m, HasInput t m, HasImageWriter t m, HasFocusReader t m
      • splitH: Now requires HasDisplayRegion t m, HasInput t m, HasImageWriter t m, HasFocusReader t m
      • splitVDrag: Now requires HasDisplayRegion t m, HasInput t m, HasImageWriter t m, HasFocusReader t m
      • fill: Now requires HasImageWriter and HasDisplayRegion
      • boxTitle: Now requires HasDisplayRegion t m, HasImageWriter t m, HasInput t m, HasFocusReader t m, HasTheme t m
      • box: Now requires HasDisplayRegion t m, HasImageWriter t m, HasInput t m, HasFocusReader t m, HasTheme t m
      • boxStatic: Now requires HasDisplayRegion t m, HasImageWriter t m, HasInput t m, HasFocusReader t m, HasTheme t m
      • richText: Now requires HasImageWriter, and HasDisplayRegion
      • scrollableText: Now requires HasInput, HasImageWriter, HasTheme, and HasDisplayRegion
      • blank: Now requires Monad
      • button: Now requires HasFocusReader, HasInput, HasImageWriter, HasTheme, and HasDisplayRegion
      • textButton: Now requires HasFocusReader, HasInput, HasImageWriter, HasTheme, and HasDisplayRegion
      • textButtonStatic: Now requires HasFocusReader, HasInput, HasImageWriter, HasTheme, and HasDisplayRegion
      • link: Now requires HasInput, HasImageWriter, HasTheme, and HasDisplayRegion
      • checkbox: Now requires HasFocusReader, HasInput, HasImageWriter, and HasDisplayRegion
    • TextZipper interface changes
      • _displayLines_offsetMap type changed to OffsetMapWithAlignment
      • _displayLines_cursorY replaced with _displayLines_cursorPos which include X position
      • some exposed methods intended for internal use only have been removed
      • textInput: Now requires HasFocusReader, HasInput, HasImageWriter, HasTheme, and HasDisplayRegion
      • multilineTextInput: Now requires HasFocusReader, HasInput, HasImageWriter, HasTheme, and HasDisplayRegion
      • textInputTile: Now requires HasFocusReader, HasInput, HasLayout, HasTheme, and HasFocus
  • Misc:
    • (#40 Add alignment support to TextZipper)[https://github.com/reflex-frp/reflex-vty/pull/40]
      • Add alignment (left/center/right) support to TextZipper
      • Add basic unit tests for newly created alignment methods in TextZipper
    • Add default instances for HasInput, HasFocus, and HasImageWriter
    • Export withinImage and add imagesInRegion to crop images to a region
    • Add anyChildFocused, which provides information about whether subwidgets are focused
    • Add filterKeys, which is the same as localInput but only cares about keyboard events
    • Add hoistRunLayout to apply a transformation to the context of a Layout action and run that action
    • Add various MFunctor instances
    • Add a CPU usage indicator to the example executable

0.1.4.2

  • Wider bounds for GHC 8.10 support

0.1.4.1

0.1.4.1

  • Migrate to new dependent-sum / dependent-map (after the “some” package split)

0.1.4.0

  • (#15) Add PostBuild instance for Layout.
  • (#17) Add splitH to implement horizontal functionality of splitV.
  • (#19) Add boxTitle: a box with a title.
  • (#19) Update the text editing example to use boxTitle.
  • (#21) Fix bug in drag that caused dragging with different mouse button to trigger the click event.
  • (#22) Add support for GHC 8.8.

0.1.3.0

  • Add mouseScroll to capture scroll wheel events.
  • Add scrollableText: a text display widget that can be scrolled using the mouse or keyboard.
  • Add widget to the example executable that displays scrollable text.

0.1.2.1

  • Add keyCombo function (single-key-combination version of keyCombos).
  • Use upstream NotReady instances instead of orphans defined in this package if reflex-0.6.3 is available.

0.1.2.0

  • Allow TextZipper contents to be transformed before being displayed.
  • Fix bug in row orientation.
  • Handle wrapping of lines containing full-width unicode characters in textInput.

0.1.1.1

  • Bump minimum version of reflex.

0.1.1.0

  • Set version bounds in cabal file.
  • Add travis CI config.

0.1.0.0

  • Initial release