Add utils.readFile and utils.interpolateFile, use them in xmonad config

- Add utils.readFile which reads a file and evaluates any nix in ${{null}}
  brackets like that, returning a string. This should be a drop-in replacement
  for builtins.readFile
- Add utils.interpolateFile which does the same as readFile but also writes to
  the store and returns a store path for the new file. This should be a drop-in
  wrapper for a path
- Use utils.interpolateFile on the xmonad config file
- Use a relative file path contained in nix interpolation brackets in the xmonad
  config file
- Use package paths inside the included file (all included paths are also
  interpolated)
- Update xmonad to have better volume change support
- Update xmonad to have better multi-display support (actually start polybar,
  display different colors for second displays)
development
Skyler Grey 3 years ago
parent 1eece6e167
commit 3a9a2b1ee0
Signed by: Minion3665
GPG Key ID: 1AFD10256B3C714D

@ -68,7 +68,7 @@
});
};
utils = import ./utils nixpkgs.lib;
utils = import ./utils pkgs;
username = "minion";

@ -1,6 +1,11 @@
{ pkgs, options, lib, ... }: {
config = {
services.logind.extraConfig = ''
HandlePowerKey=Ignore
LidSwitchIgnoreInhibited=no
'';
boot = {
kernelParams = [ "acpi_backlight=video" ];
loader = {
systemd-boot = {
/* enable = true; */ # Replaced by secure-boot.nix
@ -24,6 +29,7 @@
"tap"
"tun"
"veth"
"hid_sensor_hub"
];
};
};

@ -1,17 +1,18 @@
{ lib, pkgs, home, config, ... }: {
{ lib, pkgs, home, config, utils, ... }: {
home = {
home.packages = with pkgs; [ xob pamixer ];
xsession = {
windowManager.xmonad = {
enable = true;
enableContribAndExtras = true;
config = ./xmonad/xmonad.hs;
config = utils.interpolateFile ./xmonad/xmonad.hs;
libFiles = lib.pipe ./xmonad [
builtins.readDir
builtins.attrNames
(builtins.filter (name: name != "xmonad.hs"))
(map (name: {
inherit name;
value = "${./xmonad}/${name}";
value = utils.interpolateFile "${./xmonad}/${name}";
}))
builtins.listToAttrs
];

@ -33,11 +33,12 @@ polybarHook dbus =
grey = "#474e5d"
orange = "#e5c07b"
purple = "#c678dd"
green = "#98c379"
red = "#e06c75"
in def { ppOutput = dbusOutput dbus
, ppCurrent = wrapper red
, ppVisible = wrapper blue
, ppUrgent = wrapper orange
, ppVisible = wrapper orange
, ppUrgent = wrapper green
, ppHidden = wrapper blue
, ppHiddenNoWindows = wrapper grey
, ppTitle = shorten 100 . wrapper purple

@ -0,0 +1,30 @@
#!${{pkgs.python3}}/bin/python3
import sys
import os
import subprocess
args = sys.argv
device_argument = "--default-source" if "-i" in args else ""
control_argument = ""
control_argument += "-i" if "-u" in args else ""
control_argument += "-d" if "-d" in args else ""
control_argument += "-t" if "-m" in args else " 5"
os.system(
f"${{pkgs.pamixer}}/bin/pamixer {device_argument} {control_argument} --set-limit 150"
)
mute_char = (
"!"
if subprocess.getoutput(f"${{pkgs.pamixer}}/bin/pamixer {device_argument} --get-mute")
== "true"
else ""
)
volume = subprocess.getoutput(f"${{pkgs.pamixer}}/bin/pamixer {device_argument} --get-volume")
socket_path = f"{os.environ['XDG_RUNTIME_DIR']}/xob.sock"
with open(socket_path, "w") as socket:
socket.write(f"{volume}{mute_char}\n")

@ -1,4 +1,5 @@
-- spell-checker:words xmonad
{-# OPTIONS_GHC -Wno-deferred-out-of-scope-variables #-}
import XMonad
import System.Exit
@ -14,20 +15,28 @@ import XMonadLog
import Blaze.ByteString.Builder (toByteString)
import Foreign.C
import XMonad
import Graphics.X11.ExtraTypes (xF86XK_AudioLowerVolume,
xF86XK_AudioMute,
xF86XK_AudioRaiseVolume,
xF86XK_MonBrightnessDown,
xF86XK_MonBrightnessUp,
xF86XK_Xfer)
import qualified XMonad as W
import XMonad.Hooks.DynamicProperty (dynamicPropertyChange)
import XMonad.Hooks.ManageHelpers (doFullFloat, doLower,
isInProperty, doRectFloat)
doRectFloat, isInProperty)
import XMonad.Hooks.UrgencyHook
import XMonad.Layout.Drawer (propertyToQuery)
import XMonad.Layout.Gaps
import XMonad.Layout.Spacing
import qualified XMonad.StackSet as W
import XMonad.Util.Hacks
import qualified XMonad as W
import XMonad.Util.PureX (curScreenId, curScreen)
import XMonad.Util.PureX (curScreen, curScreenId)
import XMonad.Util.Run (safeSpawn, safeSpawnProg)
volumeChangeCmd = "${{./vol_change.py}}"
terminal = "kitty" -- Kitty, my beloved <3
terminal = "/usr/bin/env SHLVL=0 kitty" -- Kitty, my beloved <3
launcher = "pkill rofi; rofi -show combi"
networkManager = "wpa_cli select_network $(wpa_cli list_networks | tail -n +3 | awk '!seen[$2]++' | rofi -dmenu -window-title 'Select Network' | awk '{print $1;}')"
@ -36,7 +45,7 @@ selectScreenshot = "mkdir -p ~/Screenshots && maim -s | tee ~/Screenshots/\"$(da
modifierKey = mod4Mask -- Use Super as our mod key
statusBar = "pkill polybar; polybar"
statusBar = "pkill polybar; polybar main; polybar dp1; polybar dp2; polybar dp3; polybar dp4"
compositor = "pkill picom; picom"
background = "pkill show; show ~/.xmonad/wallpaper.glsl > /dev/null"
colorSelection = "xcolor | xclip -sel clip"
@ -44,11 +53,16 @@ keybindings = "setxkbmap -option caps:none && xmodmap ~/.Xmodmap"
shift = shiftMask
-- spell-checker:words xobsock
xobsock = "$XDG_RUNTIME_DIR/xob.sock"
startupHook = do
spawn Main.statusBar
spawn Main.compositor
spawn background
spawn keybindings
spawn "pgrep keepass || run_keepass"
spawn $ "pkill xob; rm -f " ++ xobsock ++ " && mkfifo " ++ xobsock ++ " && tail -f " ++ xobsock ++ " | xob"
main :: IO ()
@ -92,4 +106,15 @@ main' dbus = xmonad
, ((modifierKey .|. Main.shift, xK_s), spawn selectScreenshot)
, ((modifierKey .|. Main.shift, xK_h), spawn colorSelection)
, ((0, xK_Print), spawn screenshot)
, ((modifierKey .|. Main.shift, xK_Return), spawn Main.terminal)
, ((0, xF86XK_AudioLowerVolume), spawn $ volumeChangeCmd ++ " -d")
, ((0, xF86XK_AudioRaiseVolume), spawn $ volumeChangeCmd ++ " -u")
, ((0, xF86XK_AudioMute), spawn $ volumeChangeCmd ++ " -m")
, ((modifierKey, xF86XK_AudioLowerVolume), spawn $ volumeChangeCmd ++ " -d -i")
, ((modifierKey, xF86XK_AudioRaiseVolume), spawn $ volumeChangeCmd ++ " -u -i")
, ((modifierKey, xF86XK_AudioMute), spawn $ volumeChangeCmd ++ " -m -i")
, ((0, xF86XK_MonBrightnessDown), spawn $ "light -U 6 && light -G | cut -d'.' -f1 > " ++ xobsock)
, ((0, xF86XK_MonBrightnessUp), spawn $ "light -A 6 && light -G | cut -d'.' -f1 > " ++ xobsock)
, ((modifierKey, xF86XK_MonBrightnessDown), spawn $ "light -U 3 && light -G | cut -d'.' -f1 > " ++ xobsock)
, ((modifierKey, xF86XK_MonBrightnessUp), spawn $ "light -A 3 && light -G | cut -d'.' -f1 > " ++ xobsock)
]

@ -1,12 +1,27 @@
lib:
lib.pipe ./. [
(import ./nixFilesInWithName.nix lib)
(builtins.map ({ name
, path
,
}: {
name = lib.removeSuffix ".nix" name;
value = import path lib;
}))
builtins.listToAttrs
]
pkgs_or_lib:
let
is_pkgs = pkgs_or_lib ? lib;
lib = if is_pkgs then pkgs_or_lib.lib else pkgs_or_lib;
utils = lib.pipe ./. [
(import ./nixFilesInWithName.nix lib)
(builtins.map (file: rec {
name = lib.removeSuffix ".nix" file.name;
func = import file.path;
accepts_pkgs = builtins.hasAttr "pkgs" (builtins.functionArgs func);
value =
if accepts_pkgs then
func
(builtins.intersectAttrs (builtins.functionArgs func) {
inherit
lib utils; pkgs = pkgs_or_lib;
})
else if is_pkgs
then func lib
else
func pkgs_or_lib;
include = file.name != "default.nix" && (!accepts_pkgs || is_pkgs);
}))
(builtins.filter (utility: utility.include))
builtins.listToAttrs
];
in utils

@ -0,0 +1,8 @@
{ utils, pkgs }: file: pkgs.lib.pipe file [
utils.readFile
(text: pkgs.writeTextFile {
name = builtins.baseNameOf file;
inherit text;
executable = true; # TODO: write and use utils.isExecutable
})
]

@ -0,0 +1,42 @@
{ pkgs, utils }:
let
lib = pkgs.lib;
in
file: lib.pipe file [
builtins.readFile
(builtins.split "\\\$\\{\\{([^}]*)}}")
(map (part:
if builtins.typeOf part == "string"
then part
else
import
(
(
pkgs.writeText "generated.nix" ("pkgs: lib: " + (builtins.elemAt part 0))
).outPath
)
pkgs
lib
))
(map (part:
if builtins.typeOf part == "string" then part
else if builtins.typeOf part == "path" then
let
stringified = toString part;
in
builtins.toString (utils.interpolateFile (
file + "/.." + (builtins.substring
(builtins.stringLength "/nix/store")
(builtins.stringLength
stringified)
stringified)
# ^ Somewhat of a hack, works because we know that the file path
# is a text file (i.e. not a directory) as we read it earlier and
# relative paths end up in /nix/store due to the writeText. Absolute
# paths are not supported
))
else
toString part
))
(builtins.concatStringsSep "")
]
Loading…
Cancel
Save