diff options
author | Pavan Rikhi <pavan.rikhi@gmail.com> | 2020-04-09 13:51:37 -0400 |
---|---|---|
committer | jao <jao@gnu.org> | 2020-04-12 01:31:51 +0100 |
commit | 80913aeed46fc607f057a77ffdd884b5db77a0bc (patch) | |
tree | b81dbe7fa9cea64d1431c13bb813e7043bc8faaa /src/Xmobar/Plugins/HandleReader.hs | |
parent | dcbbf50dd474d8ea2822a31ed2c8affad828d8d1 (diff) | |
download | xmobar-80913aeed46fc607f057a77ffdd884b5db77a0bc.tar.gz xmobar-80913aeed46fc607f057a77ffdd884b5db77a0bc.tar.bz2 |
Add a HandleReader Plugin
This adds a new `HandleReader` plugin, which displays data from a
Haskell `Handle`. This is really only useful if you are running xmobar
from within another Haskell program, but lets you avoid the mechanics of
creating a named pipe with the proper file permissions.
Instead, you can use `System.Process.createPipe` to make a pair of read
& write Handles. If you pass the read handle to HandleReader, you can
use hPutStr on the write Handle to send data to xmobar from your
application code.
Diffstat (limited to 'src/Xmobar/Plugins/HandleReader.hs')
-rw-r--r-- | src/Xmobar/Plugins/HandleReader.hs | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/Xmobar/Plugins/HandleReader.hs b/src/Xmobar/Plugins/HandleReader.hs new file mode 100644 index 0000000..e1ee6a5 --- /dev/null +++ b/src/Xmobar/Plugins/HandleReader.hs @@ -0,0 +1,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 + ) + +import Xmobar.Run.Exec ( Exec(..) ) +import Xmobar.System.Utils ( hGetLineSafe ) + + +-- | 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) $ hGetLineSafe 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 |