diff options
| -rw-r--r-- | doc/write-your-own-plugin.org | 132 | ||||
| -rw-r--r-- | examples/xmobar.hs | 2 | ||||
| -rw-r--r-- | readme.org | 50 | 
3 files changed, 115 insertions, 69 deletions
| diff --git a/doc/write-your-own-plugin.org b/doc/write-your-own-plugin.org index a877ad8..fb1ca85 100644 --- a/doc/write-your-own-plugin.org +++ b/doc/write-your-own-plugin.org @@ -1,75 +1,73 @@  #+title: Writing your own plugin -Writing a plugin for xmobar is very simple! - -First, you need to create a data type with at least one constructor. -Next you must declare this data type an instance of the =Exec= class, by -defining the one needed method (alternatively =start= or =run=) and 3 -optional ones (=alias=, =rate=, and =trigger=): - -#+begin_src haskell -  start   :: e -> (String -> IO ()) -> IO () -  run     :: e -> IO String -  rate    :: e -> Int -  alias   :: e -> String -  trigger :: e -> (Maybe SignalType -> IO ()) -> IO () -#+end_src - -=start= must receive a callback to be used to display the =String= -produced by the plugin. This method can be used for plugins that need to -perform asynchronous actions. See =src/Xmobar/Plugins/PipeReader.hs= for -an example. - -=run= can be used for simpler plugins. If you define only =run= the -plugin will be run every second. To overwrite this default you just need -to implement =rate=, which must return the number of tenth of seconds -between every successive runs. See [[../examples/xmobar.hs][examples/xmobar.hs]] for an example of -a plugin that runs just once, and [[../src/Xmobar/Plugins/Date.hs][src/Xmobar/Plugins/Date.hs]] for one -that implements =rate=. - -Notice that Date could be implemented as: - -#+begin_src haskell -  instance Exec Date where -      alias (Date _ a _) = a -      start (Date f _ r) = date f r - -  date :: String -> Int -> (String -> IO ()) -> IO () -  date format r callback = do go -      where go = do -              t <- toCalendarTime =<< getClockTime -              callback $ formatCalendarTime defaultTimeLocale format t -              tenthSeconds r >> go -#+end_src - -Modulo some technicalities like refreshing the time-zone in a clever -way, this implementation is equivalent to the one you can read in -=Plugins/Date.hs=. - -=alias= is the name to be used in the output template. Default alias -will be the data type constructor. - -After that your type constructor can be used as an argument for the -Runnable type constructor =Run= in the =commands= list of the -configuration options. - -If your plugin only implements =alias= and =start=, then it is advisable -to put it into the =Xmobar/Plugins/Monitors= directory and use one of -the many =run*= functions in [[../src/Xmobar/Plugins/Monitors/Common/Run.hs][Xmobar.Plugins.Monitors.Run]] in order to -define =start=. The =Exec= instance should then live in -[[../src/Xmobar/Plugins/Monitors.hs][Xmobar.Plugins.Monitors]]. +*** Writing a plugin +    Writing a plugin for xmobar is very simple! + +    First, you need to create a data type with at least one constructor.  Next +    you must declare this data type an instance of the =Exec= class, by defining +    the one needed method (alternatively =start= or =run=) and 3 optional ones +    (=alias=, =rate=, and =trigger=): + +    #+begin_src haskell +      start   :: e -> (String -> IO ()) -> IO () +      run     :: e -> IO String +      rate    :: e -> Int +      alias   :: e -> String +      trigger :: e -> (Maybe SignalType -> IO ()) -> IO () +    #+end_src + +    =start= must receive a callback to be used to display the =String= produced by +    the plugin. This method can be used for plugins that need to perform +    asynchronous actions. See =src/Xmobar/Plugins/PipeReader.hs= for an example. + +    =run= can be used for simpler plugins. If you define only =run= the plugin +    will be run every second. To overwrite this default you just need to +    implement =rate=, which must return the number of tenth of seconds between +    every successive runs. See [[../examples/xmobar.hs][examples/xmobar.hs]] for an example of a plugin +    that runs just once, and [[../src/Xmobar/Plugins/Date.hs][src/Xmobar/Plugins/Date.hs]] for one that +    implements =rate=. + +    Notice that Date could be implemented as: + +    #+begin_src haskell +      instance Exec Date where +          alias (Date _ a _) = a +          start (Date f _ r) = date f r + +      date :: String -> Int -> (String -> IO ()) -> IO () +      date format r callback = do go +          where go = do +                  t <- toCalendarTime =<< getClockTime +                  callback $ formatCalendarTime defaultTimeLocale format t +                  tenthSeconds r >> go +    #+end_src + +    Modulo some technicalities like refreshing the time-zone in a clever way, +    this implementation is equivalent to the one you can read in +    =Plugins/Date.hs=. + +    =alias= is the name to be used in the output template. Default alias will be +    the data type constructor. + +    After that your type constructor can be used as an argument for the +    Runnable type constructor =Run= in the =commands= list of the configuration +    options. + +    If your plugin only implements =alias= and =start=, then it is advisable to +    put it into the =Xmobar/Plugins/Monitors= directory and use one of the many +    =run*= functions in [[../src/Xmobar/Plugins/Monitors/Common/Run.hs][Xmobar.Plugins.Monitors.Run]] in order to define +    =start=. The =Exec= instance should then live in [[../src/Xmobar/Plugins/Monitors.hs][Xmobar.Plugins.Monitors]].  *** Using a Plugin -    To use your new plugin, you need to use a pure Haskell -    configuration for xmobar, and load your definitions there. You can -    see an example in [[../examples/xmobar.hs][examples/xmobar.hs]] showing you how to write a -    Haskell configuration that uses a new plugin, all in one file. +    To use your new plugin, you need to use a pure Haskell configuration for +    xmobar (as explained [[../readme.org#xmobar-in-haskell][here)]] and load your definitions in your =xmobar.hs= +    file. You can see an example in [[../examples/xmobar.hs][examples/xmobar.hs]] showing you how to +    write a Haskell configuration that uses a new plugin, all in one file. -    When xmobar runs with the full path to that Haskell file as its -    argument (or if you put it in =~/.config/xmobar/xmobar.hs=), and -    with the xmobar library installed (e.g., with =cabal install --lib -    xmobar=), the Haskell code will be compiled as needed, and the new -    executable spawned for you. +    When xmobar runs with the full path to that Haskell file as its argument +    (or if you put it in =~/.config/xmobar/xmobar.hs=), and with the xmobar +    library installed (e.g., with =cabal install --lib xmobar=), the Haskell +    code will be compiled as needed, and the new executable spawned for you.      That's it! diff --git a/examples/xmobar.hs b/examples/xmobar.hs index 791d3af..f8434fe 100644 --- a/examples/xmobar.hs +++ b/examples/xmobar.hs @@ -74,4 +74,4 @@ config = defaultConfig {  }  main :: IO () -main = xmobar config +main = configFromArgs config >>= xmobar @@ -89,7 +89,7 @@ channel, ~#xmobar~, at [[ircs://irc.libera.chat][Libera]].      See [[file:doc/compiling.org][compiling]].  * Running xmobar - +*** Running xmobar with a configuration file    You can run xmobar with:    #+begin_src shell @@ -106,6 +106,54 @@ channel, ~#xmobar~, at [[ircs://irc.libera.chat][Libera]].    =$XDG_CONFIG_HOME/xmobar/xmobarrc= (defaulting to    =~/.config/xmobar/xmobarrc=), or =~/.xmobarrc=. +*** Writing your own xmobar in Haskell +    :PROPERTIES: +    :CUSTOM_ID: xmobar-in-haskell +    :END: + +    It is possible to install xmobar as a library and use it to write your own +    xmobar using Haskell instead of using a configuration file.  (This is very +    similar to how [[http://xmonad.org][xmonad]] works.) + +    Make sure that ~ghc~ will be able to locate the xmobar library, e.g. with + +    #+begin_src shell +      cabal install --lib xmobar +    #+end_src + +    and then write your Haskell configuration and main function using the +    functions and types exported in the library, which closely resemble those +    used in configuration files.  Here's a small example: + +    #+begin_src haskell +      import Xmobar + +      config :: Config +      config = +        defaultConfig +          { font = "xft:Terminus-8", +            allDesktops = True, +            alpha = 200, +            commands = +              [ Run XMonadLog, +                Run $ Memory ["t", "Mem: <usedratio>%"] 10, +                Run $ Kbd [], +                Run $ Date "%a %_d %b %Y <fc=#ee9a00>%H:%M:%S</fc>" "date" 10 +              ], +            template = "%XMonadLog% }{ %kbd% | %date% | %memory%", +            alignSep = "}{" +          } + +      main :: IO () +      main = xmobar config +    #+end_src + +    You can then for instance run =ghc --make xmobar.hs= to create a new xmobar +    executable running exactly the monitors defined above.  Or put your +    =xmobar.hs= program in =~/.config/xmobar/xmobar.hs= and, when running the +    system-wide xmobar, it will notice that you have your own implementation +    and (re)compile and run it as needed.  See also this [[./examples/xmobar.hs][extended example]]. +  *** Running xmobar in text mode      By default, xmobar will run as an X11 application, in a docked | 
