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]: 8abeb81fd0
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.
Using X.U.Parser works almost as a drop-in replacement for ReadP here.
In some places (like `parseSpecial`) we need to be a little bit more
careful when constructing the parser, but this is offset a much simpler
`readKeySequence`.
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`.
We're not parsing anything (as opposed to the respective `P` functions)
and so there's no need to create a dummy map with units as values and
then take the difference; we can simply remove the relevant keys from
the map.
Now, instead of writing out incredibly dull things like
((modMask conf .|. controlMask .|. shiftMask, xK_F2), ...)
you can just write
("M-C-S-<F2>", ...)
Hooray!
Looking for suggestions on this module. Does it belong here? Is there a better
name? Should the additional* functions pass the modMask to their second
argument? etc.