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`.
Since we now have an "internal" parser library in xmonad, use it. This
allows us to get rid of some hacks in this module that were needed
because of ReadP's parsing behaviour.
This module provides a parser combinator library based on base's ReadP,
which aims to function more like other popular combinator libraries like
attoparsec and megaparsec.
In particular, the Alternative and Monoid instances are left-biased now,
so combinators like `many` and `optional` from Control.Applicative work
in a more intuitive manner. Further, some functions (like `endBy1`)
only return the "most successful" parse, instead of returning all of
them. We can now get away with providing a single parsing result
instead of ReadP's list of results (as such, parsers need to be
disambiguated earlier instead of trimming the list down after parsing).
This adds basic font-fallback support for X.U.Font, as well as modules
using it, like X.Prompt and X.A.TreeSelect.
In the new system, multiple fonts may be specified with the syntax
"xft:iosevka-11,FontAwesome-9"
Fixes: https://github.com/xmonad/xmonad-contrib/issues/208
Instead of searching for the currently focused window across workspaces,
make it so there is never any window above focus on the Stack that is
given to the modified layout.
Closes#657.
The XS.modify was leaving thunk on the history that the demand analyser
could not prove to be neccesary as they depended on the future user
interaction. This was bad as the time advance there was less and less
neccesity to force such value, so the thunk would be increasing. Since the
datatypes that the `WorkspaceHistory` are really simple, we can just
evaluate and save a good chunk of memory.
updateHistory leaks unfiltered windows from previous states as it is never
forced. The consumer of such data structure is not visible to ghc, so the
demand analysis has to fallback on pure laziness.
We fix this inserting evaluation points on the `historyHook` function. We do
this for two reasons, this is the only function calling `updateHistory`.
Plus we cannot do it clearly at the `updateHistory` function as we operate
inside a continuation on withWindowSet. In respect to the `put`, everything
would be a big thunk.
Update left and right navigation to behave correctly even if the
currently saved position is directly on the edge of the focused window.
This makes the L/R behavior consistent with U/D navigation.
How to reproduce the issue on a 16:9 resolution like 1920x1080:
- configure Grid layout;
- open 4 terminals;
- navigate to the top-right terminal;
- open another terminal;
- immediately close it;
- try navigating left from the currently focused top-right terminal;
- observe navigation being "stuck".
The documentation for this module was lacking, making it significantly
harder to use than the functionality wise very similar
X.A.CycleRecentWS—change that.
This changes how the "is*Of" infix operators are hoisted into the
ManageHook context. Instead of `q ~? x` being a lifted version of
`isPrefixOf q x` we instead let it be a lift of `isPrefixOf x q`.
While this obviously does not matter for symmetric operators like `(==)`
and `(/=)`, for `isInfixOf` it is rather essential. The reason for that
is that the given `q` on the left side is an atom that can't (shouldn't)
be changed (by the user) and we only have control over the right hand
side. Otherwise, things like
title ~? "foo"
would read "only match if `title` is an infix of `foo`" instead of the
much more useful "only match if `foo` is an infix of `title`".
Fixes: 8b6f17ba66
Whenever possible, prefer the safe wrappers withWindowAttributes or
safeGetWindowAttributes to getWindowAttributes.
Places where these are not applicable are limited to layouts, where
there is not good "default value" to give back in case these calls fail.
In these cases, we let the exception handling of the layout mechanism
handle it and fall back to the Full layout.
Fixes: https://github.com/xmonad/xmonad-contrib/issues/146
Move the function from X.U.DebugWindow, where it was defined already.
This is a safe version of getWindowAttributes, returning a Maybe instead
of throwing an exception, in case the window attributes could not be
retrieved.
This file was obviously copied from `DwmStyle`, and the author missed changing that
out to `simpleDeco` in one place. Just patching in place since it's a one-word change.
Instead of telling the user how to add custom keybindings to
xmonad—something which is already done in the tutorial—instead explain
instead how one would go about writing a version of
X.U.EZConfig.additionalKeys. This mostly involves looking at the type
signatures and sticking some standard functions together, so it's quite
a decent way to learn about some of xmonad's internals.
During the release of xmonad 0.17.0, I realized that we need to be able
to upload candidates before tagging the release on GitHub, because there
might be issues with the tarball and Hackage may reject it. When that
happened, I had to remove the release, delete the tag, upload the
candidate manually to see what's wrong with it, try to fix it, upload it
manually again, and so on.
This commit swaps the logic: when the workflow is invoked manually, it
uploads the candidate. This can be done multiple times, and once
everything is fine, the release can finally be tagged and it's released
to Hackage proper. The only disadvantage is that we need to remember to
try uploading the candidate. Not sure if there's a perfect solution…
It no longer does what it was intended to do, and in fact, now does the
opposite.
When X.A.Search came to be in ~2007, Google's default of showing 10 or
so search hits was radically inadequate for poweruser needs. The 'num'
argument was used to force display of more hits (i.e., n meant 'display
at least n hits per page').
However, at some point, 'num' was inverted to mean something
catastrophically different: now it apparently means 'display no more
than n hits, total'. If you use that parameter, you will get 1 or 2
pages of hits at most reading 'About 98 results' or 'About 99
results' (no matter how many millions are available), and a blurb at the
bottom of the final page saying 'In order to show you the most relevant
results, we have omitted some entries very similar to the 99 already
displayed.' Removing the 'num' parameter then shows you all the hits
that were suppressed.
This is bad, and should be removed.
Fixes: https://github.com/xmonad/xmonad-contrib/issues/642
Co-authored-by: Gwern Branwen <gwern@gwern.net>
ConfigureEvents may occur after a window has been deleted, an UnmapEvent
has already been sent (and thus xmonad already unmanaged the window),
but before a DestroyWindowEvent is caught by the eventHook. For
example, this is the case when one uses smartBorders with a single
window (such that smartBorders is "active"). The ConfigureEvents
sensibly already have an empty stack (because the UnmapEvent has already
been received), which we then copy to the history.
Whenever a parent window has been found, the sensible thing to do is to
always restore it. The fact that oldStack is Nothing simply encodes an
empty workspace and is thus something we definitely need to handle as
well.
Fixes: https://github.com/xmonad/xmonad-contrib/issues/638
In [1] we changed the return type to not be an IO action and hence this
example can't work, even with an otherwise correct configuration.
[1]: 168cb6a6c3 (Removed unnecessary IO)