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