packages feed

cursor 0.3.0.0 → 0.3.1.0

raw patch · 28 files changed

+1739/−1183 lines, 28 filessetup-changedPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Cursor.Forest: forestCursorAddChildNodeSingleToNodeAtEndAndSelect :: (a -> b) -> a -> ForestCursor a b -> ForestCursor a b
+ Cursor.Forest: forestCursorAddChildNodeSingleToNodeAtPosAndSelect :: (a -> b) -> Int -> a -> ForestCursor a b -> ForestCursor a b
+ Cursor.Forest: forestCursorAddChildNodeSingleToNodeAtStartAndSelect :: (a -> b) -> a -> ForestCursor a b -> ForestCursor a b
+ Cursor.Forest: forestCursorAddChildNodeToNodeAtEndAndSelect :: (a -> b) -> a -> Forest b -> ForestCursor a b -> ForestCursor a b
+ Cursor.Forest: forestCursorAddChildNodeToNodeAtPosAndSelect :: (a -> b) -> Int -> a -> Forest b -> ForestCursor a b -> ForestCursor a b
+ Cursor.Forest: forestCursorAddChildNodeToNodeAtStartAndSelect :: (a -> b) -> a -> Forest b -> ForestCursor a b -> ForestCursor a b
+ Cursor.Forest: forestCursorAddChildToNodeAtEndAndSelect :: (a -> b) -> (b -> a) -> b -> ForestCursor a b -> ForestCursor a b
+ Cursor.Forest: forestCursorAddChildToNodeAtPosAndSelect :: (a -> b) -> (b -> a) -> Int -> b -> ForestCursor a b -> ForestCursor a b
+ Cursor.Forest: forestCursorAddChildToNodeAtStartAndSelect :: (a -> b) -> (b -> a) -> b -> ForestCursor a b -> ForestCursor a b
+ Cursor.Forest: forestCursorAddChildTreeToNodeAtEndAndSelect :: (a -> b) -> (b -> a) -> Tree b -> ForestCursor a b -> ForestCursor a b
+ Cursor.Forest: forestCursorAddChildTreeToNodeAtPosAndSelect :: (a -> b) -> (b -> a) -> Int -> Tree b -> ForestCursor a b -> ForestCursor a b
+ Cursor.Forest: forestCursorAddChildTreeToNodeAtStartAndSelect :: (a -> b) -> (b -> a) -> Tree b -> ForestCursor a b -> ForestCursor a b
+ Cursor.Forest: forestCursorAppendNodeAndSelect :: (a -> b) -> a -> CForest b -> ForestCursor a b -> ForestCursor a b
+ Cursor.Forest: forestCursorAppendNodeSingleAndSelect :: (a -> b) -> a -> ForestCursor a b -> ForestCursor a b
+ Cursor.Forest: forestCursorInsertNodeAndSelect :: (a -> b) -> a -> CForest b -> ForestCursor a b -> ForestCursor a b
+ Cursor.Forest: forestCursorInsertNodeSingleAndSelect :: (a -> b) -> a -> ForestCursor a b -> ForestCursor a b
+ Cursor.Forest: forestCursorSelectFirstOnSameLevel :: (a -> b) -> (b -> a) -> ForestCursor a b -> ForestCursor a b
+ Cursor.Forest: forestCursorSelectLastOnSameLevel :: (a -> b) -> (b -> a) -> ForestCursor a b -> ForestCursor a b
+ Cursor.Forest: singletonForestCursor :: a -> ForestCursor a b
+ Cursor.List: listCursorAppendList :: [a] -> ListCursor a -> ListCursor a
+ Cursor.List: listCursorInsertList :: [a] -> ListCursor a -> ListCursor a
+ Cursor.List: listCursorNextUntil :: (a -> Bool) -> ListCursor a -> ListCursor a
+ Cursor.List: listCursorPrevUntil :: (a -> Bool) -> ListCursor a -> ListCursor a
+ Cursor.Map: mapCursorElemSelection :: MapCursor kc vc k v -> KeyValueToggle
+ Cursor.Map: mapCursorTraverseKeyCase :: Applicative f => (kc -> v -> f (kc', v)) -> MapCursor kc vc k v -> f (MapCursor kc' vc k v)
+ Cursor.Map: mapCursorTraverseValueCase :: Applicative f => (k -> vc -> f (k, vc')) -> MapCursor kc vc k v -> f (MapCursor kc vc' k v)
+ Cursor.Map.KeyValue: keyValueCursorTraverseKeyCase :: Applicative f => (kc -> v -> f (kc', v')) -> KeyValueCursor kc vc k v -> f (KeyValueCursor kc' vc k v')
+ Cursor.Map.KeyValue: keyValueCursorTraverseValueCase :: Applicative f => (k -> vc -> f (k', vc')) -> KeyValueCursor kc vc k v -> f (KeyValueCursor kc vc' k' v)
+ Cursor.Simple.Forest: forestCursorAddChildNodeSingleToNodeAtEndAndSelect :: a -> ForestCursor a -> ForestCursor a
+ Cursor.Simple.Forest: forestCursorAddChildNodeSingleToNodeAtPosAndSelect :: Int -> a -> ForestCursor a -> ForestCursor a
+ Cursor.Simple.Forest: forestCursorAddChildNodeSingleToNodeAtStartAndSelect :: a -> ForestCursor a -> ForestCursor a
+ Cursor.Simple.Forest: forestCursorAddChildNodeToNodeAtEndAndSelect :: a -> Forest a -> ForestCursor a -> ForestCursor a
+ Cursor.Simple.Forest: forestCursorAddChildNodeToNodeAtPosAndSelect :: Int -> a -> Forest a -> ForestCursor a -> ForestCursor a
+ Cursor.Simple.Forest: forestCursorAddChildNodeToNodeAtStartAndSelect :: a -> Forest a -> ForestCursor a -> ForestCursor a
+ Cursor.Simple.Forest: forestCursorAddChildToNodeAtEndAndSelect :: a -> ForestCursor a -> ForestCursor a
+ Cursor.Simple.Forest: forestCursorAddChildToNodeAtPosAndSelect :: Int -> a -> ForestCursor a -> ForestCursor a
+ Cursor.Simple.Forest: forestCursorAddChildToNodeAtStartAndSelect :: a -> ForestCursor a -> ForestCursor a
+ Cursor.Simple.Forest: forestCursorAddChildTreeToNodeAtEndAndSelect :: Tree a -> ForestCursor a -> ForestCursor a
+ Cursor.Simple.Forest: forestCursorAddChildTreeToNodeAtPosAndSelect :: Int -> Tree a -> ForestCursor a -> ForestCursor a
+ Cursor.Simple.Forest: forestCursorAddChildTreeToNodeAtStartAndSelect :: Tree a -> ForestCursor a -> ForestCursor a
+ Cursor.Simple.Forest: forestCursorAppendNodeAndSelect :: a -> CForest a -> ForestCursor a -> ForestCursor a
+ Cursor.Simple.Forest: forestCursorAppendNodeSingleAndSelect :: a -> ForestCursor a -> ForestCursor a
+ Cursor.Simple.Forest: forestCursorInsertNodeAndSelect :: a -> CForest a -> ForestCursor a -> ForestCursor a
+ Cursor.Simple.Forest: forestCursorInsertNodeSingleAndSelect :: a -> ForestCursor a -> ForestCursor a
+ Cursor.Simple.Forest: forestCursorSelectFirstOnSameLevel :: ForestCursor a -> ForestCursor a
+ Cursor.Simple.Forest: forestCursorSelectLastOnSameLevel :: ForestCursor a -> ForestCursor a
+ Cursor.Simple.Forest: singletonForestCursor :: a -> ForestCursor a b
+ Cursor.Simple.Tree: makeNodeTreeCursor :: a -> CForest b -> TreeCursor a b
+ Cursor.Simple.Tree: treeCursorAddChildAtEndAndSelect :: Tree a -> TreeCursor a -> TreeCursor a
+ Cursor.Simple.Tree: treeCursorAddChildAtPosAndSelect :: Int -> Tree a -> TreeCursor a -> TreeCursor a
+ Cursor.Simple.Tree: treeCursorAddChildAtStartAndSelect :: Tree a -> TreeCursor a -> TreeCursor a
+ Cursor.Simple.Tree: treeCursorAddChildNodeAtEndAndSelect :: a -> Forest a -> TreeCursor a -> TreeCursor a
+ Cursor.Simple.Tree: treeCursorAddChildNodeAtPosAndSelect :: Int -> a -> Forest a -> TreeCursor a -> TreeCursor a
+ Cursor.Simple.Tree: treeCursorAddChildNodeAtStartAndSelect :: a -> Forest a -> TreeCursor a -> TreeCursor a
+ Cursor.Simple.Tree: treeCursorAddChildNodeSingleAtEndAndSelect :: a -> TreeCursor a -> TreeCursor a
+ Cursor.Simple.Tree: treeCursorAddChildNodeSingleAtPosAndSelect :: Int -> a -> TreeCursor a -> TreeCursor a
+ Cursor.Simple.Tree: treeCursorAddChildNodeSingleAtStartAndSelect :: a -> TreeCursor a -> TreeCursor a
+ Cursor.Simple.Tree: treeCursorAppendNodeAndSelect :: a -> CForest a -> TreeCursor a -> Maybe (TreeCursor a)
+ Cursor.Simple.Tree: treeCursorAppendNodeSingleAndSelect :: a -> TreeCursor a -> Maybe (TreeCursor a)
+ Cursor.Simple.Tree: treeCursorInsertNodeAndSelect :: a -> CForest a -> TreeCursor a -> Maybe (TreeCursor a)
+ Cursor.Simple.Tree: treeCursorInsertNodeSingleAndSelect :: a -> TreeCursor a -> Maybe (TreeCursor a)
+ Cursor.Simple.Tree: treeCursorSelectFirstOnSameLevel :: TreeCursor a -> TreeCursor a
+ Cursor.Simple.Tree: treeCursorSelectLastOnSameLevel :: TreeCursor a -> TreeCursor a
+ Cursor.Text: textCursorAppendString :: String -> TextCursor -> Maybe TextCursor
+ Cursor.Text: textCursorAppendText :: Text -> TextCursor -> Maybe TextCursor
+ Cursor.Text: textCursorInsertString :: String -> TextCursor -> Maybe TextCursor
+ Cursor.Text: textCursorInsertText :: Text -> TextCursor -> Maybe TextCursor
+ Cursor.Text: textCursorSelectBeginWord :: TextCursor -> TextCursor
+ Cursor.Text: textCursorSelectEndWord :: TextCursor -> TextCursor
+ Cursor.Text: textCursorSelectNextWord :: TextCursor -> TextCursor
+ Cursor.Text: textCursorSelectPrevWord :: TextCursor -> TextCursor
+ Cursor.TextField: textFieldCursorSelectBeginWord :: TextFieldCursor -> TextFieldCursor
+ Cursor.TextField: textFieldCursorSelectEndWord :: TextFieldCursor -> TextFieldCursor
+ Cursor.TextField: textFieldCursorSelectNextWord :: TextFieldCursor -> TextFieldCursor
+ Cursor.TextField: textFieldCursorSelectPrevWord :: TextFieldCursor -> TextFieldCursor
+ Cursor.Tree.Base: makeNodeTreeCursor :: a -> CForest b -> TreeCursor a b
+ Cursor.Tree.Insert: treeCursorAddChildAtEndAndSelect :: (a -> b) -> (b -> a) -> Tree b -> TreeCursor a b -> TreeCursor a b
+ Cursor.Tree.Insert: treeCursorAddChildAtPosAndSelect :: (a -> b) -> (b -> a) -> Int -> Tree b -> TreeCursor a b -> TreeCursor a b
+ Cursor.Tree.Insert: treeCursorAddChildAtStartAndSelect :: (a -> b) -> (b -> a) -> Tree b -> TreeCursor a b -> TreeCursor a b
+ Cursor.Tree.Insert: treeCursorAddChildNodeAtEndAndSelect :: (a -> b) -> a -> Forest b -> TreeCursor a b -> TreeCursor a b
+ Cursor.Tree.Insert: treeCursorAddChildNodeAtPosAndSelect :: (a -> b) -> Int -> a -> Forest b -> TreeCursor a b -> TreeCursor a b
+ Cursor.Tree.Insert: treeCursorAddChildNodeAtStartAndSelect :: (a -> b) -> a -> Forest b -> TreeCursor a b -> TreeCursor a b
+ Cursor.Tree.Insert: treeCursorAddChildNodeSingleAtEndAndSelect :: (a -> b) -> a -> TreeCursor a b -> TreeCursor a b
+ Cursor.Tree.Insert: treeCursorAddChildNodeSingleAtPosAndSelect :: (a -> b) -> Int -> a -> TreeCursor a b -> TreeCursor a b
+ Cursor.Tree.Insert: treeCursorAddChildNodeSingleAtStartAndSelect :: (a -> b) -> a -> TreeCursor a b -> TreeCursor a b
+ Cursor.Tree.Insert: treeCursorAppendNodeAndSelect :: (a -> b) -> a -> CForest b -> TreeCursor a b -> Maybe (TreeCursor a b)
+ Cursor.Tree.Insert: treeCursorAppendNodeSingleAndSelect :: (a -> b) -> a -> TreeCursor a b -> Maybe (TreeCursor a b)
+ Cursor.Tree.Insert: treeCursorInsertNodeAndSelect :: (a -> b) -> a -> CForest b -> TreeCursor a b -> Maybe (TreeCursor a b)
+ Cursor.Tree.Insert: treeCursorInsertNodeSingleAndSelect :: (a -> b) -> a -> TreeCursor a b -> Maybe (TreeCursor a b)
+ Cursor.Tree.Movement: treeCursorSelectFirstOnSameLevel :: (a -> b) -> (b -> a) -> TreeCursor a b -> TreeCursor a b
+ Cursor.Tree.Movement: treeCursorSelectLastOnSameLevel :: (a -> b) -> (b -> a) -> TreeCursor a b -> TreeCursor a b
+ Cursor.Types: instance GHC.Base.Monad Cursor.Types.DeleteOrUpdate

Files

CHANGELOG.md view
@@ -1,6 +1,13 @@ # Changelog -## [Unreleased]+## [0.3.1.0] - 2021-11-23++### Added++- `listCursorPrevUntil`+- `listCursorNextUntil`+- `listCursorInsertList`+- `listCursorAppendList`  ## [0.3.0.0] - 2020-02-14 
LICENSE view
@@ -1,6 +1,6 @@ MIT License -Copyright (c) 2018 Tom Sydney Kerckhove+Copyright (c) 2018-2021 Tom Sydney Kerckhove  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal
− Setup.hs
@@ -1,3 +0,0 @@-import Distribution.Simple--main = defaultMain
cursor.cabal view
@@ -1,13 +1,13 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.31.2.+-- This file has been generated from package.yaml by hpack version 0.34.4. -- -- see: https://github.com/sol/hpack ----- hash: eb21207b1fb477978ab67b054e6cadf6a1d4b7ccfc60a7dea2f0e206586eb33f+-- hash: 295467a341ff6e00d4d214636b3656ec0c9a1e9edbd8a56c8801ff54b64d7445  name:           cursor-version:        0.3.0.0+version:        0.3.1.0 synopsis:       Purely Functional Cursors description:    Purely Functional Cursors for common data structures                 .@@ -16,7 +16,7 @@ homepage:       https://github.com/NorfairKing/cursor author:         Tom Sydney Kerckhove maintainer:     syd@cs-syd.eu-copyright:      Copyright: (c) 2018 Tom Sydney Kerckhove+copyright:      Copyright: (c) 2018-2021 Tom Sydney Kerckhove license:        MIT license-file:   LICENSE build-type:     Simple
src/Cursor/Forest.hs view
@@ -3,109 +3,126 @@ {-# LANGUAGE TypeFamilies #-}  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+  ( ForestCursor (..),+    singletonForestCursor,+    makeForestCursor,+    rebuildForestCursor,+    drawForestCursor,+    mapForestCursor,+    forestCursorListCursorL,+    forestCursorSelectedTreeL,+    forestCursorSelectPrevTreeCursor,+    forestCursorSelectNextTreeCursor,+    forestCursorSelectFirstTreeCursor,+    forestCursorSelectLastTreeCursor,+    forestCursorSelectPrev,+    forestCursorSelectNext,+    forestCursorSelectPrevOnSameLevel,+    forestCursorSelectNextOnSameLevel,+    forestCursorSelectFirst,+    forestCursorSelectLast,+    forestCursorSelectFirstOnSameLevel,+    forestCursorSelectLastOnSameLevel,+    forestCursorSelectAbove,+    forestCursorSelectBelowAtPos,+    forestCursorSelectBelowAtStart,+    forestCursorSelectBelowAtEnd,+    forestCursorSelection,+    forestCursorSelectIndex,+    forestCursorOpenCurrentForest,+    forestCursorCloseCurrentForest,+    forestCursorToggleCurrentForest,+    forestCursorOpenCurrentForestRecursively,+    forestCursorToggleCurrentForestRecursively,+    forestCursorInsertEntireTree,+    forestCursorAppendEntireTree,+    forestCursorInsertAndSelectTreeCursor,+    forestCursorAppendAndSelectTreeCursor,+    forestCursorInsertTree,+    forestCursorAppendTree,+    forestCursorInsertAndSelectTree,+    forestCursorAppendAndSelectTree,+    forestCursorInsert,+    forestCursorAppend,+    forestCursorInsertAndSelect,+    forestCursorAppendAndSelect,+    forestCursorInsertNodeSingleAndSelect,+    forestCursorAppendNodeSingleAndSelect,+    forestCursorInsertNodeAndSelect,+    forestCursorAppendNodeAndSelect,+    forestCursorAddChildTreeToNodeAtPos,+    forestCursorAddChildTreeToNodeAtStart,+    forestCursorAddChildTreeToNodeAtEnd,+    forestCursorAddChildToNodeAtPos,+    forestCursorAddChildToNodeAtStart,+    forestCursorAddChildToNodeAtEnd,+    forestCursorAddChildTreeToNodeAtPosAndSelect,+    forestCursorAddChildTreeToNodeAtStartAndSelect,+    forestCursorAddChildTreeToNodeAtEndAndSelect,+    forestCursorAddChildToNodeAtPosAndSelect,+    forestCursorAddChildToNodeAtStartAndSelect,+    forestCursorAddChildToNodeAtEndAndSelect,+    forestCursorAddChildNodeSingleToNodeAtPosAndSelect,+    forestCursorAddChildNodeSingleToNodeAtStartAndSelect,+    forestCursorAddChildNodeSingleToNodeAtEndAndSelect,+    forestCursorAddChildNodeToNodeAtPosAndSelect,+    forestCursorAddChildNodeToNodeAtStartAndSelect,+    forestCursorAddChildNodeToNodeAtEndAndSelect,+    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 Control.Applicative import Control.DeepSeq--import Lens.Micro- import Cursor.List.NonEmpty import Cursor.Tree import Cursor.Types+import Data.List.NonEmpty (NonEmpty)+import Data.Maybe+import Data.Tree+import Data.Validity+import Data.Validity.Tree ()+import GHC.Generics (Generic)+import Lens.Micro -newtype ForestCursor a b =-  ForestCursor-    { forestCursorListCursor :: NonEmptyCursor (TreeCursor a b) (CTree b)-    }+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)  instance (NFData a, NFData b) => NFData (ForestCursor a b) +singletonForestCursor :: a -> ForestCursor a b+singletonForestCursor = ForestCursor . singletonNonEmptyCursor . singletonTreeCursor+ makeForestCursor :: (b -> a) -> NonEmpty (CTree b) -> ForestCursor a b makeForestCursor g = ForestCursor . makeNonEmptyCursor (makeTreeCursor g) @@ -115,27 +132,27 @@ drawForestCursor :: (Show a, Show b) => ForestCursor a b -> String drawForestCursor ForestCursor {..} =   drawForest $-  map showCTree (reverse $ nonEmptyCursorPrev forestCursorListCursor) ++-  [treeCursorWithPointer $ nonEmptyCursorCurrent forestCursorListCursor] ++-  map showCTree (nonEmptyCursorNext forestCursorListCursor)+    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))+  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)+  (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)+  (a -> b) -> (b -> a) -> ForestCursor a b -> Maybe (ForestCursor a b) forestCursorSelectNextTreeCursor f g =   forestCursorListCursorL $ nonEmptyCursorSelectNext (rebuildTreeCursor f) (makeTreeCursor g) @@ -149,28 +166,41 @@  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+  (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+  (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)+  (a -> b) -> (b -> a) -> ForestCursor a b -> Maybe (ForestCursor a b) forestCursorSelectNextOnSameLevel f g fc =-  (fc & forestCursorSelectedTreeL (treeCursorSelectNextOnSameLevel f g)) <|>-  forestCursorSelectNextTreeCursor f g fc+  (fc & forestCursorSelectedTreeL (treeCursorSelectNextOnSameLevel f g))+    <|> forestCursorSelectNextTreeCursor f g fc  forestCursorSelectPrevOnSameLevel ::-     (a -> b) -> (b -> a) -> ForestCursor a b -> Maybe (ForestCursor a b)+  (a -> b) -> (b -> a) -> ForestCursor a b -> Maybe (ForestCursor a b) forestCursorSelectPrevOnSameLevel f g fc =-  (fc & forestCursorSelectedTreeL (treeCursorSelectPrevOnSameLevel f g)) <|>-  forestCursorSelectPrevTreeCursor f g fc+  (fc & forestCursorSelectedTreeL (treeCursorSelectPrevOnSameLevel f g))+    <|> forestCursorSelectPrevTreeCursor f g fc +forestCursorSelectLastOnSameLevel :: (a -> b) -> (b -> a) -> ForestCursor a b -> ForestCursor a b+forestCursorSelectLastOnSameLevel f g fc =+  case forestCursorSelectNextOnSameLevel f g fc of+    Nothing -> fc+    Just fc' -> forestCursorSelectLastOnSameLevel f g fc'++forestCursorSelectFirstOnSameLevel :: (a -> b) -> (b -> a) -> ForestCursor a b -> ForestCursor a b+forestCursorSelectFirstOnSameLevel f g fc =+  case forestCursorSelectPrevOnSameLevel f g fc of+    Nothing -> fc+    Just fc' -> forestCursorSelectLastOnSameLevel f g fc'+ forestCursorSelectFirst :: (a -> b) -> (b -> a) -> ForestCursor a b -> ForestCursor a b forestCursorSelectFirst f g fc =   case forestCursorSelectPrevTreeCursor f g fc of@@ -193,11 +223,11 @@ forestCursorSelectAbove f g = forestCursorSelectedTreeL $ treeCursorSelectAbove f g  forestCursorSelectBelowAtPos ::-     (a -> b) -> (b -> a) -> Int -> ForestCursor a b -> Maybe (ForestCursor a b)+  (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)+  (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)@@ -207,7 +237,7 @@ forestCursorSelection fc = nonEmptyCursorSelection $ fc ^. forestCursorListCursorL  forestCursorSelectIndex ::-     (a -> b) -> (b -> a) -> Int -> ForestCursor a b -> Maybe (ForestCursor a b)+  (a -> b) -> (b -> a) -> Int -> ForestCursor a b -> Maybe (ForestCursor a b) forestCursorSelectIndex f g i =   forestCursorListCursorL (nonEmptyCursorSelectIndex (rebuildTreeCursor f) (makeTreeCursor g) i) @@ -232,7 +262,7 @@ forestCursorInsertEntireTree t = forestCursorListCursorL %~ nonEmptyCursorInsert (makeCTree t)  forestCursorInsertAndSelectTreeCursor ::-     (a -> b) -> TreeCursor a b -> ForestCursor a b -> ForestCursor a b+  (a -> b) -> TreeCursor a b -> ForestCursor a b -> ForestCursor a b forestCursorInsertAndSelectTreeCursor f tc =   forestCursorListCursorL %~ nonEmptyCursorInsertAndSelect (rebuildTreeCursor f) tc @@ -240,31 +270,29 @@ forestCursorAppendEntireTree t = forestCursorListCursorL %~ nonEmptyCursorAppend (makeCTree t)  forestCursorAppendAndSelectTreeCursor ::-     (a -> b) -> TreeCursor a b -> ForestCursor a b -> ForestCursor a b+  (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)+    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)+  (a -> b) -> (b -> a) -> Tree b -> ForestCursor a b -> ForestCursor a b+forestCursorInsertAndSelectTree f g (Node value forest) =+  forestCursorInsertNodeAndSelect f (g value) (makeCForest forest)  forestCursorAppendTree :: Tree b -> ForestCursor a b -> ForestCursor a b forestCursorAppendTree t fc =   fromMaybe (forestCursorAppendEntireTree t fc) $-  fc & forestCursorSelectedTreeL (treeCursorAppend t)+    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)+  (a -> b) -> (b -> a) -> Tree b -> ForestCursor a b -> ForestCursor a b+forestCursorAppendAndSelectTree f g (Node value forest) =+  forestCursorAppendNodeAndSelect f (g value) (makeCForest forest)  forestCursorInsert :: b -> ForestCursor a b -> ForestCursor a b forestCursorInsert b = forestCursorInsertTree $ Node b []@@ -272,12 +300,28 @@ forestCursorInsertAndSelect :: (a -> b) -> (b -> a) -> b -> ForestCursor a b -> ForestCursor a b forestCursorInsertAndSelect f g b = forestCursorInsertAndSelectTree f g $ Node b [] +forestCursorInsertNodeSingleAndSelect :: (a -> b) -> a -> ForestCursor a b -> ForestCursor a b+forestCursorInsertNodeSingleAndSelect f value = forestCursorInsertNodeAndSelect f value EmptyCForest++forestCursorInsertNodeAndSelect :: (a -> b) -> a -> CForest b -> ForestCursor a b -> ForestCursor a b+forestCursorInsertNodeAndSelect f value forest fc =+  fromMaybe (forestCursorInsertAndSelectTreeCursor f (makeNodeTreeCursor value forest) fc) $+    fc & forestCursorSelectedTreeL (treeCursorInsertNodeAndSelect f value forest)+ 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 [] +forestCursorAppendNodeSingleAndSelect :: (a -> b) -> a -> ForestCursor a b -> ForestCursor a b+forestCursorAppendNodeSingleAndSelect f value = forestCursorAppendNodeAndSelect f value EmptyCForest++forestCursorAppendNodeAndSelect :: (a -> b) -> a -> CForest b -> ForestCursor a b -> ForestCursor a b+forestCursorAppendNodeAndSelect f value forest fc =+  fromMaybe (forestCursorAppendAndSelectTreeCursor f (makeNodeTreeCursor value forest) fc) $+    fc & forestCursorSelectedTreeL (treeCursorAppendNodeAndSelect f value forest)+ forestCursorAddChildTreeToNodeAtPos :: Int -> Tree b -> ForestCursor a b -> ForestCursor a b forestCursorAddChildTreeToNodeAtPos i t = forestCursorSelectedTreeL %~ treeCursorAddChildAtPos i t @@ -297,75 +341,133 @@ forestCursorAddChildToNodeAtEnd :: b -> ForestCursor a b -> ForestCursor a b forestCursorAddChildToNodeAtEnd b = forestCursorAddChildTreeToNodeAtEnd $ Node b [] +forestCursorAddChildTreeToNodeAtPosAndSelect ::+  (a -> b) -> (b -> a) -> Int -> Tree b -> ForestCursor a b -> ForestCursor a b+forestCursorAddChildTreeToNodeAtPosAndSelect f g i t =+  forestCursorSelectedTreeL %~ treeCursorAddChildAtPosAndSelect f g i t++forestCursorAddChildTreeToNodeAtStartAndSelect ::+  (a -> b) -> (b -> a) -> Tree b -> ForestCursor a b -> ForestCursor a b+forestCursorAddChildTreeToNodeAtStartAndSelect f g t =+  forestCursorSelectedTreeL %~ treeCursorAddChildAtStartAndSelect f g t++forestCursorAddChildTreeToNodeAtEndAndSelect ::+  (a -> b) -> (b -> a) -> Tree b -> ForestCursor a b -> ForestCursor a b+forestCursorAddChildTreeToNodeAtEndAndSelect f g t fc =+  fc & forestCursorSelectedTreeL %~ treeCursorAddChildAtEndAndSelect f g t++forestCursorAddChildToNodeAtPosAndSelect ::+  (a -> b) -> (b -> a) -> Int -> b -> ForestCursor a b -> ForestCursor a b+forestCursorAddChildToNodeAtPosAndSelect f g i b =+  forestCursorAddChildTreeToNodeAtPosAndSelect f g i $ Node b []++forestCursorAddChildToNodeAtStartAndSelect ::+  (a -> b) -> (b -> a) -> b -> ForestCursor a b -> ForestCursor a b+forestCursorAddChildToNodeAtStartAndSelect f g b =+  forestCursorAddChildTreeToNodeAtStartAndSelect f g $ Node b []++forestCursorAddChildToNodeAtEndAndSelect ::+  (a -> b) -> (b -> a) -> b -> ForestCursor a b -> ForestCursor a b+forestCursorAddChildToNodeAtEndAndSelect f g b =+  forestCursorAddChildTreeToNodeAtEndAndSelect f g $ Node b []++forestCursorAddChildNodeSingleToNodeAtPosAndSelect ::+  (a -> b) -> Int -> a -> ForestCursor a b -> ForestCursor a b+forestCursorAddChildNodeSingleToNodeAtPosAndSelect f i t = forestCursorSelectedTreeL %~ treeCursorAddChildNodeSingleAtPosAndSelect f i t++forestCursorAddChildNodeSingleToNodeAtStartAndSelect ::+  (a -> b) -> a -> ForestCursor a b -> ForestCursor a b+forestCursorAddChildNodeSingleToNodeAtStartAndSelect f t = forestCursorSelectedTreeL %~ treeCursorAddChildNodeSingleAtStartAndSelect f t++forestCursorAddChildNodeSingleToNodeAtEndAndSelect ::+  (a -> b) -> a -> ForestCursor a b -> ForestCursor a b+forestCursorAddChildNodeSingleToNodeAtEndAndSelect f t = forestCursorSelectedTreeL %~ treeCursorAddChildNodeSingleAtEndAndSelect f t++forestCursorAddChildNodeToNodeAtPosAndSelect ::+  (a -> b) -> Int -> a -> Forest b -> ForestCursor a b -> ForestCursor a b+forestCursorAddChildNodeToNodeAtPosAndSelect f i t ts = forestCursorSelectedTreeL %~ treeCursorAddChildNodeAtPosAndSelect f i t ts++forestCursorAddChildNodeToNodeAtStartAndSelect ::+  (a -> b) -> a -> Forest b -> ForestCursor a b -> ForestCursor a b+forestCursorAddChildNodeToNodeAtStartAndSelect f t ts = forestCursorSelectedTreeL %~ treeCursorAddChildNodeAtStartAndSelect f t ts++forestCursorAddChildNodeToNodeAtEndAndSelect ::+  (a -> b) -> a -> Forest b -> ForestCursor a b -> ForestCursor a b+forestCursorAddChildNodeToNodeAtEndAndSelect f t ts = forestCursorSelectedTreeL %~ treeCursorAddChildNodeAtEndAndSelect f t ts+ forestCursorRemoveElemAndSelectPrev ::-     (b -> a) -> ForestCursor a b -> Maybe (DeleteOrUpdate (ForestCursor a b))+  (b -> a) -> ForestCursor a b -> Maybe (DeleteOrUpdate (ForestCursor a b)) forestCursorRemoveElemAndSelectPrev g fc =-  case fc &-       focusPossibleDeleteOrUpdate-         forestCursorSelectedTreeL-         (treeCursorDeleteElemAndSelectPrevious g) of+  case fc+    & focusPossibleDeleteOrUpdate+      forestCursorSelectedTreeL+      (treeCursorDeleteElemAndSelectPrevious g) of     Just Deleted ->-      fc &-      focusPossibleDeleteOrUpdate-        forestCursorListCursorL-        (nonEmptyCursorRemoveElemAndSelectPrev (makeTreeCursor g))+      fc+        & focusPossibleDeleteOrUpdate+          forestCursorListCursorL+          (nonEmptyCursorRemoveElemAndSelectPrev (makeTreeCursor g))     r -> r  forestCursorDeleteElemAndSelectNext ::-     (b -> a) -> ForestCursor a b -> Maybe (DeleteOrUpdate (ForestCursor a b))+  (b -> a) -> ForestCursor a b -> Maybe (DeleteOrUpdate (ForestCursor a b)) forestCursorDeleteElemAndSelectNext g fc =-  case fc &-       focusPossibleDeleteOrUpdate forestCursorSelectedTreeL (treeCursorDeleteElemAndSelectNext g) of+  case fc+    & focusPossibleDeleteOrUpdate forestCursorSelectedTreeL (treeCursorDeleteElemAndSelectNext g) of     Just Deleted ->-      fc &-      focusPossibleDeleteOrUpdate-        forestCursorListCursorL-        (nonEmptyCursorDeleteElemAndSelectNext (makeTreeCursor g))+      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)))+  (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)))+  (fc & forestCursorSelectedTreeL (treeCursorDeleteElem g))+    <|> (fc & forestCursorListCursorL (nonEmptyCursorDeleteElem (makeTreeCursor g)))  forestCursorRemoveSubTreeAndSelectPrev ::-     (b -> a) -> ForestCursor a b -> Maybe (DeleteOrUpdate (ForestCursor a b))+  (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)))+    ( fc+        & focusPossibleDeleteOrUpdate+          forestCursorSelectedTreeL+          (treeCursorDeleteSubTreeAndSelectPrevious g)+    )+    ( fc+        & focusPossibleDeleteOrUpdate+          forestCursorListCursorL+          (nonEmptyCursorRemoveElemAndSelectPrev (makeTreeCursor g))+    )  forestCursorDeleteSubTreeAndSelectNext ::-     (b -> a) -> ForestCursor a b -> Maybe (DeleteOrUpdate (ForestCursor a b))+  (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)))+    ( 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)))+  (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)))+  (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 =@@ -392,9 +494,9 @@     SwapperIsTopNode ->       case nonEmptyCursorPrev ne of         [] -> Nothing-        (t:ts) ->+        (t : ts) ->           pure $-          ForestCursor ne {nonEmptyCursorPrev = ts, nonEmptyCursorNext = t : nonEmptyCursorNext ne}+            ForestCursor ne {nonEmptyCursorPrev = ts, nonEmptyCursorNext = t : nonEmptyCursorNext ne}  -- | Swaps the current node with the next node on the same level --@@ -417,9 +519,9 @@     SwapperIsTopNode ->       case nonEmptyCursorNext ne of         [] -> Nothing-        (t:ts) ->+        (t : ts) ->           pure $-          ForestCursor ne {nonEmptyCursorPrev = t : nonEmptyCursorPrev ne, nonEmptyCursorNext = ts}+            ForestCursor ne {nonEmptyCursorPrev = t : nonEmptyCursorPrev ne, nonEmptyCursorNext = ts}  -- | Promotes the current node to the level of its parent. --@@ -461,7 +563,7 @@           _ ->             case treeAboveLefts ta of               [] -> Nothing-              (CNode t ls:ts) ->+              (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'}@@ -471,11 +573,11 @@           Updated tc'' -> pure tc''       pure $         ForestCursor $-        ne-          { nonEmptyCursorPrev = rebuildTreeCursor f tc'' : nonEmptyCursorPrev ne-          , nonEmptyCursorCurrent =-              singletonTreeCursor $ treeCurrent $ fc ^. forestCursorSelectedTreeL-          }+          ne+            { nonEmptyCursorPrev = rebuildTreeCursor f tc'' : nonEmptyCursorPrev ne,+              nonEmptyCursorCurrent =+                singletonTreeCursor $ treeCurrent $ fc ^. forestCursorSelectedTreeL+            }  -- | Promotes the current node to the level of its parent. --@@ -513,11 +615,11 @@         Deleted -> Nothing -- Cannot happen, otherwise we would have gotten 'CannotPromoteTopNode'.         Updated tc' ->           pure $-          ForestCursor $-          ne-            { nonEmptyCursorPrev = rebuildTreeCursor f tc' : nonEmptyCursorPrev ne-            , nonEmptyCursorCurrent = (fc ^. forestCursorSelectedTreeL) {treeAbove = Nothing}-            }+            ForestCursor $+              ne+                { nonEmptyCursorPrev = rebuildTreeCursor f tc' : nonEmptyCursorPrev ne,+                  nonEmptyCursorCurrent = (fc ^. forestCursorSelectedTreeL) {treeAbove = Nothing}+                }  -- | Demotes the current node to the level of its children. --@@ -545,11 +647,12 @@     CannotDemoteTopNode ->       case nonEmptyCursorPrev ne of         [] -> Nothing-        (CNode v vts:ts) -> do+        (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'+                  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@@ -578,11 +681,11 @@     CannotDemoteTopNode ->       case nonEmptyCursorPrev ne of         [] -> Nothing-        (CNode v vts:ts) -> do+        (CNode v vts : ts) -> do           let n' =                 CNode v $-                openForest $-                unpackCForest vts ++ [rebuildTreeCursor f (fc ^. forestCursorSelectedTreeL)]+                  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@@ -610,22 +713,22 @@     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-            }+            ne+              { nonEmptyCursorCurrent =+                  TreeCursor+                    { treeAbove =+                        Just+                          TreeAbove+                            { treeAboveLefts = [],+                              treeAboveAbove = Nothing,+                              treeAboveNode = b1,+                              treeAboveRights = []+                            },+                      treeCurrent = treeCurrent t,+                      treeBelow = emptyCForest+                    },+                nonEmptyCursorNext = CNode b2 (treeBelow t) : nonEmptyCursorNext ne+              }  -- | Demotes the current subtree to the level of its children, by adding a root. --
src/Cursor/List.hs view
@@ -1,47 +1,49 @@+{-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE DeriveFunctor #-}  module Cursor.List-  ( ListCursor(..)-  , emptyListCursor-  , makeListCursor-  , makeListCursorWithSelection-  , rebuildListCursor-  , listCursorNull-  , listCursorLength-  , listCursorIndex-  , listCursorSelectPrev-  , listCursorSelectNext-  , listCursorSelectIndex-  , listCursorSelectStart-  , listCursorSelectEnd-  , listCursorPrevItem-  , listCursorNextItem-  , listCursorInsert-  , listCursorAppend-  , listCursorRemove-  , listCursorDelete-  , listCursorSplit-  , listCursorCombine-  , traverseListCursor-  , foldListCursor-  ) where--import GHC.Generics (Generic)--import Data.Validity+  ( ListCursor (..),+    emptyListCursor,+    makeListCursor,+    makeListCursorWithSelection,+    rebuildListCursor,+    listCursorNull,+    listCursorLength,+    listCursorIndex,+    listCursorSelectPrev,+    listCursorSelectNext,+    listCursorSelectIndex,+    listCursorSelectStart,+    listCursorSelectEnd,+    listCursorPrevItem,+    listCursorNextItem,+    listCursorPrevUntil,+    listCursorNextUntil,+    listCursorInsert,+    listCursorAppend,+    listCursorInsertList,+    listCursorAppendList,+    listCursorRemove,+    listCursorDelete,+    listCursorSplit,+    listCursorCombine,+    traverseListCursor,+    foldListCursor,+  )+where  import Control.DeepSeq- import Cursor.Types+import Data.Validity+import GHC.Generics (Generic) -data ListCursor a =-  ListCursor-    { listCursorPrev :: [a] -- ^ In reverse order-    , listCursorNext :: [a]-    }+data ListCursor a = ListCursor+  { -- | In reverse order+    listCursorPrev :: [a],+    listCursorNext :: [a]+  }   deriving (Show, Eq, Generic, Functor)  instance Validity a => Validity (ListCursor a)@@ -76,13 +78,13 @@ listCursorSelectPrev tc =   case listCursorPrev tc of     [] -> Nothing-    (c:cs) -> Just ListCursor {listCursorPrev = cs, listCursorNext = c : listCursorNext tc}+    (c : cs) -> Just ListCursor {listCursorPrev = cs, listCursorNext = c : listCursorNext tc}  listCursorSelectNext :: ListCursor a -> Maybe (ListCursor a) listCursorSelectNext tc =   case listCursorNext tc of     [] -> Nothing-    (c:cs) -> Just ListCursor {listCursorPrev = c : listCursorPrev tc, listCursorNext = cs}+    (c : cs) -> Just ListCursor {listCursorPrev = c : listCursorPrev tc, listCursorNext = cs}  listCursorSelectIndex :: Int -> ListCursor a -> ListCursor a listCursorSelectIndex ix_ lc =@@ -106,20 +108,46 @@ listCursorPrevItem lc =   case listCursorPrev lc of     [] -> Nothing-    (c:_) -> Just c+    (c : _) -> Just c  listCursorNextItem :: ListCursor a -> Maybe a listCursorNextItem lc =   case listCursorNext lc of     [] -> Nothing-    (c:_) -> Just c+    (c : _) -> Just c +listCursorPrevUntil :: (a -> Bool) -> ListCursor a -> ListCursor a+listCursorPrevUntil p = go+  where+    go lc =+      case listCursorPrev lc of+        [] -> lc+        (c : _)+          | p c -> lc+        _ -> maybe lc go (listCursorSelectPrev lc)++listCursorNextUntil :: (a -> Bool) -> ListCursor a -> ListCursor a+listCursorNextUntil p = go+  where+    go lc =+      case listCursorNext lc of+        [] -> lc+        (c : _)+          | p c -> lc+        _ -> maybe lc go (listCursorSelectNext lc)+ listCursorInsert :: a -> ListCursor a -> ListCursor a listCursorInsert c lc = lc {listCursorPrev = c : listCursorPrev lc}  listCursorAppend :: a -> ListCursor a -> ListCursor a listCursorAppend c lc = lc {listCursorNext = c : listCursorNext lc} +listCursorInsertList :: [a] -> ListCursor a -> ListCursor a+listCursorInsertList l lc = lc {listCursorPrev = reverse l ++ listCursorPrev lc}++listCursorAppendList :: [a] -> ListCursor a -> ListCursor a+listCursorAppendList l lc = lc {listCursorNext = l ++ listCursorNext lc}+ listCursorRemove :: ListCursor a -> Maybe (DeleteOrUpdate (ListCursor a)) listCursorRemove tc =   case listCursorPrev tc of@@ -127,7 +155,7 @@       case listCursorNext tc of         [] -> Just Deleted         _ -> Nothing-    (_:prev) -> Just $ Updated $ tc {listCursorPrev = prev}+    (_ : prev) -> Just $ Updated $ tc {listCursorPrev = prev}  listCursorDelete :: ListCursor a -> Maybe (DeleteOrUpdate (ListCursor a)) listCursorDelete tc =@@ -136,17 +164,20 @@       case listCursorPrev tc of         [] -> Just Deleted         _ -> Nothing-    (_:next) -> Just $ Updated $ tc {listCursorNext = next}+    (_ : next) -> Just $ Updated $ tc {listCursorNext = next}  listCursorSplit :: ListCursor a -> (ListCursor a, ListCursor a) listCursorSplit ListCursor {..} =-  ( ListCursor {listCursorPrev = listCursorPrev, listCursorNext = []}-  , ListCursor {listCursorPrev = [], listCursorNext = listCursorNext})+  ( ListCursor {listCursorPrev = listCursorPrev, listCursorNext = []},+    ListCursor {listCursorPrev = [], listCursorNext = listCursorNext}+  )  listCursorCombine :: ListCursor a -> ListCursor a -> ListCursor a listCursorCombine lc1 lc2 =   ListCursor-    {listCursorPrev = reverse $ rebuildListCursor lc1, listCursorNext = rebuildListCursor lc2}+    { listCursorPrev = reverse $ rebuildListCursor lc1,+      listCursorNext = rebuildListCursor lc2+    }  traverseListCursor :: ([a] -> [a] -> f b) -> ListCursor a -> f b traverseListCursor = foldListCursor
src/Cursor/List/NonEmpty.hs view
@@ -1,65 +1,60 @@+{-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE DeriveFunctor #-}  module Cursor.List.NonEmpty-  ( NonEmptyCursor(..)-  , makeNonEmptyCursor-  , makeNonEmptyCursorWithSelection-  , singletonNonEmptyCursor-  , rebuildNonEmptyCursor-  , nonEmptyCursorElemL-  , mapNonEmptyCursor-  , nonEmptyCursorSelectPrev-  , nonEmptyCursorSelectNext-  , nonEmptyCursorSelectFirst-  , nonEmptyCursorSelectLast-  , nonEmptyCursorSelection-  , nonEmptyCursorSelectIndex-  , nonEmptyCursorInsert-  , nonEmptyCursorAppend-  , nonEmptyCursorInsertAndSelect-  , nonEmptyCursorAppendAndSelect-  , nonEmptyCursorInsertAtStart-  , nonEmptyCursorAppendAtEnd-  , nonEmptyCursorInsertAtStartAndSelect-  , nonEmptyCursorAppendAtEndAndSelect-  , nonEmptyCursorRemoveElemAndSelectPrev-  , nonEmptyCursorDeleteElemAndSelectNext-  , nonEmptyCursorRemoveElem-  , nonEmptyCursorDeleteElem-  , nonEmptyCursorSearch-  , nonEmptyCursorSelectOrAdd-  , renderNonEmptyCursor-  , nonemptyPrepend-  , nonemptyAppend-  , traverseNonEmptyCursor-  , foldNonEmptyCursor-  ) where--import GHC.Generics (Generic)--import Data.Maybe-import Data.Validity+  ( NonEmptyCursor (..),+    makeNonEmptyCursor,+    makeNonEmptyCursorWithSelection,+    singletonNonEmptyCursor,+    rebuildNonEmptyCursor,+    nonEmptyCursorElemL,+    mapNonEmptyCursor,+    nonEmptyCursorSelectPrev,+    nonEmptyCursorSelectNext,+    nonEmptyCursorSelectFirst,+    nonEmptyCursorSelectLast,+    nonEmptyCursorSelection,+    nonEmptyCursorSelectIndex,+    nonEmptyCursorInsert,+    nonEmptyCursorAppend,+    nonEmptyCursorInsertAndSelect,+    nonEmptyCursorAppendAndSelect,+    nonEmptyCursorInsertAtStart,+    nonEmptyCursorAppendAtEnd,+    nonEmptyCursorInsertAtStartAndSelect,+    nonEmptyCursorAppendAtEndAndSelect,+    nonEmptyCursorRemoveElemAndSelectPrev,+    nonEmptyCursorDeleteElemAndSelectNext,+    nonEmptyCursorRemoveElem,+    nonEmptyCursorDeleteElem,+    nonEmptyCursorSearch,+    nonEmptyCursorSelectOrAdd,+    renderNonEmptyCursor,+    nonemptyPrepend,+    nonemptyAppend,+    traverseNonEmptyCursor,+    foldNonEmptyCursor,+  )+where  import Control.DeepSeq import Control.Monad--import Lens.Micro--import Data.List.NonEmpty (NonEmpty(..), (<|))-import qualified Data.List.NonEmpty as NE- import Cursor.Types+import Data.List.NonEmpty (NonEmpty (..), (<|))+import qualified Data.List.NonEmpty as NE+import Data.Maybe+import Data.Validity+import GHC.Generics (Generic)+import Lens.Micro  -- | A 'nonempty list' cursor-data NonEmptyCursor a b =-  NonEmptyCursor-    { nonEmptyCursorPrev :: [b] -- In reverse order-    , nonEmptyCursorCurrent :: a-    , nonEmptyCursorNext :: [b]-    }+data NonEmptyCursor a b = NonEmptyCursor+  { nonEmptyCursorPrev :: [b], -- In reverse order+    nonEmptyCursorCurrent :: a,+    nonEmptyCursorNext :: [b]+  }   deriving (Show, Eq, Generic, Functor)  instance (Validity a, Validity b) => Validity (NonEmptyCursor a b)@@ -74,7 +69,10 @@   (l, m, r) <- applyNonEmptySelection ne i   pure     NonEmptyCursor-      {nonEmptyCursorPrev = reverse l, nonEmptyCursorCurrent = g m, nonEmptyCursorNext = r}+      { nonEmptyCursorPrev = reverse l,+        nonEmptyCursorCurrent = g m,+        nonEmptyCursorNext = r+      }   where     applyNonEmptySelection :: NonEmpty a -> Int -> Maybe ([a], a, [a])     applyNonEmptySelection (c :| rest) i_@@ -96,9 +94,9 @@ mapNonEmptyCursor :: (a -> c) -> (b -> d) -> NonEmptyCursor a b -> NonEmptyCursor c d mapNonEmptyCursor f g NonEmptyCursor {..} =   NonEmptyCursor-    { nonEmptyCursorPrev = map g nonEmptyCursorPrev-    , nonEmptyCursorCurrent = f nonEmptyCursorCurrent-    , nonEmptyCursorNext = map g nonEmptyCursorNext+    { nonEmptyCursorPrev = map g nonEmptyCursorPrev,+      nonEmptyCursorCurrent = f nonEmptyCursorCurrent,+      nonEmptyCursorNext = map g nonEmptyCursorNext     }  nonEmptyCursorElemL :: Lens (NonEmptyCursor a c) (NonEmptyCursor b c) a b@@ -108,25 +106,25 @@ nonEmptyCursorSelectPrev f g lec =   case nonEmptyCursorPrev lec of     [] -> Nothing-    (e:rest) ->+    (e : rest) ->       Just $-      lec-        { nonEmptyCursorPrev = rest-        , nonEmptyCursorCurrent = g e-        , nonEmptyCursorNext = f (nonEmptyCursorCurrent lec) : nonEmptyCursorNext lec-        }+        lec+          { nonEmptyCursorPrev = rest,+            nonEmptyCursorCurrent = g e,+            nonEmptyCursorNext = f (nonEmptyCursorCurrent lec) : nonEmptyCursorNext lec+          }  nonEmptyCursorSelectNext :: (a -> b) -> (b -> a) -> NonEmptyCursor a b -> Maybe (NonEmptyCursor a b) nonEmptyCursorSelectNext f g lec =   case nonEmptyCursorNext lec of     [] -> Nothing-    (e:rest) ->+    (e : rest) ->       Just $-      lec-        { nonEmptyCursorPrev = f (nonEmptyCursorCurrent lec) : nonEmptyCursorPrev lec-        , nonEmptyCursorCurrent = g e-        , nonEmptyCursorNext = rest-        }+        lec+          { nonEmptyCursorPrev = f (nonEmptyCursorCurrent lec) : nonEmptyCursorPrev lec,+            nonEmptyCursorCurrent = g e,+            nonEmptyCursorNext = rest+          }  nonEmptyCursorSelectFirst :: (a -> b) -> (b -> a) -> NonEmptyCursor a b -> NonEmptyCursor a b nonEmptyCursorSelectFirst f g lec =@@ -144,7 +142,7 @@ nonEmptyCursorSelection = length . nonEmptyCursorPrev  nonEmptyCursorSelectIndex ::-     (a -> b) -> (b -> a) -> Int -> NonEmptyCursor a b -> Maybe (NonEmptyCursor a b)+  (a -> b) -> (b -> a) -> Int -> NonEmptyCursor a b -> Maybe (NonEmptyCursor a b) nonEmptyCursorSelectIndex f g i nec   | i < nonEmptyCursorSelection nec =     nonEmptyCursorSelectPrev f g nec >>= nonEmptyCursorSelectIndex f g i@@ -161,15 +159,15 @@ nonEmptyCursorInsertAndSelect :: (a -> b) -> a -> NonEmptyCursor a b -> NonEmptyCursor a b nonEmptyCursorInsertAndSelect f c lec =   lec-    { nonEmptyCursorCurrent = c-    , nonEmptyCursorNext = f (nonEmptyCursorCurrent lec) : nonEmptyCursorNext lec+    { nonEmptyCursorCurrent = c,+      nonEmptyCursorNext = f (nonEmptyCursorCurrent lec) : nonEmptyCursorNext lec     }  nonEmptyCursorAppendAndSelect :: (a -> b) -> a -> NonEmptyCursor a b -> NonEmptyCursor a b nonEmptyCursorAppendAndSelect f c lec =   lec-    { nonEmptyCursorCurrent = c-    , nonEmptyCursorPrev = f (nonEmptyCursorCurrent lec) : nonEmptyCursorPrev lec+    { nonEmptyCursorCurrent = c,+      nonEmptyCursorPrev = f (nonEmptyCursorCurrent lec) : nonEmptyCursorPrev lec     }  nonEmptyCursorInsertAtStart :: b -> NonEmptyCursor a b -> NonEmptyCursor a b@@ -179,34 +177,34 @@ nonEmptyCursorAppendAtEnd c lec = lec {nonEmptyCursorNext = nonEmptyCursorNext lec ++ [c]}  nonEmptyCursorInsertAtStartAndSelect ::-     (a -> b) -> (b -> a) -> b -> NonEmptyCursor a b -> NonEmptyCursor a b+  (a -> b) -> (b -> a) -> b -> NonEmptyCursor a b -> NonEmptyCursor a b nonEmptyCursorInsertAtStartAndSelect f g c =   nonEmptyCursorSelectFirst f g . nonEmptyCursorInsertAtStart c  nonEmptyCursorAppendAtEndAndSelect ::-     (a -> b) -> (b -> a) -> b -> NonEmptyCursor a b -> NonEmptyCursor a b+  (a -> b) -> (b -> a) -> b -> NonEmptyCursor a b -> NonEmptyCursor a b nonEmptyCursorAppendAtEndAndSelect f g c =   nonEmptyCursorSelectLast f g . nonEmptyCursorAppendAtEnd c  nonEmptyCursorRemoveElemAndSelectPrev ::-     (b -> a) -> NonEmptyCursor a b -> Maybe (DeleteOrUpdate (NonEmptyCursor a b))+  (b -> a) -> NonEmptyCursor a b -> Maybe (DeleteOrUpdate (NonEmptyCursor a b)) nonEmptyCursorRemoveElemAndSelectPrev g lec =   case nonEmptyCursorPrev lec of     [] ->       case nonEmptyCursorNext lec of         [] -> Just Deleted         _ -> Nothing-    (e:rest) -> Just $ Updated $ lec {nonEmptyCursorPrev = rest, nonEmptyCursorCurrent = g e}+    (e : rest) -> Just $ Updated $ lec {nonEmptyCursorPrev = rest, nonEmptyCursorCurrent = g e}  nonEmptyCursorDeleteElemAndSelectNext ::-     (b -> a) -> NonEmptyCursor a b -> Maybe (DeleteOrUpdate (NonEmptyCursor a b))+  (b -> a) -> NonEmptyCursor a b -> Maybe (DeleteOrUpdate (NonEmptyCursor a b)) nonEmptyCursorDeleteElemAndSelectNext g lec =   case nonEmptyCursorNext lec of     [] ->       case nonEmptyCursorPrev lec of         [] -> Just Deleted         _ -> Nothing-    (e:rest) -> Just $ Updated $ lec {nonEmptyCursorCurrent = g e, nonEmptyCursorNext = rest}+    (e : rest) -> Just $ Updated $ lec {nonEmptyCursorCurrent = g e, nonEmptyCursorNext = rest}  nonEmptyCursorRemoveElem :: (b -> a) -> NonEmptyCursor a b -> DeleteOrUpdate (NonEmptyCursor a b) nonEmptyCursorRemoveElem g lec =@@ -221,7 +219,7 @@     (nonEmptyCursorRemoveElemAndSelectPrev g lec)  nonEmptyCursorSearch ::-     (a -> b) -> (b -> a) -> (a -> Bool) -> NonEmptyCursor a b -> Maybe (NonEmptyCursor a b)+  (a -> b) -> (b -> a) -> (a -> Bool) -> NonEmptyCursor a b -> Maybe (NonEmptyCursor a b) nonEmptyCursorSearch f g p nec =   if p $ nonEmptyCursorCurrent nec     then Just nec@@ -236,7 +234,7 @@         else look func nec'  nonEmptyCursorSelectOrAdd ::-     (a -> b) -> (b -> a) -> (a -> Bool) -> a -> NonEmptyCursor a b -> NonEmptyCursor a b+  (a -> b) -> (b -> a) -> (a -> Bool) -> a -> NonEmptyCursor a b -> NonEmptyCursor a b nonEmptyCursorSelectOrAdd f g p a nec =   case nonEmptyCursorSearch f g p nec of     Nothing -> nonEmptyCursorAppendAndSelect f a nec
src/Cursor/Map.hs view
@@ -3,61 +3,59 @@ {-# LANGUAGE TypeFamilies #-}  module Cursor.Map-  ( MapCursor(..)-  , makeMapCursor-  , makeMapCursorWithSelection-  , singletonMapCursorKey-  , singletonMapCursorValue-  , rebuildMapCursor-  , mapMapCursor-  , mapCursorNonEmptyCursorL-  , mapCursorElemL-  , mapCursorSelectKey-  , mapCursorSelectValue-  , mapCursorToggleSelected-  , mapCursorSelectPrev-  , mapCursorSelectNext-  , mapCursorSelectFirst-  , mapCursorSelectLast-  , mapCursorSelection-  , mapCursorSelectIndex-  , mapCursorInsert-  , mapCursorAppend-  , mapCursorInsertAndSelectKey-  , mapCursorAppendAndSelectKey-  , mapCursorInsertAndSelectValue-  , mapCursorAppendAndSelectValue-  , mapCursorRemoveElemAndSelectPrev-  , mapCursorDeleteElemAndSelectNext-  , mapCursorRemoveElem-  , mapCursorDeleteElem-  , mapCursorSearch-  , mapCursorSelectOrAdd-  , traverseMapCursor-  , foldMapCursor-  , module Cursor.Map.KeyValue-  ) where--import GHC.Generics (Generic)--import Data.Validity-import Data.Validity.Tree ()--import Data.List.NonEmpty (NonEmpty(..))-import Data.Maybe+  ( MapCursor (..),+    makeMapCursor,+    makeMapCursorWithSelection,+    singletonMapCursorKey,+    singletonMapCursorValue,+    rebuildMapCursor,+    mapMapCursor,+    mapCursorNonEmptyCursorL,+    mapCursorElemL,+    mapCursorElemSelection,+    mapCursorSelectKey,+    mapCursorSelectValue,+    mapCursorToggleSelected,+    mapCursorSelectPrev,+    mapCursorSelectNext,+    mapCursorSelectFirst,+    mapCursorSelectLast,+    mapCursorSelection,+    mapCursorSelectIndex,+    mapCursorInsert,+    mapCursorAppend,+    mapCursorInsertAndSelectKey,+    mapCursorAppendAndSelectKey,+    mapCursorInsertAndSelectValue,+    mapCursorAppendAndSelectValue,+    mapCursorRemoveElemAndSelectPrev,+    mapCursorDeleteElemAndSelectNext,+    mapCursorRemoveElem,+    mapCursorDeleteElem,+    mapCursorSearch,+    mapCursorSelectOrAdd,+    traverseMapCursor,+    mapCursorTraverseKeyCase,+    mapCursorTraverseValueCase,+    foldMapCursor,+    module Cursor.Map.KeyValue,+  )+where  import Control.DeepSeq--import Lens.Micro- import Cursor.List.NonEmpty import Cursor.Map.KeyValue import Cursor.Types+import Data.List.NonEmpty (NonEmpty (..))+import Data.Maybe+import Data.Validity+import Data.Validity.Tree ()+import GHC.Generics (Generic)+import Lens.Micro -newtype MapCursor kc vc k v =-  MapCursor-    { mapCursorList :: NonEmptyCursor (KeyValueCursor kc vc k v) (k, v)-    }+newtype MapCursor kc vc k v = MapCursor+  { mapCursorList :: NonEmptyCursor (KeyValueCursor kc vc k v) (k, v)+  }   deriving (Show, Eq, Generic)  instance (Validity kc, Validity vc, Validity k, Validity v) => Validity (MapCursor kc vc k v)@@ -83,20 +81,35 @@ rebuildMapCursor f g = rebuildNonEmptyCursor (rebuildKeyValueCursor f g) . mapCursorList  mapMapCursor ::-     (kc -> lc) -> (vc -> wc) -> (k -> l) -> (v -> w) -> MapCursor kc vc k v -> MapCursor lc wc l w+  (kc -> lc) -> (vc -> wc) -> (k -> l) -> (v -> w) -> MapCursor kc vc k v -> MapCursor lc wc l w mapMapCursor a b c d =   mapCursorNonEmptyCursorL %~ mapNonEmptyCursor (mapKeyValueCursor a b c d) (\(k, v) -> (c k, d v))  mapCursorNonEmptyCursorL ::-     Lens (MapCursor kc vc k v) (MapCursor lc wc l w) (NonEmptyCursor (KeyValueCursor kc vc k v) ( k-                                                                                                 , v)) (NonEmptyCursor (KeyValueCursor lc wc l w) ( l-                                                                                                                                                  , w))+  Lens+    (MapCursor kc vc k v)+    (MapCursor lc wc l w)+    ( NonEmptyCursor+        (KeyValueCursor kc vc k v)+        ( k,+          v+        )+    )+    ( NonEmptyCursor+        (KeyValueCursor lc wc l w)+        ( l,+          w+        )+    ) mapCursorNonEmptyCursorL = lens mapCursorList $ \mc ne -> mc {mapCursorList = ne}  mapCursorElemL ::-     Lens (MapCursor kc vc k v) (MapCursor kc' vc' k v) (KeyValueCursor kc vc k v) (KeyValueCursor kc' vc' k v)+  Lens (MapCursor kc vc k v) (MapCursor kc' vc' k v) (KeyValueCursor kc vc k v) (KeyValueCursor kc' vc' k v) mapCursorElemL = mapCursorNonEmptyCursorL . nonEmptyCursorElemL +mapCursorElemSelection :: MapCursor kc vc k v -> KeyValueToggle+mapCursorElemSelection mc = keyValueCursorSelection $ mc ^. mapCursorElemL+ mapCursorSelectKey :: (k -> kc) -> (vc -> v) -> MapCursor kc vc k v -> MapCursor kc vc k v mapCursorSelectKey g h = mapCursorElemL %~ keyValueCursorSelectKey g h @@ -104,26 +117,26 @@ mapCursorSelectValue f i = mapCursorElemL %~ keyValueCursorSelectValue f i  mapCursorToggleSelected ::-     (kc -> k) -> (k -> kc) -> (vc -> v) -> (v -> vc) -> MapCursor kc vc k v -> MapCursor kc vc k v+  (kc -> k) -> (k -> kc) -> (vc -> v) -> (v -> vc) -> MapCursor kc vc k v -> MapCursor kc vc k v mapCursorToggleSelected f g h i = mapCursorElemL %~ keyValueCursorToggleSelected f g h i  mapCursorSelectPrev ::-     (kc -> k) -> (k -> kc) -> (vc -> v) -> MapCursor kc vc k v -> Maybe (MapCursor kc vc k v)+  (kc -> k) -> (k -> kc) -> (vc -> v) -> MapCursor kc vc k v -> Maybe (MapCursor kc vc k v) mapCursorSelectPrev f g h =   mapCursorNonEmptyCursorL $ nonEmptyCursorSelectPrev (rebuild f h) (make g)  mapCursorSelectNext ::-     (kc -> k) -> (k -> kc) -> (vc -> v) -> MapCursor kc vc k v -> Maybe (MapCursor kc vc k v)+  (kc -> k) -> (k -> kc) -> (vc -> v) -> MapCursor kc vc k v -> Maybe (MapCursor kc vc k v) mapCursorSelectNext f g h =   mapCursorNonEmptyCursorL $ nonEmptyCursorSelectNext (rebuild f h) (make g)  mapCursorSelectFirst ::-     (kc -> k) -> (k -> kc) -> (vc -> v) -> MapCursor kc vc k v -> MapCursor kc vc k v+  (kc -> k) -> (k -> kc) -> (vc -> v) -> MapCursor kc vc k v -> MapCursor kc vc k v mapCursorSelectFirst f g h =   mapCursorNonEmptyCursorL %~ nonEmptyCursorSelectFirst (rebuild f h) (make g)  mapCursorSelectLast ::-     (kc -> k) -> (k -> kc) -> (vc -> v) -> MapCursor kc vc k v -> MapCursor kc vc k v+  (kc -> k) -> (k -> kc) -> (vc -> v) -> MapCursor kc vc k v -> MapCursor kc vc k v mapCursorSelectLast f g h =   mapCursorNonEmptyCursorL %~ nonEmptyCursorSelectLast (rebuild f h) (make g) @@ -131,12 +144,12 @@ mapCursorSelection = nonEmptyCursorSelection . mapCursorList  mapCursorSelectIndex ::-     (kc -> k)-  -> (k -> kc)-  -> (vc -> v)-  -> Int-  -> MapCursor kc vc k v-  -> Maybe (MapCursor kc vc k v)+  (kc -> k) ->+  (k -> kc) ->+  (vc -> v) ->+  Int ->+  MapCursor kc vc k v ->+  Maybe (MapCursor kc vc k v) mapCursorSelectIndex f g h i =   mapCursorNonEmptyCursorL (nonEmptyCursorSelectIndex (rebuild f h) (make g) i) @@ -147,40 +160,40 @@ mapCursorAppend k v = mapCursorNonEmptyCursorL %~ nonEmptyCursorAppend (k, v)  mapCursorInsertAndSelectKey ::-     (kc -> k) -> (vc -> v) -> kc -> v -> MapCursor kc vc k v -> MapCursor kc vc k v+  (kc -> k) -> (vc -> v) -> kc -> v -> MapCursor kc vc k v -> MapCursor kc vc k v mapCursorInsertAndSelectKey f h kc v =-  mapCursorNonEmptyCursorL %~-  nonEmptyCursorInsertAndSelect (rebuild f h) (makeKeyValueCursorKey kc v)+  mapCursorNonEmptyCursorL+    %~ nonEmptyCursorInsertAndSelect (rebuild f h) (makeKeyValueCursorKey kc v)  mapCursorAppendAndSelectKey ::-     (kc -> k) -> (vc -> v) -> kc -> v -> MapCursor kc vc k v -> MapCursor kc vc k v+  (kc -> k) -> (vc -> v) -> kc -> v -> MapCursor kc vc k v -> MapCursor kc vc k v mapCursorAppendAndSelectKey f h kc v =-  mapCursorNonEmptyCursorL %~-  nonEmptyCursorAppendAndSelect (rebuild f h) (makeKeyValueCursorKey kc v)+  mapCursorNonEmptyCursorL+    %~ nonEmptyCursorAppendAndSelect (rebuild f h) (makeKeyValueCursorKey kc v)  mapCursorInsertAndSelectValue ::-     (kc -> k) -> (vc -> v) -> k -> vc -> MapCursor kc vc k v -> MapCursor kc vc k v+  (kc -> k) -> (vc -> v) -> k -> vc -> MapCursor kc vc k v -> MapCursor kc vc k v mapCursorInsertAndSelectValue f h k vc =-  mapCursorNonEmptyCursorL %~-  nonEmptyCursorInsertAndSelect (rebuild f h) (makeKeyValueCursorValue k vc)+  mapCursorNonEmptyCursorL+    %~ nonEmptyCursorInsertAndSelect (rebuild f h) (makeKeyValueCursorValue k vc)  mapCursorAppendAndSelectValue ::-     (kc -> k) -> (vc -> v) -> k -> vc -> MapCursor kc vc k v -> MapCursor kc vc k v+  (kc -> k) -> (vc -> v) -> k -> vc -> MapCursor kc vc k v -> MapCursor kc vc k v mapCursorAppendAndSelectValue f h k vc =-  mapCursorNonEmptyCursorL %~-  nonEmptyCursorAppendAndSelect (rebuild f h) (makeKeyValueCursorValue k vc)+  mapCursorNonEmptyCursorL+    %~ nonEmptyCursorAppendAndSelect (rebuild f h) (makeKeyValueCursorValue k vc)  mapCursorRemoveElemAndSelectPrev ::-     (k -> kc) -> MapCursor kc vc k v -> Maybe (DeleteOrUpdate (MapCursor kc vc k v))+  (k -> kc) -> MapCursor kc vc k v -> Maybe (DeleteOrUpdate (MapCursor kc vc k v)) mapCursorRemoveElemAndSelectPrev g =   focusPossibleDeleteOrUpdate mapCursorNonEmptyCursorL $-  nonEmptyCursorRemoveElemAndSelectPrev (make g)+    nonEmptyCursorRemoveElemAndSelectPrev (make g)  mapCursorDeleteElemAndSelectNext ::-     (k -> kc) -> MapCursor kc vc k v -> Maybe (DeleteOrUpdate (MapCursor kc vc k v))+  (k -> kc) -> MapCursor kc vc k v -> Maybe (DeleteOrUpdate (MapCursor kc vc k v)) mapCursorDeleteElemAndSelectNext g =   focusPossibleDeleteOrUpdate mapCursorNonEmptyCursorL $-  nonEmptyCursorDeleteElemAndSelectNext (make g)+    nonEmptyCursorDeleteElemAndSelectNext (make g)  mapCursorRemoveElem :: (k -> kc) -> MapCursor kc vc k v -> DeleteOrUpdate (MapCursor kc vc k v) mapCursorRemoveElem g = mapCursorNonEmptyCursorL $ nonEmptyCursorRemoveElem (make g)@@ -189,26 +202,26 @@ mapCursorDeleteElem g = mapCursorNonEmptyCursorL $ nonEmptyCursorDeleteElem (make g)  mapCursorSearch ::-     (kc -> k)-  -> (k -> kc)-  -> (vc -> v)-  -> (k -> v -> Bool)-  -> MapCursor kc vc k v-  -> Maybe (MapCursor kc vc k v)+  (kc -> k) ->+  (k -> kc) ->+  (vc -> v) ->+  (k -> v -> Bool) ->+  MapCursor kc vc k v ->+  Maybe (MapCursor kc vc k v) mapCursorSearch f g h p =   mapCursorNonEmptyCursorL $ nonEmptyCursorSearch (rebuild f h) (make g) (uncurry p . rebuild f h)  mapCursorSelectOrAdd ::-     (kc -> k)-  -> (k -> kc)-  -> (vc -> v)-  -> (k -> v -> Bool)-  -> KeyValueCursor kc vc k v-  -> MapCursor kc vc k v-  -> MapCursor kc vc k v+  (kc -> k) ->+  (k -> kc) ->+  (vc -> v) ->+  (k -> v -> Bool) ->+  KeyValueCursor kc vc k v ->+  MapCursor kc vc k v ->+  MapCursor kc vc k v mapCursorSelectOrAdd f g h p kvc =-  mapCursorNonEmptyCursorL %~-  nonEmptyCursorSelectOrAdd (rebuild f h) (make g) (uncurry p . rebuild f h) kvc+  mapCursorNonEmptyCursorL+    %~ nonEmptyCursorSelectOrAdd (rebuild f h) (make g) (uncurry p . rebuild f h) kvc  rebuild :: (kc -> k) -> (vc -> v) -> KeyValueCursor kc vc k v -> (k, v) rebuild = rebuildKeyValueCursor@@ -217,8 +230,16 @@ make g (k, v) = makeKeyValueCursorKey (g k) v  traverseMapCursor ::-     ([(k, v)] -> KeyValueCursor kc vc k v -> [(k, v)] -> f c) -> MapCursor kc vc k v -> f c+  ([(k, v)] -> KeyValueCursor kc vc k v -> [(k, v)] -> f c) -> MapCursor kc vc k v -> f c traverseMapCursor combFunc = foldNonEmptyCursor combFunc . mapCursorList++mapCursorTraverseKeyCase ::+  Applicative f => (kc -> v -> f (kc', v)) -> MapCursor kc vc k v -> f (MapCursor kc' vc k v)+mapCursorTraverseKeyCase func = mapCursorElemL $ keyValueCursorTraverseKeyCase func++mapCursorTraverseValueCase ::+  Applicative f => (k -> vc -> f (k, vc')) -> MapCursor kc vc k v -> f (MapCursor kc vc' k v)+mapCursorTraverseValueCase func = mapCursorElemL $ keyValueCursorTraverseValueCase func  foldMapCursor :: ([(k, v)] -> KeyValueCursor kc vc k v -> [(k, v)] -> c) -> MapCursor kc vc k v -> c foldMapCursor combFunc = foldNonEmptyCursor combFunc . mapCursorList
src/Cursor/Map/KeyValue.hs view
@@ -1,35 +1,38 @@ {-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE LambdaCase #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TypeFamilies #-}  module Cursor.Map.KeyValue-  ( KeyValueCursor(..)-  , makeKeyValueCursorKey-  , makeKeyValueCursorValue-  , rebuildKeyValueCursor-  , keyValueCursorSelection-  , mapKeyValueCursor-  , keyValueCursorSelectKey-  , keyValueCursorSelectValue-  , keyValueCursorToggleSelected-  , KeyValueToggle(..)-  , traverseKeyValueCursor-  , foldKeyValueCursor-  ) where--import GHC.Generics (Generic)--import Data.Validity+  ( KeyValueCursor (..),+    makeKeyValueCursorKey,+    makeKeyValueCursorValue,+    rebuildKeyValueCursor,+    keyValueCursorSelection,+    mapKeyValueCursor,+    keyValueCursorSelectKey,+    keyValueCursorSelectValue,+    keyValueCursorToggleSelected,+    KeyValueToggle (..),+    traverseKeyValueCursor,+    keyValueCursorTraverseKeyCase,+    keyValueCursorTraverseValueCase,+    foldKeyValueCursor,+  )+where  import Control.DeepSeq+import Data.Validity+import GHC.Generics (Generic)  data KeyValueCursor kc vc k v   = KeyValueCursorKey kc v   | KeyValueCursorValue k vc   deriving (Show, Eq, Generic) -instance (Validity kc, Validity vc, Validity k, Validity v) =>-         Validity (KeyValueCursor kc vc k v)+instance+  (Validity kc, Validity vc, Validity k, Validity v) =>+  Validity (KeyValueCursor kc vc k v)  instance (NFData kc, NFData vc, NFData k, NFData v) => NFData (KeyValueCursor kc vc k v) @@ -48,38 +51,38 @@ keyValueCursorSelection (KeyValueCursorValue _ _) = ValueSelected  mapKeyValueCursor ::-     (kc -> lc)-  -> (vc -> wc)-  -> (k -> l)-  -> (v -> w)-  -> KeyValueCursor kc vc k v-  -> KeyValueCursor lc wc l w+  (kc -> lc) ->+  (vc -> wc) ->+  (k -> l) ->+  (v -> w) ->+  KeyValueCursor kc vc k v ->+  KeyValueCursor lc wc l w mapKeyValueCursor a b c d kvc =   case kvc of     KeyValueCursorKey kc v -> KeyValueCursorKey (a kc) (d v)     KeyValueCursorValue k vc -> KeyValueCursorValue (c k) (b vc)  keyValueCursorSelectKey ::-     (k -> kc) -> (vc -> v) -> KeyValueCursor kc vc k v -> KeyValueCursor kc vc k v+  (k -> kc) -> (vc -> v) -> KeyValueCursor kc vc k v -> KeyValueCursor kc vc k v keyValueCursorSelectKey g h kvc =   case kvc of     KeyValueCursorValue k vc -> KeyValueCursorKey (g k) (h vc)     _ -> kvc  keyValueCursorSelectValue ::-     (kc -> k) -> (v -> vc) -> KeyValueCursor kc vc k v -> KeyValueCursor kc vc k v+  (kc -> k) -> (v -> vc) -> KeyValueCursor kc vc k v -> KeyValueCursor kc vc k v keyValueCursorSelectValue f i kvc =   case kvc of     KeyValueCursorKey kc v -> KeyValueCursorValue (f kc) (i v)     _ -> kvc  keyValueCursorToggleSelected ::-     (kc -> k)-  -> (k -> kc)-  -> (vc -> v)-  -> (v -> vc)-  -> KeyValueCursor kc vc k v-  -> KeyValueCursor kc vc k v+  (kc -> k) ->+  (k -> kc) ->+  (vc -> v) ->+  (v -> vc) ->+  KeyValueCursor kc vc k v ->+  KeyValueCursor kc vc k v keyValueCursorToggleSelected f g h i kvc =   case kvc of     KeyValueCursorKey kc v -> KeyValueCursorValue (f kc) (i v)@@ -94,6 +97,26 @@  traverseKeyValueCursor :: (kc -> v -> f c) -> (k -> vc -> f c) -> KeyValueCursor kc vc k v -> f c traverseKeyValueCursor = foldKeyValueCursor++keyValueCursorTraverseKeyCase ::+  Applicative f =>+  (kc -> v -> f (kc', v')) ->+  KeyValueCursor kc vc k v ->+  f (KeyValueCursor kc' vc k v')+keyValueCursorTraverseKeyCase func =+  \case+    KeyValueCursorKey kc v -> uncurry KeyValueCursorKey <$> func kc v+    KeyValueCursorValue k vc -> pure (KeyValueCursorValue k vc)++keyValueCursorTraverseValueCase ::+  Applicative f =>+  (k -> vc -> f (k', vc')) ->+  KeyValueCursor kc vc k v ->+  f (KeyValueCursor kc vc' k' v)+keyValueCursorTraverseValueCase func =+  \case+    KeyValueCursorKey kc v -> pure (KeyValueCursorKey kc v)+    KeyValueCursorValue k vc -> uncurry KeyValueCursorValue <$> func k vc  foldKeyValueCursor :: (kc -> v -> c) -> (k -> vc -> c) -> KeyValueCursor kc vc k v -> c foldKeyValueCursor keyFunc valFunc kvc =
src/Cursor/Simple/Forest.hs view
@@ -1,87 +1,105 @@ {-# LANGUAGE TypeFamilies #-}  module Cursor.Simple.Forest-  ( ForestCursor-  , makeForestCursor-  , rebuildForestCursor-  , FC.drawForestCursor-  , mapForestCursor-  , FC.forestCursorListCursorL-  , FC.forestCursorSelectedTreeL-  , forestCursorSelectPrevTreeCursor-  , forestCursorSelectNextTreeCursor-  , forestCursorSelectFirstTreeCursor-  , forestCursorSelectLastTreeCursor-  , forestCursorSelectPrev-  , forestCursorSelectNext-  , forestCursorSelectPrevOnSameLevel-  , forestCursorSelectNextOnSameLevel-  , forestCursorSelectFirst-  , forestCursorSelectLast-  , forestCursorSelectAbove-  , forestCursorSelectBelowAtPos-  , forestCursorSelectBelowAtStart-  , forestCursorSelectBelowAtEnd-  , FC.forestCursorOpenCurrentForest-  , FC.forestCursorCloseCurrentForest-  , FC.forestCursorToggleCurrentForest-  , FC.forestCursorOpenCurrentForestRecursively-  , FC.forestCursorToggleCurrentForestRecursively-  , FC.forestCursorSelection-  , forestCursorSelectIndex-  , FC.forestCursorInsertEntireTree-  , forestCursorInsertAndSelectTreeCursor-  , FC.forestCursorAppendEntireTree-  , forestCursorAppendAndSelectTreeCursor-  , FC.forestCursorInsertTree-  , FC.forestCursorAppendTree-  , forestCursorInsertAndSelectTree-  , forestCursorAppendAndSelectTree-  , FC.forestCursorInsert-  , FC.forestCursorAppend-  , forestCursorInsertAndSelect-  , forestCursorAppendAndSelect-  , FC.forestCursorAddChildTreeToNodeAtPos-  , FC.forestCursorAddChildTreeToNodeAtStart-  , FC.forestCursorAddChildTreeToNodeAtEnd-  , FC.forestCursorAddChildToNodeAtPos-  , FC.forestCursorAddChildToNodeAtStart-  , FC.forestCursorAddChildToNodeAtEnd-  , forestCursorRemoveElemAndSelectPrev-  , forestCursorDeleteElemAndSelectNext-  , forestCursorRemoveElem-  , forestCursorDeleteElem-  , forestCursorRemoveSubTreeAndSelectPrev-  , forestCursorDeleteSubTreeAndSelectNext-  , forestCursorRemoveSubTree-  , forestCursorDeleteSubTree-  , forestCursorAddRoot-  , FC.forestCursorSwapPrev-  , FC.forestCursorSwapNext-  , forestCursorPromoteElem-  , forestCursorPromoteSubTree-  , forestCursorDemoteElem-  , forestCursorDemoteSubTree-  , FC.forestCursorDemoteElemUnder-  , FC.forestCursorDemoteSubTreeUnder-  , FC.CTree(..)-  , FC.makeCTree-  , FC.cTree-  , FC.rebuildCTree-  , FC.CForest(..)-  , FC.makeCForest-  , FC.cForest-  , FC.rebuildCForest-  ) where--import Data.Validity.Tree ()--import Data.List.NonEmpty (NonEmpty)-import Data.Tree+  ( ForestCursor,+    FC.singletonForestCursor,+    makeForestCursor,+    rebuildForestCursor,+    FC.drawForestCursor,+    mapForestCursor,+    FC.forestCursorListCursorL,+    FC.forestCursorSelectedTreeL,+    forestCursorSelectPrevTreeCursor,+    forestCursorSelectNextTreeCursor,+    forestCursorSelectFirstTreeCursor,+    forestCursorSelectLastTreeCursor,+    forestCursorSelectPrev,+    forestCursorSelectNext,+    forestCursorSelectPrevOnSameLevel,+    forestCursorSelectNextOnSameLevel,+    forestCursorSelectFirst,+    forestCursorSelectLast,+    forestCursorSelectFirstOnSameLevel,+    forestCursorSelectLastOnSameLevel,+    forestCursorSelectAbove,+    forestCursorSelectBelowAtPos,+    forestCursorSelectBelowAtStart,+    forestCursorSelectBelowAtEnd,+    FC.forestCursorOpenCurrentForest,+    FC.forestCursorCloseCurrentForest,+    FC.forestCursorToggleCurrentForest,+    FC.forestCursorOpenCurrentForestRecursively,+    FC.forestCursorToggleCurrentForestRecursively,+    FC.forestCursorSelection,+    forestCursorSelectIndex,+    FC.forestCursorInsertEntireTree,+    forestCursorInsertAndSelectTreeCursor,+    FC.forestCursorAppendEntireTree,+    forestCursorAppendAndSelectTreeCursor,+    FC.forestCursorInsertTree,+    FC.forestCursorAppendTree,+    forestCursorInsertAndSelectTree,+    forestCursorAppendAndSelectTree,+    FC.forestCursorInsert,+    FC.forestCursorAppend,+    forestCursorInsertAndSelect,+    forestCursorAppendAndSelect,+    forestCursorInsertNodeSingleAndSelect,+    forestCursorAppendNodeSingleAndSelect,+    forestCursorInsertNodeAndSelect,+    forestCursorAppendNodeAndSelect,+    FC.forestCursorAddChildTreeToNodeAtPos,+    FC.forestCursorAddChildTreeToNodeAtStart,+    FC.forestCursorAddChildTreeToNodeAtEnd,+    FC.forestCursorAddChildToNodeAtPos,+    FC.forestCursorAddChildToNodeAtStart,+    FC.forestCursorAddChildToNodeAtEnd,+    forestCursorAddChildTreeToNodeAtPosAndSelect,+    forestCursorAddChildTreeToNodeAtStartAndSelect,+    forestCursorAddChildTreeToNodeAtEndAndSelect,+    forestCursorAddChildToNodeAtPosAndSelect,+    forestCursorAddChildToNodeAtStartAndSelect,+    forestCursorAddChildToNodeAtEndAndSelect,+    forestCursorAddChildNodeSingleToNodeAtPosAndSelect,+    forestCursorAddChildNodeSingleToNodeAtStartAndSelect,+    forestCursorAddChildNodeSingleToNodeAtEndAndSelect,+    forestCursorAddChildNodeToNodeAtPosAndSelect,+    forestCursorAddChildNodeToNodeAtStartAndSelect,+    forestCursorAddChildNodeToNodeAtEndAndSelect,+    forestCursorRemoveElemAndSelectPrev,+    forestCursorDeleteElemAndSelectNext,+    forestCursorRemoveElem,+    forestCursorDeleteElem,+    forestCursorRemoveSubTreeAndSelectPrev,+    forestCursorDeleteSubTreeAndSelectNext,+    forestCursorRemoveSubTree,+    forestCursorDeleteSubTree,+    forestCursorAddRoot,+    FC.forestCursorSwapPrev,+    FC.forestCursorSwapNext,+    forestCursorPromoteElem,+    forestCursorPromoteSubTree,+    forestCursorDemoteElem,+    forestCursorDemoteSubTree,+    FC.forestCursorDemoteElemUnder,+    FC.forestCursorDemoteSubTreeUnder,+    FC.CTree (..),+    FC.makeCTree,+    FC.cTree,+    FC.rebuildCTree,+    FC.CForest (..),+    FC.makeCForest,+    FC.cForest,+    FC.rebuildCForest,+  )+where  import qualified Cursor.Forest as FC import Cursor.Simple.Tree import Cursor.Types+import Data.List.NonEmpty (NonEmpty)+import Data.Tree+import Data.Validity.Tree ()  type ForestCursor a = FC.ForestCursor a a @@ -124,6 +142,12 @@ forestCursorSelectLast :: ForestCursor a -> ForestCursor a forestCursorSelectLast = FC.forestCursorSelectLast id id +forestCursorSelectFirstOnSameLevel :: ForestCursor a -> ForestCursor a+forestCursorSelectFirstOnSameLevel = FC.forestCursorSelectFirstOnSameLevel id id++forestCursorSelectLastOnSameLevel :: ForestCursor a -> ForestCursor a+forestCursorSelectLastOnSameLevel = FC.forestCursorSelectLastOnSameLevel id id+ forestCursorSelectAbove :: ForestCursor a -> Maybe (ForestCursor a) forestCursorSelectAbove = FC.forestCursorSelectAbove id id @@ -154,8 +178,57 @@ forestCursorInsertAndSelect :: a -> ForestCursor a -> ForestCursor a forestCursorInsertAndSelect = FC.forestCursorInsertAndSelect id id +forestCursorInsertNodeSingleAndSelect :: a -> ForestCursor a -> ForestCursor a+forestCursorInsertNodeSingleAndSelect = FC.forestCursorInsertNodeSingleAndSelect id++forestCursorInsertNodeAndSelect :: a -> CForest a -> ForestCursor a -> ForestCursor a+forestCursorInsertNodeAndSelect = FC.forestCursorInsertNodeAndSelect id+ forestCursorAppendAndSelect :: a -> ForestCursor a -> ForestCursor a forestCursorAppendAndSelect = FC.forestCursorAppendAndSelect id id++forestCursorAppendNodeSingleAndSelect :: a -> ForestCursor a -> ForestCursor a+forestCursorAppendNodeSingleAndSelect = FC.forestCursorAppendNodeSingleAndSelect id++forestCursorAppendNodeAndSelect :: a -> CForest a -> ForestCursor a -> ForestCursor a+forestCursorAppendNodeAndSelect = FC.forestCursorAppendNodeAndSelect id++forestCursorAddChildTreeToNodeAtPosAndSelect :: Int -> Tree a -> ForestCursor a -> ForestCursor a+forestCursorAddChildTreeToNodeAtPosAndSelect = FC.forestCursorAddChildTreeToNodeAtPosAndSelect id id++forestCursorAddChildTreeToNodeAtStartAndSelect :: Tree a -> ForestCursor a -> ForestCursor a+forestCursorAddChildTreeToNodeAtStartAndSelect =+  FC.forestCursorAddChildTreeToNodeAtStartAndSelect id id++forestCursorAddChildTreeToNodeAtEndAndSelect :: Tree a -> ForestCursor a -> ForestCursor a+forestCursorAddChildTreeToNodeAtEndAndSelect = FC.forestCursorAddChildTreeToNodeAtEndAndSelect id id++forestCursorAddChildToNodeAtPosAndSelect :: Int -> a -> ForestCursor a -> ForestCursor a+forestCursorAddChildToNodeAtPosAndSelect = FC.forestCursorAddChildToNodeAtPosAndSelect id id++forestCursorAddChildToNodeAtStartAndSelect :: a -> ForestCursor a -> ForestCursor a+forestCursorAddChildToNodeAtStartAndSelect = FC.forestCursorAddChildToNodeAtStartAndSelect id id++forestCursorAddChildToNodeAtEndAndSelect :: a -> ForestCursor a -> ForestCursor a+forestCursorAddChildToNodeAtEndAndSelect = FC.forestCursorAddChildToNodeAtEndAndSelect id id++forestCursorAddChildNodeSingleToNodeAtPosAndSelect :: Int -> a -> ForestCursor a -> ForestCursor a+forestCursorAddChildNodeSingleToNodeAtPosAndSelect = FC.forestCursorAddChildNodeSingleToNodeAtPosAndSelect id++forestCursorAddChildNodeSingleToNodeAtStartAndSelect :: a -> ForestCursor a -> ForestCursor a+forestCursorAddChildNodeSingleToNodeAtStartAndSelect = FC.forestCursorAddChildNodeSingleToNodeAtStartAndSelect id++forestCursorAddChildNodeSingleToNodeAtEndAndSelect :: a -> ForestCursor a -> ForestCursor a+forestCursorAddChildNodeSingleToNodeAtEndAndSelect = FC.forestCursorAddChildNodeSingleToNodeAtEndAndSelect id++forestCursorAddChildNodeToNodeAtPosAndSelect :: Int -> a -> Forest a -> ForestCursor a -> ForestCursor a+forestCursorAddChildNodeToNodeAtPosAndSelect = FC.forestCursorAddChildNodeToNodeAtPosAndSelect id++forestCursorAddChildNodeToNodeAtStartAndSelect :: a -> Forest a -> ForestCursor a -> ForestCursor a+forestCursorAddChildNodeToNodeAtStartAndSelect = FC.forestCursorAddChildNodeToNodeAtStartAndSelect id++forestCursorAddChildNodeToNodeAtEndAndSelect :: a -> Forest a -> ForestCursor a -> ForestCursor a+forestCursorAddChildNodeToNodeAtEndAndSelect = FC.forestCursorAddChildNodeToNodeAtEndAndSelect id  forestCursorRemoveElemAndSelectPrev :: ForestCursor a -> Maybe (DeleteOrUpdate (ForestCursor a)) forestCursorRemoveElemAndSelectPrev = FC.forestCursorRemoveElemAndSelectPrev id
src/Cursor/Simple/List/NonEmpty.hs view
@@ -1,43 +1,42 @@ {-# LANGUAGE TypeFamilies #-}  module Cursor.Simple.List.NonEmpty-  ( NonEmptyCursor-  , NEC.nonEmptyCursorPrev-  , NEC.nonEmptyCursorCurrent-  , NEC.nonEmptyCursorNext-  , makeNonEmptyCursor-  , makeNonEmptyCursorWithSelection-  , NEC.singletonNonEmptyCursor-  , rebuildNonEmptyCursor-  , mapNonEmptyCursor-  , NEC.nonEmptyCursorElemL-  , nonEmptyCursorSelectPrev-  , nonEmptyCursorSelectNext-  , nonEmptyCursorSelectFirst-  , nonEmptyCursorSelectLast-  , NEC.nonEmptyCursorSelection-  , nonEmptyCursorSelectIndex-  , NEC.nonEmptyCursorInsert-  , NEC.nonEmptyCursorAppend-  , nonEmptyCursorInsertAndSelect-  , nonEmptyCursorAppendAndSelect-  , NEC.nonEmptyCursorInsertAtStart-  , NEC.nonEmptyCursorAppendAtEnd-  , nonEmptyCursorInsertAtStartAndSelect-  , nonEmptyCursorAppendAtEndAndSelect-  , nonEmptyCursorRemoveElemAndSelectPrev-  , nonEmptyCursorDeleteElemAndSelectNext-  , nonEmptyCursorRemoveElem-  , nonEmptyCursorDeleteElem-  , nonEmptyCursorSearch-  , nonEmptyCursorSelectOrAdd-  ) where--import Data.List.NonEmpty (NonEmpty(..))--import Cursor.Types+  ( NonEmptyCursor,+    NEC.nonEmptyCursorPrev,+    NEC.nonEmptyCursorCurrent,+    NEC.nonEmptyCursorNext,+    makeNonEmptyCursor,+    makeNonEmptyCursorWithSelection,+    NEC.singletonNonEmptyCursor,+    rebuildNonEmptyCursor,+    mapNonEmptyCursor,+    NEC.nonEmptyCursorElemL,+    nonEmptyCursorSelectPrev,+    nonEmptyCursorSelectNext,+    nonEmptyCursorSelectFirst,+    nonEmptyCursorSelectLast,+    NEC.nonEmptyCursorSelection,+    nonEmptyCursorSelectIndex,+    NEC.nonEmptyCursorInsert,+    NEC.nonEmptyCursorAppend,+    nonEmptyCursorInsertAndSelect,+    nonEmptyCursorAppendAndSelect,+    NEC.nonEmptyCursorInsertAtStart,+    NEC.nonEmptyCursorAppendAtEnd,+    nonEmptyCursorInsertAtStartAndSelect,+    nonEmptyCursorAppendAtEndAndSelect,+    nonEmptyCursorRemoveElemAndSelectPrev,+    nonEmptyCursorDeleteElemAndSelectNext,+    nonEmptyCursorRemoveElem,+    nonEmptyCursorDeleteElem,+    nonEmptyCursorSearch,+    nonEmptyCursorSelectOrAdd,+  )+where  import qualified Cursor.List.NonEmpty as NEC+import Cursor.Types+import Data.List.NonEmpty (NonEmpty (..))  -- | A 'nonempty list' cursor type NonEmptyCursor a = NEC.NonEmptyCursor a a@@ -82,11 +81,11 @@ nonEmptyCursorAppendAtEndAndSelect = NEC.nonEmptyCursorAppendAtEndAndSelect id id  nonEmptyCursorRemoveElemAndSelectPrev ::-     NonEmptyCursor a -> Maybe (DeleteOrUpdate (NonEmptyCursor a))+  NonEmptyCursor a -> Maybe (DeleteOrUpdate (NonEmptyCursor a)) nonEmptyCursorRemoveElemAndSelectPrev = NEC.nonEmptyCursorRemoveElemAndSelectPrev id  nonEmptyCursorDeleteElemAndSelectNext ::-     NonEmptyCursor a -> Maybe (DeleteOrUpdate (NonEmptyCursor a))+  NonEmptyCursor a -> Maybe (DeleteOrUpdate (NonEmptyCursor a)) nonEmptyCursorDeleteElemAndSelectNext = NEC.nonEmptyCursorDeleteElemAndSelectNext id  nonEmptyCursorRemoveElem :: NonEmptyCursor a -> DeleteOrUpdate (NonEmptyCursor a)
src/Cursor/Simple/Map.hs view
@@ -2,45 +2,45 @@ {-# LANGUAGE TypeFamilies #-}  module Cursor.Simple.Map-  ( MapCursor-  , MC.mapCursorList-  , makeMapCursor-  , makeMapCursorWithSelection-  , MC.singletonMapCursorKey-  , MC.singletonMapCursorValue-  , rebuildMapCursor-  , mapMapCursor-  , MC.mapCursorNonEmptyCursorL-  , MC.mapCursorElemL-  , mapCursorSelectKey-  , mapCursorSelectValue-  , mapCursorToggleSelected-  , mapCursorSelectPrev-  , mapCursorSelectNext-  , mapCursorSelectFirst-  , mapCursorSelectLast-  , MC.mapCursorSelection-  , mapCursorSelectIndex-  , MC.mapCursorInsert-  , MC.mapCursorAppend-  , mapCursorInsertAndSelectKey-  , mapCursorAppendAndSelectKey-  , mapCursorInsertAndSelectValue-  , mapCursorAppendAndSelectValue-  , mapCursorRemoveElemAndSelectPrev-  , mapCursorDeleteElemAndSelectNext-  , mapCursorRemoveElem-  , mapCursorDeleteElem-  , mapCursorSearch-  , mapCursorSelectOrAdd-  , module Cursor.Simple.Map.KeyValue-  ) where--import Data.List.NonEmpty (NonEmpty(..))+  ( MapCursor,+    MC.mapCursorList,+    makeMapCursor,+    makeMapCursorWithSelection,+    MC.singletonMapCursorKey,+    MC.singletonMapCursorValue,+    rebuildMapCursor,+    mapMapCursor,+    MC.mapCursorNonEmptyCursorL,+    MC.mapCursorElemL,+    mapCursorSelectKey,+    mapCursorSelectValue,+    mapCursorToggleSelected,+    mapCursorSelectPrev,+    mapCursorSelectNext,+    mapCursorSelectFirst,+    mapCursorSelectLast,+    MC.mapCursorSelection,+    mapCursorSelectIndex,+    MC.mapCursorInsert,+    MC.mapCursorAppend,+    mapCursorInsertAndSelectKey,+    mapCursorAppendAndSelectKey,+    mapCursorInsertAndSelectValue,+    mapCursorAppendAndSelectValue,+    mapCursorRemoveElemAndSelectPrev,+    mapCursorDeleteElemAndSelectNext,+    mapCursorRemoveElem,+    mapCursorDeleteElem,+    mapCursorSearch,+    mapCursorSelectOrAdd,+    module Cursor.Simple.Map.KeyValue,+  )+where  import qualified Cursor.Map as MC import Cursor.Simple.Map.KeyValue import Cursor.Types+import Data.List.NonEmpty (NonEmpty (..))  type MapCursor k v = MC.MapCursor k v k v 
src/Cursor/Simple/Map/KeyValue.hs view
@@ -1,19 +1,20 @@ {-# LANGUAGE PatternSynonyms #-}  module Cursor.Simple.Map.KeyValue-  ( KeyValueCursor-  , pattern KVC.KeyValueCursorKey-  , pattern KVC.KeyValueCursorValue-  , KVC.makeKeyValueCursorKey-  , KVC.makeKeyValueCursorValue-  , rebuildKeyValueCursor-  , KVC.keyValueCursorSelection-  , mapKeyValueCursor-  , keyValueCursorSelectKey-  , keyValueCursorSelectValue-  , keyValueCursorToggleSelected-  , KVC.KeyValueToggle(..)-  ) where+  ( KeyValueCursor,+    pattern KVC.KeyValueCursorKey,+    pattern KVC.KeyValueCursorValue,+    KVC.makeKeyValueCursorKey,+    KVC.makeKeyValueCursorValue,+    rebuildKeyValueCursor,+    KVC.keyValueCursorSelection,+    mapKeyValueCursor,+    keyValueCursorSelectKey,+    keyValueCursorSelectValue,+    keyValueCursorToggleSelected,+    KVC.KeyValueToggle (..),+  )+where  import qualified Cursor.Map.KeyValue as KVC 
src/Cursor/Simple/Tree.hs view
@@ -1,86 +1,101 @@ {-# LANGUAGE TypeFamilies #-}  module Cursor.Simple.Tree-  ( TreeCursor-  , TreeAbove(..)-  , singletonTreeCursor-  , makeTreeCursor-  , makeTreeCursorWithSelection-  , rebuildTreeCursor-  , TC.drawTreeCursor-  , mapTreeCursor-  , TC.treeCursorAboveL-  , TC.treeCursorCurrentL-  , TC.treeCursorBelowL-  , TC.treeAboveLeftsL-  , TC.treeAboveAboveL-  , TC.treeAboveNodeL-  , TC.treeAboveRightsL-  , TC.treeCursorWithPointer-  , TC.treeCursorSelection-  , TC.TreeCursorSelection(..)-  , treeCursorSelect-  , treeCursorSelectPrev-  , treeCursorSelectNext-  , treeCursorSelectFirst-  , treeCursorSelectLast-  , treeCursorSelectAbove-  , treeCursorSelectBelowAtPos-  , treeCursorSelectBelowAtStart-  , treeCursorSelectBelowAtEnd-  , treeCursorSelectBelowAtStartRecursively-  , treeCursorSelectBelowAtEndRecursively-  , treeCursorSelectPrevOnSameLevel-  , treeCursorSelectNextOnSameLevel-  , treeCursorSelectAbovePrev-  , treeCursorSelectAboveNext-  , TC.treeCursorOpenCurrentForest-  , TC.treeCursorCloseCurrentForest-  , TC.treeCursorToggleCurrentForest-  , TC.treeCursorOpenCurrentForestRecursively-  , TC.treeCursorToggleCurrentForestRecursively-  , TC.treeCursorInsert-  , treeCursorInsertAndSelect-  , TC.treeCursorAppend-  , treeCursorAppendAndSelect-  , TC.treeCursorAddChildAtPos-  , TC.treeCursorAddChildAtStart-  , TC.treeCursorAddChildAtEnd-  , treeCursorDeleteSubTreeAndSelectPrevious-  , treeCursorDeleteSubTreeAndSelectNext-  , treeCursorDeleteSubTreeAndSelectAbove-  , treeCursorRemoveSubTree-  , treeCursorDeleteSubTree-  , treeCursorDeleteElemAndSelectPrevious-  , treeCursorDeleteElemAndSelectNext-  , treeCursorDeleteElemAndSelectAbove-  , treeCursorRemoveElem-  , treeCursorDeleteElem-  , TC.treeCursorSwapPrev-  , TC.treeCursorSwapNext-  , TC.SwapResult(..)-  , treeCursorPromoteElem-  , TC.PromoteElemResult(..)-  , treeCursorPromoteSubTree-  , TC.PromoteResult(..)-  , treeCursorDemoteElem-  , treeCursorDemoteSubTree-  , TC.DemoteResult(..)-  , TC.treeCursorDemoteElemUnder-  , TC.treeCursorDemoteSubTreeUnder-  , TC.CTree(..)-  , TC.CForest-  , TC.makeCTree-  , TC.cTree-  , TC.rebuildCTree-  ) where--import Data.Tree--import Cursor.Types+  ( TreeCursor,+    TreeAbove (..),+    singletonTreeCursor,+    makeTreeCursor,+    TC.makeNodeTreeCursor,+    makeTreeCursorWithSelection,+    rebuildTreeCursor,+    TC.drawTreeCursor,+    mapTreeCursor,+    TC.treeCursorAboveL,+    TC.treeCursorCurrentL,+    TC.treeCursorBelowL,+    TC.treeAboveLeftsL,+    TC.treeAboveAboveL,+    TC.treeAboveNodeL,+    TC.treeAboveRightsL,+    TC.treeCursorWithPointer,+    TC.treeCursorSelection,+    TC.TreeCursorSelection (..),+    treeCursorSelect,+    treeCursorSelectPrev,+    treeCursorSelectNext,+    treeCursorSelectFirst,+    treeCursorSelectLast,+    treeCursorSelectAbove,+    treeCursorSelectBelowAtPos,+    treeCursorSelectBelowAtStart,+    treeCursorSelectBelowAtEnd,+    treeCursorSelectBelowAtStartRecursively,+    treeCursorSelectBelowAtEndRecursively,+    treeCursorSelectPrevOnSameLevel,+    treeCursorSelectNextOnSameLevel,+    treeCursorSelectFirstOnSameLevel,+    treeCursorSelectLastOnSameLevel,+    treeCursorSelectAbovePrev,+    treeCursorSelectAboveNext,+    TC.treeCursorOpenCurrentForest,+    TC.treeCursorCloseCurrentForest,+    TC.treeCursorToggleCurrentForest,+    TC.treeCursorOpenCurrentForestRecursively,+    TC.treeCursorToggleCurrentForestRecursively,+    TC.treeCursorInsert,+    treeCursorInsertAndSelect,+    treeCursorInsertNodeSingleAndSelect,+    treeCursorInsertNodeAndSelect,+    TC.treeCursorAppend,+    treeCursorAppendAndSelect,+    treeCursorAppendNodeSingleAndSelect,+    treeCursorAppendNodeAndSelect,+    TC.treeCursorAddChildAtPos,+    TC.treeCursorAddChildAtStart,+    TC.treeCursorAddChildAtEnd,+    treeCursorAddChildAtPosAndSelect,+    treeCursorAddChildAtStartAndSelect,+    treeCursorAddChildAtEndAndSelect,+    treeCursorAddChildNodeSingleAtPosAndSelect,+    treeCursorAddChildNodeSingleAtStartAndSelect,+    treeCursorAddChildNodeSingleAtEndAndSelect,+    treeCursorAddChildNodeAtPosAndSelect,+    treeCursorAddChildNodeAtStartAndSelect,+    treeCursorAddChildNodeAtEndAndSelect,+    treeCursorDeleteSubTreeAndSelectPrevious,+    treeCursorDeleteSubTreeAndSelectNext,+    treeCursorDeleteSubTreeAndSelectAbove,+    treeCursorRemoveSubTree,+    treeCursorDeleteSubTree,+    treeCursorDeleteElemAndSelectPrevious,+    treeCursorDeleteElemAndSelectNext,+    treeCursorDeleteElemAndSelectAbove,+    treeCursorRemoveElem,+    treeCursorDeleteElem,+    TC.treeCursorSwapPrev,+    TC.treeCursorSwapNext,+    TC.SwapResult (..),+    treeCursorPromoteElem,+    TC.PromoteElemResult (..),+    treeCursorPromoteSubTree,+    TC.PromoteResult (..),+    treeCursorDemoteElem,+    treeCursorDemoteSubTree,+    TC.DemoteResult (..),+    TC.treeCursorDemoteElemUnder,+    TC.treeCursorDemoteSubTreeUnder,+    TC.CTree (..),+    TC.CForest,+    TC.makeCTree,+    TC.cTree,+    TC.rebuildCTree,+  )+where +import Cursor.Tree (CForest (..), CTree, TreeAbove (..)) import qualified Cursor.Tree as TC-import Cursor.Tree (CTree, TreeAbove(..))+import Cursor.Types+import Data.Tree  type TreeCursor a = TC.TreeCursor a a @@ -138,6 +153,12 @@ treeCursorSelectNextOnSameLevel :: TreeCursor a -> Maybe (TreeCursor a) treeCursorSelectNextOnSameLevel = TC.treeCursorSelectNextOnSameLevel id id +treeCursorSelectFirstOnSameLevel :: TreeCursor a -> TreeCursor a+treeCursorSelectFirstOnSameLevel = TC.treeCursorSelectFirstOnSameLevel id id++treeCursorSelectLastOnSameLevel :: TreeCursor a -> TreeCursor a+treeCursorSelectLastOnSameLevel = TC.treeCursorSelectLastOnSameLevel id id+ -- | Go back and down as far as necessary to find a previous element on a level below treeCursorSelectAbovePrev :: TreeCursor a -> Maybe (TreeCursor a) treeCursorSelectAbovePrev = TC.treeCursorSelectAbovePrev id id@@ -151,8 +172,47 @@ treeCursorInsertAndSelect :: Tree a -> TreeCursor a -> Maybe (TreeCursor a) treeCursorInsertAndSelect = TC.treeCursorInsertAndSelect id id +treeCursorInsertNodeSingleAndSelect :: a -> TreeCursor a -> Maybe (TreeCursor a)+treeCursorInsertNodeSingleAndSelect = TC.treeCursorInsertNodeSingleAndSelect id++treeCursorInsertNodeAndSelect :: a -> CForest a -> TreeCursor a -> Maybe (TreeCursor a)+treeCursorInsertNodeAndSelect = TC.treeCursorInsertNodeAndSelect id+ treeCursorAppendAndSelect :: Tree a -> TreeCursor a -> Maybe (TreeCursor a) treeCursorAppendAndSelect = TC.treeCursorAppendAndSelect id id++treeCursorAppendNodeSingleAndSelect :: a -> TreeCursor a -> Maybe (TreeCursor a)+treeCursorAppendNodeSingleAndSelect = TC.treeCursorAppendNodeSingleAndSelect id++treeCursorAppendNodeAndSelect :: a -> CForest a -> TreeCursor a -> Maybe (TreeCursor a)+treeCursorAppendNodeAndSelect = TC.treeCursorAppendNodeAndSelect id++treeCursorAddChildAtPosAndSelect :: Int -> Tree a -> TreeCursor a -> TreeCursor a+treeCursorAddChildAtPosAndSelect = TC.treeCursorAddChildAtPosAndSelect id id++treeCursorAddChildAtStartAndSelect :: Tree a -> TreeCursor a -> TreeCursor a+treeCursorAddChildAtStartAndSelect = TC.treeCursorAddChildAtStartAndSelect id id++treeCursorAddChildAtEndAndSelect :: Tree a -> TreeCursor a -> TreeCursor a+treeCursorAddChildAtEndAndSelect = TC.treeCursorAddChildAtEndAndSelect id id++treeCursorAddChildNodeSingleAtPosAndSelect :: Int -> a -> TreeCursor a -> TreeCursor a+treeCursorAddChildNodeSingleAtPosAndSelect = TC.treeCursorAddChildNodeSingleAtPosAndSelect id++treeCursorAddChildNodeSingleAtStartAndSelect :: a -> TreeCursor a -> TreeCursor a+treeCursorAddChildNodeSingleAtStartAndSelect = TC.treeCursorAddChildNodeSingleAtStartAndSelect id++treeCursorAddChildNodeSingleAtEndAndSelect :: a -> TreeCursor a -> TreeCursor a+treeCursorAddChildNodeSingleAtEndAndSelect = TC.treeCursorAddChildNodeSingleAtEndAndSelect id++treeCursorAddChildNodeAtPosAndSelect :: Int -> a -> Forest a -> TreeCursor a -> TreeCursor a+treeCursorAddChildNodeAtPosAndSelect = TC.treeCursorAddChildNodeAtPosAndSelect id++treeCursorAddChildNodeAtStartAndSelect :: a -> Forest a -> TreeCursor a -> TreeCursor a+treeCursorAddChildNodeAtStartAndSelect = TC.treeCursorAddChildNodeAtStartAndSelect id++treeCursorAddChildNodeAtEndAndSelect :: a -> Forest a -> TreeCursor a -> TreeCursor a+treeCursorAddChildNodeAtEndAndSelect = TC.treeCursorAddChildNodeAtEndAndSelect id  treeCursorDeleteSubTreeAndSelectPrevious :: TreeCursor a -> Maybe (DeleteOrUpdate (TreeCursor a)) treeCursorDeleteSubTreeAndSelectPrevious = TC.treeCursorDeleteSubTreeAndSelectPrevious id
src/Cursor/Text.hs view
@@ -2,57 +2,62 @@ {-# LANGUAGE TypeFamilies #-}  module Cursor.Text-  ( TextCursor(..)-  , emptyTextCursor-  , makeTextCursor-  , makeTextCursorWithSelection-  , rebuildTextCursor-  , textCursorNull-  , textCursorLength-  , textCursorIndex-  , textCursorSelectPrev-  , textCursorSelectNext-  , textCursorSelectIndex-  , textCursorSelectStart-  , textCursorSelectEnd-  , textCursorPrevChar-  , textCursorNextChar-  , textCursorInsert-  , textCursorAppend-  , textCursorRemove-  , textCursorDelete-  , textCursorSplit-  , textCursorCombine-  ) where--import Data.Validity-import GHC.Generics (Generic)--import qualified Data.Text as T-import Data.Text (Text)+  ( TextCursor (..),+    emptyTextCursor,+    makeTextCursor,+    makeTextCursorWithSelection,+    rebuildTextCursor,+    textCursorNull,+    textCursorLength,+    textCursorIndex,+    textCursorSelectPrev,+    textCursorSelectNext,+    textCursorSelectIndex,+    textCursorSelectStart,+    textCursorSelectEnd,+    textCursorPrevChar,+    textCursorNextChar,+    textCursorSelectBeginWord,+    textCursorSelectEndWord,+    textCursorSelectNextWord,+    textCursorSelectPrevWord,+    textCursorInsert,+    textCursorAppend,+    textCursorInsertString,+    textCursorAppendString,+    textCursorInsertText,+    textCursorAppendText,+    textCursorRemove,+    textCursorDelete,+    textCursorSplit,+    textCursorCombine,+  )+where  import Control.DeepSeq--import Lens.Micro- import Cursor.List import Cursor.Types+import Data.Char+import Data.Text (Text)+import qualified Data.Text as T+import Data.Validity+import GHC.Generics (Generic)+import Lens.Micro  -- | A cursor for single-line texts-newtype TextCursor =-  TextCursor-    { textCursorList :: ListCursor Char-    }+newtype TextCursor = TextCursor+  { textCursorList :: ListCursor Char+  }   deriving (Show, Eq, Generic)  instance Validity TextCursor where   validate (TextCursor lc) =     mconcat-      [ genericValidate lc-      , decorateList (rebuildListCursor lc) $ \c ->+      [ genericValidate lc,+        decorateList (rebuildListCursor lc) $ \c ->           mconcat-            [ declare "The character is not a newline character" $ c /= '\n'-            , declare "The character is a safe character" $ isSafeChar c+            [ declare "The character is not a newline character" $ c /= '\n',+              declare "The character is a safe character" $ isSafeChar c             ]       ] @@ -74,7 +79,7 @@ rebuildTextCursor = T.pack . rebuildListCursor . textCursorList  textCursorListCursorL ::-     Functor f => (ListCursor Char -> f (ListCursor Char)) -> TextCursor -> f TextCursor+  Functor f => (ListCursor Char -> f (ListCursor Char)) -> TextCursor -> f TextCursor textCursorListCursorL = lens textCursorList (\tc lc -> tc {textCursorList = lc})  textCursorNull :: TextCursor -> Bool@@ -107,6 +112,80 @@ textCursorNextChar :: TextCursor -> Maybe Char textCursorNextChar = listCursorNextItem . textCursorList +-- | Move to the beginning of the word+--+-- * @"hell|o"@ -> @"|hello"@+-- * @"hello   | world"@ -> @"|hello    world"@+-- * @"hello |world"@ -> @"hello |world"@+-- * @"| hello"@ -> @"| hello"@+textCursorSelectBeginWord :: TextCursor -> TextCursor+textCursorSelectBeginWord tc =+  let goLeft = maybe tc textCursorSelectBeginWord (textCursorSelectPrev tc)+   in case textCursorPrevChar tc of+        Nothing -> tc+        Just p+          | isSpace p -> case textCursorNextChar tc of+            Nothing -> goLeft+            Just n+              | isSpace n -> goLeft+              | otherwise -> tc+          | otherwise -> goLeft++-- | Move to the end of the word+--+-- * @"hell|o"@ -> @"hello|"@+-- * @"hello   | world"@ -> @"hello    world|"@+-- * @"hello| world"@ -> @"hello| world"@+-- * @"hello |"@ -> @"hello |"@+textCursorSelectEndWord :: TextCursor -> TextCursor+textCursorSelectEndWord tc =+  let goRight = maybe tc textCursorSelectEndWord (textCursorSelectNext tc)+   in case textCursorNextChar tc of+        Nothing -> tc+        Just p+          | isSpace p -> case textCursorPrevChar tc of+            Nothing -> goRight+            Just n+              | isSpace n -> goRight+              | otherwise -> tc+          | otherwise -> goRight++-- | Move to the beginning of the next word+--+-- * @"|hello"@ -> @"hello|"@+-- * @"hell|o world"@ -> @"hello |world"@+-- * @"hello| world"@ -> @"hello |world"@+-- * @"hello |"@ -> @"hello |"@+textCursorSelectNextWord :: TextCursor -> TextCursor+textCursorSelectNextWord tc =+  case (textCursorPrevChar tc, textCursorNextChar tc) of+    (_, Nothing) -> tc+    (Just p, Just n) ->+      case (isSpace p, isSpace n) of+        (_, True) -> TextCursor $ listCursorNextUntil (not . isSpace) lc+        _ -> textCursorSelectNextWord . TextCursor $ listCursorNextUntil isSpace lc+    _ -> textCursorSelectNextWord $ TextCursor $ listCursorNextUntil isSpace lc+  where+    lc = textCursorList tc++-- | Move to the end of the previous word+--+-- * @"hello|"@ -> @"|hello"@+-- * @"hello w|orld"@ -> @"hello| world"@+-- * @"hello |world"@ -> @"hello| world"@+-- * @" h|ello"@ -> @"| hello"@+textCursorSelectPrevWord :: TextCursor -> TextCursor+textCursorSelectPrevWord tc =+  case (textCursorPrevChar tc, textCursorNextChar tc) of+    (Nothing, _) -> tc+    (Just p, Just n) ->+      case (isSpace p, isSpace n) of+        (True, _) -> TextCursor $ listCursorPrevUntil (not . isSpace) lc+        _ -> textCursorSelectPrevWord . TextCursor $ listCursorPrevUntil isSpace lc+    _ -> textCursorSelectPrevWord . TextCursor $ listCursorPrevUntil isSpace lc+  where+    lc = textCursorList tc+ textCursorInsert :: Char -> TextCursor -> Maybe TextCursor textCursorInsert '\n' _ = Nothing textCursorInsert c tc =@@ -120,6 +199,24 @@   if isSafeChar c     then Just (tc & textCursorListCursorL %~ listCursorAppend c)     else Nothing++textCursorInsertString :: String -> TextCursor -> Maybe TextCursor+textCursorInsertString s tc =+  if any (\c -> c == '\n' || not (isSafeChar c)) s+    then Nothing+    else Just $ tc & textCursorListCursorL %~ listCursorInsertList s++textCursorAppendString :: String -> TextCursor -> Maybe TextCursor+textCursorAppendString s tc =+  if any (\c -> c == '\n' || not (isSafeChar c)) s+    then Nothing+    else Just $ tc & textCursorListCursorL %~ listCursorAppendList s++textCursorInsertText :: Text -> TextCursor -> Maybe TextCursor+textCursorInsertText = textCursorInsertString . T.unpack++textCursorAppendText :: Text -> TextCursor -> Maybe TextCursor+textCursorAppendText = textCursorAppendString . T.unpack  textCursorRemove :: TextCursor -> Maybe (DeleteOrUpdate TextCursor) textCursorRemove = focusPossibleDeleteOrUpdate textCursorListCursorL listCursorRemove
src/Cursor/TextField.hs view
@@ -4,67 +4,67 @@ {-# LANGUAGE TypeFamilies #-}  module Cursor.TextField-  ( TextFieldCursor(..)-  , makeTextFieldCursor-  , makeTextFieldCursorWithSelection-  , rebuildTextFieldCursorLines-  , rebuildTextFieldCursor-  , emptyTextFieldCursor-  , nullTextFieldCursor-  , textFieldCursorSelection-  , textFieldCursorNonEmptyCursorL-  , textFieldCursorSelectedL-  , textFieldCursorSelectPrevLine-  , textFieldCursorSelectNextLine-  , textFieldCursorSelectFirstLine-  , textFieldCursorSelectLastLine-  , textFieldCursorSelectPrevChar-  , textFieldCursorSelectNextChar-  , textFieldCursorIndexOnLine-  , textFieldCursorSelectIndexOnLine-  , textFieldCursorInsertChar-  , textFieldCursorAppendChar-  , textFieldCursorInsertNewline-  , textFieldCursorAppendNewline-  , textFieldCursorRemove-  , textFieldCursorDelete-  , textFieldCursorSelectStartOfLine-  , textFieldCursorSelectEndOfLine-  ) where--import GHC.Generics (Generic)--import Data.Validity-import Data.Validity.Text ()--import Data.List.NonEmpty (NonEmpty(..))-import qualified Data.List.NonEmpty as NE-import Data.Maybe-import qualified Data.Text as T-import Data.Text (Text)+  ( TextFieldCursor (..),+    makeTextFieldCursor,+    makeTextFieldCursorWithSelection,+    rebuildTextFieldCursorLines,+    rebuildTextFieldCursor,+    emptyTextFieldCursor,+    nullTextFieldCursor,+    textFieldCursorSelection,+    textFieldCursorNonEmptyCursorL,+    textFieldCursorSelectedL,+    textFieldCursorSelectPrevLine,+    textFieldCursorSelectNextLine,+    textFieldCursorSelectFirstLine,+    textFieldCursorSelectLastLine,+    textFieldCursorSelectPrevChar,+    textFieldCursorSelectNextChar,+    textFieldCursorSelectPrevWord,+    textFieldCursorSelectNextWord,+    textFieldCursorSelectBeginWord,+    textFieldCursorSelectEndWord,+    textFieldCursorIndexOnLine,+    textFieldCursorSelectIndexOnLine,+    textFieldCursorInsertChar,+    textFieldCursorAppendChar,+    textFieldCursorInsertNewline,+    textFieldCursorAppendNewline,+    textFieldCursorRemove,+    textFieldCursorDelete,+    textFieldCursorSelectStartOfLine,+    textFieldCursorSelectEndOfLine,+  )+where  import Control.DeepSeq import Control.Monad--import Lens.Micro- import Cursor.List.NonEmpty import Cursor.Text import Cursor.Types+import Data.List.NonEmpty (NonEmpty (..))+import qualified Data.List.NonEmpty as NE+import Data.Maybe+import Data.Text (Text)+import qualified Data.Text as T+import Data.Validity+import Data.Validity.Text ()+import GHC.Generics (Generic)+import Lens.Micro -newtype TextFieldCursor =-  TextFieldCursor-    { textFieldCursorNonEmpty :: NonEmptyCursor TextCursor Text-    }+newtype TextFieldCursor = TextFieldCursor+  { textFieldCursorNonEmpty :: NonEmptyCursor TextCursor Text+  }   deriving (Show, Eq, Generic)  instance Validity TextFieldCursor where   validate tfc@TextFieldCursor {..} =     mconcat-      [ genericValidate tfc-      , decorate "None of the texts contain newlines" $-        decorateList (NE.toList $ rebuildNonEmptyCursor rebuildTextCursor textFieldCursorNonEmpty) $ \tc ->-          declare "The text of this line does not contain any newlines" $ T.all (/= '\n') tc+      [ genericValidate tfc,+        decorate "None of the texts contain newlines" $+          decorateList (NE.toList $ rebuildNonEmptyCursor rebuildTextCursor textFieldCursorNonEmpty) $+            \tc ->+              declare "The text of this line does not contain any newlines" $ T.all (/= '\n') tc       ]  instance NFData TextFieldCursor@@ -97,8 +97,9 @@  textFieldCursorSelection :: TextFieldCursor -> (Int, Int) textFieldCursorSelection tfc =-  ( nonEmptyCursorSelection $ textFieldCursorNonEmpty tfc-  , textCursorIndex $ textFieldCursorNonEmpty tfc ^. nonEmptyCursorElemL)+  ( nonEmptyCursorSelection $ textFieldCursorNonEmpty tfc,+    textCursorIndex $ textFieldCursorNonEmpty tfc ^. nonEmptyCursorElemL+  )  textFieldCursorNonEmptyCursorL :: Lens' TextFieldCursor (NonEmptyCursor TextCursor Text) textFieldCursorNonEmptyCursorL =@@ -116,9 +117,9 @@   moveMWhileKeepingSelection $ nonEmptyCursorSelectNext rebuildTextCursor unsafeMakeTextCursor  moveMWhileKeepingSelection ::-     (NonEmptyCursor TextCursor Text -> Maybe (NonEmptyCursor TextCursor Text))-  -> TextFieldCursor-  -> Maybe TextFieldCursor+  (NonEmptyCursor TextCursor Text -> Maybe (NonEmptyCursor TextCursor Text)) ->+  TextFieldCursor ->+  Maybe TextFieldCursor moveMWhileKeepingSelection movement tfc = do   let i = textFieldCursorIndexOnLine tfc   let tfc' = textFieldCursorSelectIndexOnLine 0 tfc@@ -134,9 +135,9 @@   moveWhileKeepingSelection $ nonEmptyCursorSelectLast rebuildTextCursor unsafeMakeTextCursor  moveWhileKeepingSelection ::-     (NonEmptyCursor TextCursor Text -> NonEmptyCursor TextCursor Text)-  -> TextFieldCursor-  -> TextFieldCursor+  (NonEmptyCursor TextCursor Text -> NonEmptyCursor TextCursor Text) ->+  TextFieldCursor ->+  TextFieldCursor moveWhileKeepingSelection movement tfc =   let i = textFieldCursorIndexOnLine tfc       tfc' = textFieldCursorSelectIndexOnLine 0 tfc@@ -149,6 +150,18 @@ textFieldCursorSelectNextChar :: TextFieldCursor -> Maybe TextFieldCursor textFieldCursorSelectNextChar = textFieldCursorSelectedL textCursorSelectNext +textFieldCursorSelectBeginWord :: TextFieldCursor -> TextFieldCursor+textFieldCursorSelectBeginWord = textFieldCursorSelectedL %~ textCursorSelectBeginWord++textFieldCursorSelectEndWord :: TextFieldCursor -> TextFieldCursor+textFieldCursorSelectEndWord = textFieldCursorSelectedL %~ textCursorSelectEndWord++textFieldCursorSelectPrevWord :: TextFieldCursor -> TextFieldCursor+textFieldCursorSelectPrevWord = textFieldCursorSelectedL %~ textCursorSelectPrevWord++textFieldCursorSelectNextWord :: TextFieldCursor -> TextFieldCursor+textFieldCursorSelectNextWord = textFieldCursorSelectedL %~ textCursorSelectNextWord+ textFieldCursorIndexOnLine :: TextFieldCursor -> Int textFieldCursorIndexOnLine tfc = textCursorIndex $ tfc ^. textFieldCursorSelectedL @@ -165,8 +178,8 @@     _       | isSafeChar c ->         Just $-        fromMaybe emptyTextFieldCursor mtfc &-        textFieldCursorSelectedL %~ (fromJust . textCursorInsert c)+          fromMaybe emptyTextFieldCursor mtfc+            & textFieldCursorSelectedL %~ (fromJust . textCursorInsert c)       | otherwise -> Nothing  -- |@@ -179,77 +192,83 @@     _       | isSafeChar c ->         Just $-        fromMaybe emptyTextFieldCursor mtfc &-        textFieldCursorSelectedL %~ (fromJust . textCursorAppend c)+          fromMaybe emptyTextFieldCursor mtfc+            & textFieldCursorSelectedL %~ (fromJust . textCursorAppend c)       | otherwise -> Nothing  textFieldCursorInsertNewline :: Maybe TextFieldCursor -> TextFieldCursor textFieldCursorInsertNewline mtfc =   let tfc = fromMaybe emptyTextFieldCursor mtfc-   in tfc &-      textFieldCursorNonEmptyCursorL %~-      (\lec@NonEmptyCursor {..} ->-         let (tc1, tc2) = textCursorSplit nonEmptyCursorCurrent-          in lec-               { nonEmptyCursorPrev = rebuildTextCursor tc1 : nonEmptyCursorPrev-               , nonEmptyCursorCurrent = tc2-               })+   in tfc+        & textFieldCursorNonEmptyCursorL+        %~ ( \lec@NonEmptyCursor {..} ->+               let (tc1, tc2) = textCursorSplit nonEmptyCursorCurrent+                in lec+                     { nonEmptyCursorPrev = rebuildTextCursor tc1 : nonEmptyCursorPrev,+                       nonEmptyCursorCurrent = tc2+                     }+           )  textFieldCursorAppendNewline :: Maybe TextFieldCursor -> TextFieldCursor textFieldCursorAppendNewline mtfc =   let tfc = fromMaybe emptyTextFieldCursor mtfc-   in tfc &-      textFieldCursorNonEmptyCursorL %~-      (\lec@NonEmptyCursor {..} ->-         let (tc1, tc2) = textCursorSplit nonEmptyCursorCurrent-          in lec-               { nonEmptyCursorCurrent = tc1-               , nonEmptyCursorNext = rebuildTextCursor tc2 : nonEmptyCursorNext-               })+   in tfc+        & textFieldCursorNonEmptyCursorL+        %~ ( \lec@NonEmptyCursor {..} ->+               let (tc1, tc2) = textCursorSplit nonEmptyCursorCurrent+                in lec+                     { nonEmptyCursorCurrent = tc1,+                       nonEmptyCursorNext = rebuildTextCursor tc2 : nonEmptyCursorNext+                     }+           )  textFieldCursorRemove :: TextFieldCursor -> Maybe (DeleteOrUpdate TextFieldCursor) textFieldCursorRemove tfc =   if nullTextFieldCursor tfc     then Just Deleted-    else focusPossibleDeleteOrUpdate-           textFieldCursorNonEmptyCursorL-           (\lec@NonEmptyCursor {..} ->-              case textCursorRemove nonEmptyCursorCurrent of-                Just (Updated ctc) -> Just $ Updated $ lec & nonEmptyCursorElemL .~ ctc-                _ ->-                  case nonEmptyCursorPrev of-                    [] -> Nothing-                    (pl:pls) ->-                      Just $+    else+      focusPossibleDeleteOrUpdate+        textFieldCursorNonEmptyCursorL+        ( \lec@NonEmptyCursor {..} ->+            case textCursorRemove nonEmptyCursorCurrent of+              Just (Updated ctc) -> Just $ Updated $ lec & nonEmptyCursorElemL .~ ctc+              _ ->+                case nonEmptyCursorPrev of+                  [] -> Nothing+                  (pl : pls) ->+                    Just $                       Updated $-                      lec-                        { nonEmptyCursorPrev = pls-                        , nonEmptyCursorCurrent =-                            textCursorCombine (unsafeMakeTextCursor pl) nonEmptyCursorCurrent-                        })-           tfc+                        lec+                          { nonEmptyCursorPrev = pls,+                            nonEmptyCursorCurrent =+                              textCursorCombine (unsafeMakeTextCursor pl) nonEmptyCursorCurrent+                          }+        )+        tfc  textFieldCursorDelete :: TextFieldCursor -> Maybe (DeleteOrUpdate TextFieldCursor) textFieldCursorDelete tfc =   if nullTextFieldCursor tfc     then Just Deleted-    else focusPossibleDeleteOrUpdate-           textFieldCursorNonEmptyCursorL-           (\lec@NonEmptyCursor {..} ->-              case textCursorDelete nonEmptyCursorCurrent of-                Just (Updated ctc) -> Just $ Updated $ lec & nonEmptyCursorElemL .~ ctc-                _ ->-                  case nonEmptyCursorNext of-                    [] -> Nothing-                    (pl:pls) ->-                      Just $+    else+      focusPossibleDeleteOrUpdate+        textFieldCursorNonEmptyCursorL+        ( \lec@NonEmptyCursor {..} ->+            case textCursorDelete nonEmptyCursorCurrent of+              Just (Updated ctc) -> Just $ Updated $ lec & nonEmptyCursorElemL .~ ctc+              _ ->+                case nonEmptyCursorNext of+                  [] -> Nothing+                  (pl : pls) ->+                    Just $                       Updated $-                      lec-                        { nonEmptyCursorCurrent =-                            textCursorCombine nonEmptyCursorCurrent (unsafeMakeTextCursor pl)-                        , nonEmptyCursorNext = pls-                        })-           tfc+                        lec+                          { nonEmptyCursorCurrent =+                              textCursorCombine nonEmptyCursorCurrent (unsafeMakeTextCursor pl),+                            nonEmptyCursorNext = pls+                          }+        )+        tfc  textFieldCursorSelectStartOfLine :: TextFieldCursor -> TextFieldCursor textFieldCursorSelectStartOfLine = textFieldCursorSelectedL %~ textCursorSelectStart
src/Cursor/Tree.hs view
@@ -1,29 +1,40 @@ {-# OPTIONS_GHC -fno-warn-duplicate-exports #-}  module Cursor.Tree-  ( TreeCursor(..)-  , TreeAbove(..)+  ( TreeCursor (..),+    TreeAbove (..),+     -- * Types-  , module Cursor.Tree.Types+    module Cursor.Tree.Types,+     -- * Construction, destruction-  , module Cursor.Tree.Base+    module Cursor.Tree.Base,+     -- * Drawing-  , module Cursor.Tree.Draw+    module Cursor.Tree.Draw,+     -- * Collapsing-  , module Cursor.Tree.Collapse+    module Cursor.Tree.Collapse,+     -- * Movements-  , module Cursor.Tree.Movement+    module Cursor.Tree.Movement,+     -- * Insertions-  , module Cursor.Tree.Insert+    module Cursor.Tree.Insert,+     -- * Deletions-  , module Cursor.Tree.Delete+    module Cursor.Tree.Delete,+     -- * Swapping-  , module Cursor.Tree.Swap+    module Cursor.Tree.Swap,+     -- * Promotions-  , module Cursor.Tree.Promote+    module Cursor.Tree.Promote,+     -- * Demotions-  , module Cursor.Tree.Demote-  ) where+    module Cursor.Tree.Demote,+  )+where  import Cursor.Tree.Base import Cursor.Tree.Collapse
src/Cursor/Tree/Base.hs view
@@ -3,19 +3,20 @@ {-# LANGUAGE TypeFamilies #-}  module Cursor.Tree.Base-  ( singletonTreeCursor-  , makeTreeCursor-  , makeTreeCursorWithSelection-  , rebuildTreeCursor-  , mapTreeCursor-  , currentTree-  , makeTreeCursorWithAbove-  , traverseTreeCursor-  , foldTreeCursor-  ) where+  ( singletonTreeCursor,+    makeTreeCursor,+    makeNodeTreeCursor,+    makeTreeCursorWithSelection,+    rebuildTreeCursor,+    mapTreeCursor,+    currentTree,+    makeTreeCursorWithAbove,+    traverseTreeCursor,+    foldTreeCursor,+  )+where  import Control.Monad- import Cursor.Tree.Types  singletonTreeCursor :: a -> TreeCursor a b@@ -24,25 +25,28 @@ makeTreeCursor :: (b -> a) -> CTree b -> TreeCursor a b makeTreeCursor g (CNode v fs) = TreeCursor {treeAbove = Nothing, treeCurrent = g v, treeBelow = fs} +makeNodeTreeCursor :: a -> CForest b -> TreeCursor a b+makeNodeTreeCursor v fs = TreeCursor {treeAbove = Nothing, treeCurrent = v, treeBelow = fs}+ makeTreeCursorWithSelection ::-     (a -> b) -> (b -> a) -> TreeCursorSelection -> CTree b -> Maybe (TreeCursor a b)+  (a -> b) -> (b -> a) -> TreeCursorSelection -> CTree b -> Maybe (TreeCursor a b) makeTreeCursorWithSelection f g sel = walkDown sel . makeTreeCursor g   where     walkDown SelectNode tc = pure tc     walkDown (SelectChild i s) TreeCursor {..} =       (walkDown s =<<) $-      case splitAt i $ unpackCForest treeBelow of-        (_, []) -> Nothing-        (lefts, current:rights) ->-          Just $-          makeTreeCursorWithAbove g current $-          Just $-          TreeAbove-            { treeAboveLefts = reverse lefts-            , treeAboveAbove = treeAbove-            , treeAboveNode = f treeCurrent-            , treeAboveRights = rights-            }+        case splitAt i $ unpackCForest treeBelow of+          (_, []) -> Nothing+          (lefts, current : rights) ->+            Just $+              makeTreeCursorWithAbove g current $+                Just $+                  TreeAbove+                    { treeAboveLefts = reverse lefts,+                      treeAboveAbove = treeAbove,+                      treeAboveNode = f treeCurrent,+                      treeAboveRights = rights+                    }  rebuildTreeCursor :: (a -> b) -> TreeCursor a b -> CTree b rebuildTreeCursor f TreeCursor {..} = wrapAbove treeAbove $ CNode (f treeCurrent) treeBelow@@ -50,12 +54,17 @@     wrapAbove Nothing t = t     wrapAbove (Just TreeAbove {..}) t =       wrapAbove treeAboveAbove $-      CNode treeAboveNode $ openForest $ concat [reverse treeAboveLefts, [t], treeAboveRights]+        CNode treeAboveNode $+          openForest $+            concat [reverse treeAboveLefts, [t], treeAboveRights]  mapTreeCursor :: (a -> c) -> (b -> d) -> TreeCursor a b -> TreeCursor c d mapTreeCursor f g TreeCursor {..} =   TreeCursor-    {treeAbove = fmap g <$> treeAbove, treeCurrent = f treeCurrent, treeBelow = fmap g treeBelow}+    { treeAbove = fmap g <$> treeAbove,+      treeCurrent = f treeCurrent,+      treeBelow = fmap g treeBelow+    }  currentTree :: (a -> b) -> TreeCursor a b -> CTree b currentTree f TreeCursor {..} = CNode (f treeCurrent) treeBelow@@ -65,11 +74,12 @@   TreeCursor {treeAbove = mta, treeCurrent = g a, treeBelow = forest}  traverseTreeCursor ::-     forall a b m c. Monad m-  => ([CTree b] -> b -> [CTree b] -> c -> m c)-  -> (a -> CForest b -> m c)-  -> TreeCursor a b-  -> m c+  forall a b m c.+  Monad m =>+  ([CTree b] -> b -> [CTree b] -> c -> m c) ->+  (a -> CForest b -> m c) ->+  TreeCursor a b ->+  m c traverseTreeCursor wrapFunc currentFunc TreeCursor {..} =   currentFunc treeCurrent treeBelow >>= wrapAbove treeAbove   where@@ -81,11 +91,11 @@       wrapFunc (reverse treeAboveLefts) treeAboveNode treeAboveRights >=> wrapAbove treeAboveAbove  foldTreeCursor ::-     forall a b c.-     ([CTree b] -> b -> [CTree b] -> c -> c)-  -> (a -> CForest b -> c)-  -> TreeCursor a b-  -> c+  forall a b c.+  ([CTree b] -> b -> [CTree b] -> c -> c) ->+  (a -> CForest b -> c) ->+  TreeCursor a b ->+  c foldTreeCursor wrapFunc currentFunc TreeCursor {..} =   wrapAbove treeAbove $ currentFunc treeCurrent treeBelow   where
src/Cursor/Tree/Collapse.hs view
@@ -1,14 +1,14 @@ module Cursor.Tree.Collapse-  ( treeCursorOpenCurrentForest-  , treeCursorCloseCurrentForest-  , treeCursorToggleCurrentForest-  , treeCursorOpenCurrentForestRecursively-  , treeCursorToggleCurrentForestRecursively-  ) where--import qualified Data.List.NonEmpty as NE+  ( treeCursorOpenCurrentForest,+    treeCursorCloseCurrentForest,+    treeCursorToggleCurrentForest,+    treeCursorOpenCurrentForestRecursively,+    treeCursorToggleCurrentForestRecursively,+  )+where  import Cursor.Tree.Types+import qualified Data.List.NonEmpty as NE  treeCursorOpenCurrentForest :: TreeCursor a b -> Maybe (TreeCursor a b) treeCursorOpenCurrentForest tc =
src/Cursor/Tree/Delete.hs view
@@ -2,77 +2,76 @@ {-# LANGUAGE TypeFamilies #-}  module Cursor.Tree.Delete-  ( treeCursorDeleteSubTreeAndSelectPrevious-  , treeCursorDeleteSubTreeAndSelectNext-  , treeCursorDeleteSubTreeAndSelectAbove-  , treeCursorRemoveSubTree-  , treeCursorDeleteSubTree-  , treeCursorDeleteElemAndSelectPrevious-  , treeCursorDeleteElemAndSelectNext-  , treeCursorDeleteElemAndSelectAbove-  , treeCursorRemoveElem-  , treeCursorDeleteElem-  ) where--import Data.List.NonEmpty (NonEmpty(..))-import qualified Data.List.NonEmpty as NE-import Data.Tree+  ( treeCursorDeleteSubTreeAndSelectPrevious,+    treeCursorDeleteSubTreeAndSelectNext,+    treeCursorDeleteSubTreeAndSelectAbove,+    treeCursorRemoveSubTree,+    treeCursorDeleteSubTree,+    treeCursorDeleteElemAndSelectPrevious,+    treeCursorDeleteElemAndSelectNext,+    treeCursorDeleteElemAndSelectAbove,+    treeCursorRemoveElem,+    treeCursorDeleteElem,+  )+where  import Control.Applicative- import Cursor.Tree.Base import Cursor.Tree.Types import Cursor.Types+import Data.List.NonEmpty (NonEmpty (..))+import qualified Data.List.NonEmpty as NE+import Data.Tree  treeCursorDeleteSubTreeAndSelectPrevious ::-     (b -> a) -> TreeCursor a b -> Maybe (DeleteOrUpdate (TreeCursor a b))+  (b -> a) -> TreeCursor a b -> Maybe (DeleteOrUpdate (TreeCursor a b)) treeCursorDeleteSubTreeAndSelectPrevious g TreeCursor {..} =   case treeAbove of     Nothing -> Just Deleted     Just ta ->       case treeAboveLefts ta of         [] -> Nothing-        tree:xs -> Just . Updated . makeTreeCursorWithAbove g tree $ Just ta {treeAboveLefts = xs}+        tree : xs -> Just . Updated . makeTreeCursorWithAbove g tree $ Just ta {treeAboveLefts = xs}  treeCursorDeleteSubTreeAndSelectNext ::-     (b -> a) -> TreeCursor a b -> Maybe (DeleteOrUpdate (TreeCursor a b))+  (b -> a) -> TreeCursor a b -> Maybe (DeleteOrUpdate (TreeCursor a b)) treeCursorDeleteSubTreeAndSelectNext g TreeCursor {..} =   case treeAbove of     Nothing -> Just Deleted     Just ta ->       case treeAboveRights ta of         [] -> Nothing-        tree:xs -> Just . Updated . makeTreeCursorWithAbove g tree $ Just ta {treeAboveRights = xs}+        tree : xs -> Just . Updated . makeTreeCursorWithAbove g tree $ Just ta {treeAboveRights = xs}  treeCursorDeleteSubTreeAndSelectAbove ::-     (b -> a) -> TreeCursor a b -> DeleteOrUpdate (TreeCursor a b)+  (b -> a) -> TreeCursor a b -> DeleteOrUpdate (TreeCursor a b) treeCursorDeleteSubTreeAndSelectAbove g TreeCursor {..} =   case treeAbove of     Nothing -> Deleted     Just TreeAbove {..} ->       Updated $-      TreeCursor-        { treeAbove = treeAboveAbove-        , treeCurrent = g treeAboveNode-        , treeBelow = openForest $ reverse treeAboveLefts ++ treeAboveRights-        }+        TreeCursor+          { treeAbove = treeAboveAbove,+            treeCurrent = g treeAboveNode,+            treeBelow = openForest $ reverse treeAboveLefts ++ treeAboveRights+          }  treeCursorRemoveSubTree :: (b -> a) -> TreeCursor a b -> DeleteOrUpdate (TreeCursor a b) treeCursorRemoveSubTree g tc =   joinDeletes     (treeCursorDeleteSubTreeAndSelectPrevious g tc)-    (treeCursorDeleteSubTreeAndSelectNext g tc) <|>-  treeCursorDeleteSubTreeAndSelectAbove g tc+    (treeCursorDeleteSubTreeAndSelectNext g tc)+    <|> treeCursorDeleteSubTreeAndSelectAbove g tc  treeCursorDeleteSubTree :: (b -> a) -> TreeCursor a b -> DeleteOrUpdate (TreeCursor a b) treeCursorDeleteSubTree g tc =   joinDeletes     (treeCursorDeleteSubTreeAndSelectNext g tc)-    (treeCursorDeleteSubTreeAndSelectPrevious g tc) <|>-  treeCursorDeleteSubTreeAndSelectAbove g tc+    (treeCursorDeleteSubTreeAndSelectPrevious g tc)+    <|> treeCursorDeleteSubTreeAndSelectAbove g tc  treeCursorDeleteElemAndSelectPrevious ::-     (b -> a) -> TreeCursor a b -> Maybe (DeleteOrUpdate (TreeCursor a b))+  (b -> a) -> TreeCursor a b -> Maybe (DeleteOrUpdate (TreeCursor a b)) treeCursorDeleteElemAndSelectPrevious g TreeCursor {..} =   case treeAbove of     Nothing ->@@ -82,14 +81,16 @@     Just ta ->       case treeAboveLefts ta of         [] -> Nothing-        tree:xs ->+        tree : xs ->           Just . Updated . makeTreeCursorWithAbove g tree $-          Just-            ta-              {treeAboveLefts = xs, treeAboveRights = unpackCForest treeBelow ++ treeAboveRights ta}+            Just+              ta+                { treeAboveLefts = xs,+                  treeAboveRights = unpackCForest treeBelow ++ treeAboveRights ta+                }  treeCursorDeleteElemAndSelectNext ::-     (b -> a) -> TreeCursor a b -> Maybe (DeleteOrUpdate (TreeCursor a b))+  (b -> a) -> TreeCursor a b -> Maybe (DeleteOrUpdate (TreeCursor a b)) treeCursorDeleteElemAndSelectNext g TreeCursor {..} =   case treeBelow of     EmptyCForest ->@@ -98,7 +99,7 @@         Just ta ->           case treeAboveRights ta of             [] -> Nothing-            tree:xs ->+            tree : xs ->               Just . Updated . makeTreeCursorWithAbove g tree $ Just ta {treeAboveRights = xs}     ClosedForest ts ->       case treeAbove of@@ -110,24 +111,24 @@         Just ta ->           case treeAboveRights ta of             [] -> Nothing-            tree:xs ->+            tree : xs ->               Just . Updated . makeTreeCursorWithAbove g tree $-              Just-                ta-                  { treeAboveLefts = map makeCTree (reverse $ NE.toList ts) ++ treeAboveLefts ta-                  , treeAboveRights = xs-                  }+                Just+                  ta+                    { treeAboveLefts = map makeCTree (reverse $ NE.toList ts) ++ treeAboveLefts ta,+                      treeAboveRights = xs+                    }     OpenForest (CNode e ts :| xs) ->       let t =             CNode e $-            case ts of-              EmptyCForest -> openForest xs-              OpenForest ts_ -> openForest $ NE.toList ts_ ++ xs-              ClosedForest ts_ -> closedForest $ NE.toList ts_ ++ map rebuildCTree xs+              case ts of+                EmptyCForest -> openForest xs+                OpenForest ts_ -> openForest $ NE.toList ts_ ++ xs+                ClosedForest ts_ -> closedForest $ NE.toList ts_ ++ map rebuildCTree xs        in Just . Updated $ makeTreeCursorWithAbove g t treeAbove  treeCursorDeleteElemAndSelectAbove ::-     (b -> a) -> TreeCursor a b -> Maybe (DeleteOrUpdate (TreeCursor a b))+  (b -> a) -> TreeCursor a b -> Maybe (DeleteOrUpdate (TreeCursor a b)) treeCursorDeleteElemAndSelectAbove g TreeCursor {..} =   case treeAbove of     Nothing ->@@ -136,13 +137,13 @@         _ -> Nothing     Just TreeAbove {..} ->       Just $-      Updated $-      TreeCursor-        { treeAbove = treeAboveAbove-        , treeCurrent = g treeAboveNode-        , treeBelow =-            openForest $ reverse treeAboveLefts ++ unpackCForest treeBelow ++ treeAboveRights-        }+        Updated $+          TreeCursor+            { treeAbove = treeAboveAbove,+              treeCurrent = g treeAboveNode,+              treeBelow =+                openForest $ reverse treeAboveLefts ++ unpackCForest treeBelow ++ treeAboveRights+            }  treeCursorRemoveElem :: (b -> a) -> TreeCursor a b -> DeleteOrUpdate (TreeCursor a b) treeCursorRemoveElem g tc =
src/Cursor/Tree/Demote.hs view
@@ -1,23 +1,21 @@+{-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE DeriveFunctor #-}  module Cursor.Tree.Demote-  ( treeCursorDemoteElem-  , treeCursorDemoteSubTree-  , DemoteResult(..)-  , treeCursorDemoteElemUnder-  , treeCursorDemoteSubTreeUnder-  ) where--import GHC.Generics (Generic)--import Data.Validity+  ( treeCursorDemoteElem,+    treeCursorDemoteSubTree,+    DemoteResult (..),+    treeCursorDemoteElemUnder,+    treeCursorDemoteSubTreeUnder,+  )+where  import Control.DeepSeq- import Cursor.Tree.Base import Cursor.Tree.Types+import Data.Validity+import GHC.Generics (Generic)  -- | Demotes the current node to the level of its children. --@@ -47,16 +45,16 @@     Just ta ->       case treeAboveLefts ta of         [] -> NoSiblingsToDemoteUnder-        (CNode t ls:ts) ->+        (CNode t ls : ts) ->           Demoted $-          makeTreeCursorWithAbove g (CNode (f $ treeCurrent tc) emptyCForest) $-          Just-            TreeAbove-              { treeAboveLefts = reverse $ unpackCForest ls-              , treeAboveAbove = Just ta {treeAboveLefts = ts}-              , treeAboveNode = t-              , treeAboveRights = unpackCForest $ treeBelow tc-              }+            makeTreeCursorWithAbove g (CNode (f $ treeCurrent tc) emptyCForest) $+              Just+                TreeAbove+                  { treeAboveLefts = reverse $ unpackCForest ls,+                    treeAboveAbove = Just ta {treeAboveLefts = ts},+                    treeAboveNode = t,+                    treeAboveRights = unpackCForest $ treeBelow tc+                  }  -- | Demotes the current subtree to the level of its children. --@@ -86,16 +84,16 @@     Just ta ->       case treeAboveLefts ta of         [] -> NoSiblingsToDemoteUnder-        (CNode t ls:ts) ->+        (CNode t ls : ts) ->           Demoted $-          makeTreeCursorWithAbove g (currentTree f tc) $-          Just-            TreeAbove-              { treeAboveLefts = reverse $ unpackCForest ls-              , treeAboveAbove = Just ta {treeAboveLefts = ts}-              , treeAboveNode = t-              , treeAboveRights = []-              }+            makeTreeCursorWithAbove g (currentTree f tc) $+              Just+                TreeAbove+                  { treeAboveLefts = reverse $ unpackCForest ls,+                    treeAboveAbove = Just ta {treeAboveLefts = ts},+                    treeAboveNode = t,+                    treeAboveRights = []+                  }  data DemoteResult a   = CannotDemoteTopNode@@ -134,12 +132,12 @@       { treeAbove =           Just             TreeAbove-              { treeAboveLefts = []-              , treeAboveAbove = Just ta'-              , treeAboveNode = b1-              , treeAboveRights = []-              }-      , treeBelow = emptyCForest+              { treeAboveLefts = [],+                treeAboveAbove = Just ta',+                treeAboveNode = b1,+                treeAboveRights = []+              },+        treeBelow = emptyCForest       }  -- | Demotes the current subtree to the level of its children, by adding a root.@@ -162,9 +160,9 @@     { treeAbove =         Just           TreeAbove-            { treeAboveLefts = []-            , treeAboveAbove = treeAbove tc-            , treeAboveNode = b-            , treeAboveRights = []+            { treeAboveLefts = [],+              treeAboveAbove = treeAbove tc,+              treeAboveNode = b,+              treeAboveRights = []             }     }
src/Cursor/Tree/Draw.hs view
@@ -2,19 +2,19 @@ {-# LANGUAGE TypeFamilies #-}  module Cursor.Tree.Draw-  ( drawTreeCursor-  , treeCursorWithPointer-  , showCForest-  , showCTree-  , showForest-  , showTree-  ) where+  ( drawTreeCursor,+    treeCursorWithPointer,+    showCForest,+    showCTree,+    showForest,+    showTree,+  )+where +import Cursor.Tree.Types import qualified Data.List.NonEmpty as NE import Data.Tree -import Cursor.Tree.Types- drawTreeCursor :: (Show a, Show b) => TreeCursor a b -> String drawTreeCursor = drawTree . treeCursorWithPointer @@ -26,8 +26,8 @@     wrapAbove Nothing t = t     wrapAbove (Just TreeAbove {..}) t =       wrapAbove treeAboveAbove $-      Node (show treeAboveNode) $-      concat [map showCTree $ reverse treeAboveLefts, [t], map showCTree treeAboveRights]+        Node (show treeAboveNode) $+          concat [map showCTree $ reverse treeAboveLefts, [t], map showCTree treeAboveRights]  showCForest :: Show a => CForest a -> Forest String showCForest EmptyCForest = []
src/Cursor/Tree/Insert.hs view
@@ -2,22 +2,34 @@ {-# LANGUAGE TypeFamilies #-}  module Cursor.Tree.Insert-  ( treeCursorInsert-  , treeCursorInsertAndSelect-  , treeCursorAppend-  , treeCursorAppendAndSelect-  , treeCursorAddChildAtPos-  , treeCursorAddChildAtStart-  , treeCursorAddChildAtEnd-  ) where+  ( treeCursorInsert,+    treeCursorInsertAndSelect,+    treeCursorInsertNodeSingleAndSelect,+    treeCursorInsertNodeAndSelect,+    treeCursorAppend,+    treeCursorAppendAndSelect,+    treeCursorAppendNodeSingleAndSelect,+    treeCursorAppendNodeAndSelect,+    treeCursorAddChildAtPos,+    treeCursorAddChildAtStart,+    treeCursorAddChildAtEnd,+    treeCursorAddChildAtPosAndSelect,+    treeCursorAddChildAtStartAndSelect,+    treeCursorAddChildAtEndAndSelect,+    treeCursorAddChildNodeSingleAtPosAndSelect,+    treeCursorAddChildNodeSingleAtStartAndSelect,+    treeCursorAddChildNodeSingleAtEndAndSelect,+    treeCursorAddChildNodeAtPosAndSelect,+    treeCursorAddChildNodeAtStartAndSelect,+    treeCursorAddChildNodeAtEndAndSelect,+  )+where -import qualified Data.List.NonEmpty as NE+import Cursor.Tree.Types import Data.List.NonEmpty ((<|))+import qualified Data.List.NonEmpty as NE import Data.Tree -import Cursor.Tree.Base-import Cursor.Tree.Types- treeCursorInsert :: Tree b -> TreeCursor a b -> Maybe (TreeCursor a b) treeCursorInsert tree tc@TreeCursor {..} = do   ta <- treeAbove@@ -25,12 +37,21 @@   pure tc {treeAbove = Just newTreeAbove}  treeCursorInsertAndSelect ::-     (a -> b) -> (b -> a) -> Tree b -> TreeCursor a b -> Maybe (TreeCursor a b)-treeCursorInsertAndSelect f g tree tc@TreeCursor {..} = do-  ta <- treeAbove-  let newTreeAbove = ta {treeAboveRights = currentTree f tc : treeAboveRights ta}-  pure $ makeTreeCursorWithAbove g (makeCTree tree) $ Just newTreeAbove+  (a -> b) -> (b -> a) -> Tree b -> TreeCursor a b -> Maybe (TreeCursor a b)+treeCursorInsertAndSelect f g (Node value forest) = treeCursorInsertNodeAndSelect f (g value) (makeCForest forest) +treeCursorInsertNodeSingleAndSelect ::+  (a -> b) -> a -> TreeCursor a b -> Maybe (TreeCursor a b)+treeCursorInsertNodeSingleAndSelect f a = treeCursorInsertNodeAndSelect f a EmptyCForest++treeCursorInsertNodeAndSelect ::+  (a -> b) -> a -> CForest b -> TreeCursor a b -> Maybe (TreeCursor a b)+treeCursorInsertNodeAndSelect f value forest tc = do+  ta <- treeAbove tc+  let ta' = ta {treeAboveRights = CNode (f (treeCurrent tc)) (treeBelow tc) : treeAboveRights ta}+      tc' = tc {treeAbove = Just ta', treeCurrent = value, treeBelow = forest}+  pure tc'+ treeCursorAppend :: Tree b -> TreeCursor a b -> Maybe (TreeCursor a b) treeCursorAppend tree tc@TreeCursor {..} = do   ta <- treeAbove@@ -38,12 +59,21 @@   pure tc {treeAbove = Just newTreeAbove}  treeCursorAppendAndSelect ::-     (a -> b) -> (b -> a) -> Tree b -> TreeCursor a b -> Maybe (TreeCursor a b)-treeCursorAppendAndSelect f g tree tc@TreeCursor {..} = do-  ta <- treeAbove-  let newTreeAbove = ta {treeAboveLefts = currentTree f tc : treeAboveLefts ta}-  pure $ makeTreeCursorWithAbove g (makeCTree tree) $ Just newTreeAbove+  (a -> b) -> (b -> a) -> Tree b -> TreeCursor a b -> Maybe (TreeCursor a b)+treeCursorAppendAndSelect f g (Node value forest) = treeCursorAppendNodeAndSelect f (g value) (makeCForest forest) +treeCursorAppendNodeSingleAndSelect ::+  (a -> b) -> a -> TreeCursor a b -> Maybe (TreeCursor a b)+treeCursorAppendNodeSingleAndSelect f a = treeCursorAppendNodeAndSelect f a EmptyCForest++treeCursorAppendNodeAndSelect ::+  (a -> b) -> a -> CForest b -> TreeCursor a b -> Maybe (TreeCursor a b)+treeCursorAppendNodeAndSelect f value forest tc = do+  ta <- treeAbove tc+  let ta' = ta {treeAboveLefts = CNode (f (treeCurrent tc)) (treeBelow tc) : treeAboveLefts ta}+      tc' = tc {treeAbove = Just ta', treeCurrent = value, treeBelow = forest}+  pure tc'+ -- TODO make this fail if the position doesn't make sense treeCursorAddChildAtPos :: Int -> Tree b -> TreeCursor a b -> TreeCursor a b treeCursorAddChildAtPos i t tc =@@ -69,3 +99,76 @@     EmptyCForest -> tc {treeBelow = openForest [makeCTree t]}     ClosedForest ts -> tc {treeBelow = openForest $ map makeCTree $ NE.toList ts ++ [t]}     OpenForest ts -> tc {treeBelow = openForest $ NE.toList ts ++ [makeCTree t]}++treeCursorAddChildAtPosAndSelect ::+  (a -> b) -> (b -> a) -> Int -> Tree b -> TreeCursor a b -> TreeCursor a b+treeCursorAddChildAtPosAndSelect f g i (Node t ts) = treeCursorAddChildNodeAtPosAndSelect f i (g t) ts++treeCursorAddChildAtStartAndSelect ::+  (a -> b) -> (b -> a) -> Tree b -> TreeCursor a b -> TreeCursor a b+treeCursorAddChildAtStartAndSelect f g (Node t ts) = treeCursorAddChildNodeAtStartAndSelect f (g t) ts++treeCursorAddChildAtEndAndSelect ::+  (a -> b) -> (b -> a) -> Tree b -> TreeCursor a b -> TreeCursor a b+treeCursorAddChildAtEndAndSelect f g (Node t ts) = treeCursorAddChildNodeAtEndAndSelect f (g t) ts++treeCursorAddChildNodeSingleAtPosAndSelect ::+  (a -> b) -> Int -> a -> TreeCursor a b -> TreeCursor a b+treeCursorAddChildNodeSingleAtPosAndSelect f i a = treeCursorAddChildNodeAtPosAndSelect f i a []++treeCursorAddChildNodeSingleAtStartAndSelect ::+  (a -> b) -> a -> TreeCursor a b -> TreeCursor a b+treeCursorAddChildNodeSingleAtStartAndSelect f a = treeCursorAddChildNodeAtStartAndSelect f a []++treeCursorAddChildNodeSingleAtEndAndSelect ::+  (a -> b) -> a -> TreeCursor a b -> TreeCursor a b+treeCursorAddChildNodeSingleAtEndAndSelect f a = treeCursorAddChildNodeAtEndAndSelect f a []++treeCursorAddChildNodeAtPosAndSelect ::+  (a -> b) -> Int -> a -> Forest b -> TreeCursor a b -> TreeCursor a b+treeCursorAddChildNodeAtPosAndSelect f i t ts tc =+  let (before, after) = splitAt i $ unpackCForest $ treeBelow tc+   in TreeCursor+        { treeAbove =+            Just+              TreeAbove+                { treeAboveLefts = reverse before,+                  treeAboveAbove = treeAbove tc,+                  treeAboveNode = f (treeCurrent tc),+                  treeAboveRights = after+                },+          treeCurrent = t,+          treeBelow = makeCForest ts+        }++treeCursorAddChildNodeAtStartAndSelect ::+  (a -> b) -> a -> Forest b -> TreeCursor a b -> TreeCursor a b+treeCursorAddChildNodeAtStartAndSelect f t ts tc =+  TreeCursor+    { treeAbove =+        Just+          TreeAbove+            { treeAboveLefts = [],+              treeAboveAbove = treeAbove tc,+              treeAboveNode = f (treeCurrent tc),+              treeAboveRights = unpackCForest $ treeBelow tc+            },+      treeCurrent = t,+      treeBelow = makeCForest ts+    }++treeCursorAddChildNodeAtEndAndSelect ::+  (a -> b) -> a -> Forest b -> TreeCursor a b -> TreeCursor a b+treeCursorAddChildNodeAtEndAndSelect f t ts tc =+  TreeCursor+    { treeAbove =+        Just+          TreeAbove+            { treeAboveLefts = reverse $ unpackCForest $ treeBelow tc,+              treeAboveAbove = treeAbove tc,+              treeAboveNode = f (treeCurrent tc),+              treeAboveRights = []+            },+      treeCurrent = t,+      treeBelow = makeCForest ts+    }
src/Cursor/Tree/Movement.hs view
@@ -2,33 +2,34 @@ {-# LANGUAGE TypeFamilies #-}  module Cursor.Tree.Movement-  ( treeCursorSelection-  , TreeCursorSelection(..)-  , treeCursorSelect-  , treeCursorSelectPrev-  , treeCursorSelectNext-  , treeCursorSelectFirst-  , treeCursorSelectLast-  , treeCursorSelectAbove-  , treeCursorSelectBelowAtPos-  , treeCursorSelectBelowAtStart-  , treeCursorSelectBelowAtEnd-  , treeCursorSelectBelowAtStartRecursively-  , treeCursorSelectBelowAtEndRecursively-  , treeCursorSelectPrevOnSameLevel-  , treeCursorSelectNextOnSameLevel-  , treeCursorSelectAbovePrev-  , treeCursorSelectAboveNext-  ) where--import qualified Data.List.NonEmpty as NE-import Data.Validity.Tree ()+  ( treeCursorSelection,+    TreeCursorSelection (..),+    treeCursorSelect,+    treeCursorSelectPrev,+    treeCursorSelectNext,+    treeCursorSelectFirst,+    treeCursorSelectLast,+    treeCursorSelectAbove,+    treeCursorSelectBelowAtPos,+    treeCursorSelectBelowAtStart,+    treeCursorSelectBelowAtEnd,+    treeCursorSelectBelowAtStartRecursively,+    treeCursorSelectBelowAtEndRecursively,+    treeCursorSelectPrevOnSameLevel,+    treeCursorSelectNextOnSameLevel,+    treeCursorSelectFirstOnSameLevel,+    treeCursorSelectLastOnSameLevel,+    treeCursorSelectAbovePrev,+    treeCursorSelectAboveNext,+  )+where  import Control.Applicative import Control.Monad- import Cursor.Tree.Base import Cursor.Tree.Types+import qualified Data.List.NonEmpty as NE+import Data.Validity.Tree ()  treeCursorSelection :: TreeCursor a b -> TreeCursorSelection treeCursorSelection TreeCursor {..} = wrap treeAbove SelectNode@@ -38,18 +39,18 @@     wrap (Just ta) ts = wrap (treeAboveAbove ta) $ SelectChild (length $ treeAboveLefts ta) ts  treeCursorSelect ::-     (a -> b) -> (b -> a) -> TreeCursorSelection -> TreeCursor a b -> Maybe (TreeCursor a b)+  (a -> b) -> (b -> a) -> TreeCursorSelection -> TreeCursor a b -> Maybe (TreeCursor a b) treeCursorSelect f g sel = makeTreeCursorWithSelection f g sel . rebuildTreeCursor f  treeCursorSelectPrev :: (a -> b) -> (b -> a) -> TreeCursor a b -> Maybe (TreeCursor a b) treeCursorSelectPrev f g tc =-  treeCursorSelectAbovePrev f g tc <|> treeCursorSelectPrevOnSameLevel f g tc <|>-  treeCursorSelectAbove f g tc+  treeCursorSelectAbovePrev f g tc <|> treeCursorSelectPrevOnSameLevel f g tc+    <|> treeCursorSelectAbove f g tc  treeCursorSelectNext :: (a -> b) -> (b -> a) -> TreeCursor a b -> Maybe (TreeCursor a b) treeCursorSelectNext f g tc =-  treeCursorSelectBelowAtStart f g tc <|> treeCursorSelectNextOnSameLevel f g tc <|>-  treeCursorSelectAboveNext f g tc+  treeCursorSelectBelowAtStart f g tc <|> treeCursorSelectNextOnSameLevel f g tc+    <|> treeCursorSelectAboveNext f g tc  treeCursorSelectFirst :: (a -> b) -> (b -> a) -> TreeCursor a b -> TreeCursor a b treeCursorSelectFirst f g tc = maybe tc (treeCursorSelectFirst f g) $ treeCursorSelectPrev f g tc@@ -67,7 +68,7 @@        in Just $ makeTreeCursorWithAbove g newTree treeAboveAbove  treeCursorSelectBelowAtPos ::-     (a -> b) -> (b -> a) -> Int -> TreeCursor a b -> Maybe (TreeCursor a b)+  (a -> b) -> (b -> a) -> Int -> TreeCursor a b -> Maybe (TreeCursor a b) treeCursorSelectBelowAtPos f g pos TreeCursor {..} =   case treeBelow of     EmptyCForest -> Nothing@@ -75,16 +76,16 @@     OpenForest ts ->       case splitAt pos $ NE.toList ts of         (_, []) -> Nothing-        (lefts, current:rights) ->-          Just $-          makeTreeCursorWithAbove g current $+        (lefts, current : rights) ->           Just $-          TreeAbove-            { treeAboveLefts = reverse lefts-            , treeAboveAbove = treeAbove-            , treeAboveNode = f treeCurrent-            , treeAboveRights = rights-            }+            makeTreeCursorWithAbove g current $+              Just $+                TreeAbove+                  { treeAboveLefts = reverse lefts,+                    treeAboveAbove = treeAbove,+                    treeAboveNode = f treeCurrent,+                    treeAboveRights = rights+                  }  treeCursorSelectBelowAtStart :: (a -> b) -> (b -> a) -> TreeCursor a b -> Maybe (TreeCursor a b) treeCursorSelectBelowAtStart f g = treeCursorSelectBelowAtPos f g 0@@ -97,13 +98,13 @@     OpenForest ts -> treeCursorSelectBelowAtPos f g (length ts - 1) tc  treeCursorSelectBelowAtStartRecursively ::-     (a -> b) -> (b -> a) -> TreeCursor a b -> Maybe (TreeCursor a b)+  (a -> b) -> (b -> a) -> TreeCursor a b -> Maybe (TreeCursor a b) treeCursorSelectBelowAtStartRecursively f g tc = go <$> treeCursorSelectBelowAtStart f g tc   where     go c = maybe c go $ treeCursorSelectBelowAtStart f g c  treeCursorSelectBelowAtEndRecursively ::-     (a -> b) -> (b -> a) -> TreeCursor a b -> Maybe (TreeCursor a b)+  (a -> b) -> (b -> a) -> TreeCursor a b -> Maybe (TreeCursor a b) treeCursorSelectBelowAtEndRecursively f g tc = go <$> treeCursorSelectBelowAtEnd f g tc   where     go c = maybe c go $ treeCursorSelectBelowAtEnd f g c@@ -113,19 +114,31 @@   ta <- treeAbove   case treeAboveLefts ta of     [] -> Nothing-    tree:xs ->+    tree : xs ->       Just . makeTreeCursorWithAbove g tree $-      Just ta {treeAboveLefts = xs, treeAboveRights = currentTree f tc : treeAboveRights ta}+        Just ta {treeAboveLefts = xs, treeAboveRights = currentTree f tc : treeAboveRights ta}  treeCursorSelectNextOnSameLevel :: (a -> b) -> (b -> a) -> TreeCursor a b -> Maybe (TreeCursor a b) treeCursorSelectNextOnSameLevel f g tc@TreeCursor {..} = do   ta <- treeAbove   case treeAboveRights ta of     [] -> Nothing-    tree:xs ->+    tree : xs ->       Just . makeTreeCursorWithAbove g tree . Just $-      ta {treeAboveLefts = currentTree f tc : treeAboveLefts ta, treeAboveRights = xs}+        ta {treeAboveLefts = currentTree f tc : treeAboveLefts ta, treeAboveRights = xs} +treeCursorSelectFirstOnSameLevel :: (a -> b) -> (b -> a) -> TreeCursor a b -> TreeCursor a b+treeCursorSelectFirstOnSameLevel f g tc =+  case treeCursorSelectPrevOnSameLevel f g tc of+    Nothing -> tc+    Just tc' -> treeCursorSelectFirstOnSameLevel f g tc'++treeCursorSelectLastOnSameLevel :: (a -> b) -> (b -> a) -> TreeCursor a b -> TreeCursor a b+treeCursorSelectLastOnSameLevel f g tc =+  case treeCursorSelectNextOnSameLevel f g tc of+    Nothing -> tc+    Just tc' -> treeCursorSelectLastOnSameLevel f g tc'+ -- | Go back and down as far as necessary to find a previous element on a level below treeCursorSelectAbovePrev :: (a -> b) -> (b -> a) -> TreeCursor a b -> Maybe (TreeCursor a b) treeCursorSelectAbovePrev f g =@@ -142,10 +155,7 @@       case treeBelow tc of         EmptyCForest -> go tc         ClosedForest _ -> go tc-        OpenForest ts ->-          if null ts-            then go tc-            else Nothing+        OpenForest _ -> Nothing   where     go tc_ = do       tc' <- treeCursorSelectAbove f g tc_
src/Cursor/Tree/Promote.hs view
@@ -1,22 +1,20 @@+{-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE DeriveFunctor #-}  module Cursor.Tree.Promote-  ( treeCursorPromoteElem-  , PromoteElemResult(..)-  , treeCursorPromoteSubTree-  , PromoteResult(..)-  ) where--import GHC.Generics (Generic)--import Data.Validity+  ( treeCursorPromoteElem,+    PromoteElemResult (..),+    treeCursorPromoteSubTree,+    PromoteResult (..),+  )+where  import Control.DeepSeq- import Cursor.Tree.Base import Cursor.Tree.Types+import Data.Validity+import GHC.Generics (Generic)  -- | Promotes the current node to the level of its parent. --@@ -46,27 +44,27 @@ -- >  |- d <-- -- >  |- h treeCursorPromoteElem ::-     (a -> b) -> (b -> a) -> TreeCursor a b -> PromoteElemResult (TreeCursor a b)+  (a -> b) -> (b -> a) -> TreeCursor a b -> PromoteElemResult (TreeCursor a b) treeCursorPromoteElem f g tc = do   ta <- maybe CannotPromoteTopElem pure $ treeAbove tc-    -- We need to put the below under the above lefts at the end+  -- We need to put the below under the above lefts at the end   lefts <-     case treeBelow tc of       EmptyCForest -> pure $ treeAboveLefts ta       _ ->         case treeAboveLefts ta of           [] -> NoSiblingsToAdoptChildren-          (CNode t ls:ts) ->+          (CNode t ls : ts) ->             pure $ CNode t (openForest $ unpackCForest ls ++ unpackCForest (treeBelow tc)) : ts   taa <- maybe NoGrandparentToPromoteElemUnder pure $ treeAboveAbove ta   pure $     makeTreeCursorWithAbove g (CNode (f $ treeCurrent tc) emptyCForest) $-    Just $-    taa-      { treeAboveLefts =-          CNode (treeAboveNode ta) (openForest $ reverse lefts ++ treeAboveRights ta) :-          treeAboveLefts taa-      }+      Just $+        taa+          { treeAboveLefts =+              CNode (treeAboveNode ta) (openForest $ reverse lefts ++ treeAboveRights ta) :+              treeAboveLefts taa+          }  data PromoteElemResult a   = CannotPromoteTopElem@@ -128,12 +126,12 @@   taa <- maybe NoGrandparentToPromoteUnder pure $ treeAboveAbove ta   pure $     makeTreeCursorWithAbove g (currentTree f tc) $-    Just $-    taa-      { treeAboveLefts =-          CNode (treeAboveNode ta) (openForest $ reverse (treeAboveLefts ta) ++ treeAboveRights ta) :-          treeAboveLefts taa-      }+      Just $+        taa+          { treeAboveLefts =+              CNode (treeAboveNode ta) (openForest $ reverse (treeAboveLefts ta) ++ treeAboveRights ta) :+              treeAboveLefts taa+          }  data PromoteResult a   = CannotPromoteTopNode
src/Cursor/Tree/Swap.hs view
@@ -1,20 +1,18 @@+{-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE DeriveFunctor #-}  module Cursor.Tree.Swap-  ( treeCursorSwapPrev-  , treeCursorSwapNext-  , SwapResult(..)-  ) where--import Data.Validity--import GHC.Generics (Generic)+  ( treeCursorSwapPrev,+    treeCursorSwapNext,+    SwapResult (..),+  )+where  import Control.DeepSeq- import Cursor.Tree.Types+import Data.Validity+import GHC.Generics (Generic)  -- | Swaps the current node with the previous node on the same level --@@ -38,9 +36,9 @@     Just ta ->       case treeAboveLefts ta of         [] -> NoSiblingsToSwapWith-        (t:ts) ->+        (t : ts) ->           Swapped $-          tc {treeAbove = Just ta {treeAboveLefts = ts, treeAboveRights = t : treeAboveRights ta}}+            tc {treeAbove = Just ta {treeAboveLefts = ts, treeAboveRights = t : treeAboveRights ta}}  -- | Swaps the current node with the next node on the same level --@@ -64,9 +62,9 @@     Just ta ->       case treeAboveRights ta of         [] -> NoSiblingsToSwapWith-        (t:ts) ->+        (t : ts) ->           Swapped $-          tc {treeAbove = Just ta {treeAboveLefts = t : treeAboveLefts ta, treeAboveRights = ts}}+            tc {treeAbove = Just ta {treeAboveLefts = t : treeAboveLefts ta, treeAboveRights = ts}}  data SwapResult a   = SwapperIsTopNode
src/Cursor/Tree/Types.hs view
@@ -1,53 +1,51 @@+{-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE DeriveFunctor #-}  module Cursor.Tree.Types-  ( TreeCursor(..)-  , treeCursorAboveL-  , treeCursorCurrentL-  , treeCursorBelowL-  , treeCursorCurrentSubTreeL-  , TreeAbove(..)-  , treeAboveLeftsL-  , treeAboveAboveL-  , treeAboveNodeL-  , treeAboveRightsL-  , TreeCursorSelection(..)-    -- * CTree-  , CTree(..)-  , makeCTree-  , cTree-  , rebuildCTree-  , CForest(..)-  , makeCForest-  , cForest-  , rebuildCForest-  , emptyCForest-  , openForest-  , closedForest-  , lengthCForest-  , unpackCForest-  ) where+  ( TreeCursor (..),+    treeCursorAboveL,+    treeCursorCurrentL,+    treeCursorBelowL,+    treeCursorCurrentSubTreeL,+    TreeAbove (..),+    treeAboveLeftsL,+    treeAboveAboveL,+    treeAboveNodeL,+    treeAboveRightsL,+    TreeCursorSelection (..), -import GHC.Generics (Generic)+    -- * CTree+    CTree (..),+    makeCTree,+    cTree,+    rebuildCTree,+    CForest (..),+    makeCForest,+    cForest,+    rebuildCForest,+    emptyCForest,+    openForest,+    closedForest,+    lengthCForest,+    unpackCForest,+  )+where -import Data.List.NonEmpty (NonEmpty(..))+import Control.DeepSeq+import Data.List.NonEmpty (NonEmpty (..)) import qualified Data.List.NonEmpty as NE import Data.Tree import Data.Validity import Data.Validity.Tree ()--import Control.DeepSeq-+import GHC.Generics (Generic) import Lens.Micro -data TreeCursor a b =-  TreeCursor-    { treeAbove :: !(Maybe (TreeAbove b))-    , treeCurrent :: !a-    , treeBelow :: !(CForest b)-    }+data TreeCursor a b = TreeCursor+  { treeAbove :: !(Maybe (TreeAbove b)),+    treeCurrent :: !a,+    treeBelow :: !(CForest b)+  }   deriving (Show, Eq, Generic)  instance (Validity a, Validity b) => Validity (TreeCursor a b)@@ -67,13 +65,12 @@ treeCursorCurrentSubTreeL =   lens (\tc -> (treeCurrent tc, treeBelow tc)) (\tc (a, cf) -> tc {treeCurrent = a, treeBelow = cf}) -data TreeAbove b =-  TreeAbove-    { treeAboveLefts :: ![CTree b] -- In reverse order-    , treeAboveAbove :: !(Maybe (TreeAbove b))-    , treeAboveNode :: !b-    , treeAboveRights :: ![CTree b]-    }+data TreeAbove b = TreeAbove+  { treeAboveLefts :: ![CTree b], -- In reverse order+    treeAboveAbove :: !(Maybe (TreeAbove b)),+    treeAboveNode :: !b,+    treeAboveRights :: ![CTree b]+  }   deriving (Show, Eq, Generic, Functor)  instance Validity b => Validity (TreeAbove b)@@ -101,8 +98,8 @@  instance NFData TreeCursorSelection -data CTree a =-  CNode !a (CForest a)+data CTree a+  = CNode !a (CForest a)   deriving (Show, Eq, Generic, Functor)  instance Validity a => Validity (CTree a)
src/Cursor/Types.hs view
@@ -3,15 +3,11 @@  module Cursor.Types where -import GHC.Generics (Generic)-+import Control.Applicative+import Data.Functor.Compose import qualified Data.Text.Internal as T import Data.Validity--import Data.Functor.Compose--import Control.Applicative-+import GHC.Generics (Generic) import Lens.Micro  isSafeChar :: Char -> Bool@@ -39,6 +35,11 @@   Updated a <|> _ = Updated a   Deleted <|> doua = doua +instance Monad DeleteOrUpdate where+  dou >>= f = case dou of+    Updated a -> f a+    Deleted -> Deleted+ joinDeletes :: Maybe (DeleteOrUpdate a) -> Maybe (DeleteOrUpdate a) -> DeleteOrUpdate a joinDeletes m1 m2 =   case (m1, m2) of@@ -47,10 +48,10 @@     (Just a, _) -> a  joinDeletes3 ::-     Maybe (DeleteOrUpdate a)-  -> Maybe (DeleteOrUpdate a)-  -> Maybe (DeleteOrUpdate a)-  -> DeleteOrUpdate a+  Maybe (DeleteOrUpdate a) ->+  Maybe (DeleteOrUpdate a) ->+  Maybe (DeleteOrUpdate a) ->+  DeleteOrUpdate a joinDeletes3 m1 m2 m3 =   case (m1, m2, m3) of     (Nothing, Nothing, Nothing) -> Deleted@@ -59,11 +60,11 @@     (Just a, _, _) -> a  joinPossibleDeletes ::-     Maybe (DeleteOrUpdate a) -> Maybe (DeleteOrUpdate a) -> Maybe (DeleteOrUpdate a)+  Maybe (DeleteOrUpdate a) -> Maybe (DeleteOrUpdate a) -> Maybe (DeleteOrUpdate a) joinPossibleDeletes d1 d2 = getCompose $ Compose d1 <|> Compose d2  focusPossibleDeleteOrUpdate ::-     Lens' b a -> (a -> Maybe (DeleteOrUpdate a)) -> b -> Maybe (DeleteOrUpdate b)+  Lens' b a -> (a -> Maybe (DeleteOrUpdate a)) -> b -> Maybe (DeleteOrUpdate b) focusPossibleDeleteOrUpdate l func = getCompose . l (Compose . func)  dullMDelete :: Maybe (DeleteOrUpdate a) -> Maybe a