1----------------------------------------------------------------------------- 2-- | 3-- Module : Plugins.HandleReader 4-- Copyright : (c) Pavan Rikhi 5-- License : BSD-style (see LICENSE) 6-- 7-- Maintainer : Pavan Rikhi <pavan.rikhi@gmail.com> 8-- Stability : unstable 9-- Portability : portable 10-- 11-- A plugin for reading from 'Handle's 12-- 13----------------------------------------------------------------------------- 14 15module Xmobar.Plugins.HandleReader 16 ( HandleReader(..) 17 ) 18where 19 20import System.IO ( Handle 21 , hIsEOF 22 , hGetLine 23 ) 24 25import Xmobar.Run.Exec ( Exec(..) ) 26 27 28-- | A HandleReader displays any text received from a Handle. 29-- 30-- This is only useful if you are running @xmobar@ from other Haskell code. 31-- You can create a pair of @(read, write)@ 'Handle's using 32-- 'System.Process.createPipe'. Pass the @read@ 'Handle' to HandleReader 33-- and write your desired output to the @write@ 'Handle'. 34-- 35-- @ 36-- (readHandle, writeHandle) <- 'System.Process.createPipe' 37-- xmobarProcess <- 'System.Posix.Process.forkProcess' $ 'Xmobar.xmobar' myConfig 38-- { commands = 39-- 'Xmobar.Run' ('HandleReader' readHandle "handle") : 'Xmobar.commands' myConfig 40-- } 41-- 'System.IO.hPutStr' writeHandle "Hello World" 42-- @ 43data HandleReader 44 = HandleReader 45 Handle 46 -- ^ The Handle to read from. 47 String 48 -- ^ Alias for the HandleReader 49 deriving (Show) 50 51-- | WARNING: This Read instance will throw an exception if used! It is 52-- only implemented because it is required to use HandleReader with 53-- 'Xmobar.Run' in 'Xmobar.commands'. 54instance Read HandleReader where 55 -- | Throws an 'error'! 56 readsPrec = error "HandleReader: Read instance is stub" 57 58-- | Asynchronously read from the 'Handle'. 59instance Exec HandleReader where 60 -- | Read from the 'Handle' until it is closed. 61 start (HandleReader handle _) cb = 62 untilM (hIsEOF handle) $ hGetLine handle >>= cb 63 -- | Use the 2nd argument to HandleReader as its alias. 64 alias (HandleReader _ a) = a 65 66-- Loop the action until predicateM returns True. 67untilM :: Monad m => m Bool -> m () -> m () 68untilM predicateM action = do 69 predicate <- predicateM 70 if predicate then return () else action >> untilM predicateM action 71