packages feed

cursor-brick-0.1.0.1: src/Cursor/Brick/Text.hs

{-# LANGUAGE OverloadedStrings #-}

module Cursor.Brick.Text where

import Brick.Types as Brick
import Brick.Widgets.Core as Brick
import Cursor.Text
import Data.Text (Text)
import qualified Data.Text as T

-- | Make a text cursor widget with a blink-y box.
--
-- This function does not wrap the given text.
--
-- Otherwise, because of the way indexes work, there would be rendering errors for text that crosses the side of the terminal.
selectedTextCursorWidget :: n -> TextCursor -> Widget n
selectedTextCursorWidget n tc =
  Brick.showCursor n (Brick.Location (textCursorIndex tc, 0)) $
    textCursorWidget tc

-- | Make a text cursor widget without a blink-y box.
--
-- This function does not wrap the given text.
textCursorWidget :: TextCursor -> Widget n
textCursorWidget tc =
  txt $
    let t = sanitiseText $ rebuildTextCursor tc
     in if T.null t
          then " "
          else t

-- | Draw an arbitrary Text, it will be sanitised.
textWidget :: Text -> Widget n
textWidget = txt . nonNullLinesText . sanitiseText

-- | Draw an arbitrary Text (with wrapping), it will be sanitised.
textWidgetWrap :: Text -> Widget n
textWidgetWrap = txtWrap . nonNullLinesText . sanitiseText

-- | Draw an arbitrary single-line Text, it will be sanitised.
textLineWidget :: Text -> Widget n
textLineWidget = txt . nonNullText . sanitiseText

-- | Draw an arbitrary single-line Text (with wrapping), it will be sanitised.
textLineWidgetWrap :: Text -> Widget n
textLineWidgetWrap = txtWrap . nonNullText . sanitiseText

-- | Makes every line of a Text non-empty using `nonNullText`
nonNullLinesText :: Text -> Text
nonNullLinesText = T.intercalate "\n" . map nonNullText . T.splitOn "\n"

-- | Makes a text non-empty.
--
-- This turns the empty text into " " and leaves other text as-is.
nonNullText :: Text -> Text
nonNullText "" = " "
nonNullText t = t

-- | Replace tabs by spaces so that brick doesn't render nonsense.
--
-- See https://hackage.haskell.org/package/brick/docs/Brick-Widgets-Core.html#v:txt
sanitiseText :: Text -> Text
sanitiseText =
  T.map $ \c ->
    case c of
      '\t' -> ' '
      _ -> c