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