summaryrefslogtreecommitdiffhomepage
path: root/doc/write-your-own-plugin.org
blob: a877ad820e0481b5d13339ba82a4554d436f4954 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#+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]].

*** 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.

    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!