@@ -94,6 +94,10 @@ import Data.Word (Word)
9494import Data.Either (partitionEithers)
9595import Control.DeepSeq
9696
97+import Control.Concurrent.Async (race)
98+import System.FSNotify (withManager, watchDir)
99+import System.FSNotify.Devel (allEvents, doAllEvents)
100+
97101import Numeric ( readHex )
98102
99103import Debug.Trace
@@ -671,6 +675,33 @@ lit f = case splitExtension f of
671675 (_, ".lidr") -> True
672676 _ -> False
673677
678+reload :: IState -> [FilePath] -> Idris (Maybe [FilePath])
679+reload orig inputs = do
680+ i <- getIState
681+ -- The $!! here prevents a space leak on reloading.
682+ -- This isn't a solution - but it's a temporary stopgap.
683+ -- See issue #2386
684+ putIState $!! orig { idris_options = idris_options i
685+ , idris_colourTheme = idris_colourTheme i
686+ , imported = imported i
687+ }
688+ clearErr
689+ fmap Just $ loadInputs inputs Nothing
690+
691+watch :: IState -> [FilePath] -> Idris (Maybe [FilePath])
692+watch orig inputs = do
693+ let inputSet = S.fromList inputs
694+ let dirs = nub $ map takeDirectory inputs
695+ resp <- runIO $ do
696+ signal <- newEmptyMVar
697+ withManager $ \mgr -> do
698+ forM_ dirs $ \dir ->
699+ watchDir mgr dir (allEvents $ flip S.member inputSet) (doAllEvents $ putMVar signal)
700+ race getLine (takeMVar signal)
701+ case resp of
702+ Left _ -> return (Just inputs) -- canceled, so nop
703+ Right _ -> reload orig inputs >> watch orig inputs
704+
674705processInput :: String ->
675706 IState -> [FilePath] -> FilePath -> Idris (Maybe [FilePath])
676707processInput cmd orig inputs efile
@@ -683,16 +714,15 @@ processInput cmd orig inputs efile
683714 Failure err -> do iputStrLn $ show (fixColour c err)
684715 return (Just inputs)
685716 Success (Right Reload) ->
686− -- The $!! here prevents a space leak on reloading.
687− -- This isn't a solution - but it's a temporary stopgap.
688− -- See issue #2386
689− do putIState $!! orig { idris_options = idris_options i
690− , idris_colourTheme = idris_colourTheme i
691− , imported = imported i
692− }
693− clearErr
694− mods <- loadInputs inputs Nothing
695− return (Just mods)
717+ reload orig inputs
718+ Success (Right Watch) ->
719+ if null inputs then
720+ do iputStrLn "No loaded files to watch."
721+ return (Just inputs)
722+ else
723+ do iputStrLn efile
724+ iputStrLn $ "Watching for .idr changes in " ++ show inputs ++ ", press enter to cancel."
725+ watch orig inputs
696726 Success (Right (Load f toline)) ->
697727 -- The $!! here prevents a space leak on reloading.
698728 -- This isn't a solution - but it's a temporary stopgap.