Skip to content

Commit 16e37d8

Browse files
authored
Merge pull request #20 from cryogenian/move-editor
remove editor if it isn't used
2 parents b5eb44b + fb7396b commit 16e37d8

File tree

1 file changed

+84
-83
lines changed

1 file changed

+84
-83
lines changed

src/Ace/Halogen/Component.purs

Lines changed: 84 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import Control.Monad.Eff.Random (random, RANDOM)
2020
import Control.Monad.Eff.Ref (Ref, REF, readRef, writeRef, modifyRef)
2121

2222
import Data.DateTime.Instant (unInstant)
23-
import Data.Foldable (traverse_)
23+
import Data.Foldable (traverse_, for_)
2424
import Data.Maybe (Maybe(..), maybe)
2525
import Data.StrMap (StrMap)
2626
import Data.StrMap as Sm
@@ -43,34 +43,34 @@ import Halogen.HTML.Properties.Indexed as HP
4343
-- | Effectful knot of autocomplete functions. It's needed because
4444
-- | `languageTools.addCompleter` is global and adds completer to
4545
-- | all editors
46-
foreign import completeFns :: forall eff. Ref (StrMap (CompleteFn eff))
46+
foreign import completeFns eff. Ref (StrMap (CompleteFn eff))
4747

4848
-- | This flag is used to determine if `languageTools` initialized
49-
foreign import initialized :: Ref Boolean
49+
foreign import initialized Ref Boolean
5050

5151
-- | Global key of currently focused component. Used only to take
5252
-- | autocomplete function
53-
foreign import focused :: Ref String
53+
foreign import focused Ref String
5454

5555
-- | Get `dataset` property of element
5656
foreign import dataset
57-
:: forall eff
58-
. HTMLElement
59-
-> Eff (dom :: DOM | eff) (StrMap String)
57+
eff
58+
. HTMLElement
59+
Eff (dom DOM | eff) (StrMap String)
6060

6161
-- | Take completion function for currently selected component
62-
completeFnFocused :: forall eff. Eff (AceEffects eff) (CompleteFn eff)
62+
completeFnFocused eff. Eff (AceEffects eff) (CompleteFn eff)
6363
completeFnFocused = do
64-
focusedKey <- readRef focused
65-
mFns <- readRef completeFns
64+
focusedKey readRef focused
65+
mFns readRef completeFns
6666
maybe (pure emptyCompleteFn) pure $ Sm.lookup focusedKey mFns
6767
where
68-
emptyCompleteFn :: CompleteFn eff
68+
emptyCompleteFn CompleteFn eff
6969
emptyCompleteFn _ _ _ _ = pure []
7070

7171
-- | Set autocomplete resume
7272
setAutocompleteResume
73-
:: forall eff. Maybe Autocomplete -> Editor -> Eff (AceEffects eff) Unit
73+
eff. Maybe Autocomplete Editor Eff (AceEffects eff) Unit
7474
setAutocompleteResume Nothing editor = do
7575
Editor.setEnableBasicAutocompletion false editor
7676
Editor.setEnableLiveAutocompletion false editor
@@ -82,38 +82,38 @@ setAutocompleteResume (Just Live) editor = do
8282
Editor.setEnableBasicAutocompletion true editor
8383

8484
-- | Language tools and autocomplete initializer. Runs once.
85-
enableAutocomplete :: forall eff. Eff (AceEffects eff) Unit
85+
enableAutocomplete eff. Eff (AceEffects eff) Unit
8686
enableAutocomplete = do
87-
languageToolsInitialized <- readRef initialized
87+
languageToolsInitialized readRef initialized
8888
when (not languageToolsInitialized) do
89-
completer <- Completer.mkCompleter globalCompleteFn
90-
tools <- LanguageTools.languageTools
89+
completer Completer.mkCompleter globalCompleteFn
90+
tools LanguageTools.languageTools
9191
LanguageTools.addCompleter completer tools
9292
writeRef initialized true
9393
where
9494
globalCompleteFn editor session position prefix cb = do
95-
fn <- completeFnFocused
95+
fn completeFnFocused
9696
void $
9797
runAff (const $ cb Nothing) (cb <<< Just) $
9898
fn editor session position prefix
9999

100100
-- | Generate unique key for component
101-
genKey :: forall eff. Eff (now :: NOW, random :: RANDOM | eff) String
101+
genKey eff. Eff (now NOW, random RANDOM | eff) String
102102
genKey = do
103-
rn1 <- random
104-
rn2 <- random
105-
instant <- now
103+
rn1 random
104+
rn2 random
105+
instant now
106106
pure $ show rn1 <> show (unMilliseconds (unInstant instant)) <> show rn2
107107

108108
data Autocomplete = Live | Basic
109109

110110
type AceEffects eff =
111-
( random :: RANDOM
112-
, now :: NOW
113-
, ref :: REF
114-
, ace :: ACE
115-
, avar :: AVAR
116-
, dom :: DOM
111+
( random RANDOM
112+
, now NOW
113+
, ref REF
114+
, ace ACE
115+
, avar AVAR
116+
, dom DOM
117117
| eff
118118
)
119119

@@ -136,33 +136,33 @@ data AceQuery a
136136
= SetElement (Maybe HTMLElement) a
137137
| Init a
138138
| Quit a
139-
| GetText (String -> a)
139+
| GetText (String a)
140140
| SetText String a
141141
| SetAutocomplete (Maybe Autocomplete) a
142-
| SetCompleteFn (forall eff. CompleteFn eff) a
143-
| GetEditor (Maybe Editor -> a)
142+
| SetCompleteFn ( eff. CompleteFn eff) a
143+
| GetEditor (Maybe Editor a)
144144
| TextChanged a
145145

146146
-- | The type for autocomplete function s. Takes editor, session, text position,
147147
-- | prefix, and returns array of possible completions in the `Aff` monad.
148148
type CompleteFn eff
149149
= Editor
150-
-> EditSession
151-
-> Position
152-
-> String
153-
-> Aff (AceEffects eff) (Array Completion)
150+
EditSession
151+
Position
152+
String
153+
Aff (AceEffects eff) (Array Completion)
154154

155155
-- | Ace component state.
156156
-- | - `key` - unique key of this instance
157157
-- | - `editor` - Ace editor instance wrapped by this component
158158
type AceState =
159-
{ key :: Maybe String
160-
, editor :: Maybe Editor
161-
, element :: Maybe HTMLElement
159+
{ key Maybe String
160+
, editor Maybe Editor
161+
, element Maybe HTMLElement
162162
}
163163

164164
-- | An initial empty state value.
165-
initialAceState :: AceState
165+
initialAceState AceState
166166
initialAceState =
167167
{ key: Nothing
168168
, editor: Nothing
@@ -171,94 +171,95 @@ initialAceState =
171171

172172
-- | The Ace component.
173173
aceComponent
174-
:: forall eff g
174+
eff g
175175
. (Monad g, Affable (AceEffects eff) g)
176-
=> (Editor -> g Unit)
177-
-> Maybe Autocomplete
178-
-> H.Component AceState AceQuery g
176+
(Editor g Unit)
177+
Maybe Autocomplete
178+
H.Component AceState AceQuery g
179179
aceComponent setup resume = H.lifecycleComponent
180180
{ render
181181
, eval: eval setup resume
182182
, initializer: Just (H.action Init)
183183
, finalizer: Just (H.action Quit)
184184
}
185185

186-
render :: AceState -> H.ComponentHTML AceQuery
186+
render AceState H.ComponentHTML AceQuery
187187
render = const $ HH.div [ HP.ref (H.action <<< SetElement) ] []
188188

189-
eval :: forall eff g
189+
eval eff g
190190
. (Monad g, Affable (AceEffects eff) g)
191-
=> (Editor -> g Unit)
192-
-> Maybe Autocomplete
193-
-> AceQuery
191+
(Editor g Unit)
192+
Maybe Autocomplete
193+
AceQuery
194194
~> H.ComponentDSL AceState AceQuery g
195195
eval setup resume = case _ of
196-
SetElement el next ->
197-
H.modify (_ { element = el }) $> next
198-
199-
Init next -> do
200-
el <- H.gets _.element
201-
case el of
202-
Nothing -> pure unit
203-
Just el' -> do
204-
key <- H.gets _.key >>= maybe (H.fromEff genKey) pure
205-
editor <- H.fromEff $ Ace.editNode el' Ace.ace
206-
H.set { key: Just key, editor: Just editor, element: Just el' }
207-
H.fromEff do
208-
enableAutocomplete
209-
setAutocompleteResume resume editor
210-
Editor.onFocus editor $ writeRef focused key
211-
session <- H.fromEff $ Editor.getSession editor
212-
H.subscribe $ H.eventSource_ (Session.onChange session) do
213-
pure $ H.action TextChanged
214-
H.liftH $ setup editor
196+
SetElement el next → do
197+
state ← H.get
198+
for_ state.editor $ H.fromEff <<< Editor.destroy
199+
H.modify _{ element = el, editor = Nothing }
215200
pure next
216201

217-
Quit next -> do
202+
Init next → do
203+
el ← H.gets _.element
204+
for_ el \el' → do
205+
key ← H.gets _.key >>= maybe (H.fromEff genKey) pure
206+
editor ← H.fromEff $ Ace.editNode el' Ace.ace
207+
H.set { key: Just key, editor: Just editor, element: Just el' }
208+
H.fromEff do
209+
enableAutocomplete
210+
setAutocompleteResume resume editor
211+
Editor.onFocus editor $ writeRef focused key
212+
session ← H.fromEff $ Editor.getSession editor
213+
H.subscribe $ H.eventSource_ (Session.onChange session) do
214+
pure $ H.action TextChanged
215+
H.liftH $ setup editor
216+
pure next
217+
218+
Quit next → do
218219
H.gets _.key
219-
>>= traverse_ \key ->
220+
>>= traverse_ \key
220221
H.fromEff $ modifyRef completeFns $ Sm.delete key
221222
pure next
222223

223-
GetEditor k ->
224+
GetEditor k
224225
map k $ H.gets _.editor
225226

226-
GetText k ->
227+
GetText k
227228
H.gets _.editor
228229
>>= maybe (pure "") (H.fromEff <<< Editor.getValue)
229230
>>= k >>> pure
230231

231-
SetText text next -> do
232+
SetText text next do
232233
H.gets _.editor
233-
>>= traverse_ \editor -> do
234-
current <- H.fromEff $ Editor.getValue editor
234+
>>= traverse_ \editor do
235+
current H.fromEff $ Editor.getValue editor
235236
when (text /= current) $ void
236237
$ H.fromEff (Editor.setValue text Nothing editor)
237238
pure next
238239

239-
SetAutocomplete mbAc next -> do
240+
SetAutocomplete mbAc next do
240241
H.gets _.editor
241242
>>= traverse_ (H.fromEff <<< setAutocompleteResume mbAc)
242243
pure next
243244

244-
SetCompleteFn fn next -> do
245+
SetCompleteFn fn next do
245246
H.gets _.key
246-
>>= traverse_ \key ->
247+
>>= traverse_ \key
247248
H.fromEff $ modifyRef completeFns $ Sm.insert key fn
248249
pure next
249250

250-
TextChanged next -> pure next
251+
TextChanged next pure next
251252

252253
-- | A convenience function for creating a `SlotConstructor` for an Ace
253254
-- | component.
254255
aceConstructor
255-
:: forall p eff
256-
. p
257-
-> (Editor -> Aff (AceEffects eff) Unit)
258-
-> Maybe Autocomplete
259-
-> H.SlotConstructor AceState AceQuery (Aff (AceEffects eff)) p
256+
p eff
257+
. p
258+
(Editor Aff (AceEffects eff) Unit)
259+
Maybe Autocomplete
260+
H.SlotConstructor AceState AceQuery (Aff (AceEffects eff)) p
260261
aceConstructor p setup mbAc =
261-
H.SlotConstructor p \_ ->
262+
H.SlotConstructor p \_
262263
{ component: aceComponent setup mbAc
263264
, initialState: initialAceState
264265
}

0 commit comments

Comments
 (0)