Compare commits

...

13 Commits

Author SHA1 Message Date
Alexander 873bec97fc Add wallpaper switch 2026-07-03 19:14:45 +02:00
Alexander 6f2598ef52 Handle doom emacs theme 2026-07-03 17:43:39 +02:00
Alexander 27409eb5fa Migrate to hm managed theme switch 2026-07-03 17:31:31 +02:00
Alexander 60e23edf93 Add incus, add completions for nushell 2026-07-03 14:36:45 +02:00
Alexander 6b0cb33e03 Migrate to lua hyprland 2026-06-25 18:57:22 +02:00
Alexander f0943839a8 Migrated off the split-workspaces
For some reason split-workspaces were not found by hyprland, I assume
thats because of ongoing migration of hyprland to lua
2026-06-24 18:59:02 +02:00
Alexander 3adbdf56bf Add global githook, fix emacs vterm 2026-06-24 17:13:43 +02:00
Alexander 3d112ef5d0 Add element, add doom format option 2026-06-24 17:06:17 +02:00
Alexander 6049c4aae7 Add devenv, downgrade emacs to 30.2 2026-06-19 16:51:39 +02:00
Alexander c4927658a6 Nixos update 18-06-2026 2026-06-18 22:51:55 +02:00
Alexander c496ac132b Nixos update 27-05-2026 2026-05-30 00:05:26 +02:00
Alexander 7d7deb0e6e Allow users to access fuse fs 2026-05-27 14:42:08 +02:00
Alexander 9802cc6375 Add backlog 2026-05-18 19:00:17 +02:00
20 changed files with 1179 additions and 484 deletions
Generated
+334 -175
View File
@@ -20,11 +20,11 @@
]
},
"locked": {
"lastModified": 1776876344,
"narHash": "sha256-Ubqb/agkuMJK+k19gjQgHux/eOYRc1sRGoOZOho8+VY=",
"lastModified": 1780756231,
"narHash": "sha256-tXQxKdG5716uB9/LIkLQqQwHKf5mRSpHoZhz3lyI2Cg=",
"owner": "hyprwm",
"repo": "aquamarine",
"rev": "648a13d0ee1e03a843b3e145b8ece15393058701",
"rev": "6ecde03f47172753fe5a2f334f9d3facfb7e6784",
"type": "github"
},
"original": {
@@ -33,6 +33,26 @@
"type": "github"
}
},
"backlog": {
"inputs": {
"flake-parts": "flake-parts",
"git-hooks": "git-hooks",
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1779123398,
"narHash": "sha256-8KYQSisso0bn8Z/S3+lunu3sFsMGhf2QXKu+yEWOP7k=",
"owner": "LichHunter",
"repo": "backlog",
"rev": "59507ca9f242950d45d2a6e4d3c10385869344ca",
"type": "github"
},
"original": {
"owner": "LichHunter",
"repo": "backlog",
"type": "github"
}
},
"base16": {
"inputs": {
"fromYaml": "fromYaml"
@@ -104,14 +124,14 @@
"copyparty": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
"nixpkgs": "nixpkgs_3"
},
"locked": {
"lastModified": 1777744353,
"narHash": "sha256-8UmzMm5wkq+z0kEMEjowoECa4qY813z747o0g+G/bbE=",
"lastModified": 1781648708,
"narHash": "sha256-i9ggnF31Uq3tpdp6ZMe7YAOxjTfkB7S4WjSBfXV0uMk=",
"owner": "9001",
"repo": "copyparty",
"rev": "da6e2ddca96dffc4dbe53bda25d2034428fad3d0",
"rev": "d33d11321f823f58a9109298ef886044f63b02ce",
"type": "github"
},
"original": {
@@ -127,11 +147,11 @@
]
},
"locked": {
"lastModified": 1777713215,
"narHash": "sha256-8GzXDOXckDWwST8TY5DbwYFjdvQLlP7K9CLSVx6iTTo=",
"lastModified": 1781152676,
"narHash": "sha256-RxWs5ND31KzTG7wvMM+PMfUjyNpmIEr999lqNARaM5o=",
"owner": "nix-community",
"repo": "disko",
"rev": "63b4e7e6cf75307c1d26ac3762b886b5b0247267",
"rev": "ff8702b4de27f72b4c78573dfb89ec74e36abdf1",
"type": "github"
},
"original": {
@@ -142,15 +162,15 @@
},
"emacs-overlay": {
"inputs": {
"nixpkgs": "nixpkgs_2",
"nixpkgs": "nixpkgs_4",
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1777975488,
"narHash": "sha256-JyrUp9HJCMyPj+rcrlMO2TpsKdM5Dhj7KnIg4W1CuKs=",
"lastModified": 1782301008,
"narHash": "sha256-GxQhjwF6eNDhP43Yup1LPmjKS1lZaTRvmqgYPOwv3Zs=",
"owner": "nix-community",
"repo": "emacs-overlay",
"rev": "695015ae8c42435944f62d25e6b5546948ea3e1e",
"rev": "05d06425c4e17fdf1cbc5cdbf744e5d635993245",
"type": "github"
},
"original": {
@@ -163,11 +183,11 @@
"firefox-gnome-theme": {
"flake": false,
"locked": {
"lastModified": 1776136500,
"narHash": "sha256-r0gN2brVWA351zwMV0Flmlcd6SGMvYqFbvC3DfKFM8Y=",
"lastModified": 1779670703,
"narHash": "sha256-UdfMivNMwCCqQsYDg5pSz8X2IOaOrIZLIIy+Bg3CO2o=",
"owner": "rafaelmardojai",
"repo": "firefox-gnome-theme",
"rev": "0f8ba203d475587f477e7ae12661bd8459e225b7",
"rev": "942159e73e40bf785816f7f1f5feed9ef3d7c8f9",
"type": "github"
},
"original": {
@@ -192,7 +212,41 @@
"type": "github"
}
},
"flake-compat_2": {
"flake": false,
"locked": {
"lastModified": 1767039857,
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
"owner": "NixOS",
"repo": "flake-compat",
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "flake-compat",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1777988971,
"narHash": "sha256-qIoWPDs+0/8JecyYgE3gpKQxW/4bLW/gp45vow9ioCQ=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "0678d8986be1661af6bb555f3489f2fdfc31f6ff",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_2": {
"inputs": {
"nixpkgs-lib": [
"stylix",
@@ -200,11 +254,11 @@
]
},
"locked": {
"lastModified": 1775087534,
"narHash": "sha256-91qqW8lhL7TLwgQWijoGBbiD4t7/q75KTi8NxjVmSmA=",
"lastModified": 1778716662,
"narHash": "sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "3107b77cd68437b9a76194f0f7f9c55f2329ca5b",
"rev": "f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb",
"type": "github"
},
"original": {
@@ -280,7 +334,49 @@
"type": "github"
}
},
"git-hooks": {
"inputs": {
"flake-compat": "flake-compat",
"gitignore": "gitignore",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1776796298,
"narHash": "sha256-PcRvlWayisPSjd0UcRQbhG8Oqw78AcPE6x872cPRHN8=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "3cfd774b0a530725a077e17354fbdb87ea1c4aad",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "git-hooks.nix",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"backlog",
"git-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"gitignore_2": {
"inputs": {
"nixpkgs": [
"hyprland",
@@ -348,11 +444,11 @@
]
},
"locked": {
"lastModified": 1776184304,
"narHash": "sha256-No6QGBmIv5ChiwKCcbkxjdEQ/RO2ZS1gD7SFy6EZ7rc=",
"lastModified": 1781497404,
"narHash": "sha256-9GAF8sSsnkyCVCWkomXR0T+zdSxyUlfPt6neQidimdg=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "3c7524c68348ef79ce48308e0978611a050089b2",
"rev": "1285cd3d6882a9847f2d56ed5541b3350c8a6162",
"type": "github"
},
"original": {
@@ -430,17 +526,17 @@
"hyprutils": "hyprutils",
"hyprwayland-scanner": "hyprwayland-scanner",
"hyprwire": "hyprwire",
"nixpkgs": "nixpkgs_3",
"nixpkgs": "nixpkgs_5",
"pre-commit-hooks": "pre-commit-hooks",
"systems": "systems",
"xdph": "xdph"
},
"locked": {
"lastModified": 1777910456,
"narHash": "sha256-YXQ5bhn5mklMsOuVqze3QBqqL+8zsUum24Yx1K2Rb+w=",
"lastModified": 1782315209,
"narHash": "sha256-xKpodJ++lnLqRpmcH5OSimuo874wmgm3rD85J3GDmUw=",
"ref": "refs/heads/main",
"rev": "eff3bfe261e90b8950b59379ca7815f735a7aab6",
"revCount": 7252,
"rev": "87cd2a5f6697a5923c4f427e9b399d79a354a7b8",
"revCount": 7499,
"type": "git",
"url": "https://github.com/hyprwm/Hyprland"
},
@@ -512,11 +608,11 @@
]
},
"locked": {
"lastModified": 1777937752,
"narHash": "sha256-QDc78DC6xhWKpPJzsPEJBBFYpTb+g4kO6+ydRYLU4f4=",
"lastModified": 1781442805,
"narHash": "sha256-Kt56e6Bq2sfqN8yq1RHsS6z+8QKCZelmhaeQQRtZyqU=",
"owner": "hyprwm",
"repo": "hyprland-plugins",
"rev": "b6e080577daf6575b95e6733dd2e2aef714bcf10",
"rev": "1f90c674d51a1ef83c725cd6d02280b4c969fdf7",
"type": "github"
},
"original": {
@@ -566,11 +662,11 @@
]
},
"locked": {
"lastModified": 1776426736,
"narHash": "sha256-rl7i4aY+9p8LysJp7o8uRWahCkpFznCgGHXszlTw7b0=",
"lastModified": 1777320127,
"narHash": "sha256-Qu+Wf2Bp5qUjyn2YpZNq8a7JyzTGowhT1knrwE38a9U=",
"owner": "hyprwm",
"repo": "hyprlang",
"rev": "7833ff33b2e82d3406337b5dcf0d1cec595d83e9",
"rev": "090117506ddc3d7f26e650ff344d378c2ec329cc",
"type": "github"
},
"original": {
@@ -643,11 +739,11 @@
]
},
"locked": {
"lastModified": 1777492286,
"narHash": "sha256-PwuoEJQcjSKJNP5T55qhfDwIP0tw5zxEhfu8GDfKfeg=",
"lastModified": 1780251518,
"narHash": "sha256-fG9xbb1SOAAJ+2kJRakp3ch+BmA/3dEg/K3PoAZTKkw=",
"owner": "hyprwm",
"repo": "hyprutils",
"rev": "ec5c0c709706bad5b82f667fd8758eae442577ce",
"rev": "40ede2e7bdec80ba5d4c443160d905e9f841ae5f",
"type": "github"
},
"original": {
@@ -668,11 +764,11 @@
]
},
"locked": {
"lastModified": 1777148232,
"narHash": "sha256-Uv0WZLhu89SafuSOmYDA7akrPt4wBRmsa1ucasO5aXg=",
"lastModified": 1777159683,
"narHash": "sha256-Jxixw6wZphUp+nHYxOKUYSckL17QMBx2d5Zp0rJHr1g=",
"owner": "hyprwm",
"repo": "hyprwayland-scanner",
"rev": "fec9cf1abcc1011e46f0a0986f46bf93c6bf8b92",
"rev": "b8632713a6beaf28b56f2a7b0ab2fb7088dbb404",
"type": "github"
},
"original": {
@@ -697,11 +793,11 @@
]
},
"locked": {
"lastModified": 1776728575,
"narHash": "sha256-z9eGphrArEBpl1O/GCH0wlY6z4K9vA6yWh2gAS6qytU=",
"lastModified": 1778410714,
"narHash": "sha256-o6RzFj4nJXaPRY7EM01siuCQeT41RfwwmcmFQqwFJJg=",
"owner": "hyprwm",
"repo": "hyprwire",
"rev": "f3a80888783702a39691b684d099e16b83ed4702",
"rev": "85148a8e612808cf5ddb25d0b3c5840f3498a7dc",
"type": "github"
},
"original": {
@@ -712,7 +808,7 @@
},
"minegrub-theme": {
"inputs": {
"nixpkgs": "nixpkgs_4"
"nixpkgs": "nixpkgs_6"
},
"locked": {
"lastModified": 1775570192,
@@ -750,11 +846,11 @@
]
},
"locked": {
"lastModified": 1777888924,
"narHash": "sha256-CZ9akWHCqoWlyi+alSalkzaA0hq1Cs1Tv7MnM/zMVLQ=",
"lastModified": 1781513248,
"narHash": "sha256-YLeEcfvlQiNXP9bVoIwyB+NMjMxJmkwv/y+AP/7RWYo=",
"owner": "Mic92",
"repo": "nix-ld",
"rev": "4161b94cb918d228f0452927950ed295c0131a48",
"rev": "b320f5cb8b7f141c224c3631539cd0c45fcf7ee3",
"type": "github"
},
"original": {
@@ -800,12 +896,15 @@
}
},
"nixos-hardware": {
"inputs": {
"nixpkgs": "nixpkgs_7"
},
"locked": {
"lastModified": 1777917524,
"narHash": "sha256-k+LVe9YaO2BEPB9AaCtTtOMCeGi4dxDo6gt4Un3qoPY=",
"lastModified": 1782166108,
"narHash": "sha256-/EtnQBcKbsaCAGQ5VRcplrHRkR4ryqyLMpBfkVuG9Xw=",
"owner": "NixOS",
"repo": "nixos-hardware",
"rev": "df7783100babf59001340a7a874ba3824e441ecb",
"rev": "875776f0252fcb8618bb948640a0d1f7a5b362be",
"type": "github"
},
"original": {
@@ -816,6 +915,98 @@
}
},
"nixpkgs": {
"locked": {
"lastModified": 1770073757,
"narHash": "sha256-Vy+G+F+3E/Tl+GMNgiHl9Pah2DgShmIUBJXmbiQPHbI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "47472570b1e607482890801aeaf29bfb749884f6",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1777168982,
"narHash": "sha256-GOkGPcboWE9BmGCRMLX3worL4EMnsnG8MyKmXNeYuhQ=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "f5901329dade4a6ea039af1433fb087bd9c1fe14",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1782116945,
"narHash": "sha256-G3tw/IXmaH6IQ2upZvhuN9sG8CkuX+BLuJDpE8hz0Ds=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "34268251cf5547d39063f2c5ea9a196246f7f3a6",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-26.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_10": {
"locked": {
"lastModified": 1682134069,
"narHash": "sha256-TnI/ZXSmRxQDt2sjRYK/8j8iha4B4zP2cnQCZZ3vp7k=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "fd901ef4bf93499374c5af385b2943f5801c0833",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"nixpkgs_11": {
"locked": {
"lastModified": 1781074563,
"narHash": "sha256-md8WlXOlfnIeHeOScMTTHFyf2d6iaTwPl2apR5EQ3P4=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "9ae611a455b90cf061d8f332b977e387bda8e1ca",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1778093112,
"narHash": "sha256-18rT4EfMrtYVMQX7AMAEsnv5KhCryLxGolmJ+v+vZdM=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "cf9db9282552bb3f2743fc9ed3852d239692089a",
"type": "github"
},
"original": {
"owner": "nixos",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1748162331,
"narHash": "sha256-rqc2RKYTxP3tbjA+PB3VMRQNnjesrT0pEofXQTrMsS8=",
@@ -830,55 +1021,39 @@
"type": "indirect"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1777673416,
"narHash": "sha256-5c2POKPOjU40Kh0MirOdScBLG0bu9TAuPYAtPRNZMBs=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "26ef669cffa904b6f6832ab57b77892a37c1a671",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1777578337,
"narHash": "sha256-Ad49moKWeXtKBJNy2ebiTQUEgdLyvGmTeykAQ9xM+Z4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "15f4ee454b1dce334612fa6843b3e05cf546efab",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1776877367,
"narHash": "sha256-EHq1/OX139R1RvBzOJ0aMRT3xnWyqtHBRUBuO1gFzjI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "0726a0ecb6d4e08f6adced58726b95db924cef57",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1781577229,
"narHash": "sha256-lrp67w8AulE9Ks53n27I45ADSzbOCn4H+CNW1Ck8B+8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "567a49d1913ce81ac6e9582e3553dd90a955875f",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_5": {
"locked": {
"lastModified": 1780749050,
"narHash": "sha256-3av0pIjlOWQ6rDbNOmpUSvbNnJkGORQKKjb4LtCZsIY=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "a799d3e3886da994fa307f817a6bc705ae538eeb",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_6": {
"locked": {
"lastModified": 1689850295,
"narHash": "sha256-fUYf6WdQlhd2H+3aR8jST5dhFH1d0eE22aes8fNIfyk=",
@@ -894,7 +1069,20 @@
"type": "github"
}
},
"nixpkgs_5": {
"nixpkgs_7": {
"locked": {
"lastModified": 1767892417,
"narHash": "sha256-8bW3q88CEg2u4hSP66Vf4lpbLonHz7hqDNBMcCY7E9U=",
"rev": "3497aa5c9457a9d88d71fa93a4a8368816fbeeba",
"type": "tarball",
"url": "https://releases.nixos.org/nixos/unstable/nixos-26.05pre924538.3497aa5c9457/nixexprs.tar.xz"
},
"original": {
"type": "tarball",
"url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"
}
},
"nixpkgs_8": {
"locked": {
"lastModified": 1767313136,
"narHash": "sha256-16KkgfdYqjaeRGBaYsNrhPRRENs0qzkQVUooNHtoy2w=",
@@ -910,7 +1098,7 @@
"type": "github"
}
},
"nixpkgs_6": {
"nixpkgs_9": {
"locked": {
"lastModified": 1775036866,
"narHash": "sha256-ZojAnPuCdy657PbTq5V0Y+AHKhZAIwSIT2cb8UgAz/U=",
@@ -926,36 +1114,6 @@
"type": "github"
}
},
"nixpkgs_7": {
"locked": {
"lastModified": 1682134069,
"narHash": "sha256-TnI/ZXSmRxQDt2sjRYK/8j8iha4B4zP2cnQCZZ3vp7k=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "fd901ef4bf93499374c5af385b2943f5801c0833",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"nixpkgs_8": {
"locked": {
"lastModified": 1775710090,
"narHash": "sha256-ar3rofg+awPB8QXDaFJhJ2jJhu+KqN/PRCXeyuXR76E=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "4c1018dae018162ec878d42fec712642d214fdfa",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nur": {
"inputs": {
"flake-parts": [
@@ -968,11 +1126,11 @@
]
},
"locked": {
"lastModified": 1777598946,
"narHash": "sha256-X239dAGaU1+gfDj8jKH8GzlqKMcxaVfXOio+uzBOkeE=",
"lastModified": 1780281641,
"narHash": "sha256-M/+hUKoKbHXpV0xGVfELbN1Ds1aoe3pL5p5/t46YhVo=",
"owner": "nix-community",
"repo": "NUR",
"rev": "5d55af01c0f86be583931fe99207fc56c14134b3",
"rev": "30f9ae2f04174de63ba8bcf3580ca90843b28a01",
"type": "github"
},
"original": {
@@ -983,19 +1141,19 @@
},
"pre-commit-hooks": {
"inputs": {
"flake-compat": "flake-compat",
"gitignore": "gitignore",
"flake-compat": "flake-compat_2",
"gitignore": "gitignore_2",
"nixpkgs": [
"hyprland",
"nixpkgs"
]
},
"locked": {
"lastModified": 1776796298,
"narHash": "sha256-PcRvlWayisPSjd0UcRQbhG8Oqw78AcPE6x872cPRHN8=",
"lastModified": 1778507602,
"narHash": "sha256-kTwur1wV+01SdqskVMSo6JMEpg71ps3HpbFY2GsflKs=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "3cfd774b0a530725a077e17354fbdb87ea1c4aad",
"rev": "61ab0e80d9c7ab14c256b5b453d8b3fb0189ba0a",
"type": "github"
},
"original": {
@@ -1056,6 +1214,7 @@
},
"root": {
"inputs": {
"backlog": "backlog",
"copyparty": "copyparty",
"disko": "disko",
"emacs-overlay": "emacs-overlay",
@@ -1066,7 +1225,7 @@
"nix-ld": "nix-ld",
"nixos-generators": "nixos-generators",
"nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs_5",
"nixpkgs": "nixpkgs_8",
"sops-nix": "sops-nix",
"split-monitor-workspaces": "split-monitor-workspaces",
"stylix": "stylix",
@@ -1084,11 +1243,11 @@
]
},
"locked": {
"lastModified": 1777944972,
"narHash": "sha256-VfGRo1qTBKOe3s2gOv8LSoA6Fk19PvBlwQ1ECN0Evn8=",
"lastModified": 1782165805,
"narHash": "sha256-478kKQBvK6SYTOdN2h9jhKJv94nbXRbFMfuL1WshErg=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "c591bf665727040c6cc5cb409079acb22dcce33c",
"rev": "56b24064fdcaedca53553b1a6d607fd23b613a24",
"type": "github"
},
"original": {
@@ -1105,15 +1264,15 @@
"nix-filter": "nix-filter"
},
"locked": {
"lastModified": 1777409658,
"narHash": "sha256-fBUjkrBbODd6c6j9sRfWvxqJrBHMHvp8WjAASfAqin4=",
"owner": "Duckonaut",
"lastModified": 1782237065,
"narHash": "sha256-Oxtr8k+qu4Kd/7BJ5eo8Pfoje8PDIO1YK2+mhCkHRhQ=",
"owner": "zjeffer",
"repo": "split-monitor-workspaces",
"rev": "206fc9ed4e35bdaea60c4ae16927376ff3ebac9d",
"rev": "968a6a603cabf8ab8f5ce5a402e8ed3bfcae69ce",
"type": "github"
},
"original": {
"owner": "Duckonaut",
"owner": "zjeffer",
"repo": "split-monitor-workspaces",
"type": "github"
}
@@ -1125,7 +1284,7 @@
"base16-helix": "base16-helix",
"base16-vim": "base16-vim",
"firefox-gnome-theme": "firefox-gnome-theme",
"flake-parts": "flake-parts",
"flake-parts": "flake-parts_2",
"gnome-shell": "gnome-shell",
"nixpkgs": [
"unstable"
@@ -1138,11 +1297,11 @@
"tinted-zed": "tinted-zed"
},
"locked": {
"lastModified": 1777835090,
"narHash": "sha256-VLH8zPweblCOvpnQXp4fVs7f6Q79YhXF5XFKlOrvIFk=",
"lastModified": 1782310521,
"narHash": "sha256-vsxcG0i8e4EPfdnhMTKMVzD1825H2vG1BBslzom9wxg=",
"owner": "nix-community",
"repo": "stylix",
"rev": "7989a1054b01153212dede6005abfd1576b8328c",
"rev": "e084d011e7ee9302aceaaf6c1fc28a9ace09e16a",
"type": "github"
},
"original": {
@@ -1214,7 +1373,7 @@
"thefuck": {
"inputs": {
"flake-utils": "flake-utils_2",
"nixpkgs": "nixpkgs_6",
"nixpkgs": "nixpkgs_9",
"pyproject-build-systems": "pyproject-build-systems",
"pyproject-nix": "pyproject-nix",
"uv2nix": "uv2nix"
@@ -1252,11 +1411,11 @@
"tinted-schemes": {
"flake": false,
"locked": {
"lastModified": 1777041405,
"narHash": "sha256-BAGZ7ObFV/9Z61OJZun7ifPyhkuHqNuW1QIhQ8LuzCo=",
"lastModified": 1777806186,
"narHash": "sha256-PDF0/wObw4nIsSBeXVYLsloXOiphXCgIdsrNcVXguKs=",
"owner": "tinted-theming",
"repo": "schemes",
"rev": "5f868b3a338b6904c47f3833b9c411be641983a8",
"rev": "0c94645546f4f3ddac77a1a5fce54eb95bf50795",
"type": "github"
},
"original": {
@@ -1268,11 +1427,11 @@
"tinted-tmux": {
"flake": false,
"locked": {
"lastModified": 1777169200,
"narHash": "sha256-h7dDbIzP5hDr9v97w9PL6jdAgXawmj6krcH+959rqpU=",
"lastModified": 1778379944,
"narHash": "sha256-wPDFzMGSlARlw0Sfsn48Q2+jPSfk6N0Ng6BC/d+7Q24=",
"owner": "tinted-theming",
"repo": "tinted-tmux",
"rev": "f798c2dce44ef815bb6b8f05a82135c7942d35ac",
"rev": "fe0203a198690e71a5ff11e08812a4673de3678d",
"type": "github"
},
"original": {
@@ -1284,11 +1443,11 @@
"tinted-zed": {
"flake": false,
"locked": {
"lastModified": 1777463218,
"narHash": "sha256-Bhkozqtq3BKLqWTlmKm8uAptfX4aRGI8QX3eEL54Vpc=",
"lastModified": 1778378178,
"narHash": "sha256-OXPXRIQgGwV77HjYRryOHguh4ALX96jkg+tseLkGgHA=",
"owner": "tinted-theming",
"repo": "base16-zed",
"rev": "5768d08ed2e7944a26a958868cdb073cb8856dae",
"rev": "9cd816033ff969415b190722cddf134e78a5665f",
"type": "github"
},
"original": {
@@ -1299,11 +1458,11 @@
},
"unstable": {
"locked": {
"lastModified": 1777954456,
"narHash": "sha256-hGdgeU2Nk87RAuZyYjyDjFL6LK7dAZN5RE9+hrDTkDU=",
"lastModified": 1781577229,
"narHash": "sha256-lrp67w8AulE9Ks53n27I45ADSzbOCn4H+CNW1Ck8B+8=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "549bd84d6279f9852cae6225e372cc67fb91a4c1",
"rev": "567a49d1913ce81ac6e9582e3553dd90a955875f",
"type": "github"
},
"original": {
@@ -1320,11 +1479,11 @@
]
},
"locked": {
"lastModified": 1777988791,
"narHash": "sha256-DtbtSW5+Hls7z+D9BfsAXvFuivt5iZ0OzUXjQ8d8lB8=",
"lastModified": 1782358560,
"narHash": "sha256-vCcLh9pw3XO/+Lxk8r6xv6QnoCrTfGqiACcI7O637Wg=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "d987617879f613053f6fdf4491fe28ce0283d543",
"rev": "3a70e333f2950c302e875c44cfcfaff3f80f36bc",
"type": "github"
},
"original": {
@@ -1362,7 +1521,7 @@
"vscode-server": {
"inputs": {
"flake-utils": "flake-utils_3",
"nixpkgs": "nixpkgs_7"
"nixpkgs": "nixpkgs_10"
},
"locked": {
"lastModified": 1770124655,
@@ -1406,11 +1565,11 @@
]
},
"locked": {
"lastModified": 1777035886,
"narHash": "sha256-m1TNuBoSXUBSKhD9UVMkU90M0wFTPTfvIOOltO8IM8A=",
"lastModified": 1780133819,
"narHash": "sha256-0YPKIY3dlnR7SPq7Z8ekFVvzFsfeiAtEj+QUI3KHrlI=",
"owner": "hyprwm",
"repo": "xdg-desktop-portal-hyprland",
"rev": "ecfcdcc781f48821d83e1e2a0e30d7beca0eeb5e",
"rev": "4a170c0ba96fd37374f93d8f91c9ed91814828ac",
"type": "github"
},
"original": {
@@ -1422,14 +1581,14 @@
"zen-browser": {
"inputs": {
"home-manager": "home-manager_2",
"nixpkgs": "nixpkgs_8"
"nixpkgs": "nixpkgs_11"
},
"locked": {
"lastModified": 1777959875,
"narHash": "sha256-kL2gxkGbIawygfc+DJhWBXAcRplFQlLyDBb4JHCxTzw=",
"lastModified": 1782144240,
"narHash": "sha256-RgCWSv7AJZCwPhCzz+J0lvwp1WBz9ouvCnnlmvu0xfw=",
"owner": "0xc000022070",
"repo": "zen-browser-flake",
"rev": "604c3c8814c87eac54d804253ab520cb8fac7b21",
"rev": "d1693556428967f8b4eef128feb090421ddcaf15",
"type": "github"
},
"original": {
+4 -2
View File
@@ -60,7 +60,7 @@
};
split-monitor-workspaces = {
url = "github:Duckonaut/split-monitor-workspaces";
url = "github:zjeffer/split-monitor-workspaces";
inputs.hyprland.follows = "hyprland";
};
@@ -69,6 +69,8 @@
minegrub-theme.url = "github:Lxtharia/minegrub-theme";
thefuck.url = "github:LichHunter/thefuck";
backlog.url = "github:LichHunter/backlog";
};
outputs = {
@@ -197,9 +199,9 @@
# Applications
inputs.copyparty.nixosModules.default
inputs.vscode-server.nixosModules.default
inputs.stylix.nixosModules.stylix
inputs.nix-ld.nixosModules.nix-ld
inputs.minegrub-theme.nixosModules.default
inputs.backlog.nixosModules.default
./modules
] # Extra modules
+5 -3
View File
@@ -37,9 +37,11 @@ in {
"hyprland/window"
];
"hyprland/workspaces" = {
active-only = true;
};
# NOTE: the hyprland/workspaces module is configured in
# ~/.config/waybar/config.json (waybar4.json), which is merged in via
# `include` and overrides anything set here. "Show only workspaces
# with windows" is achieved by disabling persistent workspaces in the
# Hyprland split-monitor-workspaces setup, not by a waybar flag.
modules-center = [
"clock"
+39 -9
View File
@@ -11,16 +11,46 @@ in {
type = types.attrs;
default = {};
};
carapace = {
enable = mkEnableOption "carapace external completions";
};
};
config = mkIf cfg.enable {
programs.nushell = {
enable = true;
config = mkIf cfg.enable (mkMerge [
{
programs.nushell = {
enable = true;
settings = {
};
} // (lib.optionalAttrs (cfg.shellAliases != null) {
shellAliases = cfg.shellAliases;
});
};
settings = {
};
} // (lib.optionalAttrs (cfg.shellAliases != null) {
shellAliases = cfg.shellAliases;
});
}
(mkIf cfg.carapace.enable {
home.packages = [ pkgs.carapace ];
programs.nushell.extraConfig = ''
let carapace_completer = {|spans: list<string>|
# if the current command is an alias, get the aliased command
let expanded_alias = (scope aliases | where name == $spans.0 | get value.0?.0?)
# overwrite
let spans = (if $expanded_alias != null {
$spans
| skip 1
| prepend ($expanded_alias | split row " " | take 1)
} else { $spans })
carapace $spans.0 nushell ...$spans
| from json
}
$env.config.completions.external = {
enable: true
max_results: 100
completer: $carapace_completer
}
'';
})
]);
}
+174 -8
View File
@@ -1,4 +1,4 @@
{ config, lib, pkgs, ... }:
{ config, lib, pkgs, options, ... }:
with lib;
@@ -18,6 +18,82 @@ let
};
};
# Generate all theme-variant combinations
themeVariants = concatMapAttrs (name: theme: {
"${name}-dark" = { scheme = theme.dark; polarity = "dark"; };
"${name}-light" = { scheme = theme.light; polarity = "light"; };
}) cfg.themes;
# Base is gruvbox-dark, everything else is a specialisation
baseVariant = "gruvbox-dark";
specialisationVariants = filterAttrs (name: _: name != baseVariant) themeVariants;
availableVariants = concatStringsSep " " (attrNames themeVariants);
# `variant:schemeFile` pairs so the wallpaper picker can read each variant's
# base16 palette at runtime.
variantSchemes = concatStringsSep " "
(mapAttrsToList (variant: v: "${variant}:${v.scheme}") themeVariants);
# variant:doomtheme pairs consumed by the theme-switch script's
# best-effort Doom Emacs hook (see ./theme-switch.sh).
doomThemeMap = concatStringsSep " "
(mapAttrsToList (variant: theme: "${variant}:${theme}") cfg.doomThemes);
# Stylix is only declared on hosts that import its Home Manager module
# (e.g. `fujin`). Servers (susano, izanagi, amaterasu, ...) don't, so
# `stylix` isn't declared there. We probe option *declarations* (not
# config values) to avoid an evaluation cycle.
hasStylix = options ? stylix;
# --- Wallpaper handling (runtime-cloned repo + palette matching) ----------
wallpapersEnabled = cfg.wallpaperRepo != null;
wallpapersDir = "${config.home.homeDirectory}/Wallpapers";
# hyprpaper's config points here; set-wallpaper rebinds this symlink, so we
# never have to write hyprpaper config ourselves.
wallpaperSymlink = "${config.xdg.stateHome}/theme/wallpaper-current";
wallpaper-pick = pkgs.writeShellScriptBin "wallpaper-pick" ''
SCRIPT_TAG="wallpaper-pick"
${builtins.readFile ./log.sh}
wallpapersDir="${wallpapersDir}"
wallpaperRepo="${cfg.wallpaperRepo or ""}"
variantSchemes="${variantSchemes}"
MAGICK="${getExe pkgs.imagemagick}"
GIT="${getExe pkgs.git}"
${builtins.readFile ./wallpaper-pick.sh}
'';
wallpaper-set = pkgs.writeShellScriptBin "wallpaper-set" ''
SCRIPT_TAG="wallpaper-set"
${builtins.readFile ./log.sh}
wallpaperSymlink="${wallpaperSymlink}"
${builtins.readFile ./set-wallpaper.sh}
'';
# Applied once at login (after hyprpaper) to seed a base-variant wallpaper.
wallpaper-init = pkgs.writeShellScript "wallpaper-init" ''
wp="$(${getExe wallpaper-pick} ${baseVariant} 2>/dev/null)" || exit 0
[ -n "$wp" ] && ${getExe wallpaper-set} "$wp" || true
'';
# Userspace theme switcher: activates a pre-built Home Manager
# specialisation generation. No sudo, no OS rebuild — just runs the
# specialisation's activation script in the base HM generation.
#
# The script logic lives in ./theme-switch.sh (plain shell, no Nix
# escaping); we only inject the config-derived values it needs.
theme-switch = pkgs.writeShellScriptBin "theme-switch" ''
SCRIPT_TAG="theme-switch"
${builtins.readFile ./log.sh}
baseVariant="${baseVariant}"
availableVariants="${availableVariants}"
doomThemes="${doomThemeMap}"
wallpapersEnabled="${if wallpapersEnabled then "1" else "0"}"
wallpaperPickBin="${if wallpapersEnabled then getExe wallpaper-pick else ""}"
wallpaperSetBin="${if wallpapersEnabled then getExe wallpaper-set else ""}"
${builtins.readFile ./theme-switch.sh}
'';
in {
options.dov.dynamic-theme = {
enable = mkEnableOption "dynamic theme switching";
@@ -38,14 +114,104 @@ in {
default = builtinThemes;
description = "Available themes with dark and light variants";
};
};
config = mkIf cfg.enable {
# HM-level stylix config inherits from NixOS level
# Specialisations are handled by NixOS module
stylix = {
enable = true;
autoEnable = true;
doomThemes = mkOption {
type = types.attrsOf types.str;
default = {
gruvbox-dark = "doom-gruvbox";
gruvbox-light = "doom-one-light";
catppuccin-dark = "doom-one";
catppuccin-light = "doom-one-light";
};
description = ''
Mapping from theme variant name (e.g. "gruvbox-dark") to the Doom
Emacs theme symbol (e.g. "doom-gruvbox") that theme-switch will
live-load via emacsclient when switching to that variant. Variants
absent from this map are left unchanged in Emacs.
Only themes actually installed in Doom will load; the defaults use
themes bundled with doom-themes (so they work out of the box, though
catppuccin variants fall back to generic dark/light). For accurate
catppuccin colours, install the `catppuccin-theme` Emacs package and
map the variants to `catppuccin-mocha` / `catppuccin-latte`.
'';
};
wallpaperRepo = mkOption {
type = types.nullOr types.str;
default = null;
example = "https://example.org/me/wallpapers.git";
description = ''
Git URL of a wallpaper repository. When set, theme-switch also picks
a random wallpaper whose palette matches the current variant and
applies it via hyprpaper. The repo is cloned to
`~/Wallpapers` on first use (a one-time, runtime cost — it is NOT
fetched at build time, so `nix build` stays fast).
'';
};
};
config = mkIf cfg.enable (mkMerge [
{
home.packages = [ theme-switch ]
++ optionals wallpapersEnabled [ wallpaper-pick wallpaper-set ];
}
# Only reference the `stylix` option where it is actually declared.
# `mkIf false` is NOT enough: the module system still rejects a
# definition (even a disabled one) for an option that does not exist,
# which breaks every host that doesn't import stylix. `optionalAttrs`
# (keyed on `options ?`, i.e. *declarations* — never a config value) is
# the recursion-free way to gate structure on stylix presence.
(optionalAttrs hasStylix {
stylix = {
enable = true;
autoEnable = true;
# Base scheme/polarity; overridable per specialisation below.
base16Scheme = mkDefault themeVariants.${baseVariant}.scheme;
polarity = mkDefault themeVariants.${baseVariant}.polarity;
# When we manage hyprpaper's wallpaper ourselves, disable stylix's
# hyprpaper target so the two don't fight over the wallpaper path.
targets.hyprpaper.enable = mkForce (!wallpapersEnabled);
};
# Generate Home Manager specialisations for every non-base variant.
# Each is pre-built into the nix store during the single rebuild and
# activated userspace via `theme-switch` (no sudo, no OS rebuild).
specialisation = mapAttrs (name: variant: {
configuration = {
stylix = {
base16Scheme = mkForce variant.scheme;
polarity = mkForce variant.polarity;
};
};
}) specialisationVariants;
})
# Wallpaper handling. These options always exist structurally (HM ships
# services.hyprpaper and a freeform systemd.user.services), so we gate
# the *values* with mkIf/optionals rather than shaping structure — that
# avoids the config-depends-on-config recursion that optionalAttrs on a
# config value would cause.
{
services.hyprpaper.enable = wallpapersEnabled;
services.hyprpaper.settings = mkIf wallpapersEnabled {
splash = false;
wallpaper = [{ monitor = ""; path = wallpaperSymlink; }];
};
systemd.user.services.wallpaper-init = mkIf wallpapersEnabled {
Unit = {
Description = "Pick and apply a wallpaper matching the base theme";
After = [ "hyprpaper.service" ];
PartOf = [ "graphical-session.target" ];
};
Service = {
Type = "oneshot";
ExecStart = "${wallpaper-init}";
};
Install.WantedBy = [ "graphical-session.target" ];
};
}
]);
}
+24
View File
@@ -0,0 +1,24 @@
# shellcheck shell=bash
# Colorful, TTY-aware logging helpers: log_info / log_warn / log_error.
#
# Everything is written to *stderr*, so a script's stdout stays a clean data
# channel (e.g. wallpaper-pick prints the chosen image path on stdout while
# its progress goes to stderr). Set SCRIPT_TAG to prefix every line with the
# originating script, e.g. "[theme-switch] selecting wallpaper...".
#
# Colors are auto-disabled when stderr isn't a terminal or NO_COLOR is set.
__theme_log_init() {
if [ -t 2 ] && [ -z "${NO_COLOR:-}" ]; then
__C_RESET=$'\033[0m'
__C_INFO=$'\033[1;34m' # blue
__C_WARN=$'\033[1;33m' # yellow
__C_ERR=$'\033[1;31m' # red
else
__C_RESET=""; __C_INFO=""; __C_WARN=""; __C_ERR=""
fi
}
__theme_log_init
log_info() { printf '%s%s%s%s\n' "${__C_INFO}" "${SCRIPT_TAG:+[$SCRIPT_TAG] }" "$*" "${__C_RESET}" >&2; }
log_warn() { printf '%s%s%s%s\n' "${__C_WARN}" "${SCRIPT_TAG:+[$SCRIPT_TAG] }" "warning: $*" "${__C_RESET}" >&2; }
log_error() { printf '%s%s%s%s\n' "${__C_ERR}" "${SCRIPT_TAG:+[$SCRIPT_TAG] }" "error: $*" "${__C_RESET}" >&2; }
+27
View File
@@ -0,0 +1,27 @@
# shellcheck shell=bash
# set-wallpaper — bind the runtime wallpaper symlink to $1 and restart hyprpaper
# so it picks up the new image. hyprpaper's config (managed by Home Manager)
# points at the symlink, so we never write hyprpaper config ourselves.
#
# Env (injected by the Nix wrapper):
# wallpaperSymlink path to the symlink hyprpaper's `wallpaper.path` reads
# Arg: image path
: "${wallpaperSymlink:?set-wallpaper: wallpaperSymlink not set}"
set -euo pipefail
target="${1:?usage: set-wallpaper <image-path>}"
[ -f "$target" ] || { log_error "not a file: $target"; exit 1; }
mkdir -p "$(dirname "$wallpaperSymlink")"
ln -sfn "$target" "$wallpaperSymlink"
# Apply live by (re)starting the user hyprpaper service. `systemctl restart`
# starts the unit even if it is inactive — important because a freshly-added
# hyprpaper service won't be running until the first switch. Tolerate the
# service being absent (e.g. on a host without hyprpaper).
if command -v systemctl >/dev/null 2>&1 && systemctl --user restart hyprpaper 2>/dev/null; then
log_info "applied $(basename "$target") (hyprpaper started)"
else
log_warn "could not start hyprpaper; wallpaper symlink set but not displayed"
fi
+115
View File
@@ -0,0 +1,115 @@
# shellcheck shell=bash
# theme-switch — activate a pre-built Home Manager specialisation.
#
# Expects these variables to be injected by the Nix wrapper:
# baseVariant the variant that is the generation itself (not a
# specialisation), activated via `$gen/activate`.
# availableVariants space-separated list of all variant names (help text).
# doomThemes optional space-separated `variant:doomtheme` pairs for
# the best-effort Doom Emacs live-switch (may be empty).
#
# Standalone usage for testing:
# baseVariant=gruvbox-dark \
# availableVariants="gruvbox-dark gruvbox-light catppuccin-dark catppuccin-light" \
# doomThemes="gruvbox-dark:doom-gruvbox" \
# bash theme-switch.sh <variant>
: "${baseVariant:?theme-switch: baseVariant not set}"
: "${availableVariants:?theme-switch: availableVariants not set}"
: "${doomThemes:=}"
set -euo pipefail
variant="${1:-}"
if [ -z "$variant" ]; then
echo "Usage: theme-switch <variant>"
echo "Available: ${availableVariants}"
exit 1
fi
# Resolve the Home Manager *base* generation — the one built by NixOS that
# actually contains the `specialisation/` directory holding every variant's
# activation script.
#
# IMPORTANT: do NOT use `current-home` / the HM profile as the primary
# source. Activating a specialisation repoints those to the specialisation's
# *leaf* generation, which has no `specialisation/` of its own — so after
# switching once, every other variant (and the base) would become unfindable.
# The NixOS-managed `home-manager-«user».service` unit references the base
# generation and only changes on a rebuild.
user="${USER:-$(id -un)}"
gen=""
if unit="$(systemctl cat "home-manager-${user}.service" 2>/dev/null)"; then
gen="$(printf '%s\n' "$unit" | grep -oE '/nix/store/[0-9a-z]+-home-manager-generation' | head -n1)"
fi
# Fallbacks for standalone Home Manager, where the profile symlink / gcroot
# points at the base generation (not a specialisation leaf).
for candidate in \
"${HOME}/.local/state/home-manager/gcroots/current-home" \
"/nix/var/nix/profiles/per-user/${user}/home-manager" \
"${HOME}/.local/state/home-manager/home-manager-generation"
do
[ -n "$gen" ] && break
if [ -e "$candidate" ]; then
gen="$(readlink -e "$candidate")" || gen=""
fi
done
if [ -z "$gen" ]; then
log_error "could not resolve Home Manager base generation"
exit 1
fi
case "$variant" in
"${baseVariant}")
# Base variant is the generation itself, not a specialisation.
activate="$gen/activate"
;;
*)
activate="$gen/specialisation/$variant/activate"
;;
esac
if [ ! -x "$activate" ]; then
log_error "variant '$variant' not found at $activate"
log_info "available: ${availableVariants}"
exit 1
fi
log_info "switching theme to ${variant}"
# Best-effort: live-switch the running Doom Emacs daemon too. No config
# files are touched; if the daemon isn't running or emacsclient isn't
# installed (e.g. on a server), this is silently skipped.
doom_theme=""
if [ -n "$doomThemes" ]; then
for pair in $doomThemes; do
case "$pair" in
"${variant}":*) doom_theme="${pair#*:}"; break ;;
esac
done
fi
if [ -n "$doom_theme" ]; then
if command -v emacsclient >/dev/null 2>&1 \
&& emacsclient --eval "(progn (mapc (function disable-theme) custom-enabled-themes) (load-theme (quote ${doom_theme}) t))" >/dev/null 2>&1; then
log_info "doom: ${doom_theme}"
else
log_warn "doom theme not applied (daemon not running or '${doom_theme}' not installed)"
fi
fi
# Pick a palette-matching wallpaper and apply it. This BLOCKS — on the very
# first run wallpaper-pick clones the wallpaper repo and builds the palette
# index, which can take a few minutes; progress is logged on stderr by the
# pick/set scripts. Failures fall back to leaving the wallpaper unchanged.
if [ "${wallpapersEnabled:-0}" = "1" ] && [ -n "${wallpaperPickBin:-}" ] && [ -n "${wallpaperSetBin:-}" ]; then
if wp="$("$wallpaperPickBin" "$variant")" && [ -n "$wp" ]; then
"$wallpaperSetBin" "$wp" || log_warn "wallpaper apply failed"
else
log_warn "wallpaper selection failed; leaving wallpaper unchanged"
fi
fi
log_info "activating Home Manager specialisation"
exec "$activate"
+131
View File
@@ -0,0 +1,131 @@
# shellcheck shell=bash
# wallpaper-pick — print a random wallpaper from $wallpapersDir whose palette
# best matches the given theme variant. Per-image palettes are extracted once
# (ImageMagick) and cached, keyed by the (immutable) source path so a rebuild
# that changes the wallpaper set reindexes automatically.
#
# Matching uses several key colors on both sides: the variant's base16
# base00–base05 (the background→foreground neutral range) are each matched to
# their nearest wallpaper dominant color; the sum of those nearest distances
# is the score. A random image is picked from the lowest-score tier.
#
# Env (injected by the Nix wrapper):
# wallpapersDir directory of wallpaper images (~/Wallpapers, a git clone)
# wallpaperRepo git URL cloned into wallpapersDir on first use
# variantSchemes space-separated `variant:schemeFile` pairs (base16 YAML)
# MAGICK path to the ImageMagick `magick` binary
# GIT path to the `git` binary
# Arg: variant name (e.g. gruvbox-dark)
: "${wallpapersDir:?wallpaper-pick: wallpapersDir not set}"
: "${wallpaperRepo:?wallpaper-pick: wallpaperRepo not set}"
: "${variantSchemes:?wallpaper-pick: variantSchemes not set}"
: "${MAGICK:?wallpaper-pick: MAGICK not set}"
: "${GIT:?wallpaper-pick: GIT not set}"
set -euo pipefail
variant="${1:?usage: wallpaper-pick <variant>}"
# Ensure the wallpaper repo is cloned locally. The clone is a one-time cost
# paid on first use (not at build time), keeping `nix build` fast.
if [ ! -d "$wallpapersDir/.git" ]; then
log_info "cloning wallpaper repo (one-time, may take a few minutes)..."
mkdir -p "$(dirname "$wallpapersDir")"
"$GIT" clone --depth=1 --single-branch "$wallpaperRepo" "$wallpapersDir" >&2
log_info "clone ready"
fi
cache_dir="${XDG_CACHE_HOME:-$HOME/.cache}/wallpaper-pick"
palettes="$cache_dir/palettes.tsv"
stamp_file="$cache_dir/source"
# Cache key: the clone's current commit, so a `git pull` reindexes. Falls back
# to the resolved path if git fails for some reason.
src_stamp="$("$GIT" -C "$wallpapersDir" rev-parse HEAD 2>/dev/null || readlink -f "$wallpapersDir")"
rebuild_cache() {
img_count="$(find "$wallpapersDir" -type f \( -iname '*.png' -o -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.webp' \) -printf . 2>/dev/null | wc -c)"
log_info "indexing ${img_count} wallpapers (one-time, building palette cache)..."
mkdir -p "$cache_dir"
tmp="$palettes.tmp"
: > "$tmp"
jobs="$(nproc 2>/dev/null || echo 4)"
# For each image: top dominant colors (by pixel count) as space-separated #hex.
find "$wallpapersDir" -type f \( -iname '*.png' -o -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.webp' \) -print0 \
| xargs -0 -P "$jobs" -n1 sh -c '
MAGICK="$0" img="$1"
"$MAGICK" "$img" -resize 128x128^ -gravity center -extent 128x128 +dither -colors 8 -format "%c" histogram:info: 2>/dev/null \
| grep -E "^[[:space:]]*[0-9]+:" | sort -rn | grep -oE "#[0-9A-Fa-f]{6}" | head -6 | paste -sd" " - \
| { read -r hex; [ -n "$hex" ] && printf "%s\t%s\n" "$img" "$hex"; }
' "$MAGICK" >> "$tmp" || true
mv "$tmp" "$palettes"
printf '%s\n' "$src_stamp" > "$stamp_file"
}
if [ ! -f "$palettes" ] || [ ! -f "$stamp_file" ] || [ "$(cat "$stamp_file")" != "$src_stamp" ]; then
rebuild_cache
fi
# Resolve the base16 scheme file for the requested variant.
scheme=""
for pair in $variantSchemes; do
case "$pair" in
"${variant}":*) scheme="${pair#*:}"; break ;;
esac
done
[ -n "$scheme" ] || { log_error "no scheme mapped for variant '$variant'"; exit 2; }
# Theme key colors: base00–base05 hex (one per line, with leading #).
theme_colors="$(grep -E '^[[:space:]]*base0[0-5]:' "$scheme" | grep -oE '#[0-9A-Fa-f]{6}')"
[ -n "$theme_colors" ] || { log_error "could not parse base00–05 from $scheme"; exit 2; }
# hex (no #) -> decimal rgb on stdout
hex2dec() { printf '%d %d %d\n' "$((16#${1:0:2}))" "$((16#${1:2:2}))" "$((16#${1:4:2}))"; }
# Theme colors as parallel arrays.
t_r=(); t_g=(); t_b=()
while read -r h; do
read -r r g b < <(hex2dec "${h#\#}")
t_r+=("$r"); t_g+=("$g"); t_b+=("$b")
done <<< "$theme_colors"
# Score every indexed wallpaper: sum over theme colors of nearest wallpaper color.
scores="$cache_dir/scores.tmp"
: > "$scores"
while IFS=$'\t' read -r path whexes; do
w_r=(); w_g=(); w_b=()
for wh in $whexes; do
read -r wr wg wb < <(hex2dec "${wh#\#}")
w_r+=("$wr"); w_g+=("$wg"); w_b+=("$wb")
done
if [ "${#w_r[@]}" -eq 0 ]; then continue; fi
total=0
for i in "${!t_r[@]}"; do
mind=1000000000
for j in "${!w_r[@]}"; do
dr=$(( t_r[i] - w_r[j] )); dg=$(( t_g[i] - w_g[j] )); db=$(( t_b[i] - w_b[j] ))
cd=$(( dr*dr + dg*dg + db*db ))
if [ "$cd" -lt "$mind" ]; then mind=$cd; fi
done
total=$(( total + mind ))
done
printf '%s\t%s\n' "$total" "$path"
done < "$palettes" | sort -n -k1 > "$scores"
[ -s "$scores" ] || { log_error "no wallpapers indexed"; exit 3; }
# Matched tier: within 1.4x of the best score (fall back to closest 20).
best="$(head -n1 "$scores" | cut -f1)"
threshold=$(( best * 14 / 10 ))
matched="$(awk -F'\t' -v t="$threshold" '$1 <= t {print $2}' "$scores")"
if [ "$(printf '%s\n' "$matched" | grep -c .)" -lt 5 ]; then
matched="$(head -n20 "$scores" | cut -f2)"
fi
# Print the chosen PATH on stdout (data channel for callers) and log the
# human-readable choice on stderr.
chosen="$(printf '%s\n' "$matched" | shuf -n1)"
log_info "picked $(basename "$chosen") for ${variant}"
printf '%s\n' "$chosen"
+15 -29
View File
@@ -44,6 +44,8 @@
# users.extraGroups.vboxusers.members = [ "${username}" ];
programs = {
fuse.userAllowOther = true;
nix-ld.dev.enable = true;
nm-applet.enable = true;
@@ -87,6 +89,14 @@
services.tailscale.enable = true;
services.personal-backlog = {
enable = true;
port = 48080;
user = "${username}";
group = "users";
dataDir = "/home/fujin/.local/share/backlog";
};
# Keyboard configuraions
services.udev = {
@@ -104,14 +114,13 @@
development.emacs.enable = true;
virtualisation.docker.enable = true;
virtualisation.incus.enable = true;
window-manager.hypr.enable = true;
display-manager.ly.enable = true;
gaming.enable = true;
dynamic-theme.enable = true;
};
###
@@ -122,37 +131,14 @@
useUserPackages = true;
backupFileExtension = "backup";
extraSpecialArgs = { inherit inputs username; };
# Stylix is handled entirely at the Home Manager level (see
# hm-modules/theme). Load the stylix HM module here so the `stylix`
# option exists for fujin's home configuration.
sharedModules = [ inputs.stylix.homeModules.stylix ];
users."${username}" = { imports = [ ./home.nix ] ++ extraHomeModules; };
};
stylix = {
enable = true;
# base16Scheme managed by dov.dynamic-theme module
fonts = {
serif = {
package = pkgs.dejavu_fonts;
name = "DejaVu Serif";
};
sansSerif = {
package = pkgs.dejavu_fonts;
name = "DejaVu Sans";
};
monospace = {
package = pkgs.dejavu_fonts;
name = "DejaVu Sans Mono";
};
emoji = {
package = pkgs.noto-fonts-color-emoji;
name = "Noto Color Emoji";
};
};
};
fonts.packages = with pkgs;
[
noto-fonts
@@ -395,3 +395,7 @@ Must be called BEFORE jdtls starts. Sets global lsp-java-vmargs."
;; (it contains markers/buffers that can't serialize properly)
(after! savehist
(add-to-list 'savehist-ignored-variables 'evil-jumps-history))
;; vterm: use system default shell (nushell)
(after! vterm
(setq vterm-shell (getenv "SHELL")))
@@ -58,7 +58,7 @@
(evil +everywhere); come to the dark side, we have cookies
file-templates ; auto-snippets for empty files
fold ; (nigh) universal code folding
;;(format +onsave) ; automated prettiness
(format) ; automated prettiness
;;god ; run Emacs commands without modifier keys
;;lispy ; vim for lisp, for people who don't like vim
;;multiple-cursors ; editing in many places at once
+34 -7
View File
@@ -25,6 +25,7 @@
nu = {
enable = true;
carapace.enable = true;
shellAliases = {
ll = "eza -al";
cp = "rsync -ah --progress";
@@ -69,7 +70,10 @@
notification.mako.enable = true;
dynamic-theme.enable = true;
dynamic-theme = {
enable = true;
wallpaperRepo = "https://gitea.susano-homelab.duckdns.org/fujin/gruvbox-wallpapers.git";
};
};
programs = {
@@ -103,7 +107,7 @@
# social
telegram-desktop
#thunderbird-latest
#element-desktop
element-desktop
#teams-for-linux
#webcord
discord
@@ -113,6 +117,7 @@
jetbrains.webstorm
#jetbrains.pycharm-community-src
direnv
devenv
semgrep
devpod
tmux
@@ -138,6 +143,7 @@
#qmk
google-chrome
unzip
proton-vpn
#libreoffice
grim
@@ -151,17 +157,38 @@
#mpd
#mpv
#mpc-cli
# gaming
prismlauncher
] ++ [ inputs.thefuck.packages.${pkgs.system}.default ];
# Stylix theming is driven by `dov.dynamic-theme` (hm-modules/theme),
# which sets `enable`, `base16Scheme` and `polarity` + specialisations.
# Here we only keep target overrides and the font set (moved from the
# old NixOS-level stylix config).
stylix = {
enable = true;
autoEnable = true;
targets = {
kde.enable = false;
};
fonts = {
serif = {
package = pkgs.dejavu_fonts;
name = "DejaVu Serif";
};
sansSerif = {
package = pkgs.dejavu_fonts;
name = "DejaVu Sans";
};
monospace = {
package = pkgs.dejavu_fonts;
name = "DejaVu Sans Mono";
};
emoji = {
package = pkgs.noto-fonts-color-emoji;
name = "Noto Color Emoji";
};
};
};
# blutooth applet
-1
View File
@@ -15,6 +15,5 @@
./gitlab
./jenkins
./gaming
./theme
];
}
+1 -1
View File
@@ -18,7 +18,7 @@ in {
## Emacs itself
binutils # native-comp needs 'as', provided by this
# 28.2 + native-comp
((emacsPackagesFor emacs-unstable).emacsWithPackages (epkgs: [
((emacsPackagesFor emacs30).emacsWithPackages (epkgs: [
epkgs.vterm
epkgs.treesit-grammars.with-all-grammars
epkgs.mu4e
+34 -2
View File
@@ -1,10 +1,17 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
username,
...
}:
with lib;
let
cfg = config.dov.gaming;
in {
in
{
options.dov.gaming = {
enable = mkEnableOption "gaming config";
};
@@ -15,5 +22,30 @@ in {
protontricks.enable = true;
extraCompatPackages = with pkgs; [ proton-ge-bin ];
};
home-manager.users.${username}.config = {
programs.lutris = {
enable = true;
extraPackages = with pkgs; [
umu-launcher
winetricks
];
protonPackages = [ pkgs.proton-ge-bin ];
};
home.packages = with pkgs; [
umu-launcher
];
home.file.".local/share/Steam/compatibilitytools.d/GE-Proton" = {
source = "${pkgs.proton-ge-bin.steamcompattool}";
};
};
users.users."${username}" = {
packages = with pkgs; [
prismlauncher
];
};
};
}
-65
View File
@@ -1,65 +0,0 @@
{ config, lib, pkgs, username, ... }:
with lib;
let
# Access HM theme config
hmCfg = config.home-manager.users.${username}.dov.dynamic-theme;
allThemes = hmCfg.themes;
# Generate all theme-variant combinations
themeVariants = concatMapAttrs (name: theme: {
"${name}-dark" = { scheme = theme.dark; polarity = "dark"; };
"${name}-light" = { scheme = theme.light; polarity = "light"; };
}) allThemes;
# Base is gruvbox-dark, everything else is a specialisation
baseVariant = "gruvbox-dark";
specialisationVariants = filterAttrs (name: _: name != baseVariant) themeVariants;
availableVariants = concatStringsSep " " (attrNames themeVariants);
theme-switch = pkgs.writeShellScriptBin "theme-switch" ''
case "$1" in
${baseVariant})
echo "Switching to ${baseVariant}..."
sudo nixos-rebuild switch --flake ~/nixos#${username}
;;
${concatStringsSep "\n " (map (name: ''
${name})
echo "Switching to ${name}..."
sudo nixos-rebuild switch --flake ~/nixos#${username} --specialisation ${name}
;;'') (attrNames specialisationVariants))}
*)
echo "Usage: theme-switch <variant>"
echo "Available: ${availableVariants}"
exit 1
;;
esac
'';
in {
options.dov.dynamic-theme.enable = mkEnableOption "NixOS dynamic theme specialisations";
config = mkIf (config.dov.dynamic-theme.enable && hmCfg.enable) {
# Add theme-switch script system-wide
environment.systemPackages = [ theme-switch ];
# Base theme: gruvbox-dark
stylix = {
base16Scheme = mkDefault themeVariants.${baseVariant}.scheme;
polarity = mkDefault themeVariants.${baseVariant}.polarity;
};
# Generate NixOS specialisations for all other variants
specialisation = mapAttrs (name: variant: {
configuration = {
stylix = {
base16Scheme = mkForce variant.scheme;
polarity = mkForce variant.polarity;
};
};
}) specialisationVariants;
};
}
+1
View File
@@ -4,5 +4,6 @@
imports = [
./podman
./docker
./incus
];
}
+72
View File
@@ -0,0 +1,72 @@
{
config,
lib,
pkgs,
username,
...
}:
with lib;
let
cfg = config.dov.virtualisation.incus;
in
{
options.dov.virtualisation.incus = {
enable = mkEnableOption "incus config";
};
config = mkIf cfg.enable {
networking.nftables.enable = true;
networking.firewall.interfaces.incusbr0.allowedTCPPorts = [
53
67
];
networking.firewall.interfaces.incusbr0.allowedUDPPorts = [
53
67
];
virtualisation.incus = {
enable = true;
preseed = {
storage_pools = [
{
name = "default";
driver = "dir";
}
];
networks = [
{
name = "incusbr0";
type = "bridge";
config = {
"ipv4.address" = "auto";
"ipv4.nat" = "true";
};
}
];
profiles = [
{
name = "default";
devices = {
eth0 = {
name = "eth0";
network = "incusbr0";
type = "nic";
};
root = {
path = "/";
pool = "default";
type = "disk";
};
};
}
];
};
};
users.users.${username}.extraGroups = [ "incus-admin" ];
};
}
+164 -181
View File
@@ -3,7 +3,6 @@
with lib;
let
colors = config.lib.stylix.colors;
cfg = config.dov.window-manager.hypr;
hm-cfg = config.home-manager.users.${username}.dov;
in {
@@ -12,6 +11,10 @@ in {
programs.hyprland = {
enable = true;
xwayland.enable = true;
# Launch Hyprland via UWSM (Universal Wayland Session Manager). This
# automatically enables programs.uwsm and manages the systemd
# graphical-session / wayland-session@Hyprland targets and environment.
withUWSM = true;
};
environment = {
@@ -42,7 +45,7 @@ in {
};
};
home-manager.users.fujin.config = {
home-manager.users.${username}.config = {
home.packages = with pkgs; [
awww
pipewire
@@ -60,215 +63,195 @@ in {
hypridle
];
# The Hyprland config below is generated as native Lua (Hyprland >= 0.55).
# Stylix's hyprland target emits hyprlang-style `settings` (flat dotted
# keys like "col.active_border") which do not map cleanly onto the Lua
# `hl.config{}` table API, and the previous config already force-overrode
# stylix's borders anyway. We therefore disable the stylix hyprland target
# and set the colors we care about explicitly in the Lua config.
stylix.targets.hyprland.enable = lib.mkForce false;
wayland.windowManager.hyprland = {
enable = true;
xwayland.enable = true;
package = inputs.hyprland.packages.${pkgs.system}.hyprland;
plugins = [
inputs.split-monitor-workspaces.packages.${pkgs.system}.split-monitor-workspaces
];
package = null;
portalPackage = null;
configType = "lua";
settings = {
monitor = ",preferred,auto,1";
source = "~/.config/hypr/colors";
# Required when launching Hyprland through UWSM: UWSM owns the systemd
# graphical-session target, so home-manager must not create its own.
systemd.enable = false;
env = [
"LIBVA_DRIVER_NAME,nvidia"
"XDG_SESSION_TYPE,wayland"
"WLR_NO_HARDWARE_CURSORS,1"
];
# split-monitor-workspaces is a Lua package (Hyprland >= 0.55), not a
# C++ plugin: it's require()d in extraConfig, not loaded here.
plugins = [ ];
#Autostart
exec = [
# Fix slow startup
"systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP"
"dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY XDG_CURRENT_DESKTOP"
];
# Whole config written as native Lua. We use `extraConfig` (raw Lua)
# rather than the `settings` attrset because Lua-mode binds need
# `hl.dsp.*` dispatcher expressions, a `mainMod` local and a loop for
# the workspace binds - none of which the attrset form expresses
# cleanly ($variables render to invalid `hl.$mainMod(...)`).
extraConfig = ''
-- Migrated from hyprlang to Lua. See https://wiki.hypr.land/Configuring/Start/
local mainMod = "SUPER"
exec-once = [
"polkit-kde-agent"
"emacs --fg-daemon"
"hypridle"
"kanshi"
"virsh net-start default"
#"thunderbird"
#"element-desktop"
"keepassxc"
"dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP"
] ++ lib.optionals hm-cfg.bar.waybar.enable [ "waybar" "mako" ];
-- split-monitor-workspaces (Lua package). Use the absolute Nix store
-- path: Hyprland's cwd is not the config dir, so the relative ./?.lua
-- trick from upstream's README does not resolve under UWSM.
package.path = package.path .. ";${inputs.split-monitor-workspaces}/lua/?.lua"
local smw = require("split-monitor-workspaces")
smw.setup({
workspace_count = 10,
keep_focused = true,
enable_notifications = false,
-- Don't pre-create empty workspaces: keeps the waybar workspaces
-- module showing only workspaces that actually have windows (plus
-- the currently focused one).
enable_persistent_workspaces = false,
enable_wrapping = true,
})
"$mainMod" = "SUPER";
-- Monitors (was: monitor = ",preferred,auto,1")
hl.monitor({ output = "", mode = "preferred", position = "auto", scale = 1 })
bind = [
"$mainMod, G, fullscreen,"
"$mainMod, t, togglegroup"
"$mainMod, v, togglefloating"
#"$mainMod, s, togglesplit" # invalid dispatcher, requested "togglesplit" does not exist
-- Environment
hl.env("LIBVA_DRIVER_NAME", "nvidia")
hl.env("XDG_SESSION_TYPE", "wayland")
hl.env("WLR_NO_HARDWARE_CURSORS", "1")
#bind = $mainMod, RETURN, exec, kitty
"$mainMod, RETURN, exec, alacritty"
"$mainMod, o, exec, emacsclient -c"
"SUPER_SHIFT, RETURN, exec, thunar"
"SUPER_SHIFT, l, exec, hyprctl switchxkblayout at-translated-set-2-keyboard 0 && hyprlock"
-- Config variables
hl.config({
general = {
gaps_in = 5,
gaps_out = 20,
border_size = 2,
col = {
-- gradient active border (rgba(33ccffee) rgba(00ff99ee) 45deg)
active_border = { colors = { "rgba(33ccffee)", "rgba(00ff99ee)" }, angle = 45 },
inactive_border = "rgba(595959aa)",
},
layout = "dwindle",
},
decoration = {
rounding = 10,
shadow = { enabled = true, range = 4, render_power = 3 },
},
input = {
kb_layout = "us,ru,ua",
kb_options = "grp:win_space_toggle",
follow_mouse = 1,
touchpad = { natural_scroll = false },
sensitivity = 0,
},
animations = { enabled = true },
dwindle = { preserve_split = true },
master = { new_status = "master" },
})
#bind = $mainMod, M, exit,
"SUPER_SHIFT, q, killactive,"
-- Animation curves (was: bezier = ease,0.4,0.02,0.21,1)
hl.curve("ease", { type = "bezier", points = { { 0.4, 0.02 }, { 0.21, 1 } } })
# Switch Keyboard Layouts
"$mainMod, SPACE, exec, hyprctl switchxkblayout teclado-gamer-husky-blizzard next"
-- Animations (was: NAME, ONOFF, SPEED, CURVE, [STYLE])
hl.animation({ leaf = "windows", enabled = true, speed = 3.5, bezier = "ease", style = "slide" })
hl.animation({ leaf = "windowsOut", enabled = true, speed = 3.5, bezier = "ease", style = "slide" })
hl.animation({ leaf = "border", enabled = true, speed = 6, bezier = "ease" })
hl.animation({ leaf = "fade", enabled = true, speed = 3, bezier = "ease" })
hl.animation({ leaf = "workspaces", enabled = true, speed = 3.5, bezier = "ease" })
'', Print, exec, grim -g "$(slurp)" - | wl-copy''
''
SHIFT, Print, exec, IMG=~/Pictures/$(date +%Y-%m-%d_%H-%m-%s).png && grim -g "$(slurp)" $IMG''
-- Keybinds
hl.bind(mainMod .. " + G", hl.dsp.window.fullscreen())
hl.bind(mainMod .. " + t", hl.dsp.group.toggle())
hl.bind(mainMod .. " + v", hl.dsp.window.float({ action = "toggle" }))
# Functional keybinds
",XF86AudioMicMute,exec,pamixer --default-source -t"
",XF86MonBrightnessDown,exec,brightnessctl s 20-"
",XF86MonBrightnessUp,exec,brightnessctl s 20+"
",XF86AudioMute,exec,amixer -q sset Master toggle"
",XF86AudioLowerVolume,exec,amixer -q sset Master 5%-"
",XF86AudioRaiseVolume,exec,amixer -q sset Master 5%+"
",XF86AudioPlay,exec,playerctl play-pause"
",XF86AudioPause,exec,playerctl play-pause"
hl.bind(mainMod .. " + RETURN", hl.dsp.exec_cmd("alacritty"))
hl.bind(mainMod .. " + o", hl.dsp.exec_cmd("emacsclient -c"))
hl.bind("SUPER + SHIFT + RETURN", hl.dsp.exec_cmd("thunar"))
hl.bind("SUPER + SHIFT + l", hl.dsp.exec_cmd("hyprctl switchxkblayout at-translated-set-2-keyboard 0 && hyprlock"))
hl.bind("SUPER + SHIFT + q", hl.dsp.window.close())
# to switch between windows in a floating workspace
"SUPER,Tab,changegroupactive, f"
"SUPER_SHIFT,Tab,changegroupactive, b"
-- Switch keyboard layouts
hl.bind(mainMod .. " + SPACE", hl.dsp.exec_cmd("hyprctl switchxkblayout teclado-gamer-husky-blizzard next"))
# Move focus with mainMod + arrow keys
"$mainMod, h, movefocus, l"
"$mainMod, l, movefocus, r"
"$mainMod, k, movefocus, u"
"$mainMod, j, movefocus, d"
-- Screenshots
hl.bind("Print", hl.dsp.exec_cmd([[grim -g "$(slurp)" - | wl-copy]]))
hl.bind("SHIFT + Print", hl.dsp.exec_cmd([[IMG=~/Pictures/$(date +%Y-%m-%d_%H-%m-%s).png && grim -g "$(slurp)" $IMG]]))
# Switch workspaces with mainMod + [0-9]
"$mainMod, 1, split-workspace, 1"
"$mainMod, 2, split-workspace, 2"
"$mainMod, 3, split-workspace, 3"
"$mainMod, 4, split-workspace, 4"
"$mainMod, 5, split-workspace, 5"
"$mainMod, 6, split-workspace, 6"
"$mainMod, 7, split-workspace, 7"
"$mainMod, 8, split-workspace, 8"
"$mainMod, 9, split-workspace, 9"
"$mainMod, 0, split-workspace, 10"
-- Functional / media keys
hl.bind("XF86AudioMicMute", hl.dsp.exec_cmd("pamixer --default-source -t"))
hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd("brightnessctl s 20-"))
hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd("brightnessctl s 20+"))
hl.bind("XF86AudioMute", hl.dsp.exec_cmd("amixer -q sset Master toggle"))
hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("amixer -q sset Master 5%-"))
hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("amixer -q sset Master 5%+"))
hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"))
hl.bind("XF86AudioPause", hl.dsp.exec_cmd("playerctl play-pause"))
# Move active window to a workspace with mainMod + SHIFT + [0-9]
"$mainMod SHIFT, 1, split-movetoworkspace, 1"
"$mainMod SHIFT, 2, split-movetoworkspace, 2"
"$mainMod SHIFT, 3, split-movetoworkspace, 3"
"$mainMod SHIFT, 4, split-movetoworkspace, 4"
"$mainMod SHIFT, 5, split-movetoworkspace, 5"
"$mainMod SHIFT, 6, split-movetoworkspace, 6"
"$mainMod SHIFT, 7, split-movetoworkspace, 7"
"$mainMod SHIFT, 8, split-movetoworkspace, 8"
"$mainMod SHIFT, 9, split-movetoworkspace, 9"
"$mainMod SHIFT, 0, split-movetoworkspace, 10"
-- Switch between windows in a floating workspace (changegroupactive)
hl.bind("SUPER + Tab", hl.dsp.group.next())
hl.bind("SUPER + SHIFT + Tab", hl.dsp.group.prev())
# Scroll through existing workspaces with mainMod + scroll
"$mainMod, mouse_down, split-workspace, e+1"
"$mainMod, mouse_up, split-workspace, e-1"
"$mainMod,SPACE, exec, hyprctl switchxkblayout at-translated-set-2-keyboard next"
-- Move focus
hl.bind(mainMod .. " + h", hl.dsp.focus({ direction = "left" }))
hl.bind(mainMod .. " + l", hl.dsp.focus({ direction = "right" }))
hl.bind(mainMod .. " + k", hl.dsp.focus({ direction = "up" }))
hl.bind(mainMod .. " + j", hl.dsp.focus({ direction = "down" }))
] ++ lib.optionals hm-cfg.launcher.wofi.enable
[ "$mainMod, p, exec, wofi --show drun" ];
-- Workspaces 1-10 (per-monitor): key 0 -> workspace 10
for i = 1, smw.get_amount_of_workspaces() do
local key = tostring(i)
if key == "10" then key = "0" end
hl.bind(mainMod .. " + " .. key, smw.workspace(tostring(i)))
hl.bind(mainMod .. " + SHIFT + " .. key, smw.move_to_workspace_silent(tostring(i)))
end
bindm = [
"$mainMod, mouse:272, movewindow"
"$mainMod, mouse:273, resizewindow"
"ALT, mouse:272, resizewindow"
];
-- Scroll through workspaces with mainMod + scroll
hl.bind(mainMod .. " + mouse_down", smw.cycle_workspaces("next"))
hl.bind(mainMod .. " + mouse_up", smw.cycle_workspaces("prev"))
input = {
kb_layout = "us,ru,ua";
kb_options = "grp:win_space_toggle";
-- NOTE: pre-existing duplicate SUPER+SPACE bind (last one wins,
-- identical to the original hyprlang config).
hl.bind(mainMod .. " + SPACE", hl.dsp.exec_cmd("hyprctl switchxkblayout at-translated-set-2-keyboard next"))
''
+ lib.optionalString hm-cfg.launcher.wofi.enable ''
hl.bind(mainMod .. " + p", hl.dsp.exec_cmd("wofi --show drun"))
''
+ ''
follow_mouse = 1;
-- Mouse binds (was: bindm)
hl.bind(mainMod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true })
hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true })
hl.bind("ALT + mouse:272", hl.dsp.window.resize(), { mouse = true })
touchpad = { natural_scroll = false; };
-- Workspace rules
hl.workspace_rule({ workspace = "8", monitor = "eDP-1" })
hl.workspace_rule({ workspace = "9", monitor = "eDP-1" })
sensitivity = 0;
};
-- Window rules
hl.window_rule({ match = { title = "^(.*KeePassXC.*)$" }, workspace = "8" })
general = {
gaps_in = 5;
gaps_out = 20;
border_size = 2;
"col.active_border" =
lib.mkForce "rgba(33ccffee) rgba(00ff99ee) 45deg";
"col.inactive_border" = lib.mkForce "rgba(595959aa)";
layout = "dwindle";
};
decoration = {
rounding = 10;
shadow = {
enabled = true;
range = 4;
render_power = 3;
};
};
animations = {
enabled = "yes";
bezier = "ease,0.4,0.02,0.21,1";
animation = [
"windows, 1, 3.5, ease, slide"
"windowsOut, 1, 3.5, ease, slide"
"border, 1, 6, default"
"fade, 1, 3, ease"
"workspaces, 1, 3.5, ease"
];
};
dwindle = {
preserve_split = "yes";
};
master = { new_status = "master"; };
workspace = [
#"0, monitor:DP-1"
"8, monitor:eDP-1"
"9, monitor:eDP-1"
#"9, on-created-empty:[tiled] thunderbird"
];
windowrule = [
"workspace 8, match:title ^(.*KeePassXC.*)$"
#"noinitialfocus,match:class (jetbrains-)(.*),title:^win(.*), initialTitle:win.*, floating:1"
];
};
-- Autostart (was: exec-once). UWSM imports the session environment,
-- so the old systemctl/dbus import-environment lines are dropped.
hl.on("hyprland.start", function()
hl.exec_cmd("polkit-kde-agent")
hl.exec_cmd("emacs --fg-daemon")
hl.exec_cmd("hypridle")
hl.exec_cmd("kanshi")
hl.exec_cmd("virsh net-start default")
hl.exec_cmd("keepassxc")
''
+ lib.optionalString hm-cfg.bar.waybar.enable ''
hl.exec_cmd("waybar")
hl.exec_cmd("mako")
''
+ ''
end)
'';
};
home.file.".config/hypr/colors".text = ''
$background = ${colors.base00}
$foreground = ${colors.base05}
$color0 = ${colors.base00}
$color1 = ${colors.base01}
$color2 = ${colors.base02}
$color3 = ${colors.base03}
$color4 = ${colors.base04}
$color5 = ${colors.base05}
$color6 = ${colors.base06}
$color7 = ${colors.base07}
$color8 = ${colors.base08}
$color9 = ${colors.base09}
$color10 = ${colors.base0A}
$color11 = ${colors.base0B}
$color12 = ${colors.base0C}
$color13 = ${colors.base0D}
$color14 = ${colors.base0E}
$color15 = ${colors.base0F}
'';
xdg.configFile."hypr/hyprlock.conf".source = ./hyprlock.conf;
xdg.configFile."hypr/hypridle.conf".source = ./hypridle.conf;
};
};
}