{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DeriveFunctor #-}
module Cursor.Forest
( ForestCursor(..)
, makeForestCursor
, rebuildForestCursor
, drawForestCursor
, mapForestCursor
, forestCursorListCursorL
, forestCursorSelectedTreeL
, forestCursorSelectPrevTreeCursor
, forestCursorSelectNextTreeCursor
, forestCursorSelectFirstTreeCursor
, forestCursorSelectLastTreeCursor
, forestCursorSelectPrev
, forestCursorSelectNext
, forestCursorSelectPrevOnSameLevel
, forestCursorSelectNextOnSameLevel
, forestCursorSelectFirst
, forestCursorSelectLast
, forestCursorSelectAbove
, forestCursorSelectBelowAtPos
, forestCursorSelectBelowAtStart
, forestCursorSelectBelowAtEnd
, forestCursorSelection
, forestCursorSelectIndex
, forestCursorOpenCurrentForest
, forestCursorCloseCurrentForest
, forestCursorToggleCurrentForest
, forestCursorOpenCurrentForestRecursively
, forestCursorToggleCurrentForestRecursively
, forestCursorInsertEntireTree
, forestCursorAppendEntireTree
, forestCursorInsertAndSelectTreeCursor
, forestCursorAppendAndSelectTreeCursor
, forestCursorInsertTree
, forestCursorAppendTree
, forestCursorInsertAndSelectTree
, forestCursorAppendAndSelectTree
, forestCursorInsert
, forestCursorAppend
, forestCursorInsertAndSelect
, forestCursorAppendAndSelect
, forestCursorAddChildTreeToNodeAtPos
, forestCursorAddChildTreeToNodeAtStart
, forestCursorAddChildTreeToNodeAtEnd
, forestCursorAddChildToNodeAtPos
, forestCursorAddChildToNodeAtStart
, forestCursorAddChildToNodeAtEnd
, forestCursorRemoveElemAndSelectPrev
, forestCursorDeleteElemAndSelectNext
, forestCursorRemoveElem
, forestCursorDeleteElem
, forestCursorRemoveSubTreeAndSelectPrev
, forestCursorDeleteSubTreeAndSelectNext
, forestCursorRemoveSubTree
, forestCursorDeleteSubTree
, forestCursorAddRoot
, forestCursorSwapPrev
, forestCursorSwapNext
, forestCursorPromoteElem
, forestCursorPromoteSubTree
, forestCursorDemoteElem
, forestCursorDemoteSubTree
, forestCursorDemoteElemUnder
, forestCursorDemoteSubTreeUnder
, CTree(..)
, makeCTree
, cTree
, rebuildCTree
, CForest(..)
, makeCForest
, cForest
, rebuildCForest
, traverseForestCursor
, foldForestCursor
) where
import GHC.Generics (Generic)
import Data.Validity
import Data.Validity.Tree ()
import Data.List.NonEmpty (NonEmpty)
import Data.Maybe
import Data.Tree
import Control.Applicative
import Lens.Micro
import Cursor.List.NonEmpty
import Cursor.Tree
import Cursor.Types
newtype ForestCursor a b =
ForestCursor
{ forestCursorListCursor :: NonEmptyCursor (TreeCursor a b) (CTree b)
}
deriving (Show, Eq, Generic)
instance (Validity a, Validity b) => Validity (ForestCursor a b)
makeForestCursor :: (b -> a) -> NonEmpty (CTree b) -> ForestCursor a b
makeForestCursor g = ForestCursor . makeNonEmptyCursor (makeTreeCursor g)
rebuildForestCursor :: (a -> b) -> ForestCursor a b -> NonEmpty (CTree b)
rebuildForestCursor f =
rebuildNonEmptyCursor (rebuildTreeCursor f) . forestCursorListCursor
drawForestCursor :: (Show a, Show b) => ForestCursor a b -> String
drawForestCursor ForestCursor {..} =
drawForest $
(map showCTree $ reverse $ nonEmptyCursorPrev forestCursorListCursor) ++
[treeCursorWithPointer $ nonEmptyCursorCurrent forestCursorListCursor] ++
(map showCTree $ nonEmptyCursorNext forestCursorListCursor)
mapForestCursor :: (a -> c) -> (b -> d) -> ForestCursor a b -> ForestCursor c d
mapForestCursor f g =
forestCursorListCursorL %~ mapNonEmptyCursor (mapTreeCursor f g) (fmap g)
forestCursorListCursorL ::
Lens (ForestCursor a b) (ForestCursor c d) (NonEmptyCursor (TreeCursor a b) (CTree b)) (NonEmptyCursor (TreeCursor c d) (CTree d))
forestCursorListCursorL =
lens forestCursorListCursor $ \fc lc -> fc {forestCursorListCursor = lc}
forestCursorSelectedTreeL :: Lens' (ForestCursor a b) (TreeCursor a b)
forestCursorSelectedTreeL = forestCursorListCursorL . nonEmptyCursorElemL
forestCursorSelectPrevTreeCursor ::
(a -> b) -> (b -> a) -> ForestCursor a b -> Maybe (ForestCursor a b)
forestCursorSelectPrevTreeCursor f g =
forestCursorListCursorL $
nonEmptyCursorSelectPrev (rebuildTreeCursor f) (makeTreeCursor g)
forestCursorSelectNextTreeCursor ::
(a -> b) -> (b -> a) -> ForestCursor a b -> Maybe (ForestCursor a b)
forestCursorSelectNextTreeCursor f g =
forestCursorListCursorL $
nonEmptyCursorSelectNext (rebuildTreeCursor f) (makeTreeCursor g)
forestCursorSelectFirstTreeCursor ::
(a -> b) -> (b -> a) -> ForestCursor a b -> ForestCursor a b
forestCursorSelectFirstTreeCursor f g =
forestCursorListCursorL %~
(nonEmptyCursorSelectFirst (rebuildTreeCursor f) (makeTreeCursor g))
forestCursorSelectLastTreeCursor ::
(a -> b) -> (b -> a) -> ForestCursor a b -> ForestCursor a b
forestCursorSelectLastTreeCursor f g =
forestCursorListCursorL %~
(nonEmptyCursorSelectLast (rebuildTreeCursor f) (makeTreeCursor g))
forestCursorSelectNext ::
(a -> b) -> (b -> a) -> ForestCursor a b -> Maybe (ForestCursor a b)
forestCursorSelectNext f g fc =
(fc & forestCursorSelectedTreeL (treeCursorSelectNext f g)) <|>
forestCursorSelectNextTreeCursor f g fc
forestCursorSelectPrev ::
(a -> b) -> (b -> a) -> ForestCursor a b -> Maybe (ForestCursor a b)
forestCursorSelectPrev f g fc =
(fc & forestCursorSelectedTreeL (treeCursorSelectPrev f g)) <|>
(forestCursorSelectPrevTreeCursor f g fc >>=
forestCursorSelectedTreeL (treeCursorSelectBelowAtEndRecursively f g)) <|>
(forestCursorSelectPrevTreeCursor f g fc)
forestCursorSelectNextOnSameLevel ::
(a -> b) -> (b -> a) -> ForestCursor a b -> Maybe (ForestCursor a b)
forestCursorSelectNextOnSameLevel f g fc =
(fc & forestCursorSelectedTreeL (treeCursorSelectNextOnSameLevel f g)) <|>
forestCursorSelectNextTreeCursor f g fc
forestCursorSelectPrevOnSameLevel ::
(a -> b) -> (b -> a) -> ForestCursor a b -> Maybe (ForestCursor a b)
forestCursorSelectPrevOnSameLevel f g fc =
(fc & forestCursorSelectedTreeL (treeCursorSelectPrevOnSameLevel f g)) <|>
forestCursorSelectPrevTreeCursor f g fc
forestCursorSelectFirst ::
(a -> b) -> (b -> a) -> ForestCursor a b -> ForestCursor a b
forestCursorSelectFirst f g fc =
case forestCursorSelectPrevTreeCursor f g fc of
Just fc' -> forestCursorSelectFirst f g fc'
Nothing ->
case forestCursorSelectPrev f g fc of
Just fc' -> forestCursorSelectFirst f g fc'
Nothing -> fc
forestCursorSelectLast ::
(a -> b) -> (b -> a) -> ForestCursor a b -> ForestCursor a b
forestCursorSelectLast f g fc =
case forestCursorSelectNextTreeCursor f g fc of
Just fc' -> forestCursorSelectLast f g fc'
Nothing ->
case forestCursorSelectNext f g fc of
Just fc' -> forestCursorSelectLast f g fc'
Nothing -> fc
forestCursorSelectAbove ::
(a -> b) -> (b -> a) -> ForestCursor a b -> Maybe (ForestCursor a b)
forestCursorSelectAbove f g =
forestCursorSelectedTreeL $ treeCursorSelectAbove f g
forestCursorSelectBelowAtPos ::
(a -> b) -> (b -> a) -> Int -> ForestCursor a b -> Maybe (ForestCursor a b)
forestCursorSelectBelowAtPos f g i =
forestCursorSelectedTreeL $ treeCursorSelectBelowAtPos f g i
forestCursorSelectBelowAtStart ::
(a -> b) -> (b -> a) -> ForestCursor a b -> Maybe (ForestCursor a b)
forestCursorSelectBelowAtStart f g =
forestCursorSelectedTreeL $ treeCursorSelectBelowAtStart f g
forestCursorSelectBelowAtEnd ::
(a -> b) -> (b -> a) -> ForestCursor a b -> Maybe (ForestCursor a b)
forestCursorSelectBelowAtEnd f g =
forestCursorSelectedTreeL $ treeCursorSelectBelowAtEnd f g
forestCursorSelection :: ForestCursor a b -> Int
forestCursorSelection fc =
nonEmptyCursorSelection $ fc ^. forestCursorListCursorL
forestCursorSelectIndex ::
(a -> b) -> (b -> a) -> Int -> ForestCursor a b -> Maybe (ForestCursor a b)
forestCursorSelectIndex f g i =
forestCursorListCursorL
(nonEmptyCursorSelectIndex (rebuildTreeCursor f) (makeTreeCursor g) i)
forestCursorOpenCurrentForest :: ForestCursor a b -> Maybe (ForestCursor a b)
forestCursorOpenCurrentForest =
forestCursorSelectedTreeL treeCursorOpenCurrentForest
forestCursorCloseCurrentForest :: ForestCursor a b -> Maybe (ForestCursor a b)
forestCursorCloseCurrentForest =
forestCursorSelectedTreeL treeCursorCloseCurrentForest
forestCursorToggleCurrentForest :: ForestCursor a b -> Maybe (ForestCursor a b)
forestCursorToggleCurrentForest =
forestCursorSelectedTreeL treeCursorToggleCurrentForest
forestCursorOpenCurrentForestRecursively ::
ForestCursor a b -> Maybe (ForestCursor a b)
forestCursorOpenCurrentForestRecursively =
forestCursorSelectedTreeL treeCursorOpenCurrentForestRecursively
forestCursorToggleCurrentForestRecursively ::
ForestCursor a b -> Maybe (ForestCursor a b)
forestCursorToggleCurrentForestRecursively =
forestCursorSelectedTreeL treeCursorToggleCurrentForestRecursively
forestCursorInsertEntireTree :: Tree b -> ForestCursor a b -> ForestCursor a b
forestCursorInsertEntireTree t =
forestCursorListCursorL %~ nonEmptyCursorInsert (makeCTree t)
forestCursorInsertAndSelectTreeCursor ::
(a -> b) -> TreeCursor a b -> ForestCursor a b -> ForestCursor a b
forestCursorInsertAndSelectTreeCursor f tc =
forestCursorListCursorL %~
nonEmptyCursorInsertAndSelect (rebuildTreeCursor f) tc
forestCursorAppendEntireTree :: Tree b -> ForestCursor a b -> ForestCursor a b
forestCursorAppendEntireTree t =
forestCursorListCursorL %~ nonEmptyCursorAppend (makeCTree t)
forestCursorAppendAndSelectTreeCursor ::
(a -> b) -> TreeCursor a b -> ForestCursor a b -> ForestCursor a b
forestCursorAppendAndSelectTreeCursor f tc =
forestCursorListCursorL %~
nonEmptyCursorAppendAndSelect (rebuildTreeCursor f) tc
forestCursorInsertTree :: Tree b -> ForestCursor a b -> ForestCursor a b
forestCursorInsertTree t fc =
fromMaybe (forestCursorInsertEntireTree t fc) $
fc & forestCursorSelectedTreeL (treeCursorInsert t)
forestCursorInsertAndSelectTree ::
(a -> b) -> (b -> a) -> Tree b -> ForestCursor a b -> ForestCursor a b
forestCursorInsertAndSelectTree f g t fc =
fromMaybe
(forestCursorInsertAndSelectTreeCursor f (makeTreeCursor g $ makeCTree t) fc) $
fc & forestCursorSelectedTreeL (treeCursorInsertAndSelect f g t)
forestCursorAppendTree :: Tree b -> ForestCursor a b -> ForestCursor a b
forestCursorAppendTree t fc =
fromMaybe (forestCursorAppendEntireTree t fc) $
fc & forestCursorSelectedTreeL (treeCursorAppend t)
forestCursorAppendAndSelectTree ::
(a -> b) -> (b -> a) -> Tree b -> ForestCursor a b -> ForestCursor a b
forestCursorAppendAndSelectTree f g t fc =
fromMaybe
(forestCursorAppendAndSelectTreeCursor f (makeTreeCursor g $ makeCTree t) fc) $
fc & forestCursorSelectedTreeL (treeCursorAppendAndSelect f g t)
forestCursorInsert :: b -> ForestCursor a b -> ForestCursor a b
forestCursorInsert b = forestCursorInsertTree $ Node b []
forestCursorInsertAndSelect ::
(a -> b) -> (b -> a) -> b -> ForestCursor a b -> ForestCursor a b
forestCursorInsertAndSelect f g b =
forestCursorInsertAndSelectTree f g $ Node b []
forestCursorAppend :: b -> ForestCursor a b -> ForestCursor a b
forestCursorAppend b = forestCursorAppendTree $ Node b []
forestCursorAppendAndSelect ::
(a -> b) -> (b -> a) -> b -> ForestCursor a b -> ForestCursor a b
forestCursorAppendAndSelect f g b =
forestCursorAppendAndSelectTree f g $ Node b []
forestCursorAddChildTreeToNodeAtPos ::
Int -> Tree b -> ForestCursor a b -> ForestCursor a b
forestCursorAddChildTreeToNodeAtPos i t =
forestCursorSelectedTreeL %~ treeCursorAddChildAtPos i t
forestCursorAddChildTreeToNodeAtStart ::
Tree b -> ForestCursor a b -> ForestCursor a b
forestCursorAddChildTreeToNodeAtStart t =
forestCursorSelectedTreeL %~ treeCursorAddChildAtStart t
forestCursorAddChildTreeToNodeAtEnd ::
Tree b -> ForestCursor a b -> ForestCursor a b
forestCursorAddChildTreeToNodeAtEnd t fc =
fc & forestCursorSelectedTreeL %~ treeCursorAddChildAtEnd t
forestCursorAddChildToNodeAtPos ::
Int -> b -> ForestCursor a b -> ForestCursor a b
forestCursorAddChildToNodeAtPos i b =
forestCursorAddChildTreeToNodeAtPos i $ Node b []
forestCursorAddChildToNodeAtStart :: b -> ForestCursor a b -> ForestCursor a b
forestCursorAddChildToNodeAtStart b =
forestCursorAddChildTreeToNodeAtStart $ Node b []
forestCursorAddChildToNodeAtEnd :: b -> ForestCursor a b -> ForestCursor a b
forestCursorAddChildToNodeAtEnd b =
forestCursorAddChildTreeToNodeAtEnd $ Node b []
forestCursorRemoveElemAndSelectPrev ::
(b -> a) -> ForestCursor a b -> Maybe (DeleteOrUpdate (ForestCursor a b))
forestCursorRemoveElemAndSelectPrev g fc =
case (fc &
focusPossibleDeleteOrUpdate
forestCursorSelectedTreeL
(treeCursorDeleteElemAndSelectPrevious g)) of
Just Deleted ->
(fc &
focusPossibleDeleteOrUpdate
forestCursorListCursorL
(nonEmptyCursorRemoveElemAndSelectPrev (makeTreeCursor g)))
r -> r
forestCursorDeleteElemAndSelectNext ::
(b -> a) -> ForestCursor a b -> Maybe (DeleteOrUpdate (ForestCursor a b))
forestCursorDeleteElemAndSelectNext g fc =
case (fc &
focusPossibleDeleteOrUpdate
forestCursorSelectedTreeL
(treeCursorDeleteElemAndSelectNext g)) of
Just Deleted ->
(fc &
focusPossibleDeleteOrUpdate
forestCursorListCursorL
(nonEmptyCursorDeleteElemAndSelectNext (makeTreeCursor g)))
r -> r
forestCursorRemoveElem ::
(b -> a) -> ForestCursor a b -> DeleteOrUpdate (ForestCursor a b)
forestCursorRemoveElem g fc =
(fc & forestCursorSelectedTreeL (treeCursorRemoveElem g)) <|>
(fc & forestCursorListCursorL (nonEmptyCursorRemoveElem (makeTreeCursor g)))
forestCursorDeleteElem ::
(b -> a) -> ForestCursor a b -> DeleteOrUpdate (ForestCursor a b)
forestCursorDeleteElem g fc =
(fc & forestCursorSelectedTreeL (treeCursorDeleteElem g)) <|>
(fc & forestCursorListCursorL (nonEmptyCursorDeleteElem (makeTreeCursor g)))
forestCursorRemoveSubTreeAndSelectPrev ::
(b -> a) -> ForestCursor a b -> Maybe (DeleteOrUpdate (ForestCursor a b))
forestCursorRemoveSubTreeAndSelectPrev g fc =
joinPossibleDeletes
(fc &
focusPossibleDeleteOrUpdate
forestCursorSelectedTreeL
(treeCursorDeleteSubTreeAndSelectPrevious g))
(fc &
focusPossibleDeleteOrUpdate
forestCursorListCursorL
(nonEmptyCursorRemoveElemAndSelectPrev (makeTreeCursor g)))
forestCursorDeleteSubTreeAndSelectNext ::
(b -> a) -> ForestCursor a b -> Maybe (DeleteOrUpdate (ForestCursor a b))
forestCursorDeleteSubTreeAndSelectNext g fc =
joinPossibleDeletes
(fc &
focusPossibleDeleteOrUpdate
forestCursorSelectedTreeL
(treeCursorDeleteSubTreeAndSelectNext g))
(fc &
focusPossibleDeleteOrUpdate
forestCursorListCursorL
(nonEmptyCursorDeleteElemAndSelectNext (makeTreeCursor g)))
forestCursorRemoveSubTree ::
(b -> a) -> ForestCursor a b -> DeleteOrUpdate (ForestCursor a b)
forestCursorRemoveSubTree g fc =
(fc & forestCursorSelectedTreeL (treeCursorRemoveSubTree g)) <|>
(fc & forestCursorListCursorL (nonEmptyCursorRemoveElem (makeTreeCursor g)))
forestCursorDeleteSubTree ::
(b -> a) -> ForestCursor a b -> DeleteOrUpdate (ForestCursor a b)
forestCursorDeleteSubTree g fc =
(fc & forestCursorSelectedTreeL (treeCursorDeleteSubTree g)) <|>
(fc & forestCursorListCursorL (nonEmptyCursorDeleteElem (makeTreeCursor g)))
forestCursorAddRoot ::
(a -> b) -> (b -> a) -> ForestCursor a b -> a -> TreeCursor a b
forestCursorAddRoot f g fc v =
makeTreeCursor g $ CNode (f v) $ OpenForest $ rebuildForestCursor f fc
forestCursorSwapPrev :: ForestCursor a b -> Maybe (ForestCursor a b)
forestCursorSwapPrev fc@(ForestCursor ne) =
case fc & forestCursorSelectedTreeL treeCursorSwapPrev of
Swapped fc' -> pure fc'
NoSiblingsToSwapWith -> Nothing
SwapperIsTopNode ->
case nonEmptyCursorPrev ne of
[] -> Nothing
(t:ts) ->
pure $
ForestCursor
ne
{ nonEmptyCursorPrev = ts
, nonEmptyCursorNext = t : nonEmptyCursorNext ne
}
forestCursorSwapNext :: ForestCursor a b -> Maybe (ForestCursor a b)
forestCursorSwapNext fc@(ForestCursor ne) =
case fc & forestCursorSelectedTreeL treeCursorSwapNext of
Swapped fc' -> pure fc'
NoSiblingsToSwapWith -> Nothing
SwapperIsTopNode ->
case nonEmptyCursorNext ne of
[] -> Nothing
(t:ts) ->
pure $
ForestCursor
ne
{ nonEmptyCursorPrev = t : nonEmptyCursorPrev ne
, nonEmptyCursorNext = ts
}
forestCursorPromoteElem ::
(a -> b) -> (b -> a) -> ForestCursor a b -> Maybe (ForestCursor a b)
forestCursorPromoteElem f g fc@(ForestCursor ne) =
case fc & forestCursorSelectedTreeL (treeCursorPromoteElem f g) of
PromotedElem fc' -> pure fc'
CannotPromoteTopElem -> Nothing
NoSiblingsToAdoptChildren -> Nothing
NoGrandparentToPromoteElemUnder -> do
let tc = fc ^. forestCursorSelectedTreeL
ta <- treeAbove tc
lefts <-
case (treeBelow tc) of
EmptyCForest -> pure $ treeAboveLefts ta
_ ->
case treeAboveLefts ta of
[] -> Nothing
(CNode t ls:ts) ->
pure $
CNode
t
(openForest $ unpackCForest ls ++ unpackCForest (treeBelow tc)) :
ts
let ta' = ta {treeAboveLefts = lefts}
let tc' = tc {treeAbove = Just ta'}
tc'' <-
case treeCursorDeleteSubTree g tc' of
Deleted -> Nothing
Updated tc'' -> pure tc''
pure $
ForestCursor $
ne
{ nonEmptyCursorPrev =
rebuildTreeCursor f tc'' : nonEmptyCursorPrev ne
, nonEmptyCursorCurrent =
singletonTreeCursor $
treeCurrent $ fc ^. forestCursorSelectedTreeL
}
forestCursorPromoteSubTree ::
(a -> b) -> (b -> a) -> ForestCursor a b -> Maybe (ForestCursor a b)
forestCursorPromoteSubTree f g fc@(ForestCursor ne) =
case fc & forestCursorSelectedTreeL (treeCursorPromoteSubTree f g) of
Promoted fc' -> pure fc'
CannotPromoteTopNode -> Nothing
NoGrandparentToPromoteUnder ->
case treeCursorDeleteSubTree g $ fc ^. forestCursorSelectedTreeL of
Deleted -> Nothing
Updated tc' ->
pure $
ForestCursor $
ne
{ nonEmptyCursorPrev =
rebuildTreeCursor f tc' : nonEmptyCursorPrev ne
, nonEmptyCursorCurrent =
(fc ^. forestCursorSelectedTreeL) {treeAbove = Nothing}
}
forestCursorDemoteElem ::
(a -> b) -> (b -> a) -> ForestCursor a b -> Maybe (ForestCursor a b)
forestCursorDemoteElem f g fc@(ForestCursor ne) =
case (fc & forestCursorSelectedTreeL (treeCursorDemoteElem f g)) of
Demoted fc' -> pure fc'
CannotDemoteTopNode ->
case nonEmptyCursorPrev ne of
[] -> Nothing
(CNode v vts:ts) -> do
let CNode v' vts' =
rebuildTreeCursor f (fc ^. forestCursorSelectedTreeL)
let n' =
CNode v $
openForest $
unpackCForest vts ++
(CNode v' emptyCForest) : unpackCForest vts'
tc <-
makeTreeCursorWithSelection
f
g
(SelectChild (lengthCForest vts) SelectNode)
n'
pure $
ForestCursor
ne {nonEmptyCursorPrev = ts, nonEmptyCursorCurrent = tc}
NoSiblingsToDemoteUnder -> Nothing
forestCursorDemoteSubTree ::
(a -> b) -> (b -> a) -> ForestCursor a b -> Maybe (ForestCursor a b)
forestCursorDemoteSubTree f g fc@(ForestCursor ne) =
case fc & forestCursorSelectedTreeL (treeCursorDemoteSubTree f g) of
Demoted fc' -> pure fc'
CannotDemoteTopNode ->
case nonEmptyCursorPrev ne of
[] -> Nothing
(CNode v vts:ts) -> do
let n' =
CNode v $
openForest $
unpackCForest vts ++
[rebuildTreeCursor f (fc ^. forestCursorSelectedTreeL)]
tc <-
makeTreeCursorWithSelection
f
g
(SelectChild (lengthCForest vts) SelectNode)
n'
pure $
ForestCursor
ne {nonEmptyCursorPrev = ts, nonEmptyCursorCurrent = tc}
NoSiblingsToDemoteUnder -> Nothing
forestCursorDemoteElemUnder :: b -> b -> ForestCursor a b -> ForestCursor a b
forestCursorDemoteElemUnder b1 b2 fc@(ForestCursor ne) =
case fc & forestCursorSelectedTreeL (treeCursorDemoteElemUnder b1 b2) of
Just fc' -> fc'
Nothing ->
let t = fc ^. forestCursorSelectedTreeL
in ForestCursor $
ne
{ nonEmptyCursorCurrent =
TreeCursor
{ treeAbove =
Just
TreeAbove
{ treeAboveLefts = []
, treeAboveAbove = Nothing
, treeAboveNode = b1
, treeAboveRights = []
}
, treeCurrent = treeCurrent t
, treeBelow = emptyCForest
}
, nonEmptyCursorNext =
CNode b2 (treeBelow t) : nonEmptyCursorNext ne
}
forestCursorDemoteSubTreeUnder :: b -> ForestCursor a b -> ForestCursor a b
forestCursorDemoteSubTreeUnder b =
forestCursorSelectedTreeL %~ treeCursorDemoteSubTreeUnder b
traverseForestCursor ::
([CTree b] -> TreeCursor a b -> [CTree b] -> f c)
-> ForestCursor a b
-> f c
traverseForestCursor = foldForestCursor
foldForestCursor ::
([CTree b] -> TreeCursor a b -> [CTree b] -> c) -> ForestCursor a b -> c
foldForestCursor func (ForestCursor ne) = foldNonEmptyCursor func ne