diff options
| -rw-r--r-- | changelog.md | 7 | ||||
| -rw-r--r-- | readme.md | 17 | ||||
| -rw-r--r-- | src/Xmobar.hs | 2 | ||||
| -rw-r--r-- | src/Xmobar/Plugins/HandleReader.hs | 70 | ||||
| -rw-r--r-- | xmobar.cabal | 1 | 
5 files changed, 97 insertions, 0 deletions
| diff --git a/changelog.md b/changelog.md index a88e1ba..e147c22 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,10 @@ +## Version 0.34 (Unreleased) + +_New features_ + +  - New plugin `HandleReader` for reading data from a Haskell `Handle`. This is +    useful if you are running xmobar from within a Haskell program. +  ## Version 0.33 (February, 2020)  _New features_ @@ -1613,6 +1613,23 @@ will display "N/A" if for some reason the `date` invocation fails.            logHook = dynamicLogString myPP >>= xmonadPropLog          } +### `HandleReader Handle Alias` + +- Display data from a Haskell `Handle` +- This plugin is only useful if you are running xmobar from another Haskell +  program like XMonad. +- You can use `System.Process.createPipe` to create a pair of `read` & `write` +  Handles. Pass the `read` Handle to HandleReader and write your output to the +  `write` Handle: + +        (readHandle, writeHandle) <- createPipe +        xmobarProcess <- forkProcess $ xmobar myConfig +                { commands = +                    Run (HandleReader readHandle "handle") : commands myConfig +                } +        hPutStr writeHandle "Hello World" + +  # Plugins  ## Writing a Plugin diff --git a/src/Xmobar.hs b/src/Xmobar.hs index 491aa8d..d2e4126 100644 --- a/src/Xmobar.hs +++ b/src/Xmobar.hs @@ -32,6 +32,7 @@ module Xmobar (xmobar                , module Xmobar.Plugins.DateZone  #endif                , module Xmobar.Plugins.EWMH +              , module Xmobar.Plugins.HandleReader                , module Xmobar.Plugins.Kbd                , module Xmobar.Plugins.Locks  #ifdef INOTIFY @@ -57,6 +58,7 @@ import Xmobar.Plugins.Date  import Xmobar.Plugins.DateZone  #endif  import Xmobar.Plugins.EWMH +import Xmobar.Plugins.HandleReader  import Xmobar.Plugins.Kbd  import Xmobar.Plugins.Locks  #ifdef INOTIFY 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 diff --git a/xmobar.cabal b/xmobar.cabal index 503874d..51aedce 100644 --- a/xmobar.cabal +++ b/xmobar.cabal @@ -129,6 +129,7 @@ library                     Xmobar.Plugins.CommandReader,                     Xmobar.Plugins.Date,                     Xmobar.Plugins.EWMH, +                   Xmobar.Plugins.HandleReader,                     Xmobar.Plugins.PipeReader,                     Xmobar.Plugins.MarqueePipeReader,                     Xmobar.Plugins.StdinReader, | 
