packages feed

ghcid 0.6.5 → 0.6.6

raw patch · 8 files changed

+70/−26 lines, 8 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Language.Haskell.Ghcid: instance GHC.Classes.Eq Language.Haskell.Ghcid.Ghci

Files

CHANGES.txt view
@@ -1,5 +1,10 @@ Changelog for ghcid +0.6.6+    #89, exit sooner when the child process exits unexpectedly+    Add Eq instance for Ghci+    #88, add a --project flag+    Rename --notitle flag to --no-title 0.6.5     #82, properly deal with warning messages including spans     #78, support boot files better
README.md view
@@ -31,6 +31,10 @@  Please [report any bugs](https://github.com/ndmitchell/ghcid/issues) you find. +### Ghcid Integration++There are a few tools that integrate Ghcid into editors, see the [plugins](plugins/) folder for currently supported integrations.+ ### FAQ  * _This isn't as good as full IDE._ I've gone for simplicity over features. It's a point in the design space, but not necessarily the best point in the design space for you. For "real" IDEs see [the Haskell wiki](http://www.haskell.org/haskellwiki/IDEs).
ghcid.cabal view
@@ -1,7 +1,7 @@-cabal-version:      >= 1.10+cabal-version:      >= 1.18 build-type:         Simple name:               ghcid-version:            0.6.5+version:            0.6.6 license:            BSD3 license-file:       LICENSE category:           Development
src/Ghcid.hs view
@@ -36,11 +36,12 @@     ,arguments :: [String]     ,test :: [String]     ,warnings :: Bool-    ,nostatus :: Bool+    ,no_status :: Bool     ,height :: Maybe Int     ,width :: Maybe Int     ,topmost :: Bool-    ,notitle :: Bool+    ,no_title :: Bool+    ,project :: String     ,reload :: [FilePath]     ,restart :: [FilePath]     ,directory :: FilePath@@ -54,11 +55,12 @@     ,arguments = [] &= args &= typ "MODULE"     ,test = [] &= name "T" &= typ "EXPR" &= help "Command to run after successful loading"     ,warnings = False &= name "W" &= help "Allow tests to run even with warnings"-    ,nostatus = False &= name "S" &= explicit &= name "no-status" &= help "Suppress status messages"+    ,no_status = False &= name "S" &= help "Suppress status messages"     ,height = Nothing &= help "Number of lines to use (defaults to console height)"     ,width = Nothing &= name "w" &= help "Number of columns to use (defaults to console width)"     ,topmost = False &= name "t" &= help "Set window topmost (Windows only)"-    ,notitle = False &= help "Don't update the shell title/icon"+    ,no_title = False &= help "Don't update the shell title/icon"+    ,project = "" &= typ "NAME" &= help "Name of the project, defaults to current directory"     ,restart = [] &= typ "PATH" &= help "Restart the command when the given file or directory contents change (defaults to .ghci and any .cabal file)"     ,reload = [] &= typ "PATH" &= help "Reload when the given file or directory contents change (defaults to none)"     ,directory = "." &= typDir &= name "C" &= help "Set the current directory"@@ -192,14 +194,15 @@                 if null test || countErrors /= 0 || (countWarnings /= 0 && not warnings) then Nothing                 else Just $ intercalate "\n" test -            unless notitle $ setWindowIcon $+            unless no_title $ setWindowIcon $                 if countErrors > 0 then IconError else if countWarnings > 0 then IconWarning else IconOK -            let updateTitle extra = unless notitle $ setTitle $+            let updateTitle extra = unless no_title $ setTitle $                     let f n msg = if n == 0 then "" else show n ++ " " ++ msg ++ ['s' | n > 1]                     in (if countErrors == 0 && countWarnings == 0 then allGoodMessage else f countErrors "error" ++-                        (if countErrors > 0 && countWarnings > 0 then ", " else "") ++ f countWarnings "warning") ++-                       " " ++ extra ++ [' ' | extra /= ""] ++ "- " ++ takeFileName curdir+                       (if countErrors >  0 && countWarnings >  0 then ", " else "") ++ f countWarnings "warning") +++                       " " ++ extra ++ [' ' | extra /= ""] ++ "- " +++                       (if null project then takeFileName curdir else project)              updateTitle $ if isJust test then "(running test)" else ""             outputFill (Just (loadedCount, messages)) ["Running test..." | isJust test]@@ -220,7 +223,7 @@                         updateTitle "(test done)"              reason <- nextWait $ restart ++ reload ++ loaded-            unless nostatus $ outputFill Nothing $ "Reloading..." : map ("  " ++) reason+            unless no_status $ outputFill Nothing $ "Reloading..." : map ("  " ++) reason             restartTimes2 <- mapM getModTime restart             if restartTimes == restartTimes2 then do                 nextWait <- waitFiles waiter
src/Language/Haskell/Ghcid.hs view
@@ -20,6 +20,7 @@ import Data.Maybe import Data.IORef import Control.Applicative+import Data.Unique  import System.Console.CmdArgs.Verbosity @@ -37,8 +38,12 @@ data Ghci = Ghci     {ghciProcess :: ProcessHandle     ,ghciInterrupt :: IO ()-    ,ghciExec :: String -> (Stream -> String -> IO ()) -> IO ()}+    ,ghciExec :: String -> (Stream -> String -> IO ()) -> IO ()+    ,ghciUnique :: Unique+    } +instance Eq Ghci where+    a == b = ghciUnique a == ghciUnique b  -- | Start GHCi, returning a function to perform further operation, as well as the result of the initial loading. --   If you do not call 'stopGhci' then the underlying process may be leaked.@@ -132,6 +137,7 @@                 stop <- syncFresh                 void $ consume2 "Interrupt" $ \_ s -> return $ if stop s then Just () else Nothing +    ghciUnique <- newUnique     let ghci = Ghci{..}      -- Now wait for 'GHCi, version' to appear before sending anything real, required for #57
src/Language/Haskell/Ghcid/Terminal.hs view
@@ -24,11 +24,16 @@ iCON_BIG = 1 iCON_SMALL = 0 +#ifdef x86_64_HOST_ARCH+#define CALLCONV ccall+#else+#define CALLCONV stdcall+#endif -foreign import stdcall unsafe "windows.h GetConsoleWindow"+foreign import CALLCONV unsafe "windows.h GetConsoleWindow"     getConsoleWindow :: IO HWND -foreign import stdcall unsafe "windows.h SetWindowPos"+foreign import CALLCONV unsafe "windows.h SetWindowPos"     setWindowPos :: HWND -> HWND -> Int -> Int -> Int -> Int -> Word32 -> IO Bool #endif 
src/Session.hs view
@@ -27,14 +27,11 @@     ,command :: IORef (Maybe String) -- ^ The last command passed to sessionStart     ,warnings :: IORef [Load] -- ^ The warnings from the last load     ,running :: Var Bool -- ^ Am I actively running an async command+    ,withThread :: ThreadId -- ^ Thread that called withSession     }  --- | Ensure an action runs off the main thread, so can't get hit with Ctrl-C exceptions.---   Disabled because it plays havoc with tests and cleaning up quickly enough.-ctrlC :: IO a -> IO a-ctrlC = id -- join . onceFork-+debugShutdown x = when False $ print ("DEBUG SHUTDOWN", x)  -- | The function 'withSession' expects to be run on the main thread, --   but the inner function will not. This ensures Ctrl-C is handled@@ -45,18 +42,28 @@     command <- newIORef Nothing     warnings <- newIORef []     running <- newVar False-    ctrlC (f Session{..}) `finally` do+    debugShutdown "Starting session"+    withThread <- myThreadId+    f Session{..} `finally` do+        debugShutdown "Start finally"         modifyVar_ running $ const $ return False         whenJustM (readIORef ghci) $ \v -> do             writeIORef ghci Nothing-            ctrlC $ kill v+            debugShutdown "Calling kill"+            kill v+        debugShutdown "Finish finally"   -- | Kill. Wait just long enough to ensure you've done the job, but not to see the results. kill :: Ghci -> IO () kill ghci = ignore $ do-    timeout 5 $ quit ghci+    timeout 5 $ do+        debugShutdown "Before quit"+        ignore $ quit ghci+        debugShutdown "After quit"+    debugShutdown "Before terminateProcess"     terminateProcess $ process ghci+    debugShutdown "After terminateProcess"   -- | Spawn a new Ghci process at a given command line. Returns the load messages, plus@@ -65,12 +72,26 @@ sessionStart Session{..} cmd = do     modifyVar_ running $ const $ return False     writeIORef command $ Just cmd-    val <- readIORef ghci-    whenJust val $ void . forkIO . kill-    writeIORef ghci Nothing++    -- cleanup any old instances+    whenJustM (readIORef ghci) $ \v -> do+        writeIORef ghci Nothing+        void $ forkIO $ kill v++    -- start the new     outStrLn $ "Loading " ++ cmd ++ " ..."     (v, messages) <- startGhci cmd Nothing $ const outStrLn     writeIORef ghci $ Just v++    -- install a handler+    forkIO $ do+        waitForProcess $ process v+        whenJustM (readIORef ghci) $ \ghci ->+            when (ghci == v) $ do+                sleep 0.3 -- give anyone reading from the stream a chance to throw first+                throwTo withThread $ ErrorCall $ "Command \"" ++ cmd ++ "\" exited unexpectedly"++    -- handle what the process returned     messages <- return $ mapMaybe tidyMessage messages     writeIORef warnings [m | m@Message{..} <- messages, loadSeverity == Warning]     return (messages, nubOrd $ map loadFile messages)
src/Test/Ghcid.hs view
@@ -71,7 +71,7 @@     done <- newBarrier     res <- bracket         (flip forkFinally (const $ signalBarrier done ()) $-            withArgs (["--notitle","--no-status"]++args) $+            withArgs (["--no-title","--no-status"]++args) $                 mainWithTerminal (return (100, 50)) output)         killThread $ \_ -> script require     waitBarrier done