Hello community,

here is the log from the commit of package xmobar for openSUSE:Factory checked 
in at 2019-12-27 13:59:41
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/xmobar (Old)
 and      /work/SRC/openSUSE:Factory/.xmobar.new.6675 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "xmobar"

Fri Dec 27 13:59:41 2019 rev:11 rq:759577 version:0.32

Changes:
--------
--- /work/SRC/openSUSE:Factory/xmobar/xmobar.changes    2019-08-24 
18:44:39.173767452 +0200
+++ /work/SRC/openSUSE:Factory/.xmobar.new.6675/xmobar.changes  2019-12-27 
13:59:42.872842288 +0100
@@ -1,0 +2,23 @@
+Mon Dec  9 03:02:28 UTC 2019 - psim...@suse.com
+
+- Update xmobar to version 0.32.
+  Upstream has edited the change log file since the last release in
+  a non-trivial way, i.e. they did more than just add a new entry
+  at the top. You can review the file at:
+  http://hackage.haskell.org/package/xmobar-0.32/src/changelog.md
+
+-------------------------------------------------------------------
+Fri Nov  8 16:15:22 UTC 2019 - Peter Simons <psim...@suse.com>
+
+- Drop obsolete group attributes.
+
+-------------------------------------------------------------------
+Sat Oct 12 02:01:56 UTC 2019 - psim...@suse.com
+
+- Update xmobar to version 0.31.
+  Upstream has edited the change log file since the last release in
+  a non-trivial way, i.e. they did more than just add a new entry
+  at the top. You can review the file at:
+  http://hackage.haskell.org/package/xmobar-0.31/src/changelog.md
+
+-------------------------------------------------------------------

Old:
----
  xmobar-0.30.tar.gz

New:
----
  xmobar-0.32.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ xmobar.spec ++++++
--- /var/tmp/diff_new_pack.asuNGh/_old  2019-12-27 13:59:43.280842485 +0100
+++ /var/tmp/diff_new_pack.asuNGh/_new  2019-12-27 13:59:43.284842487 +0100
@@ -19,11 +19,10 @@
 %global pkg_name xmobar
 %bcond_with tests
 Name:           %{pkg_name}
-Version:        0.30
+Version:        0.32
 Release:        0
 Summary:        A Minimalistic Text Based Status Bar
 License:        BSD-3-Clause
-Group:          System/GUI/Other
 URL:            https://hackage.haskell.org/package/%{name}
 Source0:        
https://hackage.haskell.org/package/%{name}-%{version}/%{name}-%{version}.tar.gz
 BuildRequires:  chrpath
@@ -72,14 +71,12 @@
 
 %package -n ghc-%{name}
 Summary:        Haskell %{name} library
-Group:          System/Libraries
 
 %description -n ghc-%{name}
 This package provides the Haskell %{name} shared library.
 
 %package -n ghc-%{name}-devel
 Summary:        Haskell %{name} library development files
-Group:          Development/Libraries/Haskell
 Requires:       ghc-%{name} = %{version}-%{release}
 Requires:       ghc-compiler = %{ghc_version}
 Requires:       libXpm-devel

++++++ xmobar-0.30.tar.gz -> xmobar-0.32.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmobar-0.30/changelog.md new/xmobar-0.32/changelog.md
--- old/xmobar-0.30/changelog.md        2019-08-23 03:22:33.000000000 +0200
+++ new/xmobar-0.32/changelog.md        2019-11-17 20:20:50.000000000 +0100
@@ -1,10 +1,46 @@
+## Version 0.32
+
+_New features_
+
+  - New options `--host` and `--port` for `MPD` monitor.
+  - New plugin `MailX` extending `Mail` with colors and prefix/suffix.
+  - New options `--lows`, `--mediums`, and `--highs` for `Battery`
+    to display an additional string depending on battery level (thanks
+    to *slotThe*).
+  - New options `-L` and `-H` for `Volume` to set low and high volume
+    levels, as well as `-l`, `-m`, and `-h` to display an additional
+    string depending on current volume level (thanks to *slotThe*).
+  - New option `-P` in `Battery` to add a `%` symbol to `<left>`.
+  - New option `--devices` in `DynNetwork` to select what interfaces
+    to monitor (thanks to *vindex10*).
+  - DateZone plugin now also checks TZDIR (thanks to Emmanuel Rosa).
+
+_Bug fixes_
+
+   - `Kbd` plugin: ignore "terminate" layout token (thanks to Greg
+     Steuck).
+   - Fixed compilation with GHC 8.8.x (thanks to Vanessa McHale).
+   - Avoid creating `~/.xmobar` ([issue #405]).
+
+[issue #405]: https://github.com/jaor/xmobar/issues/405
+
+## Version 0.31 (October, 2019)
+
+_New features_
+
+  - New option `--contiguous-icons` for `MultiCpu` to draw icons
+    without padding (see [issue #388]).
+  - New version of libmpd (0.9.0.10), thanks to John Tyree
+
+[issue #388]: https://github.com/jaor/xmobar/issues/388
+
 ## Version 0.30 (August, 2019)
 
 _New features_
 
   - New monitor `MultiCoreTemp`, thanks to Felix Springer.
   - `DiskIO`: Additional template variables for absolute number of
-    bytes rather than speeds (see [issue #390].
+    bytes rather than speeds (see [issue #390]).
   - `WeatherX`: An extension to the `Weather` monitor allowing the
     spefication of custom strings or icons for sky conditions.
   - The battery monitors accept the new arguments `-a` and `-A` to
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmobar-0.30/readme.md new/xmobar-0.32/readme.md
--- old/xmobar-0.30/readme.md   2019-07-24 02:32:36.000000000 +0200
+++ new/xmobar-0.32/readme.md   2019-11-17 20:20:06.000000000 +0100
@@ -198,11 +198,11 @@
   managers to feed xmobar strings with `<action>` tags mixed with un-trusted
   content (e.g. window titles).  For example, if xmobar is invoked as
 
-    ```xmobar -c "[Run UnsafeStdinReader]" -t "%UnsafeStdinReader%"```
+        xmobar -c "[Run UnsafeStdinReader]" -t "%UnsafeStdinReader%"
 
   and receives on standard input the line
 
-    ```<action=`echo test` button=1><raw=41:<action=`echo mooo` 
button=1>foo</action>/></action>```
+        <action=`echo test` button=1><raw=41:<action=`echo mooo` 
button=1>foo</action>/></action>`
 
   then it will display the text ```<action=`echo mooo` 
button=1>foo</action>```,
   which, when clicked, will cause `test` to be echoed.
@@ -799,13 +799,15 @@
 - Thresholds are expressed in Kb/s
 - Args: default monitor arguments, plus:
   - `--rx-icon-pattern`: dynamic string for reception rate in `rxipat`.
-  - `--tx-icon-pattern`: dynamic string for transmission rate in `txipat`.
+  - `--tx-icon-pattern`: dynamic string for transmission rate in `txipat`
+  - `--devices`: comma-separated list of devices to show.
 - Variables that can be used with the `-t`/`--template` argument:
   `dev`, `rx`, `tx`, `rxbar`, `rxvbar`, `rxipat`, `txbar`, `txvbar`,
   `txipat`. Reception and transmission rates (`rx` and `tx`) are displayed
   in Kbytes per second, and you can set the `-S` to "True" to make them
   displayed with units (the string "Kb/s").
 - Default template: `<dev>: <rx>KB|<tx>KB`
+- Example of usage of `--devices` option: `["--", "--devices", 
"wlp2s0,enp0s20f41"]`
 
 ### `Wireless Interface Args RefreshRate`
 
@@ -866,6 +868,8 @@
                               corresponds to nth cpu.
   - `--fallback-icon-pattern`: dynamic string used by `autoipat` and `ipat{i}` 
when no
                              `--load-icon-patterns` has been provided for 
`cpu{i}`
+  - `--contiguous-icons`: flag (no value needs to be provided) that
+                          causes the load icons to be drawn without padding.
 - Thresholds refer to percentage of CPU load
 - Variables that can be used with the `-t`/`--template` argument:
            `autototal`, `autobar`, `autovbar`, `autoipat`, `autouser`, 
`autonice`,
@@ -909,12 +913,20 @@
     percentage left in the battery is less or equal than the threshold
     given by the `-A` option.  If not present, no action is
     undertaken.
+  - `-P`: to include a percentage symbol in `left`.
   - `--on-icon-pattern`: dynamic string for current battery charge
     when AC is "on" in `leftipat`.
   - `--off-icon-pattern`: dynamic string for current battery charge
     when AC is "off" in `leftipat`.
   - `--idle-icon-pattern`: dynamic string for current battery charge
     when AC is "idle" in `leftipat`.
+  - `--lows`: string for AC "off" status and power lower than the `-L`
+    threshold (default: "")
+  - `--mediums`: string for AC "off" status and power lower than the `-H`
+    threshold (default: "")
+  - `--high`: string for AC "off" status and power higher than the `-H`
+    threshold (default: "")
+
 
 - Variables that can be used with the `-t`/`--template` argument:
            `left`, `leftbar`, `leftvbar`, `leftipat`, `timeleft`, `watts`, 
`acstatus`
@@ -1146,6 +1158,25 @@
     - `--highd` _number_ High threshold for dB. Defaults to -5.0.
     - `--lowd` _number_ Low threshold for dB. Defaults to -30.0.
     - `--volume-icon-pattern` _string_ dynamic string for current volume in 
`volumeipat`.
+    - `-H` _number_ High threshold for volume (in %). Defaults to 60.0.
+        - Long option: `--highv`
+    - `-L` _number_ Low threshold for volume (in %). Defaults to 20.0.
+        - Long option: `--lowv`
+    - `-h`: _string_ High string
+        - The string added in front of `<status>` when the mixer element
+          is on and the volume percentage is higher than the `-H` threshold.
+          Defaults to "".
+        - Long option: `--highs`
+    - `-m`: _string_ Medium string
+        - The string added in front of `<status>` when the mixer element
+          is on and the volume percentage is lower than the `-H` threshold.
+          Defaults to "".
+        - Long option: `--mediums`
+    - `-l`: _string_ Low string
+        - The string added in front of `<status>` when the mixer element
+          is on and the volume percentage is lower than the `-L` threshold.
+          Defaults to "".
+        - Long option: `--lows`
 - Variables that can be used with the `-t`/`--template` argument:
             `volume`, `volumebar`, `volumevbar`, `volumeipat`, `dB`, `status`
 - Note that `dB` might only return 0 on your system. This is known
@@ -1157,29 +1188,35 @@
 
 ### `Alsa Mixer Element Args`
 
-Like [Volume](#volume-mixer-element-args-refreshrate), but with the following 
differences:
-- Uses event-based refreshing via `alsactl monitor` instead of polling, so it 
will refresh
-  instantly when there's a volume change, and won't use CPU until a change 
happens.
-- Aliases to `alsa:` followed by the mixer name and element name separated by 
a colon. Thus,
-  `Alsa "default" "Master" []` can be used as `%alsa:default:Master%`.
+Like [Volume](#volume-mixer-element-args-refreshrate), but with the
+following differences:
+- Uses event-based refreshing via `alsactl monitor` instead of
+  polling, so it will refresh instantly when there's a volume change,
+  and won't use CPU until a change happens.
+- Aliases to `alsa:` followed by the mixer name and element name
+  separated by a colon. Thus, `Alsa "default" "Master" []` can be used
+  as `%alsa:default:Master%`.
 - Additional options (after the `--`):
     - `--alsactl=/path/to/alsactl`
-        - If this option is not specified, `alsactl` will be sought in your 
`PATH`
-          first, and failing that, at `/usr/sbin/alsactl` (this is its 
location on
-          Debian systems. `alsactl monitor` works as a non-root user despite 
living
-          in `/usr/sbin`.).
-- `stdbuf` (from coreutils) must be (and most probably already is) in your 
`PATH`.
+        - If this option is not specified, `alsactl` will be sought in
+          your `PATH` first, and failing that, at `/usr/sbin/alsactl`
+          (this is its location on Debian systems. `alsactl monitor`
+          works as a non-root user despite living in `/usr/sbin`.).
+- `stdbuf` (from coreutils) must be (and most probably already is) in
+  your `PATH`.
 
 ### `MPD Args RefreshRate`
 
 - This monitor will only be compiled if you ask for it using the
   `with_mpd` flag. It needs [libmpd] 5.0 or later (available on Hackage).
 - Aliases to `mpd`
-- Args: default monitor arguments. In addition you can provide
-  `-P`, `-S` and `-Z`, with an string argument, to represent the
-  playing, stopped and paused states in the `statei` template field.
-  The environment variables `MPD_HOST` and `MPD_PORT` are used to configure the
-  mpd server to communicate with. Also available:
+- Args: default monitor arguments. In addition you can provide `-P`,
+  `-S` and `-Z`, with an string argument, to represent the playing,
+  stopped and paused states in the `statei` template field.  The
+  environment variables `MPD_HOST` and `MPD_PORT` are used to
+  configure the mpd server to communicate with, unless given in the
+  additional arguments `-p` (`--port`) and `-h` (`--host`). Also
+  available:
   - `lapsed-icon-pattern`: dynamic string for current track position in `ipat`.
 - Variables that can be used with the `-t`/`--template` argument:
              `bar`, `vbar`, `ipat`, `state`, `statei`, `volume`, `length`,
@@ -1243,6 +1280,30 @@
                    ("lists", "~/var/mail/lists")]
                   "mail"
 
+### `MailX Args Opts Alias`
+
+- Args: list of maildirs in form
+  `[("name1","path1","color1"),...]`. Paths may start with a '~'
+  to expand to the user's home directory.  When mails are present,
+  counts are displayed with the given name and color.
+- Opts is a possibly empty list of options, as flags. Possible values:
+   -d dir  --dir dir a string giving the base directory where maildir files 
with
+                     a relative path live.
+   -p prefix --prefix prefix  a string giving a prefix for the list
+                      of displayed mail counts
+   -s suffix --suffix suffix  a string giving a suffix for the list
+                      of displayed mail counts
+- This plugin requires inotify support in your Linux kernel and the
+  [hinotify] package. To activate, pass `--flags="with_inotify"`
+  during compilation.
+- Example:
+
+         Run MailX [("I", "inbox", "green"),
+                    ("L", "lists", "orange")]
+                   ["-d", "~/var/mail", "-p", " ", "-s", " "]
+                   "mail"
+
+
 ### `MBox Mboxes Opts Alias`
 
 - Mboxes a list of mbox files of the form `[("name", "path", "color")]`,
@@ -1403,7 +1464,7 @@
 
 ## Other Plugins
 
-<font size="+1">**`StdinReader`**</font>
+### `StdinReader`
 
 - Aliases to StdinReader
 - Displays any text received by xmobar on its standard input.
@@ -1411,7 +1472,7 @@
   actions via stdin.  This is safer than `UnsafeStdinReader` because there is
   no need to escape the content before passing it to xmobar's standard input.
 
-<font size="+1">**`UnsafeStdinReader`**</font>
+### `UnsafeStdinReader`
 
 - Aliases to UnsafeStdinReader
 - Displays any text received by xmobar on its standard input.
@@ -1425,13 +1486,13 @@
   clicking on xmobar:
   ```<action=`xdotool key alt+1`>ws1</action> <action=`xdotool key 
alt+1`>ws2</action>```
 
-<font size="+1">**`Date Format Alias RefreshRate`**</font>
+### `Date Format Alias RefreshRate`
 
 - Format is a time format string, as accepted by the standard ISO C
   `strftime` function (or Haskell's `formatCalendarTime`).
 - Sample usage: `Run Date "%a %b %_d %Y <fc=#ee9a00>%H:%M:%S</fc>" "date" 10`
 
-<font size="+1">**`DateZone Format Locale Zone Alias RefreshRate`**</font>
+### `DateZone Format Locale Zone Alias RefreshRate`
 
 - Format is a time format string, as accepted by the standard ISO C
   `strftime` function (or Haskell's `formatCalendarTime`).
@@ -1444,17 +1505,17 @@
 - Sample usage:
   `Run DateZone "%a %H:%M:%S" "de_DE.UTF-8" "Europe/Vienna" "viennaTime" 10`
 
-<font size="+1">**`CommandReader "/path/to/program" Alias`**</font>
+### `CommandReader "/path/to/program" Alias`
 
 - Runs the given program, and displays its standard output.
 
-<font size="+1">**`PipeReader "default text:/path/to/pipe" Alias`**</font>
+### `PipeReader "default text:/path/to/pipe" Alias`
 
 - Reads its displayed output from the given pipe.
 - Prefix an optional default text separated by a colon
 - Expands environment variables in the first argument of syntax '${VAR}' or 
'$VAR'
 
-<font size="+1">**`MarqueePipeReader "default text:/path/to/pipe" (length, 
rate, sep) Alias`**</font>
+### `MarqueePipeReader "default text:/path/to/pipe" (length, rate, sep) Alias`
 
 - Generally equivalent to PipeReader
 - Text is displayed as marquee with the specified length, rate in 10th
@@ -1464,9 +1525,7 @@
 
 - Expands environment variables in the first argument
 
-<font size="+1">
-**`BufferedPipeReader Alias [(Timeout, Bool, "/path/to/pipe1"), ..]`**
-</font>
+### `BufferedPipeReader Alias [(Timeout, Bool, "/path/to/pipe1"), ..]`
 
 - Display data from multiple pipes.
 - Timeout (in tenth of seconds) is the value after which the previous
@@ -1498,7 +1557,7 @@
 [examples/status.sh]: 
http://github.com/jaor/xmobar/raw/master/examples/status.sh
 
 
-<font size="+1">**`XMonadLog`**</font>
+### `XMonadLog`
 
 - Aliases to XMonadLog
 - Displays information from xmonad's `_XMONAD_LOG`. You can set this
@@ -1516,7 +1575,7 @@
 
 [here]: 
http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-DynamicLog.html
 
-<font size="+1">**`UnsafeXMonadLog`**</font>
+### `UnsafeXMonadLog`
 
 - Aliases to UnsafeXMonadLog
 - Similar to StdinReader versus UnsafeStdinReader, this does not strip `<action
@@ -1616,13 +1675,14 @@
 Lunter, Vanessa McHale, Robert J. Macomber, Dmitry Malikov, David
 McLean, Marcin Mikołajczyk, Dino Morelli, Tony Morris, Eric Mrak,
 Thiago Negri, Edward O'Callaghan, Svein Ove, Martin Perner, Jens
-Petersen, Alexander Polakov, Pavan Rikhi, Petr Rockai, Andrew
-Sackville-West, Markus Scherer, Daniel Schüssler, Olivier Schneider,
-Alexander Shabalin, Valentin Shirokov, Peter Simons, Alexander
-Solovyov, Will Song, John Soros, Felix Springer, Travis Staton, Artem
-Tarasov, Samuli Thomasson, Edward Tjörnhammar, Sergei Trofimovich,
-Thomas Tuegel, Jan Vornberger, Anton Vorontsov, Daniel Wagner, Zev
-Weiss, Phil Xiaojun Hu, Edward Z. Yang and Norbert Zeh.
+Petersen, Alexander Polakov, Pavan Rikhi, Petr Rockai, Andrew Emmanuel
+Rosa, Sackville-West, Markus Scherer, Daniel Schüssler, Olivier
+Schneider, Alexander Shabalin, Valentin Shirokov, Peter Simons,
+Alexander Solovyov, Will Song, John Soros, Felix Springer, Travis
+Staton, Artem Tarasov, Samuli Thomasson, Edward Tjörnhammar, Sergei
+Trofimovich, Thomas Tuegel, John Tyree, Jan Vornberger, Anton
+Vorontsov, Daniel Wagner, Zev Weiss, Phil Xiaojun Hu, Edward Z. Yang
+and Norbert Zeh.
 
 [jao]: http://jao.io
 [incorporates patches]: http://www.ohloh.net/p/xmobar/contributors
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmobar-0.30/src/Xmobar/App/Compile.hs 
new/xmobar-0.32/src/Xmobar/App/Compile.hs
--- old/xmobar-0.30/src/Xmobar/App/Compile.hs   2018-12-08 04:12:48.000000000 
+0100
+++ new/xmobar-0.32/src/Xmobar/App/Compile.hs   2019-09-06 07:06:36.000000000 
+0200
@@ -131,13 +131,13 @@
 --
 -- 'False' is returned if there are compilation errors.
 --
-recompile :: MonadIO m => String -> String -> Bool -> Bool -> m Bool
-recompile dir execName force verb = liftIO $ do
-    let bin  = dir </> execName
-        err  = dir </> (execName ++ ".errors")
-        src  = dir </> (execName ++ ".hs")
-        lib  = dir </> "lib"
-        script = dir </> "build"
+recompile :: MonadIO m => String -> String -> String -> Bool -> Bool -> m Bool
+recompile confDir dataDir execName force verb = liftIO $ do
+    let bin  = confDir </> execName
+        err  = dataDir </> (execName ++ ".errors")
+        src  = confDir </> (execName ++ ".hs")
+        lib  = confDir </> "lib"
+        script = confDir </> "build"
     useScript <- checkBuildScript verb script
     sc <- if useScript || force
           then return True
@@ -149,8 +149,8 @@
                     \errHandle ->
                       waitForProcess =<<
                         if useScript
-                        then runScript script bin dir errHandle
-                        else runGHC bin dir errHandle
+                        then runScript script bin confDir errHandle
+                        else runGHC bin confDir errHandle
         installSignalHandlers
         if status == ExitSuccess
             then trace verb "Xmobar recompilation process exited with success!"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmobar-0.30/src/Xmobar/App/Config.hs 
new/xmobar-0.32/src/Xmobar/App/Config.hs
--- old/xmobar-0.30/src/Xmobar/App/Config.hs    2018-12-09 04:37:17.000000000 
+0100
+++ new/xmobar-0.32/src/Xmobar/App/Config.hs    2019-10-15 22:00:40.000000000 
+0200
@@ -1,7 +1,7 @@
 ------------------------------------------------------------------------------
 -- |
 -- Module: Xmobar.Config.Defaults
--- Copyright: (c) 2018 Jose Antonio Ortega Ruiz
+-- Copyright: (c) 2018, 2019 Jose Antonio Ortega Ruiz
 -- License: BSD3-style (see LICENSE)
 --
 -- Maintainer: j...@gnu.org
@@ -21,6 +21,8 @@
                           xmobarDataDir,
                           xmobarConfigFile) where
 
+import Control.Monad (when)
+
 import System.Environment
 import System.Directory
 import System.FilePath ((</>))
@@ -79,10 +81,10 @@
 --
 -- The first directory that exists will be used.  If none of the
 -- directories exist then (1) will be used if it is set, otherwise (2)
--- will be used.  Either way, a directory will be created if necessary.
+-- will be used.
 xmobarConfigDir :: IO String
 xmobarConfigDir =
-    findFirstDirWithEnv "XMOBAR_CONFIG_DIR"
+    findFirstDirWithEnv False "XMOBAR_CONFIG_DIR"
       [ getAppUserDataDirectory "xmobar"
       , getXdgDirectory XdgConfig "xmobar"
       ]
@@ -94,8 +96,8 @@
 -- Several directories are considered.  In order of preference:
 --
 --   1. The directory specified in the @XMOBAR_DATA_DIR@ environment variable.
---   2. The @~\/.xmobar@ directory.
---   3. The @XDG_DATA_HOME/xmobar@ directory.
+--   2. The @XDG_DATA_HOME/xmobar@ directory.
+--   3. The @~\/.xmobar@ directory.
 --
 -- The first directory that exists will be used.  If none of the
 -- directories exist then (1) will be used if it is set, otherwise (2)
@@ -103,24 +105,25 @@
 -- necessary.
 xmobarDataDir :: IO String
 xmobarDataDir =
-    findFirstDirWithEnv "XMOBAR_DATA_DIR"
-      [ getAppUserDataDirectory "xmobar"
-      , getXdgDirectory XdgData "xmobar"
+    findFirstDirWithEnv True "XMOBAR_DATA_DIR"
+      [ getXdgDirectory XdgData "xmobar"
+      , getAppUserDataDirectory "xmobar"
       ]
 
 -- | Helper function that will find the first existing directory and
--- return its path.  If none of the directories can be found, create
--- and return the first from the list.  If the list is empty this
--- function returns the historical @~\/.xmobar@ directory.
-findFirstDirOf :: [IO FilePath] -> IO FilePath
-findFirstDirOf [] = findFirstDirOf [getAppUserDataDirectory "xmobar"]
-findFirstDirOf possibles = do
+-- return its path.  If none of the directories can be found,
+-- optionally create and return the first from the list.  If the list
+-- is empty this function returns the historical @~\/.xmobar@
+-- directory.
+findFirstDirOf :: Bool -> [IO FilePath] -> IO FilePath
+findFirstDirOf create [] = findFirstDirOf create [getAppUserDataDirectory 
"xmobar"]
+findFirstDirOf create possibles = do
     found <- go possibles
     case found of
       Just path -> return path
       Nothing ->  do
         primary <- head possibles
-        createDirectoryIfMissing True primary
+        when create (createDirectoryIfMissing True primary)
         return primary
   where
     go [] = return Nothing
@@ -130,12 +133,12 @@
 
 -- | Simple wrapper around @findFirstDirOf@ that allows the primary
 -- path to be specified by an environment variable.
-findFirstDirWithEnv :: String -> [IO FilePath] -> IO FilePath
-findFirstDirWithEnv envName paths = do
+findFirstDirWithEnv :: Bool -> String -> [IO FilePath] -> IO FilePath
+findFirstDirWithEnv create envName paths = do
     envPath' <- lookupEnv envName
     case envPath' of
-      Nothing -> findFirstDirOf paths
-      Just envPath -> findFirstDirOf (return envPath:paths)
+      Nothing -> findFirstDirOf create paths
+      Just envPath -> findFirstDirOf create (return envPath:paths)
 
 xmobarConfigFile :: IO (Maybe FilePath)
 xmobarConfigFile =
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmobar-0.30/src/Xmobar/App/Main.hs 
new/xmobar-0.32/src/Xmobar/App/Main.hs
--- old/xmobar-0.30/src/Xmobar/App/Main.hs      2019-01-12 20:01:42.000000000 
+0100
+++ new/xmobar-0.32/src/Xmobar/App/Main.hs      2019-11-14 01:08:47.000000000 
+0100
@@ -70,14 +70,14 @@
   for_ (concat vars) $ \(asyncs, _) ->
     for_ asyncs cancel
 
-buildLaunch :: Bool -> Bool -> FilePath -> ParseError -> IO ()
+buildLaunch :: Bool -> Bool -> String -> ParseError -> IO ()
 buildLaunch verb force p e = do
   let exec = takeBaseName p
-      dir = takeDirectory p
+      confDir = takeDirectory p
       ext = takeExtension p
   if ext `elem` [".hs", ".hsc", ".lhs"]
-    then recompile dir exec force verb >>
-         executeFile (dir </> exec) False [] Nothing
+    then xmobarDataDir >>= \dd -> recompile confDir dd exec force verb >>
+         executeFile (confDir </> exec) False [] Nothing
     else trace True ("Invalid configuration file: " ++ show e) >>
          trace True "\n(No compilation attempted: \
                     \only .hs, .hsc or .lhs files are compiled)"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmobar-0.30/src/Xmobar/Plugins/DateZone.hs 
new/xmobar-0.32/src/Xmobar/Plugins/DateZone.hs
--- old/xmobar-0.30/src/Xmobar/Plugins/DateZone.hs      2018-12-02 
06:34:57.000000000 +0100
+++ new/xmobar-0.32/src/Xmobar/Plugins/DateZone.hs      2019-11-17 
20:18:18.000000000 +0100
@@ -28,6 +28,9 @@
 import Control.Concurrent.STM
 
 import System.IO.Unsafe
+import System.Environment (lookupEnv)
+
+import Data.Maybe (fromMaybe)
 
 import Data.Time.Format
 import Data.Time.LocalTime
@@ -63,7 +66,8 @@
       locale <- getTimeLocale
       atomically $ putTMVar localeLock lock
       if z /= "" then do
-        timeZone <- getTimeZoneSeriesFromOlsonFile ("/usr/share/zoneinfo/" ++ 
z)
+        tzdir <- lookupEnv "TZDIR"
+        timeZone <- getTimeZoneSeriesFromOlsonFile ((fromMaybe 
"/usr/share/zoneinfo" tzdir) ++ "/" ++ z)
         go (dateZone f locale timeZone)
        else
         go (date f locale)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmobar-0.30/src/Xmobar/Plugins/Kbd.hs 
new/xmobar-0.32/src/Xmobar/Plugins/Kbd.hs
--- old/xmobar-0.30/src/Xmobar/Plugins/Kbd.hs   2018-12-02 06:34:10.000000000 
+0100
+++ new/xmobar-0.32/src/Xmobar/Plugins/Kbd.hs   2019-10-14 19:50:26.000000000 
+0200
@@ -27,7 +27,7 @@
 
 -- 'Bad' prefixes of layouts
 noLaySymbols :: [String]
-noLaySymbols = ["group", "inet", "ctr", "pc", "ctrl"]
+noLaySymbols = ["group", "inet", "ctr", "pc", "ctrl", "terminate"]
 
 
 -- splits the layout string into the actual layouts
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmobar-0.30/src/Xmobar/Plugins/Mail.hs 
new/xmobar-0.32/src/Xmobar/Plugins/Mail.hs
--- old/xmobar-0.30/src/Xmobar/Plugins/Mail.hs  2018-12-02 06:34:16.000000000 
+0100
+++ new/xmobar-0.32/src/Xmobar/Plugins/Mail.hs  2019-10-15 02:41:15.000000000 
+0200
@@ -13,7 +13,7 @@
 --
 -----------------------------------------------------------------------------
 
-module Xmobar.Plugins.Mail(Mail(..)) where
+module Xmobar.Plugins.Mail(Mail(..),MailX(..)) where
 
 import Xmobar.Run.Exec
 #ifdef INOTIFY
@@ -26,6 +26,7 @@
 import System.Directory
 import System.FilePath
 import System.INotify
+import System.Console.GetOpt
 
 import Data.List (isPrefixOf)
 import Data.Set (Set)
@@ -47,23 +48,56 @@
 import System.IO
 #endif
 
+data MOptions = MOptions
+               { oDir :: FilePath
+               , oPrefix :: String
+               , oSuffix :: String
+               }
+
+defaults :: MOptions
+defaults = MOptions {oDir = "", oPrefix = "", oSuffix = ""}
+
+options :: [OptDescr (MOptions -> MOptions)]
+options =
+  [ Option "d" ["dir"] (ReqArg (\x o -> o { oDir = x }) "") ""
+  , Option "p" ["prefix"] (ReqArg (\x o -> o { oPrefix = x }) "") ""
+  , Option "s" ["suffix"] (ReqArg (\x o -> o { oSuffix = x }) "") ""
+  ]
+
+parseOptions :: [String] -> IO MOptions
+parseOptions args =
+  case getOpt Permute options args of
+    (o, _, []) -> return $ foldr id defaults o
+    (_, _, errs) -> ioError . userError $ concat errs
+
 
 -- | A list of mail box names and paths to maildirs.
 data Mail = Mail [(String, FilePath)] String
     deriving (Read, Show)
 
+-- | A list of mail box names, paths to maildirs and display colors.
+data MailX = MailX [(String, FilePath, String)] [String] String
+    deriving (Read, Show)
+
 instance Exec Mail where
-    alias (Mail _ a) = a
+  alias (Mail _ a) = a
+  start (Mail ms a) = start (MailX (map (\(n,p) -> (n,p,"")) ms) [] a)
+
+instance Exec MailX where
+    alias (MailX _ _ a) = a
 #ifndef INOTIFY
     start _ _ =
         hPutStrLn stderr $ "Warning: xmobar is not compiled with 
-fwith_inotify,"
                         ++ " but the Mail plugin requires it."
 #else
-    start (Mail ms _) cb = do
+    start (MailX ms args _) cb = do
         vs <- mapM (const $ newTVarIO S.empty) ms
-
-        let ts = map fst ms
-            rs = map ((</> "new") . snd) ms
+        opts <- parseOptions args
+        let prefix = oPrefix opts
+            suffix = oSuffix opts
+            dir = oDir opts
+            ps = map (\(_,p,_) -> if null dir then p else dir </> p) ms
+            rs = map (</> "new") ps
             ev = [Move, MoveIn, MoveOut, Create, Delete]
 
         ds <- mapM expandHome rs
@@ -76,9 +110,11 @@
             atomically $ modifyTVar v (S.union s)
 
         changeLoop (mapM (fmap S.size . readTVar) vs) $ \ns ->
-            cb . unwords $ [m ++ show n
-                            | (m, n) <- zip ts ns
-                            , n /= 0 ]
+            let showmbx m n c = if c == ""
+                                then m ++ show n
+                                else "<fc=" ++ c ++ ">" ++ m ++ show n ++ 
"</fc>"
+                cnts = [showmbx m n c | ((m,_,c), n) <- zip ms ns , n /= 0 ]
+            in cb $ if null cnts then "" else prefix ++ unwords cnts ++ suffix
 
 handle :: TVar (Set String) -> Event -> IO ()
 handle v e = atomically $ modifyTVar v $ case e of
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmobar-0.30/src/Xmobar/Plugins/Monitors/Batt.hs 
new/xmobar-0.32/src/Xmobar/Plugins/Monitors/Batt.hs
--- old/xmobar-0.30/src/Xmobar/Plugins/Monitors/Batt.hs 2019-06-30 
06:10:19.000000000 +0200
+++ new/xmobar-0.32/src/Xmobar/Plugins/Monitors/Batt.hs 2019-10-15 
03:57:04.000000000 +0200
@@ -45,6 +45,10 @@
   , onIconPattern :: Maybe IconPattern
   , offIconPattern :: Maybe IconPattern
   , idleIconPattern :: Maybe IconPattern
+  , lowString :: String
+  , mediumString :: String
+  , highString :: String
+  , incPerc :: Bool
   }
 
 defaultOpts :: BattOpts
@@ -65,6 +69,10 @@
   , onIconPattern = Nothing
   , offIconPattern = Nothing
   , idleIconPattern = Nothing
+  , lowString = ""
+  , mediumString = ""
+  , highString = ""
+  , incPerc = False
   }
 
 options :: [OptDescr (BattOpts -> BattOpts)]
@@ -81,6 +89,7 @@
   , Option "f" ["online"] (ReqArg (\x o -> o { onlineFile = x }) "") ""
   , Option "s" ["scale"] (ReqArg (\x o -> o {scale = read x}) "") ""
   , Option "a" ["action"] (ReqArg (\x o -> o { onLowAction = Just x }) "") ""
+  , Option "P" ["percent"] (NoArg (\o -> o {incPerc = True})) ""
   , Option "A" ["action-threshold"]
                (ReqArg (\x o -> o { actionThreshold = read x }) "") ""
   , Option "" ["on-icon-pattern"] (ReqArg (\x o ->
@@ -89,6 +98,9 @@
      o { offIconPattern = Just $ parseIconPattern x }) "") ""
   , Option "" ["idle-icon-pattern"] (ReqArg (\x o ->
      o { idleIconPattern = Just $ parseIconPattern x }) "") ""
+  , Option "" ["lows"] (ReqArg (\x o -> o { lowString = x }) "") ""
+  , Option "" ["mediums"] (ReqArg (\x o -> o { mediumString = x }) "") ""
+  , Option "" ["highs"] (ReqArg (\x o -> o { highString = x }) "") ""
   ]
 
 parseOpts :: [String] -> IO BattOpts
@@ -125,6 +137,23 @@
   , status :: !String
   }
 
+data BatteryStatus
+  = BattHigh
+  | BattMedium
+  | BattLow
+
+-- | Convert the current battery charge into a 'BatteryStatus'
+getBattStatus
+  :: Float    -- ^ Current battery charge, assumed to be in [0,1]
+  -> BattOpts -- ^ Battery options, including high/low thresholds
+  -> BatteryStatus
+getBattStatus charge opts
+  | c >= highThreshold opts = BattHigh
+  | c >= lowThreshold  opts = BattMedium
+  | otherwise = BattLow
+ where
+   c = 100 * min 1 charge
+
 safeFileExist :: String -> String -> IO Bool
 safeFileExist d f = handle noErrors $ fileExist (d </> f)
   where noErrors = const (return False) :: SomeException -> IO Bool
@@ -217,25 +246,29 @@
 runBatt' :: [String] -> [String] -> Monitor String
 runBatt' bfs args = do
   opts <- io $ parseOpts args
+  let sp = incPerc opts
   c <- io $ readBatteries opts =<< mapM batteryFiles bfs
   suffix <- getConfigValue useSuffix
   d <- getConfigValue decDigits
   nas <- getConfigValue naString
   case c of
     Result x w t s ->
-      do l <- fmtPercent x
+      do l <- fmtPercent x sp
          ws <- fmtWatts w opts suffix d
          si <- getIconPattern opts s x
-         st <- showWithColors' (fmtStatus opts s nas) (100 * x)
+         st <- showWithColors'
+                 (fmtStatus opts s nas (getBattStatus x opts))
+                 (100 * x)
          parseTemplate (l ++ [st, fmtTime $ floor t, ws, si])
     NA -> getConfigValue naString
-  where fmtPercent :: Float -> Monitor [String]
-        fmtPercent x = do
+  where fmtPercent :: Float -> Bool -> Monitor [String]
+        fmtPercent x sp = do
           let x' = minimum [1, x]
+          pc <- if sp then colorizeString (100 * x') "%" else return ""
           p <- showPercentWithColors x'
           b <- showPercentBar (100 * x') x'
           vb <- showVerticalBar (100 * x') x'
-          return [b, vb, p]
+          return [b, vb, p ++ pc]
         fmtWatts x o s d = do
           ws <- showWithPadding $ showDigits d x ++ (if s then "W" else "")
           return $ color x o ws
@@ -244,11 +277,21 @@
                                     then minutes else '0' : minutes
           where hours = show (x `div` 3600)
                 minutes = show ((x `mod` 3600) `div` 60)
-        fmtStatus opts Idle _ = idleString opts
-        fmtStatus _ Unknown na = na
-        fmtStatus opts Full _ = idleString opts
-        fmtStatus opts Charging _ = onString opts
-        fmtStatus opts Discharging _ = offString opts
+        fmtStatus
+          :: BattOpts
+          -> Status
+          -> String -- ^ What to in case battery status is unknown
+          -> BatteryStatus
+          -> String
+        fmtStatus opts Idle _ _ = idleString opts
+        fmtStatus _ Unknown na _ = na
+        fmtStatus opts Full _ _ = idleString opts
+        fmtStatus opts Charging _ _ = onString opts
+        fmtStatus opts Discharging _ battStatus =
+          (case battStatus of
+            BattHigh -> highString
+            BattMedium -> mediumString
+            BattLow -> lowString) opts ++ offString opts
         maybeColor Nothing str = str
         maybeColor (Just c) str = "<fc=" ++ c ++ ">" ++ str ++ "</fc>"
         color x o | x >= 0 = maybeColor (posColor o)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/xmobar-0.30/src/Xmobar/Plugins/Monitors/Common/Output.hs 
new/xmobar-0.32/src/Xmobar/Plugins/Monitors/Common/Output.hs
--- old/xmobar-0.30/src/Xmobar/Plugins/Monitors/Common/Output.hs        
2018-12-02 05:58:30.000000000 +0100
+++ new/xmobar-0.32/src/Xmobar/Plugins/Monitors/Common/Output.hs        
2019-10-15 03:53:01.000000000 +0200
@@ -1,7 +1,7 @@
 ------------------------------------------------------------------------------
 -- |
 -- Module: Xmobar.Plugins.Monitors.Strings
--- Copyright: (c) 2018 Jose Antonio Ortega Ruiz
+-- Copyright: (c) 2018, 2019 Jose Antonio Ortega Ruiz
 -- License: BSD3-style (see LICENSE)
 --
 -- Maintainer: j...@gnu.org
@@ -18,6 +18,7 @@
 module Xmobar.Plugins.Monitors.Common.Output ( IconPattern
                                              , parseIconPattern
                                              , padString
+                                             , colorizeString
                                              , showWithPadding
                                              , showWithColors
                                              , showWithColors'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmobar-0.30/src/Xmobar/Plugins/Monitors/Disk.hs 
new/xmobar-0.32/src/Xmobar/Plugins/Monitors/Disk.hs
--- old/xmobar-0.30/src/Xmobar/Plugins/Monitors/Disk.hs 2019-05-23 
18:44:52.000000000 +0200
+++ new/xmobar-0.32/src/Xmobar/Plugins/Monitors/Disk.hs 2019-12-08 
17:54:51.000000000 +0100
@@ -31,6 +31,7 @@
   { totalIconPattern :: Maybe IconPattern
   , writeIconPattern :: Maybe IconPattern
   , readIconPattern :: Maybe IconPattern
+  , contiguous :: Bool
   }
 
 parseDiskIOOpts :: [String] -> IO DiskIOOpts
@@ -42,6 +43,7 @@
           { totalIconPattern = Nothing
           , writeIconPattern = Nothing
           , readIconPattern = Nothing
+          , contiguous = False
           }
        options =
           [ Option "" ["total-icon-pattern"] (ReqArg (\x o ->
@@ -50,6 +52,7 @@
              o { writeIconPattern = Just $ parseIconPattern x}) "") ""
           , Option "" ["read-icon-pattern"] (ReqArg (\x o ->
              o { readIconPattern = Just $ parseIconPattern x}) "") ""
+          , Option "c" ["contiguous"] (NoArg (\o -> o {contiguous = True})) ""
           ]
 
 diskIOConfig :: IO MConfig
@@ -66,6 +69,7 @@
 data DiskUOpts = DiskUOpts
   { freeIconPattern :: Maybe IconPattern
   , usedIconPattern :: Maybe IconPattern
+  , contiguousU :: Bool
   }
 
 parseDiskUOpts :: [String] -> IO DiskUOpts
@@ -76,12 +80,14 @@
  where defaultOpts = DiskUOpts
           { freeIconPattern = Nothing
           , usedIconPattern = Nothing
+          , contiguousU = False
           }
        options =
           [ Option "" ["free-icon-pattern"] (ReqArg (\x o ->
              o { freeIconPattern = Just $ parseIconPattern x}) "") ""
           , Option "" ["used-icon-pattern"] (ReqArg (\x o ->
              o { usedIconPattern = Just $ parseIconPattern x}) "") ""
+          , Option "c" ["contiguous"] (NoArg (\o -> o {contiguousU = True})) ""
           ]
 
 diskUConfig :: IO MConfig
@@ -147,25 +153,26 @@
   return $ map (parseDev (zipWith diff dt' dt)) devs
   where diff (dev, xs) (_, ys) = (dev, zipWith (-) xs ys)
 
+
 parseDev :: [(DevName, [Float])] -> DevName -> (DevName, [Float])
 parseDev dat dev =
   case find ((==dev) . fst) dat of
     Nothing -> (dev, [0, 0, 0])
     Just (_, xs) ->
-      let r = xs !! 2
-          w = xs !! 6
+      let r = 4096 * xs !! 2
+          w = 4096 * xs !! 6
           t = r + w
           rSp = speed r (xs !! 3)
           wSp = speed w (xs !! 7)
           sp =  speed t (xs !! 3 + xs !! 7)
-          speed x d = if d == 0 then 0 else 500 * x / d
+          speed x d = if d == 0 then 0 else x / d
           dat' = if length xs > 6
                  then [sp, rSp, wSp, t, r, w]
                  else [0, 0, 0, 0, 0, 0]
       in (dev, dat')
 
 speedToStr :: Float -> String
-speedToStr = showWithUnits 2 1
+speedToStr = showWithUnits 2 1 . (/ 1024)
 
 sizeToStr :: Integer -> String
 sizeToStr = showWithUnits 3 0 . fromIntegral
@@ -205,7 +212,7 @@
   dev <- io $ mountedOrDiskDevices (map fst disks)
   dat <- io $ mountedData dref (map fst dev)
   strs <- mapM (runDiskIO' opts) $ devTemplates disks dev dat
-  return $ unwords strs
+  return $ (if contiguous opts then concat else unwords) strs
 
 startDiskIO :: [(String, String)] ->
                [String] -> Int -> (String -> IO ()) -> IO ()
@@ -249,4 +256,4 @@
   devs <- io $ mountedDevices (map fst disks)
   opts <- io $ parseDiskUOpts argv
   strs <- mapM (\(d, p) -> runDiskU' opts (findTempl d p disks) p) devs
-  return $ unwords strs
+  return $ (if contiguousU opts then concat else unwords) strs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmobar-0.30/src/Xmobar/Plugins/Monitors/MPD.hs 
new/xmobar-0.32/src/Xmobar/Plugins/Monitors/MPD.hs
--- old/xmobar-0.30/src/Xmobar/Plugins/Monitors/MPD.hs  2018-12-02 
06:15:11.000000000 +0100
+++ new/xmobar-0.32/src/Xmobar/Plugins/Monitors/MPD.hs  2019-11-14 
01:08:47.000000000 +0100
@@ -34,6 +34,8 @@
   , mStopped :: String
   , mPaused :: String
   , mLapsedIconPattern :: Maybe IconPattern
+  , mPort :: Maybe String
+  , mHost :: Maybe String
   }
 
 defaultOpts :: MOpts
@@ -42,6 +44,8 @@
   , mStopped = "><"
   , mPaused = "||"
   , mLapsedIconPattern = Nothing
+  , mPort = Nothing
+  , mHost = Nothing
   }
 
 options :: [OptDescr (MOpts -> MOpts)]
@@ -49,15 +53,20 @@
   [ Option "P" ["playing"] (ReqArg (\x o -> o { mPlaying = x }) "") ""
   , Option "S" ["stopped"] (ReqArg (\x o -> o { mStopped = x }) "") ""
   , Option "Z" ["paused"] (ReqArg (\x o -> o { mPaused = x }) "") ""
+  , Option "p" ["port"] (ReqArg (\x o -> o { mPort = Just x }) "") ""
+  , Option "h" ["host"] (ReqArg (\x o -> o { mHost = Just x }) "") ""
   , Option "" ["lapsed-icon-pattern"] (ReqArg (\x o ->
      o { mLapsedIconPattern = Just $ parseIconPattern x }) "") ""
   ]
 
+withMPD :: MOpts -> M.MPD a -> IO (M.Response a)
+withMPD opts = M.withMPD_ (mHost opts) (mPort opts)
+
 runMPD :: [String] -> Monitor String
 runMPD args = do
   opts <- io $ mopts args
-  status <- io $ M.withMPD M.status
-  song <- io $ M.withMPD M.currentSong
+  status <- io $ withMPD opts M.status
+  song <- io $ withMPD opts M.currentSong
   s <- parseMPD status song opts
   parseTemplate s
 
@@ -69,8 +78,9 @@
     _ -> return ()
 
 mpdReady :: [String] -> Monitor Bool
-mpdReady _ = do
-  response <- io $ M.withMPD M.ping
+mpdReady args = do
+  opts <- io $ mopts args
+  response <- io $ withMPD opts M.ping
   case response of
     Right _         -> return True
     -- Only cases where MPD isn't responding is an issue; bogus information at
@@ -99,13 +109,13 @@
         si = stateGlyph s opts
         vol = int2str $ fromMaybe 0 (M.stVolume st)
         (p, t) = fromMaybe (0, 0) (M.stTime st)
-        [lap, len, remain] = map showTime [floor p, t, max 0 (t - floor p)]
-        b = if t > 0 then realToFrac $ p / fromIntegral t else 0
+        [lap, len, remain] = map showTime [floor p, floor t, max 0 (floor t - 
floor p)]
+        b = if t > 0 then realToFrac $ p / t else 0
         plen = int2str $ M.stPlaylistLength st
         ppos = maybe "" (int2str . (+1)) $ M.stSongPos st
         flags = playbackMode st
 
-stateGlyph :: M.State -> MOpts -> String
+stateGlyph :: M.PlaybackState -> MOpts -> String
 stateGlyph s o =
   case s of
     M.Playing -> mPlaying o
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmobar-0.30/src/Xmobar/Plugins/Monitors/MultiCpu.hs 
new/xmobar-0.32/src/Xmobar/Plugins/Monitors/MultiCpu.hs
--- old/xmobar-0.30/src/Xmobar/Plugins/Monitors/MultiCpu.hs     2018-12-02 
06:15:16.000000000 +0100
+++ new/xmobar-0.32/src/Xmobar/Plugins/Monitors/MultiCpu.hs     2019-12-08 
17:33:49.000000000 +0100
@@ -25,6 +25,7 @@
   { loadIconPatterns :: [IconPattern]
   , loadIconPattern :: Maybe IconPattern
   , fallbackIconPattern :: Maybe IconPattern
+  , contiguous :: Bool
   }
 
 defaultOpts :: MultiCpuOpts
@@ -32,6 +33,7 @@
   { loadIconPatterns = []
   , loadIconPattern = Nothing
   , fallbackIconPattern = Nothing
+  , contiguous = False
   }
 
 options :: [OptDescr (MultiCpuOpts -> MultiCpuOpts)]
@@ -42,6 +44,7 @@
      o { loadIconPatterns = parseIconPattern x : loadIconPatterns o }) "") ""
   , Option "" ["fallback-icon-pattern"] (ReqArg (\x o ->
      o { fallbackIconPattern = Just $ parseIconPattern x }) "") ""
+  , Option "" ["contiguous-icons"] (NoArg (\o -> o {contiguous = True})) ""
   ]
 
 parseOpts :: [String] -> IO MultiCpuOpts
@@ -87,7 +90,8 @@
 
 formatMultiCpus :: MultiCpuOpts -> [[Float]] -> Monitor [String]
 formatMultiCpus _ [] = return []
-formatMultiCpus opts xs = concat <$> mapM (\(i, x) -> formatCpu opts i x) (zip 
[0..] xs)
+formatMultiCpus opts xs =
+  concat <$> mapM (\(i, x) -> formatCpu opts i x) (zip [0..] xs)
 
 formatCpu :: MultiCpuOpts -> Int -> [Float] -> Monitor [String]
 formatCpu opts i xs
@@ -100,7 +104,8 @@
                       return (b:h:d:ps)
   where tryString
           | i == 0 = loadIconPattern opts
-          | i <= length (loadIconPatterns opts) = Just $ loadIconPatterns opts 
!! (i - 1)
+          | i <= length (loadIconPatterns opts) =
+              Just $ loadIconPatterns opts !! (i - 1)
           | otherwise = fallbackIconPattern opts
 
 splitEvery :: Int -> [a] -> [[a]]
@@ -109,16 +114,17 @@
 groupData :: [String] -> [[String]]
 groupData = transpose . tail . splitEvery vNum
 
-formatAutoCpus :: [String] -> Monitor [String]
-formatAutoCpus [] = return $ replicate vNum ""
-formatAutoCpus xs = return $ map unwords (groupData xs)
+formatAutoCpus :: MultiCpuOpts -> [String] -> Monitor [String]
+formatAutoCpus _ [] = return $ replicate vNum ""
+formatAutoCpus opts xs =
+  return $ map (if contiguous opts then concat else unwords) (groupData xs)
 
 runMultiCpu :: CpuDataRef -> [String] -> Monitor String
 runMultiCpu cref argv =
   do c <- io $ parseCpuData cref
      opts <- io $ parseOpts argv
      l <- formatMultiCpus opts c
-     a <- formatAutoCpus l
+     a <- formatAutoCpus opts l
      parseTemplate $ a ++ l
 
 startMultiCpu :: [String] -> Int -> (String -> IO ()) -> IO ()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmobar-0.30/src/Xmobar/Plugins/Monitors/Net.hs 
new/xmobar-0.32/src/Xmobar/Plugins/Monitors/Net.hs
--- old/xmobar-0.30/src/Xmobar/Plugins/Monitors/Net.hs  2018-12-02 
06:15:18.000000000 +0100
+++ new/xmobar-0.32/src/Xmobar/Plugins/Monitors/Net.hs  2019-11-06 
15:21:26.000000000 +0100
@@ -13,6 +13,8 @@
 --
 -----------------------------------------------------------------------------
 
+{-# LANGUAGE OverloadedStrings #-}
+
 module Xmobar.Plugins.Monitors.Net (
                         startNet
                       , startDynNet
@@ -20,26 +22,40 @@
 
 import Xmobar.Plugins.Monitors.Common
 
-import Data.Word (Word64)
 import Data.IORef (IORef, newIORef, readIORef, writeIORef)
+import Data.Monoid ((<>))
 import Data.Time.Clock (UTCTime, getCurrentTime, diffUTCTime)
+import Data.Word (Word64)
 import Control.Monad (forM, filterM)
 import System.Directory (getDirectoryContents, doesFileExist)
 import System.FilePath ((</>))
 import System.Console.GetOpt
 import System.IO.Error (catchIOError)
+import System.IO.Unsafe (unsafeInterleaveIO)
 
-import qualified Data.ByteString.Lazy.Char8 as B
+import qualified Data.ByteString.Char8 as B
+
+type DevList = [String]
+
+parseDevList :: String -> DevList
+parseDevList = splitOnComma
+  where splitOnComma [] = [[]]
+        splitOnComma (',':xs) = [] : splitOnComma xs
+        splitOnComma (x:xs) =
+           let rest = splitOnComma xs
+           in (x : head rest) : tail rest
 
 data NetOpts = NetOpts
   { rxIconPattern :: Maybe IconPattern
   , txIconPattern :: Maybe IconPattern
+  , onlyDevList :: Maybe DevList
   }
 
 defaultOpts :: NetOpts
 defaultOpts = NetOpts
   { rxIconPattern = Nothing
   , txIconPattern = Nothing
+  , onlyDevList = Nothing
   }
 
 options :: [OptDescr (NetOpts -> NetOpts)]
@@ -48,6 +64,8 @@
      o { rxIconPattern = Just $ parseIconPattern x }) "") ""
   , Option "" ["tx-icon-pattern"] (ReqArg (\x o ->
      o { txIconPattern = Just $ parseIconPattern x }) "") ""
+  , Option "" ["devices"] (ReqArg (\x o ->
+     o { onlyDevList = Just $ parseDevList x }) "") ""
   ]
 
 parseOpts :: [String] -> IO NetOpts
@@ -65,10 +83,8 @@
     show MBs = "MB/s"
     show GBs = "GB/s"
 
-data NetDev num
-    = NA
-    | NI String
-    | ND String num num deriving (Eq,Show,Read)
+data NetDev num = N String (NetDevInfo num) | NA deriving (Eq,Show,Read)
+data NetDevInfo num = NI | ND num num deriving (Eq,Show,Read)
 
 type NetDevRawTotal = NetDev Word64
 type NetDevRate = NetDev Float
@@ -79,17 +95,16 @@
 -- Note that names don't matter. Therefore, if only the names differ,
 -- a compare evaluates to EQ while (==) evaluates to False.
 instance Ord num => Ord (NetDev num) where
-    compare NA NA              = EQ
-    compare NA _               = LT
-    compare _  NA              = GT
-    compare (NI _) (NI _)      = EQ
-    compare (NI _) ND {}       = LT
-    compare ND {} (NI _)     = GT
-    compare (ND _ x1 y1) (ND _ x2 y2) =
-        if downcmp /= EQ
-           then downcmp
-           else y1 `compare` y2
-      where downcmp = x1 `compare` x2
+    compare NA NA             = EQ
+    compare NA _              = LT
+    compare _  NA             = GT
+    compare (N _ i1) (N _ i2) = i1 `compare` i2
+
+instance Ord num => Ord (NetDevInfo num) where
+    compare NI NI                 = EQ
+    compare NI ND {}              = LT
+    compare ND {} NI              = GT
+    compare (ND x1 y1) (ND x2 y2) = x1 `compare` x2 <> y1 `compare` y2
 
 netConfig :: IO MConfig
 netConfig = mkMConfig
@@ -108,25 +123,20 @@
 isUp :: String -> IO Bool
 isUp d = flip catchIOError (const $ return False) $ do
   operstate <- B.readFile (operstateDir d)
-  return $! (B.unpack . head . B.lines) operstate `elem`  ["up", "unknown"]
+  return $! (head . B.lines) operstate `elem` ["up", "unknown"]
 
 readNetDev :: [String] -> IO NetDevRawTotal
-readNetDev (d:x:y:_) = do
-  up <- isUp d
-  return (if up then ND d (r x) (r y) else NI d)
+readNetDev ~[d, x, y] = do
+  up <- unsafeInterleaveIO $ isUp d
+  return $ N d (if up then ND (r x) (r y) else NI)
     where r s | s == "" = 0
               | otherwise = read s
 
-readNetDev _ = return NA
-
 netParser :: B.ByteString -> IO [NetDevRawTotal]
 netParser = mapM (readNetDev . splitDevLine) . readDevLines
   where readDevLines = drop 2 . B.lines
-        splitDevLine = selectCols . wordsBy (`elem` " :") . B.unpack
+        splitDevLine = map B.unpack . selectCols . filter (not . B.null) . 
B.splitWith (`elem` [' ',':'])
         selectCols cols = map (cols!!) [0,1,9]
-        wordsBy f s = case dropWhile f s of
-          [] -> []
-          s' -> w : wordsBy f s'' where (w, s'') = break f s'
 
 findNetDev :: String -> IO NetDevRawTotal
 findNetDev dev = do
@@ -134,8 +144,7 @@
   case filter isDev nds of
     x:_ -> return x
     _ -> return NA
-  where isDev (ND d _ _) = d == dev
-        isDev (NI d) = d == dev
+  where isDev (N d _) = d == dev
         isDev NA = False
 
 formatNet :: Maybe IconPattern -> Float -> Monitor (String, String, String, 
String)
@@ -154,11 +163,11 @@
 printNet :: NetOpts -> NetDevRate -> Monitor String
 printNet opts nd =
   case nd of
-    ND d r t -> do
+    N d (ND r t) -> do
         (rx, rb, rvb, ripat) <- formatNet (rxIconPattern opts) r
         (tx, tb, tvb, tipat) <- formatNet (txIconPattern opts) t
         parseTemplate [d,rx,tx,rb,rvb,ripat,tb,tvb,tipat]
-    NI _ -> return ""
+    N _ NI -> return ""
     NA -> getConfigValue naString
 
 parseNet :: NetDevRef -> String -> IO NetDevRate
@@ -170,9 +179,9 @@
   let scx = realToFrac (diffUTCTime t1 t0)
       scx' = if scx > 0 then scx else 1
       rate da db = takeDigits 2 $ fromIntegral (db - da) / scx'
-      diffRate (ND d ra ta) (ND _ rb tb) = ND d (rate ra rb) (rate ta tb)
-      diffRate (NI d) _ = NI d
-      diffRate _ (NI d) = NI d
+      diffRate (N d (ND ra ta)) (N _ (ND rb tb)) = N d (ND (rate ra rb) (rate 
ta tb))
+      diffRate (N d NI) _ = N d NI
+      diffRate _ (N d NI) = N d NI
       diffRate _ _ = NA
   return $ diffRate n0 n1
 
@@ -187,10 +196,16 @@
 
 runNets :: [(NetDevRef, String)] -> [String] -> Monitor String
 runNets refs argv = do
-  dev <- io $ parseActive refs
   opts <- io $ parseOpts argv
+  dev <- io $ parseActive $ filterRefs opts refs
   printNet opts dev
     where parseActive refs' = fmap selectActive (parseNets refs')
+          refInDevList opts' (_, refname') = case onlyDevList opts' of
+            Just theList -> refname' `elem` theList
+            Nothing -> True
+          filterRefs opts' refs' = case filter (refInDevList opts') refs' of
+            [] -> refs'
+            xs -> xs
           selectActive = maximum
 
 startNet :: String -> [String] -> Int -> (String -> IO ()) -> IO ()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmobar-0.30/src/Xmobar/Plugins/Monitors/Volume.hs 
new/xmobar-0.32/src/Xmobar/Plugins/Monitors/Volume.hs
--- old/xmobar-0.30/src/Xmobar/Plugins/Monitors/Volume.hs       2018-12-24 
02:41:54.000000000 +0100
+++ new/xmobar-0.32/src/Xmobar/Plugins/Monitors/Volume.hs       2019-10-14 
19:50:26.000000000 +0200
@@ -21,7 +21,7 @@
   , VolumeOpts
   ) where
 
-import Control.Applicative ((<$>))
+import Control.Applicative ( (<$>), liftA3 )
 import Control.Monad ( liftM2, liftM3, mplus )
 import Data.Traversable (sequenceA)
 import Xmobar.Plugins.Monitors.Common
@@ -42,6 +42,11 @@
     , highDbThresh :: Float
     , lowDbThresh :: Float
     , volumeIconPattern :: Maybe IconPattern
+    , lowVolThresh :: Maybe Float
+    , highVolThresh :: Maybe Float
+    , lowString :: String
+    , mediumString :: String
+    , highString :: String
     }
 
 defaultOpts :: VolumeOpts
@@ -53,8 +58,32 @@
     , highDbThresh = -5.0
     , lowDbThresh = -30.0
     , volumeIconPattern = Nothing
+    , lowVolThresh = Just 20.0
+    , highVolThresh = Just 60.0
+    , lowString = ""
+    , mediumString = ""
+    , highString = ""
     }
 
+data VolumeStatus
+    = VolLow
+    | VolMedium
+    | VolHigh
+    | VolOff
+
+-- | Set the volume status according to user set thresholds and the current
+-- volume
+getVolStatus :: Float -- ^ Low volume threshold, in [0,100]
+             -> Float -- ^ High volume threshold, in  [0,100]
+             -> Float -- ^ Current volume, in [0,1]
+             -> VolumeStatus
+getVolStatus lo hi val'
+    | val >= hi = VolHigh
+    | val >= lo = VolMedium
+    | otherwise = VolLow
+  where
+    val = val' * 100
+
 options :: [OptDescr (VolumeOpts -> VolumeOpts)]
 options =
     [ Option "O" ["on"] (ReqArg (\x o -> o { onString = x }) "") ""
@@ -65,6 +94,11 @@
     , Option "c" ["offc"] (ReqArg (\x o -> o { offColor = Just x }) "") ""
     , Option "" ["volume-icon-pattern"] (ReqArg (\x o ->
        o { volumeIconPattern = Just $ parseIconPattern x }) "") ""
+    , Option "L" ["lowv"] (ReqArg (\x o -> o { lowVolThresh = Just $ read x }) 
"") ""
+    , Option "H" ["highv"] (ReqArg (\x o -> o { highVolThresh = Just $ read x 
}) "") ""
+    , Option "l" ["lows"] (ReqArg (\x o -> o { lowString = x }) "") ""
+    , Option "m" ["mediums"] (ReqArg (\x o -> o { mediumString = x }) "") ""
+    , Option "h" ["highs"] (ReqArg (\x o -> o { highString = x }) "") ""
     ]
 
 parseOpts :: [String] -> IO VolumeOpts
@@ -98,15 +132,26 @@
 switchHelper :: VolumeOpts
              -> (VolumeOpts -> Maybe String)
              -> (VolumeOpts -> String)
+             -> VolumeStatus
              -> Monitor String
-switchHelper opts cHelp strHelp = return $
+switchHelper opts cHelp strHelp vs = return $
     colorHelper (cHelp opts)
+    ++ volHelper vs opts
     ++ strHelp opts
     ++ maybe "" (const "</fc>") (cHelp opts)
 
-formatSwitch :: VolumeOpts -> Bool -> Monitor String
-formatSwitch opts True = switchHelper opts onColor onString
-formatSwitch opts False = switchHelper opts offColor offString
+formatSwitch :: VolumeOpts -> Bool -> VolumeStatus -> Monitor String
+formatSwitch opts True vs = switchHelper opts onColor onString vs
+formatSwitch opts False _  = switchHelper opts offColor offString VolOff
+
+-- | Convert the current volume status into user defined strings
+volHelper :: VolumeStatus -> VolumeOpts -> String
+volHelper volStatus opts =
+    case volStatus of
+        VolHigh -> highString opts
+        VolMedium -> mediumString opts
+        VolLow -> lowString opts
+        VolOff -> ""
 
 colorHelper :: Maybe String -> String
 colorHelper = maybe "" (\c -> "<fc=" ++ c ++ ">")
@@ -138,7 +183,11 @@
     b <- liftMonitor $ liftM3 formatVolBar lo hi val
     v <- liftMonitor $ liftM3 formatVolVBar lo hi val
     d <- getFormatDB opts db
-    s <- getFormatSwitch opts sw
+    let volStat = liftA3 getVolStatus
+                         (lowVolThresh opts)
+                         (highVolThresh opts)
+                         (liftA3 percent val lo hi) -- current volume in %
+    s <- getFormatSwitch opts sw volStat
     ipat <- liftMonitor $ liftM3 (formatVolDStr $ volumeIconPattern opts) lo 
hi val
     parseTemplate [p, b, v, d, s, ipat]
 
@@ -191,8 +240,9 @@
     getFormatDB _ Nothing = unavailable
     getFormatDB opts' (Just d) = formatDb opts' d
 
-    getFormatSwitch :: VolumeOpts -> Maybe Bool -> Monitor String
-    getFormatSwitch _ Nothing = unavailable
-    getFormatSwitch opts' (Just sw) = formatSwitch opts' sw
+    getFormatSwitch :: VolumeOpts -> Maybe Bool -> Maybe VolumeStatus -> 
Monitor String
+    getFormatSwitch _ Nothing _ = unavailable
+    getFormatSwitch _ _ Nothing = unavailable
+    getFormatSwitch opts' (Just sw) (Just vs) = formatSwitch opts' sw vs
 
     unavailable = getConfigValue naString
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmobar-0.30/xmobar.cabal new/xmobar-0.32/xmobar.cabal
--- old/xmobar-0.30/xmobar.cabal        2019-08-23 03:23:28.000000000 +0200
+++ new/xmobar-0.32/xmobar.cabal        2019-11-14 01:08:47.000000000 +0100
@@ -1,5 +1,5 @@
 name:               xmobar
-version:            0.30
+version:            0.32
 homepage:           http://xmobar.org
 synopsis:           A Minimalistic Text Based Status Bar
 description:       Xmobar is a minimalistic text based status bar.
@@ -159,7 +159,7 @@
     ghc-options: -funbox-strict-fields -Wall -fno-warn-unused-do-bind
 
     build-depends:
-      base >= 4.9.1.0 && < 4.13,
+      base >= 4.9.1.0 && < 4.14,
       containers,
       regex-compat,
       process,
@@ -215,7 +215,7 @@
        cpp-options: -DIWLIB
 
     if flag(with_mpd) || flag(all_extensions)
-       build-depends: libmpd >= 0.9.0.6
+       build-depends: libmpd >= 0.9.0.10
        exposed-modules: Xmobar.Plugins.Monitors.MPD
        cpp-options: -DLIBMPD
 


Reply via email to