summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorPavan Rikhi <pavan.rikhi@gmail.com>2020-04-09 13:51:37 -0400
committerjao <jao@gnu.org>2020-04-12 01:31:51 +0100
commit80913aeed46fc607f057a77ffdd884b5db77a0bc (patch)
treeb81dbe7fa9cea64d1431c13bb813e7043bc8faaa
parentdcbbf50dd474d8ea2822a31ed2c8affad828d8d1 (diff)
downloadxmobar-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.
-rw-r--r--changelog.md7
-rw-r--r--readme.md17
-rw-r--r--src/Xmobar.hs2
-rw-r--r--src/Xmobar/Plugins/HandleReader.hs70
-rw-r--r--xmobar.cabal1
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_
diff --git a/readme.md b/readme.md
index 2a57860..aab8894 100644
--- a/readme.md
+++ b/readme.md
@@ -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,