packages feed

ghcid 0.3.2 → 0.3.3

raw patch · 8 files changed

+37/−52 lines, 8 filesdep +containersdep ~terminal-sizePVP ok

version bump matches the API change (PVP)

Dependencies added: containers

Dependency ranges changed: terminal-size

API changes (from Hackage documentation)

Files

CHANGES.txt view
@@ -1,5 +1,8 @@ Changelog for GHCiD +0.3.3+    #21, if the root file is missing, report an error+    #20, avoid an O(n^2) nub 0.3.2     #18, reformat excessively long lines, add a --width flag 0.3.1
README.md view
@@ -1,4 +1,4 @@-# ghcid [![Hackage version](https://img.shields.io/hackage/v/ghcid.svg?style=flat)](http://hackage.haskell.org/package/ghcid) [![Build Status](http://img.shields.io/travis/ndmitchell/ghcid.svg?style=flat)](https://travis-ci.org/ndmitchell/ghcid)+# ghcid [![Hackage version](https://img.shields.io/hackage/v/ghcid.svg?style=flat)](https://hackage.haskell.org/package/ghcid) [![Build Status](https://img.shields.io/travis/ndmitchell/ghcid.svg?style=flat)](https://travis-ci.org/ndmitchell/ghcid)  Either "GHCi as a daemon" or "GHC + a bit of an IDE". To a first approximation, it opens `ghci` and runs `:reload` whenever your source code changes, formatting the output to fit a fixed height console. Unlike other Haskell development tools, `ghcid` is intended to be _incredibly simple_. In particular, it doesn't integrate with any editors, doesn't depend on GHC the library and doesn't start web servers. 
ghcid.cabal view
@@ -1,7 +1,7 @@ cabal-version:      >= 1.10 build-type:         Simple name:               ghcid-version:            0.3.2+version:            0.3.3 license:            BSD3 license-file:       LICENSE category:           Development@@ -30,6 +30,7 @@         filepath,         time,         directory,+        containers,         extra >= 0.4,         process >= 1.1,         cmdargs >= 0.10@@ -52,12 +53,12 @@       base == 4.*,       filepath,       time,+      containers,       directory,       extra >= 0.4,       process >= 1.1,-      cmdargs >= 0.10-  if !os(windows)-    build-depends: terminal-size >= 0.2.1+      cmdargs >= 0.10,+      terminal-size >= 0.3   other-modules:                       Language.Haskell.Ghcid.Types,                    Language.Haskell.Ghcid.Parser,@@ -74,6 +75,7 @@     filepath,     time,     directory,+    containers,     process,     extra >= 0.4,     cmdargs,
src/Ghcid.hs view
@@ -9,7 +9,9 @@ import Data.List.Extra import Data.Maybe import Data.Time.Clock+import Data.Tuple.Extra import Data.Version+import qualified System.Console.Terminal.Size as Term import System.Console.CmdArgs import System.Directory import System.IO@@ -48,7 +50,7 @@     height <- return $ case (width, height) of         (Just w, Just h) -> return (w,h)         _ -> do-            term <- terminalSize+            term <- fmap (fmap $ Term.width &&& Term.height) Term.size             let f user def sel = fromMaybe (maybe def sel term) user             -- if we write to the end of the window then it wraps automatically             -- so putStrLn width 'x' uses up two lines
src/Language/Haskell/Ghcid/Parser.hs view
@@ -9,20 +9,22 @@  import System.FilePath import Data.Char-import Data.List+import Data.List.Extra  import Language.Haskell.Ghcid.Types+import Language.Haskell.Ghcid.Util + -- | Parse messages from show modules command parseShowModules :: [String] -> [(String, FilePath)] parseShowModules xs =-    [ (takeWhile (not . isSpace) $ dropWhile isSpace a, takeWhile (/= ',') b)+    [ (takeWhile (not . isSpace) $ trimStart a, takeWhile (/= ',') b)     | x <- xs, (a,'(':' ':b) <- [break (== '(') x]]  -- | Parse messages given on reload -- nub, because cabal repl sometimes does two reloads at the start parseLoad :: [String] -> [Load]-parseLoad  = nub . parseLoad'            +parseLoad  = ordNub . parseLoad'              -- | Parse messages given on reload parseLoad' :: [String] -> [Load]@@ -36,8 +38,11 @@     , (pos,rest2) <- span (\c -> c == ':' || isDigit c) rest     , [p1,p2] <- map read $ words $ map (\c -> if c == ':' then ' ' else c) pos      , (msg,las) <- span (isPrefixOf " ") xs-    , rest3 <- dropWhile isSpace rest2+    , rest3 <- trimStart rest2     , sev <- if "Warning:" `isPrefixOf` rest3 then Warning else Error     = Message sev file (p1,p2) (x:msg) : parseLoad las+parseLoad' (x:xs)+    | Just file <- stripPrefix "<no location info>: can't find file: " x+    = Message Error file (0,0) [file ++ ": Can't find file"] : parseLoad xs parseLoad' (_:xs) = parseLoad xs parseLoad' [] = []
src/Language/Haskell/Ghcid/Terminal.hs view
@@ -1,64 +1,24 @@ {-# LANGUAGE CPP #-} module Language.Haskell.Ghcid.Terminal(-    terminalSize, terminalTopmost+    terminalTopmost     ) where -#if !defined(mingw32_HOST_OS)-import qualified System.Console.Terminal.Size as Terminal-import System.IO (stdout)-import Data.Tuple.Extra-#endif- #if defined(mingw32_HOST_OS)-import Control.Monad import Data.Word import Data.Bits import Foreign.Ptr-import Foreign.Storable-import Foreign.Marshal.Alloc -type HANDLE = Ptr () type HWND = Ptr () -data CONSOLE_SCREEN_BUFFER_INFO-sizeCONSOLE_SCREEN_BUFFER_INFO = 22-posCONSOLE_SCREEN_BUFFER_INFO_srWindow = 10 -- 4 x Word16 Left,Top,Right,Bottom- c_SWP_NOSIZE = 1 :: Word32 c_SWP_NOMOVE = 2 :: Word32 c_HWND_TOPMOST = -1 :: Int-c_STD_OUTPUT_HANDLE = -11 :: Word32  foreign import stdcall unsafe "windows.h GetConsoleWindow"     c_GetConsoleWindow :: IO HWND  foreign import stdcall unsafe "windows.h SetWindowPos"     c_SetWindowPos :: HWND -> Int -> Int -> Int -> Int -> Int -> Word32 -> IO Bool--foreign import stdcall unsafe "windows.h GetConsoleScreenBufferInfo"-    c_GetConsoleScreenBufferInfo :: HANDLE -> Ptr CONSOLE_SCREEN_BUFFER_INFO -> IO Bool--foreign import stdcall unsafe "windows.h GetStdHandle"-    c_GetStdHandle :: Word32 -> IO HANDLE-#endif----- | Figure out the size of the current terminal, @(width,height)@, or return 'Nothing'.-terminalSize :: IO (Maybe (Int, Int))-#if defined(mingw32_HOST_OS)-terminalSize = do-    hdl <- c_GetStdHandle c_STD_OUTPUT_HANDLE-    allocaBytes sizeCONSOLE_SCREEN_BUFFER_INFO $ \p -> do-        b <- c_GetConsoleScreenBufferInfo hdl p-        if not b then return Nothing else do-            [left,top,right,bottom] <- forM [0..3] $ \i -> do-                v <- peekByteOff p ((i*2) + posCONSOLE_SCREEN_BUFFER_INFO_srWindow)-                return $ fromIntegral (v :: Word16)-            return $ Just (1+right-left, 1+bottom-top)-#else-terminalSize = do-    s <- Terminal.hSize stdout-    return $ fmap (Terminal.width &&& Terminal.height) s #endif  
src/Language/Haskell/Ghcid/Types.hs view
@@ -29,7 +29,7 @@         ,loadFilePos :: (Int,Int)         ,loadMessage :: [String]         }-      deriving (Show,Eq)+      deriving (Show, Eq, Ord)        -- | Is a Load a message with severity? isMessage :: Load -> Bool
src/Language/Haskell/Ghcid/Util.hs view
@@ -6,12 +6,14 @@   , outStrLn   , outStr   , allGoodMessage+  , ordNub   ) where  import Control.Concurrent.Extra import System.IO.Unsafe import Data.List.Extra import Data.Char+import qualified Data.Set as Set   -- | Drop a prefix from a list, no matter how many times that prefix is present@@ -43,3 +45,14 @@     if null b then (a, []) else         let (a1,a2) = breakEnd isSpace a in         if length a2 <= gap then (a1, a2 ++ b) else (a, dropWhile isSpace b)+++-- ordNub function from <https://github.com/nh2/haskell-ordnub>+ordNub :: (Ord a) => [a] -> [a]+ordNub l = go Set.empty l+  where+    go _ [] = []+    go s (x:xs) =+      if x `Set.member` s+        then go s xs+        else x : go (Set.insert x s) xs