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 +3/−0
- README.md +1/−1
- ghcid.cabal +6/−4
- src/Ghcid.hs +3/−1
- src/Language/Haskell/Ghcid/Parser.hs +9/−4
- src/Language/Haskell/Ghcid/Terminal.hs +1/−41
- src/Language/Haskell/Ghcid/Types.hs +1/−1
- src/Language/Haskell/Ghcid/Util.hs +13/−0
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 [](http://hackage.haskell.org/package/ghcid) [](https://travis-ci.org/ndmitchell/ghcid)+# ghcid [](https://hackage.haskell.org/package/ghcid) [](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