git.fiddlerwoaroof.com
src/RingReader.hs
26d4d8bf
 {-# LANGUAGE DeriveDataTypeable, RecordWildCards #-}
 
a04c414c
 module Main where
 
26d4d8bf
 import System.IO
 import System.Process
f4ef9e75
 {-import System.Environment-}
26d4d8bf
 import System.Console.CmdArgs
a04c414c
 import System.Exit
 
26d4d8bf
 import Control.Concurrent
 
 import qualified Control.Exception as Exception
 import Control.Monad
 import Control.Monad.ST
 import Data.STRef
 
 import qualified UI.HSCurses.Curses as HSCurses
 import qualified UI.HSCurses.CursesHelper as HSCursesHelper
 
f4ef9e75
 mvWAddStr2 :: HSCurses.Window -> Int -> Int -> String -> IO ()
26d4d8bf
 mvWAddStr2 w y x s = do
7f445690
   (rows, cols) <- HSCurses.scrSize
   when ((y >= 0) && (x >= 0) && (x < cols) && (y < rows)) $
f4ef9e75
       let space = cols - x
7f445690
           s2 = take space s
        in
        HSCurses.mvWAddStr w y x s2
26d4d8bf
 
8c1bc8f4
 -- This is currently a stub
26d4d8bf
 dispatch :: HSCurses.Key -> IO ()
f4ef9e75
 dispatch _ = return ()
 
8c1bc8f4
 (--->) :: Monad m => (a -> m b) -> (a -> m c) -> a -> m c
2f349ba4
 (--->) = liftM2 (>>)
 
 passTo :: a -> (a -> b) -> b
 passTo = flip ($)
 
 
f4ef9e75
 mainLoop :: Int -> Handle -> Int -> Bool -> IO ()
2f349ba4
 mainLoop lim filein cols infinitep = stToIO (newSTRef 1) >>= loop
f4ef9e75
   where
2f349ba4
     loop = discardResult . forever . wrapCode step HSCurses.refresh . stToIO . initialize
f4ef9e75
 
8c1bc8f4
     initialize n = readSTRef n >>= (incSTRef n ---> addSTRefToTuple n)
f4ef9e75
 
2f349ba4
     step (x,nextX) = discardResult $ do
bca0578e
       let handleInputp = filein /= stdin && not infinitep && ( nextX `mod` lim == 0)
2f349ba4
       eofp <- atEnd
       if eofp then threadDelay 100
               else do
                 line <- hGetLine filein
                 x `passTo` (clearLine ---> showLine line ---> showDivider)
                 handleInput handleInputp
f4ef9e75
 
2f349ba4
     clearLine x = moveAndAddString (getLinePos x) 0 $ replicate (cols+1) ' ' -- overwrite line
     showLine  line x = moveAndAddString (getLinePos x) 0 $ show x ++ (' ':line)   -- show new line
     showDivider x = moveAndAddString ( getLinePos (x+1) ) 0 div
f4ef9e75
 
2f349ba4
     addSTRefToTuple n = flippedLiftM (readSTRef n) . (,)
     atEnd = hIsEOF filein
     discardResult = when True
     div = marker ++ replicate (cols - length marker + 1) '-'
     flippedLiftM = flip liftM
     getLinePos = subtract 1 . (`mod` lim)
     handleInput handleInputp = when handleInputp $ HSCurses.getCh >>= dispatch
     incSTRef n = writeSTRef n . (+ 1)
     marker = "--- break ---"
     moveAndAddString = mvWAddStr2 HSCurses.stdScr
     wrapCode run finalize init = (init >>= run) >> finalize
f4ef9e75
 
 allocate :: IO ()
26d4d8bf
 allocate = do
    HSCurses.initCurses
    hasColors <- HSCurses.hasColors
f4ef9e75
    when hasColors $ do
      HSCurses.startColor
      HSCurses.initPair
         (HSCurses.Pair 1)
         HSCursesHelper.black
         HSCursesHelper.white
 
 
 deallocate :: IO ()
 deallocate = HSCurses.endWin
 
bca0578e
 startTask :: String -> [FilePath] -> IO (Handle,Handle)
 startTask enc run = do
f4ef9e75
    let (runprog:myArgs) = run
    (_, Just hout, Just herr, _) <-
       createProcess (proc runprog myArgs) {
          std_out=CreatePipe,
          std_err=CreatePipe
26d4d8bf
       }
 
    -- enc <- mkTextEncoding "ISO-8859-1"
f4ef9e75
    encoding <- mkTextEncoding enc
    hSetEncoding hout encoding
    hSetEncoding herr encoding
bca0578e
    return (hout,herr)
 
 getStream :: String -> String -> [FilePath] -> IO Handle
 getStream stream enc run = do
   (hout,herr) <- startTask enc run
   return $ case stream of
     "stdout" -> hout
     _        -> herr
26d4d8bf
 
bca0578e
 
 work :: String -> [FilePath] -> Bool -> String -> IO ()
 work enc run infinitep stream = do
    (rows, cols) <- HSCurses.scrSize
    stream <- case run of
                [] -> return stdin
                _ -> getStream stream enc run
    mainLoop rows stream cols infinitep
26d4d8bf
    return ()
 
 
 data MyOptions = MyOptions {
    infinite :: Bool,
    run :: [String],
f4ef9e75
    encoding :: String,
    stream :: String
26d4d8bf
 } deriving (Data, Typeable, Show, Eq)
 
 myProgOpts :: MyOptions
 myProgOpts = MyOptions {
    infinite = def &= name "i",
    encoding = "UTF-8" &= name "e",
f4ef9e75
    stream = "stdout" &= name "s",
26d4d8bf
    run = def &= args
 }
 
 getOpts :: IO MyOptions
f4ef9e75
 getOpts = cmdArgs myProgOpts
26d4d8bf
 
f4ef9e75
 main :: IO ()
26d4d8bf
 main = do
    opts <- getOpts
    optionHandler opts
 
 optionHandler :: MyOptions -> IO ()
f4ef9e75
 optionHandler opts@MyOptions{..} = Exception.bracket_ allocate deallocate (work encoding run infinite stream)