Skip to content

Commit b9bf420

Browse files
committed
Adjust to changes in nvim-hs 1.0.0.0
1 parent 73ac884 commit b9bf420

3 files changed

Lines changed: 54 additions & 48 deletions

File tree

Neovim/Ghcid.hs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,17 @@ module Neovim.Ghcid
1717
import Neovim
1818

1919
import Neovim.Ghcid.Plugin
20-
import qualified Data.Map as Map
2120

22-
plugin :: Neovim (StartupConfig NeovimConfig) () NeovimPlugin
21+
plugin :: Neovim (StartupConfig NeovimConfig) NeovimPlugin
2322
plugin = do
2423
_ <- vim_command "sign define GhcidWarn text=>> texthl=Search"
2524
_ <- vim_command "sign define GhcidErr text=!! texthl=ErrorMsg"
25+
env <- initGhcidEnv
2626
wrapPlugin Plugin
27-
{ exports = []
28-
, statefulExports =
29-
[ StatefulFunctionality
30-
{ readOnly = ()
31-
, writable = GhcidState Map.empty []
32-
, functionalities =
33-
[ $(command' 'ghcidStart) ["async", "!"]
34-
, $(command' 'ghcidStop) ["async"]
35-
, $(command' 'ghcidRestart) ["async"]
36-
]
37-
}
27+
{ environment = env
28+
, exports =
29+
[ $(command' 'ghcidStart) ["async", "!"]
30+
, $(command' 'ghcidStop) ["async"]
31+
, $(command' 'ghcidRestart) ["async"]
3832
]
3933
}

Neovim/Ghcid/Plugin.hs

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ import Data.Map (Map)
3636
import qualified Data.Map as Map
3737
import Data.Maybe (mapMaybe)
3838
import System.FilePath
39+
import UnliftIO.STM
40+
import UnliftIO.Exception (SomeException(..), catch)
3941

4042

4143
-- | Simple data type containing a few information on how to start ghcid.
@@ -56,28 +58,32 @@ instance ToJSON ProjectSettings
5658
instance FromJSON ProjectSettings
5759

5860

59-
data GhcidState r = GhcidState
60-
{ startedSessions :: Map FilePath (Ghci, Neovim r (GhcidState r) ())
61+
data GhcidEnv = GhcidEnv
62+
{ startedSessions :: TVar (Map FilePath (Ghci, Neovim GhcidEnv ()))
6163
-- ^ A map from the root directory (see 'rootDir') to a 'Ghci' session and a
6264
-- release function which unregisters some autocmds and stops the ghci
6365
-- session.
6466

65-
, quickfixItems :: [QuickfixListItem String]
67+
, quickfixItems :: TVar [QuickfixListItem String]
6668
}
6769

6870

69-
modifyStartedSessions :: (Map FilePath (Ghci, Neovim r (GhcidState r) ())
70-
-> Map FilePath (Ghci, Neovim r (GhcidState r) ()))
71-
-> Neovim r (GhcidState r) ()
72-
modifyStartedSessions f = modify $ \s -> s { startedSessions = f (startedSessions s) }
71+
initGhcidEnv :: MonadIO m => m GhcidEnv
72+
initGhcidEnv = GhcidEnv <$> newTVarIO mempty <*> newTVarIO mempty
73+
74+
modifyStartedSessions :: (Map FilePath (Ghci, Neovim GhcidEnv ())
75+
-> Map FilePath (Ghci, Neovim GhcidEnv ()))
76+
-> Neovim GhcidEnv ()
77+
modifyStartedSessions f = do
78+
atomically . flip modifyTVar' f =<< asks startedSessions
7379

7480

7581
-- | Start or update a ghcid session.
7682
--
7783
-- This will call 'determineProjectSettings' and ask you to confirm or overwrite
7884
-- its proposed settings. If you prepend a bang, it acts as if you have
7985
-- confirmed all settings.
80-
ghcidStart :: CommandArguments -> Neovim r (GhcidState r) ()
86+
ghcidStart :: CommandArguments -> Neovim GhcidEnv ()
8187
ghcidStart copts = do
8288
currentBufferPath <- errOnInvalidResult $ vim_call_function "expand" [ObjectBinary "%:p:h"]
8389
liftIO (determineProjectSettings' currentBufferPath) >>= \case
@@ -103,41 +109,45 @@ ghcidStart copts = do
103109

104110
-- | Start a new ghcid session or reload the modules to update the quickfix
105111
-- list.
106-
startOrReload :: ProjectSettings -> Neovim r (GhcidState r) ()
107-
startOrReload s@(ProjectSettings d c) = Map.lookup d <$> gets startedSessions >>= \case
108-
Nothing -> do
109-
(g, ls) <- liftIO $ startGhci c (Just d) (\_ _ -> return ())
110-
applyQuickfixActions $ loadToQuickfix ls
111-
void $ vim_command "cwindow"
112-
ra <- addAutocmd "BufWritePost" def (startOrReload s) >>= \case
113-
Nothing ->
114-
return $ return ()
112+
startOrReload :: ProjectSettings -> Neovim GhcidEnv ()
113+
startOrReload s@(ProjectSettings d c) = do
114+
sessions <- atomically . readTVar =<< asks startedSessions
115+
case Map.lookup d sessions of
116+
Nothing -> do
117+
(g, ls) <- liftIO (startGhci c (Just d) (\_ _ -> return ()))
118+
`catch` \(SomeException e) -> err . pretty $ "Failed to start ghcid session: " <> show e
119+
applyQuickfixActions $ loadToQuickfix ls
120+
void $ vim_command "cwindow"
121+
ra <- addAutocmd "BufWritePost" def (startOrReload s) >>= \case
122+
Nothing ->
123+
return $ return ()
115124

116-
Just (Left a) ->
117-
return a
125+
Just (Left a) ->
126+
return a
118127

119-
Just (Right rk) ->
120-
return $ Resource.release rk
128+
Just (Right rk) ->
129+
return $ Resource.release rk
121130

122-
modifyStartedSessions $ Map.insert d (g,ra >> liftIO (stopGhci g))
131+
modifyStartedSessions $ Map.insert d (g,ra >> liftIO (stopGhci g))
123132

124-
Just (ghci, _) -> do
125-
applyQuickfixActions =<< loadToQuickfix <$> liftIO (reload ghci)
126-
void $ vim_command "cwindow"
133+
Just (ghci, _) -> do
134+
applyQuickfixActions =<< loadToQuickfix <$> liftIO (reload ghci)
135+
void $ vim_command "cwindow"
127136

128137

129-
applyQuickfixActions :: [QuickfixListItem String] -> Neovim r (GhcidState r) ()
138+
applyQuickfixActions :: [QuickfixListItem String] -> Neovim GhcidEnv ()
130139
applyQuickfixActions qs = do
131-
fqs <- (nub' . rights . map bufOrFile) <$> gets quickfixItems
132-
modify $ \s -> s { quickfixItems = qs }
140+
qfItems <- asks quickfixItems
141+
fqs <- (nub' . rights . map bufOrFile) <$> atomically (readTVar qfItems)
142+
atomically $ modifyTVar' qfItems (const qs)
133143
forM_ fqs $ \f -> void . vim_command $ "sign unplace * file=" <> f
134144
setqflist qs Replace
135145
placeSigns qs
136146
where
137147
nub' = map head . groupBy (==) . sort
138148

139149

140-
placeSigns :: [QuickfixListItem String] -> Neovim r st ()
150+
placeSigns :: [QuickfixListItem String] -> Neovim env ()
141151
placeSigns qs = forM_ (zip [(1::Integer)..] qs) $ \(i, q) -> case (lnumOrPattern q, bufOrFile q) of
142152
(Right _, _) ->
143153
-- Patterns not handled as they are not produced
@@ -160,10 +170,11 @@ placeSigns qs = forM_ (zip [(1::Integer)..] qs) $ \(i, q) -> case (lnumOrPattern
160170
]
161171

162172
-- | Stop a ghcid session associated to the currently active buffer.
163-
ghcidStop :: CommandArguments -> Neovim r (GhcidState r) ()
173+
ghcidStop :: CommandArguments -> Neovim GhcidEnv ()
164174
ghcidStop _ = do
165175
d <- errOnInvalidResult $ vim_call_function "expand" [ObjectBinary "%:p:h"]
166-
Map.lookupLE d <$> gets startedSessions >>= \case
176+
sessions <- atomically .readTVar =<< asks startedSessions
177+
case Map.lookupLE d sessions of
167178
Nothing ->
168179
return ()
169180
Just (p,(_, releaseAction)) -> do
@@ -172,7 +183,7 @@ ghcidStop _ = do
172183

173184

174185
-- | Same as @:GhcidStop@ followed by @:GhcidStart!@. Note the bang!
175-
ghcidRestart :: CommandArguments -> Neovim r (GhcidState r) ()
186+
ghcidRestart :: CommandArguments -> Neovim GhcidEnv ()
176187
ghcidRestart _ = do
177188
ghcidStop def
178189
ghcidStart def { bang = Just True }

nvim-hs-ghcid.cabal

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: nvim-hs-ghcid
2-
version: 0.2.1
2+
version: 1.0.0.0
33
synopsis: Neovim plugin that runs ghcid to update the quickfix list
44
description: This plugin uses the nvim-hs plugin backend for neovim and
55
fills the quickfix list on file-saves with the errors and
@@ -39,8 +39,8 @@ library
3939
-- other-modules:
4040
other-extensions: OverloadedStrings, TemplateHaskell, DeriveGeneric, LambdaCase
4141
build-depends: base >=4.6 && <5
42-
, nvim-hs >=0.2.0
43-
, nvim-hs-contrib >=0.2.0
42+
, nvim-hs >=1.0 && <2
43+
, nvim-hs-contrib >=1.0 && <2
4444
, containers >=0.5
4545
, yaml
4646
, ghcid >=0.6.1
@@ -49,5 +49,6 @@ library
4949
, directory
5050
, filepath
5151
, transformers
52+
, unliftio
5253
-- hs-source-dirs:
5354
default-language: Haskell2010

0 commit comments

Comments
 (0)