Compare commits
20
Commits
92b388abb1
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
39b5ec89be
|
||
|
|
925aac68ef
|
||
|
|
786d8f9ee3
|
||
|
|
43f6edcf02
|
||
|
|
83cfd6969c
|
||
|
|
1beb5a3338
|
||
|
|
0d6deec01e
|
||
|
|
818c9f6af8
|
||
|
|
8a9384de15
|
||
|
|
8b141b9da0
|
||
|
|
dd0097a1f8
|
||
|
|
5f8c8b3948
|
||
|
|
097b02ecef
|
||
|
|
c04405c0fb
|
||
|
|
e2a8892148
|
||
|
|
724220504f
|
||
|
|
7c37843808
|
||
|
|
527812781f
|
||
|
|
e16b8ce5ea
|
||
|
|
7c67ec4c5e
|
@@ -49,3 +49,11 @@ alias offline := switch-offline
|
||||
@fmt:
|
||||
echo "Formatting files..."
|
||||
nix fmt
|
||||
|
||||
@sync-noctalia:
|
||||
echo "Folding noctalia GUI overrides back into the repo..."
|
||||
python3 scripts/sync-noctalia.py --apply
|
||||
|
||||
@sync-noctalia-preview:
|
||||
echo "Previewing noctalia config sync (no changes)..."
|
||||
python3 scripts/sync-noctalia.py
|
||||
|
||||
Generated
+70
-96
@@ -108,26 +108,27 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1784665499,
|
||||
"narHash": "sha256-9BMxlTxCCDAeoNLtb1a/st7udtTIJep+wpUzquA29VU=",
|
||||
"owner": "nix-community",
|
||||
"lastModified": 1788011267,
|
||||
"narHash": "sha256-mEq2kU+ljompTToZ44Afvm7d/rHJ5iMBl0tjZuyShJs=",
|
||||
"owner": "Mic92",
|
||||
"repo": "bun2nix",
|
||||
"rev": "0f2a1f0b6f42cebe3b149bf62d38754c5e0e9729",
|
||||
"rev": "5765b0614591f75ee8ba5596e81ae85c167d1071",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"owner": "Mic92",
|
||||
"ref": "fix-structured-attrs-hook",
|
||||
"repo": "bun2nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"crane": {
|
||||
"locked": {
|
||||
"lastModified": 1784564969,
|
||||
"narHash": "sha256-TkTWNhJV/8Wk3czlbz4bwHZkFCaCHPsOy+oJe4PUiXg=",
|
||||
"lastModified": 1787326676,
|
||||
"narHash": "sha256-lWhBbBvC05/xwivKBBiM2YNizpmgqCgyOIzomvRuwxs=",
|
||||
"owner": "ipetkov",
|
||||
"repo": "crane",
|
||||
"rev": "7930f6c291de6f83c257839d434592aa085f290a",
|
||||
"rev": "692f7e9ef2ece8125b466f66f2af532b3edaed0d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -144,11 +145,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1780519775,
|
||||
"narHash": "sha256-u12imjPk4ZhOen/PgnLiNPML+5NmuKO0Ja4wQKU/Y8E=",
|
||||
"lastModified": 1787592910,
|
||||
"narHash": "sha256-a2+yPzqXAlnErn1KGW28UBlqapBmySvLPWOskVFB/Hg=",
|
||||
"owner": "Bali10050",
|
||||
"repo": "Darkly",
|
||||
"rev": "11c27e2d98025f4d4c1598f07a185280b36f35f7",
|
||||
"rev": "65f6fa62675e3c30986f8fc8e4fdbba053096491",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -168,11 +169,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1787230056,
|
||||
"narHash": "sha256-AiAvfCRAeUMHmhUaKbtKhKyEmLJ2whreUP2XG2xgj8U=",
|
||||
"lastModified": 1788439409,
|
||||
"narHash": "sha256-AvaugOI0Hb8ZG+2goIbISKpYfW6ovdvDm/uf7PT8PO8=",
|
||||
"owner": "Mic92",
|
||||
"repo": "fast-nix-gc",
|
||||
"rev": "68287b2eb3ff360daead3e879568a9e26df5bfb1",
|
||||
"rev": "18d82a8ce3e938ff97b5e11c7d2033f0333af5bb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -189,11 +190,11 @@
|
||||
"rust-analyzer-src": "rust-analyzer-src"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1787295275,
|
||||
"narHash": "sha256-I/1JRiGmO5/PEAHX6UeaGPsiwHyFy/e6QYlo2eeKIO4=",
|
||||
"lastModified": 1788603547,
|
||||
"narHash": "sha256-/ioB+JvyRtHtQOpgZYC95KiD6Gw76ZDdSbkiItR4FG4=",
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"rev": "b2d5394982978a49df40a075f51e7cfc62c324ca",
|
||||
"rev": "03864c059200a8a96f2ee6bb050c69eae96f57ca",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -240,11 +241,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1785627969,
|
||||
"narHash": "sha256-4dtXQk/NMePegK/nWp5NSeuZKLATItOq61lpEvmXqGw=",
|
||||
"lastModified": 1788450739,
|
||||
"narHash": "sha256-glZLQlzIn1fXH6PazR2iUmTo7kzzyYSshrWhLS9TqCU=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "427bf4bd9435fdf21321c8cc628c24efc14c0f7a",
|
||||
"rev": "31729ca8cbdb4fa927b34e5f4353e6a83f39e993",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -336,11 +337,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1787176219,
|
||||
"narHash": "sha256-djoRr6jBpe35q/0JwAvXpFXg1Ktf+X54NU2RLR7wnHw=",
|
||||
"lastModified": 1788487777,
|
||||
"narHash": "sha256-Ro/e1N4ZR8/XaFF+sF9SgfPK79HM5YNEppzFj8p+0Ak=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "c53d643b3737e2fcd04e6cb3b3580ef50b2087a0",
|
||||
"rev": "693e8ce0fb240a73c116a03cfd7b19269c87af88",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -404,11 +405,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1787286673,
|
||||
"narHash": "sha256-HRmx7PnoqUNtA06P/FEyygZeUJIzbNUtx4zo9Jiiz9s=",
|
||||
"lastModified": 1788605532,
|
||||
"narHash": "sha256-kqEZkn2YPC9mgJn6Wh6L1uuukvYYMbQryzaFHO41GxU=",
|
||||
"owner": "numtide",
|
||||
"repo": "llm-agents.nix",
|
||||
"rev": "0bedd15c76b9422a649b05e44b82666196e5246f",
|
||||
"rev": "3a3523b87e7bb7253fac39c95895ec20f241d672",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -419,11 +420,11 @@
|
||||
},
|
||||
"multiverse": {
|
||||
"locked": {
|
||||
"lastModified": 1787204501,
|
||||
"narHash": "sha256-b4z25yQkSWThW9yfDdf4/TEV6zgqD3hGDpGPOJnqqFQ=",
|
||||
"lastModified": 1788596457,
|
||||
"narHash": "sha256-6iJ0N8hUClykevMfX8Qwt2ObOBaQF6yK7wf12OoOovk=",
|
||||
"owner": "fzakaria",
|
||||
"repo": "nixpkgs-multiverse",
|
||||
"rev": "12dbab7efc581bd661e4f2d7e20ad28afb7cbb9c",
|
||||
"rev": "5caf7ed36b0ddf54878ef30a738fd327c9682ffa",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -456,11 +457,11 @@
|
||||
"xwayland-satellite-unstable": "xwayland-satellite-unstable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1787097724,
|
||||
"narHash": "sha256-y5q/XFRPi5TBWdh5MhqxJZhfmzqJO0bYNLZHE7WTqso=",
|
||||
"lastModified": 1788566543,
|
||||
"narHash": "sha256-7snI9zOQMvM0ghxW9+7Tl/8pvDa4KGmQBCmRzbY9TxI=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "ecd0e136e75dc37967f5a6a5fea5a99613c503c1",
|
||||
"revCount": 171,
|
||||
"rev": "2bce88af7bbeff97ac132d870e2efd08a294c8f0",
|
||||
"revCount": 181,
|
||||
"type": "git",
|
||||
"url": "https://codeberg.org/bananad3v/niri-nix"
|
||||
},
|
||||
@@ -472,11 +473,11 @@
|
||||
"niri-unstable": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1787066149,
|
||||
"narHash": "sha256-uJKImwjqQ6Y+5b1IN93j6rEKGRoR0CsOuC/7vqluhJM=",
|
||||
"lastModified": 1787337984,
|
||||
"narHash": "sha256-BNZUEVR2H96hCKENNKoLSSTFT8W4smp7v94hJc4Ehfc=",
|
||||
"owner": "YaLTeR",
|
||||
"repo": "niri",
|
||||
"rev": "e9b215fef4b11ad36776553fb8bd45118ef03b03",
|
||||
"rev": "dd75865f547f0eac0e9b6c4d86d2cd00c0744252",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -519,11 +520,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1786373799,
|
||||
"narHash": "sha256-/MGTSKLPC6uERKHyilzRCVPDeX/AwG+4B8bf1vMHAJg=",
|
||||
"lastModified": 1787652563,
|
||||
"narHash": "sha256-ec73Anjp5QDIid2Z/iNC9jaGRqO9aLtYOJOo95dd5YU=",
|
||||
"owner": "Mic92",
|
||||
"repo": "nix-tree-rs",
|
||||
"rev": "31d54916fa110e9462fec799f1663224baddbadd",
|
||||
"rev": "9654bd185c7043c60ae999b4d3a9b038e85b111b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -557,11 +558,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1787172299,
|
||||
"narHash": "sha256-PShzS87awOlE5XWkxUGBd/58/F+AtE2ZMgFffKj4r8s=",
|
||||
"lastModified": 1788400875,
|
||||
"narHash": "sha256-JIHQ6xNAN53cdo6zZ72LRcQ9lpvnABCnNE4hldJ5uZU=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "07e1d92cdc0ed416cfa11ff3ca40d17e61cfba7a",
|
||||
"rev": "5545adfad2e98de106a5544ca7067e03010410bd",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -573,11 +574,11 @@
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1787135253,
|
||||
"narHash": "sha256-RD2kNWCG+Bjo6h+JVjWVNntZs2GtRoeY2xHjts/FNkA=",
|
||||
"lastModified": 1788531059,
|
||||
"narHash": "sha256-hLD4l3QOGBQhkVp3mQ2lJ/YbEi99qUgKapb40KovZ88=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "ffb3c9b700e759be2ef13237c9d8f953b32a1e46",
|
||||
"rev": "801bef6abd86b91e51083066b83fb354a11fc640",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -591,47 +592,20 @@
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"noctalia-qs": "noctalia-qs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1775169040,
|
||||
"narHash": "sha256-0xoCuJSRSWcn4mCX382lCxqLbnuOrrqS4dOcdpoUmZg=",
|
||||
"owner": "noctalia-dev",
|
||||
"repo": "noctalia-shell",
|
||||
"rev": "8b0c7c288063e5048a439ca308dd65f7044f42b6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "noctalia-dev",
|
||||
"ref": "v4.7.5",
|
||||
"repo": "noctalia-shell",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"noctalia-qs": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"systems"
|
||||
],
|
||||
"treefmt-nix": [
|
||||
"treefmt"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1775008123,
|
||||
"narHash": "sha256-zsd/kbsgfX2YQAlbao40JxyeVDwsUmBGyUDZc/Vo1C4=",
|
||||
"lastModified": 1787858564,
|
||||
"narHash": "sha256-WijEuINvjcXMO/e/zMqwG1lyGiWNosnVt1QY+ko0Rw8=",
|
||||
"owner": "noctalia-dev",
|
||||
"repo": "noctalia-qs",
|
||||
"rev": "b87f41771c050d3c101d1528532de53293cba6da",
|
||||
"repo": "noctalia-shell",
|
||||
"rev": "74e6c2790dd8f39bf496e90e479a9ae370846eed",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "noctalia-dev",
|
||||
"repo": "noctalia-qs",
|
||||
"ref": "v5.0.0-beta.10",
|
||||
"repo": "noctalia-shell",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
@@ -693,11 +667,11 @@
|
||||
"rust-analyzer-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1787269862,
|
||||
"narHash": "sha256-8pvHbL/ARH159+/Tvt1Savv9HOWfjvvvv6TJFOM5Rlg=",
|
||||
"lastModified": 1788445421,
|
||||
"narHash": "sha256-sKEuAgygSpMZFvrj7IcCPm+3al2bQWukulM6pMEpCcc=",
|
||||
"owner": "rust-lang",
|
||||
"repo": "rust-analyzer",
|
||||
"rev": "5f8813d64fff2e293dcc99d54a21f6f4edc88d50",
|
||||
"rev": "e8f7e90aa3e7b26aa9a000200f606c1078da99ec",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -718,11 +692,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1787201968,
|
||||
"narHash": "sha256-BaJVIdXc5kuhptOT4o+oiGTkAk3Gg1V9GraigfOr95M=",
|
||||
"lastModified": 1788514031,
|
||||
"narHash": "sha256-3nWq8IMC6GPtEqixSvpYX05nOfFqdnOfmkl0DOiWcQc=",
|
||||
"owner": "StarryReverie",
|
||||
"repo": "selector4nix",
|
||||
"rev": "a0e8b0db006cdc2f275a740f7c60f760a1346607",
|
||||
"rev": "1ff44ddb817ff943df9667ac1a0a79791b509a20",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -738,11 +712,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1786629091,
|
||||
"narHash": "sha256-gkig4nPi1CWc4Z50GBsjE4ygSE7hMpl/TwID2an2Cck=",
|
||||
"lastModified": 1788337237,
|
||||
"narHash": "sha256-gkSH8VUtCo6hnysNmb9DbTuDepH2t5pv+QWjP75xKAk=",
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"rev": "a8627b21b9107c5711c96b84f32a9a4b3d45295f",
|
||||
"rev": "fbf759290e0cb0a98dfc813a4eb7d53ad1dacb57",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -775,11 +749,11 @@
|
||||
"tinted-zed": "tinted-zed"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1787175104,
|
||||
"narHash": "sha256-tzNjlb0loxeWlipvxSNAUUihloeTZoyGFhEen87yM9k=",
|
||||
"lastModified": 1787771653,
|
||||
"narHash": "sha256-DkkJSBOXWV/mja5Vy8az5g1KpZlsbUwlmH0BsQhowaQ=",
|
||||
"owner": "danth",
|
||||
"repo": "stylix",
|
||||
"rev": "a9e5a76a1b75b137f266e4f445e1eaba82e9783e",
|
||||
"rev": "5e3809851f486e7fc7e84b40f174c74b60ecc784",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -910,11 +884,11 @@
|
||||
"xwayland-satellite-unstable": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1786221058,
|
||||
"narHash": "sha256-hF2atQzapHBLX5NFqJMcKZAWHfGkKQeNu1eQr46+AGg=",
|
||||
"lastModified": 1788436361,
|
||||
"narHash": "sha256-i0QYbUlC03SrOomU+37TdZ9EdtEWLaUtsCQjC7+KhNU=",
|
||||
"owner": "Supreeeme",
|
||||
"repo": "xwayland-satellite",
|
||||
"rev": "3bc915f09dd62bb2651a715114f9d140344bc6c1",
|
||||
"rev": "ea474b95a55ace75ad60a9bc0092a81ff5a1ba89",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -933,11 +907,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1787281392,
|
||||
"narHash": "sha256-WnGPcxoouwp2ZNQ2lBfVunY77AIFy6cdAfT4J5Vw6Fs=",
|
||||
"lastModified": 1788405419,
|
||||
"narHash": "sha256-wuGizAVEmY0u15MYrhgy7AoQdHg+4Y2QiC+v/mxA8dc=",
|
||||
"owner": "0xc000022070",
|
||||
"repo": "zen-browser-flake",
|
||||
"rev": "4ab199700226db9b91ab69fa2b78816ebe475358",
|
||||
"rev": "fdb83f8fce835213fab7eab52c375926fe1a32dc",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -96,11 +96,8 @@
|
||||
inputs.treefmt-nix.follows = "treefmt";
|
||||
};
|
||||
noctalia = {
|
||||
url = "github:noctalia-dev/noctalia-shell/v4.7.5";
|
||||
url = "github:noctalia-dev/noctalia-shell/v5.0.0-beta.10";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
inputs.noctalia-qs.inputs.nixpkgs.follows = "nixpkgs";
|
||||
inputs.noctalia-qs.inputs.systems.follows = "systems";
|
||||
inputs.noctalia-qs.inputs.treefmt-nix.follows = "treefmt";
|
||||
};
|
||||
selector4nix = {
|
||||
url = "github:StarryReverie/selector4nix";
|
||||
|
||||
@@ -34,6 +34,9 @@ in
|
||||
resumeDevice = btrfs;
|
||||
kernelParams = [
|
||||
"resume_offset=6444127"
|
||||
|
||||
# Fix connector hotplug at ly display manager
|
||||
"amdgpu.runpm=0"
|
||||
];
|
||||
|
||||
zswap.enable = true;
|
||||
|
||||
@@ -53,7 +53,7 @@ symbol = " "
|
||||
symbol = " "
|
||||
|
||||
[git_commit]
|
||||
tag_symbol = ' '
|
||||
tag_symbol = " "
|
||||
|
||||
[golang]
|
||||
symbol = " "
|
||||
|
||||
@@ -17,8 +17,7 @@ in
|
||||
enable = true;
|
||||
settings = lib.recursiveUpdate (with builtins; fromTOML (readFile ./starship-preset.toml)) {
|
||||
add_newline = false;
|
||||
command_timeout = 2000;
|
||||
nix_shell.disabled = true;
|
||||
scan_timeout = 1500;
|
||||
format =
|
||||
let
|
||||
dedupDollar =
|
||||
|
||||
@@ -17,6 +17,9 @@ in
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
my.persist.homeDirs = [
|
||||
".config/jj"
|
||||
];
|
||||
my.hm = {
|
||||
programs.jujutsu = {
|
||||
enable = true;
|
||||
|
||||
@@ -19,8 +19,8 @@ in
|
||||
# codex
|
||||
claude-code
|
||||
# opencode
|
||||
pi
|
||||
omp
|
||||
# pi
|
||||
# omp
|
||||
])
|
||||
++ (with pkgs; [
|
||||
codex
|
||||
|
||||
@@ -81,6 +81,7 @@ local servers = {
|
||||
java_language_server = {},
|
||||
jsonls = {},
|
||||
pyrefly = {},
|
||||
ruff = {},
|
||||
-- taplo = {},
|
||||
tombi = {},
|
||||
ts_ls = {},
|
||||
|
||||
@@ -18,6 +18,8 @@ in
|
||||
(lib.hiPrio clang)
|
||||
clang-tools
|
||||
cmake
|
||||
ninja
|
||||
meson
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -14,9 +14,15 @@ in
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
my.hm.home.packages = with pkgs; [
|
||||
python3
|
||||
(python3.withPackages (
|
||||
ps: with ps; [
|
||||
tomli
|
||||
tomli-w
|
||||
]
|
||||
))
|
||||
uv
|
||||
pyrefly
|
||||
ruff
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ in
|
||||
"rust-analyzer"
|
||||
])
|
||||
stdenv.cc # linker
|
||||
evcxr # rust repl
|
||||
|
||||
pest-ide-tools
|
||||
];
|
||||
|
||||
@@ -19,6 +19,22 @@ in
|
||||
gnumake
|
||||
github-cli # gh
|
||||
];
|
||||
programs.starship.settings = {
|
||||
nix_shell.disabled = true;
|
||||
# direnv =
|
||||
# let
|
||||
# esc = builtins.fromJSON ''"\u001b"'';
|
||||
# in
|
||||
# {
|
||||
# disabled = false;
|
||||
# format = "$loaded$allowed ";
|
||||
# loaded_msg = "${esc}[1;92m ${esc}[0m"; # green
|
||||
# unloaded_msg = "";
|
||||
# allowed_msg = "";
|
||||
# not_allowed_msg = "${esc}[1;93m ${esc}[0m"; # yellow
|
||||
# denied_msg = "${esc}[1;91m ${esc}[0m"; # red
|
||||
# };
|
||||
};
|
||||
programs.direnv = {
|
||||
enable = true;
|
||||
nix-direnv.enable = true;
|
||||
@@ -48,6 +64,7 @@ in
|
||||
};
|
||||
};
|
||||
my.persist.homeDirs = [
|
||||
".config/gh"
|
||||
".local/share/direnv"
|
||||
];
|
||||
};
|
||||
|
||||
@@ -63,7 +63,11 @@ in
|
||||
};
|
||||
|
||||
nix.settings = {
|
||||
experimental-features = "nix-command flakes pipe-operators";
|
||||
experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
"pipe-operators"
|
||||
];
|
||||
substituters = lib.mkForce [
|
||||
"http://127.0.0.1:${toString (config.services.selector4nix.settings.server.port or 5496)}"
|
||||
"https://cache.nixos.org"
|
||||
|
||||
@@ -14,10 +14,10 @@ in
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
my.hm.home.packages = [
|
||||
pkgs.splayer
|
||||
pkgs.splayer-next
|
||||
];
|
||||
my.persist.homeDirs = [
|
||||
".config/SPlayer"
|
||||
".config/SPlayer-Next"
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,44 +6,44 @@
|
||||
|
||||
# Default colors
|
||||
[colors.primary]
|
||||
background = '#24283b'
|
||||
foreground = '#c0caf5'
|
||||
background = "#24283b"
|
||||
foreground = "#c0caf5"
|
||||
|
||||
[colors.cursor]
|
||||
cursor = '#c0caf5'
|
||||
text = '#24283b'
|
||||
cursor = "#c0caf5"
|
||||
text = "#24283b"
|
||||
|
||||
[colors.selection]
|
||||
text = '#c0caf5'
|
||||
background = '#2e3c64'
|
||||
text = "#c0caf5"
|
||||
background = "#2e3c64"
|
||||
|
||||
# Normal colors
|
||||
[colors.normal]
|
||||
black = '#1d202f'
|
||||
red = '#f7768e'
|
||||
green = '#9ece6a'
|
||||
yellow = '#e0af68'
|
||||
blue = '#7aa2f7'
|
||||
magenta = '#bb9af7'
|
||||
cyan = '#7dcfff'
|
||||
white = '#a9b1d6'
|
||||
black = "#1d202f"
|
||||
red = "#f7768e"
|
||||
green = "#9ece6a"
|
||||
yellow = "#e0af68"
|
||||
blue = "#7aa2f7"
|
||||
magenta = "#bb9af7"
|
||||
cyan = "#7dcfff"
|
||||
white = "#a9b1d6"
|
||||
|
||||
# Bright colors
|
||||
[colors.bright]
|
||||
black = '#414868'
|
||||
red = '#ff899d'
|
||||
green = '#9fe044'
|
||||
yellow = '#faba4a'
|
||||
blue = '#8db0ff'
|
||||
magenta = '#c7a9ff'
|
||||
cyan = '#a4daff'
|
||||
white = '#c0caf5'
|
||||
black = "#414868"
|
||||
red = "#ff899d"
|
||||
green = "#9fe044"
|
||||
yellow = "#faba4a"
|
||||
blue = "#8db0ff"
|
||||
magenta = "#c7a9ff"
|
||||
cyan = "#a4daff"
|
||||
white = "#c0caf5"
|
||||
|
||||
# Indexed Colors
|
||||
[[colors.indexed_colors]]
|
||||
index = 16
|
||||
color = '#ff9e64'
|
||||
color = "#ff9e64"
|
||||
|
||||
[[colors.indexed_colors]]
|
||||
index = 17
|
||||
color = '#db4b4b'
|
||||
color = "#db4b4b"
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
binds {
|
||||
Ctrl+Alt+Escape { spawn "missioncenter"; }
|
||||
|
||||
Mod+R { spawn "noctalia-shell" "ipc" "call" "launcher" "toggle"; }
|
||||
Mod+V { spawn "noctalia-shell" "ipc" "call" "launcher" "clipboard"; }
|
||||
Mod+W { spawn "noctalia-shell" "ipc" "call" "launcher" "windows"; }
|
||||
Mod+R { spawn "noctalia" "msg" "panel-toggle" "launcher"; }
|
||||
Mod+V { spawn "noctalia" "msg" "panel-toggle" "clipboard"; }
|
||||
Mod+W { spawn "noctalia" "msg" "panel-toggle" "launcher" "/win"; }
|
||||
|
||||
XF86AudioRaiseVolume allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_SINK@" "2%+"; }
|
||||
XF86AudioLowerVolume allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_SINK@" "2%-"; }
|
||||
XF86AudioMute allow-when-locked=true { spawn "noctalia-shell" "ipc" "call" "media" "playPause"; }
|
||||
Super+XF86AudioRaiseVolume allow-when-locked=true { spawn "noctalia-shell" "ipc" "call" "media" "next"; }
|
||||
Super+XF86AudioLowerVolume allow-when-locked=true { spawn "noctalia-shell" "ipc" "call" "media" "previous"; }
|
||||
XF86AudioMute allow-when-locked=true { spawn "noctalia" "msg" "media" "playPause"; }
|
||||
Super+XF86AudioRaiseVolume allow-when-locked=true { spawn "noctalia" "msg" "media" "next"; }
|
||||
Super+XF86AudioLowerVolume allow-when-locked=true { spawn "noctalia" "msg" "media" "previous"; }
|
||||
|
||||
XF86MonBrightnessUp allow-when-locked=true { spawn "brightnessctl" "set" "+5%"; }
|
||||
XF86MonBrightnessDown allow-when-locked=true { spawn "brightnessctl" "set" "5%-"; }
|
||||
|
||||
@@ -46,6 +46,12 @@ layout {
|
||||
}
|
||||
}
|
||||
|
||||
gestures {
|
||||
hot-corners {
|
||||
off
|
||||
}
|
||||
}
|
||||
|
||||
prefer-no-csd
|
||||
|
||||
hotkey-overlay {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
assets,
|
||||
impure,
|
||||
...
|
||||
}:
|
||||
let
|
||||
@@ -69,17 +69,6 @@ in
|
||||
X-RestartIfChanged=false
|
||||
'';
|
||||
};
|
||||
systemd.user.services.niri-polkit = {
|
||||
description = "PolicyKit Authentication Agent";
|
||||
wantedBy = [ "niri.service" ];
|
||||
after = [ "graphical-session.target" ];
|
||||
partOf = [ "graphical-session.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart = "${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
};
|
||||
|
||||
services.system76-scheduler.enable = true;
|
||||
|
||||
@@ -93,177 +82,16 @@ in
|
||||
|
||||
mission-center
|
||||
|
||||
noctalia-shell
|
||||
xdg-terminal-exec
|
||||
];
|
||||
|
||||
services.system76-scheduler-niri.enable = true;
|
||||
|
||||
programs.noctalia-shell = {
|
||||
programs.noctalia = {
|
||||
enable = true;
|
||||
# modified from official Tokyo-Night theme
|
||||
colors = {
|
||||
mError = "#f7768e";
|
||||
mHover = "#bb9af7";
|
||||
mOnError = "#16161e";
|
||||
mOnHover = "#16161e";
|
||||
mOnPrimary = "#16161e";
|
||||
mOnSecondary = "#16161e";
|
||||
mOnSurface = "#c0caf5";
|
||||
mOnSurfaceVariant = "#9aa5ce";
|
||||
mOnTertiary = "#16161e";
|
||||
mOutline = "#353D57";
|
||||
mPrimary = "#7aa2f7";
|
||||
mSecondary = "#9a9ef7";
|
||||
mShadow = "#15161e";
|
||||
mSurface = "#1a1b26";
|
||||
mSurfaceVariant = "#24283b";
|
||||
mTertiary = "#bb9af7";
|
||||
};
|
||||
settings = {
|
||||
appLauncher = {
|
||||
enableClipboardHistory = true;
|
||||
useApp2Unit = true;
|
||||
terminalCommand = "kitty -e";
|
||||
};
|
||||
audio.mprisBlacklist = [
|
||||
"firefox"
|
||||
"chromium"
|
||||
"zen"
|
||||
];
|
||||
bar = {
|
||||
density = "comfortable";
|
||||
floating = true;
|
||||
marginHorizontal = 0.5;
|
||||
marginVertical = 0.5;
|
||||
showCapsule = false;
|
||||
widgets = {
|
||||
left = [
|
||||
{
|
||||
id = "ControlCenter";
|
||||
useDistroLogo = true;
|
||||
}
|
||||
{
|
||||
id = "Clock";
|
||||
formatHorizontal = "HH:mm MM/dd ddd";
|
||||
useCustomFont = false;
|
||||
usePrimaryColor = true;
|
||||
}
|
||||
{
|
||||
id = "SystemMonitor";
|
||||
showCpuTemp = false;
|
||||
showCpuUsage = true;
|
||||
showDiskUsage = false;
|
||||
showMemoryAsPercent = false;
|
||||
showMemoryUsage = true;
|
||||
showNetworkStats = true;
|
||||
}
|
||||
{
|
||||
id = "Workspace";
|
||||
hideUnoccupied = false;
|
||||
labelMode = "none";
|
||||
}
|
||||
];
|
||||
center = [
|
||||
{
|
||||
id = "MediaMini";
|
||||
hideMode = "hidden";
|
||||
scrollingMode = "hover";
|
||||
showAlbumArt = true;
|
||||
showVisualizer = true;
|
||||
visualizerType = "wave";
|
||||
}
|
||||
];
|
||||
right = [
|
||||
{
|
||||
id = "NotificationHistory";
|
||||
hideWhenZero = true;
|
||||
showUnreadBadge = true;
|
||||
}
|
||||
{
|
||||
id = "Tray";
|
||||
drawerEnabled = false;
|
||||
colorizeIcons = false;
|
||||
}
|
||||
{
|
||||
id = "Volume";
|
||||
displayMode = "onhover";
|
||||
}
|
||||
{
|
||||
id = "Microphone";
|
||||
displayMode = "onhover";
|
||||
}
|
||||
{
|
||||
id = "Battery";
|
||||
hideIfNotDetected = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
controlCenter = {
|
||||
cards = [
|
||||
{
|
||||
id = "profile-card";
|
||||
enabled = true;
|
||||
}
|
||||
{
|
||||
id = "shortcuts-card";
|
||||
enabled = true;
|
||||
}
|
||||
{
|
||||
id = "audio-card";
|
||||
enabled = true;
|
||||
}
|
||||
{
|
||||
id = "weather-card";
|
||||
enabled = false;
|
||||
}
|
||||
{
|
||||
id = "media-sysmon-card";
|
||||
enabled = true;
|
||||
}
|
||||
];
|
||||
position = "top_left";
|
||||
shortcuts = {
|
||||
left = [
|
||||
{ id = "Bluetooth"; }
|
||||
{ id = "Network"; }
|
||||
];
|
||||
right = [ { id = "Notifications"; } ];
|
||||
};
|
||||
};
|
||||
dock.enabled = false;
|
||||
general = {
|
||||
avatarImage = "${assets.avatar}";
|
||||
scaleRatio = 1.05;
|
||||
radiusRatio = 0.8;
|
||||
enableShadows = false;
|
||||
telemetryEnabled = false;
|
||||
};
|
||||
location.weatherEnabled = false;
|
||||
network.wifiEnabled = false;
|
||||
notifications = {
|
||||
alwaysOnTop = true;
|
||||
location = "top";
|
||||
};
|
||||
osd = {
|
||||
alwaysOnTop = true;
|
||||
# enable all types
|
||||
enabledTypes = [ ];
|
||||
location = "top";
|
||||
};
|
||||
setupCompleted = true;
|
||||
ui = {
|
||||
# I love Jetbrains Mono
|
||||
fontDefault = "Monospace";
|
||||
fontFixed = "Monospace";
|
||||
panelsAttachedToBar = false;
|
||||
panelsOverlayLayer = true;
|
||||
tooltipsEnabled = true;
|
||||
};
|
||||
wallpaper.enabled = false;
|
||||
};
|
||||
systemd.enable = true;
|
||||
};
|
||||
xdg.configFile."noctalia".source = impure.mkImpureLink ./noctalia;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
[accessibility]
|
||||
ui_scale = 1
|
||||
@@ -0,0 +1,2 @@
|
||||
[audio]
|
||||
enable_sounds = true
|
||||
@@ -0,0 +1,34 @@
|
||||
[bar.main]
|
||||
capsule = false
|
||||
capsule_thickness = 0.75
|
||||
center = [
|
||||
"media",
|
||||
]
|
||||
end = [
|
||||
"notifications",
|
||||
"Spacer-12",
|
||||
"tray",
|
||||
"Spacer-12",
|
||||
"output_volume",
|
||||
"input_volume",
|
||||
]
|
||||
font_family = "monospace"
|
||||
margin_edge = 11
|
||||
margin_ends = 15
|
||||
padding = 10
|
||||
position = "top"
|
||||
radius = 16
|
||||
scale = 1.15
|
||||
shadow = false
|
||||
start = [
|
||||
"control-center",
|
||||
"Spacer-12",
|
||||
"clock",
|
||||
"Spacer-12",
|
||||
"sysmon_cpu",
|
||||
"sysmon_ram",
|
||||
"battery",
|
||||
"Spacer-12",
|
||||
"workspaces",
|
||||
]
|
||||
thickness = 38
|
||||
@@ -0,0 +1,4 @@
|
||||
[control_center]
|
||||
hidden_tabs = ["weather"]
|
||||
shortcuts = []
|
||||
show_shortcut_labels = false
|
||||
@@ -0,0 +1,10 @@
|
||||
[desktop_widgets]
|
||||
schema_version = 2
|
||||
widget_order = []
|
||||
|
||||
[desktop_widgets.grid]
|
||||
cell_size = 16
|
||||
major_interval = 4
|
||||
visible = true
|
||||
|
||||
[desktop_widgets.widget]
|
||||
@@ -0,0 +1,2 @@
|
||||
[dock]
|
||||
enabled = false
|
||||
@@ -0,0 +1,7 @@
|
||||
[hot_corners]
|
||||
delay_ms = 200
|
||||
enabled = true
|
||||
|
||||
[hot_corners.top_left]
|
||||
action = "command"
|
||||
command = "niri msg action toggle-overview"
|
||||
@@ -0,0 +1,17 @@
|
||||
[idle]
|
||||
behavior_order = ["lock", "screen-off", "lock-and-suspend"]
|
||||
|
||||
[idle.behavior.lock]
|
||||
action = "lock"
|
||||
enabled = true
|
||||
timeout = 300.0
|
||||
|
||||
[idle.behavior.lock-and-suspend]
|
||||
action = "lock_and_suspend"
|
||||
enabled = false
|
||||
timeout = 900.0
|
||||
|
||||
[idle.behavior.screen-off]
|
||||
action = "screen_off"
|
||||
enabled = true
|
||||
timeout = 600.0
|
||||
@@ -0,0 +1,103 @@
|
||||
[lockscreen]
|
||||
wallpaper = "~/workspace/nixos-dotfiles/assets/wallpaper.png"
|
||||
|
||||
[lockscreen_widgets]
|
||||
enabled = true
|
||||
schema_version = 2
|
||||
widget_order = [
|
||||
"lockscreen-login-box@DP-1",
|
||||
"lockscreen-login-box@DP-2",
|
||||
"lockscreen-widget-clock@DP-1",
|
||||
"lockscreen-widget-clock@DP-2",
|
||||
]
|
||||
|
||||
[lockscreen_widgets.grid]
|
||||
cell_size = 16
|
||||
major_interval = 4
|
||||
visible = true
|
||||
|
||||
[lockscreen_widgets.widget."lockscreen-login-box@DP-1"]
|
||||
box_height = 70.0
|
||||
box_width = 400.0
|
||||
cx = 1024.0
|
||||
cy = 675.0
|
||||
output = "DP-1"
|
||||
placement_height = 1152.0
|
||||
placement_width = 2048.0
|
||||
rotation = 0.0
|
||||
type = "login_box"
|
||||
|
||||
[lockscreen_widgets.widget."lockscreen-login-box@DP-1".settings]
|
||||
background_color = "surface_variant"
|
||||
background_opacity = 0.88
|
||||
background_radius = 12.0
|
||||
center_password_text = false
|
||||
input_opacity = 1.0
|
||||
input_radius = 6.0
|
||||
layout = "compact"
|
||||
show_caps_lock = true
|
||||
show_keyboard_layout = false
|
||||
show_login_button = false
|
||||
show_media = true
|
||||
show_session_buttons = true
|
||||
show_unlock_hint = false
|
||||
show_weather = true
|
||||
|
||||
[lockscreen_widgets.widget."lockscreen-login-box@DP-2"]
|
||||
box_height = 70.0
|
||||
box_width = 400.0
|
||||
cx = 1024.0
|
||||
cy = 675.0
|
||||
output = "DP-2"
|
||||
placement_height = 1152.0
|
||||
placement_width = 2048.0
|
||||
rotation = 0.0
|
||||
type = "login_box"
|
||||
|
||||
[lockscreen_widgets.widget."lockscreen-login-box@DP-2".settings]
|
||||
background_color = "surface_variant"
|
||||
background_opacity = 0.88
|
||||
background_radius = 12.0
|
||||
center_password_text = false
|
||||
input_opacity = 1.0
|
||||
input_radius = 6.0
|
||||
layout = "compact"
|
||||
show_caps_lock = true
|
||||
show_keyboard_layout = false
|
||||
show_login_button = false
|
||||
show_media = true
|
||||
show_session_buttons = true
|
||||
show_unlock_hint = false
|
||||
show_weather = true
|
||||
|
||||
[lockscreen_widgets.widget."lockscreen-widget-clock@DP-1"]
|
||||
box_height = 144.0
|
||||
box_width = 240.0
|
||||
cx = 1024.0
|
||||
cy = 480.0
|
||||
output = "DP-1"
|
||||
placement_height = 1152.0
|
||||
placement_width = 2048.0
|
||||
rotation = 0.0
|
||||
type = "clock"
|
||||
|
||||
[lockscreen_widgets.widget."lockscreen-widget-clock@DP-1".settings]
|
||||
background = false
|
||||
clock_style = "digital"
|
||||
format = "{:%H:%M}"
|
||||
|
||||
[lockscreen_widgets.widget."lockscreen-widget-clock@DP-2"]
|
||||
box_height = 144.0
|
||||
box_width = 240.0
|
||||
cx = 1024.0
|
||||
cy = 480.0
|
||||
output = "DP-2"
|
||||
placement_height = 1152.0
|
||||
placement_width = 2048.0
|
||||
rotation = 0.0
|
||||
type = "clock"
|
||||
|
||||
[lockscreen_widgets.widget."lockscreen-widget-clock@DP-2".settings]
|
||||
background = false
|
||||
clock_style = "digital"
|
||||
format = "{:%H:%M}"
|
||||
@@ -0,0 +1,2 @@
|
||||
[notification]
|
||||
layer = "top"
|
||||
@@ -0,0 +1,6 @@
|
||||
[osd]
|
||||
position = "top_center"
|
||||
|
||||
[osd.kinds]
|
||||
keyboard_layout = false
|
||||
media = false
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"dark": {
|
||||
"mPrimary": "#7aa2f7",
|
||||
"mOnPrimary": "#16161e",
|
||||
"mSecondary": "#9a9ef7",
|
||||
"mOnSecondary": "#16161e",
|
||||
"mTertiary": "#bb9af7",
|
||||
"mOnTertiary": "#16161e",
|
||||
"mError": "#f7768e",
|
||||
"mOnError": "#16161e",
|
||||
"mSurface": "#1a1b26",
|
||||
"mOnSurface": "#c0caf5",
|
||||
"mSurfaceVariant": "#24283b",
|
||||
"mOnSurfaceVariant": "#9aa5ce",
|
||||
"mOutline": "#353d57",
|
||||
"mShadow": "#15161e",
|
||||
"mHover": "#bb9af7",
|
||||
"mOnHover": "#16161e",
|
||||
"terminal": {
|
||||
"background": "#1a1b26",
|
||||
"foreground": "#c0caf5",
|
||||
"cursor": "#c0caf5",
|
||||
"cursorText": "#1a1b26",
|
||||
"selectionFg": "#c0caf5",
|
||||
"selectionBg": "#283457",
|
||||
"normal": {
|
||||
"black": "#16161e",
|
||||
"red": "#f7768e",
|
||||
"green": "#9ece6a",
|
||||
"yellow": "#e0af68",
|
||||
"blue": "#7aa2f7",
|
||||
"magenta": "#bb9af7",
|
||||
"cyan": "#7dcfff",
|
||||
"white": "#c0caf5"
|
||||
},
|
||||
"bright": {
|
||||
"black": "#1a1b26",
|
||||
"red": "#ff7a93",
|
||||
"green": "#b9f27c",
|
||||
"yellow": "#ffc777",
|
||||
"blue": "#7da6ff",
|
||||
"magenta": "#bb9af7",
|
||||
"cyan": "#89ddff",
|
||||
"white": "#d5d6e3"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
# tombi: format.rules.table-keys-order.disabled = true
|
||||
[shell]
|
||||
avatar_path = "~/workspace/nixos-dotfiles/assets/avatar.jpg"
|
||||
corner_radius_scale = 1.5
|
||||
date_format = "%Y/%m/%d"
|
||||
font_family = "monospace"
|
||||
lang = "en"
|
||||
launch_apps_as_systemd_services = true
|
||||
panel_anchor_bar = "main"
|
||||
polkit_agent = true
|
||||
screen_time_enabled = true
|
||||
telemetry_enabled = false
|
||||
|
||||
clipboard_enabled = true
|
||||
clipboard_history_max_entries = 1000
|
||||
|
||||
[shell.animation]
|
||||
speed = 0.8
|
||||
|
||||
[shell.launcher]
|
||||
sort_by_usage = true
|
||||
|
||||
[shell.mpris]
|
||||
blacklist = ["firefox", "chromium", "zen"]
|
||||
|
||||
[shell.panel]
|
||||
borders = false
|
||||
clipboard_placement = "floating"
|
||||
control_center_placement = "floating"
|
||||
launcher_placement = "floating"
|
||||
open_near_click_control_center = true
|
||||
session_placement = "floating"
|
||||
session_position = "center"
|
||||
shadow = true
|
||||
transparency_mode = "soft"
|
||||
wallpaper_placement = "floating"
|
||||
|
||||
[shell.shadow]
|
||||
alpha = 0.0
|
||||
@@ -0,0 +1,4 @@
|
||||
[theme]
|
||||
custom_palette = "TokyoNight"
|
||||
mode = "dark"
|
||||
source = "custom"
|
||||
@@ -0,0 +1,2 @@
|
||||
[wallpaper]
|
||||
enabled = false
|
||||
@@ -0,0 +1,2 @@
|
||||
[weather]
|
||||
enabled = false
|
||||
@@ -0,0 +1,58 @@
|
||||
[widget.Spacer-12]
|
||||
length = 12
|
||||
type = "spacer"
|
||||
|
||||
[widget.battery]
|
||||
scale = 1.2
|
||||
|
||||
[widget.clock]
|
||||
format = "{:%H:%M %m/%d}"
|
||||
scale = 0.9
|
||||
|
||||
[widget.control-center]
|
||||
custom_image = "/run/current-system/sw/share/icons/hicolor/scalable/apps/nix-snowflake.svg"
|
||||
scale = 1.25
|
||||
|
||||
[widget.input_volume]
|
||||
show_label = false
|
||||
|
||||
[widget.media]
|
||||
art_size = 30
|
||||
font_scale = 0.84
|
||||
title_scroll = "always"
|
||||
hide_when_no_media = true
|
||||
|
||||
[widget.mic]
|
||||
device = "input"
|
||||
type = "volume"
|
||||
|
||||
[widget.notifications]
|
||||
capsule_radius = "auto"
|
||||
hide_when_no_unread = false
|
||||
scale = 1.05
|
||||
|
||||
[widget.output_volume]
|
||||
show_label = false
|
||||
|
||||
[widget.sysmon_cpu]
|
||||
scale = 1.2
|
||||
show_glyph = false
|
||||
show_value = false
|
||||
stat = "cpu_usage"
|
||||
type = "sysmon"
|
||||
visualization = "graph"
|
||||
|
||||
[widget.sysmon_ram]
|
||||
label_show_units = false
|
||||
show_value = false
|
||||
stat = "ram_used"
|
||||
type = "sysmon"
|
||||
|
||||
[widget.tray]
|
||||
capsule_radius = 16
|
||||
drawer = false
|
||||
|
||||
[widget.workspaces]
|
||||
hide_when_empty = false
|
||||
pill_scale = 0.9
|
||||
show_labels = false
|
||||
@@ -35,6 +35,8 @@
|
||||
# GVFS for virtual filesystems
|
||||
services.gvfs.enable = true;
|
||||
|
||||
services.speechd.enable = false;
|
||||
|
||||
# Enable desktop-related modules by default
|
||||
my = {
|
||||
audio.enable = true;
|
||||
|
||||
Executable
+491
@@ -0,0 +1,491 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Fold noctalia GUI overrides back into the declarative dotfiles config.
|
||||
|
||||
This script folds `noctalia config export merged` back into the per-aspect
|
||||
*.toml files so the repo alone reproduces the current effective config:
|
||||
|
||||
* export values win (added if missing, updated if changed),
|
||||
* repo-only keys and empty-table declarations are never deleted,
|
||||
* f32 serialization noise (0.74999998696148396 vs 0.75) is ignored,
|
||||
* floats are written back clean (0.8400000000000001 -> 0.84),
|
||||
* comments (tombi directives) are preserved across the rewrite.
|
||||
|
||||
Files are parsed with `tomli` and rewritten with `tomli_w`, then touched
|
||||
files are re-formatted with `tombi` to match repo style. Note that `tomli_w`
|
||||
renders every non-empty array on multiple lines and `tombi` preserves that
|
||||
layout, so arrays in a folded file are reflowed from inline to multiline the
|
||||
first time that file is touched.
|
||||
|
||||
After a successful fold the GUI override file is moved to
|
||||
<state-dir>/settings.bak.d/<timestamp>.toml (the 3 most recent are kept) and
|
||||
the running instance is reloaded.
|
||||
|
||||
Usage:
|
||||
sync-noctalia.py # preview the fold; change nothing
|
||||
sync-noctalia.py --apply # apply, backup settings.toml, reload
|
||||
sync-noctalia.py --export-file <file> # read the export from F instead of noctalia
|
||||
sync-noctalia.py --config-dir <dir> # target a different config dir
|
||||
sync-noctalia.py --state-dir <dir> # state dir holding settings.toml
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import math
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from subprocess import CalledProcessError
|
||||
|
||||
import tomli
|
||||
import tomli_w
|
||||
|
||||
REPO = Path(__file__).resolve().parent.parent
|
||||
DEFAULT_CONFIG_DIR = REPO / "modules" / "desktop" / "wm" / "niri" / "noctalia"
|
||||
DEFAULT_STATE_DIR = Path.home() / ".local" / "state" / "noctalia"
|
||||
KEEP_BACKUPS = 3
|
||||
FLOAT_TOL = 1e-4
|
||||
FLOAT_PRECISION = 6
|
||||
|
||||
|
||||
def parse_export(export_file: Path | None) -> dict:
|
||||
if export_file:
|
||||
return tomli.loads(export_file.read_text())
|
||||
try:
|
||||
proc = subprocess.run(
|
||||
["noctalia", "config", "export", "merged"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
except FileNotFoundError:
|
||||
sys.exit("error: `noctalia` not found on PATH")
|
||||
except CalledProcessError as err:
|
||||
sys.exit(f"error: `noctalia config export merged` failed:\n{err.stderr}")
|
||||
return tomli.loads(proc.stdout)
|
||||
|
||||
|
||||
def values_differ(a, b) -> bool:
|
||||
"""True if two values differ as config values (float-tolerant, recursive)."""
|
||||
if isinstance(a, (int, float)) and isinstance(b, (int, float)):
|
||||
return not math.isclose(float(a), float(b), rel_tol=0.0, abs_tol=FLOAT_TOL)
|
||||
if isinstance(a, list) and isinstance(b, list):
|
||||
return len(a) != len(b) or any(values_differ(x, y) for x, y in zip(a, b))
|
||||
if isinstance(a, dict) and isinstance(b, dict):
|
||||
return set(a) != set(b) or any(values_differ(a[k], b[k]) for k in a)
|
||||
return a != b
|
||||
|
||||
|
||||
def collect_changes(repo_sub, exp_sub, prefix, changes):
|
||||
"""Recursively diff export subtree against repo subtree, appending
|
||||
(path, old_value, new_value) tuples. New subtrees carry old_value=None
|
||||
and a dict new_value."""
|
||||
for k, v in exp_sub.items():
|
||||
path = prefix + [k]
|
||||
if isinstance(v, dict):
|
||||
cur = repo_sub.get(k)
|
||||
if isinstance(cur, dict):
|
||||
collect_changes(cur, v, path, changes)
|
||||
else:
|
||||
changes.append((path, cur, v))
|
||||
else:
|
||||
cur = repo_sub.get(k)
|
||||
if cur is None or values_differ(cur, v):
|
||||
changes.append((path, cur, v))
|
||||
|
||||
|
||||
def clean_value(v):
|
||||
"""Round floats to FLOAT_PRECISION places, recursively.
|
||||
|
||||
tomli_w serialises floats with str(), which would keep f32 noise like
|
||||
0.74999998696148396 written by a float slider; rounding keeps written
|
||||
values clean without losing precision we care about.
|
||||
"""
|
||||
if isinstance(v, float):
|
||||
return round(v, FLOAT_PRECISION)
|
||||
if isinstance(v, list):
|
||||
return [clean_value(x) for x in v]
|
||||
if isinstance(v, dict):
|
||||
return {k: clean_value(x) for k, x in v.items()}
|
||||
return v
|
||||
|
||||
|
||||
# Preview rendering (display only; file I/O goes through tomli_w)
|
||||
|
||||
|
||||
def _dotted(segments) -> str:
|
||||
"""Render segments as a TOML dotted path, quoting non-bare segments."""
|
||||
out = []
|
||||
for s in segments:
|
||||
if not s or not all(c.isalnum() or c in "_-" for c in s):
|
||||
out.append('"' + s.replace("\\", "\\\\").replace('"', '\\"') + '"')
|
||||
else:
|
||||
out.append(s)
|
||||
return ".".join(out)
|
||||
|
||||
|
||||
def _clean_float(v: float) -> str:
|
||||
s = f"{v:.6f}".rstrip("0").rstrip(".")
|
||||
return s + ".0" if "." not in s else s
|
||||
|
||||
|
||||
def serialize_value(v, indent: str = "") -> str:
|
||||
if isinstance(v, bool):
|
||||
return "true" if v else "false"
|
||||
if isinstance(v, int):
|
||||
return str(v)
|
||||
if isinstance(v, float):
|
||||
return _clean_float(v)
|
||||
if isinstance(v, str):
|
||||
return '"' + v.replace("\\", "\\\\").replace('"', '\\"') + '"'
|
||||
if isinstance(v, list):
|
||||
return "[" + ", ".join(serialize_value(e, indent) for e in v) + "]"
|
||||
if isinstance(v, dict):
|
||||
inner = ", ".join(
|
||||
f"{_dotted([k])} = {serialize_value(x, '')}" for k, x in v.items()
|
||||
)
|
||||
return "{ " + inner + " }"
|
||||
raise TypeError(f"unsupported TOML value: {v!r}")
|
||||
|
||||
|
||||
def serialize_subtree(path, subtree) -> str:
|
||||
"""Serialize a dict as a TOML section block: headers followed by keys."""
|
||||
out = []
|
||||
|
||||
def walk(p, d):
|
||||
out.append(f"[{_dotted(p)}]\n")
|
||||
for k, v in d.items():
|
||||
if not isinstance(v, dict):
|
||||
out.append(f"{k} = {serialize_value(v)}\n")
|
||||
for k, v in d.items():
|
||||
if isinstance(v, dict):
|
||||
walk(p + [k], v)
|
||||
|
||||
walk(path, subtree)
|
||||
return "".join(out)
|
||||
|
||||
|
||||
# Comment preservation
|
||||
|
||||
|
||||
def extract_comment_blocks(text: str) -> list[tuple[list[str], str | None]]:
|
||||
"""Contiguous comment lines, each paired with the table header that follows
|
||||
them (or None for a trailing run). tomli_w drops comments when rewriting a
|
||||
file, so they are re-anchored from the original text."""
|
||||
lines = text.splitlines()
|
||||
runs = []
|
||||
i = 0
|
||||
while i < len(lines):
|
||||
if lines[i].lstrip().startswith("#"):
|
||||
j = i
|
||||
while j < len(lines) and lines[j].lstrip().startswith("#"):
|
||||
j += 1
|
||||
runs.append((i, j))
|
||||
i = j
|
||||
else:
|
||||
i += 1
|
||||
blocks = []
|
||||
for start, end in runs:
|
||||
anchor = None
|
||||
for k in range(end, len(lines)):
|
||||
t = lines[k].strip()
|
||||
if t.startswith("[") and t.endswith("]"):
|
||||
anchor = t
|
||||
break
|
||||
blocks.append((lines[start:end], anchor))
|
||||
return blocks
|
||||
|
||||
|
||||
def restore_comments(original_text: str, rendered_text: str) -> str:
|
||||
"""Re-insert the original file's comments into tomli_w's output, before the
|
||||
table header each comment preceded (any stragglers go at EOF)."""
|
||||
blocks = extract_comment_blocks(original_text)
|
||||
if not blocks:
|
||||
return rendered_text
|
||||
pending = list(blocks)
|
||||
out = []
|
||||
for line in rendered_text.splitlines():
|
||||
stripped = line.strip()
|
||||
if stripped.startswith("[") and stripped.endswith("]"):
|
||||
for block, anchor in list(pending):
|
||||
if anchor == stripped:
|
||||
out.extend(block)
|
||||
pending.remove((block, anchor))
|
||||
out.append(line)
|
||||
for block, _anchor in pending:
|
||||
out.extend(block)
|
||||
return "\n".join(out) + "\n"
|
||||
|
||||
|
||||
# Dict-based edits
|
||||
|
||||
|
||||
def apply_path(data: dict, path, value, *, as_table: bool, old):
|
||||
"""Set ``path`` to ``value`` in ``data``, creating intermediate tables.
|
||||
|
||||
Leaf values are assigned in place (a new key appends at the end of its
|
||||
table). Sub-tables are inserted at their sorted position among sibling
|
||||
sub-tables, matching the repo's alphabetical `[section]` order; a scalar
|
||||
being replaced by a table is dropped first.
|
||||
"""
|
||||
node = data
|
||||
for seg in path[:-1]:
|
||||
nxt = node.get(seg)
|
||||
if not isinstance(nxt, dict):
|
||||
nxt = {}
|
||||
node[seg] = nxt
|
||||
node = nxt
|
||||
key = path[-1]
|
||||
if as_table:
|
||||
if old is not None:
|
||||
node.pop(key, None)
|
||||
items = list(node.items())
|
||||
pos = len(items)
|
||||
for i, (k, v) in enumerate(items):
|
||||
if isinstance(v, dict) and k > key:
|
||||
pos = i
|
||||
break
|
||||
items.insert(pos, (key, value))
|
||||
node.clear()
|
||||
node.update(items)
|
||||
else:
|
||||
node[key] = value
|
||||
|
||||
|
||||
# Verification and state handling
|
||||
|
||||
|
||||
def completeness_diffs(export, repo_after) -> list:
|
||||
"""Leaf paths where repo_after still differs from the export."""
|
||||
diffs = []
|
||||
|
||||
def walk(e, r, prefix):
|
||||
for k, v in e.items():
|
||||
p = prefix + [k]
|
||||
if isinstance(v, dict):
|
||||
if not isinstance(r.get(k), dict):
|
||||
diffs.append((p, None, v))
|
||||
else:
|
||||
walk(v, r[k], p)
|
||||
else:
|
||||
cur = r.get(k)
|
||||
if cur is None or values_differ(cur, v):
|
||||
diffs.append((p, cur, v))
|
||||
|
||||
walk(export, repo_after, [])
|
||||
return diffs
|
||||
|
||||
|
||||
def run_validate(config_dir: Path) -> bool:
|
||||
print(f" validate: noctalia config validate {config_dir}")
|
||||
proc = subprocess.run(
|
||||
["noctalia", "config", "validate", str(config_dir)],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=False,
|
||||
)
|
||||
out = proc.stdout + proc.stderr
|
||||
for line in out.splitlines():
|
||||
print(f" {line}")
|
||||
if "WARN" in out:
|
||||
print(
|
||||
" note: confirm none of the warnings above were newly introduced by this fold"
|
||||
)
|
||||
return proc.returncode == 0
|
||||
|
||||
|
||||
def run_tombi(files) -> None:
|
||||
for f in files:
|
||||
proc = subprocess.run(
|
||||
["tombi", "format", str(f)], capture_output=True, text=True, check=False
|
||||
)
|
||||
if proc.returncode != 0:
|
||||
print(f" tombi format {f.name}: FAILED\n{proc.stdout}{proc.stderr}")
|
||||
|
||||
|
||||
def backup_settings(state_dir: Path, keep: int = KEEP_BACKUPS):
|
||||
src = state_dir / "settings.toml"
|
||||
if not src.exists():
|
||||
return None
|
||||
bak = state_dir / "settings.bak.d"
|
||||
bak.mkdir(parents=True, exist_ok=True)
|
||||
ts = datetime.now(timezone.utc).strftime("%Y%m%d-%H%M%S")
|
||||
dest = bak / f"{ts}.toml"
|
||||
n = 1
|
||||
while dest.exists():
|
||||
dest = bak / f"{ts}-{n}.toml"
|
||||
n += 1
|
||||
shutil.move(str(src), str(dest))
|
||||
# Prune oldest backups, counting only timestamp-shaped files we own.
|
||||
backups = sorted(
|
||||
f for f in bak.glob("*.toml") if re.fullmatch(r"\d{8}-\d{6}(?:-\d+)?", f.stem)
|
||||
)
|
||||
for old in backups[:-keep]:
|
||||
old.unlink()
|
||||
return dest
|
||||
|
||||
|
||||
def reload_instance():
|
||||
proc = subprocess.run(
|
||||
["noctalia", "msg", "config-reload"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=15,
|
||||
check=False,
|
||||
)
|
||||
if proc.returncode == 0:
|
||||
print(" reload: noctalia msg config-reload")
|
||||
else:
|
||||
print(" reload: noctalia not running or reload failed")
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser(
|
||||
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
|
||||
)
|
||||
ap.add_argument(
|
||||
"--apply", action="store_true", help="apply the fold (default: preview only)"
|
||||
)
|
||||
ap.add_argument(
|
||||
"--config-dir", type=Path, default=DEFAULT_CONFIG_DIR, help=argparse.SUPPRESS
|
||||
)
|
||||
ap.add_argument(
|
||||
"--state-dir", type=Path, default=DEFAULT_STATE_DIR, help=argparse.SUPPRESS
|
||||
)
|
||||
ap.add_argument("--export-file", type=Path, default=None, help=argparse.SUPPRESS)
|
||||
args = ap.parse_args()
|
||||
|
||||
config_dir = args.config_dir.resolve()
|
||||
state_dir = args.state_dir
|
||||
if not config_dir.is_dir():
|
||||
sys.exit(f"error: config dir not found: {config_dir}")
|
||||
|
||||
if not args.export_file:
|
||||
live = Path(os.path.realpath(Path.home() / ".config" / "noctalia"))
|
||||
if live != config_dir:
|
||||
print(
|
||||
f"warning: ~/.config/noctalia is not linked to {config_dir} (found {live});"
|
||||
)
|
||||
print(" the live export may describe a different config")
|
||||
|
||||
export = parse_export(args.export_file)
|
||||
|
||||
# Parse per-aspect files; map each top-level root to its owning file.
|
||||
files = sorted(config_dir.glob("*.toml"))
|
||||
texts = {}
|
||||
parsed = {}
|
||||
for f in files:
|
||||
text = f.read_text()
|
||||
texts[f] = text
|
||||
parsed[f] = tomli.loads(text)
|
||||
root_map = {}
|
||||
for f, d in parsed.items():
|
||||
for root in d:
|
||||
root_map.setdefault(root, f)
|
||||
|
||||
# Collect every change the export implies relative to the repo.
|
||||
changes = []
|
||||
new_files = {}
|
||||
for root, subtree in export.items():
|
||||
if not isinstance(subtree, dict):
|
||||
continue # do not fold top-level scalars
|
||||
tgt = root_map.get(root)
|
||||
if tgt is None:
|
||||
new_files[root] = subtree
|
||||
continue
|
||||
cur = parsed[tgt].get(root)
|
||||
collect_changes(cur if isinstance(cur, dict) else {}, subtree, [root], changes)
|
||||
|
||||
sets_by_file, subs_by_file = {}, {}
|
||||
for path, old, val in changes:
|
||||
f = root_map[path[0]]
|
||||
if isinstance(val, dict): # new subtree
|
||||
subs_by_file.setdefault(f, []).append((path, old, val))
|
||||
else:
|
||||
sets_by_file.setdefault(f, []).append((path, old, val))
|
||||
|
||||
if not changes and not new_files:
|
||||
print("No changes to fold. Repo config already matches the export.")
|
||||
return
|
||||
|
||||
# Preview
|
||||
touched = set(sets_by_file) | set(subs_by_file)
|
||||
for f in sorted(touched, key=str):
|
||||
rel = os.path.relpath(f, REPO)
|
||||
print(f"\n{rel}")
|
||||
for path, old, val in sorted(
|
||||
sets_by_file.get(f, []), key=lambda c: _dotted(c[0])
|
||||
):
|
||||
key = _dotted(path)
|
||||
if old is None:
|
||||
print(f" + {key} = {serialize_value(val)}")
|
||||
else:
|
||||
print(f" ~ {key}: {serialize_value(old)} -> {serialize_value(val)}")
|
||||
for path, old, subtree in subs_by_file.get(f, []):
|
||||
print(f" + [{_dotted(path)}]")
|
||||
for line in serialize_subtree(path, subtree).splitlines():
|
||||
if line.strip():
|
||||
print(f" {line}")
|
||||
for root in new_files:
|
||||
print(
|
||||
f"\n + new section root: {root} (new file {root.replace('_', '-')}.toml)"
|
||||
)
|
||||
|
||||
if not args.apply:
|
||||
total = len(changes) + len(new_files)
|
||||
file_count = len(touched) + len(new_files)
|
||||
print(
|
||||
f"\n{total} change{'s' if total != 1 else ''} in {file_count} file(s)."
|
||||
)
|
||||
print("Run with --apply to fold into the repo.")
|
||||
return
|
||||
|
||||
# Apply
|
||||
for f in sorted(touched, key=str):
|
||||
data = parsed[f]
|
||||
for path, old, val in sets_by_file.get(f, []):
|
||||
apply_path(data, path, clean_value(val), as_table=False, old=old)
|
||||
for path, old, subtree in subs_by_file.get(f, []):
|
||||
apply_path(data, path, clean_value(subtree), as_table=True, old=old)
|
||||
f.write_text(restore_comments(texts[f], tomli_w.dumps(data)))
|
||||
|
||||
new_paths = []
|
||||
for root, subtree in new_files.items():
|
||||
p = config_dir / (root.replace("_", "-") + ".toml")
|
||||
p.write_text(tomli_w.dumps(clean_value({root: subtree})))
|
||||
new_paths.append(p)
|
||||
files.append(p)
|
||||
|
||||
print(" formatting changed files with tombi...")
|
||||
run_tombi(sorted(touched, key=str) + new_paths)
|
||||
|
||||
# Completeness: repo-as-loaded must now equal the export (within tolerance).
|
||||
repo_after = {}
|
||||
for f in files:
|
||||
repo_after.update(tomli.loads(f.read_text()))
|
||||
diffs = completeness_diffs(export, repo_after)
|
||||
if diffs:
|
||||
print("error: repo does not fully reproduce the export after applying:")
|
||||
for p, old, val in diffs[:20]:
|
||||
print(f" {_dotted(p)}: {serialize_value(old)} != {serialize_value(val)}")
|
||||
sys.exit(1)
|
||||
|
||||
if not run_validate(config_dir):
|
||||
sys.exit("error: validation failed after applying changes")
|
||||
|
||||
bak = backup_settings(state_dir)
|
||||
if bak:
|
||||
print(f" backed up {state_dir}/settings.toml -> {bak}")
|
||||
reload_instance()
|
||||
else:
|
||||
# Should not reach this branch, since a fold implies GUI overrides exist.
|
||||
print("warning: settings.toml does not exist. Nothing backuped")
|
||||
|
||||
total = len(changes) + len(new_files)
|
||||
print(f"\nDone. {total} change{'s' if total != 1 else ''} folded.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+21
-5
@@ -1,12 +1,28 @@
|
||||
{ inputs, ... }:
|
||||
{
|
||||
imports = [ inputs.treefmt.flakeModule ];
|
||||
perSystem.treefmt = {
|
||||
{ inputs, ... }: {
|
||||
imports = [
|
||||
inputs.treefmt.flakeModule
|
||||
];
|
||||
perSystem.treefmt = { lib, pkgs, ... }: {
|
||||
projectRootFile = "flake.nix";
|
||||
programs = {
|
||||
nixfmt.enable = true;
|
||||
stylua.enable = true;
|
||||
keep-sorted.enable = true;
|
||||
stylua.enable = true;
|
||||
ruff.enable = true;
|
||||
};
|
||||
settings.formatter.tombi = {
|
||||
command = "${pkgs.bash}/bin/bash";
|
||||
options = [
|
||||
"-euc"
|
||||
''
|
||||
for file in "$@"; do
|
||||
${lib.getExe pkgs.tombi} fmt $file
|
||||
done
|
||||
''
|
||||
"--"
|
||||
];
|
||||
includes = [ "*.toml" ];
|
||||
};
|
||||
settings.excludes = [ "secrets/*" ];
|
||||
};
|
||||
}
|
||||
|
||||
+4
-9
@@ -1,18 +1,13 @@
|
||||
#:schema https://raw.githubusercontent.com/crate-ci/typos/refs/heads/master/config.schema.json
|
||||
|
||||
[files]
|
||||
extend-exclude = [
|
||||
"secrets"
|
||||
]
|
||||
extend-exclude = ["secrets"]
|
||||
|
||||
[default]
|
||||
extend-ignore-identifiers-re = ["KEY_102ND", "VE_UE"]
|
||||
|
||||
[default.extend-words]
|
||||
# noice.nvim
|
||||
noice = "noice"
|
||||
enew = "enew"
|
||||
iif = "iif"
|
||||
|
||||
[default]
|
||||
extend-ignore-identifiers-re = [
|
||||
"KEY_102ND",
|
||||
"VE_UE"
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user