summaryrefslogtreecommitdiff
path: root/interactive-edit-lens/src/Interact/Types.hs
blob: 67f9ae34d963331ea803bae1bbc60b0ecea0b377 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
{-# LANGUAGE TemplateHaskell, DeriveGeneric, StandaloneDeriving #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}

module Interact.Types
  ( InteractName(..)
  , _LeftEditor, _RightEditor, _PrimitiveName
  , Validity, pattern Valid, pattern Invalid
  , InteractState(..)
  , HasLeft(..), HasRight(..), HasComplement(..), HasFocus(..), HasFocused(..), HasActive(..), HasLoadBrowser(..)
  , InteractInitial(..)
  , _InitialLeft, _InitialRight, _InitialEmpty
  , InteractConfig(..)
  , HasInitial(..), HasLens(..), HasCompileError(..)
  , InteractEvent
  , InteractApp
  , InteractDirection(..)
  , charseq
  , WithName(..)
  , module Control.Edit
  , module Control.Lens.Edit
  , module Control.DFST.Lens
  , module Data.Semigroup
  , module Numeric.Natural
  ) where

import Data.Text (Text)
import qualified Data.Text as Text
import Data.Text.Lens

import Data.Sequence (Seq(..))
import qualified Data.Sequence as Seq

import qualified Data.Foldable as Foldable

import Data.Semigroup (Semigroup(..), Last(..))
import Numeric.Natural

import Brick
import Brick.Focus
import Brick.Widgets.Edit
import Brick.Widgets.FileBrowser

import Control.Lens
import Control.Lens.TH
import Control.Edit
import Control.Lens.Edit
import Control.DFST.Lens

import Data.Text.Zipper.Generic

import Control.DeepSeq
import GHC.Generics (Generic)


deriving instance Generic (StringEdit n c)
instance (NFData n, NFData c) => NFData (StringEdit n c)
  
deriving instance Generic (StringEdits n c)
instance (NFData n, NFData c) => NFData (StringEdits n c)

deriving instance Generic (DFSTAction s c c')
instance (NFData s, NFData c, NFData c') => NFData (DFSTAction s c c')

instance (NFData s, NFData c, NFData c') => NFData (DFSTComplement s c c') where
  rnf = foldr deepseq ()


data InteractName
  = LeftEditor
  | RightEditor
  | LoadBrowser
  | PrimitiveName !Text
  deriving (Eq, Ord, Show, Read, Generic)

makePrisms ''InteractName

type Validity = Bool
pattern Valid = True
pattern Invalid = False

data InteractState c = InteractState
  { istLeft, istRight :: (Last Validity, Last (Seq Char, Int), StringEdits Natural Char)
  , istComplement :: c
  , istFocus :: FocusRing InteractName
  , istActive :: Bool
  , istLoadBrowser :: Maybe (FileBrowser InteractName)
  }

makeLensesWith abbreviatedFields ''InteractState

class HasFocused s a | s -> a where
  focused :: Traversal' s a

instance HasFocused (InteractState c) (Last Validity, Last (Seq Char, Int), StringEdits Natural Char) where
  focused f st@InteractState{..} = case focusGetCurrent istFocus of
    Just LeftEditor  -> left f st
    Just RightEditor -> right f st
    _other           -> pure st

data InteractInitial
  = InitialLeft Text
  | InitialRight Text
  | InitialEmpty
  deriving (Eq, Ord, Show, Read)

makePrisms ''InteractInitial

data InteractConfig c = InteractConfig
  { icfgInitial :: InteractInitial
  , icfgLens :: EditLens c (StringEdits Natural Char) (StringEdits Natural Char)
  , icfgCompileError :: Maybe String
  }

instance HasEditLens (InteractConfig c) (StringEdits Natural Char) (StringEdits Natural Char) where
  type Complement (InteractConfig c) = c
  ground = ground . icfgLens
  propR = propR . icfgLens
  propL = propL . icfgLens

makeLensesWith abbreviatedFields ''InteractConfig

charseq :: Iso' Text (Seq Char)
charseq = iso Text.unpack Text.pack . iso Seq.fromList Foldable.toList

type InteractEvent = ()

type InteractApp c = App (InteractState c) InteractEvent InteractName

data InteractDirection = PropagateLeft | PropagateRight
  deriving (Eq, Ord, Enum, Bounded, Show, Read)

makePrisms ''InteractDirection


infixr 1 `WithName`
data WithName x n = WithName x n
  deriving (Eq, Ord, Show, Read)

instance Named (x `WithName` n) n where
  getName (_ `WithName` n) = n