Merge pull request #155478 from ivanbrennan/xmonad-enable-configured-recompile

XMonad: enable configured recompile
This commit is contained in:
Lassulus 2022-01-20 11:27:13 +01:00 committed by GitHub
commit 634bcb85e2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 130 additions and 27 deletions

View file

@ -2,7 +2,7 @@
with lib; with lib;
let let
inherit (lib) mkOption mkIf optionals literalExpression; inherit (lib) mkOption mkIf optionals literalExpression optionalString;
cfg = config.services.xserver.windowManager.xmonad; cfg = config.services.xserver.windowManager.xmonad;
ghcWithPackages = cfg.haskellPackages.ghcWithPackages; ghcWithPackages = cfg.haskellPackages.ghcWithPackages;
@ -26,11 +26,14 @@ let
in in
pkgs.runCommandLocal "xmonad" { pkgs.runCommandLocal "xmonad" {
nativeBuildInputs = [ pkgs.makeWrapper ]; nativeBuildInputs = [ pkgs.makeWrapper ];
} '' } (''
install -D ${xmonadEnv}/share/man/man1/xmonad.1.gz $out/share/man/man1/xmonad.1.gz install -D ${xmonadEnv}/share/man/man1/xmonad.1.gz $out/share/man/man1/xmonad.1.gz
makeWrapper ${configured}/bin/xmonad $out/bin/xmonad \ makeWrapper ${configured}/bin/xmonad $out/bin/xmonad \
'' + optionalString cfg.enableConfiguredRecompile ''
--set NIX_GHC "${xmonadEnv}/bin/ghc" \
'' + ''
--set XMONAD_XMESSAGE "${pkgs.xorg.xmessage}/bin/xmessage" --set XMONAD_XMESSAGE "${pkgs.xorg.xmessage}/bin/xmessage"
''; '');
xmonad = if (cfg.config != null) then xmonad-config else xmonad-vanilla; xmonad = if (cfg.config != null) then xmonad-config else xmonad-vanilla;
in { in {
@ -95,12 +98,14 @@ in {
xmonad from PATH. This allows e.g. switching to the new xmonad binary xmonad from PATH. This allows e.g. switching to the new xmonad binary
after rebuilding your system with nixos-rebuild. after rebuilding your system with nixos-rebuild.
For the same reason, ghc is not added to the environment when this 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 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 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 $HOME/.xmonad on the fly, set <option>enableConfiguredRecompile</option>
using something like "compileRestart" from the example. 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 This should allow you to switch at will between the local xmonad and
the one NixOS puts in your PATH. the one NixOS puts in your PATH.
''; '';
@ -116,6 +121,29 @@ in {
compiledConfig = printf "xmonad-%s-%s" arch os 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 = compileRestart resume =
whenX (recompile True) $ whenX (recompile True) $
when resume writeStateToFile when resume writeStateToFile
@ -126,12 +154,17 @@ in {
executeFile (dir </> compiledConfig) False args Nothing executeFile (dir </> compiledConfig) False args Nothing
) )
main = launch defaultConfig main = launch myConfig
{ modMask = mod4Mask -- Use Super instead of Alt '';
, terminal = "urxvt" } };
`additionalKeys`
[ ( (mod4Mask,xK_r), compileRestart True) enableConfiguredRecompile = mkOption {
, ( (mod4Mask,xK_q), restart "xmonad" True ) ] 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.
''; '';
}; };

View file

@ -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"; name = "xmonad";
meta = with pkgs.lib.maintainers; { meta = with pkgs.lib.maintainers; {
maintainers = [ nequissimus ]; maintainers = [ nequissimus ];
@ -10,21 +61,10 @@ import ./make-test-python.nix ({ pkgs, ...} : {
services.xserver.displayManager.defaultSession = "none+xmonad"; services.xserver.displayManager.defaultSession = "none+xmonad";
services.xserver.windowManager.xmonad = { services.xserver.windowManager.xmonad = {
enable = true; enable = true;
enableConfiguredRecompile = true;
enableContribAndExtras = true; enableContribAndExtras = true;
extraPackages = with pkgs.haskellPackages; haskellPackages: [ xmobar ]; extraPackages = with pkgs.haskellPackages; haskellPackages: [ xmobar ];
config = '' config = mkConfig "oldXMonad" oldKeys;
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) ]
'';
}; };
}; };
@ -38,10 +78,40 @@ import ./make-test-python.nix ({ pkgs, ...} : {
machine.wait_for_window("${user.name}.*machine") machine.wait_for_window("${user.name}.*machine")
machine.sleep(1) machine.sleep(1)
machine.screenshot("terminal1") machine.screenshot("terminal1")
machine.succeed("rm /tmp/oldXMonad")
machine.send_key("alt-q") machine.send_key("alt-q")
machine.sleep(3) machine.wait_for_file("/tmp/oldXMonad")
machine.wait_for_window("${user.name}.*machine") machine.wait_for_window("${user.name}.*machine")
machine.sleep(1) machine.sleep(1)
machine.screenshot("terminal2") 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")
''; '';
}) })