about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorLassulus <github@lassul.us>2022-01-20 11:27:13 +0100
committerGitHub <noreply@github.com>2022-01-20 11:27:13 +0100
commit634bcb85e226054a3b225fdb125b0a235fa94771 (patch)
treebd53749763b827c59ac4f09bcb2fc5e495c40ee5 /nixos
parent0185def7178b3df3e134afffbbd3f21676074f33 (diff)
parent44af29e6f5d8ca7d27ff951a52615ae238c27ccb (diff)
downloadnixlib-634bcb85e226054a3b225fdb125b0a235fa94771.tar
nixlib-634bcb85e226054a3b225fdb125b0a235fa94771.tar.gz
nixlib-634bcb85e226054a3b225fdb125b0a235fa94771.tar.bz2
nixlib-634bcb85e226054a3b225fdb125b0a235fa94771.tar.lz
nixlib-634bcb85e226054a3b225fdb125b0a235fa94771.tar.xz
nixlib-634bcb85e226054a3b225fdb125b0a235fa94771.tar.zst
nixlib-634bcb85e226054a3b225fdb125b0a235fa94771.zip
Merge pull request #155478 from ivanbrennan/xmonad-enable-configured-recompile
XMonad: enable configured recompile
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/services/x11/window-managers/xmonad.nix57
-rw-r--r--nixos/tests/xmonad.nix100
2 files changed, 130 insertions, 27 deletions
diff --git a/nixos/modules/services/x11/window-managers/xmonad.nix b/nixos/modules/services/x11/window-managers/xmonad.nix
index ecad411ff683..68f97c2f504b 100644
--- a/nixos/modules/services/x11/window-managers/xmonad.nix
+++ b/nixos/modules/services/x11/window-managers/xmonad.nix
@@ -2,7 +2,7 @@
 
 with lib;
 let
-  inherit (lib) mkOption mkIf optionals literalExpression;
+  inherit (lib) mkOption mkIf optionals literalExpression optionalString;
   cfg = config.services.xserver.windowManager.xmonad;
 
   ghcWithPackages = cfg.haskellPackages.ghcWithPackages;
@@ -26,11 +26,14 @@ let
     in
       pkgs.runCommandLocal "xmonad" {
         nativeBuildInputs = [ pkgs.makeWrapper ];
-      } ''
+      } (''
         install -D ${xmonadEnv}/share/man/man1/xmonad.1.gz $out/share/man/man1/xmonad.1.gz
         makeWrapper ${configured}/bin/xmonad $out/bin/xmonad \
+      '' + optionalString cfg.enableConfiguredRecompile ''
+          --set NIX_GHC "${xmonadEnv}/bin/ghc" \
+      '' + ''
           --set XMONAD_XMESSAGE "${pkgs.xorg.xmessage}/bin/xmessage"
-      '';
+      '');
 
   xmonad = if (cfg.config != null) then xmonad-config else xmonad-vanilla;
 in {
@@ -95,12 +98,14 @@ in {
           xmonad from PATH. This allows e.g. switching to the new xmonad binary
           after rebuilding your system with nixos-rebuild.
           For the same reason, ghc is not added to the environment when this
-          option is set.
+          option is set, unless <option>enableConfiguredRecompile</option> is
+          set to <literal>true</literal>.
 
           If you actually want to run xmonad with a config specified here, but
           also be able to recompile and restart it from a copy of that source in
-          $HOME/.xmonad on the fly, you will have to implement that yourself
-          using something like "compileRestart" from the example.
+          $HOME/.xmonad on the fly, set <option>enableConfiguredRecompile</option>
+          to <literal>true</literal> and implement something like "compileRestart"
+          from the example.
           This should allow you to switch at will between the local xmonad and
           the one NixOS puts in your PATH.
         '';
@@ -116,6 +121,29 @@ in {
 
           compiledConfig = printf "xmonad-%s-%s" arch os
 
+          myConfig = defaultConfig
+            { modMask = mod4Mask -- Use Super instead of Alt
+            , terminal = "urxvt" }
+            `additionalKeys`
+            [ ( (mod4Mask,xK_r), compileRestart True)
+            , ( (mod4Mask,xK_q), restart "xmonad" True ) ]
+
+          --------------------------------------------
+          {- version 0.17.0 -}
+          --------------------------------------------
+          -- compileRestart resume =
+          --   dirs <- io getDirectories
+          --   whenX (recompile dirs True) $
+          --     when resume writeStateToFile
+          --       *> catchIO
+          --         ( do
+          --             args <- getArgs
+          --             executeFile (cacheDir dirs </> compiledConfig) False args Nothing
+          --         )
+          --
+          -- main = getDirectories >>= launch myConfig
+          --------------------------------------------
+
           compileRestart resume =
             whenX (recompile True) $
               when resume writeStateToFile
@@ -126,12 +154,17 @@ in {
                       executeFile (dir </> compiledConfig) False args Nothing
                   )
 
-          main = launch defaultConfig
-              { modMask = mod4Mask -- Use Super instead of Alt
-              , terminal = "urxvt" }
-              `additionalKeys`
-              [ ( (mod4Mask,xK_r), compileRestart True)
-              , ( (mod4Mask,xK_q), restart "xmonad" True ) ]
+          main = launch myConfig
+        '';
+      };
+
+      enableConfiguredRecompile = mkOption {
+        default = false;
+        type = lib.types.bool;
+        description = ''
+          Enable recompilation even if <option>config</option> is set to a
+          non-null value. This adds the necessary Haskell dependencies (GHC with
+          packages) to the xmonad binary's environment.
         '';
       };
 
diff --git a/nixos/tests/xmonad.nix b/nixos/tests/xmonad.nix
index 078cd2118107..a14d4b819eb6 100644
--- a/nixos/tests/xmonad.nix
+++ b/nixos/tests/xmonad.nix
@@ -1,4 +1,55 @@
-import ./make-test-python.nix ({ pkgs, ...} : {
+import ./make-test-python.nix ({ pkgs, ...}:
+
+let
+  mkConfig = name: keys: ''
+    import XMonad
+    import XMonad.Operations (restart)
+    import XMonad.Util.EZConfig
+    import XMonad.Util.SessionStart
+    import Control.Monad (when)
+    import Text.Printf (printf)
+    import System.Posix.Process (executeFile)
+    import System.Info (arch,os)
+    import System.Environment (getArgs)
+    import System.FilePath ((</>))
+
+    main = launch $ def { startupHook = startup } `additionalKeysP` myKeys
+
+    startup = isSessionStart >>= \sessInit ->
+      spawn "touch /tmp/${name}"
+        >> if sessInit then setSessionStarted else spawn "xterm"
+
+    myKeys = [${builtins.concatStringsSep ", " keys}]
+
+    compiledConfig = printf "xmonad-%s-%s" arch os
+
+    compileRestart resume =
+      whenX (recompile True) $
+        when resume writeStateToFile
+          *> catchIO
+            ( do
+                dir <- getXMonadDataDir
+                args <- getArgs
+                executeFile (dir </> compiledConfig) False args Nothing
+            )
+  '';
+
+  oldKeys =
+    [ ''("M-C-x", spawn "xterm")''
+      ''("M-q", restart "xmonad" True)''
+      ''("M-C-q", compileRestart True)''
+      ''("M-C-t", spawn "touch /tmp/somefile")'' # create somefile
+    ];
+
+  newKeys =
+    [ ''("M-C-x", spawn "xterm")''
+      ''("M-q", restart "xmonad" True)''
+      ''("M-C-q", compileRestart True)''
+      ''("M-C-r", spawn "rm /tmp/somefile")'' # delete somefile
+    ];
+
+  newConfig = pkgs.writeText "xmonad.hs" (mkConfig "newXMonad" newKeys);
+in {
   name = "xmonad";
   meta = with pkgs.lib.maintainers; {
     maintainers = [ nequissimus ];
@@ -10,21 +61,10 @@ import ./make-test-python.nix ({ pkgs, ...} : {
     services.xserver.displayManager.defaultSession = "none+xmonad";
     services.xserver.windowManager.xmonad = {
       enable = true;
+      enableConfiguredRecompile = true;
       enableContribAndExtras = true;
       extraPackages = with pkgs.haskellPackages; haskellPackages: [ xmobar ];
-      config = ''
-        import XMonad
-        import XMonad.Operations (restart)
-        import XMonad.Util.EZConfig
-        import XMonad.Util.SessionStart
-
-        main = launch $ def { startupHook = startup } `additionalKeysP` myKeys
-
-        startup = isSessionStart >>= \sessInit ->
-          if sessInit then setSessionStarted else spawn "xterm"
-
-        myKeys = [ ("M-C-x", spawn "xterm"), ("M-q", restart "xmonad" True) ]
-      '';
+      config = mkConfig "oldXMonad" oldKeys;
     };
   };
 
@@ -38,10 +78,40 @@ import ./make-test-python.nix ({ pkgs, ...} : {
     machine.wait_for_window("${user.name}.*machine")
     machine.sleep(1)
     machine.screenshot("terminal1")
+    machine.succeed("rm /tmp/oldXMonad")
     machine.send_key("alt-q")
-    machine.sleep(3)
+    machine.wait_for_file("/tmp/oldXMonad")
     machine.wait_for_window("${user.name}.*machine")
     machine.sleep(1)
     machine.screenshot("terminal2")
+
+    # /tmp/somefile should not exist yet
+    machine.fail("stat /tmp/somefile")
+
+    # original config has a keybinding that creates somefile
+    machine.send_key("alt-ctrl-t")
+    machine.sleep(1)
+    machine.succeed("stat /tmp/somefile")
+
+    # set up the new config
+    machine.succeed("mkdir -p ${user.home}/.xmonad")
+    machine.copy_from_host("${newConfig}", "${user.home}/.xmonad/xmonad.hs")
+
+    # recompile xmonad using the new config
+    machine.send_key("alt-ctrl-q")
+    machine.wait_for_file("/tmp/newXMonad")
+
+    # new config has a keybinding that deletes somefile
+    machine.send_key("alt-ctrl-r")
+    machine.sleep(1)
+    machine.fail("stat /tmp/somefile")
+
+    # restart with the old config, and confirm the old keybinding is back
+    machine.succeed("rm /tmp/oldXMonad")
+    machine.send_key("alt-q")
+    machine.wait_for_file("/tmp/oldXMonad")
+    machine.send_key("alt-ctrl-t")
+    machine.sleep(1)
+    machine.succeed("stat /tmp/somefile")
   '';
 })