nixpkgs/nixos
Ivan b90c5cb703
XMonad: configured recompile (#107696)
* nixos/xmonad: xmonad config w/ghc+xmessage

When the "config" option isn't set, we use xmonad-with-packages to
provide xmonad with runtime access to an isolated ghc, ensuring it can
recompile and exec a user's local config (e.g. $HOME/.xmonad/xmonad.hs)
regardless of which ghc (if any) is on PATH.

When the "config" option is set, however, we compile a configured xmonad
executable upfront (during nixos-rebuild), and prior to this commit, it
was not provided with runtime access to an isolated ghc.

As a result, with the "config" option set, it was not possible
to recompile and exec a user's local config unless there was a
compatible version of ghc on PATH with the necessary packages (xmonad,
xmonad-contrib, etc.) in its package database. Adding such a ghc to
environment.systemPackages, e.g.

  (haskellPackages.ghcWithPackages (ps: with ps; [xmonad xmonad-contrib]))

is problematic because it adds both ghc and an unconfigured xmonad to
PATH, e.g.

  $ ls -l $(which xmonad ghc)
  lrwxrwxrwx ... /run/current-system/sw/bin/ghc -> /nix/store/...-ghc-8.10.2-with-packages/bin/ghc
  lrwxrwxrwx ... /run/current-system/sw/bin/xmonad -> /nix/store/...-ghc-8.10.2-with-packages/bin/xmonad

Having the unconfigured xmonad on PATH is particularly bad because
restarting xmonad will dump the user into the unconfigured version, and
if no local config exists (e.g. in $HOME/.xmonad/xmonad.hs), they'll be
left in this unconfigured state.

In this commmit, we give the configured xmonad runtime access to ghc
like xmonad-with-packages does for the unconfigured version. The aim
is to allow the user to switch between the nixos module's config and a
local config (e.g. $HOME/.xmonad/xmonad.hs) at will, so they can try out
config changes without performing a nixos-rebuild.

Since the xmonad on PATH is the configured executable, there's no
danger a user could unwittingly restart into the unconfigured version,
and because xmonad will refuse to recompile when no local config
exists, there's no danger a user could unwittingly recompile into an
unconfigured version.

Given that a local config exists, the recompile/restart behavior depends
on two factors:
- which entry point is used
  * 'XMonad.xmonad' (default)
  * 'XMonad.launch' (recommended in "config" option description)
- what operation is triggered (i.e. via mod+q)
  * `spawn "xmonad --recompile && xmonad --restart"` (default)
  * `restart "xmonad" True`
  * custom function

If the default 'XMonad.xmonad' entrypoint and default mod+q operation
are used, hitting mod+q will compile and exec the local config, which
will remain in use until next time the display manager is restarted.

If the entrypoint is changed to 'XMonad.launch' but mod+q left with its
default operation, hitting mod+q will have no visible effect. The logs
(as seen by running `journalctl --identifier xmonad --follow`) will show
an error,
  X Error of failed request:  BadAccess (attempt to access private resource denied)
which indicates that the shell was unable to start xmonad because
another window manager is already running (namely, the nixos-configured
xmonad).
https://wiki.haskell.org/Xmonad/Frequently_asked_questions#X_Error_of_failed_request:_BadAccess_.28attempt_to_access_private_resource_denied.29

Changing the mod+q operation to `restart "xmonad" True` (as recommended
in the "config" option's description) will allow a restart of the
nixos-configured xmonad to be triggeredy by hitting mod+q.

Finally, if the entrypoint is 'XMonad.launch', mod+q has been
bound to `restart "xmonad" True` and another key bound to a custom
recompile/restart function (e.g. `compileRestart` as shown in the
"config" option example), the user can switch between the nixos module's
config and their local config, with the custom key switching to the
local config and mod+q switching back.

* nixos/xmonad: refactor let binding

* nixos/xmonad: refactor (eliminate duplicate code)

* nixos/xmonad: install man pages

Prior to this commit, man pages were not installed if the "config"
option was set.

* nixos/xmonad: comment grammar fixups

* nixos/xmonad: writeStateToFile in example config

Calling writeStateToFile prior to recompiling and restarting allows
state (workspaces, etc.) to be preserved across the restart.

* nixos/xmonad: add ivanbrennan to maintainers

* nixos/xmonad: adjust compileRestart example

* nixos/xmonad: add missing import to example config
2020-12-28 17:27:36 +01:00
..
doc nixos/doc: add note about codimd -> hedgedoc to release notes 2020-12-22 01:39:03 +01:00
lib Merge pull request #104292 from fgaz/image-contents 2020-12-21 19:58:49 +01:00
maintainers Merge pull request #102174 from grahamc/ami-root-use-gpt 2020-10-30 16:14:37 -04:00
modules XMonad: configured recompile (#107696) 2020-12-28 17:27:36 +01:00
tests nixos/tests/loki: satisfy linter 2020-12-28 00:37:13 +01:00
COPYING
default.nix
README
release-combined.nix release-combined: Add shadow test 2020-12-23 13:28:52 -05:00
release-small.nix Merge pull request #104322 from grahamc/amazon-image 2020-11-19 18:45:07 -05:00
release.nix

*** NixOS ***

NixOS is a Linux distribution based on the purely functional package
management system Nix.  More information can be found at
https://nixos.org/nixos and in the manual in doc/manual.