ghc-debug-brick-0.8.0.0: src/GHC/Debug/Brick/IOTree.hs
{-# LANGUAGE OverloadedStrings #-}
module GHC.Debug.Brick.IOTree where
import Brick
import qualified Data.List as List
import qualified Graphics.Vty as Vty
import Lens.Micro.Platform
import Data.Text (Text)
import qualified Data.Text as T
import Brick.Widgets.IOTree
import GHC.Debug.Brick.Lib as GD
import GHC.Debug.Brick.Namespace
import GHC.Debug.Brick.Render.Utils
mkIOTree :: Debuggee
-> [a]
-> (Debuggee -> a -> IO [a])
-> (a -> [Widget Name])
-> ([a] -> [a])
-> IOTree a Name
mkIOTree debuggee' cs getChildrenGen renderNode sort = ioTree Connected_Paused_ClosureTree
(sort cs)
(\c -> sort <$> getChildrenGen debuggee' c
)
-- rendering the row
(\state selected ctx depth closureDesc ->
let
body =
(if selected then visible . highlighted else id) $
hBox $
renderNode closureDesc
in
vdecorate state ctx depth body -- body (T.concat context)
)
-- | Draw the tree structure around the row item. Inspired by the
-- 'border' functions in brick.
--
vdecorate :: RowState -> RowCtx -> [RowCtx] -> Widget n -> Widget n
vdecorate state ctx depth body =
Widget Fixed Fixed $ do
c <- getContext
let decorationWidth = 2 * length depth + 4
bodyResult <-
render $
hLimit (c ^. availWidthL - decorationWidth) $
vLimit (c ^. availHeightL) $
body
let leftTxt =
T.concat $
map
(\ x -> case x of
LastRow -> " "
NotLastRow -> "│ "
)
(List.reverse depth)
leftPart = withAttr treeAttr (vreplicate leftTxt)
middleTxt1 =
case ctx of
LastRow -> "└─"
NotLastRow -> "├─"
middleTxt1' =
case ctx of
LastRow -> " "
NotLastRow -> "│ "
middleTxt2 =
case state of
Expanded True -> "● " -- "⋅"
Expanded False -> "┐ "
Collapsed -> "┄ "
middleTxt2' =
case state of
Expanded True -> " "
Expanded False -> "│ "
Collapsed -> " "
middlePart =
withAttr treeAttr $
(txt middleTxt1 <=> vreplicate middleTxt1')
<+> (txt middleTxt2 <=> vreplicate middleTxt2')
rightPart = Widget Fixed Fixed $ return bodyResult
total = leftPart <+> middlePart <+> rightPart
render $
hLimit (bodyResult ^. imageL . to Vty.imageWidth + decorationWidth) $
vLimit (bodyResult ^. imageL . to Vty.imageHeight) $
total
vreplicate :: Text -> Widget n
vreplicate t =
Widget Fixed Greedy $ do
c <- getContext
return $ emptyResult & imageL .~ Vty.vertCat (replicate (c ^. availHeightL) (Vty.text' (c ^. attrL) t))