summaryrefslogtreecommitdiffhomepage
path: root/doc/write-your-own-plugin.org
blob: fb1ca858868a3fdff4313651f2b1dab37e347f19 (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
#+title: Writing your own plugin

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

    That's it!