Compare commits

..
61 Commits
Author SHA1 Message Date
imxyy1soope1 39b5ec89be splayer: replace by splayer-next 2026-09-05 20:18:55 +08:00
imxyy1soope1 925aac68ef flake.lock: update 2026-09-05 20:18:35 +08:00
imxyy1soope1 786d8f9ee3 noctalia: enable audio 2026-08-30 17:57:59 +08:00
imxyy1soope1 43f6edcf02 starship: increase scan_timeout to 1500ms 2026-08-30 15:40:15 +08:00
imxyy1soope1 83cfd6969c imxyy-nix: disable amdgpu runtime power management 2026-08-30 15:39:29 +08:00
imxyy1soope1 1beb5a3338 noctalia: noctification.layer = "top" 2026-08-30 12:40:23 +08:00
imxyy1soope1 0d6deec01e noctalia: fix sync-noctalia skipping new sections when no other changes 2026-08-30 12:03:44 +08:00
imxyy1soope1 818c9f6af8 noctalia: fold bar/widget GUI overrides into config 2026-08-29 11:30:20 +08:00
imxyy1soope1 8a9384de15 noctalia: add just sync-noctalia to fold GUI overrides 2026-08-29 11:28:58 +08:00
imxyy1soope1 8b141b9da0 fmt: reformat *.toml with tombi, add tombi to treefmt.nix 2026-08-29 09:49:32 +08:00
imxyy1soope1 dd0097a1f8 desktop: disable speechd (enabled by default) 2026-08-29 09:16:40 +08:00
imxyy1soope1 5f8c8b3948 agents: disable pi & oh-my-pi 2026-08-28 17:22:55 +08:00
imxyy1soope1 097b02ecef langs: rust: drop evcxr 2026-08-28 17:14:15 +08:00
imxyy1soope1 c04405c0fb noctalia: update media widget config 2026-08-28 17:02:43 +08:00
imxyy1soope1 e2a8892148 coding: persist ~/.config/gh 2026-08-28 16:23:56 +08:00
imxyy1soope1 724220504f noctalia: clipboard_history_max_entries = 1000 2026-08-28 16:13:20 +08:00
imxyy1soope1 7c37843808 noctalia: migrate to noctalia v5 2026-08-28 14:25:36 +08:00
imxyy1soope1 527812781f jj: persist ~/.config/jj 2026-08-27 12:21:32 +08:00
imxyy1soope1 e16b8ce5ea flake.lock: update 2026-08-27 12:21:25 +08:00
imxyy1soope1 7c67ec4c5e coding: langs: c: add meson and ninja 2026-08-23 16:50:27 +08:00
imxyy1soope1 92b388abb1 selector4nix: listen 0.0.0.0 2026-08-22 22:50:56 +08:00
imxyy1soope1 6e7bf06d97 server: net: use nixpkgs' ddns-go 2026-08-22 22:50:06 +08:00
imxyy1soope1 7cdc66d415 nix: add THU's mirror; add select4nix's binary cache 2026-08-22 11:04:42 +08:00
imxyy1soope1 be47a92dd8 flake.lock: update 2026-08-21 19:00:06 +08:00
imxyy1soope1 86a132344a coding: direnv: load .envrc.local 2026-08-16 15:30:01 +08:00
imxyy1soope1 810641a7bb agents: persist ZCode 2026-08-16 15:29:44 +08:00
imxyy1soope1 425ae29c3d agents: use nixpkgs's codex 2026-08-16 15:29:30 +08:00
imxyy1soope1 6d6a93e64c nix: add nix-tree-rs and fast-nix-gc 2026-08-15 15:55:29 +08:00
imxyy1soope1 2e4582219f niri: don't stop niri.service on switch
niri-nix removed its X-StopIfChanged/X-RestartIfChanged drop-in for
niri.service in acccaf2202, so switch-to-configuration-ng now stops the
running compositor (killing the graphical session) whenever the niri
store path changes. Restore the drop-in locally; the updated binary
takes effect on the next login instead.
2026-08-15 13:44:33 +08:00
imxyy1soope1 3898153f27 flake: update flake.lock; use nixpkgs-multiverse 2026-08-14 20:55:11 +08:00
imxyy1soope1 5498833916 flake.lock: update 2026-08-14 18:43:06 +08:00
imxyy1soope1 1cf0d8fed2 nix: nix-racer -> selector4nix
Replace the vendored nix-racer Rust proxy with selector4nix as the local
substituter proxy. Drop the nix-racer crate and its systemd service, add
the selector4nix flake input, repoint nix.settings.substituters at its
port, and load upstream nixos modules via an upstreamModules list in
flake/hosts.nix.
2026-08-08 21:36:18 +08:00
imxyy1soope1 96de1d082c secrets: update 2026-08-08 10:44:44 +08:00
imxyy1soope1 c628c7abe4 coding: langs: disable java by default 2026-08-08 10:43:52 +08:00
imxyy1soope1 ac1dbb1827 coding: langs: drop qml 2026-08-08 10:43:41 +08:00
imxyy1soope1 b14a5f0e55 flake.lock: update 2026-08-08 10:43:29 +08:00
imxyy1soope1 4fd98efa70 imxyy-nix: net: use network card's own MAC address 2026-08-07 18:12:11 +08:00
imxyy1soope1 cb0d442ff1 flake.lock: update 2026-08-01 21:20:30 +08:00
imxyy1soope1 0f04406706 neovim: add hunk.nvim 2026-08-01 21:20:27 +08:00
imxyy1soope1 935530aca5 programs, xdg: move app packages and MIME defaults into modules 2026-08-01 17:14:44 +08:00
imxyy1soope1 27aaa9d05f desktop: terminal: add my.desktop.terminal.default for the niri Mod+Return binding 2026-08-01 17:13:52 +08:00
imxyy1soope1 6a2d25383d agents: persist ~/.pi and ~/.omp 2026-08-01 17:13:04 +08:00
imxyy1soope1 cab17c7fbd treewide: drop/disable unused software 2026-08-01 17:08:41 +08:00
imxyy1soope1 09d90aa045 .envrc: source .env 2026-08-01 16:37:52 +08:00
imxyy1soope1 c7aa57a644 overlays: niri-unstable: remove libdisplay overlay 2026-07-31 16:39:37 +08:00
imxyy1soope1 099149b7b0 imxyy-nix, imxyy-nix-server: hardware: enable zswap 2026-07-31 11:12:27 +08:00
imxyy1soope1 baaa799806 flake.lock: update 2026-07-31 11:12:27 +08:00
imxyy1soope1 22e63d5c4f agents: add pi and omp 2026-07-29 22:06:23 +08:00
imxyy1soope1 ad9771d339 server: podman: use nftables firewall driver
After `lpppsssy`, `networking.nat` now recreates table ip nat on each switch, evicting
netavark's published-port DNAT rules and breaking Caddy reverse proxies
to published container ports. Pin the nftables driver so rules live in
an isolated table inet netavark that NixOS never touches.
2026-07-27 22:24:04 +08:00
imxyy1soope1 fef9f79a78 net: switch from manual nftables to firewall module 2026-07-27 21:57:06 +08:00
imxyy1soope1 612ad77325 easytier: use unstable channel 2026-07-27 20:25:45 +08:00
imxyy1soope1 ad6bba9258 flake.lock: update 2026-07-27 16:16:05 +08:00
imxyy1soope1 4c39ae2673 go-musicfox: drop 2026-07-27 15:30:15 +08:00
imxyy1soope1 53444fa697 rust: install stdenv.cc 2026-07-26 22:07:22 +08:00
imxyy1soope1 ba5c0f3370 flake: update, add unstable-small channel, remove master channel 2026-07-26 21:30:28 +08:00
imxyy1soope1 35422a4210 user: pid = 1000 2026-07-26 21:29:37 +08:00
imxyy1soope1 bae1072493 server: update hardware config 2026-07-26 21:19:26 +08:00
imxyy1soope1 794260c5b8 agents: persist ~/.agents 2026-07-26 11:48:46 +08:00
imxyy1soope1 f940d94edb server: mylinspirer: init 2026-07-26 11:46:55 +08:00
imxyy1soope1 a5a52dd492 flake.lock: update 2026-07-24 18:33:54 +08:00
imxyy1soope1 ebb488ff40 server: use exact dnsmasq host records 2026-07-24 18:33:54 +08:00
93 changed files with 1748 additions and 3844 deletions
+1
View File
@@ -1 +1,2 @@
export IMPURE_ROOT=$(pwd) export IMPURE_ROOT=$(pwd)
dotenv
+8
View File
@@ -49,3 +49,11 @@ alias offline := switch-offline
@fmt: @fmt:
echo "Formatting files..." echo "Formatting files..."
nix fmt 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
+149 -445
View File
@@ -2,26 +2,16 @@
"nodes": { "nodes": {
"angrr": { "angrr": {
"inputs": { "inputs": {
"flake-compat": [
"flake-compat"
],
"flake-parts": [
"flake-parts"
],
"nix-darwin": "nix-darwin",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
],
"treefmt-nix": [
"treefmt"
] ]
}, },
"locked": { "locked": {
"lastModified": 1784308004, "lastModified": 1785554507,
"narHash": "sha256-LZ4c1msj6C2Rs6bTP3GUjJv2Jrzu17H9j8is+l3tPgc=", "narHash": "sha256-NI7EXya7us6ZH9ME6iqhDvMPbl6IewE1kfL4UuIP27c=",
"owner": "linyinfeng", "owner": "linyinfeng",
"repo": "angrr", "repo": "angrr",
"rev": "a66aa239575576fb1ee994a2cdb3928b7cedc13b", "rev": "45e0f06f3691a494d495b81e6739508657e56b5f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -118,66 +108,33 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1782772816, "lastModified": 1788011267,
"narHash": "sha256-s9BuFv0mRuZx9C1MF8qPHRdcAK14ONi0A5m6E2wqOoM=", "narHash": "sha256-mEq2kU+ljompTToZ44Afvm7d/rHJ5iMBl0tjZuyShJs=",
"owner": "nix-community", "owner": "Mic92",
"repo": "bun2nix", "repo": "bun2nix",
"rev": "5a39d717029e94163ac223aee8d5c9946cafed1c", "rev": "5765b0614591f75ee8ba5596e81ae85c167d1071",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nix-community", "owner": "Mic92",
"ref": "fix-structured-attrs-hook",
"repo": "bun2nix", "repo": "bun2nix",
"type": "github" "type": "github"
} }
}, },
"cachix": { "crane": {
"inputs": {
"devenv": [
"devenv"
],
"flake-compat": [
"devenv",
"flake-compat"
],
"git-hooks": [
"devenv",
"git-hooks"
],
"nixpkgs": [
"devenv",
"nixpkgs"
]
},
"locked": { "locked": {
"lastModified": 1777487137, "lastModified": 1787326676,
"narHash": "sha256-TuvKVBX60mqyMT6OB5JqVEh1YIWtFMR/igLCaCdC9tw=", "narHash": "sha256-lWhBbBvC05/xwivKBBiM2YNizpmgqCgyOIzomvRuwxs=",
"owner": "cachix", "owner": "ipetkov",
"repo": "cachix", "repo": "crane",
"rev": "a66a440c321d35f7193472c317f42a55ccd1cb93", "rev": "692f7e9ef2ece8125b466f66f2af532b3edaed0d",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "cachix", "owner": "ipetkov",
"ref": "latest", "ref": "master",
"repo": "cachix", "repo": "crane",
"type": "github"
}
},
"crate2nix": {
"flake": false,
"locked": {
"lastModified": 1772186516,
"narHash": "sha256-8s28pzmQ6TOIUzznwFibtW1CMieMUl1rYJIxoQYor58=",
"owner": "rossng",
"repo": "crate2nix",
"rev": "ba5dd398e31ee422fbe021767eb83b0650303a6e",
"type": "github"
},
"original": {
"owner": "rossng",
"repo": "crate2nix",
"rev": "ba5dd398e31ee422fbe021767eb83b0650303a6e",
"type": "github" "type": "github"
} }
}, },
@@ -188,11 +145,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1780519775, "lastModified": 1787592910,
"narHash": "sha256-u12imjPk4ZhOen/PgnLiNPML+5NmuKO0Ja4wQKU/Y8E=", "narHash": "sha256-a2+yPzqXAlnErn1KGW28UBlqapBmySvLPWOskVFB/Hg=",
"owner": "Bali10050", "owner": "Bali10050",
"repo": "Darkly", "repo": "Darkly",
"rev": "11c27e2d98025f4d4c1598f07a185280b36f35f7", "rev": "65f6fa62675e3c30986f8fc8e4fdbba053096491",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -201,36 +158,27 @@
"type": "github" "type": "github"
} }
}, },
"devenv": { "fast-nix-gc": {
"inputs": { "inputs": {
"cachix": "cachix", "nix-darwin": "nix-darwin",
"crate2nix": "crate2nix",
"flake-compat": [
"flake-compat"
],
"flake-parts": [
"flake-parts"
],
"ghostty": "ghostty",
"git-hooks": "git-hooks",
"nix": "nix",
"nixd": "nixd",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
], ],
"rust-overlay": "rust-overlay" "treefmt-nix": [
"treefmt"
]
}, },
"locked": { "locked": {
"lastModified": 1784325378, "lastModified": 1788439409,
"narHash": "sha256-Gof6j4d43yX2qSLLp78JILke346IggDFIxTgl3ecVQE=", "narHash": "sha256-AvaugOI0Hb8ZG+2goIbISKpYfW6ovdvDm/uf7PT8PO8=",
"owner": "cachix", "owner": "Mic92",
"repo": "devenv", "repo": "fast-nix-gc",
"rev": "5f1cf17be0fc48689bd0ecb810de6d2e06d259a1", "rev": "18d82a8ce3e938ff97b5e11c7d2033f0333af5bb",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "cachix", "owner": "Mic92",
"repo": "devenv", "repo": "fast-nix-gc",
"type": "github" "type": "github"
} }
}, },
@@ -242,11 +190,11 @@
"rust-analyzer-src": "rust-analyzer-src" "rust-analyzer-src": "rust-analyzer-src"
}, },
"locked": { "locked": {
"lastModified": 1784449545, "lastModified": 1788603547,
"narHash": "sha256-JhtSybgqZfoTwvIaRUl6k0za11aQQ5FhULPcUfj6P+M=", "narHash": "sha256-/ioB+JvyRtHtQOpgZYC95KiD6Gw76ZDdSbkiItR4FG4=",
"owner": "nix-community", "owner": "nix-community",
"repo": "fenix", "repo": "fenix",
"rev": "15b21023f8d514dfeaa2a71047288361437558e4", "rev": "03864c059200a8a96f2ee6bb050c69eae96f57ca",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -258,11 +206,11 @@
"firefox-gnome-theme": { "firefox-gnome-theme": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1779670703, "lastModified": 1783570805,
"narHash": "sha256-UdfMivNMwCCqQsYDg5pSz8X2IOaOrIZLIIy+Bg3CO2o=", "narHash": "sha256-ptl5aRlCv9/uRSv2u8Hq8UFVFeZ6Q/bT049bpqNgc3w=",
"owner": "rafaelmardojai", "owner": "rafaelmardojai",
"repo": "firefox-gnome-theme", "repo": "firefox-gnome-theme",
"rev": "942159e73e40bf785816f7f1f5feed9ef3d7c8f9", "rev": "5602ed62d638142c1ab31dccd01dfbfb28841225",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -293,11 +241,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1782949081, "lastModified": 1788450739,
"narHash": "sha256-vp6Y/Grm98ESt6ceOkWiHWyZRDV3J1RID4w+6NWK9yA=", "narHash": "sha256-glZLQlzIn1fXH6PazR2iUmTo7kzzyYSshrWhLS9TqCU=",
"owner": "hercules-ci", "owner": "hercules-ci",
"repo": "flake-parts", "repo": "flake-parts",
"rev": "17c9d6cdfc60c64f4ee8d306f9bc0b4ccb51481e", "rev": "31729ca8cbdb4fa927b34e5f4353e6a83f39e993",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -306,21 +254,6 @@
"type": "github" "type": "github"
} }
}, },
"flake-root": {
"locked": {
"lastModified": 1723604017,
"narHash": "sha256-rBtQ8gg+Dn4Sx/s+pvjdq3CB2wQNzx9XGFq/JVGCB6k=",
"owner": "srid",
"repo": "flake-root",
"rev": "b759a56851e10cb13f6b8e5698af7b59c44be26e",
"type": "github"
},
"original": {
"owner": "srid",
"repo": "flake-root",
"type": "github"
}
},
"flake-utils": { "flake-utils": {
"inputs": { "inputs": {
"systems": [ "systems": [
@@ -357,92 +290,23 @@
"type": "github" "type": "github"
} }
}, },
"ghostty": {
"flake": false,
"locked": {
"lastModified": 1782866021,
"narHash": "sha256-BOLtzL5iAHmtCOg9/DXtcfw+K86QWol088K72chJB04=",
"owner": "ghostty-org",
"repo": "ghostty",
"rev": "e1d31deaaed21aa9225afca78d778fb373c95852",
"type": "github"
},
"original": {
"owner": "ghostty-org",
"repo": "ghostty",
"type": "github"
}
},
"git-hooks": {
"inputs": {
"flake-compat": [
"devenv",
"flake-compat"
],
"nixpkgs": [
"devenv",
"nixpkgs"
]
},
"locked": {
"lastModified": 1782908218,
"narHash": "sha256-wLMOrPgVyeF3XmP+qfYcLqnVdTxikdcSvbIY7rA9jTA=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "9f7e99119ece7705299595299f3b031f39356de1",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "git-hooks.nix",
"type": "github"
}
},
"gnome-shell": { "gnome-shell": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1767737596, "host": "gitlab.gnome.org",
"narHash": "sha256-eFujfIUQDgWnSJBablOuG+32hCai192yRdrNHTv0a+s=", "lastModified": 1776175984,
"narHash": "sha256-RJFlFW8GiMei6oqUGrMkGEvVqOH8U7Q8abc1yK4VKD8=",
"owner": "GNOME", "owner": "GNOME",
"repo": "gnome-shell", "repo": "gnome-shell",
"rev": "ef02db02bf0ff342734d525b5767814770d85b49", "rev": "e0fdc4c13250e9a9b8ea9594c83925274f4a5dca",
"type": "github" "type": "gitlab"
}, },
"original": { "original": {
"host": "gitlab.gnome.org",
"owner": "GNOME", "owner": "GNOME",
"ref": "50.1",
"repo": "gnome-shell", "repo": "gnome-shell",
"rev": "ef02db02bf0ff342734d525b5767814770d85b49", "type": "gitlab"
"type": "github"
}
},
"go-musicfox": {
"inputs": {
"devenv": [
"devenv"
],
"flake-parts": [
"flake-parts"
],
"flake-root": "flake-root",
"mission-control": "mission-control",
"mk-shell-bin": "mk-shell-bin",
"nix2container": "nix2container",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1774163189,
"narHash": "sha256-X+1kQ611zdZNJfPQTLGz/zjazjU8PngzsZqmVhxSlb4=",
"owner": "imxyy1soope1",
"repo": "go-musicfox",
"rev": "6a7a4a5b7b14be5cb1e897c7540c7685034aa693",
"type": "github"
},
"original": {
"owner": "imxyy1soope1",
"repo": "go-musicfox",
"type": "github"
} }
}, },
"haumea": { "haumea": {
@@ -473,11 +337,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1784489491, "lastModified": 1788487777,
"narHash": "sha256-j9maqjx1T8+ljAVntAdSI5hSGCm77QNZz64JF1rJNu0=", "narHash": "sha256-Ro/e1N4ZR8/XaFF+sF9SgfPK79HM5YNEppzFj8p+0Ak=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "3139deb8cafbe73b39b24451255b2fdd3426077e", "rev": "693e8ce0fb240a73c116a03cfd7b19269c87af88",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -541,11 +405,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1784518056, "lastModified": 1788605532,
"narHash": "sha256-ej+RYMjdZA7pjkTAyF7hv2QPGufpbLPNqLp4m4/Egdg=", "narHash": "sha256-kqEZkn2YPC9mgJn6Wh6L1uuukvYYMbQryzaFHO41GxU=",
"owner": "numtide", "owner": "numtide",
"repo": "llm-agents.nix", "repo": "llm-agents.nix",
"rev": "001bccfd741e99a3020b7080e310478596401d1e", "rev": "3a3523b87e7bb7253fac39c95895ec20f241d672",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -554,33 +418,18 @@
"type": "github" "type": "github"
} }
}, },
"mission-control": { "multiverse": {
"locked": { "locked": {
"lastModified": 1733438716, "lastModified": 1788596457,
"narHash": "sha256-1tt43rwHk0N5fwEhbpsHWO4nBVFCQN0w1KM427DNycM=", "narHash": "sha256-6iJ0N8hUClykevMfX8Qwt2ObOBaQF6yK7wf12OoOovk=",
"owner": "Platonic-Systems", "owner": "fzakaria",
"repo": "mission-control", "repo": "nixpkgs-multiverse",
"rev": "65d04c4ab9db076eff09824d2936a5c215c21f36", "rev": "5caf7ed36b0ddf54878ef30a738fd327c9682ffa",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "Platonic-Systems", "owner": "fzakaria",
"repo": "mission-control", "repo": "nixpkgs-multiverse",
"type": "github"
}
},
"mk-shell-bin": {
"locked": {
"lastModified": 1677004959,
"narHash": "sha256-/uEkr1UkJrh11vD02aqufCxtbF5YnhRTIKlx5kyvf+I=",
"owner": "rrbutani",
"repo": "nix-mk-shell-bin",
"rev": "ff5d8bd4d68a347be5042e2f16caee391cd75887",
"type": "github"
},
"original": {
"owner": "rrbutani",
"repo": "nix-mk-shell-bin",
"type": "github" "type": "github"
} }
}, },
@@ -608,11 +457,11 @@
"xwayland-satellite-unstable": "xwayland-satellite-unstable" "xwayland-satellite-unstable": "xwayland-satellite-unstable"
}, },
"locked": { "locked": {
"lastModified": 1784429437, "lastModified": 1788566543,
"narHash": "sha256-UQjrOfWx73M3xe+2xevAZz61K0llZN+qtV8wAdXmnQE=", "narHash": "sha256-7snI9zOQMvM0ghxW9+7Tl/8pvDa4KGmQBCmRzbY9TxI=",
"ref": "refs/heads/main", "ref": "refs/heads/main",
"rev": "fedf5d937fc4a7c3008a1419d32fd0c537f829a8", "rev": "2bce88af7bbeff97ac132d870e2efd08a294c8f0",
"revCount": 144, "revCount": 181,
"type": "git", "type": "git",
"url": "https://codeberg.org/bananad3v/niri-nix" "url": "https://codeberg.org/bananad3v/niri-nix"
}, },
@@ -624,11 +473,11 @@
"niri-unstable": { "niri-unstable": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1783522755, "lastModified": 1787337984,
"narHash": "sha256-dI0HkX1djETia7cD/Y64h8BNIsSOfTRMzfNum2J6UhE=", "narHash": "sha256-BNZUEVR2H96hCKENNKoLSSTFT8W4smp7v94hJc4Ehfc=",
"owner": "YaLTeR", "owner": "YaLTeR",
"repo": "niri", "repo": "niri",
"rev": "0777769e719b7c9b7c980d4ea66288bfbb4da5b3", "rev": "dd75865f547f0eac0e9b6c4d86d2cd00c0744252",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -637,59 +486,19 @@
"type": "github" "type": "github"
} }
}, },
"nix": {
"inputs": {
"flake-compat": [
"devenv",
"flake-compat"
],
"flake-parts": [
"devenv",
"flake-parts"
],
"git-hooks-nix": [
"devenv",
"git-hooks"
],
"nixpkgs": [
"devenv",
"nixpkgs"
],
"nixpkgs-23-11": [
"devenv"
],
"nixpkgs-regression": [
"devenv"
]
},
"locked": {
"lastModified": 1782407171,
"narHash": "sha256-xem+4ncdQCTFJsQ4PrVuyVmi3j4w/Yqg298hBUzVejA=",
"owner": "cachix",
"repo": "nix",
"rev": "782ac1b155679b065ec945ae50d0fa1d495883b7",
"type": "github"
},
"original": {
"owner": "cachix",
"ref": "devenv-2.34",
"repo": "nix",
"type": "github"
}
},
"nix-darwin": { "nix-darwin": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
"angrr", "fast-nix-gc",
"nixpkgs" "nixpkgs"
] ]
}, },
"locked": { "locked": {
"lastModified": 1784123936, "lastModified": 1785389976,
"narHash": "sha256-IOWwQMJhUxcojm0MRvuKs1fKLH727u4+hHeEOPhdUyA=", "narHash": "sha256-0tLW8Ff5yt8AH97jw4ZpFJ0OCJ122zIlgWGDmOfU/VU=",
"owner": "nix-darwin", "owner": "nix-darwin",
"repo": "nix-darwin", "repo": "nix-darwin",
"rev": "a4cf1d10853b0d2be19b9eca35d749e201d70b55", "rev": "15abb8c98f336cd8bd840d71059adebabe60bf04",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -698,53 +507,29 @@
"type": "github" "type": "github"
} }
}, },
"nix2container": { "nix-tree-rs": {
"inputs": {
"flake-utils": [
"flake-utils"
],
"nixpkgs": [
"go-musicfox",
"nixpkgs"
]
},
"locked": {
"lastModified": 1730479402,
"narHash": "sha256-79NLeNjpCa4mSasmFsE3QA6obURezF0TUO5Pm+1daog=",
"owner": "nlewo",
"repo": "nix2container",
"rev": "5fb215a1564baa74ce04ad7f903d94ad6617e17a",
"type": "github"
},
"original": {
"owner": "nlewo",
"repo": "nix2container",
"type": "github"
}
},
"nixd": {
"inputs": { "inputs": {
"flake-parts": [ "flake-parts": [
"devenv",
"flake-parts" "flake-parts"
], ],
"nixpkgs": [ "nixpkgs": [
"devenv",
"nixpkgs" "nixpkgs"
], ],
"treefmt-nix": "treefmt-nix" "treefmt-nix": [
"treefmt"
]
}, },
"locked": { "locked": {
"lastModified": 1783935112, "lastModified": 1787652563,
"narHash": "sha256-IAQ14nteIKXAz4cd75UcZrsHGEVJ7QNrkUwX9rmeZ/Y=", "narHash": "sha256-ec73Anjp5QDIid2Z/iNC9jaGRqO9aLtYOJOo95dd5YU=",
"owner": "nix-community", "owner": "Mic92",
"repo": "nixd", "repo": "nix-tree-rs",
"rev": "a64cd33e53b316b6b092ea0a966640cd2309bf3d", "rev": "9654bd185c7043c60ae999b4d3a9b038e85b111b",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nix-community", "owner": "Mic92",
"repo": "nixd", "repo": "nix-tree-rs",
"type": "github" "type": "github"
} }
}, },
@@ -758,11 +543,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1784058842, "lastModified": 1784642409,
"narHash": "sha256-3u3tvbCIAid3Mv7RrJx13jusIEQC/HeKYhO/SUSxR3A=", "narHash": "sha256-hcbDqFuySAJawljt5r0sKBCJKYnbtGD0T/ZIozH1Dq0=",
"owner": "nix-community", "owner": "nix-community",
"repo": "NixOS-WSL", "repo": "NixOS-WSL",
"rev": "24c8dc8e0f2170e1a377be24dfadc7d9d21dc1ad", "rev": "eaeb18da90024448a60eb1ec7132eafa4003404e",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -773,11 +558,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1784453100, "lastModified": 1788400875,
"narHash": "sha256-zpGZb8FYui+i8KLtC0nlcmb0voR2zB80Qn8pe7lzIbk=", "narHash": "sha256-JIHQ6xNAN53cdo6zZ72LRcQ9lpvnABCnNE4hldJ5uZU=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "b471514bed69eff5255c8e63c1f80e5fe56c616f", "rev": "5545adfad2e98de106a5544ca7067e03010410bd",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -787,45 +572,13 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs-master": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1784525419, "lastModified": 1788531059,
"narHash": "sha256-yocJ4I4Kd4as0UPMFs9P7laPvvA2x/Bj8EW46iW3VVM=", "narHash": "sha256-hLD4l3QOGBQhkVp3mQ2lJ/YbEi99qUgKapb40KovZ88=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "a16c3fde2ffeab7f6326f50f460aaffde7ae066d", "rev": "801bef6abd86b91e51083066b83fb354a11fc640",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "master",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1783375776,
"narHash": "sha256-pg6hLjDeAWaUOzh2JM2Cw0BwYpGtOyNr6A4FBwP9Ymo=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "cd648d6ea62bc0ffba91e61fcfe5e33c1e2004b1",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "release-25.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1784356753,
"narHash": "sha256-12KrbMiWLcf8m7pCvAtZh1ZrgF85ZXDXvfR/fWTKy84=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "61b7c44c4073f0b827768aff0049561b5110ea5a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -839,47 +592,20 @@
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
"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": { "locked": {
"lastModified": 1775008123, "lastModified": 1787858564,
"narHash": "sha256-zsd/kbsgfX2YQAlbao40JxyeVDwsUmBGyUDZc/Vo1C4=", "narHash": "sha256-WijEuINvjcXMO/e/zMqwG1lyGiWNosnVt1QY+ko0Rw8=",
"owner": "noctalia-dev", "owner": "noctalia-dev",
"repo": "noctalia-qs", "repo": "noctalia-shell",
"rev": "b87f41771c050d3c101d1528532de53293cba6da", "rev": "74e6c2790dd8f39bf496e90e479a9ae370846eed",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "noctalia-dev", "owner": "noctalia-dev",
"repo": "noctalia-qs", "ref": "v5.0.0-beta.10",
"repo": "noctalia-shell",
"type": "github" "type": "github"
} }
}, },
@@ -895,11 +621,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1780281641, "lastModified": 1785549842,
"narHash": "sha256-M/+hUKoKbHXpV0xGVfELbN1Ds1aoe3pL5p5/t46YhVo=", "narHash": "sha256-DCwBZmGsySF7oKGTRgEv2HvpxVXkHT+38VhTM76k0B4=",
"owner": "nix-community", "owner": "nix-community",
"repo": "NUR", "repo": "NUR",
"rev": "30f9ae2f04174de63ba8bcf3580ca90843b28a01", "rev": "a9f987b57594e845e3e5cdd423b9a70846d70308",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -912,27 +638,24 @@
"inputs": { "inputs": {
"angrr": "angrr", "angrr": "angrr",
"darkly": "darkly", "darkly": "darkly",
"devenv": "devenv", "fast-nix-gc": "fast-nix-gc",
"fenix": "fenix", "fenix": "fenix",
"flake-compat": "flake-compat", "flake-compat": "flake-compat",
"flake-parts": "flake-parts", "flake-parts": "flake-parts",
"flake-utils": "flake-utils", "flake-utils": "flake-utils",
"go-musicfox": "go-musicfox",
"haumea": "haumea", "haumea": "haumea",
"home-manager": "home-manager", "home-manager": "home-manager",
"impermanence": "impermanence", "impermanence": "impermanence",
"infuse": "infuse", "infuse": "infuse",
"llm-agents": "llm-agents", "llm-agents": "llm-agents",
"multiverse": "multiverse",
"my-templates": "my-templates", "my-templates": "my-templates",
"niri-nix": "niri-nix", "niri-nix": "niri-nix",
"nix-tree-rs": "nix-tree-rs",
"nixos-wsl": "nixos-wsl", "nixos-wsl": "nixos-wsl",
"nixpkgs": [ "nixpkgs": "nixpkgs_2",
"nixpkgs-unstable"
],
"nixpkgs-master": "nixpkgs-master",
"nixpkgs-stable": "nixpkgs-stable",
"nixpkgs-unstable": "nixpkgs-unstable",
"noctalia": "noctalia", "noctalia": "noctalia",
"selector4nix": "selector4nix",
"sops-nix": "sops-nix", "sops-nix": "sops-nix",
"stylix": "stylix", "stylix": "stylix",
"system76-scheduler-niri": "system76-scheduler-niri", "system76-scheduler-niri": "system76-scheduler-niri",
@@ -944,11 +667,11 @@
"rust-analyzer-src": { "rust-analyzer-src": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1784363916, "lastModified": 1788445421,
"narHash": "sha256-ugQVFz4RGj12q8jhISxd07VcKS1hhd2Gz2Gn0z4V7tA=", "narHash": "sha256-sKEuAgygSpMZFvrj7IcCPm+3al2bQWukulM6pMEpCcc=",
"owner": "rust-lang", "owner": "rust-lang",
"repo": "rust-analyzer", "repo": "rust-analyzer",
"rev": "cac0779549328e4bd4b808000c03307f1721f869", "rev": "e8f7e90aa3e7b26aa9a000200f606c1078da99ec",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -958,24 +681,27 @@
"type": "github" "type": "github"
} }
}, },
"rust-overlay": { "selector4nix": {
"inputs": { "inputs": {
"crane": "crane",
"flake-parts": [
"flake-parts"
],
"nixpkgs": [ "nixpkgs": [
"devenv",
"nixpkgs" "nixpkgs"
] ]
}, },
"locked": { "locked": {
"lastModified": 1782875958, "lastModified": 1788514031,
"narHash": "sha256-5eqDcnBjb1424HRQdnhuhNOBZguq1Z2tqSa2OMF/m2c=", "narHash": "sha256-3nWq8IMC6GPtEqixSvpYX05nOfFqdnOfmkl0DOiWcQc=",
"owner": "oxalica", "owner": "StarryReverie",
"repo": "rust-overlay", "repo": "selector4nix",
"rev": "13139aefa973f3d96c60c0fbab801de058ae25ca", "rev": "1ff44ddb817ff943df9667ac1a0a79791b509a20",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "oxalica", "owner": "StarryReverie",
"repo": "rust-overlay", "repo": "selector4nix",
"type": "github" "type": "github"
} }
}, },
@@ -986,11 +712,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1783174389, "lastModified": 1788337237,
"narHash": "sha256-aCWC8ngycU7OdJrU2+Je3qf+1a2ykuBvpPhZT/9tXMc=", "narHash": "sha256-gkSH8VUtCo6hnysNmb9DbTuDepH2t5pv+QWjP75xKAk=",
"owner": "Mic92", "owner": "Mic92",
"repo": "sops-nix", "repo": "sops-nix",
"rev": "f1406619a3884cd5c47992a70b8b35c9c0fcb4c9", "rev": "fbf759290e0cb0a98dfc813a4eb7d53ad1dacb57",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1023,11 +749,11 @@
"tinted-zed": "tinted-zed" "tinted-zed": "tinted-zed"
}, },
"locked": { "locked": {
"lastModified": 1784059683, "lastModified": 1787771653,
"narHash": "sha256-q5MZrmKlg9A4ORx3EQcr7qkuidMU1gVZ+xJ3nCK+xgc=", "narHash": "sha256-DkkJSBOXWV/mja5Vy8az5g1KpZlsbUwlmH0BsQhowaQ=",
"owner": "danth", "owner": "danth",
"repo": "stylix", "repo": "stylix",
"rev": "c8ccc31f3ea29dc3eb5b54945e5eb549529491d6", "rev": "5e3809851f486e7fc7e84b40f174c74b60ecc784",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1090,11 +816,11 @@
"tinted-schemes": { "tinted-schemes": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1777806186, "lastModified": 1785153830,
"narHash": "sha256-PDF0/wObw4nIsSBeXVYLsloXOiphXCgIdsrNcVXguKs=", "narHash": "sha256-fNdfCTeCXU3tZG3TMincd+u68qBHQgCr2Ljr/M1mWP0=",
"owner": "tinted-theming", "owner": "tinted-theming",
"repo": "schemes", "repo": "schemes",
"rev": "0c94645546f4f3ddac77a1a5fce54eb95bf50795", "rev": "9bd28ed313560db3c5b605c63bc4e309e78e3fc8",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1106,11 +832,11 @@
"tinted-tmux": { "tinted-tmux": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1778379944, "lastModified": 1785031658,
"narHash": "sha256-wPDFzMGSlARlw0Sfsn48Q2+jPSfk6N0Ng6BC/d+7Q24=", "narHash": "sha256-mZp9O2LjzdMzlqQF3l3fjqsuPBzXy+1qTfBEUGjTlpk=",
"owner": "tinted-theming", "owner": "tinted-theming",
"repo": "tinted-tmux", "repo": "tinted-tmux",
"rev": "fe0203a198690e71a5ff11e08812a4673de3678d", "rev": "5d2c67f61ea7af36f16865ab6d541cdba41dc257",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1122,11 +848,11 @@
"tinted-zed": { "tinted-zed": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1778378178, "lastModified": 1785030526,
"narHash": "sha256-OXPXRIQgGwV77HjYRryOHguh4ALX96jkg+tseLkGgHA=", "narHash": "sha256-klZf8UviewRkxuu74Bhbq6tqy7oxebQC7UVRWbbtQxU=",
"owner": "tinted-theming", "owner": "tinted-theming",
"repo": "base16-zed", "repo": "base16-zed",
"rev": "9cd816033ff969415b190722cddf134e78a5665f", "rev": "16f5a8adf4a6b1310d0a61ab172de963e8f76a02",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1142,33 +868,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1784369104, "lastModified": 1786901030,
"narHash": "sha256-47cxbcZODibHv3rELFQ9vZly0vUNkND/atn/U7HLeb0=", "narHash": "sha256-WSFCsDSE5ffgD2MqzkM2CYjeFiKhRF/dJUN8uedb6YE=",
"owner": "numtide", "owner": "numtide",
"repo": "treefmt-nix", "repo": "treefmt-nix",
"rev": "df3c0640565d04a0261253cdd89fce78ec50168a", "rev": "27b3b12a8e6375f28ebe122f07d230ca5459bbfa",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"devenv",
"nixd",
"nixpkgs"
]
},
"locked": {
"lastModified": 1780220602,
"narHash": "sha256-eynAfOmbmxJnkp7YewvCEbShNnnYJ9gLLqkzsYtBPeM=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "db947814a175b7ca6ded66e21383d938df01c227",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1180,11 +884,11 @@
"xwayland-satellite-unstable": { "xwayland-satellite-unstable": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1783895132, "lastModified": 1788436361,
"narHash": "sha256-Dl0Gvrig3EpE962hzF3ETPhUztlfuRhcmlpd8ioHN54=", "narHash": "sha256-i0QYbUlC03SrOomU+37TdZ9EdtEWLaUtsCQjC7+KhNU=",
"owner": "Supreeeme", "owner": "Supreeeme",
"repo": "xwayland-satellite", "repo": "xwayland-satellite",
"rev": "a2b5c635d8c8c99b286967658d0d177044887eb8", "rev": "ea474b95a55ace75ad60a9bc0092a81ff5a1ba89",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1203,11 +907,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1784352415, "lastModified": 1788405419,
"narHash": "sha256-sHuh1KQopmLPWouFBYwZ5PVWj19Y4mKAjkQeQHCT3E0=", "narHash": "sha256-wuGizAVEmY0u15MYrhgy7AoQdHg+4Y2QiC+v/mxA8dc=",
"owner": "0xc000022070", "owner": "0xc000022070",
"repo": "zen-browser-flake", "repo": "zen-browser-flake",
"rev": "7202b917826e2e335d9935c3a943ae18681056b1", "rev": "fdb83f8fce835213fab7eab52c375926fe1a32dc",
"type": "github" "type": "github"
}, },
"original": { "original": {
+19 -26
View File
@@ -3,12 +3,8 @@
inputs = { inputs = {
# Nixpkgs # Nixpkgs
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable"; nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
nixpkgs-stable.url = "github:nixos/nixpkgs/release-25.11"; multiverse.url = "github:fzakaria/nixpkgs-multiverse";
nixpkgs-master.url = "github:nixos/nixpkgs/master";
# nixpkgs.follows = "nixpkgs-stable";
nixpkgs.follows = "nixpkgs-unstable";
# nixpkgs.follows = "nixpkgs-master";
# Home manager # Home manager
home-manager = { home-manager = {
@@ -67,25 +63,20 @@
angrr = { angrr = {
url = "github:linyinfeng/angrr"; url = "github:linyinfeng/angrr";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-compat.follows = "flake-compat";
inputs.flake-parts.follows = "flake-parts";
inputs.treefmt-nix.follows = "treefmt";
}; };
darkly = { darkly = {
url = "github:Bali10050/Darkly"; url = "github:Bali10050/Darkly";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
fast-nix-gc = {
url = "github:Mic92/fast-nix-gc";
inputs.nixpkgs.follows = "nixpkgs";
inputs.treefmt-nix.follows = "treefmt";
};
fenix = { fenix = {
url = "github:nix-community/fenix"; url = "github:nix-community/fenix";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
go-musicfox = {
url = "github:imxyy1soope1/go-musicfox";
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-parts.follows = "flake-parts";
inputs.devenv.follows = "devenv";
inputs.nix2container.inputs.flake-utils.follows = "flake-utils";
};
llm-agents = { llm-agents = {
url = "github:numtide/llm-agents.nix"; url = "github:numtide/llm-agents.nix";
# Not followed intentionally (binary cache) # Not followed intentionally (binary cache)
@@ -98,12 +89,20 @@
url = "git+https://codeberg.org/bananad3v/niri-nix"; url = "git+https://codeberg.org/bananad3v/niri-nix";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
nix-tree-rs = {
url = "github:Mic92/nix-tree-rs";
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-parts.follows = "flake-parts";
inputs.treefmt-nix.follows = "treefmt";
};
noctalia = { 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";
};
selector4nix = {
url = "github:StarryReverie/selector4nix";
inputs.flake-parts.follows = "flake-parts";
inputs.nixpkgs.follows = "nixpkgs"; 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";
}; };
zen = { zen = {
url = "github:0xc000022070/zen-browser-flake"; url = "github:0xc000022070/zen-browser-flake";
@@ -126,12 +125,6 @@
inputs.systems.follows = "systems"; inputs.systems.follows = "systems";
}; };
systems.url = "github:nix-systems/default"; systems.url = "github:nix-systems/default";
devenv = {
url = "github:cachix/devenv";
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-parts.follows = "flake-parts";
inputs.flake-compat.follows = "flake-compat";
};
}; };
outputs = outputs =
+11 -17
View File
@@ -2,7 +2,6 @@
self, self,
lib, lib,
inputs, inputs,
withSystem,
config, config,
pkgsParams, pkgsParams,
... ...
@@ -35,6 +34,16 @@ let
useGlobalPkgs = true; useGlobalPkgs = true;
}; };
}; };
upstreamModules = [
# keep-sorted start
inputs.angrr.nixosModules.angrr
inputs.home-manager.nixosModules.default
inputs.impermanence.nixosModules.impermanence
inputs.niri-nix.nixosModules.default
inputs.selector4nix.nixosModules.selector4nix
inputs.sops-nix.nixosModules.sops
# keep-sorted end
];
in in
{ {
options.nixosHosts = lib.mkOption { options.nixosHosts = lib.mkOption {
@@ -82,8 +91,6 @@ in
# Generate nixosConfigurations from declarative host definitions # Generate nixosConfigurations from declarative host definitions
flake.nixosConfigurations = lib.mapAttrs ( flake.nixosConfigurations = lib.mapAttrs (
hostname: hostConfig: hostname: hostConfig:
withSystem hostConfig.system (
{ ... }:
lib.nixosSystem { lib.nixosSystem {
inherit (hostConfig) system; inherit (hostConfig) system;
@@ -110,38 +117,25 @@ in
// hostConfig.extraSpecialArgs; // hostConfig.extraSpecialArgs;
modules = modules =
# Automatically import all feature modules
(lib.umport { (lib.umport {
paths = [ ../modules ]; paths = [ ../modules ];
extraExcludePredicate = path: lib.hasInfix "/_" (toString path); extraExcludePredicate = path: lib.hasInfix "/_" (toString path);
recursive = true; recursive = true;
}) })
++ [ ++ [
# Base profile (always included)
../profiles/base.nix ../profiles/base.nix
] ]
# Add requested profiles
++ (map (profile: ../profiles/${profile}.nix) hostConfig.profiles) ++ (map (profile: ../profiles/${profile}.nix) hostConfig.profiles)
# Add host-specific modules
++ hostConfig.modules ++ hostConfig.modules
++ upstreamModules
++ [ ++ [
(lib.mkAliasOptionModule [ "my" "hm" ] [ "home-manager" "users" vars.username ]) (lib.mkAliasOptionModule [ "my" "hm" ] [ "home-manager" "users" vars.username ])
# Upstream modules
# keep-sorted start
inputs.angrr.nixosModules.angrr
inputs.home-manager.nixosModules.default
inputs.impermanence.nixosModules.impermanence
inputs.niri-nix.nixosModules.default
inputs.sops-nix.nixosModules.sops
# keep-sorted end
# pkgs and home-manager configuration # pkgs and home-manager configuration
pkgsModule pkgsModule
hmModule hmModule
]; ];
} }
)
) config.nixosHosts; ) config.nixosHosts;
}; };
} }
+6 -19
View File
@@ -5,30 +5,17 @@
... ...
}: }:
[ [
(final: _prev: {
mv = inputs.multiverse.lib.mkMultiverse {
inherit (final.stdenv.hostPlatform) system;
inherit (config.nixpkgs) config;
};
})
( (
final: prev: final: prev:
lib.infuse prev { lib.infuse prev {
cage.__output.patches.__append = [ ./cage-specify-output-name.patch ]; cage.__output.patches.__append = [ ./cage-specify-output-name.patch ];
bottles.__input.removeWarningPopup.__assign = true; bottles.__input.removeWarningPopup.__assign = true;
easytier.__assign = final.stable.easytier;
python314Packages.patool.__input.file.__output.postPatch.__append =
lib.warn "Remove `file` patch once https://github.com/NixOS/nixpkgs/pull/540742 is merged" ''
substituteInPlace src/landlock.c --replace-fail \
"LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_READ_DIR" \
"LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_READ_DIR | LANDLOCK_ACCESS_FS_EXECUTE"
'';
} }
) )
(final: _prev: {
stable = import inputs.nixpkgs-stable {
inherit (final.stdenv.hostPlatform) system;
inherit (config.nixpkgs) config;
};
master = import inputs.nixpkgs-master {
inherit (final.stdenv.hostPlatform) system;
inherit (config.nixpkgs) config;
};
})
] ]
+16 -6
View File
@@ -9,16 +9,26 @@
_module.args = { _module.args = {
pkgsParams = { pkgsParams = {
overlays = builtins.attrValues config.flake.overlays ++ [ overlays = builtins.attrValues config.flake.overlays ++ [
inputs.go-musicfox.overlays.default
inputs.niri-nix.overlays.niri-nix inputs.niri-nix.overlays.niri-nix
inputs.fenix.overlays.default inputs.fenix.overlays.default
inputs.angrr.overlays.default inputs.angrr.overlays.default
(final: prev: {
darkly-qt6 = inputs.darkly.packages.${final.stdenv.hostPlatform.system}.darkly-qt6;
noctalia-shell = inputs.noctalia.packages.${final.stdenv.hostPlatform.system}.default;
})
inputs.llm-agents.overlays.shared-nixpkgs inputs.llm-agents.overlays.shared-nixpkgs
(
final: prev:
let
system = final.stdenv.hostPlatform.system;
in
{
darkly-qt6 = inputs.darkly.packages.${system}.darkly-qt6;
noctalia-shell = inputs.noctalia.packages.${system}.default;
nix-tree-rs = inputs.nix-tree-rs.packages.${system}.default;
fast-nix-gc = inputs.fast-nix-gc.packages.${system}.default.overrideAttrs {
doCheck = false;
};
}
)
]; ];
config.allowUnfree = true; config.allowUnfree = true;
flake.setNixPath = false; flake.setNixPath = false;
-14
View File
@@ -1,14 +0,0 @@
{ lib, ... }:
{
virtualisation.oci-containers.backend = lib.mkForce "podman";
virtualisation.podman = {
enable = true;
dockerCompat = true;
dockerSocket.enable = true;
defaultNetwork.settings.dns_enabled = true;
};
# avoid collision with dnsmasq
virtualisation.containers = {
containersConf.settings.network.dns_bind_port = 5353;
};
}
+19 -2
View File
@@ -5,7 +5,7 @@
... ...
}: }:
let let
btrfs = "/dev/disk/by-uuid/c7889c5c-c5b6-4e3c-9645-dfd49c2e84d0"; btrfs = "/dev/disk/by-uuid/1e1b403d-4a04-46ee-a6eb-cb4dd5f793a2";
in in
{ {
boot.initrd.availableKernelModules = [ boot.initrd.availableKernelModules = [
@@ -47,8 +47,25 @@ in
]; ];
}; };
fileSystems."/swap" = {
device = btrfs;
fsType = "btrfs";
options = [
"noatime"
"subvol=swap"
];
neededForBoot = true;
};
swapDevices = [
{
device = "/swap/swapfile";
size = 24 * 1024;
}
];
boot.zswap.enable = true;
fileSystems."/boot" = { fileSystems."/boot" = {
device = "/dev/disk/by-uuid/32AA-2998"; device = "/dev/disk/by-uuid/58F4-135A";
fsType = "vfat"; fsType = "vfat";
options = [ options = [
"uid=0" "uid=0"
+8
View File
@@ -0,0 +1,8 @@
{
services.caddy.virtualHosts."linspirer.imxyy.top" = {
extraConfig = ''
reverse_proxy :8800
'';
};
my.services.frp.webServers = [ "linspirer.imxyy.top" ];
}
+26 -92
View File
@@ -47,81 +47,31 @@
"192.168.3.2" "192.168.3.2"
]; ];
firewall.enable = false; firewall = {
nftables = {
enable = true; enable = true;
flushRuleset = true; checkReversePath = false;
ruleset = '' allowedTCPPorts = [
table inet firewall { 80
set LANv4 { 443
type ipv4_addr 2222
flags interval ];
extraInputRules = ''
elements = { 10.0.0.0/8, 100.64.0.0/10, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 } ip saddr { 10.0.0.0/8, 100.64.0.0/10, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 } accept
} ip6 saddr { fd00::/8, fe80::/10 } accept
set LANv6 {
type ipv6_addr
flags interval
elements = { fd00::/8, fe80::/10 }
}
set tcp_ports {
type inet_service
flags interval
elements = {
http,
https,
2222,
25565
}
}
chain prerouting {
type filter hook prerouting priority mangle; policy accept;
ip daddr @LANv4 accept
ip6 daddr @LANv6 accept
}
chain output {
type filter hook output priority 100; policy accept;
ip daddr @LANv4 accept
ip6 daddr @LANv6 accept
}
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
ct state invalid drop
ct state established,related accept
ip protocol { icmp, igmp } accept
ip saddr @LANv4 accept
ip6 saddr @LANv6 accept
tcp dport 2222 ct state new limit rate 15/minute counter accept
tcp dport @tcp_ports counter accept
}
chain forward {
type filter hook forward priority 0; policy accept;
}
chain nat {
type nat hook postrouting priority 0; policy accept;
ip saddr 192.168.3.0/24 masquerade
}
}
''; '';
filterForward = false;
};
nftables.enable = true;
nat = {
enable = true;
externalInterface = "mac0";
internalIPs = [ "192.168.3.0/24" ];
}; };
}; };
services.openssh = { services.openssh = {
enable = true; enable = true;
openFirewall = false;
settings = { settings = {
# PermitRootLogin = "yes"; # PermitRootLogin = "yes";
PermitRootLogin = "prohibit-password"; PermitRootLogin = "prohibit-password";
@@ -143,6 +93,7 @@
services.dae = { services.dae = {
enable = true; enable = true;
configFile = config.sops.secrets.dae-imxyy-nix-server.path; configFile = config.sops.secrets.dae-imxyy-nix-server.path;
openFirewall.enable = false;
}; };
systemd.services.dae = { systemd.services.dae = {
after = [ "sops-nix.service" ]; after = [ "sops-nix.service" ];
@@ -227,29 +178,12 @@
}; };
my.services.frp.webServers = [ "oidc.imxyy.top" ]; my.services.frp.webServers = [ "oidc.imxyy.top" ];
systemd.services.ddns-go = systemd.services.ddns-go = {
let
version = "6.6.7";
ddns-go = pkgs.buildGoModule {
inherit version;
pname = "ddns-go";
src = pkgs.fetchFromGitHub {
owner = "jeessy2";
repo = "ddns-go";
rev = "v${version}";
hash = "sha256-Ejoe6e9GFhHxQ9oIBDgDRQW9Xx1XZK+qSAXiRXLdn+c=";
};
meta.mainProgram = "ddns-go";
vendorHash = "sha256-XZii7gV3DmTunYyGYzt5xXhv/VpTPIoYKbW4LnmlAgs=";
doCheck = false;
};
in
{
description = "Go Dynamic DNS"; description = "Go Dynamic DNS";
after = [ "network.target" ]; after = [ "network.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
serviceConfig = { serviceConfig = {
ExecStart = "${lib.getExe ddns-go} -l :9876 -f 10 -cacheTimes 180 -c /var/lib/ddns-go/config.yaml"; ExecStart = "${lib.getExe pkgs.ddns-go} -l :9876 -f 10 -cacheTimes 180 -c /var/lib/ddns-go/config.yaml";
Restart = "always"; Restart = "always";
RestartSec = 120; RestartSec = 120;
}; };
@@ -264,12 +198,12 @@
settings = { settings = {
no-resolv = true; no-resolv = true;
server = [ "192.168.3.1" ]; server = [ "192.168.3.1" ];
address = [ host-record = [
"/imxyy-nix-server/192.168.3.2" "imxyy-nix-server,192.168.3.2"
"/imxyy-cloudwin/192.168.3.4" "imxyy-cloudwin,192.168.3.4"
"/printer.home/192.168.3.53" "printer.home,192.168.3.53"
] ]
++ (map (domain: "/${domain}/192.168.3.2") config.my.services.frp.webServers); ++ (map (domain: "${domain},192.168.3.2") config.my.services.frp.webServers);
cache-size = 0; cache-size = 0;
log-queries = "extra"; log-queries = "extra";
}; };
+20
View File
@@ -0,0 +1,20 @@
{ lib, ... }:
{
virtualisation.oci-containers.backend = lib.mkForce "podman";
virtualisation.podman = {
enable = true;
dockerCompat = true;
dockerSocket.enable = true;
defaultNetwork.settings.dns_enabled = true;
};
virtualisation.containers = {
containersConf.settings.network = {
# avoid collision with dnsmasq
dns_bind_port = 5353;
# keep netavark rules in an isolated `table inet netavark` instead of the
# `table ip nat` that networking.nat recreates on each nixos-rebuild switch,
# which would otherwise evict podman's published-port DNAT rules.
firewall_driver = "nftables";
};
};
}
+18 -76
View File
@@ -1,28 +1,28 @@
{ {
config,
pkgs, pkgs,
username, username,
... ...
}: }:
{ {
my.programs = {
ollama.enable = true;
localsend.enable = true;
wpsoffice.enable = true;
papers.enable = true;
nautilus.enable = true;
ayugram.enable = true;
signal.enable = true;
element.enable = true;
fractal.enable = true;
qq.enable = true;
wechat.enable = true;
};
my.hm = { my.hm = {
home.packages = with pkgs; [ home.packages = with pkgs; [
localsend
wpsoffice-cn
wps-office-fonts
ttf-wps-fonts
papers
anki
ayugram-desktop
signal-desktop-wayland
element-desktop
fractal
qq-wayland
wechat
gnome-clocks gnome-clocks
]; ];
programs.zsh = { programs.zsh = {
@@ -52,52 +52,9 @@
coding.all.enable = true; coding.all.enable = true;
desktop.all.enable = true; desktop.all.enable = true;
virt.moonlight.enable = true; virt.moonlight.enable = true;
i18n.fcitx5.enable = true; i18n.fcitx5.enable = true;
xdg.enable = true;
xdg = {
enable = true;
defaultApplications =
let
browser = [ config.my.desktop.browser.default.desktop ];
editor = [ "nvim.desktop" ];
imageviewer = [ "org.gnome.Loupe.desktop" ];
in
{
"inode/directory" = [ "org.gnome.Nautilus.desktop" ];
"application/pdf" = [ "org.gnome.Papers.desktop" ];
"text/*" = editor;
"application/json" = editor;
"text/xml" = editor;
"application/xml" = editor;
"application/xhtml+xml" = editor;
"application/xhtml_xml" = editor;
"application/rdf+xml" = editor;
"application/rss+xml" = editor;
"application/x-extension-htm" = editor;
"application/x-extension-html" = editor;
"application/x-extension-shtml" = editor;
"application/x-extension-xht" = editor;
"application/x-extension-xhtml" = editor;
"text/html" = browser;
"x-scheme-handler/about" = browser;
"x-scheme-handler/ftp" = browser;
"x-scheme-handler/http" = browser;
"x-scheme-handler/https" = browser;
"x-scheme-handler/unknown" = browser;
"audio/*" = imageviewer;
"video/*" = imageviewer;
"image/*" = imageviewer;
"image/gif" = imageviewer;
"image/jpeg" = imageviewer;
"image/png" = imageviewer;
"image/webp" = imageviewer;
};
};
persist = { persist = {
enable = true; enable = true;
homeDirs = [ homeDirs = [
@@ -112,21 +69,6 @@
".cache" ".cache"
".local/state" ".local/state"
".local/share/Anki2"
".local/share/shotwell"
".local/share/Kingsoft"
".local/share/AyuGramDesktop"
".local/share/fractal"
".config/Signal"
".config/Element"
".config/QQ"
".xwechat"
".config/Kingsoft"
".config/dconf"
".config/pip"
".config/sunshine"
]; ];
}; };
}; };
+9 -36
View File
@@ -12,45 +12,17 @@
my.persist.nixosDirs = [ "/etc/NetworkManager/system-connections" ]; my.persist.nixosDirs = [ "/etc/NetworkManager/system-connections" ];
networking = { networking = {
networkmanager.enable = true; networkmanager.enable = true;
firewall.enable = false; firewall = {
nftables = {
enable = true; enable = true;
flushRuleset = true; checkReversePath = false;
ruleset = '' allowPing = false;
table inet firewall { extraInputRules = ''
set LANv4 { ip saddr { 10.0.0.0/8, 100.64.0.0/10, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 } accept
type ipv4_addr ip6 saddr { fd00::/8, fe80::/10 } accept
flags interval
elements = { 10.0.0.0/8, 100.64.0.0/10, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 }
}
set LANv6 {
type ipv6_addr
flags interval
elements = { fd00::/8, fe80::/10 }
}
chain output {
type filter hook output priority 100; policy accept;
}
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
ct state invalid drop
ct state established,related accept
ip saddr @LANv4 accept
ip6 saddr @LANv6 accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
}
''; '';
filterForward = true;
}; };
nftables.enable = true;
}; };
sops.secrets.dae-imxyy-nix-x16 = { sops.secrets.dae-imxyy-nix-x16 = {
@@ -61,6 +33,7 @@
services.dae = { services.dae = {
enable = true; enable = true;
configFile = config.sops.secrets.dae-imxyy-nix-x16.path; configFile = config.sops.secrets.dae-imxyy-nix-x16.path;
openFirewall.enable = false;
}; };
systemd.services.dae.after = [ "sops-nix.service" ]; systemd.services.dae.after = [ "sops-nix.service" ];
sops.secrets.mihomo = { sops.secrets.mihomo = {
+1
View File
@@ -31,6 +31,7 @@
services.openssh = { services.openssh = {
enable = true; enable = true;
openFirewall = false;
settings = { settings = {
# Forbid root login through SSH. # Forbid root login through SSH.
PermitRootLogin = null; PermitRootLogin = null;
+5
View File
@@ -34,7 +34,12 @@ in
resumeDevice = btrfs; resumeDevice = btrfs;
kernelParams = [ kernelParams = [
"resume_offset=6444127" "resume_offset=6444127"
# Fix connector hotplug at ly display manager
"amdgpu.runpm=0"
]; ];
zswap.enable = true;
}; };
my.persist.btrfs = { my.persist.btrfs = {
+18 -78
View File
@@ -1,28 +1,28 @@
{ {
config,
pkgs, pkgs,
username, username,
... ...
}: }:
{ {
my.programs = {
ollama.enable = true;
localsend.enable = true;
wpsoffice.enable = true;
papers.enable = true;
nautilus.enable = true;
ayugram.enable = true;
signal.enable = true;
element.enable = true;
fractal.enable = true;
qq.enable = true;
wechat.enable = true;
};
my.hm = { my.hm = {
home.packages = with pkgs; [ home.packages = with pkgs; [
localsend
wpsoffice-cn
wps-office-fonts
ttf-wps-fonts
papers
anki
ayugram-desktop
signal-desktop-wayland
element-desktop
fractal
qq-wayland
wechat
gnome-clocks gnome-clocks
]; ];
programs.zsh = { programs.zsh = {
@@ -74,56 +74,9 @@
cli.all.enable = true; cli.all.enable = true;
coding.all.enable = true; coding.all.enable = true;
desktop.all.enable = true; desktop.all.enable = true;
i18n.fcitx5.enable = true; i18n.fcitx5.enable = true;
xdg.enable = true;
programs = {
ollama.enable = true;
};
xdg = {
enable = true;
defaultApplications =
let
browser = [ config.my.desktop.browser.default.desktop ];
editor = [ "nvim.desktop" ];
imageviewer = [ "org.gnome.Loupe.desktop" ];
in
{
"inode/directory" = [ "org.gnome.Nautilus.desktop" ];
"application/pdf" = [ "org.gnome.Papers.desktop" ];
"text/*" = editor;
"application/json" = editor;
"text/xml" = editor;
"application/xml" = editor;
"application/xhtml+xml" = editor;
"application/xhtml_xml" = editor;
"application/rdf+xml" = editor;
"application/rss+xml" = editor;
"application/x-extension-htm" = editor;
"application/x-extension-html" = editor;
"application/x-extension-shtml" = editor;
"application/x-extension-xht" = editor;
"application/x-extension-xhtml" = editor;
"text/html" = browser;
"x-scheme-handler/about" = browser;
"x-scheme-handler/ftp" = browser;
"x-scheme-handler/http" = browser;
"x-scheme-handler/https" = browser;
"x-scheme-handler/unknown" = browser;
"audio/*" = imageviewer;
"video/*" = imageviewer;
"image/*" = imageviewer;
"image/gif" = imageviewer;
"image/jpeg" = imageviewer;
"image/png" = imageviewer;
"image/webp" = imageviewer;
};
};
persist = { persist = {
enable = true; enable = true;
homeDirs = [ homeDirs = [
@@ -136,20 +89,7 @@
".cache" ".cache"
".local/state" ".local/state"
".local/share/Anki2"
".local/share/shotwell"
".local/share/Kingsoft"
".local/share/AyuGramDesktop"
".local/share/fractal"
".config/Signal"
".config/Element"
".config/QQ"
".xwechat"
".config/Kingsoft"
".config/dconf"
".config/pip"
".config/sunshine" ".config/sunshine"
]; ];
}; };
+12 -39
View File
@@ -24,7 +24,6 @@
eth0 = { eth0 = {
useDHCP = lib.mkForce true; useDHCP = lib.mkForce true;
wakeOnLan.enable = true; wakeOnLan.enable = true;
macAddress = "3C:7C:3F:7C:D3:9D";
ipv4 = { ipv4 = {
addresses = [ addresses = [
{ {
@@ -43,49 +42,22 @@
"192.168.3.2" "192.168.3.2"
]; ];
firewall.enable = false; firewall = {
nftables = {
enable = true; enable = true;
flushRuleset = true; checkReversePath = false;
ruleset = '' allowPing = false;
table inet firewall { trustedInterfaces = [ "waydroid0" ];
set LANv4 { extraInputRules = ''
type ipv4_addr ip saddr { 10.0.0.0/8, 100.64.0.0/10, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 } accept
flags interval ip6 saddr { fd00::/8, fe80::/10 } accept
'';
elements = { 10.0.0.0/8, 100.64.0.0/10, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 } filterForward = true;
} extraForwardRules = ''
set LANv6 {
type ipv6_addr
flags interval
elements = { fd00::/8, fe80::/10 }
}
chain output {
type filter hook output priority 100; policy accept;
}
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
iifname waydroid0 accept
ct state invalid drop
ct state established,related accept
ip saddr @LANv4 accept
ip6 saddr @LANv6 accept
}
chain forward {
type filter hook forward priority 0; policy drop;
iifname waydroid0 accept iifname waydroid0 accept
oifname waydroid0 accept oifname waydroid0 accept
}
}
''; '';
}; };
nftables.enable = true;
}; };
sops.secrets.dae-imxyy-nix = { sops.secrets.dae-imxyy-nix = {
@@ -96,6 +68,7 @@
services.dae = { services.dae = {
enable = true; enable = true;
configFile = config.sops.secrets.dae-imxyy-nix.path; configFile = config.sops.secrets.dae-imxyy-nix.path;
openFirewall.enable = false;
}; };
systemd.services.dae.after = [ "sops-nix.service" ]; systemd.services.dae.after = [ "sops-nix.service" ];
sops.secrets.mihomo = { sops.secrets.mihomo = {
+1
View File
@@ -78,6 +78,7 @@ in
}; };
services.openssh = { services.openssh = {
enable = true; enable = true;
openFirewall = false;
settings = { settings = {
# Forbid root login through SSH. # Forbid root login through SSH.
PermitRootLogin = null; PermitRootLogin = null;
-1
View File
@@ -9,7 +9,6 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
my.cli.media = { my.cli.media = {
go-musicfox.enable = true;
ffmpeg.enable = true; ffmpeg.enable = true;
}; };
}; };
-39
View File
@@ -1,39 +0,0 @@
{
config,
lib,
pkgs,
secrets,
...
}:
let
cfg = config.my.cli.media.go-musicfox;
in
{
options.my.cli.media.go-musicfox = {
enable = lib.mkEnableOption "go-musicfox";
};
config = lib.mkIf cfg.enable {
my = {
hm = {
home.packages = [
pkgs.go-musicfox
];
sops.secrets.go-musicfox = {
sopsFile = secrets.go-musicfox;
format = "binary";
path = "${config.my.hm.xdg.configHome}/go-musicfox/config.toml";
};
};
desktop.media.mpv.enable = lib.mkForce true;
persist.homeDirs = [
".local/share/go-musicfox/db"
];
persist.homeFiles = [
".local/share/go-musicfox/cookie"
];
};
};
}
+1
View File
@@ -53,6 +53,7 @@ in
my.persist.homeDirs = [ my.persist.homeDirs = [
".local/share/zoxide" ".local/share/zoxide"
".config/television/cable" ".config/television/cable"
".config/dconf"
]; ];
my.hm = { my.hm = {
programs.fish.shellAliases = { programs.fish.shellAliases = {
+1 -1
View File
@@ -53,7 +53,7 @@ symbol = " "
symbol = " " symbol = " "
[git_commit] [git_commit]
tag_symbol = '' tag_symbol = ""
[golang] [golang]
symbol = " " symbol = " "
+1 -2
View File
@@ -17,8 +17,7 @@ in
enable = true; enable = true;
settings = lib.recursiveUpdate (with builtins; fromTOML (readFile ./starship-preset.toml)) { settings = lib.recursiveUpdate (with builtins; fromTOML (readFile ./starship-preset.toml)) {
add_newline = false; add_newline = false;
command_timeout = 2000; scan_timeout = 1500;
nix_shell.disabled = true;
format = format =
let let
dedupDollar = dedupDollar =
+3
View File
@@ -17,6 +17,9 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
my.persist.homeDirs = [
".config/jj"
];
my.hm = { my.hm = {
programs.jujutsu = { programs.jujutsu = {
enable = true; enable = true;
+20 -6
View File
@@ -14,20 +14,34 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
my.hm = { my.hm = {
home.packages = with pkgs.llm-agents; [ home.packages =
codex (with pkgs.llm-agents; [
# codex
claude-code claude-code
opencode # opencode
]; # pi
# omp
])
++ (with pkgs; [
codex
]);
}; };
my.persist = { my.persist = {
homeDirs = [ homeDirs = [
".agents"
".claude" ".claude"
".config/opencode" # ".config/opencode"
".local/share/opencode" # ".local/share/opencode"
".codex" ".codex"
".pi"
".omp"
".config/ZCode"
".zcode"
]; ];
homeFiles = [ homeFiles = [
".claude.json" ".claude.json"
+2 -2
View File
@@ -10,8 +10,8 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
my.coding.editor = { my.coding.editor = {
neovim.enable = true; neovim.enable = true;
vscode.enable = true; vscode.enable = false;
zed.enable = true; zed.enable = false;
}; };
}; };
} }
+16
View File
@@ -7,6 +7,7 @@
}: }:
let let
cfg = config.my.coding.editor.neovim; cfg = config.my.coding.editor.neovim;
desktop = [ "nvim.desktop" ];
in in
{ {
options.my.coding.editor.neovim = { options.my.coding.editor.neovim = {
@@ -49,5 +50,20 @@ in
my.persist.homeDirs = [ my.persist.homeDirs = [
".local/share/nvim" ".local/share/nvim"
]; ];
my.xdg.defaultApplications = {
"text/*" = desktop;
"application/json" = desktop;
"text/xml" = desktop;
"application/xml" = desktop;
"application/xhtml+xml" = desktop;
"application/xhtml_xml" = desktop;
"application/rdf+xml" = desktop;
"application/rss+xml" = desktop;
"application/x-extension-htm" = desktop;
"application/x-extension-html" = desktop;
"application/x-extension-shtml" = desktop;
"application/x-extension-xht" = desktop;
"application/x-extension-xhtml" = desktop;
};
}; };
} }
@@ -8,6 +8,7 @@
"gitsigns.nvim": { "branch": "main", "commit": "25050e4ed39e628282831d4cbecb1850454ce915" }, "gitsigns.nvim": { "branch": "main", "commit": "25050e4ed39e628282831d4cbecb1850454ce915" },
"glance.nvim": { "branch": "master", "commit": "bf86d8b79dce808e65fdb6e9269d0b4ed6d2eefc" }, "glance.nvim": { "branch": "master", "commit": "bf86d8b79dce808e65fdb6e9269d0b4ed6d2eefc" },
"guess-indent.nvim": { "branch": "main", "commit": "84a4987ff36798c2fc1169cbaff67960aed9776f" }, "guess-indent.nvim": { "branch": "main", "commit": "84a4987ff36798c2fc1169cbaff67960aed9776f" },
"hunk.nvim": { "branch": "master", "commit": "c8a8e7b6973576f63e5bf39aa8338d7f37f4dc53" },
"indent-blankline.nvim": { "branch": "master", "commit": "d28a3f70721c79e3c5f6693057ae929f3d9c0a03" }, "indent-blankline.nvim": { "branch": "master", "commit": "d28a3f70721c79e3c5f6693057ae929f3d9c0a03" },
"inlay-hints.nvim": { "branch": "master", "commit": "297a65ab9543eb0850c1a55df4bb89e22cfec504" }, "inlay-hints.nvim": { "branch": "master", "commit": "297a65ab9543eb0850c1a55df4bb89e22cfec504" },
"lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" }, "lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" },
@@ -27,6 +28,7 @@
"nvim-treesitter": { "branch": "main", "commit": "4916d6592ede8c07973490d9322f187e07dfefac" }, "nvim-treesitter": { "branch": "main", "commit": "4916d6592ede8c07973490d9322f187e07dfefac" },
"nvim-treesitter-textobjects": { "branch": "main", "commit": "851e865342e5a4cb1ae23d31caf6e991e1c99f1e" }, "nvim-treesitter-textobjects": { "branch": "main", "commit": "851e865342e5a4cb1ae23d31caf6e991e1c99f1e" },
"nvim-web-devicons": { "branch": "master", "commit": "dfbfaa967a6f7ec50789bead7ef87e336c1fa63c" }, "nvim-web-devicons": { "branch": "master", "commit": "dfbfaa967a6f7ec50789bead7ef87e336c1fa63c" },
"obsidian.nvim": { "branch": "main", "commit": "ae1f76a75c7ce36866e1d9342a8f6f5b9c2caf9b" },
"outline.nvim": { "branch": "main", "commit": "2a132953b944561d45b52e4541ebfff71934a742" }, "outline.nvim": { "branch": "main", "commit": "2a132953b944561d45b52e4541ebfff71934a742" },
"pest.vim": { "branch": "master", "commit": "60cae7ea1beb644ed40081a3ec213ea9061aba09" }, "pest.vim": { "branch": "master", "commit": "60cae7ea1beb644ed40081a3ec213ea9061aba09" },
"plenary.nvim": { "branch": "master", "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" }, "plenary.nvim": { "branch": "master", "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" },
@@ -81,6 +81,7 @@ local servers = {
java_language_server = {}, java_language_server = {},
jsonls = {}, jsonls = {},
pyrefly = {}, pyrefly = {},
ruff = {},
-- taplo = {}, -- taplo = {},
tombi = {}, tombi = {},
ts_ls = {}, ts_ls = {},
@@ -21,7 +21,7 @@ local plugins = {
}, },
{ {
"nvim-lualine/lualine.nvim", "nvim-lualine/lualine.nvim",
dependencies = { { "nvim-tree/nvim-web-devicons", lazy = true } }, dependencies = { { "nvim-tree/nvim-web-devicons" } },
config = function() config = function()
require("lualine").setup(require("plugins.lualine")) require("lualine").setup(require("plugins.lualine"))
end, end,
@@ -178,7 +178,7 @@ local plugins = {
{ {
"L3MON4D3/LuaSnip", "L3MON4D3/LuaSnip",
event = "InsertEnter", event = "InsertEnter",
dependencies = { { "rafamadriz/friendly-snippets", lazy = true } }, dependencies = { { "rafamadriz/friendly-snippets" } },
build = "make install_jsregexp", build = "make install_jsregexp",
config = function() config = function()
require("luasnip").setup(require("plugins.cmp.luasnip")) require("luasnip").setup(require("plugins.cmp.luasnip"))
@@ -353,6 +353,24 @@ local plugins = {
}, },
}, },
}, },
{
"julienvincent/hunk.nvim",
cmd = { "DiffEditor" },
dependencies = { { "nvim-tree/nvim-web-devicons" } },
opts = {
keys = {
global = {
quit = { "<leader>q" },
},
diff = {
prev_hunk = { "<S-Tab>" },
next_hunk = { "<Tab>" },
toggle_focus = {},
},
},
},
},
}, },
} }
+1 -2
View File
@@ -15,8 +15,7 @@ in
python.enable = true; python.enable = true;
rust.enable = true; rust.enable = true;
lua.enable = true; lua.enable = true;
java.enable = true; java.enable = false;
qml.enable = true;
typst.enable = true; typst.enable = true;
toml.enable = true; toml.enable = true;
}; };
+2
View File
@@ -18,6 +18,8 @@ in
(lib.hiPrio clang) (lib.hiPrio clang)
clang-tools clang-tools
cmake cmake
ninja
meson
]; ];
}; };
} }
-1
View File
@@ -20,7 +20,6 @@ in
typescript typescript
typescript-language-server typescript-language-server
vue-language-server
biome biome
]; ];
+7 -1
View File
@@ -14,9 +14,15 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
my.hm.home.packages = with pkgs; [ my.hm.home.packages = with pkgs; [
python3 (python3.withPackages (
ps: with ps; [
tomli
tomli-w
]
))
uv uv
pyrefly pyrefly
ruff
]; ];
}; };
} }
-20
View File
@@ -1,20 +0,0 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.coding.langs.qml;
in
{
options.my.coding.langs.qml = {
enable = lib.mkEnableOption "QML";
};
config = lib.mkIf cfg.enable {
my.hm.home.packages = with pkgs; [
kdePackages.qtdeclarative
];
};
}
+1 -1
View File
@@ -23,7 +23,7 @@ in
"rustfmt" "rustfmt"
"rust-analyzer" "rust-analyzer"
]) ])
evcxr # rust repl stdenv.cc # linker
pest-ide-tools pest-ide-tools
]; ];
+34
View File
@@ -19,6 +19,22 @@ in
gnumake gnumake
github-cli # gh 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 = { programs.direnv = {
enable = true; enable = true;
nix-direnv.enable = true; nix-direnv.enable = true;
@@ -28,9 +44,27 @@ in
hide_env_diff = false; hide_env_diff = false;
}; };
}; };
stdlib = lib.mkAfter ''
if [[ -f .envrc.local && -z "$DIRENV_LOCAL_LOADED" ]]; then
export DIRENV_LOCAL_LOADED=1
log_status ".envrc.local detected, loading..."
skip_default_envrc() {
log_status "skip_default_envrc triggered, skipping .envrc"
exit 0
}
source_env .envrc.local
use() {
log_status "intercepted 'use $@' in .envrc"
}
fi
'';
}; };
}; };
my.persist.homeDirs = [ my.persist.homeDirs = [
".config/gh"
".local/share/direnv" ".local/share/direnv"
]; ];
}; };
-1
View File
@@ -1 +0,0 @@
/target
-2105
View File
File diff suppressed because it is too large Load Diff
-13
View File
@@ -1,13 +0,0 @@
[package]
name = "nix-racer"
version = "0.1.0"
edition = "2024"
[dependencies]
axum = "0.8"
reqwest = { version = "0.13", features = ["rustls"] }
serde = { version = "1.0.228", features = ["derive"] }
tokio = { version = "1.52", features = ["full"] }
toml = "1.1"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
-29
View File
@@ -1,29 +0,0 @@
{
lib,
rustPlatform,
}:
rustPlatform.buildRustPackage {
pname = "nix-racer";
version = "0.1.0";
src = lib.fileset.toSource {
root = ./.;
fileset = lib.fileset.unions [
./Cargo.toml
./Cargo.lock
./src
];
};
cargoLock = {
lockFile = ./Cargo.lock;
};
meta = {
description = "Nix substituter proxy with parallel cache queries and latency-aware selection";
mainProgram = "nix-racer";
license = lib.licenses.mit;
platforms = lib.platforms.unix;
};
}
-64
View File
@@ -1,64 +0,0 @@
use reqwest::Url;
use serde::{Deserialize, Deserializer, de::Error};
use std::net::{SocketAddr, SocketAddrV4};
#[derive(Debug, Clone, Deserialize)]
pub struct AppConfig {
#[serde(default = "default_listen")]
pub listen: SocketAddr,
pub substituters: Vec<Substituter>,
}
impl Default for AppConfig {
fn default() -> Self {
Self {
listen: default_listen(),
substituters: vec![
Substituter {
url: "https://mirror.sjtu.edu.cn/nix-channels/store",
penalty: 0,
},
Substituter {
url: "https://mirrors.ustc.edu.cn/nix-channels/store",
penalty: 0,
},
Substituter {
url: "https://cache.nixos.org",
penalty: 100,
},
],
}
}
}
fn default_listen() -> SocketAddr {
SocketAddr::V4(SocketAddrV4::new([127, 0, 0, 1].into(), 2048))
}
#[derive(Debug, Clone)]
pub struct Substituter {
pub url: &'static str,
pub penalty: u32,
}
impl<'de> Deserialize<'de> for Substituter {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Debug, Clone, Deserialize)]
struct ShadowSubstituter {
url: String,
#[serde(default)]
penalty: u32,
}
let sub = <ShadowSubstituter as Deserialize>::deserialize(deserializer);
sub.and_then(|ShadowSubstituter { url, penalty }| {
let url = match Url::parse(&url) {
Ok(url) => Ok(Box::leak(url.to_string().into_boxed_str())),
Err(err) => Err(<D::Error as Error>::custom(err.to_string())),
}?;
Ok(Substituter { url, penalty })
})
}
}
-212
View File
@@ -1,212 +0,0 @@
use std::{
collections::HashMap,
sync::Arc,
time::{Duration, Instant},
};
use axum::{
Router,
extract::{Path, State},
http::{StatusCode, header},
response::{IntoResponse, Redirect},
routing::get,
};
use reqwest::Client;
use tokio::task::JoinSet;
use tracing_subscriber::{EnvFilter, layer::SubscriberExt as _, util::SubscriberInitExt as _};
mod config;
use config::*;
#[derive(Clone)]
struct AppState {
client: Client,
config: Arc<AppConfig>,
}
#[tokio::main]
async fn main() {
tracing_subscriber::registry()
.with(tracing_subscriber::fmt::layer())
.with(
EnvFilter::builder()
.with_env_var("NIX_RACER_LOG")
.with_default_directive("nix_racer=debug".parse().unwrap())
.from_env()
.unwrap(),
)
.init();
let config: Arc<AppConfig> = match std::fs::read_to_string("/etc/nix/nix-racer.toml") {
Ok(file) => toml::from_str::<AppConfig>(&file).unwrap_or_else(|x| {
tracing::warn!("Failed to parse config file ({x}), fallback to default configuration");
AppConfig::default()
}),
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
tracing::info!("Config file not found, fallback to default configuration");
AppConfig::default()
}
Err(err) => {
tracing::warn!("Failed to read config file ({err}), fallback to default configuration");
AppConfig::default()
}
}
.into();
if config.substituters.is_empty() {
tracing::error!("No substituters found");
std::process::exit(1);
}
let listen = config.listen;
let client = Client::builder()
.timeout(Duration::from_secs(5))
.pool_idle_timeout(Duration::from_secs(90))
.build()
.unwrap();
let state = AppState { client, config };
let listener = tokio::net::TcpListener::bind(listen).await.unwrap();
let app = Router::new()
.route("/nix-cache-info", get(nix_cache_info_handler))
.route("/{*path}", get(proxy_handler))
.with_state(state);
tracing::info!("Smart Nix Proxy listening on http://{listen}");
axum::serve(listener, app).await.unwrap();
}
async fn nix_cache_info_handler() -> impl IntoResponse {
let info = "StoreDir: /nix/store\nWantMassQuery: 1\nPriority: 30\n";
([(header::CONTENT_TYPE, "text/x-nix-cache-info")], info)
}
async fn proxy_handler(
Path(path): Path<String>,
State(state): State<AppState>,
) -> impl IntoResponse {
if !path.ends_with(".narinfo") {
let redirect_url = format!("{}/{}", state.config.substituters[0].url, path);
return Redirect::temporary(&redirect_url).into_response();
}
let start_time = Instant::now();
let mut set = JoinSet::new();
let mut penalties = HashMap::new();
for upstream in state.config.substituters.iter() {
let url = format!("{}/{}", upstream.url, path);
let client = state.client.clone();
let base_url = upstream.url;
let handle = set.spawn(async move {
let max_retries = 2;
let mut delay = Duration::from_millis(50);
for attempt in 0..=max_retries {
match client.get(&url).send().await {
Ok(resp) if resp.status().is_success() => {
let bytes = resp.bytes().await.map_err(|_| "Body error")?;
let text = String::from_utf8_lossy(&bytes);
let mut new_text = String::with_capacity(text.len() + 64);
for line in text.lines() {
if let Some(rel_url) = line.strip_prefix("URL: ") {
if rel_url.starts_with("http://") || rel_url.starts_with("https://")
{
new_text.push_str(line);
} else {
new_text.push_str(&format!("URL: {}/{}", base_url, rel_url));
}
} else {
new_text.push_str(line);
}
new_text.push('\n');
}
return Ok((new_text.into_bytes(), base_url));
}
Ok(resp) if resp.status() == StatusCode::NOT_FOUND => return Err("404"),
Err(_) => {
if attempt == max_retries {
return Err("Max retries");
}
tokio::time::sleep(delay).await;
delay *= 2;
}
_ => return Err("Other HTTP Error"),
}
}
Err("Unreachable")
});
penalties.insert(handle.id(), upstream.penalty);
}
struct ProxyResult {
score: Duration,
body: Vec<u8>,
url: &'static str,
}
let mut best_result: Option<ProxyResult> = None;
loop {
let min_active_penalty = penalties.values().min().copied();
if let Some(ProxyResult { score, .. }) = best_result {
if let Some(min_p) = min_active_penalty {
if start_time.elapsed() + Duration::from_millis(u64::from(min_p)) >= score {
break;
}
} else {
break;
}
} else if min_active_penalty.is_none() {
break;
}
let timeout_dur = if let Some(ProxyResult { score, .. }) = best_result {
score.saturating_sub(start_time.elapsed())
} else {
Duration::from_secs(86400)
};
if timeout_dur.is_zero() && best_result.is_some() {
break;
}
let res = tokio::time::timeout(timeout_dur, set.join_next_with_id()).await;
match res {
Ok(Some(Ok((task_id, task_res)))) => {
let penalty = penalties.remove(&task_id).unwrap();
if let Ok((body, url)) = task_res {
let score = start_time.elapsed() + Duration::from_millis(u64::from(penalty));
if best_result.as_ref().is_none_or(|best| score < best.score) {
best_result = Some(ProxyResult { score, body, url })
}
}
}
Ok(Some(Err(join_err))) => {
penalties.remove(&join_err.id());
}
Ok(None) => break,
Err(_) => break,
}
}
if let Some(ProxyResult { score, body, url }) = best_result {
tracing::debug!("Winner for {}: {} (Score: {:?})", path, url, score,);
(
StatusCode::OK,
[(header::CONTENT_TYPE, "text/x-nix-narinfo")],
body,
)
.into_response()
} else {
(StatusCode::NOT_FOUND, "Not Found").into_response()
}
}
+30 -83
View File
@@ -30,104 +30,51 @@ in
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
nix-output-monitor nix-output-monitor
nh nh
nix-tree-rs
fast-nix-gc
]; ];
environment.etc = environment.etc = (
(lib.mapAttrs' (name: value: { lib.mapAttrs' (name: value: {
name = "nix/path/${name}"; name = "nix/path/${name}";
value.source = value.flake; value.source = value.flake;
}) config.nix.registry) }) config.nix.registry
// { );
"nix/nix-racer.toml".source = (pkgs.formats.toml { }).generate "nix-racer.toml" {
listen = "127.0.0.1:2048"; services.selector4nix = {
substituters = [ enable = true;
# { configureSubstituter = "keep";
# penalty = 0; settings = {
# url = "https://mirror.sjtu.edu.cn/nix-channels/store"; server = {
# } ip = "0.0.0.0";
{ port = 5496;
penalty = 0;
url = "https://mirrors.sjtug.sjtu.edu.cn/nix-channels/store";
}
{
penalty = 50;
url = "https://mirrors.ustc.edu.cn/nix-channels/store";
}
{
penalty = 0;
url = "https://nix-community.cachix.org";
}
{
penalty = 0;
url = "https://cache.numtide.com";
}
{
penalty = 100;
url = "https://cache.nixos.org";
}
];
}; };
}; substituters = map (subst: if builtins.isString subst then { url = subst; } else subst) [
"https://mirror.sjtu.edu.cn/nix-channels/store"
systemd.services.nix-racer = { "https://mirrors.sjtug.sjtu.edu.cn/nix-channels/store"
description = "Nix substituter proxy with parallel cache queries and latency-aware selection"; "https://mirrors.ustc.edu.cn/nix-channels/store"
wantedBy = [ "multi-user.target" ]; "https://mirrors.tuna.tsinghua.edu.cn/nix-channels/store"
after = [ "network-online.target" ]; "https://nix-community.cachix.org"
wants = [ "network-online.target" ]; "https://selector4nix.cachix.org/"
"https://cache.numtide.com"
serviceConfig = { "https://cache.nixos.org"
Type = "simple";
ExecStart = "${lib.getExe (pkgs.callPackage ./nix-racer/_package.nix { })}";
Restart = "on-failure";
RestartSec = 5;
DynamicUser = true;
CapabilityBoundingSet = [ "" ];
DeviceAllow = "";
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateTmp = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectSystem = "strict";
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
]; ];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@resources"
"~@privileged"
];
UMask = "0077";
}; };
}; };
nix.settings = { nix.settings = {
experimental-features = "nix-command flakes pipe-operators"; experimental-features = [
"nix-command"
"flakes"
"pipe-operators"
];
substituters = lib.mkForce [ substituters = lib.mkForce [
"http://127.0.0.1:2048" "http://127.0.0.1:${toString (config.services.selector4nix.settings.server.port or 5496)}"
"https://mirrors.sjtug.sjtu.edu.cn/nix-channels/store"
"https://cache.numtide.com"
"https://cache.nixos.org" "https://cache.nixos.org"
# "https://mirrors.ustc.edu.cn/nix-channels/store"
# "https://mirrors.sjtug.sjtu.edu.cn/nix-channels/store"
# "https://nix-community.cachix.org"
]; ];
trusted-public-keys = [ trusted-public-keys = [
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
"selector4nix.cachix.org-1:wovVlT07In5JCVz2tFgxPQTLpnN8hZT6P/RwfFcz3KE="
"niks3.numtide.com-1:DTx8wZduET09hRmMtKdQDxNNthLQETkc/yaX7M4qK0g=" "niks3.numtide.com-1:DTx8wZduET09hRmMtKdQDxNNthLQETkc/yaX7M4qK0g="
]; ];
download-buffer-size = 536870912; # 512 MiB download-buffer-size = 536870912; # 512 MiB
+1
View File
@@ -28,6 +28,7 @@ in
mutableUsers = false; mutableUsers = false;
users.${username} = { users.${username} = {
isNormalUser = true; isNormalUser = true;
uid = 1000;
description = userdesc; description = userdesc;
extraGroups = [ extraGroups = [
username username
+2 -2
View File
@@ -9,8 +9,8 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
my.desktop.browser = { my.desktop.browser = {
firefox.enable = true; firefox.enable = false;
chromium.enable = true; chromium.enable = false;
zen.enable = true; zen.enable = true;
}; };
}; };
+16 -1
View File
@@ -1,4 +1,8 @@
{ lib, ... }: { lib, config, ... }:
let
cfg = config.my.desktop.browser.default;
desktop = [ cfg.desktop ];
in
{ {
options.my.desktop.browser.default = { options.my.desktop.browser.default = {
command = lib.mkOption { command = lib.mkOption {
@@ -10,4 +14,15 @@
default = "zen-beta.desktop"; default = "zen-beta.desktop";
}; };
}; };
config = {
my.xdg.defaultApplications = {
"text/html" = desktop;
"x-scheme-handler/about" = desktop;
"x-scheme-handler/ftp" = desktop;
"x-scheme-handler/http" = desktop;
"x-scheme-handler/https" = desktop;
"x-scheme-handler/unknown" = desktop;
};
};
} }
+3 -3
View File
@@ -13,10 +13,10 @@ in
mpv.enable = true; mpv.enable = true;
loupe.enable = true; loupe.enable = true;
thunderbird.enable = true; thunderbird.enable = true;
vlc.enable = true; vlc.enable = false;
splayer.enable = true; splayer.enable = true;
spotify.enable = true; spotify.enable = false;
spotube.enable = true; spotube.enable = false;
}; };
}; };
} }
+5
View File
@@ -6,6 +6,7 @@
}: }:
let let
cfg = config.my.desktop.media.cine; cfg = config.my.desktop.media.cine;
desktop = [ "io.github.diegopvlk.Cine.desktop" ];
in in
{ {
options.my.desktop.media.cine = { options.my.desktop.media.cine = {
@@ -14,5 +15,9 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
my.hm.home.packages = [ pkgs.cine ]; my.hm.home.packages = [ pkgs.cine ];
my.xdg.defaultApplications = {
"audio/*" = desktop;
"video/*" = desktop;
};
}; };
} }
+8
View File
@@ -6,6 +6,7 @@
}: }:
let let
cfg = config.my.desktop.media.loupe; cfg = config.my.desktop.media.loupe;
desktop = [ "org.gnome.Loupe.desktop" ];
in in
{ {
options.my.desktop.media.loupe = { options.my.desktop.media.loupe = {
@@ -14,5 +15,12 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
my.hm.home.packages = [ pkgs.loupe ]; my.hm.home.packages = [ pkgs.loupe ];
my.xdg.defaultApplications = {
"image/*" = desktop;
"image/gif" = desktop;
"image/jpeg" = desktop;
"image/png" = desktop;
"image/webp" = desktop;
};
}; };
} }
+2 -2
View File
@@ -14,10 +14,10 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
my.hm.home.packages = [ my.hm.home.packages = [
pkgs.splayer pkgs.splayer-next
]; ];
my.persist.homeDirs = [ my.persist.homeDirs = [
".config/SPlayer" ".config/SPlayer-Next"
]; ];
}; };
} }
+1 -1
View File
@@ -9,7 +9,7 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
my.desktop.screencast = { my.desktop.screencast = {
obs-studio.enable = true; obs-studio.enable = false;
}; };
}; };
} }
@@ -6,44 +6,44 @@
# Default colors # Default colors
[colors.primary] [colors.primary]
background = '#24283b' background = "#24283b"
foreground = '#c0caf5' foreground = "#c0caf5"
[colors.cursor] [colors.cursor]
cursor = '#c0caf5' cursor = "#c0caf5"
text = '#24283b' text = "#24283b"
[colors.selection] [colors.selection]
text = '#c0caf5' text = "#c0caf5"
background = '#2e3c64' background = "#2e3c64"
# Normal colors # Normal colors
[colors.normal] [colors.normal]
black = '#1d202f' black = "#1d202f"
red = '#f7768e' red = "#f7768e"
green = '#9ece6a' green = "#9ece6a"
yellow = '#e0af68' yellow = "#e0af68"
blue = '#7aa2f7' blue = "#7aa2f7"
magenta = '#bb9af7' magenta = "#bb9af7"
cyan = '#7dcfff' cyan = "#7dcfff"
white = '#a9b1d6' white = "#a9b1d6"
# Bright colors # Bright colors
[colors.bright] [colors.bright]
black = '#414868' black = "#414868"
red = '#ff899d' red = "#ff899d"
green = '#9fe044' green = "#9fe044"
yellow = '#faba4a' yellow = "#faba4a"
blue = '#8db0ff' blue = "#8db0ff"
magenta = '#c7a9ff' magenta = "#c7a9ff"
cyan = '#a4daff' cyan = "#a4daff"
white = '#c0caf5' white = "#c0caf5"
# Indexed Colors # Indexed Colors
[[colors.indexed_colors]] [[colors.indexed_colors]]
index = 16 index = 16
color = '#ff9e64' color = "#ff9e64"
[[colors.indexed_colors]] [[colors.indexed_colors]]
index = 17 index = 17
color = '#db4b4b' color = "#db4b4b"
+3 -3
View File
@@ -9,10 +9,10 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
my.desktop.terminal = { my.desktop.terminal = {
alacritty.enable = true; alacritty.enable = false;
foot.enable = true; foot.enable = false;
kitty.enable = true; kitty.enable = true;
ghostty.enable = true; ghostty.enable = false;
}; };
}; };
} }
+13
View File
@@ -0,0 +1,13 @@
{ lib, ... }:
{
options.my.desktop.terminal.default = {
command = lib.mkOption {
type = lib.types.str;
default = "kitty";
};
desktop = lib.mkOption {
type = lib.types.str;
default = "kitty.desktop";
};
};
}
-115
View File
@@ -1,115 +0,0 @@
include "generated.kdl"
input {
focus-follows-mouse max-scroll-amount="0%"
workspace-auto-back-and-forth
}
layout {
gaps 23
center-focused-column "on-overflow"
always-center-single-column
focus-ring {
off
}
border {
on
width 4
inactive-color "#2e2e3eee"
active-gradient from="#6186d6ee" to="#cba6f7ee" angle=180 relative-to="workspace-view"
}
insert-hint {
color "rgba(42, 44, 54, 0.5)"
}
preset-column-widths {
proportion 0.33333
proportion 0.4
proportion 0.5
proportion 0.6
proportion 0.66667
proportion 0.8
}
default-column-width { proportion 0.8; }
background-color "transparent"
tab-indicator {
width 10
place-within-column
}
}
prefer-no-csd
hotkey-overlay {
skip-at-startup
}
clipboard {
disable-primary
}
blur {
passes 3
offset 4
noise 0.02
saturation 1.5
}
layer-rule {
match namespace="^wallpaper$"
place-within-backdrop true
}
overview {
workspace-shadow {
off
}
}
animations {
on
slowdown 1.5
workspace-switch {
spring damping-ratio=1.0 stiffness=1000 epsilon=0.0001
}
}
window-rule {
draw-border-with-background false
geometry-corner-radius 14.000000 14.000000 14.000000 14.000000
clip-to-geometry true
background-effect {
xray true
blur true
}
}
window-rule {
match is-floating=true
background-effect {
xray false
}
}
window-rule {
match app-id="kitty|foot|Alacritty|ghostty"
opacity 0.8
}
window-rule {
match app-id="org.gnome.Nautilus"
opacity 0.6
}
window-rule {
match app-id="org.jackhuang.hmcl.Launcher"
border {
off
}
}
+1
View File
@@ -55,6 +55,7 @@ in
binds = lib.mkMerge [ binds = lib.mkMerge [
{ {
"Mod+G".spawn = [ config.my.desktop.browser.default.command ]; "Mod+G".spawn = [ config.my.desktop.browser.default.command ];
"Mod+Return".spawn = [ config.my.desktop.terminal.default.command ];
} }
(builtins.listToAttrs ( (builtins.listToAttrs (
map (n: { map (n: {
+6 -8
View File
@@ -1,17 +1,15 @@
binds { binds {
Mod+Return { spawn "kitty" "-1"; }
Mod+E { spawn "nautilus"; }
Ctrl+Alt+Escape { spawn "missioncenter"; } Ctrl+Alt+Escape { spawn "missioncenter"; }
Mod+R { spawn "noctalia-shell" "ipc" "call" "launcher" "toggle"; } Mod+R { spawn "noctalia" "msg" "panel-toggle" "launcher"; }
Mod+V { spawn "noctalia-shell" "ipc" "call" "launcher" "clipboard"; } Mod+V { spawn "noctalia" "msg" "panel-toggle" "clipboard"; }
Mod+W { spawn "noctalia-shell" "ipc" "call" "launcher" "windows"; } Mod+W { spawn "noctalia" "msg" "panel-toggle" "launcher" "/win"; }
XF86AudioRaiseVolume allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_SINK@" "2%+"; } XF86AudioRaiseVolume allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_SINK@" "2%+"; }
XF86AudioLowerVolume 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"; } XF86AudioMute allow-when-locked=true { spawn "noctalia" "msg" "media" "playPause"; }
Super+XF86AudioRaiseVolume allow-when-locked=true { spawn "noctalia-shell" "ipc" "call" "media" "next"; } Super+XF86AudioRaiseVolume allow-when-locked=true { spawn "noctalia" "msg" "media" "next"; }
Super+XF86AudioLowerVolume allow-when-locked=true { spawn "noctalia-shell" "ipc" "call" "media" "previous"; } Super+XF86AudioLowerVolume allow-when-locked=true { spawn "noctalia" "msg" "media" "previous"; }
XF86MonBrightnessUp allow-when-locked=true { spawn "brightnessctl" "set" "+5%"; } XF86MonBrightnessUp allow-when-locked=true { spawn "brightnessctl" "set" "+5%"; }
XF86MonBrightnessDown 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 prefer-no-csd
hotkey-overlay { hotkey-overlay {
+15 -177
View File
@@ -2,7 +2,7 @@
lib, lib,
config, config,
pkgs, pkgs,
assets, impure,
... ...
}: }:
let let
@@ -33,6 +33,7 @@ in
}; };
security.pam.services.login.enableGnomeKeyring = true; security.pam.services.login.enableGnomeKeyring = true;
services.gnome.gnome-keyring.enable = true;
my.persist.homeDirs = [ my.persist.homeDirs = [
{ {
directory = ".local/share/keyrings"; directory = ".local/share/keyrings";
@@ -57,16 +58,16 @@ in
xdg-desktop-portal-gnome xdg-desktop-portal-gnome
]; ];
}; };
systemd.user.services.niri-polkit = { # Keep switch-to-configuration from stopping the running compositor
description = "PolicyKit Authentication Agent"; # when the niri store path changes; niri-nix dropped this drop-in in
wantedBy = [ "niri.service" ]; # acccaf2202. The new binary takes effect on next login instead.
after = [ "graphical-session.target" ]; systemd.user.units."niri.service" = {
partOf = [ "graphical-session.target" ]; overrideStrategy = "asDropinIfExists";
serviceConfig = { text = ''
Type = "simple"; [Service]
ExecStart = "${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1"; X-StopIfChanged=false
Restart = "on-failure"; X-RestartIfChanged=false
}; '';
}; };
services.system76-scheduler.enable = true; services.system76-scheduler.enable = true;
@@ -75,185 +76,22 @@ in
home.packages = with pkgs; [ home.packages = with pkgs; [
xwayland-satellite-unstable xwayland-satellite-unstable
wlr-randr
wl-clipboard wl-clipboard
cliphist cliphist
brightnessctl brightnessctl
nautilus
mission-center mission-center
noctalia-shell
xdg-terminal-exec xdg-terminal-exec
]; ];
services.system76-scheduler-niri.enable = true; services.system76-scheduler-niri.enable = true;
programs.noctalia-shell = { programs.noctalia = {
enable = true; enable = true;
# modified from official Tokyo-Night theme systemd.enable = true;
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;
};
}; };
xdg.configFile."noctalia".source = impure.mkImpureLink ./noctalia;
}; };
}; };
} }
@@ -0,0 +1,2 @@
[accessibility]
ui_scale = 1
@@ -0,0 +1,2 @@
[audio]
enable_sounds = true
+34
View File
@@ -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
+23
View File
@@ -0,0 +1,23 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.programs.ayugram;
in
{
options.my.programs.ayugram = {
enable = lib.mkEnableOption "ayugram";
};
config = lib.mkIf cfg.enable {
my.hm.home.packages = [
pkgs.ayugram-desktop
];
my.persist.homeDirs = [
".local/share/AyuGramDesktop"
];
};
}
+23
View File
@@ -0,0 +1,23 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.programs.element;
in
{
options.my.programs.element = {
enable = lib.mkEnableOption "element";
};
config = lib.mkIf cfg.enable {
my.hm.home.packages = [
pkgs.element-desktop
];
my.persist.homeDirs = [
".config/Element"
];
};
}
+23
View File
@@ -0,0 +1,23 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.programs.fractal;
in
{
options.my.programs.fractal = {
enable = lib.mkEnableOption "fractal";
};
config = lib.mkIf cfg.enable {
my.hm.home.packages = [
pkgs.fractal
];
my.persist.homeDirs = [
".local/share/fractal"
];
};
}
+23
View File
@@ -0,0 +1,23 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.programs.localsend;
in
{
options.my.programs.localsend = {
enable = lib.mkEnableOption "localsend";
};
config = lib.mkIf cfg.enable {
my.hm.home.packages = [
pkgs.localsend
];
my.persist.homeDirs = [
".local/share/org.localsend.localsend_app"
];
};
}
+26
View File
@@ -0,0 +1,26 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.programs.nautilus;
in
{
options.my.programs.nautilus = {
enable = lib.mkEnableOption "nautilus";
};
config = lib.mkIf cfg.enable {
my.hm.home.packages = [
pkgs.nautilus
];
my.xdg.defaultApplications = {
"inode/directory" = [ "org.gnome.Nautilus.desktop" ];
};
my.hm.wayland.windowManager.niri.settings.binds."Mod+E".spawn = [
"nautilus"
];
};
}
+21
View File
@@ -0,0 +1,21 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.programs.papers;
in
{
options.my.programs.papers = {
enable = lib.mkEnableOption "papers";
};
config = lib.mkIf cfg.enable {
my.hm.home.packages = [
pkgs.papers
];
my.xdg.defaultApplications."application/pdf" = [ "org.gnome.Papers.desktop" ];
};
}
+23
View File
@@ -0,0 +1,23 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.programs.qq;
in
{
options.my.programs.qq = {
enable = lib.mkEnableOption "qq";
};
config = lib.mkIf cfg.enable {
my.hm.home.packages = [
pkgs.qq-wayland
];
my.persist.homeDirs = [
".config/QQ"
];
};
}
+23
View File
@@ -0,0 +1,23 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.programs.signal;
in
{
options.my.programs.signal = {
enable = lib.mkEnableOption "signal";
};
config = lib.mkIf cfg.enable {
my.hm.home.packages = [
pkgs.signal-desktop-wayland
];
my.persist.homeDirs = [
".config/Signal"
];
};
}
+23
View File
@@ -0,0 +1,23 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.programs.wechat;
in
{
options.my.programs.wechat = {
enable = lib.mkEnableOption "wechat";
};
config = lib.mkIf cfg.enable {
my.hm.home.packages = [
pkgs.wechat
];
my.persist.homeDirs = [
".xwechat"
];
};
}
+26
View File
@@ -0,0 +1,26 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.programs.wpsoffice;
in
{
options.my.programs.wpsoffice = {
enable = lib.mkEnableOption "wpsoffice";
};
config = lib.mkIf cfg.enable {
my.hm.home.packages = with pkgs; [
wpsoffice-cn
wps-office-fonts
ttf-wps-fonts
];
my.persist.homeDirs = [
".config/Kingsoft"
".local/share/Kingsoft"
];
};
}
+2
View File
@@ -35,6 +35,8 @@
# GVFS for virtual filesystems # GVFS for virtual filesystems
services.gvfs.enable = true; services.gvfs.enable = true;
services.speechd.enable = false;
# Enable desktop-related modules by default # Enable desktop-related modules by default
my = { my = {
audio.enable = true; audio.enable = true;
+491
View File
@@ -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()
File diff suppressed because one or more lines are too long
+21 -5
View File
@@ -1,12 +1,28 @@
{ inputs, ... }: { inputs, ... }: {
{ imports = [
imports = [ inputs.treefmt.flakeModule ]; inputs.treefmt.flakeModule
perSystem.treefmt = { ];
perSystem.treefmt = { lib, pkgs, ... }: {
projectRootFile = "flake.nix"; projectRootFile = "flake.nix";
programs = { programs = {
nixfmt.enable = true; nixfmt.enable = true;
stylua.enable = true;
keep-sorted.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
View File
@@ -1,18 +1,13 @@
#:schema https://raw.githubusercontent.com/crate-ci/typos/refs/heads/master/config.schema.json #:schema https://raw.githubusercontent.com/crate-ci/typos/refs/heads/master/config.schema.json
[files] [files]
extend-exclude = [ extend-exclude = ["secrets"]
"secrets"
] [default]
extend-ignore-identifiers-re = ["KEY_102ND", "VE_UE"]
[default.extend-words] [default.extend-words]
# noice.nvim # noice.nvim
noice = "noice" noice = "noice"
enew = "enew" enew = "enew"
iif = "iif" iif = "iif"
[default]
extend-ignore-identifiers-re = [
"KEY_102ND",
"VE_UE"
]