{ lib, config, pkgs, modifier ? "Mod4", directional, workspace, launchers }: with lib; let mod = modifier; # Directional shortcuts. # # These are used to change focus and move windows around. genDirectional = ({ left, right, up, down }: { # Change window focus "${mod}+${left}" = "focus left"; "${mod}+${down}" = "focus down"; "${mod}+${up}" = "focus up"; "${mod}+${right}" = "focus right"; # Move windows "${mod}+Shift+${left}" = "move left"; "${mod}+Shift+${down}" = "move down"; "${mod}+Shift+${up}" = "move up"; "${mod}+Shift+${right}" = "move right"; }); # Workspace shortcuts. # # The `numbered` parameter defines the number of numbered workspaces, # which can be no more than 8. # # The `named` parameter defines a set of named workspaces and the key # used to navigate to it. # # For each entry this generates two keybindings: # - `+`: focus workspace # - `+Shift+`: move focused window to workspace # # `` is set to the workspace number for numbered workspaces. genWorkspaces = ({ numbered ? 0, named ? {} }: with lib; let nums = genAttrs (map toString (range 1 (min numbered 9))) id; workspaces = named // nums; genBinds = (n: k: { # Focus the workspace "${mod}+${k}" = "workspace ${n}"; # Move a window to the workspace "${mod}+Shift+${k}" = "move window to workspace ${n}"; }); keybinds = mapAttrsToList genBinds workspaces; in mkMerge (keybinds) ); # Application launchers genLaunchers = ({ browser }: { "${mod}+Tab" = "exec ${browser}"; "${mod}+Return" = "exec alacritty"; }); # Layout manipulation layout = ({ "${mod}+A" = "split v"; "${mod}+S" = "split h"; "${mod}+F" = "fullscreen toggle"; "${mod}+BackSpace" = "kill"; }); # Media-related keys media = ({ mpc_cli ? null, pulseaudio }: let cmd = "${mpc_cli}/bin/mpc"; in (optionalAttrs (mpc_cli != null) { "${mod}+comma" = "exec ${cmd} prev"; "${mod}+period" = "exec ${cmd} next"; "${mod}+slash" = "exec ${cmd} toggle"; }) // (with config.devices; optionalAttrs (audio != null) (with audio; { # Main speakers "${mod}+z" = "exec pactl set-sink-volume ${speakers} -10%"; "${mod}+x" = "exec pactl set-sink-volume ${speakers} +10%"; # Secondary output "${mod}+Alt+z" = "exec pactl set-sink-volume ${external} -10%"; "${mod}+Alt+x" = "exec pactl set-sink-volume ${external} +10%"; } // (optionalAttrs (main-mic != null) { # Microphone "${mod}+c" = "exec pactl set-source-mute ${main-mic} toggle"; }))) ); in (mkMerge [ (media { inherit (pkgs) mpc_cli pulseaudio; }) (genDirectional directional) (genWorkspaces workspace) (genLaunchers launchers) layout ])