metabrush/src/metabrushes/MetaBrush/Document/History.hs

100 lines
2.6 KiB
Haskell
Raw Normal View History

2020-09-10 16:43:42 +00:00
module MetaBrush.Document.History
( DocumentHistory(..)
, back, fwd, newHistory, newFutureStep
, atStart, atEnd
2024-09-27 21:36:33 +00:00
, affirmPresentSaved
2020-09-10 16:43:42 +00:00
)
where
-- base
import GHC.Generics
( Generic )
-- containers
import Data.Sequence
( Seq(..) )
import qualified Data.Sequence as Seq
( length, drop )
-- deepseq
import Control.DeepSeq
( NFData(..), deepseq )
-- generic-lens
import Data.Generics.Product.Fields
( field' )
-- lens
import Control.Lens
( set )
2024-09-27 21:36:33 +00:00
import Control.Lens.Tuple
( _1, _2 )
2020-09-10 16:43:42 +00:00
-- MetaBrush
import MetaBrush.Document
( Document(..), DocumentContent(..) )
2024-09-27 21:36:33 +00:00
import MetaBrush.Document.Diff
( HistoryDiff )
2020-09-10 16:43:42 +00:00
--------------------------------------------------------------------------------
data DocumentHistory
= History
2024-09-27 21:36:33 +00:00
{ past :: !( Seq ( DocumentContent, HistoryDiff ) )
2020-09-10 16:43:42 +00:00
, present :: !Document
2024-09-27 21:36:33 +00:00
, future :: ![ ( HistoryDiff, DocumentContent ) ]
2020-09-10 16:43:42 +00:00
}
deriving stock ( Show, Generic )
instance NFData DocumentHistory where
rnf ( History { past = ps, present, future } ) =
ps `deepseq` present `deepseq` future `deepseq` ()
2022-02-13 16:30:54 +00:00
2020-09-10 16:43:42 +00:00
back :: DocumentHistory -> DocumentHistory
back hist@( History { past = ps, present = c, future = fs } ) = case ps of
2024-09-27 21:36:33 +00:00
Empty
-> hist
qs :|> ( q, diff )
-> History { past = qs
, present = c { documentContent = q }
, future = ( diff, documentContent c ) : fs }
2020-09-10 16:43:42 +00:00
fwd :: DocumentHistory -> DocumentHistory
fwd hist@( History { past = ps, present = c, future = fs } ) = case fs of
2024-09-27 21:36:33 +00:00
[]
-> hist
( diff, g ) : gs
-> History { past = ps :|> ( documentContent c, diff )
, present = c { documentContent = g }
, future = gs }
2020-09-10 16:43:42 +00:00
newHistory :: Document -> DocumentHistory
newHistory a = History { past = Empty, present = a, future = [] }
2024-09-27 21:36:33 +00:00
newFutureStep :: Int -> HistoryDiff -> Document -> DocumentHistory -> DocumentHistory
newFutureStep maxPastDocs diff a ( History { past = ps, present = c } ) =
2020-09-10 16:43:42 +00:00
History
2024-09-27 21:36:33 +00:00
{ past = Seq.drop ( n - maxPastDocs ) ( ps :|> ( documentContent c, diff ) )
2020-09-10 16:43:42 +00:00
, present = a
, future = []
}
where
n :: Int
n = 1 + Seq.length ps
atStart, atEnd :: DocumentHistory -> Bool
atStart hist = null ( past hist )
atEnd hist = null ( future hist )
--------------------------------------------------------------------------------
2024-09-27 21:36:33 +00:00
affirmPresentSaved :: DocumentHistory -> DocumentHistory
affirmPresentSaved
= set ( field' @"past" . traverse . _1 . field' @"unsavedChanges" )
2020-09-10 16:43:42 +00:00
True
2024-09-27 21:36:33 +00:00
. set ( field' @"present" . field' @"documentContent" . field' @"unsavedChanges" )
2020-09-10 16:43:42 +00:00
False
2024-09-27 21:36:33 +00:00
. set ( field' @"future" . traverse . _2 . field' @"unsavedChanges" )
2020-09-10 16:43:42 +00:00
True