u/pfassina

▲ 13 r/NixOS

Hyprland HM Lua Config Migration

I recently migrated my hyprland HM config to lua.

It wasn't straightforward, so I wanted to show what the new and old look like for anyone trying to make the change themselves.

New Config:

{
  pkgs,
  lib,
  ...
}:
let
  lua = lib.generators.mkLuaInline;

  dsp = {
    exec = cmd: lua ''hl.dsp.exec_cmd("${cmd}")'';
    close = lua "hl.dsp.window.close()";
    exit = lua "hl.dsp.exit()";
    float = lua ''hl.dsp.window.float({ action = "toggle" })'';
    fullscreen = lua "hl.dsp.window.fullscreen()";
    pseudo = lua "hl.dsp.window.pseudo()";
    layout = msg: lua ''hl.dsp.layout("${msg}")'';
    focus = dir: lua ''hl.dsp.focus({ direction = "${dir}" })'';
    swap = dir: lua ''hl.dsp.window.swap({ direction = "${dir}" })'';
    toggleSpecial = name: lua ''hl.dsp.workspace.toggle_special("${name}")'';
    moveToSpecial = name: lua ''hl.dsp.window.move({ workspace = "special:${name}" })'';
    focusWorkspace = ws: lua ''hl.dsp.focus({ workspace = "${toString ws}" })'';
    moveToWorkspace = ws: lua ''hl.dsp.window.move({ workspace = "${toString ws}" })'';
    drag = lua "hl.dsp.window.drag()";
    resize = lua "hl.dsp.window.resize()";
    sendshortcut = mod: key: lua ''hl.dsp.send_shortcut({ mods = "${mod}", key = "${key}" })'';
  };

  bind = keys: dispatcher: { _args = [keys dispatcher]; };
  bindOpts = keys: dispatcher: opts: { _args = [keys dispatcher opts]; };

  workspaceBinds = lib.concatMap (i:
    let key = toString (lib.mod i 10);
    in [
      (bind "SUPER + ${key}" (dsp.focusWorkspace i))
      (bind "SUPER + SHIFT + ${key}" (dsp.moveToWorkspace i))
    ]
  ) (lib.range 1 10);

  startupScript = pkgs.pkgs.writeShellScriptBin "start" ''
    ${pkgs.waybar}/bin/waybar &
    gsettings set org.gnome.desktop.interface color-scheme "prefer-dark"
    hyprlock &
  '';
in
{
  wayland.windowManager.hyprland = {
    enable = true;
    configType = "lua";

    settings = {
      monitor = [{
        output = "DP-1";
        mode = "3840x2160";
        position = "0x0";
        scale = "1.0";
      }];

      config = {
        general = {
          gaps_in = 5;
          gaps_out = 5;
          border_size = 1;
          col = {
            active_border = "rgb(e1e1e1)";
            inactive_border = "rgb(151515)";
          };
        };

        decoration = {
          rounding = 5;
          active_opacity = 1.0;
          inactive_opacity = 1.0;
          blur = {
            enabled = true;
            size = 3;
            passes = 1;
            vibrancy = 0.1696;
          };
        };

        animations = {
          enabled = true;
        };

        dwindle = {
          force_split = 2;
          preserve_split = true;
        };

        misc = {
          force_default_wallpaper = -1;
          disable_hyprland_logo = true;
        };

        input = {
          kb_layout = "us";
          follow_mouse = 0;
          sensitivity = -0.2;
          natural_scroll = true;
          touchpad = {
            natural_scroll = true;
          };
        };
      };

      curve = [{
        _args = [
          "myBezier"
          {
            type = "bezier";
            points = lua "{ {0.05, 0.9}, {0.1, 1.05} }";
          }
        ];
      }];

      animation = [
        { leaf = "windows"; enabled = true; speed = 7; bezier = "myBezier"; }
        { leaf = "windowsOut"; enabled = true; speed = 7; bezier = "default"; style = "popin 80%"; }
        { leaf = "border"; enabled = true; speed = 10; bezier = "default"; }
        { leaf = "borderangle"; enabled = true; speed = 8; bezier = "default"; }
        { leaf = "fade"; enabled = true; speed = 7; bezier = "default"; }
        { leaf = "workspaces"; enabled = true; speed = 6; bezier = "default"; }
      ];

      window_rule = [{
        match = {
          class = "^(kitty)$";
          title = "^(bw-unlock)$";
        };
        float = true;
      }];

      on = {
        _args = [
          "hyprland.start"
          (lua ''
            function()
              hl.exec_cmd("${startupScript}/bin/start")
            end'')
        ];
      };

      bind = [
        # App launchers
        (bind "SUPER + RETURN" (dsp.exec "kitty"))
        (bind "SUPER + B" (dsp.exec "zen-twilight -P default"))
        (bind "SUPER + SPACE" (dsp.exec "walker"))
        (bind "SUPER + CTRL + V" (dsp.exec "walker -m clipboard"))
        (bind "SUPER + M" (dsp.exec "kitty nvim ~/Cortex/00_NOTES/temp.md"))

        # Screenshots
        (bind "SUPER + CTRL + 4" (dsp.exec "grimblast copysave area"))
        (bind "SUPER + CTRL + 5" (dsp.exec "grimblast copysave screen"))

        # Universal copy/paste
        (bind "SUPER + C" (dsp.sendshortcut "CTRL" "Insert"))
        (bind "SUPER + V" (dsp.sendshortcut "SHIFT" "Insert"))
        (bind "SUPER + X" (dsp.sendshortcut "CTRL" "X"))

        # Window management
        (bind "SUPER + Q" dsp.close)
        (bind "SUPER + SHIFT + Q" dsp.exit)
        (bind "SUPER + CTRL + Q" (dsp.exec "hyprlock"))
        (bind "SUPER + T" dsp.float)
        (bind "SUPER + F" dsp.fullscreen)
        (bind "SUPER + P" dsp.pseudo)
        (bind "SUPER + J" (dsp.layout "togglesplit"))

        # Focus
        (bind "SUPER + left" (dsp.focus "left"))
        (bind "SUPER + right" (dsp.focus "right"))
        (bind "SUPER + up" (dsp.focus "up"))
        (bind "SUPER + down" (dsp.focus "down"))

        # Swap windows
        (bind "SUPER + SHIFT + left" (dsp.swap "left"))
        (bind "SUPER + SHIFT + right" (dsp.swap "right"))
        (bind "SUPER + SHIFT + up" (dsp.swap "up"))
        (bind "SUPER + SHIFT + down" (dsp.swap "down"))

        # Special workspace
        (bind "SUPER + S" (dsp.toggleSpecial "magic"))
        (bind "SUPER + SHIFT + S" (dsp.moveToSpecial "magic"))

        # Scroll through workspaces
        (bind "SUPER + mouse_down" (dsp.focusWorkspace "e+1"))
        (bind "SUPER + mouse_up" (dsp.focusWorkspace "e-1"))

        # Volume keys
        (bindOpts "XF86AudioRaiseVolume" (dsp.exec "wpctl set-volume @ 5%+") { locked = true; repeating = true; })
        (bindOpts "XF86AudioLowerVolume" (dsp.exec "wpctl set-volume @ 5%-") { locked = true; repeating = true; })
        (bindOpts "XF86AudioMute" (dsp.exec "wpctl set-mute @ toggle") { locked = true; })
        (bindOpts "XF86AudioMicMute" (dsp.exec "wpctl set-mute u/DEFAULT_AUDIO_SOURCE@ toggle") { locked = true; })

        # Mouse move/resize
        (bindOpts "SUPER + mouse:272" dsp.drag { mouse = true; })
        (bindOpts "SUPER + mouse:273" dsp.resize { mouse = true; })
      ] ++ workspaceBinds;
    };
  };
}

Old Config:

{pkgs, ...}: let
  startupScript = pkgs.pkgs.writeShellScriptBin "start" ''
    ${pkgs.waybar}/bin/waybar &
    gsettings set org.gnome.desktop.interface color-scheme "prefer-dark"
    hyprlock &
  '';
in {
  wayland.windowManager.hyprland = {
    enable = true;
    # configType = "lua";
    extraConfig = ''
      # Universal copy/paste using sendshortcut (Omarchy style)
      bindd = SUPER, C, Universal copy, sendshortcut, CTRL, Insert,
      bindd = SUPER, V, Universal paste, sendshortcut, SHIFT, Insert,
      bindd = SUPER, X, Universal cut, sendshortcut, CTRL, X,
    '';
    settings = {
      monitor = [
        "DP-1,3840x2160,0x0,1.0"
      ];
      exec-once = ''${startupScript}/bin/start'';

      general = {
        gaps_in = 5;
        gaps_out = 5;
        border_size = 1;

        "col.active_border" = "rgb(e1e1e1)";
        "col.inactive_border" = "rgb(151515)";
      };

      decoration = {
        rounding = 5;
        active_opacity = 1.0;
        inactive_opacity = 1.0;

        blur = {
          enabled = true;
          size = 3;
          passes = 1;
          vibrancy = 0.1696;
        };
      };

      animations = {
        enabled = true;
        bezier = "myBezier, 0.05, 0.9, 0.1, 1.05";

        animation = [
          "windows, 1, 7, myBezier"
          "windowsOut, 1, 7, default, popin 80%"
          "border, 1, 10, default"
          "borderangle, 1, 8, default"
          "fade, 1, 7, default"
          "workspaces, 1, 6, default"
        ];
      };

      dwindle = {
        force_split = 2;
        preserve_split = true;
      };

      misc = {
        force_default_wallpaper = -1;
        disable_hyprland_logo = true;
      };

      input = {
        kb_layout = "us";
        follow_mouse = 0;
        sensitivity = -0.2;
        natural_scroll = true;
        touchpad.natural_scroll = true;
      };

      windowrule = [
        "float on, match:class ^(kitty)$, match:title ^(bw-unlock)$"
      ];

      "$mod" = "SUPER";
      bind = [
        # Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more
        "$mod, RETURN, exec, kitty"
        "$mod, B, exec, zen-twilight -P default"
        "$mod, Q, killactive,"
        "$mod SHIFT, Q, exit,"
        "$mod CTRL, Q, exec, hyprlock"

        "$mod, SPACE, exec, walker"
        "$mod CTRL, 4, exec, grimblast copysave area"
        "$mod CTRL, 5, exec, grimblast copysave screen"
        "$mod CTRL, V, exec, walker -m clipboard"

        # "$mod, E, exec, $fileManager"
        "$mod, T, togglefloating,"
        "$mod, F, fullscreen,"
        "$mod, P, pseudo, # dwindle"
        "$mod, J, togglesplit, # dwindle"

        # Move focus with mod + arrow keys
        "$mod, left, movefocus, l"
        "$mod, right, movefocus, r"
        "$mod, up, movefocus, u"
        "$mod, down, movefocus, d"

        # Move active window with mod shift + arrow keys
        "$mod SHIFT, left, swapwindow, l"
        "$mod SHIFT, right, swapwindow, r"
        "$mod SHIFT, up, swapwindow, u"
        "$mod SHIFT, down, swapwindow, d"

        # Switch workspaces with mod + [0-9]
        "$mod, 1, workspace, 1"
        "$mod, 2, workspace, 2"
        "$mod, 3, workspace, 3"
        "$mod, 4, workspace, 4"
        "$mod, 5, workspace, 5"
        "$mod, 6, workspace, 6"
        "$mod, 7, workspace, 7"
        "$mod, 8, workspace, 8"
        "$mod, 9, workspace, 9"
        "$mod, 0, workspace, 10"

        # Move active window to a workspace with mod + SHIFT + [0-9]
        "$mod SHIFT, 1, movetoworkspace, 1"
        "$mod SHIFT, 2, movetoworkspace, 2"
        "$mod SHIFT, 3, movetoworkspace, 3"
        "$mod SHIFT, 4, movetoworkspace, 4"
        "$mod SHIFT, 5, movetoworkspace, 5"
        "$mod SHIFT, 6, movetoworkspace, 6"
        "$mod SHIFT, 7, movetoworkspace, 7"
        "$mod SHIFT, 8, movetoworkspace, 8"
        "$mod SHIFT, 9, movetoworkspace, 9"
        "$mod SHIFT, 0, movetoworkspace, 10"

        # Example special workspace (scratchpad)
        "$mod, S, togglespecialworkspace, magic"
        "$mod SHIFT, S, movetoworkspace, special:magic"

        # Open Neovim with temp.md
        "$mod, M, exec, kitty nvim ~/Cortex/00_NOTES/temp.md"

        # Scroll through existing workspaces with mod + scroll
        "$mod, mouse_down, workspace, e+1"
        "$mod, mouse_up, workspace, e-1"
      ];

      # Volume keys (wpctl, works on lock screen)
      bindel = [
        ", XF86AudioRaiseVolume, exec, wpctl set-volume @ 5%+"
        ", XF86AudioLowerVolume, exec, wpctl set-volume @ 5%-"
      ];
      bindl = [
        ", XF86AudioMute, exec, wpctl set-mute @ toggle"
        ", XF86AudioMicMute, exec, wpctl set-mute u/DEFAULT_AUDIO_SOURCE@ toggle"
      ];

      bindm = [
        # Move/resize windows with mod + LMB/RMB and dragging
        "$mod, mouse:272, movewindow"
        "$mod, mouse:273, resizewindow"
      ];
    };
  };
}
reddit.com
u/pfassina — 4 days ago

Just used my last port on my Pro Max 16

Oof..
The USL Gateway did the trick.

People had told me that 16 would be short lived. It lasted me a little over a year.

I guess that will prevent me from expanding my network in the short term. At some point I will have to decide whether I buy more switches or replace it with a 24. Hopefully it will take some time before I feel the urge to expand.

reddit.com
u/pfassina — 6 days ago
▲ 23 r/Cosmere

Question about Moash

Are those spikes hemalurgic in nature?

There are many similarities, but I thought that Hemalurgy was an investiture power granted by Ruin. How was Odium able to make use of it?

reddit.com
u/pfassina — 13 days ago