@@ -196,7 +196,7 @@ main = do
196196 hPutStrLn stderr $ " with arguments: " <> show args
197197 hPutStrLn stderr $ " with plugins: " <> show (Map. keys $ ipMap idePlugins')
198198 hPutStrLn stderr " If you are seeing this in a terminal, you probably should have run ghcide WITHOUT the --lsp option!"
199- runLanguageServer options (pluginHandler plugins) getInitialConfig getConfigFromNotification $ \ getLspId event vfs caps -> do
199+ runLanguageServer options (pluginHandler plugins) getInitialConfig getConfigFromNotification $ \ getLspId event vfs caps wProg wIndefProg -> do
200200 t <- t
201201 hPutStrLn stderr $ " Started LSP server in " ++ showDuration t
202202 let options = (defaultIdeOptions $ loadSessionShake dir)
@@ -207,7 +207,7 @@ main = do
207207 }
208208 debouncer <- newAsyncDebouncer
209209 initialise caps (mainRule >> pluginRules plugins)
210- getLspId event hlsLogger debouncer options vfs
210+ getLspId event wProg wIndefProg hlsLogger debouncer options vfs
211211 else do
212212 -- GHC produces messages with UTF8 in them, so make sure the terminal doesn't error
213213 hSetEncoding stdout utf8
@@ -230,7 +230,8 @@ main = do
230230 putStrLn " \n Step 3/4: Initializing the IDE"
231231 vfs <- makeVFSHandle
232232 debouncer <- newAsyncDebouncer
233- ide <- initialise def mainRule (pure $ IdInt 0 ) (showEvent lock) (logger Info ) debouncer (defaultIdeOptions $ loadSessionShake dir) vfs
233+ let dummyWithProg _ _ f = f (const (pure () ))
234+ ide <- initialise def mainRule (pure $ IdInt 0 ) (showEvent lock) dummyWithProg (const (const id )) (logger Info ) debouncer (defaultIdeOptions $ loadSessionShake dir) vfs
234235
235236 putStrLn " \n Step 4/4: Type checking the files"
236237 setFilesOfInterest ide $ HashSet. fromList $ map toNormalizedFilePath' files
@@ -304,13 +305,13 @@ loadSessionShake fp = do
304305 se <- getShakeExtras
305306 IdeOptions {optTesting = IdeTesting ideTesting} <- getIdeOptions
306307 res <- liftIO $ loadSession ideTesting se fp
307- return ( fmap liftIO res)
308+ return res
308309
309310-- | This is the key function which implements multi-component support. All
310311-- components mapping to the same hie.yaml file are mapped to the same
311312-- HscEnv which is updated as new components are discovered.
312- loadSession :: Bool -> ShakeExtras -> FilePath -> IO (FilePath -> IO (IdeResult HscEnvEq ))
313- loadSession optTesting ShakeExtras {logger, eventer, restartShakeSession , ideNc} dir = do
313+ loadSession :: Bool -> ShakeExtras -> FilePath -> IO (FilePath -> Action (IdeResult HscEnvEq ))
314+ loadSession optTesting ShakeExtras {logger, eventer, withIndefiniteProgress , ideNc} dir = do
314315 -- Mapping from hie.yaml file to HscEnv, one per hie.yaml file
315316 hscEnvs <- newVar Map. empty :: IO (Var HieMap )
316317 -- Mapping from a Filepath to HscEnv
@@ -403,7 +404,7 @@ loadSession optTesting ShakeExtras{logger, eventer, restartShakeSession, ideNc}
403404 -- existing packages
404405 pure (Map. insert hieYaml (newHscEnv, new_deps) m, (newHscEnv, head new_deps', tail new_deps'))
405406
406- let session :: (Maybe FilePath , NormalizedFilePath , ComponentOptions ) -> IO (IdeResult HscEnvEq )
407+ let session :: (Maybe FilePath , NormalizedFilePath , ComponentOptions ) -> IO ([ NormalizedFilePath ], IdeResult HscEnvEq )
407408 session (hieYaml, cfp, opts) = do
408409 (hscEnv, new, old_deps) <- packageSetup (hieYaml, cfp, opts)
409410 -- Make a map from unit-id to DynFlags, this is used when trying to
@@ -424,16 +425,22 @@ loadSession optTesting ShakeExtras{logger, eventer, restartShakeSession, ideNc}
424425 pure $ Map. insert hieYaml (HM. fromList (cs ++ cached_targets)) var
425426
426427 -- Invalidate all the existing GhcSession build nodes by restarting the Shake session
427- restartShakeSession [kick]
428+ -- restartShakeSession [kick]
428429
429- return (fst res)
430+ return (map fst cs, fst res)
430431
431- let consultCradle :: Maybe FilePath -> FilePath -> IO (IdeResult HscEnvEq )
432+ let consultCradle :: Maybe FilePath -> FilePath -> IO ([ NormalizedFilePath ], IdeResult HscEnvEq )
432433 consultCradle hieYaml cfp = do
433434 when optTesting $ eventer $ notifyCradleLoaded cfp
434435 logInfo logger $ T. pack (" Consulting the cradle for " <> show cfp)
436+
435437 cradle <- maybe (loadImplicitCradle $ addTrailingPathSeparator dir) loadCradle hieYaml
436- eopts <- cradleToSessionOpts cradle cfp
438+ -- Display a user friendly progress message here: They probably don't know what a
439+ -- cradle is
440+ let progMsg = " Setting up project " <> T. pack (takeBaseName (cradleRootDir cradle))
441+ eopts <- withIndefiniteProgress progMsg LSP. NotCancellable $
442+ cradleToSessionOpts cradle cfp
443+
437444 logDebug logger $ T. pack (" Session loading result: " <> show eopts)
438445 case eopts of
439446 -- The cradle gave us some options so get to work turning them
@@ -447,10 +454,10 @@ loadSession optTesting ShakeExtras{logger, eventer, restartShakeSession, ideNc}
447454 let res = (map (renderCradleError ncfp) err, Nothing )
448455 modifyVar_ fileToFlags $ \ var -> do
449456 pure $ Map. insertWith HM. union hieYaml (HM. singleton ncfp (res, dep_info)) var
450- return res
457+ return ([ncfp], res)
451458
452459 -- This caches the mapping from hie.yaml + Mod.hs -> [String]
453- let sessionOpts :: (Maybe FilePath , FilePath ) -> IO (IdeResult HscEnvEq )
460+ let sessionOpts :: (Maybe FilePath , FilePath ) -> IO ([ NormalizedFilePath ], IdeResult HscEnvEq )
454461 sessionOpts (hieYaml, file) = do
455462 v <- fromMaybe HM. empty . Map. lookup hieYaml <$> readVar fileToFlags
456463 cfp <- canonicalizePath file
@@ -465,7 +472,7 @@ loadSession optTesting ShakeExtras{logger, eventer, restartShakeSession, ideNc}
465472 -- Keep the same name cache
466473 modifyVar_ hscEnvs (return . Map. adjust (\ (h, _) -> (h, [] )) hieYaml )
467474 consultCradle hieYaml cfp
468- else return opts
475+ else return ( [] , opts)
469476 Nothing -> consultCradle hieYaml cfp
470477
471478 dummyAs <- async $ return (error " Uninitialised" )
@@ -474,18 +481,26 @@ loadSession optTesting ShakeExtras{logger, eventer, restartShakeSession, ideNc}
474481 -- at a time. Therefore the IORef contains the currently running cradle, if we try
475482 -- to get some more options then we wait for the currently running action to finish
476483 -- before attempting to do so.
477- let getOptions :: FilePath -> IO (IdeResult HscEnvEq )
484+ let getOptions :: FilePath -> IO ([ NormalizedFilePath ], IdeResult HscEnvEq )
478485 getOptions file = do
479486 hieYaml <- cradleLoc file
480- sessionOpts (hieYaml, file) `catch` \ e ->
481- return ([renderPackageSetupException compileTime file e], Nothing )
487+ sessionOpts (hieYaml, file) `catch` \ e -> do
488+ return ([] ,([ renderPackageSetupException compileTime file e], Nothing ) )
482489
483490 return $ \ file -> do
484- join $ mask_ $ modifyVar runningCradle $ \ as -> do
491+ (cs, opts) <- liftIO $ join $ mask_ $ modifyVar runningCradle $ \ as -> do
485492 -- If the cradle is not finished, then wait for it to finish.
486493 void $ wait as
487494 as <- async $ getOptions file
488- return (as, wait as)
495+ return $ (fmap snd as, wait as)
496+ let cfps = cs
497+ unless (null cs) $
498+ delay " InitialLoad" $ void $ do
499+ cfps' <- liftIO $ filterM (IO. doesFileExist . fromNormalizedFilePath) cfps
500+ mmt <- uses GetModificationTime cfps'
501+ let cs_exist = catMaybes (zipWith (<$) cfps' mmt)
502+ uses GetModIface cs_exist
503+ pure opts
489504
490505
491506
@@ -577,7 +592,7 @@ setCacheDir logger prefix hscComponents comps dflags = do
577592 liftIO $ logInfo logger $ " Using interface files cache dir: " <> T. pack cacheDir
578593 pure $ dflags
579594 & setHiDir cacheDir
580- & setDefaultHieDir cacheDir
595+ & setHieDir cacheDir
581596
582597
583598renderCradleError :: NormalizedFilePath -> CradleError -> FileDiagnostic
0 commit comments