module Language.Haskell.Ghcid.Util(
dropPrefixRepeatedly,
chunksOfWord,
outWith, outStrLn,
allGoodMessage,
getModTime, getModTimeResolution, getShortTime
) where
import Control.Concurrent.Extra
import System.Time.Extra
import System.IO.Unsafe
import System.IO.Extra
import System.FilePath
import System.Info.Extra
import Data.Version.Extra
import Data.List.Extra
import Data.Char
import Data.Time.Clock
import Data.Time.Format
import Data.Time.LocalTime
import System.IO.Error
import System.Directory
import Control.Exception
import Control.Monad.Extra
import Control.Applicative
import Prelude
dropPrefixRepeatedly :: Eq a => [a] -> [a] -> [a]
dropPrefixRepeatedly [] s = s
dropPrefixRepeatedly pre s = maybe s (dropPrefixRepeatedly pre) $ stripPrefix pre s
lock :: Lock
lock = unsafePerformIO newLock
outWith :: IO a -> IO a
outWith = withLock lock
outStrLn :: String -> IO ()
outStrLn = outWith . putStrLn
allGoodMessage :: String
allGoodMessage = "All good"
chunksOfWord :: Int -> Int -> String -> [String]
chunksOfWord mx gap = repeatedly $ \x ->
let (a,b) = splitAt mx x in
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)
getModTime :: FilePath -> IO (Maybe UTCTime)
getModTime file = handleJust
(\e -> if isDoesNotExistError e then Just () else Nothing)
(\_ -> return Nothing)
(Just <$> getModificationTime file)
getShortTime :: IO String
getShortTime = formatTime defaultTimeLocale "%H:%M:%S" <$> getZonedTime
getModTimeResolution :: IO Seconds
getModTimeResolution = return getModTimeResolutionCache
getModTimeResolutionCache :: Seconds
getModTimeResolutionCache = unsafePerformIO $ withTempDir $ \dir -> do
let file = dir </> "calibrate.txt"
mtime <- fmap maximum $ forM [1..3] $ \i -> fmap fst $ duration $ do
writeFile file $ show i
t1 <- getModificationTime file
flip loopM 0 $ \j -> do
writeFile file $ show (i,j)
t2 <- getModificationTime file
return $ if t1 == t2 then Left $ j+1 else Right ()
mtime <- return $ if compilerVersion < makeVersion [7,8] then max mtime 1 else mtime
putStrLn $ "Longest file modification time lag was " ++ show (ceiling (mtime * 1000)) ++ "ms"
return $ mtime + min 0.1 mtime