diff --git a/overlays/default.nix b/overlays/default.nix index 69642a7..f18888c 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -9,6 +9,7 @@ new-packages patches variables + lib_extended ]; nur = inputs.nur.overlay; @@ -83,4 +84,18 @@ variables = (final: prev: { uservars = import ../user/variables.nix; }); + + lib_extended = (final: prev: { + lib = prev.lib // rec { + # Utility funcion + # Input: [{v1=1;} {v2=2;}] + # Output: {v1=1;v2=2;} + mergeAttrsSet = prev.lib.foldAttrs (n: _: n) { }; + + # Easily translate imperative templating code + # Input: [ 1 2 ] (num: { "v${num}" = num; }) + # Output: {v1=1;v2=2;} + forEachMerge = list: func: mergeAttrsSet (prev.lib.forEach list func); + }; + }); } diff --git a/user/sway/default.nix b/user/sway/default.nix index 70d95ec..81f03aa 100644 --- a/user/sway/default.nix +++ b/user/sway/default.nix @@ -2,40 +2,26 @@ let inherit (pkgs.uservars) key accent font theme; inherit (theme) color; - _lock = pkgs.writeShellScriptBin "_lock" '' - ${pkgs.swaylock}/bin/swaylock -f - systemctl --user start swayidle.service - ''; - _suspend = pkgs.writeShellScriptBin "_suspend" '' - ${_lock}/bin/_lock - systemctl suspend - ''; - _sway_idle_toggle = pkgs.writeShellScriptBin "_sway_idle_toggle" '' - if systemctl --user status swayidle > /dev/null; then - systemctl --user stop swayidle.service - else - systemctl --user start swayidle.service - fi - ''; in { - imports = [ ./theme.nix ./mako.nix ./swaylock.nix ./swayidle.nix ]; + imports = [ + ./kanshi.nix + ./mako.nix + ./sway-binds.nix + ./swayidle.nix + ./swaylock.nix + ./theme.nix + ]; config = { programs.mako.enable = true; services.swayidle.enable = true; + services.kanshi.enable = true; wayland.windowManager.sway = let mod = "Mod4"; - menu = "wlauncher"; - terminal = "alacritty"; - - # Utility funcion - # Input: [{v1=1;} {v2=2;}] - # Output: {v1=1;v2=2;} - mergeAttrsSet = lib.foldAttrs (n: _: n) { }; - - forEachMerge = list: func: mergeAttrsSet (lib.forEach list func); + # menu = "wlauncher"; + # terminal = "alacritty"; in { enable = true; @@ -191,166 +177,6 @@ in { app_id = ".*[Hh]elvum.*"; } ]; }; - keybindings = - let - # mod+1 to swich to workspace 1 - # mod+shift+1 to move to workspace 1 - workspace_binds = - let - workspaceBinds = map makeWorkspaceBinds (lib.range 1 10); - makeWorkspaceBinds = (i: - let - key = toString (lib.mod i 10); - workspaceNumber = toString i; - in - { - "${mod}+${key}" = "workspace number ${workspaceNumber}"; - "${mod}+Shift+${key}" = - "move container to workspace number ${workspaceNumber}"; - }); - in - mergeAttrsSet workspaceBinds; - - prev_next_binds = - let - maybe_window = key: - if (lib.strings.hasInfix "button" key) then - "--whole-window" - else - ""; - makePrevNextBindFunction = (prev_or_next: - map (key: { - "${maybe_window key} ${mod}+${key}" = - "workspace ${prev_or_next}_on_output"; - })); - prev_binds = makePrevNextBindFunction "prev" [ - key.tabL - "bracketleft" - "Prior" - "button9" - "button4" - "Shift+Tab" - ]; - next_binds = makePrevNextBindFunction "next" [ - key.tabR - "bracketright" - "Next" - "button8" - "button5" - "Tab" - ]; - in - mergeAttrsSet (prev_binds ++ next_binds); - - # focus, move, resize, (focus and move output) - # for every direction with both arrow keys and vim keys - movement_binds = - let - directions = [ "Left" "Up" "Right" "Down" ]; - makeVimKeys = (k: key.${lib.toLower k}); - makeArrowKeys = (k: k); - makeResizeCommand = direction: - { - Left = "shrink width 20px"; - Up = "shrink height 20px"; - Right = "grow width 20px"; - Down = "grow height 20px"; - }.${direction}; - in - forEachMerge [ makeVimKeys makeArrowKeys ] (prefixFun: - forEachMerge directions (direction: - let - resize_cmd = makeResizeCommand direction; - keyBind = prefixFun direction; - in - { - # Move focus - "${mod}+${keyBind}" = "focus ${direction}"; - # Move window - "${mod}+Shift+${keyBind}" = "move ${direction}"; - # Resize window - "${mod}+Control+${keyBind}" = "resize ${resize_cmd}"; - # focus output - "${mod}+mod1+${keyBind}" = "focus output ${direction}"; - # Move workspace to output - "${mod}+mod1+Shift+${keyBind}" = - "move workspace output ${direction}"; - })); - - parenting_binds = { - "${mod}+equal" = "focus parent"; - "${mod}+minus" = "focus child"; - "${mod}+r" = "layout toggle split"; - "${mod}+t" = "layout toggle split tabbed stacking"; - "${mod}+b" = "splith"; - "${mod}+v" = "splitv"; - "${mod}+a" = "focus parent"; - - ## TODO: - # "${mod}+Shift+minus" = "move scratchpad"; - # "${mod}+minus" = "scratchpad show"; - }; - - audio_binds = { - XF86AudioRaiseVolume = "exec volumesh -i 10"; - XF86AudioLowerVolume = "exec volumesh -d 10"; - XF86AudioMute = "exec volumesh -t"; - XF86AudioMicMute = - "exec pactl set-source-mute @DEFAULT_SOURCE@ toggle"; - # Control media - XF86AudioPlay = "exec playerctl play-pause"; - XF86AudioPause = "exec playerctl play-pause"; - XF86AudioNext = "exec playerctl next"; - XF86AudioPrev = "exec playerctl previous"; - }; - system_binds = { - "--locked Ctrl+${mod}+z" = "exec ${_suspend}/bin/_suspend"; - "${mod}+Alt+c" = "exec ${_sway_idle_toggle}/bin/_sway_idle_toggle"; - }; - screenshot_binds = { - # Screens to file - "Print" = "exec ${pkgs.screenshotsh}/bin/screenshotsh def"; - # Screen area to file - "Shift+Print" = "exec ${pkgs.screenshotsh}/bin/screenshotsh area"; - # Screen area to clipboard - "Control+Shift+Print" = - "exec ${pkgs.screenshotsh}/bin/screenshotsh area-clip"; - # Focused monitor to clipboard - "Control+Print" = "exec ${pkgs.screenshotsh}/bin/screenshotsh clip"; - }; - other_binds = { - "${mod}+p" = "exec ${pkgs.wpass}/bin/wpass"; - "${mod}+s" = "exec ${menu}"; - "${mod}+g" = "exec ${pkgs.demoji}/bin/demoji --lang pt --fallback --copy -- ${pkgs.wdmenu}/bin/wdmenu"; - "${mod}+c" = "exec ${pkgs.color_picker}/bin/color_picker"; - "${mod}+Return" = "exec ${terminal}"; - "${mod}+Ctrl+Return" = "exec thunar"; - "${mod}+Shift+s" = "exec grim - | swappy -f -"; - "${mod}+Ctrl+v" = "exec wl-paste | tesseract -l por - - | wl-copy"; - "${mod}+k" = "exec showkeys"; - "${mod}+x" = "kill"; - "${mod}+m" = "mode audio"; - "${mod}+escape" = - "mode passthrough;exec notify-send 'Passthrough on'"; - "${mod}+f" = "fullscreen toggle"; - "${mod}+Shift+space" = "floating toggle"; - "${mod}+space" = "focus mode_toggle"; - "${mod}+ctrl+space" = "sticky toggle"; - "${mod}+Shift+c" = "reload"; - # "${mod}+Shift+e" = - # "exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit'"; - }; - in - mergeAttrsSet [ - other_binds - workspace_binds - prev_next_binds - movement_binds - audio_binds - system_binds - parenting_binds - screenshot_binds - ]; terminal = pkgs.alacritty.executable; }; extraConfig = '' @@ -363,33 +189,6 @@ in enable = true; provider = "geoclue2"; }; - services.kanshi = { - enable = true; - profiles = { - sedetary = { - outputs = [ - { - criteria = "eDP-1"; - status = "disable"; - position = "1920,312"; - } - { - criteria = "HDMI-A-1"; - position = "0,0"; - } - ]; - exec = [ "xrdb .Xresources" ]; - }; - nomad = { - outputs = [{ - criteria = "eDP-1"; - status = "enable"; - position = "1920,312"; - }]; - exec = [ "xrdb .Xresources" ]; - }; - }; - }; home.packages = with pkgs; [ sway swaybg diff --git a/user/sway/kanshi.nix b/user/sway/kanshi.nix new file mode 100644 index 0000000..edc2e3f --- /dev/null +++ b/user/sway/kanshi.nix @@ -0,0 +1,33 @@ +{ config, pkgs, lib, ... }: +let + inherit (pkgs.uservars) key accent font theme; + inherit (theme) color; +in +{ + services.kanshi = { + profiles = { + sedetary = { + outputs = [ + { + criteria = "eDP-1"; + status = "disable"; + position = "1920,312"; + } + { + criteria = "HDMI-A-1"; + position = "0,0"; + } + ]; + exec = [ "xrdb .Xresources" ]; + }; + nomad = { + outputs = [{ + criteria = "eDP-1"; + status = "enable"; + position = "1920,312"; + }]; + exec = [ "xrdb .Xresources" ]; + }; + }; + }; +} diff --git a/user/sway/sway-binds.nix b/user/sway/sway-binds.nix new file mode 100644 index 0000000..fadcfd0 --- /dev/null +++ b/user/sway/sway-binds.nix @@ -0,0 +1,185 @@ +{ config, pkgs, ... }: +let + inherit (pkgs.uservars) key accent font theme; + inherit (theme) color; + inherit (pkgs) lib; + + mod = "Mod4"; + menu = "wlauncher"; + terminal = "alacritty"; + + _lock = pkgs.writeShellScriptBin "_lock" '' + ${pkgs.swaylock}/bin/swaylock -f + systemctl --user start swayidle.service + ''; + _suspend = pkgs.writeShellScriptBin "_suspend" '' + ${_lock}/bin/_lock + systemctl suspend + ''; + + _sway_idle_toggle = pkgs.writeShellScriptBin "_sway_idle_toggle" '' + if systemctl --user status swayidle > /dev/null; then + systemctl --user stop swayidle.service + else + systemctl --user start swayidle.service + fi + ''; + + # mod+1 to swich to workspace 1 + # mod+shift+1 to move to workspace 1 + workspace_binds = lib.forEachMerge (lib.range 1 10) (i: + let + key = toString (lib.mod i 10); + workspaceNumber = toString i; + in + { + "${mod}+${key}" = "workspace number ${workspaceNumber}"; + "${mod}+Shift+${key}" = + "move container to workspace number ${workspaceNumber}"; + }); + + prev_next_binds = + let + maybe_window = key: + if (lib.strings.hasInfix "button" key) then + "--whole-window" + else + ""; + makePrevNextBindFunction = (prev_or_next: + map (key: { + "${maybe_window key} ${mod}+${key}" = + "workspace ${prev_or_next}_on_output"; + })); + prev_binds = makePrevNextBindFunction "prev" [ + key.tabL + "bracketleft" + "Prior" + "button9" + "button4" + "Shift+Tab" + ]; + next_binds = makePrevNextBindFunction "next" [ + key.tabR + "bracketright" + "Next" + "button8" + "button5" + "Tab" + ]; + in + lib.mergeAttrsSet (prev_binds ++ next_binds); + + # focus, move, resize, (focus and move output) + # for every direction with both arrow keys and vim keys + movement_binds = + let + directions = [ "Left" "Up" "Right" "Down" ]; + makeVimKeys = (k: key.${lib.toLower k}); + makeArrowKeys = (k: k); + makeResizeCommand = direction: + { + Left = "shrink width 20px"; + Up = "shrink height 20px"; + Right = "grow width 20px"; + Down = "grow height 20px"; + }.${direction}; + in + lib.forEachMerge [ makeVimKeys makeArrowKeys ] (prefixFun: + lib.forEachMerge directions (direction: + let + resize_cmd = makeResizeCommand direction; + keyBind = prefixFun direction; + in + { + # Move focus + "${mod}+${keyBind}" = "focus ${direction}"; + # Move window + "${mod}+Shift+${keyBind}" = "move ${direction}"; + # Resize window + "${mod}+Control+${keyBind}" = "resize ${resize_cmd}"; + # focus output + "${mod}+mod1+${keyBind}" = "focus output ${direction}"; + # Move workspace to output + "${mod}+mod1+Shift+${keyBind}" = + "move workspace output ${direction}"; + })); + + parenting_binds = { + "${mod}+equal" = "focus parent"; + "${mod}+minus" = "focus child"; + "${mod}+r" = "layout toggle split"; + "${mod}+t" = "layout toggle split tabbed stacking"; + "${mod}+b" = "splith"; + "${mod}+v" = "splitv"; + "${mod}+a" = "focus parent"; + + ## TODO: + # "${mod}+Shift+minus" = "move scratchpad"; + # "${mod}+minus" = "scratchpad show"; + }; + + audio_binds = { + XF86AudioRaiseVolume = "exec volumesh -i 10"; + XF86AudioLowerVolume = "exec volumesh -d 10"; + XF86AudioMute = "exec volumesh -t"; + XF86AudioMicMute = + "exec pactl set-source-mute @DEFAULT_SOURCE@ toggle"; + # Control media + XF86AudioPlay = "exec playerctl play-pause"; + XF86AudioPause = "exec playerctl play-pause"; + XF86AudioNext = "exec playerctl next"; + XF86AudioPrev = "exec playerctl previous"; + }; + + system_binds = { + "--locked Ctrl+${mod}+z" = "exec ${_suspend}/bin/_suspend"; + "${mod}+Alt+c" = "exec ${_sway_idle_toggle}/bin/_sway_idle_toggle"; + }; + + screenshot_binds = { + # Screens to file + "Print" = "exec ${pkgs.screenshotsh}/bin/screenshotsh def"; + # Screen area to file + "Shift+Print" = "exec ${pkgs.screenshotsh}/bin/screenshotsh area"; + # Screen area to clipboard + "Control+Shift+Print" = + "exec ${pkgs.screenshotsh}/bin/screenshotsh area-clip"; + # Focused monitor to clipboard + "Control+Print" = "exec ${pkgs.screenshotsh}/bin/screenshotsh clip"; + }; + + other_binds = { + "${mod}+p" = "exec ${pkgs.wpass}/bin/wpass"; + "${mod}+s" = "exec ${menu}"; + "${mod}+g" = "exec ${pkgs.demoji}/bin/demoji --lang pt --fallback --copy -- ${pkgs.wdmenu}/bin/wdmenu"; + "${mod}+c" = "exec ${pkgs.color_picker}/bin/color_picker"; + "${mod}+Return" = "exec ${terminal}"; + "${mod}+Ctrl+Return" = "exec thunar"; + "${mod}+Shift+s" = "exec grim - | swappy -f -"; + "${mod}+Ctrl+v" = "exec wl-paste | tesseract -l por - - | wl-copy"; + "${mod}+k" = "exec showkeys"; + "${mod}+x" = "kill"; + "${mod}+m" = "mode audio"; + "${mod}+escape" = + "mode passthrough;exec notify-send 'Passthrough on'"; + "${mod}+f" = "fullscreen toggle"; + "${mod}+Shift+space" = "floating toggle"; + "${mod}+space" = "focus mode_toggle"; + "${mod}+ctrl+space" = "sticky toggle"; + "${mod}+Shift+c" = "reload"; + # "${mod}+Shift+e" = + # "exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit'"; + }; +in +{ + wayland.windowManager.sway.config.keybindings = lib.mergeAttrsSet [ + other_binds + workspace_binds + prev_next_binds + movement_binds + audio_binds + system_binds + parenting_binds + screenshot_binds + ]; +}