Skip to content

Commit 2ad92a0

Browse files
committed
Simple progress counter
1 parent 62892ae commit 2ad92a0

File tree

1 file changed

+35
-27
lines changed

1 file changed

+35
-27
lines changed

ghcide/src/Development/IDE/Core/ProgressReporting.hs

+35-27
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ module Development.IDE.Core.ProgressReporting
99
-- for tests
1010
, recordProgress
1111
, InProgressState(..)
12+
-- simple counter
13+
, progressCounter
1214
)
1315
where
1416

@@ -33,7 +35,7 @@ import Language.LSP.Server (ProgressAmount (..),
3335
withProgress)
3436
import qualified Language.LSP.Server as LSP
3537
import qualified StmContainers.Map as STM
36-
import UnliftIO (Async, async, cancel)
38+
import UnliftIO (Async, STM, async, cancel)
3739

3840
data ProgressEvent
3941
= KickStarted
@@ -103,40 +105,46 @@ progressReporting
103105
:: Maybe (LSP.LanguageContextEnv c)
104106
-> ProgressReportingStyle
105107
-> IO ProgressReporting
108+
progressReporting _ optProgressStyle | optProgressStyle == NoProgress = noProgressReporting
106109
progressReporting Nothing _optProgressStyle = noProgressReporting
107-
progressReporting (Just lspEnv) optProgressStyle = do
108-
inProgressState <- newInProgress
110+
progressReporting (Just lspEnv) _optProgressStyle = do
111+
inProgressState@InProgressState{todoVar, doneVar} <- newInProgress
109112
progressState <- newVar NotStarted
110113
let progressUpdate event = updateStateVar $ Event event
111114
progressStop = updateStateVar StopProgress
112-
updateStateVar = modifyVar_ progressState . updateState (lspShakeProgressNew inProgressState)
115+
updateStateVar = modifyVar_ progressState . updateState (progressCounter lspEnv (readTVar todoVar) (readTVar doneVar))
113116
inProgress = updateStateForFile inProgressState
114117
return ProgressReporting{..}
115118
where
116-
lspShakeProgressNew :: InProgressState -> IO ()
117-
lspShakeProgressNew InProgressState{..} =
118-
LSP.runLspT lspEnv $ withProgress "Processing" Nothing NotCancellable $ \update -> loop update 0
119-
where
120-
loop _ _ | optProgressStyle == NoProgress = forever $ liftIO $ threadDelay maxBound
121-
loop update prevPct = do
122-
(todo, done, nextPct) <- liftIO $ atomically $ do
123-
todo <- readTVar todoVar
124-
done <- readTVar doneVar
125-
let nextFrac :: Double
126-
nextFrac = if todo == 0 then 0 else fromIntegral done / fromIntegral todo
127-
nextPct :: UInt
128-
nextPct = floor $ 100 * nextFrac
129-
when (nextPct == prevPct) retry
130-
pure (todo, done, nextPct)
119+
updateStateForFile inProgress file = actionBracket (f succ) (const $ f pred) . const
120+
-- This functions are deliberately eta-expanded to avoid space leaks.
121+
-- Do not remove the eta-expansion without profiling a session with at
122+
-- least 1000 modifications.
123+
where
124+
f shift = recordProgress inProgress file shift
131125

132-
_ <- update (ProgressAmount (Just nextPct) (Just $ T.pack $ show done <> "/" <> show todo))
133-
loop update nextPct
134-
updateStateForFile inProgress file = actionBracket (f succ) (const $ f pred) . const
135-
-- This functions are deliberately eta-expanded to avoid space leaks.
136-
-- Do not remove the eta-expansion without profiling a session with at
137-
-- least 1000 modifications.
138-
where
139-
f shift = recordProgress inProgress file shift
126+
-- Kill this to complete the progress session
127+
progressCounter
128+
:: LSP.LanguageContextEnv c
129+
-> STM Int
130+
-> STM Int
131+
-> IO ()
132+
progressCounter lspEnv getTodo getDone =
133+
LSP.runLspT lspEnv $ withProgress "Processing" Nothing NotCancellable $ \update -> loop update 0
134+
where
135+
loop update prevPct = do
136+
(todo, done, nextPct) <- liftIO $ atomically $ do
137+
todo <- getTodo
138+
done <- getDone
139+
let nextFrac :: Double
140+
nextFrac = if todo == 0 then 0 else fromIntegral done / fromIntegral todo
141+
nextPct :: UInt
142+
nextPct = floor $ 100 * nextFrac
143+
when (nextPct == prevPct) retry
144+
pure (todo, done, nextPct)
145+
146+
_ <- update (ProgressAmount (Just nextPct) (Just $ T.pack $ show done <> "/" <> show todo))
147+
loop update nextPct
140148

141149
mRunLspT :: Applicative m => Maybe (LSP.LanguageContextEnv c ) -> LSP.LspT c m () -> m ()
142150
mRunLspT (Just lspEnv) f = LSP.runLspT lspEnv f

0 commit comments

Comments
 (0)