@@ -114,71 +114,6 @@ restartCabalShakeSession ide vfs file actionMsg = do
114114 join $ atomically $ Shake. recordDirtyKeys (shakeExtras ide) GetModificationTime [file]
115115 restartShakeSession (shakeExtras ide) (VFSModified vfs) (fromNormalizedFilePath file ++ " " ++ actionMsg) []
116116
117- -- ----------------------------------------------------------------
118- -- Cabal file of Interset rules and global variable
119- -- ----------------------------------------------------------------
120-
121- newtype OfInterestCabalVar = OfInterestCabalVar (Var (HashMap NormalizedFilePath FileOfInterestStatus ))
122-
123- instance Shake. IsIdeGlobal OfInterestCabalVar
124-
125- data IsCabalFileOfInterest = IsCabalFileOfInterest
126- deriving (Eq , Show , Typeable , Generic )
127- instance Hashable IsCabalFileOfInterest
128- instance NFData IsCabalFileOfInterest
129-
130- type instance RuleResult IsCabalFileOfInterest = CabalFileOfInterestResult
131-
132- data CabalFileOfInterestResult = NotCabalFOI | IsCabalFOI FileOfInterestStatus
133- deriving (Eq , Show , Typeable , Generic )
134- instance Hashable CabalFileOfInterestResult
135- instance NFData CabalFileOfInterestResult
136-
137- -- | The rule that initialises the files of interest state.
138- ofInterestRules :: Recorder (WithPriority Log ) -> Rules ()
139- ofInterestRules recorder = do
140- Shake. addIdeGlobal . OfInterestCabalVar =<< liftIO (newVar HashMap. empty)
141- Shake. defineEarlyCutoff (cmapWithPrio LogShake recorder) $ RuleNoDiagnostics $ \ IsCabalFileOfInterest f -> do
142- alwaysRerun
143- filesOfInterest <- getCabalFilesOfInterestUntracked
144- let foi = maybe NotCabalFOI IsCabalFOI $ f `HashMap.lookup` filesOfInterest
145- fp = summarize foi
146- res = (Just fp, Just foi)
147- return res
148- where
149- summarize NotCabalFOI = BS. singleton 0
150- summarize (IsCabalFOI OnDisk ) = BS. singleton 1
151- summarize (IsCabalFOI (Modified False )) = BS. singleton 2
152- summarize (IsCabalFOI (Modified True )) = BS. singleton 3
153-
154- getCabalFilesOfInterestUntracked :: Action (HashMap NormalizedFilePath FileOfInterestStatus )
155- getCabalFilesOfInterestUntracked = do
156- OfInterestCabalVar var <- Shake. getIdeGlobalAction
157- liftIO $ readVar var
158-
159- getFilesOfInterest :: IdeState -> IO ( HashMap NormalizedFilePath FileOfInterestStatus )
160- getFilesOfInterest state = do
161- OfInterestCabalVar var <- Shake. getIdeGlobalState state
162- readVar var
163-
164- addFileOfInterest :: IdeState -> NormalizedFilePath -> FileOfInterestStatus -> IO ()
165- addFileOfInterest state f v = do
166- OfInterestCabalVar var <- Shake. getIdeGlobalState state
167- (prev, files) <- modifyVar var $ \ dict -> do
168- let (prev, new) = HashMap. alterF (, Just v) f dict
169- pure (new, (prev, new))
170- when (prev /= Just v) $ do
171- join $ atomically $ Shake. recordDirtyKeys (shakeExtras state) IsFileOfInterest [f]
172- logDebug (ideLogger state) $
173- " Set files of interest to: " <> T. pack (show files)
174-
175- deleteFileOfInterest :: IdeState -> NormalizedFilePath -> IO ()
176- deleteFileOfInterest state f = do
177- OfInterestCabalVar var <- Shake. getIdeGlobalState state
178- files <- modifyVar' var $ HashMap. delete f
179- join $ atomically $ Shake. recordDirtyKeys (shakeExtras state) IsFileOfInterest [f]
180- logDebug (ideLogger state) $ " Set files of interest to: " <> T. pack (show files)
181-
182117-- ----------------------------------------------------------------
183118-- Plugin Rules
184119-- ----------------------------------------------------------------
@@ -192,7 +127,9 @@ type instance RuleResult ParseCabal = ()
192127
193128cabalRules :: Recorder (WithPriority Log ) -> Rules ()
194129cabalRules recorder = do
130+ -- Make sure we initialise the cabal files-of-interest.
195131 ofInterestRules recorder
132+ -- Rule to produce diagnostics for cabal files.
196133 define (cmapWithPrio LogShake recorder) $ \ ParseCabal file -> do
197134 t <- use GetModificationTime file
198135 log' Debug $ LogModificationTime file t
@@ -222,7 +159,12 @@ cabalRules recorder = do
222159 where
223160 log' = logWith recorder
224161
225- -- | TODO: add documentation
162+ -- | This is the kick function for the cabal plugin.
163+ -- We run this action, whenever we need to restart the shake session, which triggers
164+ -- actions to produce diagnostics for cabal files.
165+ --
166+ -- It is paramount that this kick-function can be run quickly, since it is a blocking
167+ -- function invocation.
226168kick :: Action ()
227169kick = do
228170 files <- HashMap. keys <$> getCabalFilesOfInterestUntracked
@@ -239,3 +181,71 @@ licenseSuggestCodeAction
239181 -> LspM Config (Either ResponseError (ResponseResult 'TextDocumentCodeAction))
240182licenseSuggestCodeAction _ _ (CodeActionParams _ _ (TextDocumentIdentifier uri) _range CodeActionContext {_diagnostics= List diags}) =
241183 pure $ Right $ List $ mapMaybe (fmap InR . LicenseSuggest. licenseErrorAction uri) diags
184+
185+ -- ----------------------------------------------------------------
186+ -- Cabal file of Interest rules and global variable
187+ -- ----------------------------------------------------------------
188+
189+ -- | Cabal files that are currently open in the lsp-client.
190+ -- Specific actions happen when these files are saved, closed or modified,
191+ -- such as generating diagnostics, re-parsing, etc...
192+ --
193+ -- We need to store the open files to parse them again if we restart the shake session.
194+ -- Restarting of the shake session happens whenever these files are modified.
195+ newtype OfInterestCabalVar = OfInterestCabalVar (Var (HashMap NormalizedFilePath FileOfInterestStatus ))
196+
197+ instance Shake. IsIdeGlobal OfInterestCabalVar
198+
199+ data IsCabalFileOfInterest = IsCabalFileOfInterest
200+ deriving (Eq , Show , Typeable , Generic )
201+ instance Hashable IsCabalFileOfInterest
202+ instance NFData IsCabalFileOfInterest
203+
204+ type instance RuleResult IsCabalFileOfInterest = CabalFileOfInterestResult
205+
206+ data CabalFileOfInterestResult = NotCabalFOI | IsCabalFOI FileOfInterestStatus
207+ deriving (Eq , Show , Typeable , Generic )
208+ instance Hashable CabalFileOfInterestResult
209+ instance NFData CabalFileOfInterestResult
210+
211+ -- | The rule that initialises the files of interest state.
212+ --
213+ -- Needs to be run on start-up.
214+ ofInterestRules :: Recorder (WithPriority Log ) -> Rules ()
215+ ofInterestRules recorder = do
216+ Shake. addIdeGlobal . OfInterestCabalVar =<< liftIO (newVar HashMap. empty)
217+ Shake. defineEarlyCutoff (cmapWithPrio LogShake recorder) $ RuleNoDiagnostics $ \ IsCabalFileOfInterest f -> do
218+ alwaysRerun
219+ filesOfInterest <- getCabalFilesOfInterestUntracked
220+ let foi = maybe NotCabalFOI IsCabalFOI $ f `HashMap.lookup` filesOfInterest
221+ fp = summarize foi
222+ res = (Just fp, Just foi)
223+ return res
224+ where
225+ summarize NotCabalFOI = BS. singleton 0
226+ summarize (IsCabalFOI OnDisk ) = BS. singleton 1
227+ summarize (IsCabalFOI (Modified False )) = BS. singleton 2
228+ summarize (IsCabalFOI (Modified True )) = BS. singleton 3
229+
230+ getCabalFilesOfInterestUntracked :: Action (HashMap NormalizedFilePath FileOfInterestStatus )
231+ getCabalFilesOfInterestUntracked = do
232+ OfInterestCabalVar var <- Shake. getIdeGlobalAction
233+ liftIO $ readVar var
234+
235+ addFileOfInterest :: IdeState -> NormalizedFilePath -> FileOfInterestStatus -> IO ()
236+ addFileOfInterest state f v = do
237+ OfInterestCabalVar var <- Shake. getIdeGlobalState state
238+ (prev, files) <- modifyVar var $ \ dict -> do
239+ let (prev, new) = HashMap. alterF (, Just v) f dict
240+ pure (new, (prev, new))
241+ when (prev /= Just v) $ do
242+ join $ atomically $ Shake. recordDirtyKeys (shakeExtras state) IsFileOfInterest [f]
243+ logDebug (ideLogger state) $
244+ " Set files of interest to: " <> T. pack (show files)
245+
246+ deleteFileOfInterest :: IdeState -> NormalizedFilePath -> IO ()
247+ deleteFileOfInterest state f = do
248+ OfInterestCabalVar var <- Shake. getIdeGlobalState state
249+ files <- modifyVar' var $ HashMap. delete f
250+ join $ atomically $ Shake. recordDirtyKeys (shakeExtras state) IsFileOfInterest [f]
251+ logDebug (ideLogger state) $ " Set files of interest to: " <> T. pack (show files)
0 commit comments