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 +8/−1
- LICENSE +1/−1
- Setup.hs +0/−3
- cursor.cabal +4/−4
- src/Cursor/Forest.hs +302/−199
- src/Cursor/List.hs +75/−44
- src/Cursor/List/NonEmpty.hs +78/−80
- src/Cursor/Map.hs +118/−97
- src/Cursor/Map/KeyValue.hs +56/−33
- src/Cursor/Simple/Forest.hs +150/−77
- src/Cursor/Simple/List/NonEmpty.hs +36/−37
- src/Cursor/Simple/Map.hs +35/−35
- src/Cursor/Simple/Map/KeyValue.hs +14/−13
- src/Cursor/Simple/Tree.hs +138/−78
- src/Cursor/Text.hs +137/−40
- src/Cursor/TextField.hs +128/−109
- src/Cursor/Tree.hs +24/−13
- src/Cursor/Tree/Base.hs +46/−36
- src/Cursor/Tree/Collapse.hs +8/−8
- src/Cursor/Tree/Delete.hs +56/−55
- src/Cursor/Tree/Demote.hs +38/−40
- src/Cursor/Tree/Draw.hs +11/−11
- src/Cursor/Tree/Insert.hs +125/−22
- src/Cursor/Tree/Movement.hs +57/−47
- src/Cursor/Tree/Promote.hs +24/−26
- src/Cursor/Tree/Swap.hs +12/−14
- src/Cursor/Tree/Types.hs +44/−47
- src/Cursor/Types.hs +14/−13
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