diff options
Diffstat (limited to 'src/lib/Xmobar/Run')
| -rw-r--r-- | src/lib/Xmobar/Run/Commands.hs | 72 | ||||
| -rw-r--r-- | src/lib/Xmobar/Run/Runnable.hs | 60 | ||||
| -rw-r--r-- | src/lib/Xmobar/Run/Runnable.hs-boot | 8 | ||||
| -rw-r--r-- | src/lib/Xmobar/Run/Template.hs | 65 | ||||
| -rw-r--r-- | src/lib/Xmobar/Run/Types.hs | 65 | 
5 files changed, 270 insertions, 0 deletions
| diff --git a/src/lib/Xmobar/Run/Commands.hs b/src/lib/Xmobar/Run/Commands.hs new file mode 100644 index 0000000..198edee --- /dev/null +++ b/src/lib/Xmobar/Run/Commands.hs @@ -0,0 +1,72 @@ +----------------------------------------------------------------------------- +-- | +-- Module      :  Xmobar.Commands +-- Copyright   :  (c) Andrea Rossato +-- License     :  BSD-style (see LICENSE) +-- +-- Maintainer  :  Jose A. Ortega Ruiz <jao@gnu.org> +-- Stability   :  unstable +-- Portability :  unportable +-- +-- The 'Exec' class and the 'Command' data type. +-- +-- The 'Exec' class rappresents the executable types, whose constructors may +-- appear in the 'Config.commands' field of the 'Config.Config' data type. +-- +-- The 'Command' data type is for OS commands to be run by xmobar +-- +----------------------------------------------------------------------------- + +module Xmobar.Run.Commands (Command (..), Exec (..)) where + +import Prelude +import Control.Exception (handle, SomeException(..)) +import Data.Char +import System.Process +import System.Exit +import System.IO (hClose) + +import Xmobar.System.Signal +import Xmobar.Utils (hGetLineSafe, tenthSeconds) + +class Show e => Exec e where +    alias   :: e -> String +    alias   e    = takeWhile (not . isSpace) $ show e +    rate    :: e -> Int +    rate    _    = 10 +    run     :: e -> IO String +    run     _    = return "" +    start   :: e -> (String -> IO ()) -> IO () +    start   e cb = go +        where go = run e >>= cb >> tenthSeconds (rate e) >> go +    trigger :: e -> (Maybe SignalType -> IO ()) -> IO () +    trigger _ sh  = sh Nothing + +data Command = Com Program Args Alias Rate +             | ComX Program Args String Alias Rate +               deriving (Show,Read,Eq) + +type Args    = [String] +type Program = String +type Alias   = String +type Rate    = Int + +instance Exec Command where +    alias (ComX p _ _ a _) = +      if p /= "" then (if a == "" then p else a) else "" +    alias (Com p a al r) = alias (ComX p a "" al r) +    start (Com p as al r) cb = +      start (ComX p as ("Could not execute command " ++ p) al r) cb +    start (ComX prog args msg _ r) cb = if r > 0 then go else exec +        where go = exec >> tenthSeconds r >> go +              exec = do +                (i,o,e,p) <- runInteractiveProcess prog args Nothing Nothing +                exit <- waitForProcess p +                let closeHandles = hClose o >> hClose i >> hClose e +                    getL = handle (\(SomeException _) -> return "") +                                  (hGetLineSafe o) +                case exit of +                  ExitSuccess -> do str <- getL +                                    closeHandles +                                    cb str +                  _ -> closeHandles >> cb msg diff --git a/src/lib/Xmobar/Run/Runnable.hs b/src/lib/Xmobar/Run/Runnable.hs new file mode 100644 index 0000000..962166e --- /dev/null +++ b/src/lib/Xmobar/Run/Runnable.hs @@ -0,0 +1,60 @@ +{-# LANGUAGE ExistentialQuantification, MultiParamTypeClasses, FlexibleContexts, FlexibleInstances #-} +----------------------------------------------------------------------------- +-- | +-- Module      :  Xmobar.Runnable +-- Copyright   :  (c) Andrea Rossato +-- License     :  BSD-style (see LICENSE) +-- +-- Maintainer  :  Jose A. Ortega Ruiz <jao@gnu.org> +-- Stability   :  unstable +-- Portability :  unportable +-- +-- The existential type to store the list of commands to be executed. +-- I must thank Claus Reinke for the help in understanding the mysteries of +-- reading existential types. The Read instance of Runnable must be credited to +-- him. +-- +-- See here: +-- http:\/\/www.haskell.org\/pipermail\/haskell-cafe\/2007-July\/028227.html +-- +----------------------------------------------------------------------------- + +module Xmobar.Run.Runnable where + +import Control.Monad +import Text.Read +import Xmobar.Run.Types (runnableTypes) +import Xmobar.Run.Commands + +data Runnable = forall r . (Exec r, Read r, Show r) => Run r + +instance Exec Runnable where +     start   (Run a) = start   a +     alias   (Run a) = alias   a +     trigger (Run a) = trigger a + +instance Show Runnable where +    show (Run x) = show x + +instance Read Runnable where +    readPrec = readRunnable + +class ReadAsAnyOf ts ex where +    -- | Reads an existential type as any of hidden types ts +    readAsAnyOf :: ts -> ReadPrec ex + +instance ReadAsAnyOf () ex where +    readAsAnyOf ~() = mzero + +instance (Read t, Exec t, ReadAsAnyOf ts Runnable) => ReadAsAnyOf (t,ts) Runnable where +    readAsAnyOf ~(t,ts) = r t `mplus` readAsAnyOf ts +              where r ty = do { m <- readPrec; return (Run (m `asTypeOf` ty)) } + +-- | The 'Prelude.Read' parser for the 'Runnable' existential type. It +-- needs an 'Prelude.undefined' with a type signature containing the +-- list of all possible types hidden within 'Runnable'. See 'Config.runnableTypes'. +-- Each hidden type must have a 'Prelude.Read' instance. +readRunnable :: ReadPrec Runnable +readRunnable = prec 10 $ do +                 Ident "Run" <- lexP +                 parens $ readAsAnyOf runnableTypes diff --git a/src/lib/Xmobar/Run/Runnable.hs-boot b/src/lib/Xmobar/Run/Runnable.hs-boot new file mode 100644 index 0000000..f272d81 --- /dev/null +++ b/src/lib/Xmobar/Run/Runnable.hs-boot @@ -0,0 +1,8 @@ +{-# LANGUAGE ExistentialQuantification  #-} +module Xmobar.Run.Runnable where +import Xmobar.Run.Commands + +data Runnable = forall r . (Exec r,Read r,Show r) => Run r + +instance Read Runnable +instance Exec Runnable diff --git a/src/lib/Xmobar/Run/Template.hs b/src/lib/Xmobar/Run/Template.hs new file mode 100644 index 0000000..5bada89 --- /dev/null +++ b/src/lib/Xmobar/Run/Template.hs @@ -0,0 +1,65 @@ +------------------------------------------------------------------------------ +-- | +-- Module: Xmobar.Template +-- Copyright: (c) 2018 Jose Antonio Ortega Ruiz +-- License: BSD3-style (see LICENSE) +-- +-- Maintainer: jao@gnu.org +-- Stability: unstable +-- Portability: portable +-- Created: Sun Nov 25, 2018 05:49 +-- +-- +-- Handling the top-level output template +-- +------------------------------------------------------------------------------ + + +module Xmobar.Run.Template(parseCommands) where + +import qualified Data.Map as Map +import Text.ParserCombinators.Parsec + +import Xmobar.Run.Commands +import Xmobar.Run.Runnable +import Xmobar.Config + +-- | Parses the output template string +templateStringParser :: Config -> Parser (String,String,String) +templateStringParser c = do +  s   <- allTillSep c +  com <- templateCommandParser c +  ss  <- allTillSep c +  return (com, s, ss) + +-- | Parses the command part of the template string +templateCommandParser :: Config -> Parser String +templateCommandParser c = +  let chr = char . head . sepChar +  in  between (chr c) (chr c) (allTillSep c) + +-- | Combines the template parsers +templateParser :: Config -> Parser [(String,String,String)] +templateParser = many . templateStringParser + +-- | Actually runs the template parsers +parseCommands :: Config -> String -> IO [(Runnable,String,String)] +parseCommands c s = +    do str <- case parse (templateParser c) "" s of +                Left _  -> return [("", s, "")] +                Right x -> return x +       let cl = map alias (commands c) +           m  = Map.fromList $ zip cl (commands c) +       return $ combine c m str + +-- | Given a finite "Map" and a parsed template produce the resulting +-- output string. +combine :: Config -> Map.Map String Runnable +           -> [(String, String, String)] -> [(Runnable,String,String)] +combine _ _ [] = [] +combine c m ((ts,s,ss):xs) = (com, s, ss) : combine c m xs +    where com  = Map.findWithDefault dflt ts m +          dflt = Run $ Com ts [] [] 10 + +allTillSep :: Config -> Parser String +allTillSep = many . noneOf . sepChar diff --git a/src/lib/Xmobar/Run/Types.hs b/src/lib/Xmobar/Run/Types.hs new file mode 100644 index 0000000..4fb526a --- /dev/null +++ b/src/lib/Xmobar/Run/Types.hs @@ -0,0 +1,65 @@ +{-# LANGUAGE TypeOperators, CPP #-} +------------------------------------------------------------------------------ +-- | +-- Module: Xmobar.Run.Types +-- Copyright: (c) 2018 Jose Antonio Ortega Ruiz +-- License: BSD3-style (see LICENSE) +-- +-- Maintainer: jao@gnu.org +-- Stability: unstable +-- Portability: portable +-- Created: Sun Nov 25, 2018 07:17 +-- +-- +-- An enumeration of all runnable types +-- +------------------------------------------------------------------------------ + + +module Xmobar.Run.Types(runnableTypes) where + +import Xmobar.Run.Commands + +import {-# SOURCE #-} Xmobar.Run.Runnable() +import Xmobar.Plugins.Monitors +import Xmobar.Plugins.Date +import Xmobar.Plugins.PipeReader +import Xmobar.Plugins.BufferedPipeReader +import Xmobar.Plugins.MarqueePipeReader +import Xmobar.Plugins.CommandReader +import Xmobar.Plugins.StdinReader +import Xmobar.Plugins.XMonadLog +import Xmobar.Plugins.EWMH +import Xmobar.Plugins.Kbd +import Xmobar.Plugins.Locks + +#ifdef INOTIFY +import Xmobar.Plugins.Mail +import Xmobar.Plugins.MBox +#endif + +#ifdef DATEZONE +import Xmobar.Plugins.DateZone +#endif + +-- | An alias for tuple types that is more convenient for long lists. +type a :*: b = (a, b) +infixr :*: + +-- | This is the list of types that can be hidden inside +-- 'Runnable.Runnable', the existential type that stores all commands +-- to be executed by Xmobar. It is used by 'Runnable.readRunnable' in +-- the 'Runnable.Runnable' Read instance. To install a plugin just add +-- the plugin's type to the list of types (separated by ':*:') appearing in +-- this function's type signature. +runnableTypes :: Command :*: Monitors :*: Date :*: PipeReader :*: +                 BufferedPipeReader :*: CommandReader :*: StdinReader :*: +                 XMonadLog :*: EWMH :*: Kbd :*: Locks :*: +#ifdef INOTIFY +                 Mail :*: MBox :*: +#endif +#ifdef DATEZONE +                 DateZone :*: +#endif +                 MarqueePipeReader :*: () +runnableTypes = undefined | 
