Add the trivial Arbitrary instance for Priority, extend the Arbitrary
instance of OrgMsg, as well as some plumbing. Also work in some unit
tests for regression testing.
Adds property tests in both directions for the parser in X.U.EZConfig.
As with the tests for X.P.OrgMode, these (modulo `Maybe` noise) take the
shape of the operation of an inverse semigroup:
pp ∘ p ∘ pp ≡ pp and p ∘ pp ∘ p = p,
where pp is pretty-printing and p is parsing.
When users specify non-existent keys, it seems most intuitive to just
abort the parse and not try to take the "longest" input that still
works. For example, given the "key" `M-10` we should signal a parse
error (by returning `Nothing`) instead of parsing `M-1` and ignoring
the rest of the input. The old EZConfig parser accounted for this but
when the module was rewritten to use X.U.Parser in [1], this was
forgotten about.
Fixes: https://github.com/xmonad/xmonad/issues/361
[1]: 8abeb81fd0693bd4ee914b522c0a2a2cfcfaf0dd
Ever since [1] we allow a second representation for the month (namely,
the numerical one). Since we lose this information during parsing,
pretty printing is now not a proper postinverse of parsing (it still is
a proper preinverse, however).
Thus, we can't simply check for an inverse anymore. However, the
operations still form an inverse semigroup [2], which is something
that's easily checkable. For simplicity, do this in both directions and
completely forget about linearity for now.
[1]: 91f1a0de1e4a536e6c81a3de96e566622b3eb20a (Fix date parsing issue
for org mode plugin)
[2]: https://en.wikipedia.org/wiki/Inverse_semigroup
This patch fixes the date parsing issue currently when an entry like
`todo +d 22 01 2022` is used. I have added tests too which demonstrate
the current issue so that we can prevent future regression.
Add very basic unit tests for EZConfig to see if it can parse all of the
keys (and key combinations) that it promises to parse.
The long-term goal here should be to write a pretty-printer for EZConfig
and to check whether that's a proper inverse (either in the normal sense
or in the inverse semigroup sense), as the tests for X.P.OrgMode do.
For configuration values that don't compose well using a Semigroup
instance, provide a high-level API allowing arbitrary modification of
the value, taking its Default if absent. This API is only usable for
separate configuration data and cannot be used to guard addition of hook
using `once`.
Due to differences between random-1.1 and random-1.2, on newer systems
stringToRatio returns numbers outside [0, 1] range, which breaks
colorRangeFromClassName colorizers.
This commit fixes the issue by using randomR to directly generate the random number.
Also this fixes the compilation warning (genRange and next are deprecated in random-1.2).
This appears to be more natural. The function will most often be fixed
by the module using `XC.once` and the configuration will often be
supplied by users of those modules, so it's better to partially apply
the function first.
Entirely unnecessary for the current version of `cycleWindowSets`, but
if anyone ever wants to use `greedyView`, this shows that it's not at
all complicated to adapt `unView` to that.
To make this more "obviously correct", make it resemble the `view`
implementation, just do the exact reverse. Now the only complex bit is
the "undelete" operation.
This also fixes another issue: state was only preserved in the focused
workspace, but it may have changed in another visible workspace as well.
The property test is updated to test this.
It's often difficult to make contrib modules work together. When one
depends on a functionality of another, it is often necessary to expose
lots of low-level functions and hooks and have the user combine these
into a complex configuration that works. This is error-prone, and
arguably a bad UX in general.
This commit presents a simple solution to that problem inspired by
"extensible state": extensible config. It allows contrib modules to
store custom configuration values inside XConfig. This lets them create
custom hooks, ensure they hook into xmonad core only once, and possibly
other use cases I haven't thought of yet.
This requires changes to xmonad core: https://github.com/xmonad/xmonad/pull/294
A couple examples of what this gives us:
* [X.H.RescreenHook](https://github.com/xmonad/xmonad-contrib/pull/460)
can be made safe to apply multiple times, making it composable and
usable in other contrib modules like X.H.StatusBar
* `withSB` from X.H.StatusBar can also be made safe to apply multiple
times, and we can even provide an API [similar to what we had
before](https://hackage.haskell.org/package/xmonad-contrib-0.16/docs/XMonad-Hooks-DynamicLog.html#v:statusBar)
if we want (probably not, consistency with the new dynamic status bars
of https://github.com/xmonad/xmonad-contrib/pull/463 is more important)
* The [X.H.EwmhDesktops refactor](https://github.com/xmonad/xmonad-contrib/pull/399)
can possibly be made without breaking the `ewmh`/`ewmhFullscreen` API.
And we will finally be able to have composable EWMH hooks.
Related: https://github.com/xmonad/xmonad/pull/294
This is a convenience module in order to have less import noise. It
re-exports the following:
a) Commonly used modules in full (Data.Foldable, Data.Applicative, and
so on); though only those that play nicely with each other, so that
XMonad.Prelude can be imported unqualified without any problems.
This prevents things like `Prelude.(.)` and `Control.Category.(.)`
fighting with each other.
b) Helper functions that don't necessarily fit in any other module;
e.g., the often used abbreviation `fi = fromIntegral`.
My main motivation here is that I'd like to add some unit tests (as
opposed to testing everything using QuickCheck properties), but there
are other benefits: it's now easier to run a subset of tests -- the
command-line interface is more powerful.
Also, rename the test-suite to "tests" as it's no longer limited to
properties.
Verify that rotateSome behaves as expected and never fails to pattern
match.
In order to run these tests, I ran a custom script:
scripts/run-tests.sh tests/RotateSome.hs
where the script contained the following:
set -eu
toplevel=$(git rev-parse --show-toplevel)
XMONAD="${XMONAD:-$toplevel/../xmonad}"
main=$(realpath -e "$1")
instances_target="$XMONAD/tests/Instances.hs"
instances_symlink="$toplevel/tests/Instances.hs"
properties_target="$XMONAD/tests/Properties"
properties_symlink="$toplevel/tests/Properties"
utils_target="$XMONAD/tests/Utils.hs"
utils_symlink="$toplevel/tests/Utils.hs"
trap "
rm '$instances_symlink' '$utils_symlink' '$properties_symlink' || true
" EXIT INT QUIT TERM
ln -s "$instances_target" "$instances_symlink"
ln -s "$properties_target" "$properties_symlink"
ln -s "$utils_target" "$utils_symlink"
runghc -DTESTING \
-i"$toplevel" \
-i"$toplevel/tests" \
"$main"
Now the number of runs each can be set, and the failures and successes are
summarized in the same way as the core Properties.hs. There is some duplicated
code which could be avoided by modifying Properties.hs.