Fix re-init of ghc-modi session after environment change
Using `dropSession` instead of a weird exception cludge
This commit is contained in:
parent
20bccae1fc
commit
f61dd0a9e6
@ -28,6 +28,7 @@ module Language.Haskell.GhcMod (
|
|||||||
-- * Monad utilities
|
-- * Monad utilities
|
||||||
, runGhcModT
|
, runGhcModT
|
||||||
, withOptions
|
, withOptions
|
||||||
|
, dropSession
|
||||||
-- * 'GhcMod' utilities
|
-- * 'GhcMod' utilities
|
||||||
, boot
|
, boot
|
||||||
, browse
|
, browse
|
||||||
@ -73,3 +74,4 @@ import Language.Haskell.GhcMod.Modules
|
|||||||
import Language.Haskell.GhcMod.Monad
|
import Language.Haskell.GhcMod.Monad
|
||||||
import Language.Haskell.GhcMod.PkgDoc
|
import Language.Haskell.GhcMod.PkgDoc
|
||||||
import Language.Haskell.GhcMod.Types
|
import Language.Haskell.GhcMod.Types
|
||||||
|
import Language.Haskell.GhcMod.Target
|
||||||
|
@ -110,6 +110,8 @@ initSession opts mdf = do
|
|||||||
_ <- setSessionDynFlags =<< setDf =<< getSessionDynFlags
|
_ <- setSessionDynFlags =<< setDf =<< getSessionDynFlags
|
||||||
getSession
|
getSession
|
||||||
|
|
||||||
|
-- | Drop the currently active GHC session, the next that requires a GHC session
|
||||||
|
-- will initialize a new one.
|
||||||
dropSession :: IOish m => GhcModT m ()
|
dropSession :: IOish m => GhcModT m ()
|
||||||
dropSession = do
|
dropSession = do
|
||||||
s <- gmsGet
|
s <- gmsGet
|
||||||
@ -120,10 +122,10 @@ dropSession = do
|
|||||||
liftIO $ writeIORef ref (error "HscEnv: session was dropped")
|
liftIO $ writeIORef ref (error "HscEnv: session was dropped")
|
||||||
-- Not available on ghc<7.8; didn't really help anyways
|
-- Not available on ghc<7.8; didn't really help anyways
|
||||||
-- liftIO $ setUnsafeGlobalDynFlags (error "DynFlags: session was dropped")
|
-- liftIO $ setUnsafeGlobalDynFlags (error "DynFlags: session was dropped")
|
||||||
|
gmsPut s { gmGhcSession = Nothing }
|
||||||
|
|
||||||
Nothing -> return ()
|
Nothing -> return ()
|
||||||
gmsPut s { gmGhcSession = Nothing }
|
|
||||||
|
|
||||||
runGmlT :: IOish m => [Either FilePath ModuleName] -> GmlT m a -> GhcModT m a
|
runGmlT :: IOish m => [Either FilePath ModuleName] -> GmlT m a -> GhcModT m a
|
||||||
runGmlT fns action = runGmlT' fns return action
|
runGmlT fns action = runGmlT' fns return action
|
||||||
|
@ -341,12 +341,11 @@ progMain (globalOptions,cmdArgs) = do
|
|||||||
|
|
||||||
-- ghc-modi
|
-- ghc-modi
|
||||||
legacyInteractive :: IOish m => GhcModT m ()
|
legacyInteractive :: IOish m => GhcModT m ()
|
||||||
legacyInteractive =
|
legacyInteractive = do
|
||||||
liftIO emptyNewUnGetLine >>= \ref -> do
|
|
||||||
opt <- options
|
opt <- options
|
||||||
symdbreq <- liftIO $ newSymDbReq opt
|
symdbreq <- liftIO $ newSymDbReq opt
|
||||||
world <- liftIO . getCurrentWorld =<< cradle
|
world <- liftIO . getCurrentWorld =<< cradle
|
||||||
legacyInteractiveLoop symdbreq ref world
|
legacyInteractiveLoop symdbreq world
|
||||||
|
|
||||||
bug :: String -> IO ()
|
bug :: String -> IO ()
|
||||||
bug msg = do
|
bug msg = do
|
||||||
@ -363,19 +362,18 @@ replace :: String -> String -> String -> String
|
|||||||
replace needle replacement = intercalate replacement . splitOn needle
|
replace needle replacement = intercalate replacement . splitOn needle
|
||||||
|
|
||||||
legacyInteractiveLoop :: IOish m
|
legacyInteractiveLoop :: IOish m
|
||||||
=> SymDbReq -> UnGetLine -> World -> GhcModT m ()
|
=> SymDbReq -> World -> GhcModT m ()
|
||||||
legacyInteractiveLoop symdbreq ref world = do
|
legacyInteractiveLoop symdbreq world = do
|
||||||
liftIO . setCurrentDirectory =<< cradleRootDir <$> cradle
|
liftIO . setCurrentDirectory =<< cradleRootDir <$> cradle
|
||||||
|
|
||||||
-- blocking
|
-- blocking
|
||||||
cmdArg <- liftIO $ getCommand ref
|
cmdArg <- liftIO $ getLine
|
||||||
|
|
||||||
-- after blocking, we need to see if the world has changed.
|
-- after blocking, we need to see if the world has changed.
|
||||||
|
|
||||||
changed <- liftIO . didWorldChange world =<< cradle
|
changed <- liftIO . didWorldChange world =<< cradle
|
||||||
when changed $ do
|
when changed $ do
|
||||||
liftIO $ ungetCommand ref cmdArg
|
dropSession
|
||||||
throw Restart
|
|
||||||
|
|
||||||
let (cmd':args') = split (keepDelimsR $ condense $ whenElt isSpace) cmdArg
|
let (cmd':args') = split (keepDelimsR $ condense $ whenElt isSpace) cmdArg
|
||||||
arg = concat args'
|
arg = concat args'
|
||||||
@ -405,7 +403,7 @@ legacyInteractiveLoop symdbreq ref world = do
|
|||||||
_ -> fatalError $ "unknown command: `" ++ cmd ++ "'"
|
_ -> fatalError $ "unknown command: `" ++ cmd ++ "'"
|
||||||
|
|
||||||
liftIO $ putStr res >> putStrLn "OK" >> hFlush stdout
|
liftIO $ putStr res >> putStrLn "OK" >> hFlush stdout
|
||||||
legacyInteractiveLoop symdbreq ref world
|
legacyInteractiveLoop symdbreq world
|
||||||
|
|
||||||
globalCommands :: [String] -> Maybe String
|
globalCommands :: [String] -> Maybe String
|
||||||
globalCommands [] = Nothing
|
globalCommands [] = Nothing
|
||||||
|
39
src/Misc.hs
39
src/Misc.hs
@ -1,13 +1,7 @@
|
|||||||
{-# LANGUAGE DeriveDataTypeable, CPP #-}
|
{-# LANGUAGE DeriveDataTypeable, CPP #-}
|
||||||
|
|
||||||
module Misc (
|
module Misc (
|
||||||
GHCModiError(..)
|
SymDbReq
|
||||||
, Restart(..)
|
|
||||||
, UnGetLine
|
|
||||||
, emptyNewUnGetLine
|
|
||||||
, ungetCommand
|
|
||||||
, getCommand
|
|
||||||
, SymDbReq
|
|
||||||
, newSymDbReq
|
, newSymDbReq
|
||||||
, getDb
|
, getDb
|
||||||
, checkDb
|
, checkDb
|
||||||
@ -26,37 +20,6 @@ import Language.Haskell.GhcMod.Internal
|
|||||||
|
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
|
|
||||||
data GHCModiError = CmdArg [String] deriving (Show, Typeable)
|
|
||||||
|
|
||||||
instance Exception GHCModiError
|
|
||||||
|
|
||||||
----------------------------------------------------------------
|
|
||||||
|
|
||||||
data Restart = Restart deriving (Show, Typeable)
|
|
||||||
|
|
||||||
instance Exception Restart
|
|
||||||
|
|
||||||
----------------------------------------------------------------
|
|
||||||
|
|
||||||
newtype UnGetLine = UnGetLine (IORef (Maybe String))
|
|
||||||
|
|
||||||
emptyNewUnGetLine :: IO UnGetLine
|
|
||||||
emptyNewUnGetLine = UnGetLine <$> newIORef Nothing
|
|
||||||
|
|
||||||
ungetCommand :: UnGetLine -> String -> IO ()
|
|
||||||
ungetCommand (UnGetLine ref) cmd = writeIORef ref (Just cmd)
|
|
||||||
|
|
||||||
getCommand :: UnGetLine -> IO String
|
|
||||||
getCommand (UnGetLine ref) = do
|
|
||||||
mcmd <- readIORef ref
|
|
||||||
case mcmd of
|
|
||||||
Nothing -> getLine
|
|
||||||
Just cmd -> do
|
|
||||||
writeIORef ref Nothing
|
|
||||||
return cmd
|
|
||||||
|
|
||||||
----------------------------------------------------------------
|
|
||||||
|
|
||||||
type SymDbReqAction = (Either GhcModError SymbolDb, GhcModLog)
|
type SymDbReqAction = (Either GhcModError SymbolDb, GhcModLog)
|
||||||
data SymDbReq = SymDbReq (IORef (Async SymDbReqAction)) (IO SymDbReqAction)
|
data SymDbReq = SymDbReq (IORef (Async SymDbReqAction)) (IO SymDbReqAction)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user