at 21.11-pre 6.1 kB view raw
1{pkgs, lib, config, ...}: 2 3with lib; 4let 5 inherit (lib) mkOption mkIf optionals literalExample; 6 cfg = config.services.xserver.windowManager.xmonad; 7 8 ghcWithPackages = cfg.haskellPackages.ghcWithPackages; 9 packages = self: cfg.extraPackages self ++ 10 optionals cfg.enableContribAndExtras 11 [ self.xmonad-contrib self.xmonad-extras ]; 12 13 xmonad-vanilla = pkgs.xmonad-with-packages.override { 14 inherit ghcWithPackages packages; 15 }; 16 17 xmonad-config = 18 let 19 xmonadAndPackages = self: [ self.xmonad ] ++ packages self; 20 xmonadEnv = ghcWithPackages xmonadAndPackages; 21 configured = pkgs.writers.writeHaskellBin "xmonad" { 22 ghc = cfg.haskellPackages.ghc; 23 libraries = xmonadAndPackages cfg.haskellPackages; 24 inherit (cfg) ghcArgs; 25 } cfg.config; 26 in 27 pkgs.runCommandLocal "xmonad" { 28 nativeBuildInputs = [ pkgs.makeWrapper ]; 29 } '' 30 install -D ${xmonadEnv}/share/man/man1/xmonad.1.gz $out/share/man/man1/xmonad.1.gz 31 makeWrapper ${configured}/bin/xmonad $out/bin/xmonad \ 32 --set NIX_GHC "${xmonadEnv}/bin/ghc" \ 33 --set XMONAD_XMESSAGE "${pkgs.xorg.xmessage}/bin/xmessage" 34 ''; 35 36 xmonad = if (cfg.config != null) then xmonad-config else xmonad-vanilla; 37in { 38 meta.maintainers = with maintainers; [ lassulus xaverdh ivanbrennan ]; 39 40 options = { 41 services.xserver.windowManager.xmonad = { 42 enable = mkEnableOption "xmonad"; 43 haskellPackages = mkOption { 44 default = pkgs.haskellPackages; 45 defaultText = "pkgs.haskellPackages"; 46 example = literalExample "pkgs.haskell.packages.ghc784"; 47 description = '' 48 haskellPackages used to build Xmonad and other packages. 49 This can be used to change the GHC version used to build 50 Xmonad and the packages listed in 51 <varname>extraPackages</varname>. 52 ''; 53 }; 54 55 extraPackages = mkOption { 56 type = types.functionTo (types.listOf types.package); 57 default = self: []; 58 defaultText = "self: []"; 59 example = literalExample '' 60 haskellPackages: [ 61 haskellPackages.xmonad-contrib 62 haskellPackages.monad-logger 63 ] 64 ''; 65 description = '' 66 Extra packages available to ghc when rebuilding Xmonad. The 67 value must be a function which receives the attrset defined 68 in <varname>haskellPackages</varname> as the sole argument. 69 ''; 70 }; 71 72 enableContribAndExtras = mkOption { 73 default = false; 74 type = lib.types.bool; 75 description = "Enable xmonad-{contrib,extras} in Xmonad."; 76 }; 77 78 config = mkOption { 79 default = null; 80 type = with lib.types; nullOr (either path str); 81 description = '' 82 Configuration from which XMonad gets compiled. If no value is 83 specified, a vanilla xmonad binary is put in PATH, which will 84 attempt to recompile and exec your xmonad config from $HOME/.xmonad. 85 This setup is then analogous to other (non-NixOS) linux distributions. 86 87 If you do set this option, you likely want to use "launch" as your 88 entry point for xmonad (as in the example), to avoid xmonad's 89 recompilation logic on startup. Doing so will render the default 90 "mod+q" restart key binding dysfunctional though, because that attempts 91 to call your binary with the "--restart" command line option, unless 92 you implement that yourself. You way mant to bind "mod+q" to 93 <literal>(restart "xmonad" True)</literal> instead, which will just restart 94 xmonad from PATH. This allows e.g. switching to the new xmonad binary 95 after rebuilding your system with nixos-rebuild. 96 97 If you actually want to run xmonad with a config specified here, but 98 also be able to recompile and restart it from a copy of that source in 99 $HOME/.xmonad on the fly, you will have to implement that yourself 100 using something like "compileRestart" from the example. 101 This should allow you to switch at will between the local xmonad and 102 the one NixOS puts in your PATH. 103 ''; 104 example = '' 105 import XMonad 106 import XMonad.Util.EZConfig (additionalKeys) 107 import Control.Monad (when) 108 import Text.Printf (printf) 109 import System.Posix.Process (executeFile) 110 import System.Info (arch,os) 111 import System.Environment (getArgs) 112 import System.FilePath ((</>)) 113 114 compiledConfig = printf "xmonad-%s-%s" arch os 115 116 compileRestart resume = 117 whenX (recompile True) $ 118 when resume writeStateToFile 119 *> catchIO 120 ( do 121 dir <- getXMonadDataDir 122 args <- getArgs 123 executeFile (dir </> compiledConfig) False args Nothing 124 ) 125 126 main = launch defaultConfig 127 { modMask = mod4Mask -- Use Super instead of Alt 128 , terminal = "urxvt" } 129 `additionalKeys` 130 [ ( (mod4Mask,xK_r), compileRestart True) 131 , ( (mod4Mask,xK_q), restart "xmonad" True ) ] 132 ''; 133 }; 134 135 xmonadCliArgs = mkOption { 136 default = []; 137 type = with lib.types; listOf str; 138 description = '' 139 Command line arguments passed to the xmonad binary. 140 ''; 141 }; 142 143 ghcArgs = mkOption { 144 default = []; 145 type = with lib.types; listOf str; 146 description = '' 147 Command line arguments passed to the compiler (ghc) 148 invocation when xmonad.config is set. 149 ''; 150 }; 151 152 }; 153 }; 154 config = mkIf cfg.enable { 155 services.xserver.windowManager = { 156 session = [{ 157 name = "xmonad"; 158 start = '' 159 systemd-cat -t xmonad -- ${xmonad}/bin/xmonad ${lib.escapeShellArgs cfg.xmonadCliArgs} & 160 waitPID=$! 161 ''; 162 }]; 163 }; 164 165 environment.systemPackages = [ xmonad ]; 166 }; 167}