57fd6b8a1b
The cabal file and stackage resolver says that time is `>= 1.5.0` anyway.
46 lines
1.4 KiB
Haskell
46 lines
1.4 KiB
Haskell
-- | A quick and dirty way to echo a printf-style debugging message to
|
|
-- a file from anywhere.
|
|
--
|
|
-- To use from Emacs, run `tail -f /tmp/echo` with M-x grep. You can
|
|
-- rename the buffer to *echo* or something. The grep-mode buffer has
|
|
-- handy up/down keybindings that will open the file location for you
|
|
-- and it supports results coming in live. So it's a perfect way to
|
|
-- browse printf-style debugging logs.
|
|
|
|
module Echo where
|
|
|
|
import Control.Concurrent.MVar
|
|
import Control.Monad.Trans (MonadIO(..))
|
|
import Data.Time
|
|
import Language.Haskell.TH
|
|
import Language.Haskell.TH.Lift
|
|
import Prelude
|
|
import System.IO.Unsafe
|
|
|
|
-- | God forgive me for my sins.
|
|
echoV :: MVar ()
|
|
echoV = unsafePerformIO (newMVar ())
|
|
{-# NOINLINE echoV #-}
|
|
|
|
-- | Echo something.
|
|
echo :: Q Exp
|
|
echo = [|write $(location >>= liftLoc) |]
|
|
|
|
-- | Grab the filename and line/col.
|
|
liftLoc :: Loc -> Q Exp
|
|
liftLoc (Loc filename _pkg _mod (line, _) _) =
|
|
[|($(lift filename)
|
|
,$(lift line))|]
|
|
|
|
-- | Thread-safely (probably) write to the log.
|
|
write :: (MonadIO m) => (FilePath,Int) -> String -> m ()
|
|
write (file,line) it =
|
|
liftIO (withMVar echoV (const (loggit)))
|
|
where loggit =
|
|
do now <- getCurrentTime
|
|
appendFile "/tmp/echo" (loc ++ ": " ++ fmt now ++ " " ++ it ++ "\n")
|
|
loc = file ++ ":" ++ show line
|
|
fmt = formatTime defaultTimeLocale "%T%Q"
|
|
|
|
clear :: IO ()
|
|
clear = writeFile "/tmp/echo" ""
|