windowManager.xmonad: Make it configurable and extensible.

PR #1366
The previous windowManager.xmonad option only starts xmonad and
doesn't make ghc available. This assumes that the user has GHC with
access to the xmonad package in his PATH when using xmonad.

Xmonad in Nix is now patched to accept the XMONAD_{GHC,XMESSAGE}
environment variables which define the path to either ghc or xmessage.
These are set automatically when using xmonad through
windowManager.xmonad.

My (or specific: @aristidb and my) changes make it possible to use
Xmonad without adding GHC to any profile. This is useful if you want
to add a different GHC to your profile.

This commit introduces some options:

- xmonad.haskellPackages: Controls which Haskell package set & GHC set
  is used to (re)build Xmonad

- xmonad.extraPackages: Function returning a list of additional
  packages to make available to GHC when rebuilding Xmonad

- xmonad.enableContribExtras: Boolean option to build xmonadContrib
  and xmonadExtras.

Signed-off-by: Moritz Ulrich <moritz@tarn-vedra.de>
This commit is contained in:
Moritz Ulrich 2013-12-12 22:33:51 +01:00 committed by Vladimír Čunát
parent 5331088ba1
commit 5890215501
3 changed files with 97 additions and 8 deletions

View File

@ -1,10 +1,14 @@
{pkgs, config, ...}: {pkgs, config, ...}:
let let
inherit (pkgs.lib) mkOption mkIf; inherit (pkgs.lib) mkOption mkIf optionals literalExample;
cfg = config.services.xserver.windowManager.xmonad; cfg = config.services.xserver.windowManager.xmonad;
xmonadEnv = cfg.haskellPackages.ghcWithPackages(self: [
self.xmonad
] ++ optionals cfg.enableContribAndExtras [ self.xmonadContrib self.xmonadExtras]
++ optionals (cfg.extraPackages != null) (cfg.extraPackages self));
xmessage = pkgs.xlibs.xmessage;
in in
{ {
options = { options = {
services.xserver.windowManager.xmonad = { services.xserver.windowManager.xmonad = {
@ -13,18 +17,53 @@ in
example = true; example = true;
description = "Enable the xmonad window manager."; description = "Enable the xmonad window manager.";
}; };
haskellPackages = mkOption {
default = pkgs.haskellPackages;
defaultText = "pkgs.haskellPackages";
example = literalExample "pkgs.haskellPackages_ghc701";
description = ''
haskellPackages used to build Xmonad and other packages.
This can be used to change the GHC version used to build
Xmonad and the packages listed in
<varname>extraPackages</varname>.
'';
};
extraPackages = mkOption {
default = null;
example = literalExample ''
haskellPackages: [
haskellPackages.xmonadContrib
haskellPackages.monadLogger
]
'';
description = ''
Extra packages available to ghc when rebuilding Xmonad. The
value must be a function which receives the attrset defined
in <varname>haskellpackages</varname> as the sole argument.
'';
};
enableContribAndExtras = mkOption {
default = false;
example = true;
type = pkgs.lib.types.bool;
description = "Enable xmonad-{contrib,extras} in Xmonad.";
};
}; };
}; };
config = mkIf cfg.enable {
config = {
services.xserver.windowManager = { services.xserver.windowManager = {
session = mkIf cfg.enable [{ session = [{
name = "xmonad"; name = "xmonad";
start = " start = ''
${pkgs.haskellPackages.xmonad}/bin/xmonad & XMONAD_GHC=${xmonadEnv}/bin/ghc XMONAD_XMESSAGE=${xmessage}/bin/xmessage xmonad &
waitPID=$! waitPID=$!
"; '';
}]; }];
}; };
environment.systemPackages = [ cfg.haskellPackages.xmonad ];
}; };
} }

View File

@ -13,6 +13,12 @@ cabal.mkDerivation (self: {
mkdir -p $out/share/man/man1 mkdir -p $out/share/man/man1
mv $out/share/xmonad-*/man/*.1 $out/share/man/man1/ mv $out/share/xmonad-*/man/*.1 $out/share/man/man1/
''; '';
patches = [
# Patch to make xmonad use XMONAD_{GHC,XMESSAGE} (if available).
./xmonad_ghc_var_0.11.patch
];
meta = { meta = {
homepage = "http://xmonad.org"; homepage = "http://xmonad.org";
description = "A tiling window manager"; description = "A tiling window manager";

View File

@ -0,0 +1,44 @@
--- xmonad-0.11/XMonad/Core.hs 2013-01-01 01:31:47.000000000 +0000
+++ new-xmonad/XMonad/Core.hs 2013-12-23 17:36:40.862146910 +0000
@@ -47,6 +47,7 @@
import System.Process
import System.Directory
import System.Exit
+import System.Environment (lookupEnv)
import Graphics.X11.Xlib
import Graphics.X11.Xlib.Extras (Event)
import Data.Typeable
@@ -452,6 +453,7 @@
err = base ++ ".errors"
src = base ++ ".hs"
lib = dir </> "lib"
+ ghc <- fromMaybe "ghc" <$> liftIO (lookupEnv "XMONAD_GHC")
libTs <- mapM getModTime . Prelude.filter isSource =<< allFiles lib
srcT <- getModTime src
binT <- getModTime bin
@@ -460,7 +462,7 @@
-- temporarily disable SIGCHLD ignoring:
uninstallSignalHandlers
status <- bracket (openFile err WriteMode) hClose $ \h ->
- waitForProcess =<< runProcess "ghc" ["--make", "xmonad.hs", "-i", "-ilib", "-fforce-recomp", "-v0", "-o",binn] (Just dir)
+ waitForProcess =<< runProcess ghc ["--make", "xmonad.hs", "-i", "-ilib", "-fforce-recomp", "-v0", "-o",binn] (Just dir)
Nothing Nothing Nothing (Just h)
-- re-enable SIGCHLD:
@@ -469,6 +471,7 @@
-- now, if it fails, run xmessage to let the user know:
when (status /= ExitSuccess) $ do
ghcErr <- readFile err
+ xmessage <- fromMaybe "xmessage" <$> liftIO (lookupEnv "XMONAD_XMESSAGE")
let msg = unlines $
["Error detected while loading xmonad configuration file: " ++ src]
++ lines (if null ghcErr then show status else ghcErr)
@@ -476,7 +479,7 @@
-- nb, the ordering of printing, then forking, is crucial due to
-- lazy evaluation
hPutStrLn stderr msg
- forkProcess $ executeFile "xmessage" True ["-default", "okay", msg] Nothing
+ forkProcess $ executeFile xmessage True ["-default", "okay", msg] Nothing
return ()
return (status == ExitSuccess)
else return True