Compare commits

..

124 Commits

Author SHA1 Message Date
kiri 9df7bfd825 chore: remove outdated AGENTS.md 2026-06-12 15:46:06 +02:00
kiri 9f565b85db feat: remove global git ignores 2026-06-12 11:33:56 +02:00
kiri 562a65a714 feat: make escape exit menuselect in zsh 2026-06-12 11:33:36 +02:00
kiri beabcabb60 feat: add work repo to trusted codex folders 2026-06-08 10:04:02 +02:00
kiri 709e89c017 fix: nix-wrapper-modules warning 2026-06-08 10:02:36 +02:00
kiri b35c95b4c8 feat: remove uv 2026-06-08 10:02:05 +02:00
kiri 5a1f5a9894 feat: move to limine 2026-06-08 10:01:59 +02:00
kiri d6a3587a89 feat: set notifcation density to compact 2026-06-06 11:35:10 +02:00
kiri ed1c94735c chore: update inputs 2026-06-05 14:54:05 +02:00
kiri 239febf3e0 feat: move notifications to bottom right 2026-05-29 13:15:15 +02:00
kiri e7c0a084a0 chore: update inputs 2026-05-29 10:07:46 +02:00
kiri 30564171f0 chore: update inputs and devenv 2026-05-27 19:23:01 +02:00
kiri 1d591c4f4a feat: add vps-insights to orion 2026-05-07 01:52:25 +02:00
kiri b204e48509 chore: update nix-wrapper-modules call 2026-05-07 00:59:18 +02:00
kiri 86dcf5ce4b fix: transmission failing because of non-existing directory 2026-05-07 00:58:52 +02:00
kiri 8453447f90 feat: switch torrent client to transmission 2026-05-07 00:45:23 +02:00
kiri 2c2276c9b8 feat: always approve nixos mcp requests in codex 2026-05-07 00:37:15 +02:00
kiri c4146eaae0 feat: reduce number of nixpkgs revisions 2026-05-07 00:24:32 +02:00
kiri f193c02f4a feat: better zsh completion 2026-05-06 23:51:54 +02:00
kiri d84fec1a82 feat: enable bitwarden for walker 2026-05-06 22:56:34 +02:00
kiri 1458dd1ae6 feat: use sops for radicale password 2026-05-06 22:56:23 +02:00
kiri c501097e4c feat: enable khal 2026-05-06 22:11:30 +02:00
kiri 4b6e05212c refactor: schema 2026-05-06 21:57:58 +02:00
kiri c01c13aa50 feat: enable walker 2026-05-06 21:21:15 +02:00
kiri e33602e879 refactor: dendritic principles 2026-05-06 19:45:03 +02:00
kiri d6878abc61 refactor default apps and add walker 2026-05-06 19:32:37 +02:00
kiri be1a9b7852 feat: use upstream walker and elephant flakes 2026-05-06 16:03:33 +02:00
kiri 7299f5bb79 fix: walker and gtk4 2026-05-05 21:05:24 +02:00
kiri c2082e942e feat: add walker and general launcher config 2026-05-05 20:56:09 +02:00
kiri fdf6ac5e08 feat: add discord 2026-05-05 17:52:56 +02:00
kiri fdc269483e feat: add phone to syncthing 2026-05-05 16:28:49 +02:00
kiri e8d1f58ed5 chore: update inputs 2026-05-01 18:34:04 +02:00
kiri 5bc37c7009 refactor: niri config 2026-04-29 15:49:32 +02:00
kiri efb0179344 feat: improve config UX 2026-04-29 13:50:20 +02:00
kiri a18d405ea7 feat: make shift+enter newline 2026-04-29 12:26:38 +02:00
kiri 9b3db93dbd feat: disable command-not-found for nix-index 2026-04-29 12:19:49 +02:00
kiri cacb6c01e9 feat: make YUNZII keyboard accessible 2026-04-28 16:16:46 +02:00
kiri f4ac94c65c feat: change font weights on foot 2026-04-28 00:21:42 +02:00
kiri 85cf1d92ca feat: make kitty boot in single instance mode 2026-04-27 23:15:08 +02:00
kiri 61971e2b37 feat: change font rendering 2026-04-27 22:15:12 +02:00
kiri 783bd9958d feat: improve foot font rendering 2026-04-27 20:35:48 +02:00
kiri 44fe4552ef refactor: desktop default applications 2026-04-27 17:57:39 +02:00
kiri 93624900ad refactor: reorganize features 2026-04-27 16:47:12 +02:00
kiri 0b2ecd31b0 refactor: restructure config files 2026-04-27 15:59:20 +02:00
kiri bac6e4997b feat: add foot and clean up config 2026-04-27 15:27:27 +02:00
kiri 8b31e1ca9f feat: replace dust with dua 2026-04-27 01:17:53 +02:00
kiri 4cd2d1addd feat: install github-cli 2026-04-27 01:15:34 +02:00
kiri 5091db4ac9 feat: remove git_status from starship prompt 2026-04-27 00:15:45 +02:00
kiri 8126141b22 feat: install terminfo on orion 2026-04-26 23:44:48 +02:00
kiri 9b0c2e647d feat: disable touchpad when typing 2026-04-26 23:39:13 +02:00
kiri ca4594d420 feat: move syncthing, shell and neovim config to host-wide defaults 2026-04-26 23:32:10 +02:00
kiri 6d3c549284 feat: add zenith to syncthing mesh 2026-04-26 23:21:03 +02:00
kiri 7ccbdcfa33 feat: disable gemini-cli 2026-04-26 22:49:32 +02:00
kiri f769de0c91 feat: home directory cleanup 2026-04-26 22:37:43 +02:00
kiri aecdfef9b3 feat: switch sshAgentAuth to rssh 2026-04-26 22:00:18 +02:00
kiri 5d604e827a feat: update orion encryption key 2026-04-26 20:11:40 +02:00
kiri 0937d29ed4 fix: orion fixes 2026-04-26 19:48:12 +02:00
kiri 52ea09563f feat: generalize SSH key config 2026-04-26 19:40:29 +02:00
kiri 0318dd0cf6 fix: update zenith public key 2026-04-26 19:29:00 +02:00
kiri 703c0e82e0 fix: update polaris public keys 2026-04-26 19:27:58 +02:00
kiri 0e29e08c20 refactor: simplify source control 2026-04-26 19:11:20 +02:00
kiri 2a2b192255 feat: remove module attribute and fix duplicate import 2026-04-26 18:20:15 +02:00
kiri dba24ce5f3 feat: move to single-user config 2026-04-26 18:08:48 +02:00
kiri 75ba00929e chore: update llm-agents 2026-04-26 15:47:54 +02:00
kiri 66bc0866b7 feat(neovim): add kulala 2026-04-26 15:47:46 +02:00
kiri c5e3f674b6 feat: UI improvements 2026-04-26 14:21:13 +02:00
kiri c61efc6f5c feat: UI improvements 2026-04-26 00:49:37 +02:00
kiri 3cbfe566e4 fix: lazy loading 2026-04-25 23:02:56 +02:00
kiri 26e9593aab feat: add typst dependencies and make conform use isort 2026-04-25 22:42:23 +02:00
kiri 3ab9f0b465 feat: add mcp-nixos and add global context 2026-04-25 22:07:14 +02:00
kiri 233cb2c2f3 chore: update inputs 2026-04-25 21:05:53 +02:00
kiri 7fba97378a fix: comma not having database 2026-04-25 19:46:09 +02:00
kiri d96ec9aa58 feat: add resterm 2026-04-25 17:46:14 +02:00
kiri 6c945a04f0 feat: add posting 2026-04-25 17:24:21 +02:00
kiri 9fa55bc8b9 fix: install jujutsu via home-manager 2026-04-25 16:22:11 +02:00
kiri 26dc1ff38c fix: install jujutsu not jj 2026-04-25 16:20:27 +02:00
kiri 3b24b54096 feat: add jj 2026-04-25 16:10:47 +02:00
kiri e374d3eae0 feat: theme updates 2026-04-25 02:09:11 +02:00
kiri 343ae79738 feat: update gpt model 2026-04-25 01:30:34 +02:00
kiri 16712777dc refactor: extract users 2026-04-25 01:28:28 +02:00
kiri 0500aab3cb refactor: further progress 2026-04-25 00:19:20 +02:00
kiri 55fbe82a42 refactor: orion and base 2026-04-24 21:57:43 +02:00
kiri 32c12e8797 feat: add xh 2026-04-24 16:12:23 +02:00
kiri 66ba4acf0d feat: update global gitignore 2026-04-24 16:12:20 +02:00
kiri 1f42996307 feat: remove brave 2026-04-24 10:10:41 +02:00
kiri cc1ccd19a5 feat: set yazi shell alias 2026-04-24 10:10:37 +02:00
kiri 2aad12f57e feat: switch tldr to tlrc 2026-04-24 09:56:04 +02:00
kiri b70f596897 feat: add useful CLI tools 2026-04-24 09:53:40 +02:00
kiri 076a63d812 chore: update inputs 2026-04-24 00:48:37 +02:00
kiri 112fa1b006 Revert "refactor: cleanup and extract user config"
This reverts commit 8a14ad2ed5.
2026-04-24 00:43:19 +02:00
kiri 5e4b1fc930 feat: decrease brightness step size 2026-04-24 00:21:24 +02:00
kiri 8a14ad2ed5 refactor: cleanup and extract user config 2026-04-23 20:03:51 +02:00
kiri 2e02ebb1e2 refactor: remove unnecessary workstation feature 2026-04-23 18:36:02 +02:00
kiri 7e6f103de4 fix: remove non-working fix for keyboards 2026-04-23 17:10:46 +02:00
kiri f85b7ad751 feat: add rustup and usql to ergon 2026-04-23 17:10:10 +02:00
kiri 23ad48cd5d feat: hopefully fix keyboard detection errors 2026-04-23 12:42:23 +02:00
kiri d0ef1acb0c feat: add http tools 2026-04-23 12:42:09 +02:00
kiri 7f98d54e74 feat: add devenv 2026-04-22 23:22:19 +02:00
kiri fbe351070d feat: add plymouth 2026-04-22 23:04:33 +02:00
kiri a4af935e6e refactor: simplify shared config contracts 2026-04-22 04:41:09 +02:00
kiri cf308a1371 refactor: shared config metadata 2026-04-22 04:10:29 +02:00
kiri 503c1fe9bc refactor: simplify host composition and shared feature config 2026-04-22 03:29:19 +02:00
kiri 5eec5689f4 refactor: simplify module composition 2026-04-22 02:35:26 +02:00
kiri 3b6c42ebe3 feat: remove ssh profile generation 2026-04-22 01:28:28 +02:00
Jelle Spreeuwenberg ddccf6425f Add ssh keys for ergon@zenith 2026-04-22 01:07:21 +02:00
kiri 86446fa797 feat: add source control identity management 2026-04-22 01:02:27 +02:00
kiri be6ad78637 feat: set projects directory 2026-04-21 23:42:26 +02:00
kiri 67b7ebf062 feat: switch to sddm hidpi instead of custom scaling 2026-04-21 23:26:23 +02:00
kiri 38c8c32a80 fix: cursor not showing in SDDM 2026-04-21 23:06:19 +02:00
kiri 732ebb483f feat: set mouse sensitivity for polaris 2026-04-21 22:48:20 +02:00
kiri 8de3bc1b72 refactor: use terminal package attr paths with shared resolver 2026-04-21 22:48:00 +02:00
kiri 4781cc60be feat: derive desktop input and SDDM scale from host metadata 2026-04-21 22:30:57 +02:00
kiri 592e70cf33 feat: add zenith specific modifications to noctalia 2026-04-21 22:29:32 +02:00
kiri 65f49429d5 feat: add power management to zenith 2026-04-21 22:27:00 +02:00
kiri 055a139fd2 refactor: centralize workstation HM base and derive terminal from user metadata 2026-04-21 22:10:11 +02:00
kiri d252de8a3a feat: add nh 2026-04-21 17:54:30 +02:00
kiri 571082c713 feat: codex config 2026-04-21 17:54:26 +02:00
kiri 8cc4690839 feat: add nixosConfigurationPath variable 2026-04-21 17:24:11 +02:00
kiri 6f363afbc8 feat: add gemini and codex config 2026-04-21 17:06:30 +02:00
kiri 8e713666a3 chore: update flake inputs 2026-04-21 16:09:27 +02:00
kiri a73cefb9df refactor: compose hosts and home-manager features explicitly 2026-04-21 16:04:06 +02:00
kiri 8c254f2eb1 docs: add repository agent guidance 2026-04-21 16:03:55 +02:00
kiri c728c9e627 feat: split hm user base by host type and remove nvim secret 2026-04-21 12:41:43 +02:00
kiri 6332c96d3e refactor: centralize host and user metadata 2026-04-21 12:12:43 +02:00
107 changed files with 4094 additions and 2166 deletions
-83
View File
@@ -1,83 +0,0 @@
# Repository Guidelines
## Project Structure & Module Organization
This repository is a simplified `flake-parts` NixOS flake. `flake.nix` imports `./modules` through `import-tree`, so normal `.nix` files under `modules/` are loaded automatically unless their file or directory name starts with `_`.
- `modules/flake-parts.nix` defines the `flake-parts` setup, formatter, and the exported `nixosConfigurations`.
- `modules/hosts/<name>/default.nix` defines one top-level `flake.modules.nixos.<host>` module and assembles that machine by importing reusable features, user modules, and host-local helpers.
- `modules/hosts/<name>/_*.nix` are private host-local helper modules such as hardware and disk layout files.
- `modules/users/<name>.nix` defines one reusable NixOS user module and the baseline Home Manager imports for that account.
- `modules/features/*.nix` contains reusable NixOS and Home Manager feature modules.
- `modules/features/<feature>/default.nix` is used when a feature needs private helper files, for example `niri/_bindings.nix`.
- `modules/features/services/*.nix` contains reusable service-oriented NixOS modules.
- `modules/secrets/sops.nix` wires `sops-nix` for both NixOS and Home Manager.
- `modules/secrets/secrets.yaml` stores encrypted secrets, with `.sops.yaml` defining SOPS creation rules.
- `modules/_treefmt.nix` configures repository formatting.
Keep host files thin. Shared behavior belongs in `modules/features/` or `modules/users/`. Host files should mainly compose imports and hold host-only settings such as monitor layouts, hardware quirks, boot tweaks, and machine-local firewall or service choices.
## Mental Model
This repo is direct module composition around `flake.modules`, not the old inventory-driven dendritic design.
- Reusable building blocks are exposed as `flake.modules.nixos.<name>` and `flake.modules.homeManager.<name>`.
- Host modules are the composition root. They import the reusable NixOS modules they need, enable Home Manager, and add any host-specific Home Manager imports inline.
- User modules define the Unix user plus that accounts baseline Home Manager setup.
- There is no `config.repo`, inventory schema, profiles layer, or attachment builder anymore.
In practice:
- Prefer importing a feature module directly over inventing a repo-local option just to toggle it.
- Put cross-host reusable behavior in `modules/features/`.
- Put account-specific defaults in `modules/users/`.
- Keep private helper files `_`-prefixed so `import-tree` does not expose them as top-level modules.
- Match the existing split between NixOS composition in host modules and Home Manager composition in user or host modules.
## Current Host Composition
There are three exported hosts:
- `orion`: server-oriented host with `kiri`, SOPS, and service modules such as Caddy, Gitea, Vaultwarden, Radicale, Actual, and OpenSSH.
- `polaris`: graphical desktop host with `kiri` and `ergon`, hardware imports, Niri, Steam, local desktop features, and host-specific monitor layout.
- `zenith`: graphical laptop host with `kiri` and `ergon`, Niri, laptop hardware support, firmware updates, and host-specific monitor layout.
When adjusting user-facing software, check whether it belongs in:
- a user baseline in `modules/users/<name>.nix`
- a reusable Home Manager feature in `modules/features/*.nix`
- a host-local extension inside `modules/hosts/<name>/default.nix`
Be careful not to move host-specific Home Manager imports into a user baseline unless that behavior should apply on every host that imports that user module.
## Validation And Development Commands
Run commands from the repository root.
- `nix build --no-link --show-trace .#nixosConfigurations.<host>.config.system.build.toplevel`: baseline validation for one host.
- `nix build --no-link --show-trace .#nixosConfigurations.orion.config.system.build.toplevel .#nixosConfigurations.polaris.config.system.build.toplevel .#nixosConfigurations.zenith.config.system.build.toplevel`: validate all defined hosts in one invocation.
- `nixos-rebuild build --flake .#<host>`: use when you specifically want `nixos-rebuild` semantics without activation.
- `nix eval --json .#nixosConfigurations.<host>.config.<option>`: inspect a single evaluated option while iterating.
- `nix fmt`: format the repository using the flake-provided formatter from `modules/_treefmt.nix`.
- `nix store diff-closures <old> <new>`: compare built system closures when reviewing refactors for parity or regressions.
This repo does not define a first-party `checks` output. Validation is primarily host builds plus targeted `nix eval` checks.
## Coding Style & Naming Conventions
Use two-space indentation and standard Nix attrset formatting. Prefer small `let` bindings, lowerCamelCase local names, and lowercase file names.
- Define reusable modules as `flake.modules.nixos.<name>` or `flake.modules.homeManager.<name>`.
- Keep one obvious feature per file or directory.
- Use `default.nix` only when the feature needs private helper files alongside it.
- Match surrounding style instead of reformatting unrelated code.
- Prefer explicit host imports over hidden indirection.
## Commit
Follow the existing history style: short imperative subjects, optionally with a conventional prefix, for example `refactor: simplify host composition`.
## Security & Configuration Tips
Never commit plaintext secrets. Add or update secrets through `modules/secrets/secrets.yaml` and reference them via `config.sops.secrets.<name>.path`.
Be explicit and cautious with changes to:
- firewall and OpenSSH settings
- disk layout and boot configuration
- SOPS key handling and admin user access
- firmware, hardware, and authentication settings
- host-vs-user module boundaries, because it is easy to accidentally broaden behavior to the wrong machines
Generated
+597 -203
View File
File diff suppressed because it is too large Load Diff
+34 -7
View File
@@ -2,20 +2,47 @@
description = "NixOS Configuration"; description = "NixOS Configuration";
inputs = { inputs = {
disko.url = "github:nix-community/disko"; disko = {
url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs";
};
devenv.url = "github:cachix/devenv";
flake-parts.follows = "lux-pkgs/flake-parts"; flake-parts.follows = "lux-pkgs/flake-parts";
home-manager.url = "github:nix-community/home-manager"; home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
import-tree.url = "github:vic/import-tree"; import-tree.url = "github:vic/import-tree";
llm-agents = {
url = "github:numtide/llm-agents.nix";
inputs.nixpkgs.follows = "nixpkgs";
};
niri.url = "github:sodiboo/niri-flake"; niri.url = "github:sodiboo/niri-flake";
nix-wrapper-modules.url = "github:BirdeeHub/nix-wrapper-modules"; nix-wrapper-modules = {
url = "github:BirdeeHub/nix-wrapper-modules";
inputs.nixpkgs.follows = "nixpkgs";
};
nixos-hardware.url = "github:NixOS/nixos-hardware/master"; nixos-hardware.url = "github:NixOS/nixos-hardware/master";
nixpkgs.url = "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz"; nixpkgs.url = "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz";
noctalia.url = "github:noctalia-dev/noctalia-shell"; noctalia.url = "github:noctalia-dev/noctalia-shell";
sops-nix.url = "github:Mic92/sops-nix"; sops-nix = {
treefmt-nix.url = "github:numtide/treefmt-nix"; url = "github:Mic92/sops-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
nix-index-database = {
url = "github:nix-community/nix-index-database";
inputs.nixpkgs.follows = "nixpkgs";
};
#vicinae.url = "github:vicinaehq/vicinae"; elephant = {
vicinae-extensions.url = "github:vicinaehq/extensions"; url = "github:abenz1267/elephant";
inputs.nixpkgs.follows = "nixpkgs";
};
walker = {
url = "github:abenz1267/walker";
inputs.elephant.follows = "elephant";
inputs.nixpkgs.follows = "nixpkgs";
};
lux-pkgs.url = "git+ssh://gitea@orion/kiri/lux-pkgs"; lux-pkgs.url = "git+ssh://gitea@orion/kiri/lux-pkgs";
}; };
+69
View File
@@ -0,0 +1,69 @@
{
cursor = {
name = "phinger-cursors-light";
packagePath = [ "phinger-cursors" ];
size = 24;
};
kanagawa = {
displayName = "Kanagawa Wave";
name = "kanagawa-wave";
gtkThemeName = "Kanagawa-BL-LB";
iconThemeName = "Kanagawa";
owner = "Fausto-Korpsvart";
repo = "Kanagawa-GKT-Theme";
rev = "55ca4ba249eba21f861b9866b71ab41bb8930318";
hash = "sha256-UdMoMx2DoovcxSp/zBZ3PRv/Qpj+prd0uPm1gmdak2E=";
version = "unstable-2025-10-23";
palette = {
background = "#1F1F28";
foreground = "#DCD7BA";
secondaryBackground = "#16161D";
border = "#2A2A37";
selectionBackground = "#2D4F67";
selectionForeground = "#C8C093";
url = "#72A7BC";
cursor = "#C8C093";
muted = "#727169";
accents = {
blue = "#7E9CD8";
green = "#98BB6C";
magenta = "#D27E99";
orange = "#FFA066";
purple = "#957FB8";
red = "#E82424";
yellow = "#E6C384";
cyan = "#7AA89F";
};
niri.border = {
active = "#7E9CD8";
inactive = "#54546D";
urgent = "#E82424";
};
terminal = {
color0 = "#16161D";
color1 = "#C34043";
color2 = "#76946A";
color3 = "#C0A36E";
color4 = "#7E9CD8";
color5 = "#957FB8";
color6 = "#6A9589";
color7 = "#C8C093";
color8 = "#727169";
color9 = "#E82424";
color10 = "#98BB6C";
color11 = "#E6C384";
color12 = "#7FB4CA";
color13 = "#938AA9";
color14 = "#7AA89F";
color15 = "#DCD7BA";
color16 = "#FFA066";
color17 = "#FF5D62";
};
};
};
}
+100
View File
@@ -0,0 +1,100 @@
{ inputs, config, ... }:
let
account = config.repo.account;
hmModules = config.flake.modules.homeManager;
sharedContext = ''
# Global Agent Context
Be a concise technical thought partner. Check the premise before executing, optimize for the user's actual outcome, and make important assumptions or tradeoffs visible.
## Machine Environment
- This machine is Nix/NixOS-based. Standard Linux assumptions may be wrong: software is usually provided by flakes, dev shells, `devenv`, `direnv`, or the user's NixOS/Home Manager config rather than `apt`, `dnf`, or global installs.
- If a repo has `flake.nix`, `devenv.nix`, `shell.nix`, or `.envrc`, prefer entering or invoking its dev environment (`nix develop`, `devenv shell`, or `direnv exec . <cmd>`). `direnv` may not be loaded automatically inside agent shells.
- For NixOS/Home Manager/nixpkgs/packages/options, use the NixOS MCP when available instead of relying on memory.
## User Preferences
- The user values precision, minimalism, and conceptual clarity. Challenge weak premises, but explain why.
- For larger or ambiguous work, interview or plan before broad implementation. For small concrete requests, proceed with the obvious scoped change.
'';
in
{
flake.modules.nixos.ai = {
home-manager.sharedModules = [ hmModules.ai ];
nixpkgs.overlays = [ inputs.llm-agents.overlays.default ];
nix.settings = {
extra-substituters = [ "https://cache.numtide.com" ];
extra-trusted-public-keys = [
"niks3.numtide.com-1:DTx8wZduET09hRmMtKdQDxNNthLQETkc/yaX7M4qK0g="
];
};
};
flake.modules.homeManager.ai =
{
config,
lib,
pkgs,
...
}:
{
home.sessionVariables.GEMINI_CONFIG_DIR = "${config.xdg.configHome}/gemini";
programs.mcp = {
enable = true;
servers.nixos = {
command = "${pkgs.uv}/bin/uvx";
args = [ "mcp-nixos" ];
};
};
programs.gemini-cli = {
enable = false;
package = pkgs.llm-agents.gemini-cli;
enableMcpIntegration = true;
context.AGENTS = sharedContext;
settings = {
context = {
fileName = [
"AGENTS.md"
"GEMINI.md"
];
loadMemoryFromIncludeDirectories = true;
};
model.name = "gemini-3.1-pro-preview";
};
};
programs.codex = {
enable = true;
package = pkgs.llm-agents.codex;
enableMcpIntegration = true;
context = sharedContext;
settings = {
model = "gpt-5.5";
model_reasoning_effort = "high";
plan_mode_reasoning_effort = "high";
tui.status_line = [
"model-with-reasoning"
"current-dir"
"git-branch"
"context-remaining"
"five-hour-limit"
];
projects.${account.nixosConfigurationPath}.trust_level = "trusted";
projects."${config.home.homeDirectory}/work/repos/yookr_data_science".trust_level = "trusted";
sandbox_mode = "workspace-write";
personality = "pragmatic";
features.undo = true;
mcp_servers.nixos = config.programs.mcp.servers.nixos // {
enabled = true;
default_tools_approval_mode = "approve";
};
};
};
};
}
+115
View File
@@ -0,0 +1,115 @@
{ config, ... }:
let
homeModules = config.flake.modules.homeManager;
vivaldiPackage = pkgs: pkgs.vivaldi;
nautilusPackage = pkgs: pkgs.nautilus;
in
{
flake.modules.homeManager.browser-vivaldi =
{ pkgs, ... }:
{
home.packages = [ (vivaldiPackage pkgs) ];
};
flake.modules.homeManager.primary-browser-vivaldi =
{ lib, pkgs, ... }:
{
imports = [ homeModules.browser-vivaldi ];
facts.desktop.browserCommand = lib.getExe (vivaldiPackage pkgs);
home.sessionVariables.BROWSER = lib.getExe (vivaldiPackage pkgs);
xdg.mimeApps.defaultApplicationPackages = [ (vivaldiPackage pkgs) ];
};
flake.modules.homeManager.file-manager-nautilus =
{ pkgs, ... }:
{
home.packages = [ (nautilusPackage pkgs) ];
};
flake.modules.homeManager.primary-file-manager-nautilus =
{ lib, pkgs, ... }:
{
imports = [ homeModules.file-manager-nautilus ];
xdg.mimeApps.defaultApplicationPackages = [ (nautilusPackage pkgs) ];
};
flake.modules.homeManager.image-viewer-imv = {
programs.imv.enable = true;
};
flake.modules.homeManager.default-image-viewer-imv =
{ pkgs, ... }:
{
imports = [ homeModules.image-viewer-imv ];
xdg.mimeApps.defaultApplicationPackages = [ pkgs.imv ];
};
flake.modules.homeManager.document-viewer-sioyek = {
programs.sioyek.enable = true;
};
flake.modules.homeManager.default-document-viewer-sioyek =
{ pkgs, ... }:
{
imports = [ homeModules.document-viewer-sioyek ];
xdg.mimeApps.defaultApplicationPackages = [ pkgs.sioyek ];
};
flake.modules.homeManager.workstation-apps =
{ pkgs, ... }:
{
home.packages = with pkgs; [
postman
spotify
calcure
planify
unzip
gimp
dbeaver-bin
];
};
flake.modules.homeManager.xdg =
{ config, ... }:
let
homeDir = config.home.homeDirectory;
localDir = "${homeDir}/.local";
mediaDir = "${homeDir}/media";
in
{
home.preferXdgDirectories = true;
xdg = {
enable = true;
cacheHome = "${localDir}/cache";
configHome = "${homeDir}/.config";
dataHome = "${localDir}/share";
stateHome = "${localDir}/state";
userDirs = {
enable = true;
createDirectories = true;
setSessionVariables = true;
download = "${homeDir}/downloads";
documents = "${homeDir}/documents";
projects = "${homeDir}/dev";
music = "${mediaDir}/music";
pictures = "${mediaDir}/images";
videos = "${mediaDir}/videos";
desktop = "${localDir}/desktop";
publicShare = "${localDir}/public";
templates = "${localDir}/templates";
};
mimeApps = {
enable = true;
};
};
};
}
+37
View File
@@ -0,0 +1,37 @@
{ inputs, ... }:
{
flake.modules.homeManager.dev-tools =
{ config, pkgs, ... }:
{
home.sessionVariables.CARGO_HOME = "${config.xdg.dataHome}/cargo";
home.packages = with pkgs; [
httpie
bruno
usql
posting
resterm
inputs.devenv.packages.${pkgs.stdenv.hostPlatform.system}.default
];
# programs.direnv = {
# enable = true;
# enableZshIntegration = true;
# nix-direnv.enable = true;
# };
programs.zsh.initContent = ''
eval "$(devenv hook zsh)"
'';
programs.lazygit = {
enable = true;
enableZshIntegration = true;
};
programs.jujutsu.enable = true;
programs.jq.enable = true;
programs.bun.enable = true;
programs.ripgrep.enable = true;
#programs.uv.enable = true;
};
}
@@ -21,6 +21,24 @@
source-sans-pro source-sans-pro
source-serif-pro source-serif-pro
]; ];
fontconfig = {
enable = true;
antialias = true;
allowBitmaps = false;
useEmbeddedBitmaps = false;
hinting = {
enable = true;
autohint = false;
style = "slight";
};
subpixel = {
rgba = "none";
lcdfilter = "none";
};
};
}; };
}; };
} }
+83
View File
@@ -0,0 +1,83 @@
{ config, lib, ... }:
let
account = config.repo.account;
in
{
flake.modules.homeManager.git =
{
config,
osConfig,
...
}:
let
machine = osConfig.facts.machine;
allowedSignersFile = "${config.xdg.configHome}/git/allowed_signers";
mkScope =
scope:
let
email = account.emails.${scope}.address;
key = lib.attrByPath [ scope ] null machine.sshKeys;
hasSigningKey = key != null;
privateKeyPath = key.privateKeyPath or "~/.ssh/id_${scope}";
in
{
allowedSigners = lib.optional hasSigningKey "${email} ${key.publicKey}";
git = {
user = {
name = account.realName;
inherit email;
}
// lib.optionalAttrs hasSigningKey {
signingKey = "${privateKeyPath}.pub";
};
}
// lib.optionalAttrs hasSigningKey {
gpg.ssh.allowedSignersFile = allowedSignersFile;
};
};
personal = mkScope "personal";
work = mkScope "work";
in
{
xdg.configFile."git/allowed_signers".text = lib.concatStringsSep "\n" (
personal.allowedSigners ++ work.allowedSigners ++ [ "" ]
);
programs.git = {
enable = true;
signing.format = "ssh";
ignores = [
".claude/"
".codex"
];
settings = {
init.defaultBranch = "main";
user = {
name = account.realName;
email = account.emails.personal.address;
};
};
includes = [
{
condition = "gitdir:${account.nixosConfigurationPath}/";
contents = personal.git;
}
{
condition = "gitdir:${config.xdg.userDirs.projects}/";
contents = personal.git;
}
{
condition = "gitdir:${config.home.homeDirectory}/work/";
contents = work.git;
}
];
};
programs.gh = {
enable = true;
settings.git_protocol = "ssh";
};
};
}
+8
View File
@@ -0,0 +1,8 @@
{
flake.modules.nixos.hidraw-access = {
services.udev.extraRules = ''
# ROYUAN YUNZII B75 PRO
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="3151", ATTRS{idProduct}=="4015", MODE="0660", GROUP="users"
'';
};
}
+6
View File
@@ -0,0 +1,6 @@
{
flake.modules.nixos.laptop-power = {
services.upower.enable = true;
services.power-profiles-daemon.enable = true;
};
}
+75
View File
@@ -0,0 +1,75 @@
{ config, lib, ... }:
let
palette = config.repo.theme.kanagawa.palette;
hex = lib.removePrefix "#";
terminalPalette = palette.terminal;
mkPalette = colors: lib.concatStringsSep ";" (map hex colors);
in
{
flake.modules.nixos.limine =
{ config, lib, ... }:
let
displayValues = builtins.attrValues (config.facts.machine.displays or { });
primaryDisplays = lib.filter (display: display.primary or false) displayValues;
primaryDisplay = if primaryDisplays == [ ] then null else builtins.head primaryDisplays;
interfaceResolution =
if primaryDisplay != null && primaryDisplay ? width && primaryDisplay ? height then
"${toString primaryDisplay.width}x${toString primaryDisplay.height}"
else
null;
in
{
boot.loader = {
efi.canTouchEfiVariables = true;
limine = {
enable = true;
maxGenerations = 10;
resolution = "2560x1440";
style = {
backdrop = hex palette.secondaryBackground;
graphicalTerminal = {
background = "00${hex palette.background}";
foreground = hex palette.foreground;
brightForeground = hex palette.selectionForeground;
brightBackground = hex palette.selectionBackground;
palette = mkPalette [
terminalPalette.color0
terminalPalette.color1
terminalPalette.color2
terminalPalette.color3
terminalPalette.color4
terminalPalette.color5
terminalPalette.color6
terminalPalette.color7
];
brightPalette = mkPalette [
terminalPalette.color8
terminalPalette.color9
terminalPalette.color10
terminalPalette.color11
terminalPalette.color12
terminalPalette.color13
terminalPalette.color14
terminalPalette.color15
];
font = {
scale = "2x2";
spacing = 1;
};
margin = 64;
marginGradient = 24;
};
interface = {
branding = config.networking.hostName;
brandingColor = hex palette.accents.blue;
helpHidden = false;
resolution = interfaceResolution;
};
};
};
};
};
}
@@ -1,6 +1,6 @@
{ ... }: { ... }:
{ {
flake.modules.nixos.regionNl = { flake.modules.nixos.locale-nl = {
time.timeZone = "Europe/Amsterdam"; time.timeZone = "Europe/Amsterdam";
i18n.defaultLocale = "en_US.UTF-8"; i18n.defaultLocale = "en_US.UTF-8";
@@ -0,0 +1,64 @@
{ themeName }:
''
require("kanagawa").setup({
dimInactive = true,
colors = {
theme = {
all = {
ui = {
bg_gutter = "none"
}
}
}
},
overrides = function(colors)
local theme = colors.theme
local makeDiagnosticColor = function(color)
local c = require("kanagawa.lib.color")
return { fg = color, bg = c(color):blend(theme.ui.bg, 0.95):to_hex() }
end
return {
TelescopeTitle = { fg = theme.ui.special, bold = true },
TelescopePromptNormal = { bg = theme.ui.bg_p1 },
TelescopePromptBorder = { fg = theme.ui.bg_p1, bg = theme.ui.bg_p1 },
TelescopeResultsNormal = { fg = theme.ui.fg_dim, bg = theme.ui.bg_m1 },
TelescopeResultsBorder = { fg = theme.ui.bg_m1, bg = theme.ui.bg_m1 },
TelescopePreviewNormal = { bg = theme.ui.bg_dim },
TelescopePreviewBorder = { bg = theme.ui.bg_dim, fg = theme.ui.bg_dim },
Pmenu = { fg = theme.ui.shade0, bg = theme.ui.bg_p1 }, -- add `blend = vim.o.pumblend` to enable transparency
PmenuSel = { fg = "NONE", bg = theme.ui.bg_p2 },
PmenuSbar = { bg = theme.ui.bg_m1 },
PmenuThumb = { bg = theme.ui.bg_p2 },
DiagnosticVirtualTextHint = makeDiagnosticColor(theme.diag.hint),
DiagnosticVirtualTextInfo = makeDiagnosticColor(theme.diag.info),
DiagnosticVirtualTextWarn = makeDiagnosticColor(theme.diag.warning),
DiagnosticVirtualTextError = makeDiagnosticColor(theme.diag.error),
DiagnosticVirtualLinesHint = makeDiagnosticColor(theme.diag.hint),
DiagnosticVirtualLinesInfo = makeDiagnosticColor(theme.diag.info),
DiagnosticVirtualLinesWarn = makeDiagnosticColor(theme.diag.warning),
DiagnosticVirtualLinesError = makeDiagnosticColor(theme.diag.error),
FloatBorder = { fg = theme.ui.float.fg_border, bg = theme.ui.float.bg },
NormalFloat = { fg = theme.ui.float.fg, bg = theme.ui.float.bg },
WinBar = { fg = theme.ui.fg_dim, bg = "NONE" },
WinBarNC = { fg = theme.ui.nontext, bg = theme.ui.bg_dim },
BufferLineFill = { bg = theme.ui.bg_m3 },
BufferLineBackground = { fg = theme.ui.fg_dim, bg = theme.ui.bg_m3 },
BufferLineBufferSelected = { fg = theme.ui.fg, bg = theme.ui.bg, bold = true },
BufferLineModified = { fg = theme.vcs.changed, bg = theme.ui.bg_m3 },
BufferLineModifiedSelected = { fg = theme.vcs.changed, bg = theme.ui.bg },
BufferLineDiagnostic = { fg = theme.ui.nontext, bg = theme.ui.bg_m3 },
BufferLineDiagnosticSelected = { fg = theme.ui.fg_dim, bg = theme.ui.bg },
}
end,
})
vim.cmd.colorscheme("${themeName}")
''
+183
View File
@@ -0,0 +1,183 @@
{ config, ... }:
let
account = config.repo.account;
repoTheme = config.repo.theme.kanagawa;
in
{
flake.modules.homeManager.default-editor-neovim =
{ pkgs, ... }:
{
xdg.mimeApps.defaultApplicationPackages = [ pkgs.neovim ];
};
flake.modules.homeManager.neovim =
{
pkgs,
config,
inputs,
osConfig,
...
}:
{
home.sessionVariables = {
EDITOR = "nvim";
VISUAL = "nvim";
};
imports = [
(inputs.nix-wrapper-modules.lib.getInstallModule {
name = "neovim";
value = inputs.nix-wrapper-modules.lib.wrapperModules.neovim;
})
];
wrappers.neovim = {
enable = true;
# 1. Point to your existing Lua config directory
settings.config_directory = ./lua-config;
# 2. Runtime Dependencies (from lspsAndRuntimeDeps)
# These are added to the PATH of the wrapper
runtimePkgs = with pkgs; [
# Tools
universal-ctags
ripgrep
fd
tree-sitter
wl-clipboard
# LSPs & Formatters
stylua
lua-language-server
nixd
nix-doc
nixfmt
dafny
typescript
typescript-language-server
rustc
rust-analyzer
rustfmt
astro-language-server
tinymist
typstyle
websocat
# ty
# basedpyright
ty
ruff
];
# 3. Plugins
# Nix provisions plugins; lz.n controls when lazy specs are packadd'd.
specs = {
lz-n = {
data = pkgs.vimPlugins.lz-n;
};
support = {
data = with pkgs.vimPlugins; [
plenary-nvim
kanagawa-nvim
nvim-treesitter.withAllGrammars
nvim-treesitter-textobjects
rainbow-delimiters-nvim
];
};
completion = {
lazy = true;
data = with pkgs.vimPlugins; [
blink-cmp
luasnip
friendly-snippets
colorful-menu-nvim
];
};
lsp = {
lazy = true;
data = with pkgs.vimPlugins; [
nvim-lspconfig
lazydev-nvim
trouble-nvim
typst-preview-nvim
];
};
formatting = {
lazy = true;
data = with pkgs.vimPlugins; [
conform-nvim
];
};
core = {
lazy = true;
data = with pkgs.vimPlugins; [
mini-nvim
guess-indent-nvim
direnv-vim
];
};
ui = {
lazy = true;
data = with pkgs.vimPlugins; [
lualine-nvim
bufferline-nvim
gitsigns-nvim
zen-mode-nvim
which-key-nvim
kulala-nvim
];
};
project = {
lazy = true;
data = with pkgs.vimPlugins; [
project-nvim
];
};
telescope = {
lazy = true;
data = with pkgs.vimPlugins; [
telescope-nvim
telescope-fzf-native-nvim
telescope-ui-select-nvim
];
};
};
# 4. Values exposed to Lua through require("nix-info").settings.
settings = {
# Hostname/ConfigDir needed for nixd
nixdExtras = {
nixpkgs = "import ${pkgs.path} {}";
nixos_options = ''(builtins.getFlake "path://${account.nixosConfigurationPath}").nixosConfigurations.${osConfig.facts.machine.name}.options'';
home_manager_options = ''(builtins.getFlake "path://${account.nixosConfigurationPath}").nixosConfigurations.${osConfig.facts.machine.name}.options.home-manager.users.type.getSubOptions []'';
};
themeSetup = import ./_kanagawa-theme.nix {
themeName = repoTheme.name;
};
typstPreviewDependencies = {
tinymist = "${pkgs.tinymist}/bin/tinymist";
websocat = "${pkgs.websocat}/bin/websocat";
};
};
# 5. Wrapper Configuration
# Enable Python/Node providers
hosts.python3.nvim-host.enable = true;
hosts.node.nvim-host.enable = true;
# Ensure the bin name matches what you expect
binName = "nvim";
};
};
}
@@ -6,4 +6,3 @@ require("plugins.treesitter")
require("plugins.telescope") require("plugins.telescope")
require("plugins.ui") require("plugins.ui")
require("plugins.core") require("plugins.core")
require("plugins.ai")
@@ -0,0 +1,74 @@
vim.g.mapleader = " "
vim.g.maplocalleader = " "
vim.o.expandtab = true
vim.o.shiftwidth = 2
vim.o.tabstop = 2
vim.o.softtabstop = 2
vim.o.number = true
-- vim.o.relativenumber = true
vim.o.mouse = "a"
vim.o.showmode = false
vim.opt.shortmess:append("Wc")
vim.schedule(function()
vim.o.clipboard = "unnamedplus"
end)
vim.o.breakindent = true
vim.o.undofile = true
vim.o.ignorecase = true
vim.o.smartcase = true
vim.o.signcolumn = "yes"
vim.o.updatetime = 250
vim.o.timeoutlen = 300
vim.o.splitright = true
vim.o.splitbelow = true
vim.o.list = true
vim.opt.listchars = { tab = "» ", trail = "·", nbsp = "" }
vim.o.inccommand = "split"
vim.o.cursorline = true
vim.o.scrolloff = 10
vim.o.confirm = true
vim.keymap.set("n", "<Esc>", "<cmd>nohlsearch<CR>")
vim.keymap.set("n", "<leader>q", vim.diagnostic.setloclist, { desc = "Open diagnostic [Q]uickfix list" })
vim.keymap.set("t", "<Esc><Esc>", "<C-\\><C-n>", { desc = "Exit terminal mode" })
vim.keymap.set("n", "<C-h>", "<C-w><C-h>", { desc = "Move focus to the left window" })
vim.keymap.set("n", "<C-l>", "<C-w><C-l>", { desc = "Move focus to the right window" })
vim.keymap.set("n", "<C-j>", "<C-w><C-j>", { desc = "Move focus to the lower window" })
vim.keymap.set("n", "<C-k>", "<C-w><C-k>", { desc = "Move focus to the upper window" })
vim.keymap.set("n", "j", "gj", { silent = true })
vim.keymap.set("n", "k", "gk", { silent = true })
-- vim.keymap.set("n", "<C-S-h>", "<C-w>H", { desc = "Move window to the left" })
-- vim.keymap.set("n", "<C-S-l>", "<C-w>L", { desc = "Move window to the right" })
-- vim.keymap.set("n", "<C-S-j>", "<C-w>J", { desc = "Move window to the lower" })
-- vim.keymap.set("n", "<C-S-k>", "<C-w>K", { desc = "Move window to the upper" })
vim.api.nvim_create_autocmd("TextYankPost", {
desc = "Highlight when yanking (copying) text",
group = vim.api.nvim_create_augroup("lux-highlight-yank", { clear = true }),
callback = function()
vim.hl.on_yank()
end,
})
@@ -4,6 +4,7 @@ require("lz.n").load({
}, },
{ {
"luasnip", "luasnip",
event = { "InsertEnter", "CmdlineEnter" },
before = function() before = function()
require("lz.n").trigger_load("friendly-snippets") require("lz.n").trigger_load("friendly-snippets")
end, end,
@@ -15,6 +16,7 @@ require("lz.n").load({
}, },
{ {
"colorful-menu.nvim", "colorful-menu.nvim",
event = { "InsertEnter", "CmdlineEnter" },
after = function() after = function()
require("colorful-menu").setup({}) require("colorful-menu").setup({})
end, end,
@@ -51,8 +53,12 @@ require("lz.n").load({
documentation = { documentation = {
auto_show = true, auto_show = true,
auto_show_delay_ms = 500, auto_show_delay_ms = 500,
window = {
border = "none",
},
}, },
menu = { menu = {
border = "none",
draw = { draw = {
columns = { { "kind_icon" }, { "label", gap = 1 } }, columns = { { "kind_icon" }, { "label", gap = 1 } },
components = { components = {
@@ -96,9 +102,11 @@ require("lz.n").load({
signature = { signature = {
enabled = true, enabled = true,
window = {
border = "none",
},
}, },
}) })
end, end,
}, },
}) })
@@ -3,13 +3,8 @@ require("lz.n").load({
"mini.nvim", "mini.nvim",
event = { "BufReadPre", "BufNewFile" }, event = { "BufReadPre", "BufNewFile" },
after = function() after = function()
-- Better Around/Inside textobjects
require("mini.ai").setup({ n_lines = 500 }) require("mini.ai").setup({ n_lines = 500 })
-- Add/delete/replace surroundings (brackets, quotes, etc.)
require("mini.surround").setup() require("mini.surround").setup()
-- Auto-pairs (replaces nvim-autopairs)
require("mini.pairs").setup() require("mini.pairs").setup()
local files = require("mini.files") local files = require("mini.files")
@@ -27,9 +22,7 @@ require("lz.n").load({
local hipatterns = require("mini.hipatterns") local hipatterns = require("mini.hipatterns")
hipatterns.setup({ hipatterns.setup({
highlighters = { highlighters = {
-- Highlight hex color strings (#rrggbb) using that color
hex_color = hipatterns.gen_highlighter.hex_color(), hex_color = hipatterns.gen_highlighter.hex_color(),
-- Highlight TODOs, FIXMEs, etc. (replaces todo-comments.nvim)
fixme = { pattern = "%f[%w]()FIXME()%f[%W]", group = "MiniHipatternsFixme" }, fixme = { pattern = "%f[%w]()FIXME()%f[%W]", group = "MiniHipatternsFixme" },
hack = { pattern = "%f[%w]()HACK()%f[%W]", group = "MiniHipatternsHack" }, hack = { pattern = "%f[%w]()HACK()%f[%W]", group = "MiniHipatternsHack" },
todo = { pattern = "%f[%w]()TODO()%f[%W]", group = "MiniHipatternsTodo" }, todo = { pattern = "%f[%w]()TODO()%f[%W]", group = "MiniHipatternsTodo" },
@@ -43,7 +36,7 @@ require("lz.n").load({
}) })
vim.api.nvim_create_autocmd("FileType", { vim.api.nvim_create_autocmd("FileType", {
pattern = { "help", "alpha", "dashboard", "neo-tree", "Trouble", "lazy", "mason" }, pattern = { "help", "Trouble" },
callback = function() callback = function()
vim.b.miniindentscope_disable = true vim.b.miniindentscope_disable = true
end, end,
@@ -62,4 +55,3 @@ require("lz.n").load({
event = "BufEnter", event = "BufEnter",
}, },
}) })
@@ -17,9 +17,6 @@ require("lz.n").load({
require("conform").setup({ require("conform").setup({
notify_on_error = true, notify_on_error = true,
format_on_save = function(bufnr) format_on_save = function(bufnr)
-- Disable "format_on_save lsp_fallback" for languages that don't
-- have a well standardized coding style. You can add additional
-- languages here or re-enable it for the disabled ones.
local disable_filetypes = { c = true, cpp = true } local disable_filetypes = { c = true, cpp = true }
if disable_filetypes[vim.bo[bufnr].filetype] then if disable_filetypes[vim.bo[bufnr].filetype] then
return nil return nil
@@ -32,11 +29,7 @@ require("lz.n").load({
end, end,
formatters_by_ft = { formatters_by_ft = {
lua = { "stylua" }, lua = { "stylua" },
-- Conform can also run multiple formatters sequentially python = { "ruff_fix", "ruff_format", "ruff_organize_imports" },
python = { "isort", "black" },
--
-- You can use 'stop_after_first' to run the first available formatter from the list
-- javascript = { "prettierd", "prettier", stop_after_first = true },
}, },
formatters = { formatters = {
stylua = { stylua = {
@@ -6,9 +6,7 @@ require("lz.n").load({
-- Setup typst-preview -- Setup typst-preview
require("typst-preview").setup({ require("typst-preview").setup({
-- Optionally configure things here -- Optionally configure things here
dependencies_bin = { dependencies_bin = require("nix-info").settings.typstPreviewDependencies,
-- For example, use tinymist as the LSP if that's what you are running
},
}) })
vim.keymap.set("n", "<leader>tp", "<cmd>TypstPreviewToggle<cr>", { desc = "[T]ypst [P]review Toggle" }) vim.keymap.set("n", "<leader>tp", "<cmd>TypstPreviewToggle<cr>", { desc = "[T]ypst [P]review Toggle" })
@@ -21,7 +19,7 @@ require("lz.n").load({
after = function() after = function()
require("lazydev").setup({ require("lazydev").setup({
library = { library = {
{ words = { "nixCats", "settings" }, path = "nix-info" }, { words = { "nix%-info", "settings" }, path = "nix-info" },
}, },
}) })
end, end,
@@ -33,10 +31,73 @@ require("lz.n").load({
require("lz.n").trigger_load("lazydev.nvim") require("lz.n").trigger_load("lazydev.nvim")
end, end,
after = function() after = function()
vim.api.nvim_create_autocmd("LspAttach", { local telescope_plugins = {
group = vim.api.nvim_create_augroup("kickstart-lsp-attach", { clear = true }), "project.nvim",
"telescope.nvim",
"telescope-fzf-native.nvim",
"telescope-ui-select.nvim",
}
local telescope_picker = function(picker)
return function()
require("lz.n").trigger_load(telescope_plugins)
require("telescope.builtin")[picker]()
end
end
local lsp_float = { border = "single" }
local navic_excluded_filetypes = {
[""] = true,
help = true,
minifiles = true,
TelescopePrompt = true,
Trouble = true,
}
local function navic_enabled(bufnr)
return vim.bo[bufnr].buftype == "" and not navic_excluded_filetypes[vim.bo[bufnr].filetype]
end
_G.lux_navic_location = function()
local ok, navic = pcall(require, "nvim-navic")
if not ok or not navic.is_available() then
return ""
end
return navic.get_location()
end
local function update_winbar(winid, bufnr)
if not vim.api.nvim_win_is_valid(winid) then
return
end
local is_float = vim.api.nvim_win_get_config(winid).relative ~= ""
local winbar = ""
if not is_float and vim.b[bufnr].lux_navic_attached and navic_enabled(bufnr) then
winbar = "%{%v:lua.lux_navic_location()%}"
end
vim.api.nvim_set_option_value("winbar", winbar, { win = winid })
end
local function update_winbars_for_buffer(bufnr)
for _, winid in ipairs(vim.fn.win_findbuf(bufnr)) do
update_winbar(winid, bufnr)
end
end
vim.api.nvim_create_autocmd({ "BufEnter", "BufWinEnter", "WinEnter" }, {
group = vim.api.nvim_create_augroup("lux-navic-winbar", { clear = true }),
callback = function(args)
update_winbar(vim.api.nvim_get_current_win(), args.buf)
end,
})
vim.api.nvim_create_autocmd("LspAttach", {
group = vim.api.nvim_create_augroup("lux-lsp-attach", { clear = true }),
callback = function(args) callback = function(args)
-- Get the client and buffer from the event arguments [cite: 119]
local client = vim.lsp.get_client_by_id(args.data.client_id) local client = vim.lsp.get_client_by_id(args.data.client_id)
local bufnr = args.buf local bufnr = args.buf
@@ -45,23 +106,35 @@ require("lz.n").load({
vim.keymap.set(mode, keys, func, { buffer = bufnr, desc = "LSP: " .. desc }) vim.keymap.set(mode, keys, func, { buffer = bufnr, desc = "LSP: " .. desc })
end end
-- Standard LSP functions
map("<leader>rn", vim.lsp.buf.rename, "[R]e[n]ame") map("<leader>rn", vim.lsp.buf.rename, "[R]e[n]ame")
map("<leader>ca", vim.lsp.buf.code_action, "[C]ode [A]ction", { "n", "x" }) map("<leader>ca", vim.lsp.buf.code_action, "[C]ode [A]ction", { "n", "x" })
map("gD", vim.lsp.buf.declaration, "[G]oto [D]eclaration") map("gD", vim.lsp.buf.declaration, "[G]oto [D]eclaration")
map("K", vim.lsp.buf.hover, "Hover Documentation") map("K", function()
vim.lsp.buf.hover(lsp_float)
end, "Hover Documentation")
map("<C-s>", function()
vim.lsp.buf.signature_help(lsp_float)
end, "Signature Help", { "i", "s" })
-- Telescope Mappings map("gd", telescope_picker("lsp_definitions"), "[G]oto [D]efinition")
map("gd", require("telescope.builtin").lsp_definitions, "[G]oto [D]efinition") map("gr", telescope_picker("lsp_references"), "[G]oto [R]eferences")
map("gr", require("telescope.builtin").lsp_references, "[G]oto [R]eferences") map("gI", telescope_picker("lsp_implementations"), "[G]oto [I]mplementation")
map("gI", require("telescope.builtin").lsp_implementations, "[G]oto [I]mplementation") map("<leader>D", telescope_picker("lsp_type_definitions"), "Type [D]efinition")
map("<leader>D", require("telescope.builtin").lsp_type_definitions, "Type [D]efinition") map("<leader>ds", telescope_picker("lsp_document_symbols"), "[D]ocument [S]ymbols")
map("<leader>ds", require("telescope.builtin").lsp_document_symbols, "[D]ocument [S]ymbols") map("<leader>ws", telescope_picker("lsp_dynamic_workspace_symbols"), "[W]orkspace [S]ymbols")
map("<leader>ws", require("telescope.builtin").lsp_dynamic_workspace_symbols, "[W]orkspace [S]ymbols")
if client and client:supports_method("textDocument/documentSymbol", bufnr) and navic_enabled(bufnr) then
require("lz.n").trigger_load("nvim-navic")
local ok, navic = pcall(require, "nvim-navic")
if ok then
navic.attach(client, bufnr)
vim.b[bufnr].lux_navic_attached = true
update_winbars_for_buffer(bufnr)
end
end
-- Highlight references (Document Highlight)
if client and client:supports_method("textDocument/documentHighlight", bufnr) then if client and client:supports_method("textDocument/documentHighlight", bufnr) then
local highlight_augroup = vim.api.nvim_create_augroup("kickstart-lsp-highlight", { clear = false }) local highlight_augroup = vim.api.nvim_create_augroup("lux-lsp-highlight", { clear = false })
vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, { vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, {
buffer = bufnr, buffer = bufnr,
group = highlight_augroup, group = highlight_augroup,
@@ -75,15 +148,14 @@ require("lz.n").load({
}) })
vim.api.nvim_create_autocmd("LspDetach", { vim.api.nvim_create_autocmd("LspDetach", {
group = vim.api.nvim_create_augroup("kickstart-lsp-detach", { clear = true }), group = vim.api.nvim_create_augroup("lux-lsp-detach", { clear = true }),
callback = function(event) callback = function(event)
vim.lsp.buf.clear_references() vim.lsp.buf.clear_references()
vim.api.nvim_clear_autocmds({ group = "kickstart-lsp-highlight", buffer = event.buf }) vim.api.nvim_clear_autocmds({ group = "lux-lsp-highlight", buffer = event.buf })
end, end,
}) })
end end
-- Inlay Hints
if client and client:supports_method("textDocument/inlayHint", bufnr) then if client and client:supports_method("textDocument/inlayHint", bufnr) then
vim.lsp.inlay_hint.enable(true, { bufnr = bufnr }) vim.lsp.inlay_hint.enable(true, { bufnr = bufnr })
map("<leader>th", function() map("<leader>th", function()
@@ -93,10 +165,9 @@ require("lz.n").load({
end, end,
}) })
-- 1. Setup Diagnostics (Visuals)
vim.diagnostic.config({ vim.diagnostic.config({
severity_sort = true, severity_sort = true,
-- underline = { severity = vim.diagnostic.severity.ERROR }, underline = true,
signs = { signs = {
text = { text = {
[vim.diagnostic.severity.ERROR] = "", [vim.diagnostic.severity.ERROR] = "",
@@ -105,19 +176,13 @@ require("lz.n").load({
[vim.diagnostic.severity.HINT] = "󰠠 ", [vim.diagnostic.severity.HINT] = "󰠠 ",
}, },
}, },
virtual_text = { virtual_text = false,
virtual_lines = {
current_line = true,
},
float = {
border = "single",
source = "if_many", source = "if_many",
spacing = 4,
prefix = "",
format = function(diagnostic)
local diagnostic_message = {
[vim.diagnostic.severity.ERROR] = diagnostic.message,
[vim.diagnostic.severity.WARN] = diagnostic.message,
[vim.diagnostic.severity.INFO] = diagnostic.message,
[vim.diagnostic.severity.HINT] = diagnostic.message,
}
return diagnostic_message[diagnostic.severity]
end,
}, },
}) })
@@ -126,7 +191,7 @@ require("lz.n").load({
Lua = { Lua = {
runtime = { version = "LuaJIT" }, runtime = { version = "LuaJIT" },
signatureHelp = { enabled = true }, signatureHelp = { enabled = true },
diagnostics = { globals = { "nixCats", "vim" } }, diagnostics = { globals = { "vim" } },
telemetry = { enabled = false }, telemetry = { enabled = false },
completion = { callSnippet = "Replace" }, completion = { callSnippet = "Replace" },
}, },
@@ -136,7 +201,6 @@ require("lz.n").load({
local settings = require("nix-info").settings local settings = require("nix-info").settings
-- Nix
vim.lsp.config("nixd", { vim.lsp.config("nixd", {
settings = { settings = {
nixd = { nixd = {
@@ -151,19 +215,11 @@ require("lz.n").load({
}) })
vim.lsp.enable("nixd") vim.lsp.enable("nixd")
-- Dafny
vim.lsp.enable("dafny") vim.lsp.enable("dafny")
-- TypeScript/JS
vim.lsp.enable("ts_ls") vim.lsp.enable("ts_ls")
-- Rust
vim.lsp.enable("rust_analyzer") vim.lsp.enable("rust_analyzer")
-- Python
vim.lsp.enable("ty") vim.lsp.enable("ty")
vim.lsp.enable("ruff") vim.lsp.enable("ruff")
vim.lsp.enable("astro") vim.lsp.enable("astro")
vim.lsp.config("tinymist", { vim.lsp.config("tinymist", {
@@ -186,6 +242,9 @@ require("lz.n").load({
after = function() after = function()
require("trouble").setup({ require("trouble").setup({
focus = true, focus = true,
preview = {
border = "single",
},
}) })
end, end,
}, },
@@ -0,0 +1,111 @@
local telescope_plugins = {
"project.nvim",
"telescope.nvim",
"telescope-fzf-native.nvim",
"telescope-ui-select.nvim",
}
local function load_telescope()
require("lz.n").trigger_load(telescope_plugins)
return require("telescope.builtin")
end
local function map_picker(lhs, picker, desc, opts)
vim.keymap.set("n", lhs, function()
load_telescope()[picker](opts or {})
end, { desc = desc })
end
map_picker("<leader>sh", "help_tags", "[S]earch [H]elp")
map_picker("<leader>sk", "keymaps", "[S]earch [K]eymaps")
map_picker("<leader>sf", "find_files", "[S]earch [F]iles")
map_picker("<leader>ss", "builtin", "[S]earch [S]elect Telescope")
map_picker("<leader>sw", "grep_string", "[S]earch current [W]ord")
map_picker("<leader>sg", "live_grep", "[S]earch by [G]rep")
map_picker("<leader>sd", "diagnostics", "[S]earch [D]iagnostics")
map_picker("<leader>sr", "resume", "[S]earch [R]esume")
map_picker("<leader>s.", "oldfiles", '[S]earch Recent Files ("." for repeat)')
map_picker("<leader><leader>", "buffers", "[ ] Find existing buffers")
map_picker("<leader>sn", "find_files", "[S]earch [N]eovim files", { cwd = vim.fn.stdpath("config") })
vim.keymap.set("n", "<leader>sp", function()
load_telescope()
require("telescope").extensions.projects.projects({})
end, { desc = "[S]earch [P]rojects" })
vim.keymap.set("n", "<leader>/", function()
local builtin = load_telescope()
builtin.current_buffer_fuzzy_find(require("telescope.themes").get_dropdown({
winblend = 10,
previewer = false,
}))
end, { desc = "[/] Fuzzily search in current buffer" })
vim.keymap.set("n", "<leader>s/", function()
load_telescope().live_grep({
grep_open_files = true,
prompt_title = "Live Grep in Open Files",
})
end, { desc = "[S]earch [/] in Open Files" })
require("lz.n").load({
{
"project.nvim",
event = "VimEnter",
after = function()
require("project").setup({
manual_mode = false,
lsp = { enabled = true },
patterns = { ".git", "_darcs", ".hg", ".bzr", ".svn", "Makefile", "package.json", "flake.nix" },
show_hidden = true,
scope_chdir = "global",
})
end,
},
{
"telescope-fzf-native.nvim",
},
{
"telescope-ui-select.nvim",
},
{
"telescope.nvim",
cmd = "Telescope",
before = function()
require("lz.n").trigger_load("project.nvim")
end,
after = function()
local actions = require("telescope.actions")
require("telescope").setup({
defaults = {
path_display = { "truncate" },
border = true,
borderchars = { "", "", "", "", "", "", "", "" },
layout_strategy = "horizontal",
layout_config = {
prompt_position = "top",
},
sorting_strategy = "ascending",
mappings = {
i = {
["<C-k>"] = actions.move_selection_previous,
["<C-j>"] = actions.move_selection_next,
["<C-q>"] = actions.send_selected_to_qflist + actions.open_qflist,
},
},
},
extensions = {
["ui-select"] = {
require("telescope.themes").get_dropdown(),
},
},
})
require("lz.n").trigger_load({ "telescope-fzf-native.nvim", "telescope-ui-select.nvim" })
pcall(require("telescope").load_extension, "projects")
pcall(require("telescope").load_extension, "fzf")
pcall(require("telescope").load_extension, "ui-select")
end,
},
})
@@ -0,0 +1,201 @@
require("lz.n").load({
{
"theme-loader",
event = "VimEnter",
load = function()
local settings = require("nix-info").settings
local theme_code = settings.themeSetup
local func, err = loadstring(theme_code)
if func then
func()
else
print("Error loading theme code: " .. err)
end
end,
},
{
"kulala.nvim",
after = function()
require("kulala").setup({
global_keymaps = true,
global_keymaps_prefix = "<leader>R",
})
end,
},
{
"lualine.nvim",
event = "VimEnter",
after = function()
local filename = {
"filename",
path = 1,
symbols = {
modified = "",
readonly = "",
unnamed = "[No Name]",
},
}
require("lualine").setup({
options = {
icons_enabled = true,
globalstatus = false,
component_separators = "",
section_separators = "",
theme = "kanagawa",
},
sections = {
lualine_a = { "mode" },
lualine_b = { "branch", "diff", "diagnostics" },
lualine_c = { filename },
lualine_x = { "lsp_status" },
lualine_y = { "progress" },
lualine_z = { "location" },
},
inactive_sections = {
lualine_a = {},
lualine_b = {},
lualine_c = { filename },
lualine_x = {},
lualine_y = {},
lualine_z = {},
},
})
end,
},
{
"bufferline.nvim",
event = "VimEnter",
before = function()
require("lz.n").trigger_load("mini.nvim")
end,
after = function()
require("bufferline").setup({
options = {
mode = "buffers",
numbers = "none",
diagnostics = "nvim_lsp",
diagnostics_indicator = function(count, level)
local icon = level:match("error") and "" or level:match("warning") and "" or ""
return " " .. icon .. count
end,
always_show_bufferline = true,
show_buffer_close_icons = false,
show_close_icon = false,
separator_style = "thin",
sort_by = "insert_after_current",
offsets = {
{
filetype = "minifiles",
text = "Files",
separator = true,
},
},
},
})
vim.keymap.set("n", "<C-0>", "<cmd>BufferLineCycleNext<cr>", { desc = "[B]uffer [N]ext" })
vim.keymap.set("n", "<C-9>", "<cmd>BufferLineCyclePrev<cr>", { desc = "[B]uffer [P]revious" })
vim.keymap.set("n", "<leader>bb", "<cmd>BufferLinePick<cr>", { desc = "[B]uffer [B]rowse" })
vim.keymap.set("n", "<leader>bd", "<cmd>bdelete<cr>", { desc = "[B]uffer [D]elete" })
end,
},
{
"gitsigns.nvim",
event = { "BufReadPre", "BufNewFile" },
after = function()
require("gitsigns").setup({
signs = {
add = { text = "" },
change = { text = "" },
delete = { text = "_" },
topdelete = { text = "" },
changedelete = { text = "~" },
untracked = { text = "" },
},
signs_staged_enable = true,
on_attach = function(bufnr)
local gs = package.loaded.gitsigns
local map = function(mode, lhs, rhs, desc, opts)
opts = opts or {}
opts.buffer = bufnr
opts.desc = desc
vim.keymap.set(mode, lhs, rhs, opts)
end
map("n", "]h", function()
if vim.wo.diff then
return "]h"
end
vim.schedule(function()
gs.nav_hunk("next")
end)
return "<Ignore>"
end, "Next git hunk", { expr = true })
map("n", "[h", function()
if vim.wo.diff then
return "[h"
end
vim.schedule(function()
gs.nav_hunk("prev")
end)
return "<Ignore>"
end, "Previous git hunk", { expr = true })
map("n", "<leader>hp", gs.preview_hunk, "Git [H]unk [P]review")
map("n", "<leader>hs", gs.stage_hunk, "Git [H]unk [S]tage")
map("n", "<leader>hr", gs.reset_hunk, "Git [H]unk [R]eset")
map("n", "<leader>hu", gs.undo_stage_hunk, "Git [H]unk [U]ndo stage")
map("n", "<leader>hS", gs.stage_buffer, "Git [H]unk [S]tage buffer")
map("n", "<leader>hR", gs.reset_buffer, "Git [H]unk [R]eset buffer")
map("v", "<leader>hs", function()
gs.stage_hunk({ vim.fn.line("."), vim.fn.line("v") })
end, "Git [H]unk [S]tage")
map("v", "<leader>hr", function()
gs.reset_hunk({ vim.fn.line("."), vim.fn.line("v") })
end, "Git [H]unk [R]eset")
end,
})
end,
},
{
"zen-mode.nvim",
cmd = "ZenMode",
after = function()
require("zen-mode").setup({
window = {
options = {
linebreak = true,
},
},
})
end,
},
{
"which-key.nvim",
event = "VimEnter",
before = function()
require("lz.n").trigger_load("mini.nvim")
end,
after = function()
require("which-key").setup({
preset = "modern",
delay = 200,
icons = {
mappings = true,
keys = {},
},
spec = {
{ "<leader>b", group = "[B]uffer" },
{ "<leader>s", group = "[S]earch" },
{ "<leader>t", group = "[T]oggle" },
{ "<leader>h", group = "Git [H]unk", mode = { "n", "v" } },
},
})
end,
},
})
+23
View File
@@ -0,0 +1,23 @@
{ config, ... }:
let
nixosModules = config.flake.modules.nixos;
in
{
flake.modules.nixos.nftables-firewall = {
networking.nftables.enable = true;
};
flake.modules.nixos.network-manager = {
networking.networkmanager.enable = true;
};
flake.modules.nixos.server-firewall =
{ ... }:
{
imports = [
nixosModules.nftables-firewall
];
networking.firewall.allowPing = false;
};
}
@@ -1,21 +1,51 @@
{ {
browserCommand,
launcherCommand,
shortcutCommands,
terminalCommand,
}:
{
# Application and utility launchers
"Mod+Return" = { "Mod+Return" = {
action.spawn = "kitty"; action.spawn = terminalCommand;
hotkey-overlay.title = "Terminal"; hotkey-overlay.title = "Terminal";
}; };
"Mod+B" = { "Mod+B" = {
action.spawn = "vivaldi"; action.spawn = browserCommand;
hotkey-overlay.title = "Browser"; hotkey-overlay.title = "Browser";
}; };
"Mod+Space" = { "Mod+Space" = {
repeat = false; repeat = false;
action.spawn = [ action.spawn = launcherCommand;
"vicinae"
"toggle"
];
hotkey-overlay.title = "App Launcher"; hotkey-overlay.title = "App Launcher";
}; };
"Mod+E" = {
repeat = false;
action.spawn = shortcutCommands.neovimProjects;
hotkey-overlay.title = "Neovim Projects";
};
"Mod+Ctrl+Return" = {
repeat = false;
action.spawn = shortcutCommands.nixosTerminal;
hotkey-overlay.title = "NixOS Config Terminal";
};
"Mod+Ctrl+Shift+Return" = {
repeat = false;
action.spawn = shortcutCommands.nixosSwitch;
hotkey-overlay.title = "NixOS Switch";
};
"Mod+Ctrl+E" = {
repeat = false;
action.spawn = shortcutCommands.editSecrets;
hotkey-overlay.title = "Edit Secrets";
};
"Mod+Ctrl+C" = {
repeat = false;
action.spawn = shortcutCommands.pickColor;
hotkey-overlay.title = "Pick Color";
};
# Hardware media, volume, and brightness keys
"XF86AudioPlay" = { "XF86AudioPlay" = {
action.spawn-sh = "playerctl play-pause"; action.spawn-sh = "playerctl play-pause";
allow-when-locked = true; allow-when-locked = true;
@@ -49,31 +79,34 @@
allow-when-locked = true; allow-when-locked = true;
}; };
"XF86MonBrightnessUp" = { "XF86MonBrightnessUp" = {
action.spawn-sh = "brightnessctl s 10%+"; action.spawn-sh = "brightnessctl s 5%+";
allow-when-locked = true; allow-when-locked = true;
}; };
"XF86MonBrightnessDown" = { "XF86MonBrightnessDown" = {
action.spawn-sh = "brightnessctl s 10%-"; action.spawn-sh = "brightnessctl s 5%-";
allow-when-locked = true; allow-when-locked = true;
}; };
# Screenshots
"Mod+S".action.screenshot = [ ]; "Mod+S".action.screenshot = [ ];
"Mod+Ctrl+S".action.screenshot-screen = [ ]; "Mod+Ctrl+S".action.screenshot-screen = [ ];
"Mod+Alt+S".action.screenshot-window = [ ]; "Mod+Alt+S".action.screenshot-window = [ ];
# Session and compositor controls
"Mod+Shift+Slash".action.show-hotkey-overlay = [ ]; "Mod+Shift+Slash".action.show-hotkey-overlay = [ ];
"Mod+Escape" = { "Mod+Escape" = {
action.toggle-keyboard-shortcuts-inhibit = [ ]; action.toggle-keyboard-shortcuts-inhibit = [ ];
allow-inhibiting = false; allow-inhibiting = false;
}; };
"Mod+Alt+L" = { "Mod+Ctrl+L" = {
action.spawn-sh = "loginctl lock-session"; action.spawn-sh = "loginctl lock-session";
hotkey-overlay.title = "Lock Screen"; hotkey-overlay.title = "Lock Screen";
}; };
"Mod+Shift+E".action.quit = [ ]; "Mod+Ctrl+Shift+Q".action.quit = [ ];
"Ctrl+Alt+Delete".action.quit = [ ]; "Ctrl+Alt+Delete".action.quit = [ ];
"Mod+Shift+P".action.power-off-monitors = [ ]; "Mod+Shift+P".action.power-off-monitors = [ ];
# Overview and window close
"Mod+O" = { "Mod+O" = {
action.toggle-overview = [ ]; action.toggle-overview = [ ];
repeat = false; repeat = false;
@@ -83,58 +116,66 @@
repeat = false; repeat = false;
}; };
# Keyboard focus movement
"Mod+Left".action.focus-column-or-monitor-left = [ ];
"Mod+Down".action.focus-window-down = [ ];
"Mod+Up".action.focus-window-up = [ ];
"Mod+Right".action.focus-column-or-monitor-right = [ ];
"Mod+H".action.focus-column-or-monitor-left = [ ]; "Mod+H".action.focus-column-or-monitor-left = [ ];
"Mod+J".action.focus-window-down = [ ]; "Mod+J".action.focus-window-down = [ ];
"Mod+K".action.focus-window-up = [ ]; "Mod+K".action.focus-window-up = [ ];
"Mod+L".action.focus-column-or-monitor-right = [ ]; "Mod+L".action.focus-column-or-monitor-right = [ ];
"Mod+Ctrl+Left".action.move-column-left = [ ]; # Keyboard window and column movement
"Mod+Ctrl+Down".action.move-window-down = [ ]; "Mod+Alt+Left".action.move-column-left-or-to-monitor-left = [ ];
"Mod+Ctrl+Up".action.move-window-up = [ ]; "Mod+Alt+Down".action.move-window-down-or-to-workspace-down = [ ];
"Mod+Ctrl+Right".action.move-column-right = [ ]; "Mod+Alt+Up".action.move-window-up-or-to-workspace-up = [ ];
"Mod+Ctrl+H".action.move-column-left = [ ]; "Mod+Alt+Right".action.move-column-right-or-to-monitor-right = [ ];
"Mod+Ctrl+J".action.move-window-down = [ ]; "Mod+Alt+H".action.move-column-left-or-to-monitor-left = [ ];
"Mod+Ctrl+K".action.move-window-up = [ ]; "Mod+Alt+J".action.move-window-down-or-to-workspace-down = [ ];
"Mod+Ctrl+L".action.move-column-right = [ ]; "Mod+Alt+K".action.move-window-up-or-to-workspace-up = [ ];
"Mod+Alt+L".action.move-column-right-or-to-monitor-right = [ ];
# First and last column navigation
"Mod+Home".action.focus-column-first = [ ]; "Mod+Home".action.focus-column-first = [ ];
"Mod+End".action.focus-column-last = [ ]; "Mod+End".action.focus-column-last = [ ];
"Mod+Ctrl+Home".action.move-column-to-first = [ ]; "Mod+Alt+Home".action.move-column-to-first = [ ];
"Mod+Ctrl+End".action.move-column-to-last = [ ]; "Mod+Alt+End".action.move-column-to-last = [ ];
# Move focus, columns, and workspaces across monitors
"Mod+Tab".action.focus-monitor-next = [ ];
"Mod+A" = {
repeat = false;
action.spawn = shortcutCommands.swapMonitorWorkspaces;
hotkey-overlay.title = "Swap Monitor Workspaces";
};
"Mod+Alt+Tab".action.move-column-to-monitor-next = [ ];
"Mod+Shift+Tab".action.move-workspace-to-monitor-next = [ ];
"Mod+Shift+Left".action.focus-monitor-left = [ ]; "Mod+Shift+Left".action.focus-monitor-left = [ ];
"Mod+Shift+Down".action.focus-monitor-down = [ ]; "Mod+Shift+Down".action.focus-monitor-down = [ ];
"Mod+Shift+Up".action.focus-monitor-up = [ ]; "Mod+Shift+Up".action.focus-monitor-up = [ ];
"Mod+Shift+Right".action.focus-monitor-right = [ ]; "Mod+Shift+Right".action.focus-monitor-right = [ ];
"Mod+Shift+H".action.focus-monitor-left = [ ];
"Mod+Shift+J".action.focus-monitor-down = [ ];
"Mod+Shift+K".action.focus-monitor-up = [ ];
"Mod+Shift+L".action.focus-monitor-right = [ ];
"Mod+Shift+Ctrl+Left".action.move-column-to-monitor-left = [ ];
"Mod+Shift+Ctrl+Down".action.move-column-to-monitor-down = [ ];
"Mod+Shift+Ctrl+Up".action.move-column-to-monitor-up = [ ];
"Mod+Shift+Ctrl+Right".action.move-column-to-monitor-right = [ ];
"Mod+Shift+Ctrl+H".action.move-column-to-monitor-left = [ ];
"Mod+Shift+Ctrl+J".action.move-column-to-monitor-down = [ ];
"Mod+Shift+Ctrl+K".action.move-column-to-monitor-up = [ ];
"Mod+Shift+Ctrl+L".action.move-column-to-monitor-right = [ ];
# Linear workspace navigation
"Mod+Page_Down".action.focus-workspace-down = [ ]; "Mod+Page_Down".action.focus-workspace-down = [ ];
"Mod+Page_Up".action.focus-workspace-up = [ ]; "Mod+Page_Up".action.focus-workspace-up = [ ];
"Mod+U".action.focus-workspace-down = [ ]; "Mod+U".action.focus-workspace-down = [ ];
"Mod+I".action.focus-workspace-up = [ ]; "Mod+I".action.focus-workspace-up = [ ];
"Mod+Ctrl+Page_Down".action.move-column-to-workspace-down = [ ]; # Move columns between adjacent workspaces
"Mod+Ctrl+Page_Up".action.move-column-to-workspace-up = [ ]; "Mod+Alt+Page_Down".action.move-column-to-workspace-down = [ ];
"Mod+Ctrl+U".action.move-column-to-workspace-down = [ ]; "Mod+Alt+Page_Up".action.move-column-to-workspace-up = [ ];
"Mod+Ctrl+I".action.move-column-to-workspace-up = [ ]; "Mod+Alt+U".action.move-column-to-workspace-down = [ ];
"Mod+Alt+I".action.move-column-to-workspace-up = [ ];
# Reorder workspaces
"Mod+Shift+Page_Down".action.move-workspace-down = [ ]; "Mod+Shift+Page_Down".action.move-workspace-down = [ ];
"Mod+Shift+Page_Up".action.move-workspace-up = [ ]; "Mod+Shift+Page_Up".action.move-workspace-up = [ ];
"Mod+Shift+U".action.move-workspace-down = [ ]; "Mod+Shift+U".action.move-workspace-down = [ ];
"Mod+Shift+I".action.move-workspace-up = [ ]; "Mod+Shift+I".action.move-workspace-up = [ ];
# Mouse workspace navigation
"Mod+WheelScrollDown" = { "Mod+WheelScrollDown" = {
action.focus-workspace-down = [ ]; action.focus-workspace-down = [ ];
cooldown-ms = 150; cooldown-ms = 150;
@@ -143,24 +184,24 @@
action.focus-workspace-up = [ ]; action.focus-workspace-up = [ ];
cooldown-ms = 150; cooldown-ms = 150;
}; };
"Mod+Ctrl+WheelScrollDown" = { "Mod+Alt+WheelScrollDown" = {
action.move-column-to-workspace-down = [ ]; action.move-column-to-workspace-down = [ ];
cooldown-ms = 150; cooldown-ms = 150;
}; };
"Mod+Ctrl+WheelScrollUp" = { "Mod+Alt+WheelScrollUp" = {
action.move-column-to-workspace-up = [ ]; action.move-column-to-workspace-up = [ ];
cooldown-ms = 150; cooldown-ms = 150;
}; };
"Mod+WheelScrollRight".action.focus-column-right = [ ]; # Mouse column navigation and movement
"Mod+WheelScrollLeft".action.focus-column-left = [ ]; "Mod+WheelScrollRight".action.focus-column-or-monitor-right = [ ];
"Mod+Ctrl+WheelScrollRight".action.move-column-right = [ ]; "Mod+WheelScrollLeft".action.focus-column-or-monitor-left = [ ];
"Mod+Ctrl+WheelScrollLeft".action.move-column-left = [ ]; "Mod+Alt+WheelScrollRight".action.move-column-right-or-to-monitor-right = [ ];
"Mod+Shift+WheelScrollDown".action.focus-column-right = [ ]; "Mod+Alt+WheelScrollLeft".action.move-column-left-or-to-monitor-left = [ ];
"Mod+Shift+WheelScrollUp".action.focus-column-left = [ ]; "Mod+Shift+WheelScrollDown".action.focus-column-or-monitor-right = [ ];
"Mod+Ctrl+Shift+WheelScrollDown".action.move-column-right = [ ]; "Mod+Shift+WheelScrollUp".action.focus-column-or-monitor-left = [ ];
"Mod+Ctrl+Shift+WheelScrollUp".action.move-column-left = [ ];
# Direct workspace focus
"Mod+1".action.focus-workspace = 1; "Mod+1".action.focus-workspace = 1;
"Mod+2".action.focus-workspace = 2; "Mod+2".action.focus-workspace = 2;
"Mod+3".action.focus-workspace = 3; "Mod+3".action.focus-workspace = 3;
@@ -171,6 +212,7 @@
"Mod+8".action.focus-workspace = 8; "Mod+8".action.focus-workspace = 8;
"Mod+9".action.focus-workspace = 9; "Mod+9".action.focus-workspace = 9;
# Move columns to numbered workspaces
"Mod+Ctrl+1".action.move-column-to-workspace = 1; "Mod+Ctrl+1".action.move-column-to-workspace = 1;
"Mod+Ctrl+2".action.move-column-to-workspace = 2; "Mod+Ctrl+2".action.move-column-to-workspace = 2;
"Mod+Ctrl+3".action.move-column-to-workspace = 3; "Mod+Ctrl+3".action.move-column-to-workspace = 3;
@@ -181,27 +223,34 @@
"Mod+Ctrl+8".action.move-column-to-workspace = 8; "Mod+Ctrl+8".action.move-column-to-workspace = 8;
"Mod+Ctrl+9".action.move-column-to-workspace = 9; "Mod+Ctrl+9".action.move-column-to-workspace = 9;
# Add and remove windows from columns
"Mod+BracketLeft".action.consume-or-expel-window-left = [ ]; "Mod+BracketLeft".action.consume-or-expel-window-left = [ ];
"Mod+BracketRight".action.consume-or-expel-window-right = [ ]; "Mod+BracketRight".action.consume-or-expel-window-right = [ ];
"Mod+Comma".action.consume-window-into-column = [ ]; "Mod+Comma".action.consume-window-into-column = [ ];
"Mod+Period".action.expel-window-from-column = [ ]; "Mod+Period".action.expel-window-from-column = [ ];
# Column and window presentation modes
"Mod+R".action.switch-preset-column-width = [ ]; "Mod+R".action.switch-preset-column-width = [ ];
"Mod+Shift+R".action.switch-preset-window-height = [ ]; "Mod+Shift+R".action.switch-preset-column-width-back = [ ];
"Mod+Ctrl+R".action.reset-window-height = [ ]; "Mod+Ctrl+R".action.reset-window-height = [ ];
"Mod+Ctrl+Shift+R".action.switch-preset-window-height = [ ];
"Mod+F".action.maximize-column = [ ]; "Mod+F".action.maximize-column = [ ];
"Mod+Shift+F".action.fullscreen-window = [ ]; "Mod+Shift+F".action.fullscreen-window = [ ];
"Mod+M".action.maximize-window-to-edges = [ ]; "Mod+M".action.maximize-window-to-edges = [ ];
"Mod+Ctrl+F".action.expand-column-to-available-width = [ ];
"Mod+C".action.center-column = [ ]; "Mod+C".action.center-column = [ ];
"Mod+Ctrl+C".action.center-visible-columns = [ ];
# Manual column width and window height adjustments
"Mod+Shift+H".action.set-column-width = "-10%";
"Mod+Shift+L".action.set-column-width = "+10%";
"Mod+Shift+J".action.set-window-height = "+10%";
"Mod+Shift+K".action.set-window-height = "-10%";
"Mod+Minus".action.set-column-width = "-10%"; "Mod+Minus".action.set-column-width = "-10%";
"Mod+Equal".action.set-column-width = "+10%"; "Mod+Equal".action.set-column-width = "+10%";
"Mod+Shift+Minus".action.set-window-height = "-10%"; "Mod+Shift+Minus".action.set-window-height = "-10%";
"Mod+Shift+Equal".action.set-window-height = "+10%"; "Mod+Shift+Equal".action.set-window-height = "+10%";
"Mod+V".action.toggle-window-floating = [ ]; # Floating and tabbed layout toggles
"Mod+Alt+V".action.toggle-window-floating = [ ];
"Mod+Shift+V".action.switch-focus-between-floating-and-tiling = [ ]; "Mod+Shift+V".action.switch-focus-between-floating-and-tiling = [ ];
"Mod+W".action.toggle-column-tabbed-display = [ ]; "Mod+W".action.toggle-column-tabbed-display = [ ];
} }
+146
View File
@@ -0,0 +1,146 @@
{
config,
lib,
pkgs,
repo,
}:
let
nixosConfigDir = repo.account.nixosConfigurationPath;
mkTerminalScript =
{
name,
workdir ? nixosConfigDir,
command ? null,
runtimeInputs ? [ ],
}:
let
args = lib.optionals (command != null) [
"--"
"${pkgs.bash}/bin/bash"
"-lc"
command
];
argString = lib.concatMapStringsSep " " lib.escapeShellArg args;
in
pkgs.writeShellApplication {
inherit name runtimeInputs;
checkPhase = "";
text = lib.concatStringsSep "\n" [
"# shellcheck disable=SC2016"
"cd ${lib.escapeShellArg workdir}"
"exec ${lib.escapeShellArg config.facts.desktop.terminalCommand} ${argString}"
];
};
in
rec {
scripts = {
nixosTerminal = mkTerminalScript {
name = "niri-shortcut-nixos-terminal";
};
nixosSwitch = mkTerminalScript {
name = "niri-shortcut-nixos-switch";
runtimeInputs = [
pkgs.coreutils
pkgs.nh
];
command = ''
set -o pipefail
log_dir="''${XDG_STATE_HOME:-$HOME/.local/state}/nixos-switch"
mkdir -p "$log_dir"
log="$log_dir/$(date +%Y%m%d-%H%M%S).log"
status_file="$(mktemp)"
printf 'Running nh os switch in %s\n\n' ${lib.escapeShellArg nixosConfigDir}
(
cd ${lib.escapeShellArg nixosConfigDir}
nh os switch
printf '%s' "$?" > "$status_file"
) 2>&1 | tee "$log"
status="$(cat "$status_file")"
rm -f "$status_file"
printf '\nLog: %s\n' "$log"
if [ "$status" -eq 0 ]; then
printf 'NixOS switch completed successfully.\n'
else
printf 'NixOS switch failed with exit code %s.\n' "$status"
fi
printf 'Press Enter to close...'
read -r _
exit "$status"
'';
};
editSecrets = mkTerminalScript {
name = "niri-shortcut-edit-secrets";
runtimeInputs = [ pkgs.sops ];
command = ''
sops edit ${lib.escapeShellArg "${nixosConfigDir}/modules/secrets/secrets.yaml"}
'';
};
neovimProjects = mkTerminalScript {
name = "niri-shortcut-neovim-projects";
command = ''
nvim -c 'Telescope projects'
'';
};
pickColor = pkgs.writeShellApplication {
name = "niri-shortcut-pick-color";
runtimeInputs = [
pkgs.libnotify
pkgs.niri
pkgs.wl-clipboard
];
text = ''
color="$(niri msg pick-color)"
printf '%s' "$color" | wl-copy
notify-send 'Color picked' "$color"
'';
};
swapMonitorWorkspaces = pkgs.writeShellApplication {
name = "niri-shortcut-swap-monitor-workspaces";
runtimeInputs = [
pkgs.jq
pkgs.niri
];
text = ''
focused_output="$(niri msg --json focused-output | jq -r '.name // empty')"
if [ -z "$focused_output" ]; then
exit 0
fi
niri msg action focus-monitor-next
target_output="$(niri msg --json focused-output | jq -r '.name // empty')"
if [ -z "$target_output" ] || [ "$target_output" = "$focused_output" ]; then
exit 0
fi
target_workspace_idx="$(
niri msg --json workspaces \
| jq -r --arg output "$target_output" '
first(.[] | select(.output == $output and .is_active) | .idx) // empty
'
)"
if [ -z "$target_workspace_idx" ]; then
niri msg action focus-monitor "$focused_output"
exit 0
fi
niri msg action focus-monitor "$focused_output"
niri msg action move-workspace-to-monitor "$target_output"
niri msg action focus-workspace "$target_workspace_idx"
niri msg action move-workspace-to-monitor "$focused_output"
'';
};
};
commands = lib.mapAttrs (_: lib.getExe) scripts;
}
+174
View File
@@ -0,0 +1,174 @@
{
inputs,
config,
...
}:
let
repo = config.repo;
hmModules = config.flake.modules.homeManager;
in
{
flake.modules.nixos.niri =
{ pkgs, ... }:
{
imports = [ inputs.niri.nixosModules.niri ];
home-manager.sharedModules = [ hmModules.niri ];
nixpkgs.overlays = [ inputs.niri.overlays.niri ];
programs = {
dconf.enable = true;
niri = {
enable = true;
package = pkgs.niri-unstable;
};
};
services = {
gvfs.enable = true;
udisks2.enable = true;
};
xdg.portal.enable = true;
};
flake.modules.homeManager.niri =
{
config,
lib,
osConfig,
pkgs,
...
}:
let
borderPalette = repo.theme.kanagawa.palette.niri.border;
shortcuts = import ./_shortcuts.nix {
inherit
config
lib
pkgs
repo
;
};
machine = osConfig.facts.machine;
in
{
home = {
sessionVariables.NIXOS_OZONE_WL = "1";
packages =
with pkgs;
[
playerctl
brightnessctl
xwayland-satellite
]
++ lib.attrValues shortcuts.scripts;
};
dconf.settings."org/gnome/desktop/interface".color-scheme = "prefer-dark";
programs.niri.settings = {
outputs = lib.mapAttrs (
_: display:
let
scale = display.scale or null;
width = display.width or null;
height = display.height or null;
refresh = display.refresh or null;
in
{
position = {
x = display.x or 0;
y = display.y or 0;
};
}
// lib.optionalAttrs (display.primary or false) {
"focus-at-startup" = true;
}
// lib.optionalAttrs (scale != null) {
inherit scale;
}
// lib.optionalAttrs (width != null && height != null && refresh != null) {
mode = {
inherit
width
height
refresh
;
};
}
) (machine.displays or { });
environment.DISPLAY = ":0";
spawn-at-startup = [
{ command = [ "xwayland-satellite" ]; }
{ command = [ "noctalia-shell" ]; }
];
prefer-no-csd = true;
hotkey-overlay.skip-at-startup = true;
screenshot-path = "${config.xdg.userDirs.pictures}/screenshots/%Y-%m-%dT%H:%M:%S.png";
animations.slowdown = 0.6;
cursor = {
inherit (config.home.pointerCursor) size;
theme = config.home.pointerCursor.name;
hide-after-inactive-ms = 3000;
hide-when-typing = true;
};
layout = {
always-center-single-column = true;
gaps = 14;
focus-ring.enable = false;
default-column-width.proportion = 1. / 2.;
border = {
enable = true;
width = 3;
active.color = borderPalette.active;
inactive.color = borderPalette.inactive;
urgent.color = borderPalette.urgent;
};
};
window-rules = [
{
geometry-corner-radius =
let
radius = 10.0;
in
{
bottom-left = radius;
bottom-right = radius;
top-left = radius;
top-right = radius;
};
clip-to-geometry = true;
}
];
debug.honor-xdg-activation-with-invalid-serial = true;
gestures.hot-corners.enable = false;
input = {
focus-follows-mouse.enable = true;
mouse."accel-speed" = 0.4;
keyboard = {
repeat-delay = 300;
repeat-rate = 50;
xkb.options = "caps:escape";
};
touchpad.dwt = true;
};
binds = import ./_bindings.nix {
browserCommand = config.facts.desktop.browserCommand;
launcherCommand = config.facts.desktop.launcherCommand;
terminalCommand = config.facts.desktop.terminalCommand;
shortcutCommands = shortcuts.commands;
};
};
};
}
@@ -1,6 +1,10 @@
{ inputs, config, ... }:
let
account = config.repo.account;
in
{ {
flake.modules.nixos.nix = flake.modules.nixos.nix =
{ inputs, ... }: { ... }:
{ {
nixpkgs.config.allowUnfree = true; nixpkgs.config.allowUnfree = true;
@@ -26,6 +30,10 @@
flake.modules.homeManager.nix = flake.modules.homeManager.nix =
{ pkgs, ... }: { pkgs, ... }:
{ {
imports = [
inputs.nix-index-database.homeModules.default
];
home.packages = [ home.packages = [
(pkgs.writeShellApplication { (pkgs.writeShellApplication {
name = "ns"; name = "ns";
@@ -37,6 +45,9 @@
}) })
]; ];
programs.nix-index.enableZshIntegration = false;
programs.nix-index-database.comma.enable = true;
programs.television = { programs.television = {
enable = true; enable = true;
enableZshIntegration = false; enableZshIntegration = false;
@@ -46,5 +57,10 @@
enable = true; enable = true;
enableTelevisionIntegration = true; enableTelevisionIntegration = true;
}; };
programs.nh = {
enable = true;
flake = account.nixosConfigurationPath;
};
}; };
} }
@@ -1,3 +1,8 @@
{
homeDirectory,
lib,
terminalCommand,
}:
{ {
settingsVersion = 53; settingsVersion = 53;
bar = { bar = {
@@ -98,7 +103,7 @@
screenOverrides = [ ]; screenOverrides = [ ];
}; };
general = { general = {
avatarImage = "/home/kiri/.face"; avatarImage = "${homeDirectory}/.face";
dimmerOpacity = 0; dimmerOpacity = 0;
showScreenCorners = false; showScreenCorners = false;
forceBlackScreenCorners = false; forceBlackScreenCorners = false;
@@ -209,7 +214,7 @@
wallpaper = { wallpaper = {
enabled = true; enabled = true;
overviewEnabled = false; overviewEnabled = false;
directory = "/home/kiri/media/images/wallpapers"; directory = "${homeDirectory}/media/images/wallpapers";
monitorDirectories = [ ]; monitorDirectories = [ ];
enableMultiMonitorDirectories = false; enableMultiMonitorDirectories = false;
showHiddenFiles = false; showHiddenFiles = false;
@@ -255,7 +260,7 @@
pinnedApps = [ ]; pinnedApps = [ ];
useApp2Unit = false; useApp2Unit = false;
sortByMostUsed = true; sortByMostUsed = true;
terminalCommand = "kitty -e"; inherit terminalCommand;
customLaunchPrefixEnabled = false; customLaunchPrefixEnabled = false;
customLaunchPrefix = ""; customLaunchPrefix = "";
viewMode = "grid"; viewMode = "grid";
@@ -453,9 +458,9 @@
notifications = { notifications = {
enabled = true; enabled = true;
enableMarkdown = false; enableMarkdown = false;
density = "default"; density = "compact";
monitors = [ ]; monitors = [ ];
location = "top_right"; location = "bottom_right";
overlayLayer = true; overlayLayer = true;
backgroundOpacity = 1; backgroundOpacity = 1;
respectExpireTimeout = false; respectExpireTimeout = false;
+92
View File
@@ -0,0 +1,92 @@
{
config,
lib,
...
}:
let
mkNoctaliaSettings =
{
homeDirectory,
lib,
terminalCommand,
}:
import ./_noctalia-config.nix {
inherit
homeDirectory
lib
terminalCommand
;
};
mkBaseSettings =
{
homeDirectory,
lib,
terminalCommand,
}:
mkNoctaliaSettings {
inherit
homeDirectory
lib
terminalCommand
;
};
mkPortableSettings =
baseSettings:
lib.recursiveUpdate baseSettings {
bar.widgets.right = lib.concatMap (
widget:
if widget.id == "ControlCenter" then
[
{
id = "Network";
}
{
id = "Battery";
showPowerProfiles = true;
displayMode = "graphic";
}
widget
]
else
[ widget ]
) baseSettings.bar.widgets.right;
};
in
{
flake.modules.homeManager.noctalia =
{
config,
inputs,
lib,
osConfig,
pkgs,
...
}:
let
baseSettings = mkBaseSettings {
inherit lib;
homeDirectory = config.home.homeDirectory;
terminalCommand = lib.getExe pkgs.xdg-terminal-exec;
};
settings =
if baseSettings == { } || !(osConfig.facts.machine.portable or false) then
baseSettings
else
mkPortableSettings baseSettings;
in
{
imports = [ inputs.noctalia.homeModules.default ];
programs.noctalia-shell = {
enable = true;
package = lib.mkForce (
inputs.noctalia.packages.${pkgs.stdenv.hostPlatform.system}.default.override {
calendarSupport = true;
}
);
inherit settings;
};
};
}
+28
View File
@@ -0,0 +1,28 @@
{
config,
...
}:
let
repo = config.repo;
account = repo.account;
in
{
flake.modules.homeManager.passwords =
{
pkgs,
...
}:
let
pinentryPackage = pkgs.pinentry-gnome3;
in
{
programs.rbw = {
enable = true;
settings = {
base_url = repo.services.vaultwarden.url;
email = account.primaryEmail.address;
pinentry = pinentryPackage;
};
};
};
}
+168
View File
@@ -0,0 +1,168 @@
{
config,
...
}:
let
repo = config.repo;
account = repo.account;
in
{
flake.modules.homeManager.email =
{
config,
lib,
...
}:
let
mkOffice365Account =
{
address,
primary ? false,
...
}:
{
enable = true;
inherit address primary;
realName = account.realName;
userName = address;
thunderbird = {
enable = true;
settings = id: {
"mail.smtpserver.smtp_${id}.authMethod" = 10;
"mail.server.server_${id}.authMethod" = 10;
};
};
flavor = "outlook.office365.com";
};
mkMxrouteAccount =
{
address,
primary ? false,
...
}:
{
enable = true;
inherit address primary;
realName = account.realName;
userName = address;
thunderbird.enable = true;
imap = {
authentication = "plain";
host = "taylor.mxrouting.net";
port = 993;
tls.enable = true;
};
smtp = {
authentication = "plain";
host = "taylor.mxrouting.net";
port = 465;
tls.enable = true;
};
};
mkEmailAccount =
email:
if email.type == "office365" then
mkOffice365Account email
else if email.type == "mxrouting" then
mkMxrouteAccount email
else
throw "Unsupported email type `${email.type}` for ${config.home.username}";
in
{
programs.thunderbird = {
enable = true;
profiles.${config.home.username} = {
isDefault = true;
withExternalGnupg = true;
settings = {
"mail.ui.display.message_pane_vertical" = true;
"mail.ui.display.thread_pane_view_type" = "cards";
"mail.uidensity" = 1;
"privacy.donottrackheader.enabled" = true;
"mail.server.server2.hidden" = true;
"mailnews.start_page.enabled" = false;
"mail.provider.enabled" = false;
"layout.css.devPixelsPerPx" = 0.85;
};
};
};
accounts.email.accounts = lib.mapAttrs (_: mkEmailAccount) account.emails;
};
flake.modules.homeManager.calendar-tasks =
{
config,
pkgs,
...
}:
let
calendarsPath = "${config.xdg.dataHome}/calendars";
in
{
programs.pimsync.enable = true;
services.pimsync.enable = true;
sops.secrets."radicale-pass" = { };
programs.khal = {
enable = true;
locale = {
timeformat = "%H:%M";
dateformat = "$m-$d";
};
};
programs.todoman = {
enable = true;
glob = "*/*";
extraConfig = ''
date_format = "%Y-%m-%d"
time_format = "%H:%M"
default_list = "personal"
default_due = 0
default_command = "list --sort priority,due"
humanize = True
'';
};
accounts.calendar = {
basePath = calendarsPath;
accounts.radicale = {
primary = true;
primaryCollection = "personal";
local = {
type = "filesystem";
fileExt = ".ics";
};
remote = {
url = repo.services.radicale.url;
type = "caldav";
userName = config.home.username;
passwordCommand = [
"${pkgs.coreutils}/bin/cat"
config.sops.secrets."radicale-pass".path
];
};
pimsync = {
enable = true;
extraPairDirectives = [
{
name = "collections";
params = [ "from b" ];
}
];
};
khal = {
enable = true;
type = "discover";
color = "light blue";
};
};
};
};
}
+24
View File
@@ -0,0 +1,24 @@
{ ... }:
{
flake.modules.nixos.plymouth =
{ pkgs, ... }:
{
boot = {
consoleLogLevel = 3;
initrd.verbose = false;
kernelParams = [
"quiet"
"udev.log_priority=3"
"rd.systemd.show_status=false"
"vt.global_cursor_default=0"
];
plymouth = {
enable = true;
theme = "spinner_alt";
themePackages = [ pkgs.adi1090x-plymouth-themes ];
};
};
};
}
+21
View File
@@ -0,0 +1,21 @@
{
flake.modules.nixos.sddm =
{
pkgs,
...
}:
{
services.displayManager.sddm = {
enable = true;
enableHidpi = true;
wayland.enable = true;
wayland.compositor = "kwin";
theme = "${
pkgs.sddm-astronaut.override { embeddedTheme = "purple_leaves"; }
}/share/sddm/themes/sddm-astronaut-theme";
extraPackages = with pkgs; [
kdePackages.qtmultimedia
];
};
};
}
+36
View File
@@ -0,0 +1,36 @@
{ config, ... }:
let
repo = config.repo;
repoHelpers = repo.helpers;
service = repo.services.actual;
in
{
repo.services.actual = {
domain = "finance.jelles.net";
host = "127.0.0.1";
port = 3000;
url = "https://finance.jelles.net";
};
flake.modules.nixos.actual =
{ lib, ... }:
lib.mkMerge [
{
services.actual = {
enable = true;
openFirewall = false;
settings = {
inherit (service) port;
hostname = service.host;
};
};
}
(repoHelpers.mkCaddyReverseProxy {
inherit (service)
domain
port
;
})
];
}
@@ -1,8 +1,12 @@
{ config, ... }:
let
repo = config.repo;
in
{ {
flake.modules.nixos.caddy = { flake.modules.nixos.caddy = {
services.caddy = { services.caddy = {
enable = true; enable = true;
email = "mail@jelles.net"; email = repo.account.primaryEmail.address;
openFirewall = true; openFirewall = true;
}; };
}; };
+49
View File
@@ -0,0 +1,49 @@
{ config, ... }:
let
repo = config.repo;
repoHelpers = repo.helpers;
service = repo.services.gitea;
in
{
repo.services.gitea = {
domain = "git.jelles.net";
host = "127.0.0.1";
port = 3001;
url = "https://git.jelles.net/";
};
flake.modules.nixos.gitea =
{ lib, ... }:
lib.mkMerge [
{
services.gitea = {
enable = true;
settings = {
server = {
DOMAIN = service.domain;
ROOT_URL = service.url;
HTTP_PORT = service.port;
HTTP_ADDR = service.host;
START_SSH_SERVER = false;
SSH_PORT = 22;
};
service.DISABLE_REGISTRATION = true;
};
};
}
{
services.openssh.settings.AllowUsers = [ "gitea" ];
}
(repoHelpers.mkCaddyReverseProxy {
inherit (service)
domain
port
;
})
];
}
+34
View File
@@ -0,0 +1,34 @@
{ config, lib, ... }:
let
account = config.repo.account;
personalPublicKeys =
machines:
map (machine: (machine.sshKeys or { }).personal.publicKey) (
lib.filter (machine: (machine.sshKeys or { }) ? personal) (builtins.attrValues machines)
);
in
{
flake.modules.nixos.sudo-ssh-agent-auth = {
security.pam = {
rssh.enable = true;
services.sudo.rssh = true;
};
};
flake.modules.nixos.openssh =
{ ... }:
{
services.openssh.openFirewall = true;
services.openssh = {
enable = true;
settings = {
PermitRootLogin = "no";
PasswordAuthentication = false;
AllowUsers = [ account.name ];
};
};
users.users.${account.name}.openssh.authorizedKeys.keys = personalPublicKeys config.repo.machines;
};
}
@@ -0,0 +1,56 @@
{ config, ... }:
let
repo = config.repo;
repoHelpers = repo.helpers;
service = repo.services.radicale;
in
{
repo.services.radicale = {
domain = "radicale.jelles.net";
host = "127.0.0.1";
port = 5232;
url = "https://radicale.jelles.net/";
};
flake.modules.nixos.radicale =
{ lib, ... }:
lib.mkMerge [
{
services.radicale = {
enable = true;
settings = {
server.hosts = [ "${service.host}:${toString service.port}" ];
auth = {
type = "htpasswd";
htpasswd_filename = "/var/lib/radicale/users";
htpasswd_encryption = "bcrypt";
};
storage.filesystem_folder = "/var/lib/radicale/collections";
};
};
}
(repoHelpers.mkCaddyReverseProxy {
inherit (service)
domain
port
;
extraHeaders = [
{
name = "X-Script-Name";
value = "/";
}
{
name = "X-Forwarded-For";
value = "{remote}";
}
{
name = "X-Remote-User";
value = "{http.auth.user.id}";
}
];
})
];
}
@@ -0,0 +1,28 @@
{ config, ... }:
let
account = config.repo.account;
in
{
flake.modules.nixos.transmission =
{ config, pkgs, ... }:
{
services.transmission = {
enable = true;
package = pkgs.transmission_4;
openPeerPorts = true;
downloadDirPermissions = "775";
settings = {
download-dir = "${account.homeDirectory}/torrents";
incomplete-dir = "${account.homeDirectory}/torrents/.incomplete";
peer-port = 43864;
umask = "002";
};
};
# NOTE: Upstream bug?
systemd.services.transmission-setup.requiredBy = [ "transmission.service" ];
users.users.${account.name}.extraGroups = [ config.services.transmission.group ];
};
}
@@ -0,0 +1,38 @@
{ config, ... }:
let
repo = config.repo;
repoHelpers = repo.helpers;
service = repo.services.vaultwarden;
in
{
repo.services.vaultwarden = {
domain = "vault.jelles.net";
host = "127.0.0.1";
port = 8100;
url = "https://vault.jelles.net";
};
flake.modules.nixos.vaultwarden =
{ lib, ... }:
lib.mkMerge [
{
services.vaultwarden = {
enable = true;
backupDir = "/var/backup/vaultwarden";
config = {
DOMAIN = service.url;
SIGNUPS_ALLOWED = false;
ROCKET_PORT = service.port;
ROCKET_LOG = "critical";
};
};
}
(repoHelpers.mkCaddyReverseProxy {
inherit (service)
domain
port
;
})
];
}
@@ -0,0 +1,215 @@
{ ... }:
{
flake.modules.nixos.vps-insights =
{ config, pkgs, ... }:
let
localAddress = "127.0.0.1";
grafanaDataDir = config.services.grafana.dataDir;
lokiDataDir = config.services.loki.dataDir;
lokiUrl = "http://${localAddress}:3100";
prometheusUrl = "http://${localAddress}:9090";
in
{
environment = {
etc."alloy/config.alloy".text = ''
loki.relabel "journal" {
forward_to = []
rule {
source_labels = ["__journal__systemd_unit"]
target_label = "unit"
}
rule {
source_labels = ["__journal_syslog_identifier"]
target_label = "syslog_identifier"
}
rule {
source_labels = ["__journal_priority_keyword"]
target_label = "level"
}
}
loki.source.journal "system" {
forward_to = [loki.write.local.receiver]
relabel_rules = loki.relabel.journal.rules
max_age = "24h"
labels = {
host = "${config.networking.hostName}",
}
}
loki.write "local" {
endpoint {
url = "${lokiUrl}/loki/api/v1/push"
}
}
'';
systemPackages = with pkgs; [
goaccess
lynis
];
};
services = {
# Keep local system logs available for Loki and manual inspection.
journald.extraConfig = ''
Storage=persistent
SystemMaxUse=1G
MaxRetentionSec=30day
'';
# Detect and block common attacks against SSH and Caddy.
crowdsec = {
enable = true;
hub.collections = [
"crowdsecurity/linux"
"crowdsecurity/caddy"
];
localConfig.acquisitions = [
{
source = "journalctl";
journalctl_filter = [ "_SYSTEMD_UNIT=sshd.service" ];
labels.type = "syslog";
}
{
filenames = [ "/var/log/caddy/*.log" ];
labels.type = "caddy";
}
];
};
crowdsec-firewall-bouncer = {
enable = true;
registerBouncer.bouncerName = "${config.networking.hostName}-firewall-bouncer";
};
# Grafana defaults to 127.0.0.1:3000; add secrets and datasources only.
grafana = {
enable = true;
settings = {
analytics.reporting_enabled = false;
security = {
admin_password = "$__file{${grafanaDataDir}/admin-password}";
secret_key = "$__file{${grafanaDataDir}/secret-key}";
};
};
provision.datasources.settings = {
prune = true;
datasources = [
{
name = "Prometheus";
type = "prometheus";
uid = "prometheus";
url = prometheusUrl;
isDefault = true;
}
{
name = "Loki";
type = "loki";
uid = "loki";
url = lokiUrl;
}
];
};
};
# Store local logs in Loki and feed them from journald through Alloy.
loki = {
enable = true;
configuration = {
analytics.reporting_enabled = false;
auth_enabled = false;
server = {
http_listen_address = localAddress;
http_listen_port = 3100;
grpc_listen_address = localAddress;
grpc_listen_port = 9096;
};
common = {
path_prefix = lokiDataDir;
replication_factor = 1;
instance_interface_names = [ "lo" ];
ring = {
instance_addr = localAddress;
kvstore.store = "inmemory";
};
};
schema_config.configs = [
{
from = "2025-01-01";
store = "tsdb";
object_store = "filesystem";
schema = "v13";
index = {
prefix = "index_";
period = "24h";
};
}
];
storage_config.filesystem.directory = "${lokiDataDir}/chunks";
compactor = {
working_directory = "${lokiDataDir}/compactor";
retention_enabled = true;
delete_request_store = "filesystem";
};
limits_config.retention_period = "720h";
};
};
alloy = {
enable = true;
extraFlags = [ "--server.http.listen-addr=${localAddress}:12345" ];
};
# Collect basic VPS health metrics for Grafana.
prometheus = {
enable = true;
listenAddress = localAddress;
retentionTime = "30d";
scrapeConfigs = [
{
job_name = "prometheus";
static_configs = [
{
targets = [ "${localAddress}:9090" ];
}
];
}
{
job_name = "node";
static_configs = [
{
targets = [ "${localAddress}:9100" ];
}
];
}
];
exporters.node = {
enable = true;
listenAddress = localAddress;
};
};
};
systemd.services.grafana.preStart = ''
umask 077
if [ ! -s ${grafanaDataDir}/admin-password ]; then
${pkgs.openssl}/bin/openssl rand -base64 32 > ${grafanaDataDir}/admin-password
fi
if [ ! -s ${grafanaDataDir}/secret-key ]; then
${pkgs.openssl}/bin/openssl rand -hex 32 > ${grafanaDataDir}/secret-key
fi
'';
};
}
@@ -1,6 +1,12 @@
{ {
flake.modules.homeManager.shell = flake.modules.homeManager.shell =
{ lib, config, ... }: {
lib,
config,
pkgs,
...
}:
{ {
home.sessionVariables = { home.sessionVariables = {
STARSHIP_CACHE = "${config.xdg.cacheHome}/starship"; STARSHIP_CACHE = "${config.xdg.cacheHome}/starship";
@@ -59,12 +65,21 @@
bindkey -v bindkey -v
export KEYTIMEOUT=1 export KEYTIMEOUT=1
setopt MENU_COMPLETE
zmodload zsh/complist
autoload -U history-search-end autoload -U history-search-end
zle -N history-beginning-search-backward-end history-search-end zle -N history-beginning-search-backward-end history-search-end
zle -N history-beginning-search-forward-end history-search-end zle -N history-beginning-search-forward-end history-search-end
bindkey "^[OA" history-beginning-search-backward-end bindkey "^[OA" history-beginning-search-backward-end
bindkey "^[OB" history-beginning-search-forward-end bindkey "^[OB" history-beginning-search-forward-end
if [[ -n "''${terminfo[kcbt]}" ]]; then
bindkey "''${terminfo[kcbt]}" reverse-menu-complete
bindkey -M menuselect "''${terminfo[kcbt]}" reverse-menu-complete
fi
bindkey "^[[Z" reverse-menu-complete
bindkey -M menuselect "^[[Z" reverse-menu-complete
bindkey -M menuselect "^[" send-break
zstyle ':completion:*' completer _extensions _complete _approximate zstyle ':completion:*' completer _extensions _complete _approximate
zstyle ':completion:*' use-cache on zstyle ':completion:*' use-cache on
@@ -73,7 +88,7 @@
zstyle ':completion:*' complete-options true zstyle ':completion:*' complete-options true
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*' zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*'
zstyle ':completion:*' keep-prefix true zstyle ':completion:*' keep-prefix true
zstyle ':completion:*' menu select zstyle ':completion:*' menu yes select=1
zstyle ':completion:*' list-grouped false zstyle ':completion:*' list-grouped false
zstyle ':completion:*' list-separator ''' zstyle ':completion:*' list-separator '''
zstyle ':completion:*' group-name ''' zstyle ':completion:*' group-name '''
@@ -111,7 +126,6 @@
"$directory" "$directory"
"$git_branch" "$git_branch"
"$git_state" "$git_state"
"$git_status"
"$line_break" "$line_break"
"$character" "$character"
]; ];
@@ -127,15 +141,6 @@
style = ""; style = "";
}; };
git_status = {
format = "[[(*$conflicted$untracked$modified$staged$renamed$deleted)](218)($ahead_behind$stashed)]($style)";
style = "cyan";
conflicted = "";
renamed = "";
deleted = "";
stashed = "";
};
git_state = { git_state = {
format = "([$state( $progress_current/$progress_total)]($style)) "; format = "([$state( $progress_current/$progress_total)]($style)) ";
style = "bright-black"; style = "bright-black";
@@ -145,10 +150,43 @@
}; };
}; };
programs.eza.enable = true; programs.eza = {
enable = true;
extraOptions = [ "--group-directories-first" ];
};
programs.zoxide = {
enable = true;
enableZshIntegration = true;
};
programs.fzf = { programs.fzf = {
enable = true; enable = true;
enableZshIntegration = true; enableZshIntegration = true;
}; };
programs.bottom.enable = true;
programs.yazi = {
enable = true;
shellWrapperName = "y";
};
home.packages = [
pkgs.fd
pkgs.bat
pkgs.tlrc
pkgs.sd
pkgs.procs
pkgs.dua
pkgs.duf
pkgs.systemctl-tui
pkgs.xh
];
services.tldr-update = {
enable = true;
package = pkgs.tlrc;
};
}; };
} }
@@ -1,5 +1,5 @@
{ {
flake.modules.homeManager.sshClient = flake.modules.homeManager.ssh-client =
{ config, ... }: { config, ... }:
{ {
programs.ssh = { programs.ssh = {
+66
View File
@@ -0,0 +1,66 @@
{
config,
lib,
...
}:
let
syncMachines = lib.listToAttrs (
lib.concatLists (
lib.mapAttrsToList (
machineName: machine:
let
syncthingId = machine.syncthingId or null;
in
lib.optional (syncthingId != null) (
let
name = "${config.repo.account.name}@${machineName}";
in
{
inherit name;
value = {
inherit name;
id = syncthingId;
};
}
)
) config.repo.machines
)
);
syncPhones = {
"pixel-10" = {
name = "pixel-10";
id = "MTJHEHA-UMZDQZ7-BTMRRLQ-Y7BFPUJ-ZTY6LZX-PDXV3IS-XVJCU7B-EPETBQZ";
};
};
syncDevices = syncMachines // syncPhones;
in
{
flake.modules.homeManager.syncthing =
{ ... }:
{
services.syncthing = {
enable = true;
overrideDevices = true;
overrideFolders = true;
settings = {
folders = {
sync = {
path = "~/sync";
label = "sync";
devices = builtins.attrNames syncDevices;
};
calibre = {
path = "~/calibre";
label = "calibre";
devices = builtins.attrNames syncMachines;
};
};
devices = syncDevices;
};
};
};
}
+35
View File
@@ -0,0 +1,35 @@
{ ... }:
{
flake.modules.nixos.systemd-boot =
{ config, pkgs, ... }:
{
boot = {
loader = {
efi.canTouchEfiVariables = true;
systemd-boot = {
enable = true;
consoleMode = "auto";
configurationLimit = 5;
extraInstallCommands = ''
ENTRIES="${config.boot.loader.efi.efiSysMountPoint}/loader/entries"
PROFILES="/nix/var/nix/profiles"
for file in "$ENTRIES"/nixos-generation-*.conf; do
generation=$(${pkgs.coreutils}/bin/basename "$file" | ${pkgs.gnugrep}/bin/grep -o -E '[0-9]+')
timestamp=$(${pkgs.coreutils}/bin/stat -c %y "$PROFILES/system-$generation-link" 2>/dev/null | ${pkgs.coreutils}/bin/cut -d. -f1)
if [ -z "$timestamp" ]; then
timestamp="Unknown Date"
fi
${pkgs.gnused}/bin/sed -i "s/^version .*/version Generation $generation - $timestamp/" "$file"
done
'';
};
};
tmp.cleanOnBoot = true;
kernelPackages = pkgs.linuxPackages_latest;
};
};
}
+198
View File
@@ -0,0 +1,198 @@
{ lib, config, ... }:
let
repo = config.repo;
kittySingleInstance =
pkgs:
pkgs.symlinkJoin {
name = "kitty-single";
paths = [ pkgs.kitty ];
meta = pkgs.kitty.meta;
buildInputs = [ pkgs.makeWrapper ];
postBuild = ''
# Wrap the binary to always launch as a single instance
wrapProgram $out/bin/kitty --add-flags "-1"
# Patch the .desktop file for strict app launchers like Vicinae
rm $out/share/applications/kitty.desktop
sed 's/Exec=kitty/Exec=kitty -1/g' ${pkgs.kitty}/share/applications/kitty.desktop > $out/share/applications/kitty.desktop
'';
};
in
{
flake.modules.homeManager.terminal-foot =
{
lib,
pkgs,
...
}:
let
repoTheme = repo.theme.kanagawa;
palette = repoTheme.palette;
hex = lib.removePrefix "#";
in
{
programs.foot = {
enable = true;
package = pkgs.foot;
settings = {
main = {
font = "JetBrains Mono:style=Medium:size=11:fontfeatures=-liga:fontfeatures=-calt";
font-bold = "JetBrains Mono:style=Bold:size=11:fontfeatures=-liga:fontfeatures=-calt";
font-italic = "JetBrains Mono:style=Medium Italic:size=11:fontfeatures=-liga:fontfeatures=-calt";
font-bold-italic = "JetBrains Mono:style=Bold Italic:size=11:fontfeatures=-liga:fontfeatures=-calt";
gamma-correct-blending = "yes";
pad = "3x3";
# vertical-letter-offset = -1;
# letter-spacing = -0.2;
};
tweak.box-drawing-base-thickness = 0.1;
bell.system = "no";
scrollback.lines = 10000;
text-bindings."\\x0a" = "Shift+Return Shift+KP_Enter";
colors-dark = {
background = hex palette.background;
foreground = hex palette.foreground;
selection-background = hex palette.selectionBackground;
selection-foreground = hex palette.selectionForeground;
urls = hex palette.url;
cursor = "${hex palette.background} ${hex palette.cursor}";
regular0 = hex palette.terminal.color0;
regular1 = hex palette.terminal.color1;
regular2 = hex palette.terminal.color2;
regular3 = hex palette.terminal.color3;
regular4 = hex palette.terminal.color4;
regular5 = hex palette.terminal.color5;
regular6 = hex palette.terminal.color6;
regular7 = hex palette.terminal.color7;
bright0 = hex palette.terminal.color8;
bright1 = hex palette.terminal.color9;
bright2 = hex palette.terminal.color10;
bright3 = hex palette.terminal.color11;
bright4 = hex palette.terminal.color12;
bright5 = hex palette.terminal.color13;
bright6 = hex palette.terminal.color14;
bright7 = hex palette.terminal.color15;
"16" = hex palette.terminal.color16;
"17" = hex palette.terminal.color17;
};
};
};
};
flake.modules.homeManager.terminal-kitty =
{ pkgs, ... }:
let
repoTheme = repo.theme.kanagawa;
palette = repoTheme.palette;
in
{
programs.kitty = {
enable = true;
package = kittySingleInstance pkgs;
font = {
name = "JetBrains Mono";
size = 11;
};
settings = {
disable_ligatures = "always";
scrollback_lines = 10000;
enable_audio_bell = false;
confirm_os_window_close = 0;
window_padding_width = 3;
update_check_interval = 0;
};
keybindings."shift+enter" = "send_text all \\x0a";
extraConfig = ''
## name: ${repoTheme.displayName}
## license: MIT
## author: Tommaso Laurenzi
## upstream: https://github.com/rebelot/kanagawa.nvim/
background ${palette.background}
foreground ${palette.foreground}
selection_background ${palette.selectionBackground}
selection_foreground ${palette.selectionForeground}
url_color ${palette.url}
cursor ${palette.cursor}
active_tab_background ${palette.background}
active_tab_foreground ${palette.selectionForeground}
inactive_tab_background ${palette.background}
inactive_tab_foreground ${palette.muted}
color0 ${palette.terminal.color0}
color1 ${palette.terminal.color1}
color2 ${palette.terminal.color2}
color3 ${palette.terminal.color3}
color4 ${palette.terminal.color4}
color5 ${palette.terminal.color5}
color6 ${palette.terminal.color6}
color7 ${palette.terminal.color7}
color8 ${palette.terminal.color8}
color9 ${palette.terminal.color9}
color10 ${palette.terminal.color10}
color11 ${palette.terminal.color11}
color12 ${palette.terminal.color12}
color13 ${palette.terminal.color13}
color14 ${palette.terminal.color14}
color15 ${palette.terminal.color15}
color16 ${palette.terminal.color16}
color17 ${palette.terminal.color17}
'';
};
systemd.user.services.kitty-daemon = {
Unit = {
Description = "Kitty Terminal Daemon";
PartOf = [ "graphical-session.target" ];
After = [ "graphical-session.target" ];
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
Service = {
# Use the wrapped package (which already includes -1)
# Start it hidden and run an infinite dummy process so the instance stays alive
ExecStart = "${lib.getExe (kittySingleInstance pkgs)} --start-as=hidden ${pkgs.coreutils}/bin/tail -f /dev/null";
Restart = "on-failure";
};
};
};
flake.modules.homeManager.primary-terminal-foot =
{ lib, pkgs, ... }:
{
imports = [ config.flake.modules.homeManager.terminal-foot ];
facts.desktop.terminalCommand = lib.getExe pkgs.foot;
xdg.terminal-exec = {
enable = true;
settings.default = [ "foot.desktop" ];
};
};
flake.modules.homeManager.primary-terminal-kitty =
{ lib, pkgs, ... }:
{
imports = [ config.flake.modules.homeManager.terminal-kitty ];
facts.desktop.terminalCommand = lib.getExe (kittySingleInstance pkgs);
xdg.terminal-exec = {
enable = true;
settings.default = [ "kitty.desktop" ];
};
};
}
+97
View File
@@ -0,0 +1,97 @@
{
config,
...
}:
let
repo = config.repo;
repoHelpers = repo.helpers;
hmModules = config.flake.modules.homeManager;
in
{
repo.theme = import ./_theme.nix;
flake.modules.nixos.theme =
{
pkgs,
...
}:
let
repoTheme = repo.theme;
cursorTheme = repoTheme.cursor // {
package = repoHelpers.resolvePackagePath {
inherit pkgs;
path = repoTheme.cursor.packagePath;
};
};
in
{
home-manager.sharedModules = [ hmModules.theme ];
environment.systemPackages = [ cursorTheme.package ];
services.displayManager.sddm.settings = {
Theme = {
CursorTheme = cursorTheme.name;
CursorSize = cursorTheme.size;
};
};
};
flake.modules.homeManager.theme =
{ config, pkgs, ... }:
let
repoTheme = repo.theme;
cursorTheme = repoTheme.cursor // {
package = repoHelpers.resolvePackagePath {
inherit pkgs;
path = repoTheme.cursor.packagePath;
};
};
kanagawaThemeSrc = pkgs.fetchFromGitHub {
inherit (repoTheme.kanagawa)
hash
owner
repo
rev
;
};
kanagawaOverride = {
version = repoTheme.kanagawa.version;
src = kanagawaThemeSrc;
};
in
{
home.pointerCursor = {
inherit (cursorTheme)
name
package
size
;
dotIcons.enable = false;
gtk.enable = true;
};
gtk = {
enable = true;
gtk3.bookmarks = [
"sftp://orion Orion VPS"
];
theme = {
name = repoTheme.kanagawa.gtkThemeName;
package = pkgs.kanagawa-gtk-theme.overrideAttrs (_: kanagawaOverride);
};
gtk4.theme = null;
iconTheme = {
name = repoTheme.kanagawa.iconThemeName;
package = pkgs.kanagawa-icon-theme.overrideAttrs (_: kanagawaOverride);
};
};
qt = {
enable = true;
platformTheme.name = "gtk3";
};
};
}
@@ -1,44 +1,60 @@
{ config, ... }:
let
repo = config.repo;
in
{ {
flake.modules.homeManager.vicinae = flake.modules.homeManager.vicinae =
{ pkgs, inputs, ... }: {
config,
pkgs,
inputs,
lib,
...
}:
let
repoTheme = repo.theme.kanagawa;
palette = repoTheme.palette;
in
{ {
programs.vicinae = { programs.vicinae = {
enable = true; enable = true;
systemd.enable = true; systemd.enable = true;
themes.kanagawa-wave = { themes.${repoTheme.name} = {
meta = { meta = {
version = 1; version = 1;
name = "Kanagawa Wave"; name = repoTheme.displayName;
description = "A dark theme inspired by the colors of the famous painting by Katsushika Hokusai."; description = "A dark theme inspired by the colors of the famous painting by Katsushika Hokusai.";
variant = "dark"; variant = "dark";
inherits = "vicinae-dark"; inherits = "vicinae-dark";
}; };
colors = { colors = {
core = { core = {
background = "#1F1F28"; background = palette.background;
foreground = "#DCD7BA"; foreground = palette.foreground;
secondary_background = "#16161D"; secondary_background = palette.secondaryBackground;
border = "#2A2A37"; border = palette.border;
accent = "#7E9CD8"; accent = palette.accents.blue;
}; };
accents = { accents = {
blue = "#7E9CD8"; inherit (palette.accents)
green = "#98BB6C"; blue
magenta = "#D27E99"; cyan
orange = "#FFA066"; green
purple = "#957FB8"; magenta
red = "#E82424"; orange
yellow = "#E6C384"; purple
cyan = "#7AA89F"; red
yellow
;
}; };
input.border_focus = "colors.core.accent"; input.border_focus = "colors.core.accent";
}; };
}; };
settings.theme = { settings.theme = {
light.name = "kanagawa-wave"; light.name = repoTheme.name;
dark.name = "kanagawa-wave"; dark.name = repoTheme.name;
}; };
extensions = with inputs.vicinae-extensions.packages.${pkgs.stdenv.hostPlatform.system}; [ extensions = with inputs.vicinae-extensions.packages.${pkgs.stdenv.hostPlatform.system}; [
@@ -56,5 +72,7 @@
ssh ssh
]; ];
}; };
facts.desktop.launcherCommand = lib.getExe config.programs.vicinae.package;
}; };
} }
+47
View File
@@ -0,0 +1,47 @@
{ config, inputs, ... }:
let
homeModules = config.flake.modules.homeManager;
in
{
flake.modules.nixos.walker-cache = {
nix.settings = {
extra-substituters = [
"https://walker.cachix.org"
"https://walker-git.cachix.org"
];
extra-trusted-public-keys = [
"walker.cachix.org-1:fG8q+uAaMqhsMxWjwvk0IMb4mFPFLqHjuvfwQxE4oJM="
"walker-git.cachix.org-1:vmC0ocfPWh0S/vRAQGtChuiZBTAe4wiKDeyyXM0/7pM="
];
};
};
flake.modules.homeManager.walker-base =
{
config,
...
}:
{
imports = [ inputs.walker.homeManagerModules.default ];
programs.walker = {
enable = true;
runAsService = true;
config.providers.prefixes = [
{
provider = "bitwarden";
prefix = "?";
}
];
};
};
flake.modules.homeManager.primary-launcher-walker =
{ config, lib, ... }:
{
imports = [ homeModules.walker-base ];
facts.desktop.launcherCommand = lib.getExe config.programs.walker.package;
};
}
+32
View File
@@ -0,0 +1,32 @@
{
repo = {
account = rec {
name = "kiri";
realName = "Jelle Spreeuwenberg";
homeDirectory = "/home/${name}";
nixosConfigurationPath = "${homeDirectory}/.config/nixos";
emails = {
personal = {
address = "mail@jelles.net";
primary = true;
type = "mxrouting";
};
old = {
address = "mail@jellespreeuwenberg.nl";
type = "mxrouting";
};
uni = {
address = "j.spreeuwenberg@student.tue.nl";
type = "office365";
};
work = {
address = "jelle.spreeuwenberg@yookr.org";
type = "office365";
};
};
primaryEmail = emails.personal;
};
};
}
-14
View File
@@ -1,14 +0,0 @@
{ ... }:
{
flake.modules.homeManager.bitwarden =
{ pkgs, ... }:
{
programs.rbw = {
enable = true;
settings = {
base_url = "https://vault.jelles.net";
pinentry = pkgs.pinentry-gnome3;
};
};
};
}
-35
View File
@@ -1,35 +0,0 @@
{ inputs, config, ... }:
let
nixosModules = config.flake.modules.nixos;
in
{
flake.modules.nixos.desktopBase = {
imports = [
inputs.home-manager.nixosModules.home-manager
nixosModules.nix
nixosModules.systemBase
nixosModules.standardBoot
nixosModules.regionNl
nixosModules.sddm
nixosModules.niri
nixosModules.audio
nixosModules.bluetooth
nixosModules.flatpak
nixosModules.fonts
nixosModules.networking
nixosModules.printing
nixosModules.qbittorrentClient
nixosModules.sopsHost
];
home-manager = {
useGlobalPkgs = true;
backupFileExtension = "bak";
extraSpecialArgs = { inherit inputs; };
};
security.sudo.extraConfig = ''
Defaults env_keep+=SSH_AUTH_SOCK
'';
};
}
-23
View File
@@ -1,23 +0,0 @@
{
flake.modules.homeManager.devTools =
{ config, ... }:
{
home.sessionVariables.CARGO_HOME = "${config.xdg.dataHome}/cargo";
programs.direnv = {
enable = true;
enableZshIntegration = true;
nix-direnv.enable = true;
};
programs.lazygit = {
enable = true;
enableZshIntegration = true;
};
programs.jq.enable = true;
programs.bun.enable = true;
programs.ripgrep.enable = true;
programs.uv.enable = true;
};
}
-99
View File
@@ -1,99 +0,0 @@
{ ... }:
{
flake.modules.homeManager.email =
{ config, ... }:
let
realName = "Jelle Spreeuwenberg";
mkOffice365Account =
{
address,
primary,
}:
{
enable = true;
inherit address primary realName;
userName = address;
thunderbird = {
enable = true;
settings = id: {
"mail.smtpserver.smtp_${id}.authMethod" = 10;
"mail.server.server_${id}.authMethod" = 10;
};
};
flavor = "outlook.office365.com";
};
mkMxrouteAccount =
{
address,
primary,
}:
{
enable = true;
inherit address primary realName;
userName = address;
thunderbird.enable = true;
imap = {
authentication = "plain";
host = "taylor.mxrouting.net";
port = 993;
tls.enable = true;
};
smtp = {
authentication = "plain";
host = "taylor.mxrouting.net";
port = 465;
tls.enable = true;
};
};
in
{
programs.thunderbird = {
enable = true;
profiles.${config.home.username} = {
isDefault = true;
withExternalGnupg = true;
settings = {
"mail.ui.display.message_pane_vertical" = true;
"mail.ui.display.thread_pane_view_type" = "cards";
"mail.uidensity" = 1;
"privacy.donottrackheader.enabled" = true;
"mail.server.server2.hidden" = true;
"mailnews.start_page.enabled" = false;
"mail.provider.enabled" = false;
"layout.css.devPixelsPerPx" = 0.85;
};
};
};
accounts.email.accounts =
if config.home.username == "ergon" then
{
work = mkOffice365Account {
address = "jelle.spreeuwenberg@yookr.org";
primary = true;
};
}
else
{
main = mkMxrouteAccount {
address = "mail@jelles.net";
primary = true;
};
old = mkMxrouteAccount {
address = "mail@jellespreeuwenberg.nl";
primary = false;
};
uni = mkOffice365Account {
address = "j.spreeuwenberg@student.tue.nl";
primary = false;
};
work = mkOffice365Account {
address = "jelle.spreeuwenberg@yookr.org";
primary = false;
};
};
};
}
-11
View File
@@ -1,11 +0,0 @@
{
flake.modules.homeManager.gemini =
{ config, ... }:
{
home.sessionVariables.GEMINI_CONFIG_DIR = "${config.xdg.configHome}/gemini";
programs.gemini-cli.enable = true;
programs.opencode.enable = true;
programs.npm.enable = true;
};
}
-18
View File
@@ -1,18 +0,0 @@
{ ... }:
{
flake.modules.homeManager.git =
{ ... }:
{
programs.git = {
enable = true;
signing.format = "ssh";
ignores = [
".claude/"
".codex/"
];
settings = {
init.defaultBranch = "main";
};
};
};
}
-22
View File
@@ -1,22 +0,0 @@
{
flake.modules.homeManager.localApps =
{ pkgs, ... }:
{
home.sessionVariables.BROWSER = "vivaldi";
home.packages = with pkgs; [
brave
vivaldi
postman
spotify
calcure
planify
unzip
gimp
dbeaver-bin
];
programs.imv.enable = true;
programs.sioyek.enable = true;
};
}
-184
View File
@@ -1,184 +0,0 @@
{
flake.modules.homeManager.neovim =
{
pkgs,
lib,
config,
inputs,
osConfig,
...
}:
{
home.sessionVariables = {
EDITOR = "nvim";
VISUAL = "nvim";
};
imports = [
(inputs.nix-wrapper-modules.lib.mkInstallModule {
name = "neovim";
value = inputs.nix-wrapper-modules.lib.wrapperModules.neovim;
loc = [
"home"
"packages"
];
})
];
# Configure sops-nix secret
sops.secrets.gemini-api-key-neovim = { };
wrappers.neovim = {
enable = true;
# Inject the API key into the Neovim environment only
env = {
GEMINI_API_KEY = "$(cat ${config.sops.secrets.gemini-api-key-neovim.path})";
};
# 1. Point to your existing Lua config directory
settings.config_directory = ./lua-config;
# 2. Runtime Dependencies (from lspsAndRuntimeDeps)
# These are added to the PATH of the wrapper
extraPackages = with pkgs; [
# Tools
universal-ctags
ripgrep
fd
tree-sitter
wl-clipboard
# LSPs & Formatters
stylua
lua-language-server
nixd
nix-doc
nixfmt
dafny
typescript
typescript-language-server
rustc
rust-analyzer
rustfmt
astro-language-server
tinymist
typstyle
# ty
# basedpyright
ty
ruff
];
# 3. Plugins (from startupPlugins & optionalPlugins)
# Since you use lz.n in Lua, we just list them all here.
# The wrapper will add them to the packpath.
specs = {
# Core lazy-loading plugin
lz-n = {
data = pkgs.vimPlugins.lz-n;
};
plenary = {
data = pkgs.vimPlugins.plenary-nvim;
};
# All other plugins
general = {
data = with pkgs.vimPlugins; [
nvim-treesitter.withAllGrammars
nvim-treesitter-textobjects
trouble-nvim
guess-indent-nvim
which-key-nvim
telescope-nvim
telescope-fzf-native-nvim
telescope-ui-select-nvim
conform-nvim
blink-cmp
luasnip
friendly-snippets
mini-nvim
nvim-lspconfig
lazydev-nvim
colorful-menu-nvim
lualine-nvim
zen-mode-nvim
kanagawa-nvim
project-nvim
typst-preview-nvim
direnv-vim
codecompanion-nvim
copilot-lua
];
};
};
# 4. Passing Data to Lua (Replacing nixCats.extra)
# We put these in `settings` so they appear in require('nix-info').settings
settings = {
# Hostname/ConfigDir needed for nixd
nixdExtras = {
nixpkgs = "import ${pkgs.path} {}";
nixos_options = ''(builtins.getFlake "path://${config.home.homeDirectory}/.config/nixos").nixosConfigurations.${osConfig.networking.hostName}.options'';
home_manager_options = ''(builtins.getFlake "path://${config.home.homeDirectory}/.config/nixos").nixosConfigurations.${osConfig.networking.hostName}.options.home-manager.users.type.getSubOptions []'';
};
# TODO: Put in separate theme file
themeSetup = # lua
''
require("kanagawa").setup({
colors = {
theme = {
all = {
ui = {
bg_gutter = "none"
}
}
}
},
overrides = function(colors)
local theme = colors.theme
local makeDiagnosticColor = function(color)
local c = require("kanagawa.lib.color")
return { fg = color, bg = c(color):blend(theme.ui.bg, 0.95):to_hex() }
end
return {
TelescopeTitle = { fg = theme.ui.special, bold = true },
TelescopePromptNormal = { bg = theme.ui.bg_p1 },
TelescopePromptBorder = { fg = theme.ui.bg_p1, bg = theme.ui.bg_p1 },
TelescopeResultsNormal = { fg = theme.ui.fg_dim, bg = theme.ui.bg_m1 },
TelescopeResultsBorder = { fg = theme.ui.bg_m1, bg = theme.ui.bg_m1 },
TelescopePreviewNormal = { bg = theme.ui.bg_dim },
TelescopePreviewBorder = { bg = theme.ui.bg_dim, fg = theme.ui.bg_dim },
Pmenu = { fg = theme.ui.shade0, bg = theme.ui.bg_p1 }, -- add `blend = vim.o.pumblend` to enable transparency
PmenuSel = { fg = "NONE", bg = theme.ui.bg_p2 },
PmenuSbar = { bg = theme.ui.bg_m1 },
PmenuThumb = { bg = theme.ui.bg_p2 },
DiagnosticVirtualTextHint = makeDiagnosticColor(theme.diag.hint),
DiagnosticVirtualTextInfo = makeDiagnosticColor(theme.diag.info),
DiagnosticVirtualTextWarn = makeDiagnosticColor(theme.diag.warning),
DiagnosticVirtualTextError = makeDiagnosticColor(theme.diag.error),
}
end,
})
vim.cmd.colorscheme("kanagawa-wave")
'';
};
# 5. Wrapper Configuration
# Enable Python/Node providers
hosts.python3.nvim-host.enable = true;
hosts.node.nvim-host.enable = true;
# Ensure the bin name matches what you expect
binName = "nvim";
};
};
}
@@ -1,138 +0,0 @@
-- Set <space> as the leader key
-- See `:help mapleader`
-- NOTE: Must happen before plugins are loaded (otherwise wrong leader will be used)
vim.g.mapleader = " "
vim.g.maplocalleader = " "
-- [[ Setting options ]]
-- See `:help vim.o`
-- NOTE: You can change these options as you wish!
-- For more options, you can see `:help option-list`
vim.o.expandtab = true
vim.o.shiftwidth = 2
vim.o.tabstop = 2
vim.o.softtabstop = 2
-- Make line numbers default
vim.o.number = true
-- You can also add relative line numbers, to help with jumping.
-- Experiment for yourself to see if you like it!
-- vim.o.relativenumber = true
-- Enable mouse mode, can be useful for resizing splits for example!
vim.o.mouse = "a"
-- Don't show the mode, since it's already in the status line
vim.o.showmode = false
vim.opt.shortmess:append("Wc")
-- Sync clipboard between OS and Neovim.
-- Schedule the setting after `UiEnter` because it can increase startup-time.
-- Remove this option if you want your OS clipboard to remain independent.
-- See `:help 'clipboard'`
vim.schedule(function()
vim.o.clipboard = "unnamedplus"
end)
-- Enable break indent
vim.o.breakindent = true
-- Save undo history
vim.o.undofile = true
-- Case-insensitive searching UNLESS \C or one or more capital letters in the search term
vim.o.ignorecase = true
vim.o.smartcase = true
-- Keep signcolumn on by default
vim.o.signcolumn = "yes"
-- Decrease update time
vim.o.updatetime = 250
-- Decrease mapped sequence wait time
vim.o.timeoutlen = 300
-- Configure how new splits should be opened
vim.o.splitright = true
vim.o.splitbelow = true
-- Sets how neovim will display certain whitespace characters in the editor.
-- See `:help 'list'`
-- and `:help 'listchars'`
--
-- Notice listchars is set using `vim.opt` instead of `vim.o`.
-- It is very similar to `vim.o` but offers an interface for conveniently interacting with tables.
-- See `:help lua-options`
-- and `:help lua-options-guide`
vim.o.list = true
vim.opt.listchars = { tab = "» ", trail = "·", nbsp = "" }
-- Preview substitutions live, as you type!
vim.o.inccommand = "split"
-- Show which line your cursor is on
vim.o.cursorline = true
-- Minimal number of screen lines to keep above and below the cursor.
vim.o.scrolloff = 10
-- if performing an operation that would fail due to unsaved changes in the buffer (like `:q`),
-- instead raise a dialog asking if you wish to save the current file(s)
-- See `:help 'confirm'`
vim.o.confirm = true
-- [[ Basic Keymaps ]]
-- See `:help vim.keymap.set()`
-- Clear highlights on search when pressing <Esc> in normal mode
-- See `:help hlsearch`
vim.keymap.set("n", "<Esc>", "<cmd>nohlsearch<CR>")
-- Diagnostic keymaps
vim.keymap.set("n", "<leader>q", vim.diagnostic.setloclist, { desc = "Open diagnostic [Q]uickfix list" })
-- Exit terminal mode in the builtin terminal with a shortcut that is a bit easier
-- for people to discover. Otherwise, you normally need to press <C-\><C-n>, which
-- is not what someone will guess without a bit more experience.
--
-- NOTE: This won't work in all terminal emulators/tmux/etc. Try your own mapping
-- or just use <C-\><C-n> to exit terminal mode
vim.keymap.set("t", "<Esc><Esc>", "<C-\\><C-n>", { desc = "Exit terminal mode" })
-- TIP: Disable arrow keys in normal mode
-- vim.keymap.set('n', '<left>', '<cmd>echo "Use h to move!!"<CR>')
-- vim.keymap.set('n', '<right>', '<cmd>echo "Use l to move!!"<CR>')
-- vim.keymap.set('n', '<up>', '<cmd>echo "Use k to move!!"<CR>')
-- vim.keymap.set('n', '<down>', '<cmd>echo "Use j to move!!"<CR>')
-- Keybinds to make split navigation easier.
-- Use CTRL+<hjkl> to switch between windows
--
-- See `:help wincmd` for a list of all window commands
vim.keymap.set("n", "<C-h>", "<C-w><C-h>", { desc = "Move focus to the left window" })
vim.keymap.set("n", "<C-l>", "<C-w><C-l>", { desc = "Move focus to the right window" })
vim.keymap.set("n", "<C-j>", "<C-w><C-j>", { desc = "Move focus to the lower window" })
vim.keymap.set("n", "<C-k>", "<C-w><C-k>", { desc = "Move focus to the upper window" })
-- NOTE: Some terminals have colliding keymaps or are not able to send distinct keycodes
-- vim.keymap.set("n", "<C-S-h>", "<C-w>H", { desc = "Move window to the left" })
-- vim.keymap.set("n", "<C-S-l>", "<C-w>L", { desc = "Move window to the right" })
-- vim.keymap.set("n", "<C-S-j>", "<C-w>J", { desc = "Move window to the lower" })
-- vim.keymap.set("n", "<C-S-k>", "<C-w>K", { desc = "Move window to the upper" })
-- [[ Basic Autocommands ]]
-- See `:help lua-guide-autocommands`
-- Highlight when yanking (copying) text
-- Try it with `yap` in normal mode
-- See `:help vim.hl.on_yank()`
vim.api.nvim_create_autocmd("TextYankPost", {
desc = "Highlight when yanking (copying) text",
group = vim.api.nvim_create_augroup("kickstart-highlight-yank", { clear = true }),
callback = function()
vim.hl.on_yank()
end,
})
@@ -1,72 +0,0 @@
require("lz.n").load({
{
"copilot.lua",
cmd = "Copilot",
event = "InsertEnter",
after = function()
require("copilot").setup({
-- Disable inline suggestions, let CodeCompanion (or blink) handle interactions
suggestion = { enabled = false },
panel = { enabled = false },
})
end,
},
{
"codecompanion.nvim",
cmd = { "CodeCompanion", "CodeCompanionChat", "CodeCompanionActions" },
keys = {
{ "<leader>aa", "<cmd>CodeCompanionChat Toggle<cr>", mode = { "n", "v" }, desc = "[A]I [A]ssistant" },
{ "<leader>ac", "<cmd>CodeCompanionActions<cr>", mode = { "n", "v" }, desc = "[A]I [C]ode Actions" },
},
after = function()
require("codecompanion").setup({
-- Set Gemini as the default strategy
strategies = {
chat = {
adapter = "gemini",
},
inline = {
adapter = "gemini",
},
},
-- Configure all available adapters
adapters = {
copilot = function()
return require("codecompanion.adapters").extend("copilot", {
schema = {
model = {
default = "claude-3.5-sonnet", -- Good default for Copilot chat
},
},
})
end,
gemini = function()
return require("codecompanion.adapters").extend("gemini", {
env = {
api_key = "GEMINI_API_KEY",
},
schema = {
model = {
default = "gemini-3.1-pro-preview",
},
},
})
end,
gemini_cli = function()
return require("codecompanion.adapters").extend("gemini_cli", {
-- Pass the model as a CLI argument
args = {
"--model",
"gemini-3.1-pro-preview",
},
-- Set authentication to use standard Google Login
env = {
auth_method = "oauth-personal",
},
})
end,
},
})
end,
},
})
@@ -1,101 +0,0 @@
require("lz.n").load({
{
"project.nvim",
event = { "VimEnter" }, -- Load early to set root correctly
after = function()
require("project").setup({
-- 1. Automagically change directory to project root
manual_mode = false,
-- LSP detection
lsp = { enabled = true },
-- Files/folders that indicate a root
patterns = { ".git", "_darcs", ".hg", ".bzr", ".svn", "Makefile", "package.json", "flake.nix" },
-- Show hidden files in telescope
show_hidden = true,
-- When the project scope changes, change the directory
scope_chdir = "global",
})
end,
},
{
"telescope.nvim",
event = "VimEnter",
before = function()
require("lz.n").trigger_load("project.nvim")
end,
after = function()
local actions = require("telescope.actions")
require("telescope").setup({
defaults = {
path_display = { "truncate" },
layout_strategy = "horizontal",
layout_config = {
prompt_position = "top",
},
sorting_strategy = "ascending",
mappings = {
i = {
["<C-k>"] = actions.move_selection_previous, -- Move up with Ctrl-k
["<C-j>"] = actions.move_selection_next, -- Move down with Ctrl-j
["<C-q>"] = actions.send_selected_to_qflist + actions.open_qflist, -- Send to quickfix
},
},
},
extensions = {
["ui-select"] = {
require("telescope.themes").get_dropdown(),
},
},
})
-- Enable Telescope extensions if they are installed
pcall(require("telescope").load_extension, "projects")
pcall(require("telescope").load_extension, "fzf")
pcall(require("telescope").load_extension, "ui-select")
-- See `:help telescope.builtin`
local builtin = require("telescope.builtin")
vim.keymap.set("n", "<leader>sh", builtin.help_tags, { desc = "[S]earch [H]elp" })
vim.keymap.set("n", "<leader>sk", builtin.keymaps, { desc = "[S]earch [K]eymaps" })
vim.keymap.set("n", "<leader>sf", builtin.find_files, { desc = "[S]earch [F]iles" })
vim.keymap.set("n", "<leader>ss", builtin.builtin, { desc = "[S]earch [S]elect Telescope" })
vim.keymap.set("n", "<leader>sw", builtin.grep_string, { desc = "[S]earch current [W]ord" })
vim.keymap.set("n", "<leader>sg", builtin.live_grep, { desc = "[S]earch by [G]rep" })
vim.keymap.set("n", "<leader>sd", builtin.diagnostics, { desc = "[S]earch [D]iagnostics" })
vim.keymap.set("n", "<leader>sr", builtin.resume, { desc = "[S]earch [R]esume" })
vim.keymap.set("n", "<leader>s.", builtin.oldfiles, { desc = '[S]earch Recent Files ("." for repeat)' })
vim.keymap.set("n", "<leader><leader>", builtin.buffers, { desc = "[ ] Find existing buffers" })
vim.keymap.set("n", "<leader>sp", function()
require("telescope").extensions.projects.projects({})
end, { desc = "[S]earch [P]rojects" })
-- Slightly advanced example of overriding default behavior and theme
vim.keymap.set("n", "<leader>/", function()
-- You can pass additional configuration to Telescope to change the theme, layout, etc.
builtin.current_buffer_fuzzy_find(require("telescope.themes").get_dropdown({
winblend = 10,
previewer = false,
}))
end, { desc = "[/] Fuzzily search in current buffer" })
-- It's also possible to pass additional configuration options.
-- See `:help telescope.builtin.live_grep()` for information about particular keys
vim.keymap.set("n", "<leader>s/", function()
builtin.live_grep({
grep_open_files = true,
prompt_title = "Live Grep in Open Files",
})
end, { desc = "[S]earch [/] in Open Files" })
-- Shortcut for searching your Neovim configuration files
vim.keymap.set("n", "<leader>sn", function()
builtin.find_files({ cwd = vim.fn.stdpath("config") })
end, { desc = "[S]earch [N]eovim files" })
end,
},
})
@@ -1 +0,0 @@
require("lz.n").load({})
@@ -1,81 +0,0 @@
require("lz.n").load({
{
"theme-loader",
event = "VimEnter",
load = function()
local settings = require("nix-info").settings
local theme_code = settings.themeSetup
local func, err = loadstring(theme_code)
if func then
func()
else
print("Error loading theme code: " .. err)
end
end,
},
{
"lualine.nvim",
event = "VimEnter",
after = function()
require("lualine").setup({
options = {
icons_enabled = true,
globalstatus = true,
component_separators = "",
section_separators = "",
},
sections = {
lualine_a = { "mode" },
lualine_b = { "branch", "diagnostics" },
lualine_c = { "filename" },
lualine_x = { "lsp_status" },
lualine_y = { "progress" },
lualine_z = { "location" },
},
})
end,
},
{
"zen-mode.nvim",
cmd = "ZenMode",
after = function()
require("zen-mode").setup({
window = {
options = {
linebreak = true,
},
},
})
end,
},
{
"which-key.nvim",
event = "VimEnter",
before = function()
require("lz.n").trigger_load("mini.nvim")
end,
after = function()
require("which-key").setup({
preset = "modern",
delay = 200,
icons = {
-- set icon mappings to true if you have a Nerd Font
mappings = true,
-- If you are using a Nerd Font: set icons.keys to an empty table which will use the
-- default which-key.nvim defined Nerd Font icons, otherwise define a string table
keys = {},
},
-- Document existing key chains
spec = {
{ "<leader>s", group = "[S]earch" },
{ "<leader>t", group = "[T]oggle" },
{ "<leader>h", group = "Git [H]unk", mode = { "n", "v" } },
},
})
end,
},
})
-8
View File
@@ -1,8 +0,0 @@
{
flake.modules.nixos.networking = {
networking = {
nftables.enable = true;
networkmanager.enable = true;
};
};
}
-103
View File
@@ -1,103 +0,0 @@
{ inputs, ... }:
{
flake.modules.nixos.niri =
{ pkgs, ... }:
{
imports = [ inputs.niri.nixosModules.niri ];
nixpkgs.overlays = [ inputs.niri.overlays.niri ];
programs.niri.enable = true;
programs.niri.package = pkgs.niri-unstable;
programs.dconf.enable = true;
services.gvfs.enable = true;
services.udisks2.enable = true;
xdg.portal.enable = true;
};
flake.modules.homeManager.niri =
{ config, pkgs, ... }:
{
home.sessionVariables.NIXOS_OZONE_WL = "1";
dconf.settings = {
"org/gnome/desktop/interface" = {
color-scheme = "prefer-dark";
};
};
home.packages = with pkgs; [
playerctl
nautilus
brightnessctl
xwayland-satellite
];
programs.niri.settings = {
environment.DISPLAY = ":0";
spawn-at-startup = [
{ command = [ "xwayland-satellite" ]; }
{ command = [ "noctalia-shell" ]; }
{ command = [ "qbittorrent" ]; }
];
prefer-no-csd = true;
hotkey-overlay.skip-at-startup = true;
screenshot-path = "${config.xdg.userDirs.pictures}/screenshots/%Y-%m-%dT%H:%M:%S.png";
animations.slowdown = 0.6;
cursor = with config.home.pointerCursor; {
size = size;
theme = name;
hide-after-inactive-ms = 3000;
hide-when-typing = true;
};
layout = {
always-center-single-column = true;
gaps = 14;
focus-ring.enable = false;
default-column-width.proportion = 1. / 2.;
border = {
enable = true;
width = 3;
active.color = "#7E9CD8";
inactive.color = "#54546D";
urgent.color = "#E82424";
};
};
window-rules = [
{
geometry-corner-radius =
let
radius = 10.0;
in
{
bottom-left = radius;
bottom-right = radius;
top-left = radius;
top-right = radius;
};
clip-to-geometry = true;
}
];
debug.honor-xdg-activation-with-invalid-serial = true;
input = {
focus-follows-mouse.enable = true;
keyboard = {
repeat-delay = 300;
repeat-rate = 50;
xkb.options = "caps:escape";
};
mouse.accel-speed = 0.4;
};
binds = import ./_bindings.nix;
};
};
}
-23
View File
@@ -1,23 +0,0 @@
{
flake.modules.homeManager.noctalia =
{
inputs,
lib,
pkgs,
...
}:
{
imports = [ inputs.noctalia.homeModules.default ];
programs.noctalia-shell = {
enable = true;
package = lib.mkForce (
inputs.noctalia.packages.${pkgs.stdenv.hostPlatform.system}.default.override {
calendarSupport = true;
}
);
settings = import ./_noctalia-config.nix;
};
};
}
-75
View File
@@ -1,75 +0,0 @@
{
flake.modules.homeManager.pim =
{
config,
...
}:
let
calendarsPath = "${config.xdg.dataHome}/calendars";
in
{
programs.pimsync.enable = true;
services.pimsync.enable = true;
programs.khal = {
enable = false;
locale = {
timeformat = "%H:%M";
dateformat = "$m-$d";
};
};
programs.todoman = {
enable = true;
glob = "*/*";
extraConfig = ''
date_format = "%Y-%m-%d"
time_format = "%H:%M"
default_list = "personal"
default_due = 0
default_command = "list --sort priority,due"
humanize = True
'';
};
accounts.calendar = {
basePath = calendarsPath;
accounts.radicale = {
primary = true;
primaryCollection = "personal";
local = {
type = "filesystem";
fileExt = ".ics";
};
remote = {
url = "https://radicale.jelles.net/";
type = "caldav";
userName = config.home.username;
passwordCommand = [
"rbw"
"get"
"Radicale"
];
};
pimsync = {
enable = true;
extraPairDirectives = [
{
name = "collections";
params = [ "from b" ];
}
];
};
khal = {
enable = true;
type = "discover";
color = "light blue";
};
};
};
};
}
-14
View File
@@ -1,14 +0,0 @@
{
flake.modules.nixos.qbittorrentClient = {
networking.firewall = {
allowedTCPPorts = [ 43864 ];
allowedUDPPorts = [ 43864 ];
};
};
flake.modules.homeManager.qbittorrentClient =
{ pkgs, ... }:
{
home.packages = [ pkgs.qbittorrent ];
};
}
-14
View File
@@ -1,14 +0,0 @@
{
flake.modules.nixos.sddm =
{ pkgs, ... }:
{
services.displayManager.sddm = {
enable = true;
wayland.enable = true;
theme = "${pkgs.sddm-astronaut}/share/sddm/themes/sddm-astronaut-theme";
extraPackages = with pkgs; [
kdePackages.qtmultimedia
];
};
};
}
-17
View File
@@ -1,17 +0,0 @@
{
flake.modules.nixos.actual =
{ config, ... }:
{
services.actual = {
enable = true;
openFirewall = false;
settings = {
port = 3000;
hostname = "127.0.0.1";
};
};
services.caddy.virtualHosts."finance.jelles.net".extraConfig =
"reverse_proxy :${toString config.services.actual.settings.port}";
};
}
-18
View File
@@ -1,18 +0,0 @@
{
flake.modules.nixos.delugeService =
{ ... }:
{
sops.secrets.deluge-auth-file = { };
services.deluge = {
enable = true;
declarative = false;
};
};
flake.modules.homeManager.delugeClient =
{ pkgs, ... }:
{
home.packages = [ pkgs.deluge ];
};
}
-28
View File
@@ -1,28 +0,0 @@
{
flake.modules.nixos.gitea =
{ config, ... }:
{
services.gitea = {
enable = true;
settings = {
server = {
DOMAIN = "git.jelles.net";
ROOT_URL = "https://git.jelles.net/";
HTTP_PORT = 3001;
HTTP_ADDR = "127.0.0.1";
START_SSH_SERVER = false;
SSH_PORT = 22;
};
service.DISABLE_REGISTRATION = true;
};
};
services.openssh.settings.AllowUsers = [ "gitea" ];
services.caddy.virtualHosts."git.jelles.net".extraConfig =
"reverse_proxy :${toString config.services.gitea.settings.server.HTTP_PORT}";
};
}
-27
View File
@@ -1,27 +0,0 @@
{ ... }:
{
flake.modules.nixos.openssh =
{
config,
hostType ? "desktop",
lib,
...
}:
let
isServer = hostType == "server";
hostUserNames = builtins.attrNames (
lib.filterAttrs (_: user: user.isNormalUser or false) config.users.users
);
in
{
services.openssh = {
enable = true;
openFirewall = isServer;
settings = {
PermitRootLogin = "no";
PasswordAuthentication = false;
AllowUsers = hostUserNames;
};
};
};
}
-11
View File
@@ -1,11 +0,0 @@
{ ... }:
{
flake.modules.nixos.qbittorrent = {
services.qbittorrent = {
enable = true;
openFirewall = true;
torrentingPort = 43864;
webuiPort = 8123;
};
};
}
-27
View File
@@ -1,27 +0,0 @@
{
flake.modules.nixos.radicale =
{ ... }:
{
services.radicale = {
enable = true;
settings = {
server.hosts = [ "127.0.0.1:5232" ];
auth = {
type = "htpasswd";
htpasswd_filename = "/var/lib/radicale/users";
htpasswd_encryption = "bcrypt";
};
storage.filesystem_folder = "/var/lib/radicale/collections";
};
};
services.caddy.virtualHosts."radicale.jelles.net".extraConfig = ''
reverse_proxy :5232 {
header_up X-Script-Name /
header_up X-Forwarded-For {remote}
header_up X-Remote-User {http.auth.user.id}
}'';
};
}
-19
View File
@@ -1,19 +0,0 @@
{
flake.modules.nixos.vaultwarden =
{ config, ... }:
{
services.vaultwarden = {
enable = true;
backupDir = "/var/backup/vaultwarden";
config = {
DOMAIN = "https://vault.jelles.net";
SIGNUPS_ALLOWED = false;
ROCKET_PORT = 8100;
ROCKET_LOG = "critical";
};
};
services.caddy.virtualHosts."vault.jelles.net".extraConfig =
"reverse_proxy :${toString config.services.vaultwarden.config.ROCKET_PORT}";
};
}
-20
View File
@@ -1,20 +0,0 @@
{ ... }:
{
flake.modules.nixos.standardBoot =
{ pkgs, ... }:
{
boot = {
loader = {
efi.canTouchEfiVariables = true;
systemd-boot = {
enable = true;
consoleMode = "auto";
configurationLimit = 5;
};
};
tmp.cleanOnBoot = true;
kernelPackages = pkgs.linuxPackages_latest;
};
};
}
-41
View File
@@ -1,41 +0,0 @@
{
flake.modules.homeManager.syncthing =
{ ... }:
let
syncthingMesh = {
"kiri@orion" = {
name = "kiri@orion";
id = "NNRNQKZ-OWPHSVA-B6KKBHE-SDYLSTV-7SVHGPR-NEWLKPL-4MWNJG4-G5FHUAI";
};
"kiri@polaris" = {
name = "kiri@polaris";
id = "6HBAKXB-DB3B4H2-BODCAXF-KD23H5W-6X5LGLC-ZJHZHLG-7U7YMGO-BB6IXQ3";
};
};
in
{
services.syncthing = {
enable = true;
overrideDevices = true;
overrideFolders = true;
settings = {
folders = {
sync = {
path = "~/sync";
label = "sync";
devices = builtins.attrNames syncthingMesh;
};
calibre = {
path = "~/calibre";
label = "calibre";
devices = builtins.attrNames syncthingMesh;
};
};
devices = syncthingMesh;
};
};
};
}
-10
View File
@@ -1,10 +0,0 @@
{
flake.modules.nixos.systemBase = {
users.mutableUsers = false;
services.dbus.implementation = "broker";
programs.nix-ld.enable = true;
environment.localBinInPath = true;
};
}
-65
View File
@@ -1,65 +0,0 @@
{
flake.modules.homeManager.terminal =
{ pkgs, ... }:
{
xdg.terminal-exec = {
enable = true;
settings.default = [ "kitty.desktop" ];
};
programs.kitty = {
enable = true;
font = {
name = "JetBrains Mono";
size = 11;
};
settings = {
disable_ligatures = "always";
scrollback_lines = 10000;
enable_audio_bell = false;
confirm_os_window_close = 0;
window_padding_width = 3;
update_check_interval = 0;
};
extraConfig = ''
## name: Kanagawa
## license: MIT
## author: Tommaso Laurenzi
## upstream: https://github.com/rebelot/kanagawa.nvim/
background #1F1F28
foreground #DCD7BA
selection_background #2D4F67
selection_foreground #C8C093
url_color #72A7BC
cursor #C8C093
active_tab_background #1F1F28
active_tab_foreground #C8C093
inactive_tab_background #1F1F28
inactive_tab_foreground #727169
color0 #16161D
color1 #C34043
color2 #76946A
color3 #C0A36E
color4 #7E9CD8
color5 #957FB8
color6 #6A9589
color7 #C8C093
color8 #727169
color9 #E82424
color10 #98BB6C
color11 #E6C384
color12 #7FB4CA
color13 #938AA9
color14 #7AA89F
color15 #DCD7BA
color16 #FFA066
color17 #FF5D62
'';
};
};
}
-48
View File
@@ -1,48 +0,0 @@
{
flake.modules.homeManager.theme =
{ config, pkgs, ... }:
let
kanagawaThemeSrc = pkgs.fetchFromGitHub {
owner = "Fausto-Korpsvart";
repo = "Kanagawa-GKT-Theme";
rev = "55ca4ba249eba21f861b9866b71ab41bb8930318";
hash = "sha256-UdMoMx2DoovcxSp/zBZ3PRv/Qpj+prd0uPm1gmdak2E=";
};
kanagawaOverride = {
version = "unstable-2025-10-23";
src = kanagawaThemeSrc;
};
in
{
home.pointerCursor = {
name = "phinger-cursors-light";
package = pkgs.phinger-cursors;
size = 24;
gtk.enable = true;
};
gtk = {
enable = true;
gtk3.bookmarks = [
"sftp://orion Orion VPS"
];
theme = {
name = "Kanagawa-BL-LB";
package = pkgs.kanagawa-gtk-theme.overrideAttrs (_: kanagawaOverride);
};
gtk4.theme = {
inherit (config.gtk.theme) name package;
};
iconTheme = {
name = "Kanagawa";
package = pkgs.kanagawa-icon-theme.overrideAttrs (_: kanagawaOverride);
};
};
qt = {
enable = true;
platformTheme.name = "gtk3";
};
};
}
-19
View File
@@ -1,19 +0,0 @@
{ config, ... }:
let
homeModules = config.flake.modules.homeManager;
in
{
flake.modules.homeManager.userBase = {
imports = with homeModules; [
terminal
shell
neovim
sshClient
sopsAdmin
git
devTools
podman
gemini
];
};
}
-45
View File
@@ -1,45 +0,0 @@
{
flake.modules.homeManager.xdg =
{ config, pkgs, ... }:
let
homeDir = config.home.homeDirectory;
localDir = "${homeDir}/.local";
mediaDir = "${homeDir}/media";
in
{
xdg = {
enable = true;
cacheHome = "${localDir}/cache";
configHome = "${homeDir}/.config";
dataHome = "${localDir}/share";
stateHome = "${localDir}/state";
userDirs = {
enable = true;
createDirectories = true;
setSessionVariables = true;
download = "${homeDir}/downloads";
documents = "${homeDir}/documents";
music = "${mediaDir}/music";
pictures = "${mediaDir}/images";
videos = "${mediaDir}/videos";
desktop = "${localDir}/desktop";
publicShare = "${localDir}/public";
templates = "${localDir}/templates";
};
mimeApps = {
enable = true;
defaultApplicationPackages = with pkgs; [
sioyek
imv
vivaldi
neovim
nautilus
];
};
};
};
}
+10 -19
View File
@@ -3,30 +3,21 @@
config, config,
... ...
}: }:
let
nixosModules = config.flake.modules.nixos;
in
{ {
imports = [ inputs.flake-parts.flakeModules.modules ]; imports = [
inputs.flake-parts.flakeModules.modules
./data.nix
];
systems = [ "x86_64-linux" ]; systems = [ "x86_64-linux" ];
flake.nixosConfigurations = { flake.nixosConfigurations = builtins.mapAttrs (
orion = inputs.nixpkgs.lib.nixosSystem { name: machine:
inputs.nixpkgs.lib.nixosSystem {
specialArgs = { inherit inputs; }; specialArgs = { inherit inputs; };
modules = [ nixosModules.orion ]; modules = [ (config.repo.helpers.mkHost name machine) ];
}; }
) config.repo.machines;
polaris = inputs.nixpkgs.lib.nixosSystem {
specialArgs = { inherit inputs; };
modules = [ nixosModules.polaris ];
};
zenith = inputs.nixpkgs.lib.nixosSystem {
specialArgs = { inherit inputs; };
modules = [ nixosModules.zenith ];
};
};
perSystem = perSystem =
{ pkgs, ... }: { pkgs, ... }:
+18 -42
View File
@@ -5,61 +5,37 @@
}: }:
let let
nixosModules = config.flake.modules.nixos; nixosModules = config.flake.modules.nixos;
account = config.repo.account;
in in
{ {
flake.modules.nixos.orion = repo.machines.orion = {
{ pkgs, ... }: syncthingId = "NNRNQKZ-OWPHSVA-B6KKBHE-SDYLSTV-7SVHGPR-NEWLKPL-4MWNJG4-G5FHUAI";
{
_module.args.hostType = "server";
stateVersion = "24.05";
};
flake.modules.nixos.orion =
{ ... }:
{
imports = [ imports = [
inputs.home-manager.nixosModules.home-manager nixosModules.host-base
nixosModules.sopsHost
nixosModules.caddy nixosModules.sops-host-ssh-key
nixosModules.openssh nixosModules.openssh
nixosModules.caddy
nixosModules.server-firewall
nixosModules.sudo-ssh-agent-auth
nixosModules.vps-insights
nixosModules.vaultwarden nixosModules.vaultwarden
nixosModules.radicale nixosModules.radicale
nixosModules.actual nixosModules.actual
nixosModules.gitea nixosModules.gitea
nixosModules.kiri
./_hardware.nix ./_hardware.nix
./_disk.nix ./_disk.nix
]; ];
system.stateVersion = "24.05"; environment.enableAllTerminfo = true;
home-manager = { users.users.${account.name}.linger = true;
useGlobalPkgs = true;
backupFileExtension = "bak";
extraSpecialArgs = { inherit inputs; };
};
networking.hostName = "orion";
security.sudo.extraConfig = ''
Defaults env_keep+=SSH_AUTH_SOCK
'';
users.users.kiri = {
linger = true;
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAU2LydkXRTtNFY7oyX8JQURwXLVhB71DeK8XzrXeFX1 openpgp:0xA490D93A"
];
};
environment.systemPackages = [
pkgs.kitty
];
networking = {
firewall.enable = true;
firewall.allowPing = false;
nftables.enable = true;
};
security.pam = {
sshAgentAuth.enable = true;
services.sudo.sshAgentAuth = true;
};
}; };
} }
+28 -65
View File
@@ -5,23 +5,39 @@
}: }:
let let
nixosModules = config.flake.modules.nixos; nixosModules = config.flake.modules.nixos;
homeModules = config.flake.modules.homeManager;
in in
{ {
flake.modules.nixos.polaris = repo.machines.polaris = {
{ sshKeys = {
config, personal.publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEVORk45HKkX7gaGGp90KsVyUy6t+fKhbWN/grjkf3cQ kiri@polaris";
pkgs, work.publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM5DMV6EQzsscgEOE0912mNglUHTEl+LPnaWYjj0y57B kiri@polaris#work";
... };
}:
{
_module.args.hostType = "desktop";
syncthingId = "6HBAKXB-DB3B4H2-BODCAXF-KD23H5W-6X5LGLC-ZJHZHLG-7U7YMGO-BB6IXQ3";
stateVersion = "24.05";
displays = {
"LG Electronics LG ULTRAGEAR 103NTYT8R290" = {
primary = true;
x = 0;
y = 0;
};
"LG Electronics LG ULTRAGEAR 103NTJJ8R332" = {
x = 2560;
y = 0;
};
};
};
flake.modules.nixos.polaris =
{ ... }:
{
imports = [ imports = [
nixosModules.desktopBase nixosModules.workstation-base
nixosModules.transmission
nixosModules.steam nixosModules.steam
nixosModules.kiri
nixosModules.ergon
./_hardware.nix ./_hardware.nix
] ]
++ (with inputs.nixos-hardware.nixosModules; [ ++ (with inputs.nixos-hardware.nixosModules; [
@@ -30,58 +46,5 @@ in
common-cpu-amd common-cpu-amd
common-gpu-amd common-gpu-amd
]); ]);
system.stateVersion = "24.05";
networking.hostName = "polaris";
home-manager.users.kiri.imports = with homeModules; [
nix
bitwarden
email
pim
mpv
niri
clipboard
localApps
qbittorrentClient
vicinae
xdg
theme
noctalia
];
home-manager.users.kiri.programs.niri.settings.outputs = {
"LG Electronics LG ULTRAGEAR 103NTYT8R290" = {
"focus-at-startup" = true;
position = {
x = 0;
y = 0;
};
};
"LG Electronics LG ULTRAGEAR 103NTJJ8R332" = {
position = {
x = 2560;
y = 0;
};
};
};
boot.loader.systemd-boot.extraInstallCommands = ''
ENTRIES="${config.boot.loader.efi.efiSysMountPoint}/loader/entries"
PROFILES="/nix/var/nix/profiles"
for file in "$ENTRIES"/nixos-generation-*.conf; do
generation=$(${pkgs.coreutils}/bin/basename "$file" | ${pkgs.gnugrep}/bin/grep -o -E '[0-9]+')
timestamp=$(${pkgs.coreutils}/bin/stat -c %y "$PROFILES/system-$generation-link" 2>/dev/null | ${pkgs.coreutils}/bin/cut -d. -f1)
if [ -z "$timestamp" ]; then
timestamp="Unknown Date"
fi
${pkgs.gnused}/bin/sed -i "s/^version .*/version Generation $generation - $timestamp/" "$file"
done
'';
}; };
} }
+25 -40
View File
@@ -5,59 +5,44 @@
}: }:
let let
nixosModules = config.flake.modules.nixos; nixosModules = config.flake.modules.nixos;
homeModules = config.flake.modules.homeManager;
in in
{ {
flake.modules.nixos.zenith = repo.machines.zenith = {
{ ... }: portable = true;
{
_module.args.hostType = "laptop";
imports = [ sshKeys = {
nixosModules.desktopBase personal.publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIQy4k04gU7UpjBgyUQ57kUwxOdt79LvMCiCekXZeZhd kiri@zenith";
nixosModules.kiri work.publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIHJz5uHKm0/TiMNh/cmzrODHNZ8NgEEZe+47XnJwQGk kiri@zenith#work";
nixosModules.ergon
./_hardware.nix
inputs.nixos-hardware.nixosModules.lenovo-yoga-7-14ARH7-amdgpu
];
system.stateVersion = "24.05";
networking.hostName = "zenith";
home-manager.users.kiri.imports = with homeModules; [
nix
bitwarden
email
pim
mpv
niri
clipboard
localApps
qbittorrentClient
vicinae
xdg
theme
noctalia
];
home-manager.users.kiri.programs.niri.settings.outputs = {
"California Institute of Technology 0x1410 Unknown" = {
"focus-at-startup" = true;
position = {
x = 0;
y = 0;
}; };
syncthingId = "5VMGBZJ-NNAVCLY-YWHCJLM-EJ3SCFC-EOGCECD-DGXC7EL-J5NXAAG-4JDEMQG";
displays = {
"California Institute of Technology 0x1410 Unknown" = {
primary = true;
scale = 1.5; scale = 1.5;
mode = {
width = 3072; width = 3072;
height = 1920; height = 1920;
refresh = 120.002; refresh = 120.002;
}; };
}; };
stateVersion = "24.05";
}; };
flake.modules.nixos.zenith =
{ ... }:
{
imports = [
nixosModules.workstation-base
nixosModules.transmission
nixosModules.laptop-power
{
hardware.enableRedistributableFirmware = true; hardware.enableRedistributableFirmware = true;
services.fwupd.enable = true; services.fwupd.enable = true;
}
./_hardware.nix
inputs.nixos-hardware.nixosModules.lenovo-yoga-7-14ARH7-amdgpu
];
}; };
} }
+93
View File
@@ -0,0 +1,93 @@
{ lib, config, ... }:
let
nixosModules = config.flake.modules.nixos;
resolvePackagePath =
{
pkgs,
path,
}:
lib.attrByPath path null pkgs;
mkCaddyReverseProxy =
{
domain,
port,
extraHeaders ? [ ],
extraConfigText ? "",
}:
let
headerLines = map (header: " header_up ${header.name} ${header.value}") extraHeaders;
extraConfigLines = map (line: " ${line}") (
lib.filter (line: line != "") (lib.splitString "\n" extraConfigText)
);
bodyLines = headerLines ++ extraConfigLines;
body = lib.concatStringsSep "\n" bodyLines;
in
{
services.caddy.virtualHosts.${domain}.extraConfig =
if body == "" then
"reverse_proxy :${toString port}"
else
''
reverse_proxy :${toString port} {
${body}
}
'';
};
mkHost =
name: machine:
{ pkgs, ... }:
let
account = config.repo.account;
accountHome = account.homeDirectory or "/home/${account.name}";
normalizedMachine = machine // {
inherit name;
displays = machine.displays or { };
hmStateVersion = machine.hmStateVersion or machine.stateVersion;
portable = machine.portable or false;
sshKeys = machine.sshKeys or { };
syncthingId = machine.syncthingId or null;
};
in
{
imports = [
nixosModules.${name}
];
facts.machine = normalizedMachine;
networking.hostName = name;
system.stateVersion = machine.stateVersion;
programs.zsh.enable = true;
users.users.${account.name} = {
isNormalUser = true;
home = accountHome;
extraGroups = [
"wheel"
"networkmanager"
];
shell = pkgs.zsh;
};
home-manager.users.${account.name} = {
home = {
username = account.name;
homeDirectory = accountHome;
stateVersion = normalizedMachine.hmStateVersion;
};
};
};
in
{
config.repo.helpers = {
inherit
mkCaddyReverseProxy
mkHost
resolvePackagePath
;
};
}
+33
View File
@@ -0,0 +1,33 @@
{ lib, ... }:
{
options.repo = lib.mkOption {
type = lib.types.submodule {
freeformType = lib.types.attrsOf lib.types.anything;
options.helpers = lib.mkOption {
type = lib.types.attrsOf lib.types.raw;
default = { };
internal = true;
};
};
default = { };
};
config.flake.modules.nixos.facts =
{ lib, ... }:
{
options.facts.machine = lib.mkOption {
type = lib.types.attrsOf lib.types.anything;
default = { };
};
};
config.flake.modules.homeManager.facts =
{ lib, ... }:
{
options.facts.desktop = lib.mkOption {
type = lib.types.attrsOf lib.types.anything;
default = { };
};
};
}

Some files were not shown because too many files have changed in this diff Show More