Skip to content

Commit

Permalink
Civilized indexing progress reporting (haskell#1633)
Browse files Browse the repository at this point in the history
* Civilized indexing progress reporting

* optProgressStyle

* Consistency: Indexing references ==> Indexing

* Fix progress tests
  • Loading branch information
pepeiborra authored and berberman committed Apr 4, 2021
1 parent 6089686 commit f0b89fd
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 26 deletions.
35 changes: 24 additions & 11 deletions ghcide/src/Development/IDE/Core/Compile.hs
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,9 @@ spliceExpresions Splices{..} =
-- can just increment the 'indexCompleted' TVar and exit.
--
indexHieFile :: ShakeExtras -> ModSummary -> NormalizedFilePath -> Fingerprint -> Compat.HieFile -> IO ()
indexHieFile se mod_summary srcPath hash hf = atomically $ do
indexHieFile se mod_summary srcPath hash hf = do
IdeOptions{optProgressStyle} <- getIdeOptionsIO se
atomically $ do
pending <- readTVar indexPending
case HashMap.lookup srcPath pending of
Just pendingHash | pendingHash == hash -> pure () -- An index is already scheduled
Expand All @@ -523,7 +525,7 @@ indexHieFile se mod_summary srcPath hash hf = atomically $ do
-- If the hash in the pending list doesn't match the current hash, then skip
Just pendingHash -> pendingHash /= hash
unless newerScheduled $ do
pre
pre optProgressStyle
addRefsFromLoaded db targetPath (RealFile $ fromNormalizedFilePath srcPath) hash hf
post
where
Expand All @@ -532,7 +534,7 @@ indexHieFile se mod_summary srcPath hash hf = atomically $ do
HieDbWriter{..} = hiedbWriter se

-- Get a progress token to report progress and update it for the current file
pre = do
pre style = do
tok <- modifyVar indexProgressToken $ fmap dupe . \case
x@(Just _) -> pure x
-- Create a token if we don't already have one
Expand All @@ -545,7 +547,7 @@ indexHieFile se mod_summary srcPath hash hf = atomically $ do
_ <- LSP.sendRequest LSP.SWindowWorkDoneProgressCreate (LSP.WorkDoneProgressCreateParams u) (const $ pure ())
LSP.sendNotification LSP.SProgress $ LSP.ProgressParams u $
LSP.Begin $ LSP.WorkDoneProgressBeginParams
{ _title = "Indexing references from:"
{ _title = "Indexing"
, _cancellable = Nothing
, _message = Nothing
, _percentage = Nothing
Expand All @@ -557,15 +559,26 @@ indexHieFile se mod_summary srcPath hash hf = atomically $ do
remaining <- HashMap.size <$> readTVar indexPending
pure (done, remaining)

let progress = " (" <> T.pack (show done) <> "/" <> T.pack (show $ done + remaining) <> ")..."

whenJust (lspEnv se) $ \env -> whenJust tok $ \tok -> LSP.runLspT env $
LSP.sendNotification LSP.SProgress $ LSP.ProgressParams tok $
LSP.Report $ LSP.WorkDoneProgressReportParams
{ _cancellable = Nothing
, _message = Just $ T.pack (fromNormalizedFilePath srcPath) <> progress
, _percentage = Nothing
}
LSP.Report $
case style of
Percentage -> LSP.WorkDoneProgressReportParams
{ _cancellable = Nothing
, _message = Nothing
, _percentage = Just (100 * fromIntegral done / fromIntegral (done + remaining) )
}
Explicit -> LSP.WorkDoneProgressReportParams
{ _cancellable = Nothing
, _message = Just $
T.pack " (" <> T.pack (show done) <> "/" <> T.pack (show $ done + remaining) <> ")..."
, _percentage = Nothing
}
NoProgress -> LSP.WorkDoneProgressReportParams
{ _cancellable = Nothing
, _message = Nothing
, _percentage = Nothing
}

-- Report the progress once we are done indexing this file
post = do
Expand Down
34 changes: 24 additions & 10 deletions ghcide/src/Development/IDE/Core/Shake.hs
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ shakeOpen lspEnv defaultConfig logger debouncer
let hiedbWriter = HieDbWriter{..}
progressAsync <- async $
when reportProgress $
progressThread mostRecentProgressEvent inProgress
progressThread optProgressStyle mostRecentProgressEvent inProgress
exportsMap <- newVar mempty

actionQueue <- newQueue
Expand All @@ -517,7 +517,10 @@ shakeOpen lspEnv defaultConfig logger debouncer
shakeDatabaseProfile <- shakeDatabaseProfileIO shakeProfileDir
let ideState = IdeState{..}

IdeOptions{ optOTMemoryProfiling = IdeOTMemoryProfiling otProfilingEnabled } <- getIdeOptionsIO shakeExtras
IdeOptions
{ optOTMemoryProfiling = IdeOTMemoryProfiling otProfilingEnabled
, optProgressStyle
} <- getIdeOptionsIO shakeExtras
startTelemetry otProfilingEnabled logger $ state shakeExtras

return ideState
Expand All @@ -528,7 +531,7 @@ shakeOpen lspEnv defaultConfig logger debouncer
-- And two transitions, modelled by 'ProgressEvent':
-- 1. KickCompleted - transitions from Reporting into Idle
-- 2. KickStarted - transitions from Idle into Reporting
progressThread mostRecentProgressEvent inProgress = progressLoopIdle
progressThread style mostRecentProgressEvent inProgress = progressLoopIdle
where
progressLoopIdle = do
atomically $ do
Expand Down Expand Up @@ -560,7 +563,7 @@ shakeOpen lspEnv defaultConfig logger debouncer
bracket_
(start u)
(stop u)
(loop u Nothing)
(loop u 0)
where
start id = LSP.sendNotification LSP.SProgress $
LSP.ProgressParams
Expand All @@ -585,16 +588,27 @@ shakeOpen lspEnv defaultConfig logger debouncer
current <- liftIO $ readVar inProgress
let done = length $ filter (== 0) $ HMap.elems current
let todo = HMap.size current
let next = Just $ T.pack $ show done <> "/" <> show todo
let next = 100 * fromIntegral done / fromIntegral todo
when (next /= prev) $
LSP.sendNotification LSP.SProgress $
LSP.ProgressParams
{ _token = id
, _value = LSP.Report $ LSP.WorkDoneProgressReportParams
{ _cancellable = Nothing
, _message = next
, _percentage = Nothing
}
, _value = LSP.Report $ case style of
Explicit -> LSP.WorkDoneProgressReportParams
{ _cancellable = Nothing
, _message = Just $ T.pack $ show done <> "/" <> show todo
, _percentage = Nothing
}
Percentage -> LSP.WorkDoneProgressReportParams
{ _cancellable = Nothing
, _message = Nothing
, _percentage = Just next
}
NoProgress -> LSP.WorkDoneProgressReportParams
{ _cancellable = Nothing
, _message = Nothing
, _percentage = Nothing
}
}
loop id next

Expand Down
9 changes: 9 additions & 0 deletions ghcide/src/Development/IDE/Types/Options.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module Development.IDE.Types.Options
, IdeResult
, IdeGhcSession(..)
, OptHaddockParse(..)
, ProgressReportingStyle(..)
,optShakeFiles) where

import qualified Data.Text as T
Expand Down Expand Up @@ -78,6 +79,7 @@ data IdeOptions = IdeOptions
, optShakeOptions :: ShakeOptions
, optSkipProgress :: forall a. Typeable a => a -> Bool
-- ^ Predicate to select which rule keys to exclude from progress reporting.
, optProgressStyle :: ProgressReportingStyle
}

optShakeFiles :: IdeOptions -> Maybe FilePath
Expand All @@ -104,6 +106,12 @@ newtype IdeDefer = IdeDefer Bool
newtype IdeTesting = IdeTesting Bool
newtype IdeOTMemoryProfiling = IdeOTMemoryProfiling Bool

data ProgressReportingStyle
= Percentage -- ^ Report using the LSP @_percentage@ field
| Explicit -- ^ Report using explicit 123/456 text
| NoProgress -- ^ Do not report any percentage


clientSupportsProgress :: LSP.ClientCapabilities -> IdeReportProgress
clientSupportsProgress caps = IdeReportProgress $ Just True ==
(LSP._workDoneProgress =<< LSP._window (caps :: LSP.ClientCapabilities))
Expand Down Expand Up @@ -131,6 +139,7 @@ defaultIdeOptions session = IdeOptions
,optHaddockParse = HaddockParse
,optCustomDynFlags = id
,optSkipProgress = defaultSkipProgress
,optProgressStyle = Explicit
}

defaultSkipProgress :: Typeable a => a -> Bool
Expand Down
9 changes: 4 additions & 5 deletions test/functional/Progress.hs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ tests =
runSession hlsCommand progressCaps "test/testdata" $ do
let path = "hlint" </> "ApplyRefact2.hs"
_ <- openDoc path "haskell"
expectProgressReports [pack ("Setting up hlint (for " ++ path ++ ")"), "Processing"]
expectProgressReports [pack ("Setting up hlint (for " ++ path ++ ")"), "Processing", "Indexing"]
, testCase "eval plugin sends progress reports" $
runSession hlsCommand progressCaps "plugins/hls-eval-plugin/test/testdata" $ do
doc <- openDoc "T1.hs" "haskell"
expectProgressReports ["Setting up testdata (for T1.hs)", "Processing"]
expectProgressReports ["Setting up testdata (for T1.hs)", "Processing", "Indexing"]
[evalLens] <- getCodeLenses doc
let cmd = evalLens ^?! L.command . _Just
_ <- sendRequest SWorkspaceExecuteCommand $ ExecuteCommandParams Nothing (cmd ^. L.command) (decode $ encode $ fromJust $ cmd ^. L.arguments)
Expand All @@ -41,14 +41,14 @@ tests =
runSession hlsCommand progressCaps "test/testdata/format" $ do
sendNotification SWorkspaceDidChangeConfiguration (DidChangeConfigurationParams (formatLspConfig "ormolu"))
doc <- openDoc "Format.hs" "haskell"
expectProgressReports ["Setting up testdata (for Format.hs)", "Processing"]
expectProgressReports ["Setting up testdata (for Format.hs)", "Processing", "Indexing"]
_ <- sendRequest STextDocumentFormatting $ DocumentFormattingParams Nothing doc (FormattingOptions 2 True Nothing Nothing Nothing)
expectProgressReports ["Formatting Format.hs"]
, testCase "fourmolu plugin sends progress notifications" $ do
runSession hlsCommand progressCaps "test/testdata/format" $ do
sendNotification SWorkspaceDidChangeConfiguration (DidChangeConfigurationParams (formatLspConfig "fourmolu"))
doc <- openDoc "Format.hs" "haskell"
expectProgressReports ["Setting up testdata (for Format.hs)", "Processing"]
expectProgressReports ["Setting up testdata (for Format.hs)", "Processing", "Indexing"]
_ <- sendRequest STextDocumentFormatting $ DocumentFormattingParams Nothing doc (FormattingOptions 2 True Nothing Nothing Nothing)
expectProgressReports ["Formatting Format.hs"]
, ignoreTestBecause "no liquid Haskell support" $
Expand Down Expand Up @@ -90,7 +90,6 @@ expectProgressReports xs = expectProgressReports' [] xs
CreateM msg ->
expectProgressReports' (token msg : tokens) expectedTitles
BeginM msg -> do
liftIO $ title msg `expectElem` ("Indexing references from:":xs)
liftIO $ token msg `expectElem` tokens
expectProgressReports' tokens (delete (title msg) expectedTitles)
ProgressM msg -> do
Expand Down

0 comments on commit f0b89fd

Please sign in to comment.