Initial commit
This commit is contained in:
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
.agents/
|
||||
.claude/
|
||||
.codex/
|
||||
.opencode/
|
||||
39
AGENTS.md
Normal file
39
AGENTS.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Repository Guidelines
|
||||
|
||||
## Project Structure & Module Organization
|
||||
This repository is a Den-based NixOS flake. `flake.nix` evaluates `./modules` through `import-tree`, so normal `.nix` files under `modules/` are auto-imported.
|
||||
|
||||
- `modules/hosts/` contains host-specific composition and hardware data for `polaris` and `orion`.
|
||||
- `modules/features/` contains aspects such as desktop, shell, services, and Neovim.
|
||||
- `modules/profiles/` holds higher-level bundles such as `workstation.nix`.
|
||||
- `modules/users/` defines user metadata and per-user behavior.
|
||||
- `modules/secrets/` wires `sops-nix` and stores the encrypted `secrets.yaml`.
|
||||
- `.agents/den/` is a local checkout of Den with source, docs, and examples.
|
||||
|
||||
Keep host files thin. Shared behavior belongs in `modules/features/` or `modules/profiles/`.
|
||||
When Den behavior is unclear, read `.agents/den/docs/`, `.agents/den/modules/`, and `.agents/den/templates/ci/` before guessing.
|
||||
|
||||
## Build, Test, and Development Commands
|
||||
Run commands from the repository root.
|
||||
|
||||
- `nix build .#nixosConfigurations.polaris.config.system.build.toplevel --show-trace`: evaluate and build the Polaris system.
|
||||
- `nix build .#nixosConfigurations.orion.config.system.build.toplevel --show-trace`: evaluate and build the Orion system.
|
||||
- `nixos-rebuild build --flake .#<host>`: use the standard rebuild path without activating it.
|
||||
- `nix fmt`: format Nix files using the flake-provided formatter.
|
||||
- `nix eval .#nixosConfigurations.<host>.config.<option>`: inspect a single option while iterating.
|
||||
|
||||
`nix flake check` is useful for evaluation, but this repo does not define an automated test suite.
|
||||
|
||||
## Coding Style & Naming Conventions
|
||||
Use two-space indentation and standard Nix attrset formatting. Prefer small `let` bindings, lowerCamelCase local names, and lowercase file names such as `sops-password.nix`. Match the surrounding module style instead of reformatting unrelated code.
|
||||
|
||||
Prefer Den composition through `includes`; avoid host-specific duplication when a reusable aspect is clearer.
|
||||
|
||||
## Testing Guidelines
|
||||
There are no first-party unit tests. Treat evaluation and build-only checks as the baseline. For scoped changes, run the matching `nix build` target first, or `nixos-rebuild build --flake .#<host>` when you want the standard rebuild path without activation. Activation and switching are manual steps and should not be performed by contributors or agents.
|
||||
|
||||
## Commit
|
||||
Follow the history style: short imperative subjects, optionally with a conventional prefix, for example `refactor: restructure openssh config`. Keep each commit focused on one concern.
|
||||
|
||||
## 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 about firewall, SSH, disk, or boot changes; those are the highest-risk edits here.
|
||||
13
NOTES.md
Normal file
13
NOTES.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Notes
|
||||
## 16-04
|
||||
- See if pinentry should be a variable and how pure ssh (no gpg anymore) handles pinentry.
|
||||
- Reconsider placement and existence of system-base.nix
|
||||
- Implement system-wide theming system
|
||||
- Do we need separate stateVersions per host?
|
||||
- pinentry.nix should not set programs consuming it explicitly, should probably be host-level concern or smoething.
|
||||
- Primary email schema validation should not be located inside aspects like git.nix but somewhere in the schema definition probably
|
||||
- assertions are defined, not sure if that actually does anything.
|
||||
|
||||
Code style related todos:
|
||||
Consistent rules/guidelines for function or attribute set at root of aspect file.
|
||||
When to nest sets and when to set directly (podman.nix).
|
||||
152
SESSION_LOG.md
Normal file
152
SESSION_LOG.md
Normal file
@@ -0,0 +1,152 @@
|
||||
# Session Log
|
||||
|
||||
## Current Repo State
|
||||
- The git worktree is dirty. Many files were already modified before or during this session. Do not revert unrelated changes.
|
||||
- New main host/user additions are already in place:
|
||||
- hosts: `polaris`, `zenith`, `orion`
|
||||
- users: `kiri`, `ergon`
|
||||
- `zenith` is the Lenovo Yoga Slim 7 ProX 14ARH7 laptop.
|
||||
- `ergon` is the work user and is present on `polaris` and `zenith`, not `orion`.
|
||||
|
||||
## Naming Decisions
|
||||
- Host names chosen:
|
||||
- `polaris` = main machine
|
||||
- `zenith` = laptop
|
||||
- `orion` = VPS
|
||||
- Work user chosen:
|
||||
- `ergon`
|
||||
|
||||
## Den / Architecture Decisions
|
||||
- `kiri` stays on `den._.primary-user`.
|
||||
- `ergon` is explicit and should not use `den._.primary-user`.
|
||||
- Do not introduce a local `admin-user` battery yet. Keep repeated patterns explicit until they stabilize.
|
||||
- Prefer host files thin and move reusable behavior into `modules/features/` or `modules/profiles/`.
|
||||
|
||||
## Den Helper Mental Model
|
||||
- `perHost` / `perUser` are stage gates, not just readability helpers.
|
||||
- `perUser` is not the same as `parametric.exactly`.
|
||||
- Actual behavior:
|
||||
- `perUser` gates entry at exact `{ host, user }`, then evaluates the wrapped aspect under fixed `{ host, user }` with normal `atLeast` matching inside.
|
||||
- `parametric.exactly` is an inner include matcher based on exact context shape.
|
||||
- Practical rule used in this repo:
|
||||
- use `perHost` for host-owned NixOS config that must apply once per host
|
||||
- use `perUser` for host-user-pair HM or NixOS config
|
||||
- avoid `take.*` unless doing low-level Den plumbing
|
||||
|
||||
## Niri / Display Model
|
||||
- `lux.niri` was intentionally collapsed back into one conceptual aspect in `modules/features/niri.nix`.
|
||||
- It now uses:
|
||||
- `den.lib.perHost` for NixOS-side Niri setup
|
||||
- `den.lib.perUser` for HM-side Niri settings
|
||||
- Host monitor layout is a host fact, not a user fact.
|
||||
- `den.schema.host.displays` exists and is the source of truth for monitor facts.
|
||||
- Current `polaris` display layout lives in `modules/infra.nix`.
|
||||
- `programs.niri.settings.outputs` is derived from `host.displays`, so both `kiri` and `ergon` on `polaris` get the same output configuration.
|
||||
- `displays` intentionally has no `enabled` flag; omission means absent.
|
||||
|
||||
## SOPS / SSH / GPG Decisions
|
||||
- Repo-managed GPG was removed from `modules/features/ssh.nix`.
|
||||
- If commit signing is added later, prefer SSH signing rather than restoring repo-managed GPG.
|
||||
- Secret recipient policy currently is:
|
||||
- one admin age recipient
|
||||
- `orion` SSH host key recipient
|
||||
- `.sops.yaml` and `modules/secrets/secrets.yaml` were rekeyed to that policy.
|
||||
|
||||
## Current SOPS Model
|
||||
- SOPS is now host-owned conceptually.
|
||||
- Current host schema fields:
|
||||
- `sopsHostSshKeyPath`
|
||||
- `sopsAdminKeyPath`
|
||||
- `sopsAdminKeyUsers`
|
||||
- Current policy:
|
||||
- `orion` uses `sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]` for host-level NixOS decryption.
|
||||
- local hosts (`polaris`, `zenith`) use `/var/lib/sops-nix/admin-key.txt` for host-level NixOS decryption.
|
||||
- HM SOPS also uses the host-provisioned `/var/lib/sops-nix/admin-key.txt`, but only for users listed in `host.sopsAdminKeyUsers`.
|
||||
- Shared reader group:
|
||||
- `sops-users`
|
||||
- Current host metadata in `modules/infra.nix`:
|
||||
- `polaris.sopsAdminKeyPath = "/var/lib/sops-nix/admin-key.txt"`
|
||||
- `polaris.sopsAdminKeyUsers = [ "kiri" "ergon" ]`
|
||||
- `zenith.sopsAdminKeyPath = "/var/lib/sops-nix/admin-key.txt"`
|
||||
- `zenith.sopsAdminKeyUsers = [ "kiri" "ergon" ]`
|
||||
- `orion.sopsAdminKeyPath = "/var/lib/sops-nix/admin-key.txt"`
|
||||
- `orion.sopsAdminKeyUsers = [ "kiri" ]`
|
||||
- `orion.sopsHostSshKeyPath = "/etc/ssh/ssh_host_ed25519_key"`
|
||||
- Important operational caveat:
|
||||
- the admin key file is expected to be provisioned out-of-band on hosts
|
||||
- config creates `/var/lib/sops-nix` via tmpfiles and adds listed users to `sops-users`, but does not create the private key itself
|
||||
|
||||
## SSH Recovery Policy
|
||||
- `orion` is treated as the remote recovery-critical host.
|
||||
- `modules/features/services/openssh.nix` now owns both:
|
||||
- OpenSSH base config
|
||||
- user `authorizedKeys`
|
||||
- Recovery assertions now enforce for `requiresSshRecovery = true`:
|
||||
- OpenSSH enabled
|
||||
- password auth disabled
|
||||
- root login disabled
|
||||
- `sshRecoveryUsers` non-empty
|
||||
- every recovery user exists
|
||||
- every recovery user has plain `authorizedSshKeys`
|
||||
- `sopsHostSshKeyPath` non-null
|
||||
- SSH exposed through firewall
|
||||
- `AllowUsers = lib.attrNames host.users` is still the intended model.
|
||||
|
||||
## Recent Validation Results
|
||||
- Successfully built after the Niri / SOPS / SSH refactors:
|
||||
- `nix build .#nixosConfigurations.polaris.config.system.build.toplevel --show-trace`
|
||||
- `nix build .#nixosConfigurations.orion.config.system.build.toplevel --show-trace`
|
||||
- `nix build .#nixosConfigurations.zenith.config.system.build.toplevel --show-trace`
|
||||
- Verified by evaluation:
|
||||
- `polaris` Niri outputs for `kiri` and `ergon` match
|
||||
- local hosts resolve `config.sops.age.keyFile = "/var/lib/sops-nix/admin-key.txt"`
|
||||
- `orion` resolves `config.sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]`
|
||||
- HM SOPS for allowed users resolves `"/var/lib/sops-nix/admin-key.txt"`
|
||||
- `ergon@polaris` has `["sops-users", "wheel", "networkmanager"]`
|
||||
- tmpfiles includes `d /var/lib/sops-nix 0750 root sops-users -`
|
||||
|
||||
## Remaining Warnings / Caveats
|
||||
- Builds still emit pre-existing Home Manager default-change warnings:
|
||||
- `gtk.gtk4.theme`
|
||||
- `xdg.userDirs.setSessionVariables`
|
||||
- `programs.git.signing.format`
|
||||
- These warnings were not addressed in this session.
|
||||
- There is no deployment wrapper or automated bootstrap tooling yet.
|
||||
- `nixos-anywhere --copy-host-keys` remains the intended `orion` install approach when preserving the SSH host key for first-boot SOPS decryption.
|
||||
|
||||
## Architecture Contract
|
||||
- Added `ARCHITECTURE.md` as the single durable reference for the repo's intended 1.0 structure.
|
||||
- The contract is grounded in the current codebase:
|
||||
- `schema` and `infra` own facts
|
||||
- `users` own cross-host user baselines
|
||||
- `features` own reusable behavior
|
||||
- `profiles` and `environments` own bundling
|
||||
- `hosts` stay thin and compose the final machine shape
|
||||
- Kept the existing Den helper convention explicit:
|
||||
- `perHost` and `perUser` are stage gates
|
||||
- `parametric.exactly` is only for exact inner matching
|
||||
- avoid new local batteries until the pattern is stable
|
||||
- No repo redesign was done; this was documentation only.
|
||||
- Validation:
|
||||
- doc-only change
|
||||
- no `nix build` run in this session
|
||||
- Small open question for later:
|
||||
- whether `ARCHITECTURE.md` should stay standalone or also be linked from `AGENTS.md` / future README if a contributor-facing index is added
|
||||
|
||||
## Architecture Simplification
|
||||
- Collapsed `environments` into `profiles`.
|
||||
- Current rule is now simpler:
|
||||
- `features` are the smallest reusable behavior units
|
||||
- `profiles` are all named bundles larger than a single feature
|
||||
- `hosts` still own final composition and explicit host-specific exceptions
|
||||
- `modules/environments.nix` was removed.
|
||||
- `graphical` and `development` now live under `lux.profiles._`.
|
||||
- Kept the repeated `provides.kiri` / `provides.ergon` host wiring explicit for now. The duplication is intentional until a shared host-composition pattern is clearly stable enough to justify extraction.
|
||||
- Validation:
|
||||
- `nix build .#nixosConfigurations.polaris.config.system.build.toplevel --show-trace`
|
||||
- `nix build .#nixosConfigurations.orion.config.system.build.toplevel --show-trace`
|
||||
- `nix build .#nixosConfigurations.zenith.config.system.build.toplevel --show-trace`
|
||||
|
||||
## MANUAL INTERVENTION NOTE BY HUMAN USER, NOT AI AGENT
|
||||
Removed `ARCHITECTURE.md`. Pinning down the architecture this explicitly feels too rigid and unnecessary.
|
||||
Perhaps a more generally applicable Design Philsophy would be more helpful and allow for more flexibility.
|
||||
188
TASKS.md
Normal file
188
TASKS.md
Normal file
@@ -0,0 +1,188 @@
|
||||
# Tasks
|
||||
|
||||
This file is an execution queue for independent Codex sessions.
|
||||
|
||||
Rules for every task:
|
||||
- Work in `/home/kiri/.config/nixos`.
|
||||
- Read `SESSION_LOG.md` first.
|
||||
- Preserve current architecture unless the task explicitly asks to refine it.
|
||||
- Keep unrelated changes out of scope.
|
||||
- Validate your work with the relevant `nix build` commands whenever possible.
|
||||
- Do not revert unrelated dirty-worktree changes.
|
||||
- Append a short entry to `SESSION_LOG.md` at the end of the task. The entry should record:
|
||||
- important decisions made
|
||||
- short reasoning behind those decisions
|
||||
- important structural code changes
|
||||
- validation results
|
||||
Keep it concise and useful for the next independent session.
|
||||
|
||||
## Task 1
|
||||
|
||||
```text
|
||||
Work in /home/kiri/.config/nixos.
|
||||
|
||||
Read AGENTS.md and SESSION_LOG.md first.
|
||||
|
||||
Task: remove the remaining Home Manager default-change warnings without changing intended behavior.
|
||||
|
||||
Known warnings from the previous session:
|
||||
- gtk.gtk4.theme
|
||||
- xdg.userDirs.setSessionVariables
|
||||
- programs.git.signing.format
|
||||
|
||||
Likely files:
|
||||
- modules/features/theme.nix
|
||||
- modules/features/xdg.nix
|
||||
- modules/features/dev.nix
|
||||
|
||||
Requirements:
|
||||
- Keep changes minimal and explicit.
|
||||
- Match surrounding Nix style.
|
||||
- Do not restructure unrelated parts of the repo.
|
||||
- Validate by building all three hosts:
|
||||
- nix build .#nixosConfigurations.polaris.config.system.build.toplevel --show-trace
|
||||
- nix build .#nixosConfigurations.orion.config.system.build.toplevel --show-trace
|
||||
- nix build .#nixosConfigurations.zenith.config.system.build.toplevel --show-trace
|
||||
|
||||
Done when:
|
||||
- the known warning set above no longer appears
|
||||
- all three builds succeed
|
||||
|
||||
Expected output:
|
||||
- the code changes
|
||||
- the validation results
|
||||
- a short explanation of the final choices
|
||||
- a short appended entry in SESSION_LOG.md for the next session
|
||||
```
|
||||
|
||||
## Task 2
|
||||
|
||||
```text
|
||||
Work in /home/kiri/.config/nixos.
|
||||
|
||||
Read AGENTS.md and SESSION_LOG.md first, then inspect the current module structure.
|
||||
|
||||
Task: define a short architecture contract for the repo's intended 1.0 state.
|
||||
|
||||
The goal is not to redesign the repo. The goal is to document the structure and philosophy that should remain stable after the current cleanup phase.
|
||||
|
||||
The document should cover:
|
||||
- the layering model of the repo
|
||||
- where things should go
|
||||
- how to think about hosts vs users vs features vs profiles vs environments
|
||||
- the practical mental model for Den helper usage
|
||||
- the abstraction bar for introducing new batteries
|
||||
- how to add or remove a host, user, or feature cleanly
|
||||
|
||||
Requirements:
|
||||
- Keep it concise and operational.
|
||||
- Ground it in the current codebase, not wishful architecture.
|
||||
- Use the existing decisions in SESSION_LOG.md, especially the Den helper mental model.
|
||||
- Prefer one clear reference document over scattered notes.
|
||||
|
||||
Done when:
|
||||
- there is one short durable architecture reference in the repo
|
||||
- it reflects the actual current repo structure
|
||||
- it is specific enough to guide future changes
|
||||
|
||||
Expected output:
|
||||
- the new or updated doc
|
||||
- a short summary of the principles it establishes
|
||||
- any small open questions that should be decided later
|
||||
- a short appended entry in SESSION_LOG.md for the next session
|
||||
```
|
||||
|
||||
## Task 3
|
||||
|
||||
```text
|
||||
Work in /home/kiri/.config/nixos.
|
||||
|
||||
Read AGENTS.md and SESSION_LOG.md first.
|
||||
|
||||
Task: audit the service composition and recovery behavior for the orion host, and make the ownership model clearer where needed.
|
||||
|
||||
Important context:
|
||||
- orion is the remote recovery-critical host
|
||||
- modules/features/services/openssh.nix currently owns the base SSH and recovery assertions
|
||||
- modules/features/services/gitea.nix also writes services.openssh.settings.AllowUsers
|
||||
- the previous session intentionally tightened SSH recovery requirements
|
||||
|
||||
Focus on:
|
||||
- modules/hosts/orion/default.nix
|
||||
- modules/features/services/openssh.nix
|
||||
- modules/features/services/caddy.nix
|
||||
- modules/features/services/gitea.nix
|
||||
- modules/features/services/vaultwarden.nix
|
||||
- modules/features/services/actual.nix
|
||||
- modules/features/services/radicale.nix
|
||||
- any other file directly involved in orion service composition
|
||||
|
||||
Requirements:
|
||||
- Do not do broad architectural refactors outside this scope.
|
||||
- Prefer making ownership explicit over adding clever abstraction.
|
||||
- If a cross-module write is acceptable, document why.
|
||||
- If it is not acceptable, simplify it.
|
||||
- Validate with:
|
||||
- nix build .#nixosConfigurations.orion.config.system.build.toplevel --show-trace
|
||||
|
||||
Done when:
|
||||
- SSH policy ownership is clear
|
||||
- cross-module writes that affect recovery or exposure are removed, consolidated, or explicitly justified
|
||||
- orion still builds successfully
|
||||
- the final state is easier to explain than the starting state
|
||||
|
||||
Expected output:
|
||||
- the code changes
|
||||
- what was ambiguous before
|
||||
- how the final ownership model works
|
||||
- validation results
|
||||
- a short appended entry in SESSION_LOG.md for the next session
|
||||
```
|
||||
|
||||
## Task 4
|
||||
|
||||
```text
|
||||
Work in /home/kiri/.config/nixos.
|
||||
|
||||
Read AGENTS.md and SESSION_LOG.md first. Treat the "Den Helper Mental Model" section as the current convention baseline.
|
||||
|
||||
Task: do a final structural audit and cleanup pass aimed at preparing the repo for an initial 1.0 state.
|
||||
|
||||
This task has four parts:
|
||||
1. Validate every aspect/helper usage against the current Den helper conventions.
|
||||
2. Fix helper mismatches or explicitly justify them.
|
||||
3. Remove dead, stale, empty, or misleading scaffolding where safe.
|
||||
4. Scan the repo for patterns that might deserve extraction into reusable batteries, and produce a small decision list: introduce / defer / reject.
|
||||
|
||||
The helper validation must review usage of:
|
||||
- den.lib.perHost
|
||||
- den.lib.perUser
|
||||
- den.lib.parametric.exactly
|
||||
- den.lib.parametric.atLeast
|
||||
- avoid take.* unless truly needed
|
||||
|
||||
Important constraints:
|
||||
- The goal is repo clarity, not abstraction for its own sake.
|
||||
- A battery should only be introduced if it makes the repo simpler and reflects one stable underlying idea.
|
||||
- One explicit candidate to evaluate is a possible lux.admin-user battery, but do not assume it should exist.
|
||||
- Keep the repo grounded in the conventions already established by the previous session.
|
||||
|
||||
Suggested approach:
|
||||
- inventory aspect/helper usage first
|
||||
- review mismatches and repeated patterns
|
||||
- decide what should remain explicit
|
||||
- make only the cleanup/refactor changes that are justified by that review
|
||||
|
||||
Done when:
|
||||
- every aspect/helper use has been reviewed against the stated conventions
|
||||
- any mismatches are fixed or explicitly justified
|
||||
- the repo is simpler or clearer afterward
|
||||
- there is a short decision list for abstraction candidates, including lux.admin-user
|
||||
|
||||
Expected output:
|
||||
- any code cleanup or helper-fix changes
|
||||
- a short audit summary
|
||||
- a decision list for abstraction candidates, including lux.admin-user
|
||||
- any residual risks or open questions
|
||||
- a short appended entry in SESSION_LOG.md for the next session
|
||||
```
|
||||
741
flake.lock
generated
Normal file
741
flake.lock
generated
Normal file
@@ -0,0 +1,741 @@
|
||||
{
|
||||
"nodes": {
|
||||
"den": {
|
||||
"locked": {
|
||||
"lastModified": 1776133621,
|
||||
"narHash": "sha256-RNbDvS6voiq2GalVHRt6w2EpdlEmmCjUAb6fvPO9PnE=",
|
||||
"owner": "vic",
|
||||
"repo": "den",
|
||||
"rev": "927f4d8e2be40d05c976a91bbec66238c622bbf5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "vic",
|
||||
"ref": "v0.16.0",
|
||||
"repo": "den",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"disko": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1773889306,
|
||||
"narHash": "sha256-PAqwnsBSI9SVC2QugvQ3xeYCB0otOwCacB1ueQj2tgw=",
|
||||
"owner": "nix-community",
|
||||
"repo": "disko",
|
||||
"rev": "5ad85c82cc52264f4beddc934ba57f3789f28347",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "disko",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1751685974,
|
||||
"narHash": "sha256-NKw96t+BgHIYzHUjkTK95FqYRVKB8DHpVhefWSz/kTw=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "549f2762aebeff29a2e5ece7a7dc0f955281a1d1",
|
||||
"revCount": 92,
|
||||
"type": "git",
|
||||
"url": "https://git.lix.systems/lix-project/flake-compat.git"
|
||||
},
|
||||
"original": {
|
||||
"type": "git",
|
||||
"url": "https://git.lix.systems/lix-project/flake-compat.git"
|
||||
}
|
||||
},
|
||||
"flake-compat_2": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1767039857,
|
||||
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
|
||||
"owner": "NixOS",
|
||||
"repo": "flake-compat",
|
||||
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": "nixpkgs-lib"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769996383,
|
||||
"narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "57928607ea566b5db3ad13af0e57e921e6b12381",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts_2": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
"nvf",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769996383,
|
||||
"narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "57928607ea566b5db3ad13af0e57e921e6b12381",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"home-manager": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1776184304,
|
||||
"narHash": "sha256-No6QGBmIv5ChiwKCcbkxjdEQ/RO2ZS1gD7SFy6EZ7rc=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "3c7524c68348ef79ce48308e0978611a050089b2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"import-tree": {
|
||||
"locked": {
|
||||
"lastModified": 1773693634,
|
||||
"narHash": "sha256-BtZ2dtkBdSUnFPPFc+n0kcMbgaTxzFNPv2iaO326Ffg=",
|
||||
"owner": "vic",
|
||||
"repo": "import-tree",
|
||||
"rev": "c41e7d58045f9057880b0d85e1152d6a4430dbf1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "vic",
|
||||
"repo": "import-tree",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"lux-pkgs": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts",
|
||||
"nixpkgs": "nixpkgs_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1772315038,
|
||||
"narHash": "sha256-YL6NQd97AiZGe/Q4ZWxZaguKVHL0pfNvP/Cqgl/oh4g=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "d7660146e70475c096bed703e4dad687a58e13dc",
|
||||
"revCount": 1,
|
||||
"type": "git",
|
||||
"url": "ssh://gitea@orion/kiri/lux-pkgs"
|
||||
},
|
||||
"original": {
|
||||
"type": "git",
|
||||
"url": "ssh://gitea@orion/kiri/lux-pkgs"
|
||||
}
|
||||
},
|
||||
"mnw": {
|
||||
"locked": {
|
||||
"lastModified": 1770419553,
|
||||
"narHash": "sha256-b1XqsH7AtVf2dXmq2iyRr2NC1yG7skY7Z6N2MpWHlK4=",
|
||||
"owner": "Gerg-L",
|
||||
"repo": "mnw",
|
||||
"rev": "2aaffa8030d0b262176146adbb6b0e6374ce2957",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "Gerg-L",
|
||||
"repo": "mnw",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"ndg": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nvf",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1768214250,
|
||||
"narHash": "sha256-hnBZDQWUxJV3KbtvyGW5BKLO/fAwydrxm5WHCWMQTbw=",
|
||||
"owner": "feel-co",
|
||||
"repo": "ndg",
|
||||
"rev": "a6bd3c1ce2668d096e4fdaaa03ad7f03ba1fbca8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "feel-co",
|
||||
"ref": "refs/tags/v2.6.0",
|
||||
"repo": "ndg",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"niri": {
|
||||
"inputs": {
|
||||
"niri-stable": "niri-stable",
|
||||
"niri-unstable": "niri-unstable",
|
||||
"nixpkgs": "nixpkgs_4",
|
||||
"nixpkgs-stable": "nixpkgs-stable",
|
||||
"xwayland-satellite-stable": "xwayland-satellite-stable",
|
||||
"xwayland-satellite-unstable": "xwayland-satellite-unstable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1776337800,
|
||||
"narHash": "sha256-yZvCnzf0NDL1vfMGRBkKthRmg8V93FzQ4CQNXhxh0Wg=",
|
||||
"owner": "sodiboo",
|
||||
"repo": "niri-flake",
|
||||
"rev": "3877b9fd1f78e831b3ea223f9e992c758d13df0f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "sodiboo",
|
||||
"repo": "niri-flake",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"niri-stable": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1756556321,
|
||||
"narHash": "sha256-RLD89dfjN0RVO86C/Mot0T7aduCygPGaYbog566F0Qo=",
|
||||
"owner": "YaLTeR",
|
||||
"repo": "niri",
|
||||
"rev": "01be0e65f4eb91a9cd624ac0b76aaeab765c7294",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "YaLTeR",
|
||||
"ref": "v25.08",
|
||||
"repo": "niri",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"niri-unstable": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1776332135,
|
||||
"narHash": "sha256-7cKy5sGmN4Yt47Op0+A/b3iEMk/E2Ru+UiI42KfiEPc=",
|
||||
"owner": "YaLTeR",
|
||||
"repo": "niri",
|
||||
"rev": "892470afd3dce5396828dd9b211b19210a16eaeb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "YaLTeR",
|
||||
"repo": "niri",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix-wrapper-modules": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_5"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1776287200,
|
||||
"narHash": "sha256-rBg1UXDO/EWWrlRoJvv9tj75cjCEoaAQTRO+7ISVCrQ=",
|
||||
"owner": "BirdeeHub",
|
||||
"repo": "nix-wrapper-modules",
|
||||
"rev": "0e699fc8acd4ce08b4bbf4175f8e95cca68a3977",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "BirdeeHub",
|
||||
"repo": "nix-wrapper-modules",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixos-hardware": {
|
||||
"locked": {
|
||||
"lastModified": 1775490113,
|
||||
"narHash": "sha256-2ZBhDNZZwYkRmefK5XLOusCJHnoeKkoN95hoSGgMxWM=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixos-hardware",
|
||||
"rev": "c775c2772ba56e906cbeb4e0b2db19079ef11ff7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "master",
|
||||
"repo": "nixos-hardware",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1773628058,
|
||||
"narHash": "sha256-hpXH0z3K9xv0fHaje136KY872VT2T5uwxtezlAskQgY=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "f8573b9c935cfaa162dd62cc9e75ae2db86f85df",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-lib": {
|
||||
"locked": {
|
||||
"lastModified": 1769909678,
|
||||
"narHash": "sha256-cBEymOf4/o3FD5AZnzC3J9hLbiZ+QDT/KDuyHXVJOpM=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"rev": "72716169fe93074c333e8d0173151350670b824c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1776067740,
|
||||
"narHash": "sha256-B35lpsqnSZwn1Lmz06BpwF7atPgFmUgw1l8KAV3zpVQ=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "7e495b747b51f95ae15e74377c5ce1fe69c1765f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-25.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-stable_2": {
|
||||
"locked": {
|
||||
"lastModified": 1776067740,
|
||||
"narHash": "sha256-B35lpsqnSZwn1Lmz06BpwF7atPgFmUgw1l8KAV3zpVQ=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "7e495b747b51f95ae15e74377c5ce1fe69c1765f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-25.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_10": {
|
||||
"locked": {
|
||||
"lastModified": 1768564909,
|
||||
"narHash": "sha256-Kell/SpJYVkHWMvnhqJz/8DqQg2b6PguxVWOuadbHCc=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "e4bae1bd10c9c57b2cf517953ab70060a828ee6f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1775423009,
|
||||
"narHash": "sha256-vPKLpjhIVWdDrfiUM8atW6YkIggCEKdSAlJPzzhkQlw=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "68d8aa3d661f0e6bd5862291b5bb263b2a6595c9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1772173633,
|
||||
"narHash": "sha256-MOH58F4AIbCkh6qlQcwMycyk5SWvsqnS/TCfnqDlpj4=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "c0f3d81a7ddbc2b1332be0d8481a672b4f6004d6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_4": {
|
||||
"locked": {
|
||||
"lastModified": 1776169885,
|
||||
"narHash": "sha256-l/iNYDZ4bGOAFQY2q8y5OAfBBtrDAaPuRQqWaFHVRXM=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "4bd9165a9165d7b5e33ae57f3eecbcb28fb231c9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_5": {
|
||||
"locked": {
|
||||
"lastModified": 1775579569,
|
||||
"narHash": "sha256-/m3yyS/EnXqoPGBJYVy4jTOsirdgsEZ3JdN2gGkBr14=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "dfd9566f82a6e1d55c30f861879186440614696e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_6": {
|
||||
"locked": {
|
||||
"lastModified": 1776255774,
|
||||
"narHash": "sha256-bo9Hbl5yPjDRldsn1Stnbsmn/nPF0cVlowuLSGHduuA=",
|
||||
"rev": "566acc07c54dc807f91625bb286cb9b321b5f42a",
|
||||
"type": "tarball",
|
||||
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.05pre980800.566acc07c54d/nixexprs.tar.xz"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz"
|
||||
}
|
||||
},
|
||||
"nixpkgs_7": {
|
||||
"locked": {
|
||||
"lastModified": 1776169885,
|
||||
"narHash": "sha256-l/iNYDZ4bGOAFQY2q8y5OAfBBtrDAaPuRQqWaFHVRXM=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "4bd9165a9165d7b5e33ae57f3eecbcb28fb231c9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_8": {
|
||||
"locked": {
|
||||
"lastModified": 1774386573,
|
||||
"narHash": "sha256-4hAV26quOxdC6iyG7kYaZcM3VOskcPUrdCQd/nx8obc=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "46db2e09e1d3f113a13c0d7b81e2f221c63b8ce9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_9": {
|
||||
"locked": {
|
||||
"lastModified": 1775888245,
|
||||
"narHash": "sha256-nwASzrRDD1JBEu/o8ekKYEXm/oJW6EMCzCRdrwcLe90=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "13043924aaa7375ce482ebe2494338e058282925",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"noctalia": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_7",
|
||||
"noctalia-qs": "noctalia-qs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1776302695,
|
||||
"narHash": "sha256-xZc9o1JLQpmWn2Dqui323+Tq2Ai4sSdtdvbFZCs4qLo=",
|
||||
"owner": "noctalia-dev",
|
||||
"repo": "noctalia-shell",
|
||||
"rev": "a7c724181fca5d1aff2d47b18fa733504cfdbda2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "noctalia-dev",
|
||||
"repo": "noctalia-shell",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"noctalia-qs": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"noctalia",
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": "systems",
|
||||
"treefmt-nix": "treefmt-nix"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1775957204,
|
||||
"narHash": "sha256-d4CVRtAty2GzDYXx4xYQmR+nlOjjKovyprQfZhgLckU=",
|
||||
"owner": "noctalia-dev",
|
||||
"repo": "noctalia-qs",
|
||||
"rev": "68e82fe34c68ee839a9c37e3466820e266af0c86",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "noctalia-dev",
|
||||
"repo": "noctalia-qs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nvf": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"flake-parts": "flake-parts_2",
|
||||
"mnw": "mnw",
|
||||
"ndg": "ndg",
|
||||
"nixpkgs": "nixpkgs_8",
|
||||
"systems": "systems_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1776331518,
|
||||
"narHash": "sha256-Hj6Rqmyv7f2CkQN4f3NLnK0VUJM/ypfHIrkGckA4WQA=",
|
||||
"owner": "notashelf",
|
||||
"repo": "nvf",
|
||||
"rev": "39416a521dbbc3b722de1bb3607cddaa1e698f4a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "notashelf",
|
||||
"repo": "nvf",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"den": "den",
|
||||
"disko": "disko",
|
||||
"home-manager": "home-manager",
|
||||
"import-tree": "import-tree",
|
||||
"lux-pkgs": "lux-pkgs",
|
||||
"niri": "niri",
|
||||
"nix-wrapper-modules": "nix-wrapper-modules",
|
||||
"nixos-hardware": "nixos-hardware",
|
||||
"nixpkgs": "nixpkgs_6",
|
||||
"nixpkgs-stable": "nixpkgs-stable_2",
|
||||
"noctalia": "noctalia",
|
||||
"nvf": "nvf",
|
||||
"sops-nix": "sops-nix",
|
||||
"vicinae-extensions": "vicinae-extensions"
|
||||
}
|
||||
},
|
||||
"sops-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_9"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1776119890,
|
||||
"narHash": "sha256-Zm6bxLNnEOYuS/SzrAGsYuXSwk3cbkRQZY0fJnk8a5M=",
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"rev": "d4971dd58c6627bfee52a1ad4237637c0a2fb0cd",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1689347949,
|
||||
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default-linux",
|
||||
"rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default-linux",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_2": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_3": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"treefmt-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"noctalia",
|
||||
"noctalia-qs",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1775636079,
|
||||
"narHash": "sha256-pc20NRoMdiar8oPQceQT47UUZMBTiMdUuWrYu2obUP0=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "790751ff7fd3801feeaf96d7dc416a8d581265ba",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"vicinae": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"vicinae-extensions",
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"vicinae-extensions",
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1768856963,
|
||||
"narHash": "sha256-u5bWDuwk6oieTnvm1YjNotcYK8iJSddH5+S68+X4TSc=",
|
||||
"owner": "vicinaehq",
|
||||
"repo": "vicinae",
|
||||
"rev": "934bc0ad47be6dbd6498a0dac655c4613fd0ab27",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "vicinaehq",
|
||||
"repo": "vicinae",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"vicinae-extensions": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat_2",
|
||||
"nixpkgs": "nixpkgs_10",
|
||||
"systems": "systems_3",
|
||||
"vicinae": "vicinae"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1775911073,
|
||||
"narHash": "sha256-Fa5JvMFVwBzbnOjEV2Cer8ak0zF/CDwdHT7+wslL30w=",
|
||||
"owner": "vicinaehq",
|
||||
"repo": "extensions",
|
||||
"rev": "d12bcb134d45dedad1a28a18e1cd8807353338d0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "vicinaehq",
|
||||
"repo": "extensions",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"xwayland-satellite-stable": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1755491097,
|
||||
"narHash": "sha256-m+9tUfsmBeF2Gn4HWa6vSITZ4Gz1eA1F5Kh62B0N4oE=",
|
||||
"owner": "Supreeeme",
|
||||
"repo": "xwayland-satellite",
|
||||
"rev": "388d291e82ffbc73be18169d39470f340707edaa",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "Supreeeme",
|
||||
"ref": "v0.7",
|
||||
"repo": "xwayland-satellite",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"xwayland-satellite-unstable": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1773622265,
|
||||
"narHash": "sha256-wToKwH7IgWdGLMSIWksEDs4eumR6UbbsuPQ42r0oTXQ=",
|
||||
"owner": "Supreeeme",
|
||||
"repo": "xwayland-satellite",
|
||||
"rev": "a879e5e0896a326adc79c474bf457b8b99011027",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "Supreeeme",
|
||||
"repo": "xwayland-satellite",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
38
flake.nix
Normal file
38
flake.nix
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
description = "NixOS Configuration";
|
||||
|
||||
inputs = {
|
||||
den.url = "github:vic/den/v0.16.0";
|
||||
disko.url = "github:nix-community/disko";
|
||||
home-manager.url = "github:nix-community/home-manager";
|
||||
import-tree.url = "github:vic/import-tree";
|
||||
niri.url = "github:sodiboo/niri-flake";
|
||||
nix-wrapper-modules.url = "github:BirdeeHub/nix-wrapper-modules";
|
||||
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
|
||||
nixpkgs.url = "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz";
|
||||
nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-25.11";
|
||||
noctalia.url = "github:noctalia-dev/noctalia-shell";
|
||||
nvf.url = "github:notashelf/nvf";
|
||||
sops-nix.url = "github:Mic92/sops-nix";
|
||||
|
||||
#vicinae.url = "github:vicinaehq/vicinae";
|
||||
vicinae-extensions.url = "github:vicinaehq/extensions";
|
||||
|
||||
lux-pkgs.url = "git+ssh://gitea@orion/kiri/lux-pkgs";
|
||||
};
|
||||
|
||||
outputs =
|
||||
inputs:
|
||||
let
|
||||
flake = (inputs.nixpkgs.lib.evalModules {
|
||||
modules = [ (inputs.import-tree ./modules) ];
|
||||
specialArgs.inputs = inputs;
|
||||
}).config.flake;
|
||||
in
|
||||
flake
|
||||
// {
|
||||
formatter = inputs.nixpkgs.lib.genAttrs flake.den.systems (
|
||||
system: inputs.nixpkgs.legacyPackages.${system}.nixfmt
|
||||
);
|
||||
};
|
||||
}
|
||||
35
modules/bundles.nix
Normal file
35
modules/bundles.nix
Normal file
@@ -0,0 +1,35 @@
|
||||
{ den, lux, ... }:
|
||||
{
|
||||
lux.bundles._.local-session = {
|
||||
includes = with lux; [
|
||||
nix
|
||||
region-nl
|
||||
sddm
|
||||
niri
|
||||
audio
|
||||
bluetooth
|
||||
clipboard
|
||||
flatpak
|
||||
fonts
|
||||
local-apps
|
||||
networking
|
||||
pinentry
|
||||
printing
|
||||
qbittorrent-client
|
||||
system-base
|
||||
vicinae
|
||||
xdg
|
||||
theme
|
||||
noctalia
|
||||
];
|
||||
};
|
||||
|
||||
lux.bundles._.development = {
|
||||
includes = with lux; [
|
||||
git
|
||||
dev-tools
|
||||
podman
|
||||
gemini
|
||||
];
|
||||
};
|
||||
}
|
||||
23
modules/defaults.nix
Normal file
23
modules/defaults.nix
Normal file
@@ -0,0 +1,23 @@
|
||||
{ den, ... }:
|
||||
let
|
||||
configState = "24.05";
|
||||
in
|
||||
{
|
||||
den.default = {
|
||||
includes = [
|
||||
den._.define-user
|
||||
den._.hostname
|
||||
];
|
||||
|
||||
nixos.system.stateVersion = configState;
|
||||
homeManager.home.stateVersion = configState;
|
||||
};
|
||||
|
||||
den.ctx.user.includes = [ den._.mutual-provider ];
|
||||
_module.args.__findFile = den.lib.__findFile;
|
||||
|
||||
den.ctx.hm-host.nixos.home-manager = {
|
||||
useGlobalPkgs = true;
|
||||
backupFileExtension = "bak";
|
||||
};
|
||||
}
|
||||
9
modules/den.nix
Normal file
9
modules/den.nix
Normal file
@@ -0,0 +1,9 @@
|
||||
{ inputs, den, ... }:
|
||||
{
|
||||
imports = [
|
||||
inputs.den.flakeModule
|
||||
(inputs.den.namespace "lux" true)
|
||||
];
|
||||
|
||||
flake.den = den;
|
||||
}
|
||||
564
modules/features/_noctalia-config.nix
Normal file
564
modules/features/_noctalia-config.nix
Normal file
@@ -0,0 +1,564 @@
|
||||
{
|
||||
settingsVersion = 53;
|
||||
bar = {
|
||||
barType = "simple";
|
||||
position = "top";
|
||||
monitors = [];
|
||||
density = "default";
|
||||
showOutline = false;
|
||||
showCapsule = false;
|
||||
capsuleOpacity = 1;
|
||||
capsuleColorKey = "none";
|
||||
widgetSpacing = 6;
|
||||
contentPadding = 2;
|
||||
fontScale = 1;
|
||||
backgroundOpacity = 0;
|
||||
useSeparateOpacity = false;
|
||||
floating = false;
|
||||
marginVertical = 6;
|
||||
marginHorizontal = 8;
|
||||
frameThickness = 0;
|
||||
frameRadius = 0;
|
||||
outerCorners = false;
|
||||
hideOnOverview = true;
|
||||
displayMode = "always_visible";
|
||||
autoHideDelay = 500;
|
||||
autoShowDelay = 150;
|
||||
showOnWorkspaceSwitch = true;
|
||||
widgets = {
|
||||
left = [
|
||||
{
|
||||
colorizeSystemIcon = "none";
|
||||
customIconPath = "";
|
||||
enableColorization = false;
|
||||
icon = "rocket";
|
||||
iconColor = "none";
|
||||
id = "Launcher";
|
||||
useDistroLogo = false;
|
||||
}
|
||||
{
|
||||
characterCount = 2;
|
||||
colorizeIcons = true;
|
||||
emptyColor = "secondary";
|
||||
enableScrollWheel = true;
|
||||
focusedColor = "primary";
|
||||
followFocusedScreen = false;
|
||||
groupedBorderOpacity = 1;
|
||||
hideUnoccupied = true;
|
||||
iconScale = 0.75;
|
||||
id = "Workspace";
|
||||
labelMode = "none";
|
||||
occupiedColor = "secondary";
|
||||
pillSize = 0.6;
|
||||
showApplications = true;
|
||||
showBadge = false;
|
||||
showLabelsOnlyWhenOccupied = true;
|
||||
unfocusedIconsOpacity = 1;
|
||||
}
|
||||
];
|
||||
center = [
|
||||
{
|
||||
clockColor = "none";
|
||||
customFont = "";
|
||||
formatHorizontal = "HH:mm ddd, MMM dd";
|
||||
formatVertical = "HH mm - dd MM";
|
||||
id = "Clock";
|
||||
tooltipFormat = "HH:mm ddd, MMM dd";
|
||||
useCustomFont = false;
|
||||
}
|
||||
];
|
||||
right = [
|
||||
{
|
||||
blacklist = [];
|
||||
chevronColor = "none";
|
||||
colorizeIcons = false;
|
||||
drawerEnabled = true;
|
||||
hidePassive = false;
|
||||
id = "Tray";
|
||||
pinned = [];
|
||||
}
|
||||
{
|
||||
displayMode = "onhover";
|
||||
iconColor = "none";
|
||||
id = "Volume";
|
||||
middleClickCommand = "pwvucontrol || pavucontrol";
|
||||
textColor = "none";
|
||||
}
|
||||
{
|
||||
colorizeDistroLogo = false;
|
||||
colorizeSystemIcon = "none";
|
||||
customIconPath = "";
|
||||
enableColorization = false;
|
||||
icon = "noctalia";
|
||||
id = "ControlCenter";
|
||||
useDistroLogo = false;
|
||||
}
|
||||
];
|
||||
};
|
||||
screenOverrides = [];
|
||||
};
|
||||
general = {
|
||||
avatarImage = "/home/kiri/.face";
|
||||
dimmerOpacity = 0;
|
||||
showScreenCorners = false;
|
||||
forceBlackScreenCorners = false;
|
||||
scaleRatio = 1;
|
||||
radiusRatio = 0.5;
|
||||
iRadiusRatio = 0.5;
|
||||
boxRadiusRatio = 0;
|
||||
screenRadiusRatio = 0;
|
||||
animationSpeed = 2;
|
||||
animationDisabled = false;
|
||||
compactLockScreen = false;
|
||||
lockScreenAnimations = false;
|
||||
lockOnSuspend = true;
|
||||
showSessionButtonsOnLockScreen = true;
|
||||
showHibernateOnLockScreen = false;
|
||||
enableLockScreenMediaControls = false;
|
||||
enableShadows = true;
|
||||
shadowDirection = "bottom_right";
|
||||
shadowOffsetX = 2;
|
||||
shadowOffsetY = 3;
|
||||
language = "";
|
||||
allowPanelsOnScreenWithoutBar = true;
|
||||
showChangelogOnStartup = true;
|
||||
telemetryEnabled = false;
|
||||
enableLockScreenCountdown = true;
|
||||
lockScreenCountdownDuration = 10000;
|
||||
autoStartAuth = false;
|
||||
allowPasswordWithFprintd = false;
|
||||
clockStyle = "custom";
|
||||
clockFormat = "hh\\nmm";
|
||||
passwordChars = false;
|
||||
lockScreenMonitors = [];
|
||||
lockScreenBlur = 0;
|
||||
lockScreenTint = 0;
|
||||
keybinds = {
|
||||
keyUp = [
|
||||
"Up"
|
||||
"Ctrl+K"
|
||||
];
|
||||
keyDown = [
|
||||
"Down"
|
||||
"Ctrl+J"
|
||||
];
|
||||
keyLeft = [
|
||||
"Left"
|
||||
"Ctrl+H"
|
||||
];
|
||||
keyRight = [
|
||||
"Right"
|
||||
"Ctrl+L"
|
||||
];
|
||||
keyEnter = [
|
||||
"Return"
|
||||
];
|
||||
keyEscape = [
|
||||
"Esc"
|
||||
];
|
||||
keyRemove = [
|
||||
"Del"
|
||||
];
|
||||
};
|
||||
reverseScroll = false;
|
||||
};
|
||||
ui = {
|
||||
fontDefault = "Comfortaa Medium";
|
||||
fontFixed = "FiraCode Nerd Font";
|
||||
fontDefaultScale = 1;
|
||||
fontFixedScale = 1;
|
||||
tooltipsEnabled = true;
|
||||
boxBorderEnabled = false;
|
||||
panelBackgroundOpacity = 1;
|
||||
panelsAttachedToBar = true;
|
||||
settingsPanelMode = "attached";
|
||||
settingsPanelSideBarCardStyle = false;
|
||||
};
|
||||
location = {
|
||||
name = "Meterik, Limburg";
|
||||
weatherEnabled = true;
|
||||
weatherShowEffects = true;
|
||||
useFahrenheit = false;
|
||||
use12hourFormat = false;
|
||||
showWeekNumberInCalendar = true;
|
||||
showCalendarEvents = true;
|
||||
showCalendarWeather = true;
|
||||
analogClockInCalendar = false;
|
||||
firstDayOfWeek = "unknown character to parse: -";
|
||||
",
|
||||
" = "unknown character to parse: h";
|
||||
deWeatherTimezone = false;
|
||||
hideWeatherCityName = false;
|
||||
};
|
||||
calendar = {
|
||||
cards = [
|
||||
{
|
||||
enabled = true;
|
||||
id = "calendar-header-card";
|
||||
}
|
||||
{
|
||||
enabled = true;
|
||||
id = "calendar-month-card";
|
||||
}
|
||||
{
|
||||
enabled = true;
|
||||
id = "weather-card";
|
||||
}
|
||||
];
|
||||
};
|
||||
wallpaper = {
|
||||
enabled = true;
|
||||
overviewEnabled = false;
|
||||
directory = "/home/kiri/media/images/wallpapers";
|
||||
monitorDirectories = [];
|
||||
enableMultiMonitorDirectories = false;
|
||||
showHiddenFiles = false;
|
||||
viewMode = "recursive";
|
||||
setWallpaperOnAllMonitors = true;
|
||||
fillMode = "crop";
|
||||
fillColor = "#000000";
|
||||
useSolidColor = false;
|
||||
solidColor = "#1a1a2e";
|
||||
automationEnabled = false;
|
||||
wallpaperChangeMode = "random";
|
||||
randomIntervalSec = 300;
|
||||
transitionDuration = 1500;
|
||||
transitionType = "random";
|
||||
skipStartupTransition = false;
|
||||
transitionEdgeSmoothness = 5.0e-2;
|
||||
panelPosition = "follow_bar";
|
||||
hideWallpaperFilenames = false;
|
||||
overviewBlur = 0.4;
|
||||
overviewTint = 0.6;
|
||||
useWallhaven = false;
|
||||
wallhavenQuery = "";
|
||||
wallhavenSorting = "relevance";
|
||||
wallhavenOrder = "desc";
|
||||
wallhavenCategories = "111";
|
||||
wallhavenPurity = "100";
|
||||
wallhavenRatios = "";
|
||||
wallhavenApiKey = "";
|
||||
wallhavenResolutionMode = "atleast";
|
||||
wallhavenResolutionWidth = "";
|
||||
wallhavenResolutionHeight = "";
|
||||
sortOrder = "name";
|
||||
favorites = [];
|
||||
};
|
||||
appLauncher = {
|
||||
enableClipboardHistory = true;
|
||||
autoPasteClipboard = false;
|
||||
enableClipPreview = true;
|
||||
clipboardWrapText = true;
|
||||
clipboardWatchTextCommand = "wl-paste --type text --watch cliphist store";
|
||||
clipboardWatchImageCommand = "wl-paste --type image --watch cliphist store";
|
||||
position = "top_center";
|
||||
pinnedApps = [];
|
||||
useApp2Unit = false;
|
||||
sortByMostUsed = true;
|
||||
terminalCommand = "kitty -e";
|
||||
customLaunchPrefixEnabled = false;
|
||||
customLaunchPrefix = "";
|
||||
viewMode = "grid";
|
||||
showCategories = true;
|
||||
iconMode = "tabler";
|
||||
showIconBackground = false;
|
||||
enableSettingsSearch = true;
|
||||
enableWindowsSearch = true;
|
||||
enableSessionSearch = true;
|
||||
ignoreMouseInput = false;
|
||||
screenshotAnnotationTool = "";
|
||||
overviewLayer = false;
|
||||
density = "default";
|
||||
};
|
||||
controlCenter = {
|
||||
position = "close_to_bar_button";
|
||||
diskPath = "/";
|
||||
shortcuts = {
|
||||
left = [
|
||||
{
|
||||
id = "Network";
|
||||
}
|
||||
{
|
||||
id = "Bluetooth";
|
||||
}
|
||||
{
|
||||
id = "WallpaperSelector";
|
||||
}
|
||||
{
|
||||
id = "NoctaliaPerformance";
|
||||
}
|
||||
];
|
||||
right = [
|
||||
{
|
||||
id = "Notifications";
|
||||
}
|
||||
{
|
||||
id = "PowerProfile";
|
||||
}
|
||||
{
|
||||
id = "KeepAwake";
|
||||
}
|
||||
{
|
||||
id = "NightLight";
|
||||
}
|
||||
];
|
||||
};
|
||||
cards = [
|
||||
{
|
||||
enabled = true;
|
||||
id = "profile-card";
|
||||
}
|
||||
{
|
||||
enabled = true;
|
||||
id = "shortcuts-card";
|
||||
}
|
||||
{
|
||||
enabled = true;
|
||||
id = "audio-card";
|
||||
}
|
||||
{
|
||||
enabled = false;
|
||||
id = "brightness-card";
|
||||
}
|
||||
{
|
||||
enabled = true;
|
||||
id = "weather-card";
|
||||
}
|
||||
{
|
||||
enabled = true;
|
||||
id = "media-sysmon-card";
|
||||
}
|
||||
];
|
||||
};
|
||||
systemMonitor = {
|
||||
cpuWarningThreshold = 80;
|
||||
cpuCriticalThreshold = 90;
|
||||
tempWarningThreshold = 80;
|
||||
tempCriticalThreshold = 90;
|
||||
gpuWarningThreshold = 80;
|
||||
gpuCriticalThreshold = 90;
|
||||
memWarningThreshold = 80;
|
||||
memCriticalThreshold = 90;
|
||||
swapWarningThreshold = 80;
|
||||
swapCriticalThreshold = 90;
|
||||
diskWarningThreshold = 80;
|
||||
diskCriticalThreshold = 90;
|
||||
diskAvailWarningThreshold = 20;
|
||||
diskAvailCriticalThreshold = 10;
|
||||
batteryWarningThreshold = 20;
|
||||
batteryCriticalThreshold = 5;
|
||||
enableDgpuMonitoring = false;
|
||||
useCustomColors = false;
|
||||
warningColor = "";
|
||||
criticalColor = "";
|
||||
externalMonitor = "resources || missioncenter || jdsystemmonitor || corestats || system-monitoring-center || gnome-system-monitor || plasma-systemmonitor || mate-system-monitor || ukui-system-monitor || deepin-system-monitor || pantheon-system-monitor";
|
||||
};
|
||||
dock = {
|
||||
enabled = false;
|
||||
position = "bottom";
|
||||
displayMode = "exclusive";
|
||||
dockType = "floating";
|
||||
backgroundOpacity = 1;
|
||||
floatingRatio = 1;
|
||||
size = 1;
|
||||
onlySameOutput = true;
|
||||
monitors = [];
|
||||
pinnedApps = [];
|
||||
colorizeIcons = false;
|
||||
showLauncherIcon = false;
|
||||
launcherPosition = "end";
|
||||
launcherIconColor = "none";
|
||||
pinnedStatic = false;
|
||||
inactiveIndicators = false;
|
||||
groupApps = false;
|
||||
groupContextMenuMode = "extended";
|
||||
groupClickAction = "cycle";
|
||||
groupIndicatorStyle = "dots";
|
||||
deadOpacity = 0.6;
|
||||
animationSpeed = 1;
|
||||
sitOnFrame = false;
|
||||
showFrameIndicator = true;
|
||||
};
|
||||
network = {
|
||||
wifiEnabled = true;
|
||||
airplaneModeEnabled = false;
|
||||
bluetoothRssiPollingEnabled = false;
|
||||
bluetoothRssiPollIntervalMs = 60000;
|
||||
networkPanelView = "wifi";
|
||||
wifiDetailsViewMode = "grid";
|
||||
bluetoothDetailsViewMode = "grid";
|
||||
bluetoothHideUnnamedDevices = false;
|
||||
disableDiscoverability = false;
|
||||
};
|
||||
sessionMenu = {
|
||||
enableCountdown = true;
|
||||
countdownDuration = 10000;
|
||||
position = "center";
|
||||
showHeader = true;
|
||||
showKeybinds = true;
|
||||
largeButtonsStyle = true;
|
||||
largeButtonsLayout = "single-row";
|
||||
powerOptions = [
|
||||
{
|
||||
action = "lock";
|
||||
command = "";
|
||||
countdownEnabled = true;
|
||||
enabled = true;
|
||||
keybind = "1";
|
||||
}
|
||||
{
|
||||
action = "suspend";
|
||||
command = "";
|
||||
countdownEnabled = true;
|
||||
enabled = true;
|
||||
keybind = "2";
|
||||
}
|
||||
{
|
||||
action = "hibernate";
|
||||
command = "";
|
||||
countdownEnabled = true;
|
||||
enabled = true;
|
||||
keybind = "3";
|
||||
}
|
||||
{
|
||||
action = "reboot";
|
||||
command = "";
|
||||
countdownEnabled = true;
|
||||
enabled = true;
|
||||
keybind = "4";
|
||||
}
|
||||
{
|
||||
action = "logout";
|
||||
command = "";
|
||||
countdownEnabled = true;
|
||||
enabled = true;
|
||||
keybind = "5";
|
||||
}
|
||||
{
|
||||
action = "shutdown";
|
||||
command = "";
|
||||
countdownEnabled = true;
|
||||
enabled = true;
|
||||
keybind = "6";
|
||||
}
|
||||
{
|
||||
action = "rebootToUefi";
|
||||
command = "";
|
||||
countdownEnabled = true;
|
||||
enabled = true;
|
||||
keybind = "";
|
||||
}
|
||||
];
|
||||
};
|
||||
notifications = {
|
||||
enabled = true;
|
||||
enableMarkdown = false;
|
||||
density = "default";
|
||||
monitors = [];
|
||||
location = "top_right";
|
||||
overlayLayer = true;
|
||||
backgroundOpacity = 1;
|
||||
respectExpireTimeout = false;
|
||||
lowUrgencyDuration = 3;
|
||||
normalUrgencyDuration = 8;
|
||||
criticalUrgencyDuration = 15;
|
||||
clearDismissed = true;
|
||||
saveToHistory = {
|
||||
low = true;
|
||||
normal = true;
|
||||
critical = true;
|
||||
};
|
||||
sounds = {
|
||||
enabled = false;
|
||||
volume = 0.5;
|
||||
separateSounds = false;
|
||||
criticalSoundFile = "";
|
||||
normalSoundFile = "";
|
||||
lowSoundFile = "";
|
||||
excludedApps = "discord,firefox,chrome,chromium,edge";
|
||||
};
|
||||
enableMediaToast = false;
|
||||
enableKeyboardLayoutToast = true;
|
||||
enableBatteryToast = true;
|
||||
};
|
||||
osd = {
|
||||
enabled = true;
|
||||
location = "top_right";
|
||||
autoHideMs = 2000;
|
||||
overlayLayer = true;
|
||||
backgroundOpacity = 1;
|
||||
enabledTypes = [
|
||||
0
|
||||
1
|
||||
2
|
||||
];
|
||||
monitors = [];
|
||||
};
|
||||
audio = {
|
||||
volumeStep = 5;
|
||||
volumeOverdrive = false;
|
||||
cavaFrameRate = 30;
|
||||
visualizerType = "linear";
|
||||
mprisBlacklist = [];
|
||||
preferredPlayer = "";
|
||||
volumeFeedback = false;
|
||||
volumeFeedbackSoundFile = "";
|
||||
};
|
||||
brightness = {
|
||||
brightnessStep = 5;
|
||||
enforceMinimum = true;
|
||||
enableDdcSupport = false;
|
||||
backlightDeviceMappings = [];
|
||||
};
|
||||
colorSchemes = {
|
||||
useWallpaperColors = false;
|
||||
predefinedScheme = "Kanagawa";
|
||||
darkMode = true;
|
||||
schedulingMode = "off";
|
||||
manualSunrise = "06:30";
|
||||
manualSunset = "18:30";
|
||||
generationMethod = "tonal-spot";
|
||||
monitorForColors = "";
|
||||
};
|
||||
templates = {
|
||||
activeTemplates = [];
|
||||
enableUserTheming = false;
|
||||
};
|
||||
nightLight = {
|
||||
enabled = false;
|
||||
forced = false;
|
||||
autoSchedule = true;
|
||||
nightTemp = "4000";
|
||||
dayTemp = "6500";
|
||||
manualSunrise = "06:30";
|
||||
manualSunset = "18:30";
|
||||
};
|
||||
hooks = {
|
||||
enabled = false;
|
||||
wallpaperChange = "";
|
||||
darkModeChange = "";
|
||||
screenLock = "";
|
||||
screenUnlock = "";
|
||||
performanceModeEnabled = "";
|
||||
performanceModeDisabled = "";
|
||||
startup = "";
|
||||
session = "";
|
||||
};
|
||||
plugins = {
|
||||
autoUpdate = false;
|
||||
};
|
||||
idle = {
|
||||
enabled = false;
|
||||
screenOffTimeout = 600;
|
||||
lockTimeout = 660;
|
||||
suspendTimeout = 1800;
|
||||
fadeDuration = 5;
|
||||
customCommands = "[]";
|
||||
};
|
||||
desktopWidgets = {
|
||||
enabled = false;
|
||||
overviewEnabled = true;
|
||||
gridSnap = false;
|
||||
monitorWidgets = [];
|
||||
};
|
||||
}
|
||||
12
modules/features/audio.nix
Normal file
12
modules/features/audio.nix
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
lux.audio.nixos = {
|
||||
security.rtkit.enable = true;
|
||||
services.pipewire = {
|
||||
enable = true;
|
||||
alsa.enable = true;
|
||||
pulse.enable = true;
|
||||
jack.enable = true;
|
||||
wireplumber.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
25
modules/features/bitwarden.nix
Normal file
25
modules/features/bitwarden.nix
Normal file
@@ -0,0 +1,25 @@
|
||||
{ den, lib, ... }:
|
||||
let
|
||||
getPrimaryEmail =
|
||||
user:
|
||||
(lib.findFirst (email: email.primary) (throw "Missing primary email for ${user.userName}") (builtins.attrValues user.emails)).address;
|
||||
in
|
||||
{
|
||||
lux.bitwarden = den.lib.parametric {
|
||||
includes = [
|
||||
(
|
||||
{ host, user }:
|
||||
{
|
||||
homeManager.programs.rbw.settings = {
|
||||
email = getPrimaryEmail user;
|
||||
base_url = "https://vault.${host.serviceDomain}";
|
||||
};
|
||||
}
|
||||
)
|
||||
];
|
||||
|
||||
homeManager = {
|
||||
programs.rbw.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
6
modules/features/bluetooth.nix
Normal file
6
modules/features/bluetooth.nix
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
lux.bluetooth.nixos = {
|
||||
hardware.bluetooth.enable = true;
|
||||
services.blueman.enable = true;
|
||||
};
|
||||
}
|
||||
10
modules/features/clipboard.nix
Normal file
10
modules/features/clipboard.nix
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
lux.clipboard.homeManager =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
home.packages = [ pkgs.wl-clipboard ];
|
||||
|
||||
services.cliphist.enable = true;
|
||||
services.wl-clip-persist.enable = true;
|
||||
};
|
||||
}
|
||||
23
modules/features/dev-tools.nix
Normal file
23
modules/features/dev-tools.nix
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
lux.dev-tools.homeManager =
|
||||
{ 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;
|
||||
};
|
||||
}
|
||||
84
modules/features/email.nix
Normal file
84
modules/features/email.nix
Normal file
@@ -0,0 +1,84 @@
|
||||
{ den, lib, ... }:
|
||||
{
|
||||
lux.email = den.lib.perUser (
|
||||
{ user, ... }:
|
||||
let
|
||||
mkEmailAccount =
|
||||
_: email:
|
||||
{
|
||||
enable = true;
|
||||
address = email.address;
|
||||
primary = email.primary;
|
||||
realName = user.realName;
|
||||
userName = email.address;
|
||||
thunderbird =
|
||||
{
|
||||
enable = true;
|
||||
}
|
||||
// lib.optionalAttrs (email.kind == "office365") {
|
||||
settings = id: {
|
||||
"mail.smtpserver.smtp_${id}.authMethod" = 10;
|
||||
"mail.server.server_${id}.authMethod" = 10;
|
||||
};
|
||||
};
|
||||
}
|
||||
// (
|
||||
if email.kind == "mxrouting" then
|
||||
{
|
||||
imap = {
|
||||
authentication = "plain";
|
||||
host = "taylor.mxrouting.net";
|
||||
port = 993;
|
||||
tls.enable = true;
|
||||
};
|
||||
smtp = {
|
||||
authentication = "plain";
|
||||
host = "taylor.mxrouting.net";
|
||||
port = 465;
|
||||
tls.enable = true;
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
flavor = "outlook.office365.com";
|
||||
}
|
||||
);
|
||||
in
|
||||
{
|
||||
homeManager = { ... }: {
|
||||
programs.thunderbird = {
|
||||
enable = true;
|
||||
profiles.${user.name} = {
|
||||
isDefault = true;
|
||||
withExternalGnupg = true;
|
||||
settings = {
|
||||
# LAYOUT: Force 3-Pane Vertical View (Folders | List | Message)
|
||||
"mail.ui.display.message_pane_vertical" = true;
|
||||
|
||||
# APPEARANCE: Enable "Cards View" (modern multi-line list)
|
||||
# Note: 'cards' is the value for the new view
|
||||
"mail.ui.display.thread_pane_view_type" = "cards";
|
||||
|
||||
# DENSITY: "Compact" is usually cleaner for tech-savvy users
|
||||
"mail.uidensity" = 1; # 0=Default, 1=Compact, 2=Touch
|
||||
|
||||
# PRIVACY & CLEANUP
|
||||
"privacy.donottrackheader.enabled" = true;
|
||||
"mail.server.server2.hidden" = true; # Hide "Local Folders"
|
||||
|
||||
# Start page disable for faster boot
|
||||
"mailnews.start_page.enabled" = false;
|
||||
|
||||
# Disable the "Get a new email address" feature in account manager
|
||||
"mail.provider.enabled" = false;
|
||||
|
||||
"layout.css.devPixelsPerPx" = 0.85;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
accounts.email.accounts = lib.mapAttrs mkEmailAccount user.emails;
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
3
modules/features/flatpak.nix
Normal file
3
modules/features/flatpak.nix
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
lux.flatpak.nixos.services.flatpak.enable = true;
|
||||
}
|
||||
26
modules/features/fonts.nix
Normal file
26
modules/features/fonts.nix
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
lux.fonts.nixos =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
fonts = {
|
||||
enableDefaultPackages = false;
|
||||
packages = with pkgs; [
|
||||
noto-fonts
|
||||
noto-fonts-cjk-sans
|
||||
noto-fonts-color-emoji
|
||||
iosevka
|
||||
jetbrains-mono
|
||||
fira-code
|
||||
roboto
|
||||
fira
|
||||
merriweather
|
||||
ibm-plex
|
||||
lexend
|
||||
literata
|
||||
montserrat
|
||||
source-sans-pro
|
||||
source-serif-pro
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
15
modules/features/gemini.nix
Normal file
15
modules/features/gemini.nix
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
lux.gemini = {
|
||||
homeManager =
|
||||
{ config, ... }:
|
||||
{
|
||||
home.sessionVariables.GEMINI_CONFIG_DIR = "${config.xdg.configHome}/gemini";
|
||||
|
||||
programs.gemini-cli.enable = true;
|
||||
programs.opencode.enable = true;
|
||||
|
||||
# Needed for extensions
|
||||
programs.npm.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
32
modules/features/git.nix
Normal file
32
modules/features/git.nix
Normal file
@@ -0,0 +1,32 @@
|
||||
{ den, lib, ... }:
|
||||
let
|
||||
getPrimaryEmail =
|
||||
user:
|
||||
(lib.findFirst (email: email.primary) (throw "Missing primary email for ${user.userName}") (
|
||||
builtins.attrValues user.emails
|
||||
)).address;
|
||||
in
|
||||
{
|
||||
lux.git = den.lib.parametric {
|
||||
includes = [
|
||||
(
|
||||
{ user, ... }:
|
||||
{
|
||||
homeManager.programs.git = {
|
||||
enable = true;
|
||||
signing.format = "ssh";
|
||||
ignores = [
|
||||
".claude/"
|
||||
".codex/"
|
||||
];
|
||||
settings = {
|
||||
user.name = user.realName;
|
||||
user.email = getPrimaryEmail user;
|
||||
init.defaultBranch = "main";
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
];
|
||||
};
|
||||
}
|
||||
22
modules/features/local-apps.nix
Normal file
22
modules/features/local-apps.nix
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
lux.local-apps.homeManager =
|
||||
{ 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;
|
||||
};
|
||||
}
|
||||
49
modules/features/mpv.nix
Normal file
49
modules/features/mpv.nix
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
lux.mpv = {
|
||||
homeManager =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
programs.mpv = {
|
||||
enable = true;
|
||||
bindings = {
|
||||
D = "cycle deband";
|
||||
};
|
||||
config = {
|
||||
profile = "high-quality";
|
||||
|
||||
osc = "no";
|
||||
border = "no";
|
||||
|
||||
vo = "gpu-next";
|
||||
gpu-api = "vulkan";
|
||||
hwdec = "vulkan";
|
||||
|
||||
demuxer-mkv-subtitle-preroll = "yes";
|
||||
sub-auto = "fuzzy";
|
||||
|
||||
sub-gauss = 1.0;
|
||||
sub-gray = "yes";
|
||||
|
||||
tone-mapping = "bt.2446a";
|
||||
|
||||
keep-open = "yes";
|
||||
save-position-on-quit = "yes";
|
||||
|
||||
volume-max = 150;
|
||||
|
||||
deband = "yes";
|
||||
deband-iterations = 2;
|
||||
deband-threshold = 64;
|
||||
deband-range = 17;
|
||||
deband-grain = 12;
|
||||
};
|
||||
scripts = with pkgs.mpvScripts; [
|
||||
modernz
|
||||
thumbfast
|
||||
mpris
|
||||
autosub
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
187
modules/features/neovim/default.nix
Normal file
187
modules/features/neovim/default.nix
Normal file
@@ -0,0 +1,187 @@
|
||||
{ inputs, ... }:
|
||||
{
|
||||
lux.neovim.homeManager =
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
{
|
||||
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
|
||||
# NOTE: Adjust these paths to match your actual denful/flake variables
|
||||
nixdExtras = {
|
||||
nixpkgs = "import ${pkgs.path} {}";
|
||||
# Assuming you have access to the flake path in your config,
|
||||
# otherwise hardcode or pass via specialArgs
|
||||
nixos_options = ''(builtins.getFlake "path://${config.home.homeDirectory}/.config/nixos").nixosConfigurations.polaris.config.networking.hostName}.options'';
|
||||
home_manager_options = ''(builtins.getFlake "path://${config.home.homeDirectory}/.config/nixos").nixosConfigurations.polaris.config.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";
|
||||
};
|
||||
};
|
||||
}
|
||||
9
modules/features/neovim/lua-config/init.lua
Normal file
9
modules/features/neovim/lua-config/init.lua
Normal file
@@ -0,0 +1,9 @@
|
||||
require("options")
|
||||
require("plugins.lsp")
|
||||
require("plugins.completion")
|
||||
require("plugins.formatting")
|
||||
require("plugins.treesitter")
|
||||
require("plugins.telescope")
|
||||
require("plugins.ui")
|
||||
require("plugins.core")
|
||||
require("plugins.ai")
|
||||
138
modules/features/neovim/lua-config/lua/options.lua
Normal file
138
modules/features/neovim/lua-config/lua/options.lua
Normal file
@@ -0,0 +1,138 @@
|
||||
-- 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,
|
||||
})
|
||||
72
modules/features/neovim/lua-config/lua/plugins/ai.lua
Normal file
72
modules/features/neovim/lua-config/lua/plugins/ai.lua
Normal file
@@ -0,0 +1,72 @@
|
||||
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,
|
||||
},
|
||||
})
|
||||
104
modules/features/neovim/lua-config/lua/plugins/completion.lua
Normal file
104
modules/features/neovim/lua-config/lua/plugins/completion.lua
Normal file
@@ -0,0 +1,104 @@
|
||||
require("lz.n").load({
|
||||
{
|
||||
"friendly-snippets",
|
||||
},
|
||||
{
|
||||
"luasnip",
|
||||
before = function()
|
||||
require("lz.n").trigger_load("friendly-snippets")
|
||||
end,
|
||||
after = function()
|
||||
require("luasnip.loaders.from_vscode").lazy_load()
|
||||
-- Load custom lua snippets
|
||||
require("luasnip.loaders.from_lua").load({ paths = { vim.fn.stdpath("config") .. "/snippets" } })
|
||||
end,
|
||||
},
|
||||
{
|
||||
"colorful-menu.nvim",
|
||||
after = function()
|
||||
require("colorful-menu").setup({})
|
||||
end,
|
||||
},
|
||||
{
|
||||
"blink.cmp",
|
||||
event = { "InsertEnter", "CmdlineEnter" },
|
||||
before = function()
|
||||
-- Trigger lazydev so it's ready for blink source
|
||||
require("lz.n").trigger_load({ "lazydev.nvim", "luasnip", "colorful-menu.nvim" })
|
||||
end,
|
||||
after = function()
|
||||
require("blink.cmp").setup({
|
||||
keymap = {
|
||||
preset = "default",
|
||||
|
||||
-- [Up/Down]
|
||||
["<C-j>"] = { "select_next", "fallback" },
|
||||
["<C-k>"] = { "select_prev", "fallback" }, -- Overrides Signature Help
|
||||
|
||||
-- [Insert Suggestion]
|
||||
["<tab>"] = { "select_and_accept", "fallback" },
|
||||
|
||||
-- [Remap Signature Help]
|
||||
-- Since we took <C-k>, let's move signature help to <C-g> (optional)
|
||||
["<C-g>"] = { "show_signature", "hide_signature", "fallback" },
|
||||
},
|
||||
|
||||
appearance = {
|
||||
nerd_font_variant = "mono",
|
||||
},
|
||||
|
||||
completion = {
|
||||
documentation = {
|
||||
auto_show = true,
|
||||
auto_show_delay_ms = 500,
|
||||
},
|
||||
menu = {
|
||||
draw = {
|
||||
columns = { { "kind_icon" }, { "label", gap = 1 } },
|
||||
components = {
|
||||
label = {
|
||||
text = function(ctx)
|
||||
return require("colorful-menu").blink_components_text(ctx)
|
||||
end,
|
||||
highlight = function(ctx)
|
||||
return require("colorful-menu").blink_components_highlight(ctx)
|
||||
end,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
cmdline = {
|
||||
completion = {
|
||||
menu = {
|
||||
auto_show = true,
|
||||
},
|
||||
},
|
||||
keymap = { preset = "inherit" },
|
||||
},
|
||||
|
||||
sources = {
|
||||
default = {
|
||||
"lsp",
|
||||
"path",
|
||||
"snippets",
|
||||
"lazydev",
|
||||
},
|
||||
providers = {
|
||||
lazydev = { module = "lazydev.integrations.blink", score_offset = 100 },
|
||||
},
|
||||
},
|
||||
|
||||
snippets = { preset = "luasnip" },
|
||||
|
||||
fuzzy = { implementation = "prefer_rust_with_warning" },
|
||||
|
||||
signature = {
|
||||
enabled = true,
|
||||
},
|
||||
})
|
||||
end,
|
||||
},
|
||||
})
|
||||
|
||||
65
modules/features/neovim/lua-config/lua/plugins/core.lua
Normal file
65
modules/features/neovim/lua-config/lua/plugins/core.lua
Normal file
@@ -0,0 +1,65 @@
|
||||
require("lz.n").load({
|
||||
{
|
||||
"mini.nvim",
|
||||
event = { "BufReadPre", "BufNewFile" },
|
||||
after = function()
|
||||
-- Better Around/Inside textobjects
|
||||
require("mini.ai").setup({ n_lines = 500 })
|
||||
|
||||
-- Add/delete/replace surroundings (brackets, quotes, etc.)
|
||||
require("mini.surround").setup()
|
||||
|
||||
-- Auto-pairs (replaces nvim-autopairs)
|
||||
require("mini.pairs").setup()
|
||||
|
||||
local files = require("mini.files")
|
||||
files.setup()
|
||||
vim.keymap.set("n", "<leader>e", function()
|
||||
if not files.close() then
|
||||
files.open(vim.api.nvim_buf_get_name(0))
|
||||
end
|
||||
end, { desc = "File [E]xplorer" })
|
||||
|
||||
local icons = require("mini.icons")
|
||||
icons.setup()
|
||||
icons.mock_nvim_web_devicons()
|
||||
|
||||
local hipatterns = require("mini.hipatterns")
|
||||
hipatterns.setup({
|
||||
highlighters = {
|
||||
-- Highlight hex color strings (#rrggbb) using that 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" },
|
||||
hack = { pattern = "%f[%w]()HACK()%f[%W]", group = "MiniHipatternsHack" },
|
||||
todo = { pattern = "%f[%w]()TODO()%f[%W]", group = "MiniHipatternsTodo" },
|
||||
note = { pattern = "%f[%w]()NOTE()%f[%W]", group = "MiniHipatternsNote" },
|
||||
},
|
||||
})
|
||||
|
||||
local indentscope = require("mini.indentscope")
|
||||
indentscope.setup({
|
||||
symbol = "│",
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd("FileType", {
|
||||
pattern = { "help", "alpha", "dashboard", "neo-tree", "Trouble", "lazy", "mason" },
|
||||
callback = function()
|
||||
vim.b.miniindentscope_disable = true
|
||||
end,
|
||||
})
|
||||
end,
|
||||
},
|
||||
{
|
||||
"guess-indent.nvim",
|
||||
event = { "BufReadPre", "BufNewFile" },
|
||||
after = function()
|
||||
require("guess-indent").setup({})
|
||||
end,
|
||||
},
|
||||
{
|
||||
"direnv.vim",
|
||||
event = "BufEnter",
|
||||
},
|
||||
})
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
require("lz.n").load({
|
||||
{
|
||||
"conform.nvim",
|
||||
event = "BufWritePre",
|
||||
cmd = "ConformInfo",
|
||||
keys = {
|
||||
{
|
||||
"<leader>f",
|
||||
function()
|
||||
require("conform").format({ async = true, lsp_format = "fallback" })
|
||||
end,
|
||||
mode = "",
|
||||
desc = "[F]ormat buffer",
|
||||
},
|
||||
},
|
||||
after = function()
|
||||
require("conform").setup({
|
||||
notify_on_error = true,
|
||||
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 }
|
||||
if disable_filetypes[vim.bo[bufnr].filetype] then
|
||||
return nil
|
||||
else
|
||||
return {
|
||||
timeout_ms = 500,
|
||||
lsp_format = "fallback",
|
||||
}
|
||||
end
|
||||
end,
|
||||
formatters_by_ft = {
|
||||
lua = { "stylua" },
|
||||
-- Conform can also run multiple formatters sequentially
|
||||
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 = {
|
||||
stylua = {
|
||||
prepend_args = { "--indent-type", "Spaces", "--indent-width", "2" },
|
||||
},
|
||||
},
|
||||
})
|
||||
end,
|
||||
},
|
||||
})
|
||||
192
modules/features/neovim/lua-config/lua/plugins/lsp.lua
Normal file
192
modules/features/neovim/lua-config/lua/plugins/lsp.lua
Normal file
@@ -0,0 +1,192 @@
|
||||
require("lz.n").load({
|
||||
{
|
||||
"typst-preview.nvim",
|
||||
ft = "typst",
|
||||
after = function()
|
||||
-- Setup typst-preview
|
||||
require("typst-preview").setup({
|
||||
-- Optionally configure things here
|
||||
dependencies_bin = {
|
||||
-- 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" })
|
||||
end,
|
||||
},
|
||||
{
|
||||
"lazydev.nvim",
|
||||
cmd = "LazyDev",
|
||||
ft = "lua",
|
||||
after = function()
|
||||
require("lazydev").setup({
|
||||
library = {
|
||||
{ words = { "nixCats", "settings" }, path = "nix-info" },
|
||||
},
|
||||
})
|
||||
end,
|
||||
},
|
||||
{
|
||||
"nvim-lspconfig",
|
||||
event = { "BufReadPre", "BufNewFile" },
|
||||
before = function()
|
||||
require("lz.n").trigger_load("lazydev.nvim")
|
||||
end,
|
||||
after = function()
|
||||
vim.api.nvim_create_autocmd("LspAttach", {
|
||||
group = vim.api.nvim_create_augroup("kickstart-lsp-attach", { clear = true }),
|
||||
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 bufnr = args.buf
|
||||
|
||||
local map = function(keys, func, desc, mode)
|
||||
mode = mode or "n"
|
||||
vim.keymap.set(mode, keys, func, { buffer = bufnr, desc = "LSP: " .. desc })
|
||||
end
|
||||
|
||||
-- Standard LSP functions
|
||||
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("gD", vim.lsp.buf.declaration, "[G]oto [D]eclaration")
|
||||
map("K", vim.lsp.buf.hover, "Hover Documentation")
|
||||
|
||||
-- Telescope Mappings
|
||||
map("gd", require("telescope.builtin").lsp_definitions, "[G]oto [D]efinition")
|
||||
map("gr", require("telescope.builtin").lsp_references, "[G]oto [R]eferences")
|
||||
map("gI", require("telescope.builtin").lsp_implementations, "[G]oto [I]mplementation")
|
||||
map("<leader>D", require("telescope.builtin").lsp_type_definitions, "Type [D]efinition")
|
||||
map("<leader>ds", require("telescope.builtin").lsp_document_symbols, "[D]ocument [S]ymbols")
|
||||
map("<leader>ws", require("telescope.builtin").lsp_dynamic_workspace_symbols, "[W]orkspace [S]ymbols")
|
||||
|
||||
-- Highlight references (Document Highlight)
|
||||
if client and client:supports_method("textDocument/documentHighlight", bufnr) then
|
||||
local highlight_augroup = vim.api.nvim_create_augroup("kickstart-lsp-highlight", { clear = false })
|
||||
vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, {
|
||||
buffer = bufnr,
|
||||
group = highlight_augroup,
|
||||
callback = vim.lsp.buf.document_highlight,
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI" }, {
|
||||
buffer = bufnr,
|
||||
group = highlight_augroup,
|
||||
callback = vim.lsp.buf.clear_references,
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd("LspDetach", {
|
||||
group = vim.api.nvim_create_augroup("kickstart-lsp-detach", { clear = true }),
|
||||
callback = function(event)
|
||||
vim.lsp.buf.clear_references()
|
||||
vim.api.nvim_clear_autocmds({ group = "kickstart-lsp-highlight", buffer = event.buf })
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
-- Inlay Hints
|
||||
if client and client:supports_method("textDocument/inlayHint", bufnr) then
|
||||
vim.lsp.inlay_hint.enable(true, { bufnr = bufnr })
|
||||
map("<leader>th", function()
|
||||
vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled({ bufnr = bufnr }))
|
||||
end, "[T]oggle Inlay [H]ints")
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
-- 1. Setup Diagnostics (Visuals)
|
||||
vim.diagnostic.config({
|
||||
severity_sort = true,
|
||||
-- underline = { severity = vim.diagnostic.severity.ERROR },
|
||||
signs = {
|
||||
text = {
|
||||
[vim.diagnostic.severity.ERROR] = " ",
|
||||
[vim.diagnostic.severity.WARN] = " ",
|
||||
[vim.diagnostic.severity.INFO] = " ",
|
||||
[vim.diagnostic.severity.HINT] = " ",
|
||||
},
|
||||
},
|
||||
virtual_text = {
|
||||
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,
|
||||
},
|
||||
})
|
||||
|
||||
vim.lsp.config("lua_ls", {
|
||||
settings = {
|
||||
Lua = {
|
||||
runtime = { version = "LuaJIT" },
|
||||
signatureHelp = { enabled = true },
|
||||
diagnostics = { globals = { "nixCats", "vim" } },
|
||||
telemetry = { enabled = false },
|
||||
completion = { callSnippet = "Replace" },
|
||||
},
|
||||
},
|
||||
})
|
||||
vim.lsp.enable("lua_ls")
|
||||
|
||||
local settings = require("nix-info").settings
|
||||
|
||||
-- Nix
|
||||
vim.lsp.config("nixd", {
|
||||
settings = {
|
||||
nixd = {
|
||||
nixpkgs = { expr = settings.nixdExtras.nixpkgs },
|
||||
options = {
|
||||
nixos = { expr = settings.nixdExtras.nixos_options },
|
||||
["home-manager"] = { expr = settings.nixdExtras.home_manager_options },
|
||||
},
|
||||
formatting = { command = { "nixfmt" } },
|
||||
},
|
||||
},
|
||||
})
|
||||
vim.lsp.enable("nixd")
|
||||
|
||||
-- Dafny
|
||||
vim.lsp.enable("dafny")
|
||||
|
||||
-- TypeScript/JS
|
||||
vim.lsp.enable("ts_ls")
|
||||
|
||||
-- Rust
|
||||
vim.lsp.enable("rust_analyzer")
|
||||
|
||||
-- Python
|
||||
vim.lsp.enable("ty")
|
||||
vim.lsp.enable("ruff")
|
||||
|
||||
vim.lsp.enable("astro")
|
||||
|
||||
vim.lsp.config("tinymist", {
|
||||
settings = {
|
||||
tinymist = {
|
||||
formatterMode = "typstyle",
|
||||
},
|
||||
},
|
||||
})
|
||||
vim.lsp.enable("tinymist")
|
||||
end,
|
||||
},
|
||||
{
|
||||
"trouble.nvim",
|
||||
cmd = "Trouble",
|
||||
keys = {
|
||||
{ "<leader>xx", "<cmd>Trouble diagnostics toggle<cr>", desc = "Diagnostics (Trouble)" },
|
||||
{ "<leader>xX", "<cmd>Trouble diagnostics toggle filter.buf=0<cr>", desc = "Buffer Diagnostics (Trouble)" },
|
||||
},
|
||||
after = function()
|
||||
require("trouble").setup({
|
||||
focus = true,
|
||||
})
|
||||
end,
|
||||
},
|
||||
})
|
||||
101
modules/features/neovim/lua-config/lua/plugins/telescope.lua
Normal file
101
modules/features/neovim/lua-config/lua/plugins/telescope.lua
Normal file
@@ -0,0 +1,101 @@
|
||||
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,
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,28 @@
|
||||
local ok, treesitter = pcall(require, "nvim-treesitter")
|
||||
|
||||
if not ok then
|
||||
return
|
||||
end
|
||||
|
||||
treesitter.setup({})
|
||||
|
||||
local group = vim.api.nvim_create_augroup("lux-treesitter", { clear = true })
|
||||
local enableTreesitter = function(bufnr)
|
||||
vim.schedule(function()
|
||||
if not vim.api.nvim_buf_is_valid(bufnr) then
|
||||
return
|
||||
end
|
||||
|
||||
if pcall(vim.treesitter.start, bufnr) then
|
||||
vim.bo[bufnr].indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
vim.api.nvim_create_autocmd({ "BufEnter", "BufWinEnter", "FileType" }, {
|
||||
group = group,
|
||||
pattern = "*",
|
||||
callback = function(args)
|
||||
enableTreesitter(args.buf)
|
||||
end,
|
||||
})
|
||||
1
modules/features/neovim/lua-config/lua/plugins/typst.lua
Normal file
1
modules/features/neovim/lua-config/lua/plugins/typst.lua
Normal file
@@ -0,0 +1 @@
|
||||
require("lz.n").load({})
|
||||
81
modules/features/neovim/lua-config/lua/plugins/ui.lua
Normal file
81
modules/features/neovim/lua-config/lua/plugins/ui.lua
Normal file
@@ -0,0 +1,81 @@
|
||||
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,
|
||||
},
|
||||
})
|
||||
91
modules/features/neovim/lua-config/snippets/nix.lua
Normal file
91
modules/features/neovim/lua-config/snippets/nix.lua
Normal file
@@ -0,0 +1,91 @@
|
||||
local ls = require("luasnip")
|
||||
local s = ls.snippet
|
||||
local t = ls.text_node
|
||||
local i = ls.insert_node
|
||||
|
||||
return {
|
||||
-- Full lux module (both nixos and homeManager)
|
||||
s("luxmod", {
|
||||
t({
|
||||
"{ inputs, ... }:",
|
||||
"{",
|
||||
" lux."
|
||||
}),
|
||||
i(1, "moduleName"),
|
||||
t({
|
||||
" = {",
|
||||
" nixos = { config, lib, pkgs, ... }: {",
|
||||
" "
|
||||
}),
|
||||
i(2),
|
||||
t({
|
||||
"",
|
||||
" };",
|
||||
"",
|
||||
" homeManager = { config, lib, pkgs, ... }: {",
|
||||
" "
|
||||
}),
|
||||
i(3),
|
||||
t({
|
||||
"",
|
||||
" };",
|
||||
" };",
|
||||
"}",
|
||||
}),
|
||||
}),
|
||||
|
||||
-- lux nixos only module
|
||||
s("luxnixos", {
|
||||
t({
|
||||
"{ inputs, ... }:",
|
||||
"{",
|
||||
" lux."
|
||||
}),
|
||||
i(1, "moduleName"),
|
||||
t({
|
||||
".nixos = { config, lib, pkgs, ... }: {",
|
||||
" "
|
||||
}),
|
||||
i(0),
|
||||
t({
|
||||
"",
|
||||
" };",
|
||||
"}",
|
||||
}),
|
||||
}),
|
||||
|
||||
-- lux homeManager only module
|
||||
s("luxhm", {
|
||||
t({
|
||||
"{ inputs, ... }:",
|
||||
"{",
|
||||
" lux."
|
||||
}),
|
||||
i(1, "moduleName"),
|
||||
t({
|
||||
".homeManager = { config, lib, pkgs, ... }: {",
|
||||
" "
|
||||
}),
|
||||
i(0),
|
||||
t({
|
||||
"",
|
||||
" };",
|
||||
"}",
|
||||
}),
|
||||
}),
|
||||
|
||||
-- den inline aspect
|
||||
s("denaspect", {
|
||||
t({
|
||||
"(",
|
||||
" { host, user, ... }: {",
|
||||
" "
|
||||
}),
|
||||
i(0),
|
||||
t({
|
||||
"",
|
||||
" }",
|
||||
")"
|
||||
}),
|
||||
}),
|
||||
}
|
||||
6
modules/features/networking.nix
Normal file
6
modules/features/networking.nix
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
lux.networking.nixos.networking = {
|
||||
nftables.enable = true;
|
||||
networkmanager.enable = true;
|
||||
};
|
||||
}
|
||||
374
modules/features/niri.nix
Normal file
374
modules/features/niri.nix
Normal file
@@ -0,0 +1,374 @@
|
||||
{ den, inputs, lib, ... }:
|
||||
let
|
||||
mkOutputs =
|
||||
host:
|
||||
lib.mapAttrs (
|
||||
_: display:
|
||||
lib.optionalAttrs display.primary {
|
||||
focus-at-startup = true;
|
||||
}
|
||||
// lib.filterAttrs (_: value: value != null) {
|
||||
position = display.position;
|
||||
scale = display.scale;
|
||||
mode = display.mode;
|
||||
}
|
||||
) host.displays;
|
||||
in
|
||||
{
|
||||
lux.niri = {
|
||||
includes = [
|
||||
(den.lib.perHost {
|
||||
nixos =
|
||||
{ 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;
|
||||
|
||||
# Essential services for Nautilus (Trash, Networking, Disks, Search)
|
||||
services.gvfs.enable = true;
|
||||
services.udisks2.enable = true;
|
||||
};
|
||||
})
|
||||
(den.lib.perUser (
|
||||
{ host, ... }:
|
||||
{
|
||||
homeManager =
|
||||
{ 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 = {
|
||||
outputs = mkOutputs host;
|
||||
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";
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Aesthetics & Visuals
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
# Fast, snappy animations
|
||||
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.;
|
||||
};
|
||||
# Kanagawa-wave Colorscheme for border
|
||||
border = {
|
||||
enable = true;
|
||||
width = 3;
|
||||
active.color = "#7E9CD8"; # Crystal Blue
|
||||
inactive.color = "#54546D"; # Sumi Ink 4
|
||||
urgent.color = "#E82424"; # Samurai Red
|
||||
};
|
||||
};
|
||||
|
||||
window-rules = [
|
||||
{
|
||||
# Sleek rounded corners
|
||||
geometry-corner-radius =
|
||||
let
|
||||
radius = 10.0;
|
||||
in
|
||||
{
|
||||
bottom-left = radius;
|
||||
bottom-right = radius;
|
||||
top-left = radius;
|
||||
top-right = radius;
|
||||
};
|
||||
clip-to-geometry = true;
|
||||
}
|
||||
];
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# System & Input
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Keybinds
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
binds = {
|
||||
# --- Applications & Launchers ---
|
||||
"Mod+Return" = {
|
||||
action.spawn = "kitty";
|
||||
hotkey-overlay.title = "Terminal";
|
||||
};
|
||||
"Mod+B" = {
|
||||
action.spawn = "vivaldi";
|
||||
hotkey-overlay.title = "Browser";
|
||||
};
|
||||
"Mod+Space" = {
|
||||
repeat = false;
|
||||
action.spawn = [
|
||||
"vicinae"
|
||||
"toggle"
|
||||
];
|
||||
hotkey-overlay.title = "App Launcher";
|
||||
};
|
||||
|
||||
# --- Media & Brightness Controls ---
|
||||
"XF86AudioPlay" = {
|
||||
action.spawn-sh = "playerctl play-pause";
|
||||
allow-when-locked = true;
|
||||
};
|
||||
"XF86AudioStop" = {
|
||||
action.spawn-sh = "playerctl stop";
|
||||
allow-when-locked = true;
|
||||
};
|
||||
"XF86AudioPrev" = {
|
||||
action.spawn-sh = "playerctl previous";
|
||||
allow-when-locked = true;
|
||||
};
|
||||
"XF86AudioNext" = {
|
||||
action.spawn-sh = "playerctl next";
|
||||
allow-when-locked = true;
|
||||
};
|
||||
"XF86AudioRaiseVolume" = {
|
||||
action.spawn-sh = "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+";
|
||||
allow-when-locked = true;
|
||||
};
|
||||
"XF86AudioLowerVolume" = {
|
||||
action.spawn-sh = "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-";
|
||||
allow-when-locked = true;
|
||||
};
|
||||
"XF86AudioMute" = {
|
||||
action.spawn-sh = "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle";
|
||||
allow-when-locked = true;
|
||||
};
|
||||
"XF86AudioMicMute" = {
|
||||
action.spawn-sh = "wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle";
|
||||
allow-when-locked = true;
|
||||
};
|
||||
"XF86MonBrightnessUp" = {
|
||||
action.spawn-sh = "brightnessctl s 10%+";
|
||||
allow-when-locked = true;
|
||||
};
|
||||
"XF86MonBrightnessDown" = {
|
||||
action.spawn-sh = "brightnessctl s 10%-";
|
||||
allow-when-locked = true;
|
||||
};
|
||||
|
||||
# --- Screenshots ---
|
||||
"Mod+S".action.screenshot = [ ];
|
||||
"Mod+Ctrl+S".action.screenshot-screen = [ ];
|
||||
"Mod+Alt+S".action.screenshot-window = [ ];
|
||||
|
||||
# --- Session & System ---
|
||||
"Mod+Shift+Slash".action.show-hotkey-overlay = [ ];
|
||||
"Mod+Escape" = {
|
||||
action.toggle-keyboard-shortcuts-inhibit = [ ];
|
||||
allow-inhibiting = false;
|
||||
};
|
||||
"Mod+Alt+L" = {
|
||||
action.spawn-sh = "loginctl lock-session";
|
||||
hotkey-overlay.title = "Lock Screen";
|
||||
};
|
||||
"Mod+Shift+E".action.quit = [ ];
|
||||
"Ctrl+Alt+Delete".action.quit = [ ];
|
||||
"Mod+Shift+P".action.power-off-monitors = [ ];
|
||||
|
||||
# --- Overview & Window Management ---
|
||||
"Mod+O" = {
|
||||
action.toggle-overview = [ ];
|
||||
repeat = false;
|
||||
};
|
||||
"Mod+Q" = {
|
||||
action.close-window = [ ];
|
||||
repeat = false;
|
||||
};
|
||||
|
||||
# Focus Movement (Vim-like + Arrows)
|
||||
"Mod+H".action.focus-column-or-monitor-left = [ ];
|
||||
"Mod+J".action.focus-window-down = [ ];
|
||||
"Mod+K".action.focus-window-up = [ ];
|
||||
"Mod+L".action.focus-column-or-monitor-right = [ ];
|
||||
|
||||
# Window Movement
|
||||
"Mod+Ctrl+Left".action.move-column-left = [ ];
|
||||
"Mod+Ctrl+Down".action.move-window-down = [ ];
|
||||
"Mod+Ctrl+Up".action.move-window-up = [ ];
|
||||
"Mod+Ctrl+Right".action.move-column-right = [ ];
|
||||
"Mod+Ctrl+H".action.move-column-left = [ ];
|
||||
"Mod+Ctrl+J".action.move-window-down = [ ];
|
||||
"Mod+Ctrl+K".action.move-window-up = [ ];
|
||||
"Mod+Ctrl+L".action.move-column-right = [ ];
|
||||
|
||||
# Column Focus & Movement
|
||||
"Mod+Home".action.focus-column-first = [ ];
|
||||
"Mod+End".action.focus-column-last = [ ];
|
||||
"Mod+Ctrl+Home".action.move-column-to-first = [ ];
|
||||
"Mod+Ctrl+End".action.move-column-to-last = [ ];
|
||||
|
||||
# Monitor Focus
|
||||
"Mod+Shift+Left".action.focus-monitor-left = [ ];
|
||||
"Mod+Shift+Down".action.focus-monitor-down = [ ];
|
||||
"Mod+Shift+Up".action.focus-monitor-up = [ ];
|
||||
"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 = [ ];
|
||||
|
||||
# Monitor Movement
|
||||
"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 = [ ];
|
||||
|
||||
# Workspace Focus
|
||||
"Mod+Page_Down".action.focus-workspace-down = [ ];
|
||||
"Mod+Page_Up".action.focus-workspace-up = [ ];
|
||||
"Mod+U".action.focus-workspace-down = [ ];
|
||||
"Mod+I".action.focus-workspace-up = [ ];
|
||||
|
||||
# Workspace Movement (Column)
|
||||
"Mod+Ctrl+Page_Down".action.move-column-to-workspace-down = [ ];
|
||||
"Mod+Ctrl+Page_Up".action.move-column-to-workspace-up = [ ];
|
||||
"Mod+Ctrl+U".action.move-column-to-workspace-down = [ ];
|
||||
"Mod+Ctrl+I".action.move-column-to-workspace-up = [ ];
|
||||
|
||||
# Workspace Movement (Entire Workspace)
|
||||
"Mod+Shift+Page_Down".action.move-workspace-down = [ ];
|
||||
"Mod+Shift+Page_Up".action.move-workspace-up = [ ];
|
||||
"Mod+Shift+U".action.move-workspace-down = [ ];
|
||||
"Mod+Shift+I".action.move-workspace-up = [ ];
|
||||
|
||||
# --- Mouse Wheel Scrolling ---
|
||||
"Mod+WheelScrollDown" = {
|
||||
action.focus-workspace-down = [ ];
|
||||
cooldown-ms = 150;
|
||||
};
|
||||
"Mod+WheelScrollUp" = {
|
||||
action.focus-workspace-up = [ ];
|
||||
cooldown-ms = 150;
|
||||
};
|
||||
"Mod+Ctrl+WheelScrollDown" = {
|
||||
action.move-column-to-workspace-down = [ ];
|
||||
cooldown-ms = 150;
|
||||
};
|
||||
"Mod+Ctrl+WheelScrollUp" = {
|
||||
action.move-column-to-workspace-up = [ ];
|
||||
cooldown-ms = 150;
|
||||
};
|
||||
|
||||
"Mod+WheelScrollRight".action.focus-column-right = [ ];
|
||||
"Mod+WheelScrollLeft".action.focus-column-left = [ ];
|
||||
"Mod+Ctrl+WheelScrollRight".action.move-column-right = [ ];
|
||||
"Mod+Ctrl+WheelScrollLeft".action.move-column-left = [ ];
|
||||
"Mod+Shift+WheelScrollDown".action.focus-column-right = [ ];
|
||||
"Mod+Shift+WheelScrollUp".action.focus-column-left = [ ];
|
||||
"Mod+Ctrl+Shift+WheelScrollDown".action.move-column-right = [ ];
|
||||
"Mod+Ctrl+Shift+WheelScrollUp".action.move-column-left = [ ];
|
||||
|
||||
# --- Workspace Indices ---
|
||||
"Mod+1".action.focus-workspace = 1;
|
||||
"Mod+2".action.focus-workspace = 2;
|
||||
"Mod+3".action.focus-workspace = 3;
|
||||
"Mod+4".action.focus-workspace = 4;
|
||||
"Mod+5".action.focus-workspace = 5;
|
||||
"Mod+6".action.focus-workspace = 6;
|
||||
"Mod+7".action.focus-workspace = 7;
|
||||
"Mod+8".action.focus-workspace = 8;
|
||||
"Mod+9".action.focus-workspace = 9;
|
||||
|
||||
"Mod+Ctrl+1".action.move-column-to-workspace = 1;
|
||||
"Mod+Ctrl+2".action.move-column-to-workspace = 2;
|
||||
"Mod+Ctrl+3".action.move-column-to-workspace = 3;
|
||||
"Mod+Ctrl+4".action.move-column-to-workspace = 4;
|
||||
"Mod+Ctrl+5".action.move-column-to-workspace = 5;
|
||||
"Mod+Ctrl+6".action.move-column-to-workspace = 6;
|
||||
"Mod+Ctrl+7".action.move-column-to-workspace = 7;
|
||||
"Mod+Ctrl+8".action.move-column-to-workspace = 8;
|
||||
"Mod+Ctrl+9".action.move-column-to-workspace = 9;
|
||||
|
||||
# --- Column/Window Reshaping & Organization ---
|
||||
"Mod+BracketLeft".action.consume-or-expel-window-left = [ ];
|
||||
"Mod+BracketRight".action.consume-or-expel-window-right = [ ];
|
||||
"Mod+Comma".action.consume-window-into-column = [ ];
|
||||
"Mod+Period".action.expel-window-from-column = [ ];
|
||||
|
||||
"Mod+R".action.switch-preset-column-width = [ ];
|
||||
"Mod+Shift+R".action.switch-preset-window-height = [ ];
|
||||
"Mod+Ctrl+R".action.reset-window-height = [ ];
|
||||
"Mod+F".action.maximize-column = [ ];
|
||||
"Mod+Shift+F".action.fullscreen-window = [ ];
|
||||
"Mod+M".action.maximize-window-to-edges = [ ];
|
||||
"Mod+Ctrl+F".action.expand-column-to-available-width = [ ];
|
||||
"Mod+C".action.center-column = [ ];
|
||||
"Mod+Ctrl+C".action.center-visible-columns = [ ];
|
||||
|
||||
"Mod+Minus".action.set-column-width = "-10%";
|
||||
"Mod+Equal".action.set-column-width = "+10%";
|
||||
"Mod+Shift+Minus".action.set-window-height = "-10%";
|
||||
"Mod+Shift+Equal".action.set-window-height = "+10%";
|
||||
|
||||
"Mod+V".action.toggle-window-floating = [ ];
|
||||
"Mod+Shift+V".action.switch-focus-between-floating-and-tiling = [ ];
|
||||
"Mod+W".action.toggle-column-tabbed-display = [ ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
))
|
||||
];
|
||||
};
|
||||
}
|
||||
55
modules/features/nix.nix
Normal file
55
modules/features/nix.nix
Normal file
@@ -0,0 +1,55 @@
|
||||
{ den, inputs, ... }:
|
||||
{
|
||||
lux.nix = {
|
||||
includes = [
|
||||
(den.lib.perHost {
|
||||
nixos = {
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
|
||||
nix = {
|
||||
gc.automatic = true;
|
||||
optimise.automatic = true;
|
||||
registry.nixpkgs.flake = inputs.nixpkgs;
|
||||
channel.enable = false;
|
||||
|
||||
settings = {
|
||||
trusted-users = [ "@wheel" ];
|
||||
use-xdg-base-directories = true;
|
||||
auto-optimise-store = true;
|
||||
|
||||
experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
homeManager =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
home.packages = [
|
||||
(pkgs.writeShellApplication {
|
||||
name = "ns";
|
||||
runtimeInputs = [
|
||||
pkgs.fzf
|
||||
pkgs.nix-search-tv
|
||||
];
|
||||
text = builtins.readFile "${pkgs.nix-search-tv.src}/nixpkgs.sh";
|
||||
})
|
||||
];
|
||||
|
||||
programs.television = {
|
||||
enable = true;
|
||||
enableZshIntegration = false;
|
||||
};
|
||||
|
||||
programs.nix-search-tv = {
|
||||
enable = true;
|
||||
enableTelevisionIntegration = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
19
modules/features/noctalia.nix
Normal file
19
modules/features/noctalia.nix
Normal file
@@ -0,0 +1,19 @@
|
||||
{ inputs, ... }:
|
||||
{
|
||||
lux.noctalia.homeManager =
|
||||
{ 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;
|
||||
};
|
||||
};
|
||||
}
|
||||
86
modules/features/pim.nix
Normal file
86
modules/features/pim.nix
Normal file
@@ -0,0 +1,86 @@
|
||||
{ den, ... }:
|
||||
let
|
||||
calendarAccount = den.lib.perUser (
|
||||
{ host, user }:
|
||||
{
|
||||
homeManager =
|
||||
{ config, ... }:
|
||||
let
|
||||
calendarsPath = "${config.xdg.dataHome}/calendars";
|
||||
in
|
||||
{
|
||||
programs.pimsync.enable = true;
|
||||
services.pimsync.enable = true;
|
||||
|
||||
programs.khal = {
|
||||
# FIXME: Temporarily disabled because of bug in nixpkgs-unstable (27-02-26)
|
||||
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.${host.serviceDomain}/";
|
||||
type = "caldav";
|
||||
userName = user.userName;
|
||||
passwordCommand = [
|
||||
"rbw"
|
||||
"get"
|
||||
"Radicale"
|
||||
];
|
||||
};
|
||||
|
||||
pimsync = {
|
||||
enable = true;
|
||||
extraPairDirectives = [
|
||||
{
|
||||
name = "collections";
|
||||
params = [ "from b" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
khal = {
|
||||
enable = true;
|
||||
type = "discover";
|
||||
color = "light blue";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
in
|
||||
{
|
||||
lux.pim = {
|
||||
includes = [ calendarAccount ];
|
||||
};
|
||||
}
|
||||
7
modules/features/pinentry.nix
Normal file
7
modules/features/pinentry.nix
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
lux.pinentry.homeManager =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
programs.rbw.settings.pinentry = pkgs.pinentry-gnome3;
|
||||
};
|
||||
}
|
||||
10
modules/features/podman.nix
Normal file
10
modules/features/podman.nix
Normal file
@@ -0,0 +1,10 @@
|
||||
{ ... }:
|
||||
{
|
||||
lux.podman = {
|
||||
homeManager = {
|
||||
services.podman = {
|
||||
enable = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
14
modules/features/printing.nix
Normal file
14
modules/features/printing.nix
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
lux.printing.nixos =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
services.printing = {
|
||||
enable = true;
|
||||
drivers = with pkgs; [
|
||||
cups-filters
|
||||
cups-browsed
|
||||
cnijfilter2
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
19
modules/features/qbittorrent-client.nix
Normal file
19
modules/features/qbittorrent-client.nix
Normal file
@@ -0,0 +1,19 @@
|
||||
{ den, ... }:
|
||||
{
|
||||
lux.qbittorrent-client = {
|
||||
includes = [
|
||||
(den.lib.perHost {
|
||||
nixos.networking.firewall = {
|
||||
allowedTCPPorts = [ 43864 ];
|
||||
allowedUDPPorts = [ 43864 ];
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
homeManager =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
home.packages = [ pkgs.qbittorrent ];
|
||||
};
|
||||
};
|
||||
}
|
||||
22
modules/features/region-nl.nix
Normal file
22
modules/features/region-nl.nix
Normal file
@@ -0,0 +1,22 @@
|
||||
{ ... }:
|
||||
{
|
||||
lux.region-nl.nixos = {
|
||||
time.timeZone = "Europe/Amsterdam";
|
||||
|
||||
i18n.defaultLocale = "en_US.UTF-8";
|
||||
i18n.extraLocaleSettings = {
|
||||
LC_MEASUREMENT = "nl_NL.UTF-8";
|
||||
LC_PAPER = "nl_NL.UTF-8";
|
||||
LC_ADDRESS = "nl_NL.UTF-8";
|
||||
LC_TELEPHONE = "nl_NL.UTF-8";
|
||||
LC_NAME = "nl_NL.UTF-8";
|
||||
|
||||
# Use '.' as decimal point and ',' as thouands separator
|
||||
LC_NUMERIC = "en_IE.UTF-8";
|
||||
LC_MONETARY = "en_IE.UTF-8";
|
||||
|
||||
# English day and month names, YYYY-MM-DD format
|
||||
LC_TIME = "en_IE.UTF-8";
|
||||
};
|
||||
};
|
||||
}
|
||||
17
modules/features/sddm.nix
Normal file
17
modules/features/sddm.nix
Normal file
@@ -0,0 +1,17 @@
|
||||
{ inputs, ... }:
|
||||
{
|
||||
lux.sddm = {
|
||||
nixos =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
services.displayManager.sddm = {
|
||||
enable = true;
|
||||
wayland.enable = true;
|
||||
theme = "${pkgs.sddm-astronaut}/share/sddm/themes/sddm-astronaut-theme";
|
||||
extraPackages = with pkgs; [
|
||||
kdePackages.qtmultimedia
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
22
modules/features/services/actual.nix
Normal file
22
modules/features/services/actual.nix
Normal file
@@ -0,0 +1,22 @@
|
||||
{ den, ... }:
|
||||
{
|
||||
lux.services._.actual = den.lib.perHost (
|
||||
{ host, ... }:
|
||||
{
|
||||
nixos =
|
||||
{ config, ... }:
|
||||
{
|
||||
services.actual = {
|
||||
enable = true;
|
||||
openFirewall = false;
|
||||
settings = {
|
||||
port = 3000;
|
||||
hostname = "127.0.0.1";
|
||||
};
|
||||
};
|
||||
services.caddy.virtualHosts."finance.${host.serviceDomain}".extraConfig =
|
||||
"reverse_proxy :${toString config.services.actual.settings.port}";
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
10
modules/features/services/caddy.nix
Normal file
10
modules/features/services/caddy.nix
Normal file
@@ -0,0 +1,10 @@
|
||||
{ den, ... }:
|
||||
{
|
||||
lux.services._.caddy = den.lib.perHost ({ host }: {
|
||||
nixos.services.caddy = {
|
||||
enable = true;
|
||||
email = "mail@jelles.net";
|
||||
openFirewall = true;
|
||||
};
|
||||
});
|
||||
}
|
||||
20
modules/features/services/deluge.nix
Normal file
20
modules/features/services/deluge.nix
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
lux.deluge = {
|
||||
nixos =
|
||||
{ config, ... }:
|
||||
{
|
||||
sops.secrets.deluge-auth-file = { };
|
||||
|
||||
services.deluge = {
|
||||
enable = true;
|
||||
# For some reason passwords never match??
|
||||
declarative = false;
|
||||
};
|
||||
};
|
||||
homeManager =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
home.packages = [ pkgs.deluge ];
|
||||
};
|
||||
};
|
||||
}
|
||||
36
modules/features/services/gitea.nix
Normal file
36
modules/features/services/gitea.nix
Normal file
@@ -0,0 +1,36 @@
|
||||
{ den, ... }:
|
||||
{
|
||||
lux.services._.gitea = den.lib.perHost (
|
||||
{ host }:
|
||||
{
|
||||
nixos =
|
||||
{ config, ... }:
|
||||
{
|
||||
services.gitea = {
|
||||
enable = true;
|
||||
|
||||
settings = {
|
||||
server = {
|
||||
DOMAIN = "git.${host.serviceDomain}";
|
||||
ROOT_URL = "https://git.${host.serviceDomain}/";
|
||||
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.${host.serviceDomain}".extraConfig =
|
||||
"reverse_proxy :${toString config.services.gitea.settings.server.HTTP_PORT}";
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
80
modules/features/services/openssh.nix
Normal file
80
modules/features/services/openssh.nix
Normal file
@@ -0,0 +1,80 @@
|
||||
{ den, lib, ... }:
|
||||
let
|
||||
hostConfig =
|
||||
{ host }:
|
||||
{
|
||||
nixos =
|
||||
{ config, ... }:
|
||||
{
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
settings = {
|
||||
PermitRootLogin = "no";
|
||||
PasswordAuthentication = false;
|
||||
AllowUsers = lib.attrNames host.users;
|
||||
};
|
||||
};
|
||||
|
||||
users.users = lib.mapAttrs (_: user: {
|
||||
openssh.authorizedKeys.keys = user.authorizedSshKeys;
|
||||
}) host.users;
|
||||
|
||||
assertions = lib.optionals host.requiresSshRecovery (
|
||||
let
|
||||
missingUsers = lib.filter (userName: !(builtins.hasAttr userName host.users)) host.sshRecoveryUsers;
|
||||
usersWithoutKeys = lib.filter (
|
||||
userName:
|
||||
(builtins.hasAttr userName host.users) && host.users.${userName}.authorizedSshKeys == [ ]
|
||||
) host.sshRecoveryUsers;
|
||||
in
|
||||
[
|
||||
{
|
||||
assertion = config.services.openssh.enable;
|
||||
message = "Hosts with requiresSshRecovery must enable OpenSSH.";
|
||||
}
|
||||
{
|
||||
assertion = config.services.openssh.settings.PasswordAuthentication == false;
|
||||
message = "Hosts with requiresSshRecovery must disable SSH password authentication.";
|
||||
}
|
||||
{
|
||||
assertion =
|
||||
let
|
||||
rootLogin = config.services.openssh.settings.PermitRootLogin;
|
||||
in
|
||||
rootLogin == false || rootLogin == "no";
|
||||
message = "Hosts with requiresSshRecovery must disable SSH root login.";
|
||||
}
|
||||
{
|
||||
assertion = host.sshRecoveryUsers != [ ];
|
||||
message = "Hosts with requiresSshRecovery must declare at least one sshRecoveryUser.";
|
||||
}
|
||||
{
|
||||
assertion = missingUsers == [ ];
|
||||
message =
|
||||
"All sshRecoveryUsers must exist on the host. Missing: "
|
||||
+ lib.concatStringsSep ", " missingUsers;
|
||||
}
|
||||
{
|
||||
assertion = usersWithoutKeys == [ ];
|
||||
message =
|
||||
"All sshRecoveryUsers must have plain authorizedSshKeys. Missing keys for: "
|
||||
+ lib.concatStringsSep ", " usersWithoutKeys;
|
||||
}
|
||||
{
|
||||
assertion = host.sopsHostSshKeyPath != null;
|
||||
message = "Hosts with requiresSshRecovery must set sopsHostSshKeyPath.";
|
||||
}
|
||||
{
|
||||
assertion = config.services.openssh.openFirewall || lib.elem 22 config.networking.firewall.allowedTCPPorts;
|
||||
message = "Hosts with requiresSshRecovery must expose SSH through the firewall.";
|
||||
}
|
||||
]
|
||||
);
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
lux.services._.openssh = den.lib.parametric.exactly {
|
||||
includes = [ hostConfig ];
|
||||
};
|
||||
}
|
||||
13
modules/features/services/qbittorrent.nix
Normal file
13
modules/features/services/qbittorrent.nix
Normal file
@@ -0,0 +1,13 @@
|
||||
{ ... }:
|
||||
{
|
||||
lux.qbittorrent = {
|
||||
nixos = {
|
||||
services.qbittorrent = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
torrentingPort = 43864;
|
||||
webuiPort = 8123;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
33
modules/features/services/radicale.nix
Normal file
33
modules/features/services/radicale.nix
Normal file
@@ -0,0 +1,33 @@
|
||||
{ den, ... }:
|
||||
{
|
||||
lux.services._.radicale = den.lib.perHost (
|
||||
{ host }:
|
||||
{
|
||||
nixos =
|
||||
{ config, ... }:
|
||||
{
|
||||
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.${host.serviceDomain}".extraConfig = ''
|
||||
reverse_proxy :5232 {
|
||||
header_up X-Script-Name /
|
||||
header_up X-Forwarded-For {remote}
|
||||
header_up X-Remote-User {http.auth.user.id}
|
||||
}'';
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
20
modules/features/services/vaultwarden.nix
Normal file
20
modules/features/services/vaultwarden.nix
Normal file
@@ -0,0 +1,20 @@
|
||||
{ den, ... }:
|
||||
{
|
||||
lux.services._.vaultwarden = den.lib.perHost ({ host }: {
|
||||
nixos = { config, ... }: {
|
||||
services.vaultwarden = {
|
||||
enable = true;
|
||||
backupDir = "/var/backup/vaultwarden";
|
||||
config = {
|
||||
DOMAIN = "https://vault.${host.serviceDomain}";
|
||||
SIGNUPS_ALLOWED = false;
|
||||
ROCKET_PORT = 8100;
|
||||
ROCKET_LOG = "critical";
|
||||
};
|
||||
};
|
||||
|
||||
services.caddy.virtualHosts."vault.${host.serviceDomain}".extraConfig =
|
||||
"reverse_proxy :${toString config.services.vaultwarden.config.ROCKET_PORT}";
|
||||
};
|
||||
});
|
||||
}
|
||||
184
modules/features/shell.nix
Normal file
184
modules/features/shell.nix
Normal file
@@ -0,0 +1,184 @@
|
||||
{ inputs, ... }:
|
||||
{
|
||||
lux.shell = {
|
||||
homeManager =
|
||||
{ lib, config, ... }:
|
||||
{
|
||||
home.sessionVariables = {
|
||||
STARSHIP_CACHE = "${config.xdg.cacheHome}/starship";
|
||||
};
|
||||
|
||||
# Delete zcompdump on config switch, so that we regenerate completions
|
||||
home.activation = {
|
||||
clearZshCompDump = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||
rm -f "${config.programs.zsh.dotDir}"/.zcompdump*
|
||||
'';
|
||||
};
|
||||
|
||||
programs.zsh = {
|
||||
enable = true;
|
||||
dotDir = "${config.xdg.configHome}/zsh";
|
||||
|
||||
enableCompletion = true;
|
||||
completionInit = ''
|
||||
autoload -U compinit
|
||||
compinit -C
|
||||
|
||||
ZCOMPDUMP="${config.programs.zsh.dotDir}/.zcompdump"
|
||||
# Compile it in the background
|
||||
{
|
||||
if [[ -s "$ZCOMPDUMP" && (! -s "''${ZCOMPDUMP}.zwc" || "$ZCOMPDUMP" -nt "''${ZCOMPDUMP}.zwc") ]]; then
|
||||
zcompile "$ZCOMPDUMP"
|
||||
fi
|
||||
} &!
|
||||
'';
|
||||
autosuggestion.enable = true;
|
||||
|
||||
syntaxHighlighting = {
|
||||
enable = true;
|
||||
highlighters = [
|
||||
"main"
|
||||
"brackets"
|
||||
"pattern"
|
||||
"regexp"
|
||||
"root"
|
||||
"line"
|
||||
];
|
||||
};
|
||||
|
||||
historySubstringSearch.enable = true;
|
||||
|
||||
history = {
|
||||
ignoreDups = true;
|
||||
save = 10000;
|
||||
size = 10000;
|
||||
path = "${config.xdg.dataHome}/zsh_history";
|
||||
};
|
||||
|
||||
profileExtra = lib.optionalString (config.home.sessionPath != [ ]) ''
|
||||
export PATH="$PATH''${PATH:+:}${lib.concatStringsSep ":" config.home.sessionPath}"
|
||||
'';
|
||||
|
||||
initContent =
|
||||
# bash
|
||||
''
|
||||
bindkey -v
|
||||
|
||||
export KEYTIMEOUT=1
|
||||
|
||||
# search history based on what's typed in the prompt
|
||||
autoload -U history-search-end
|
||||
zle -N history-beginning-search-backward-end history-search-end
|
||||
zle -N history-beginning-search-forward-end history-search-end
|
||||
bindkey "^[OA" history-beginning-search-backward-end
|
||||
bindkey "^[OB" history-beginning-search-forward-end
|
||||
|
||||
# General completion behavior
|
||||
zstyle ':completion:*' completer _extensions _complete _approximate
|
||||
|
||||
# Use cache
|
||||
zstyle ':completion:*' use-cache on
|
||||
zstyle ':completion:*' cache-path "$XDG_CACHE_HOME/zsh/.zcompcache"
|
||||
|
||||
# Complete the alias
|
||||
zstyle ':completion:*' complete true
|
||||
|
||||
# Autocomplete options
|
||||
zstyle ':completion:*' complete-options true
|
||||
|
||||
# Completion matching control
|
||||
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*'
|
||||
zstyle ':completion:*' keep-prefix true
|
||||
|
||||
# Group matches and describe
|
||||
zstyle ':completion:*' menu select
|
||||
zstyle ':completion:*' list-grouped false
|
||||
zstyle ':completion:*' list-separator '''
|
||||
zstyle ':completion:*' group-name '''
|
||||
zstyle ':completion:*' verbose yes
|
||||
zstyle ':completion:*:matches' group 'yes'
|
||||
zstyle ':completion:*:warnings' format '%F{red}%B-- No match for: %d --%b%f'
|
||||
zstyle ':completion:*:messages' format '%d'
|
||||
zstyle ':completion:*:corrections' format '%B%d (errors: %e)%b'
|
||||
zstyle ':completion:*:descriptions' format '[%d]'
|
||||
|
||||
# Colors
|
||||
zstyle ':completion:*' list-colors ''${(s.:.)LS_COLORS}
|
||||
|
||||
# case insensitive tab completion
|
||||
zstyle ':completion:*:*:cd:*' tag-order local-directories directory-stack path-directories
|
||||
zstyle ':completion:*:*:cd:*:directory-stack' menu yes select
|
||||
zstyle ':completion:*:-tilde-:*' group-order 'named-directories' 'path-directories' 'users' 'expand'
|
||||
zstyle ':completion:*:*:-command-:*:*' group-order aliases builtins functions commands
|
||||
zstyle ':completion:*' special-dirs true
|
||||
zstyle ':completion:*' squeeze-slashes true
|
||||
|
||||
# Sort
|
||||
zstyle ':completion:*' sort false
|
||||
zstyle ":completion:*:git-checkout:*" sort false
|
||||
zstyle ':completion:*' file-sort modification
|
||||
zstyle ':completion:*:eza' sort false
|
||||
zstyle ':completion:complete:*:options' sort false
|
||||
zstyle ':completion:files' sort false
|
||||
'';
|
||||
};
|
||||
|
||||
programs.starship = {
|
||||
enable = true;
|
||||
enableZshIntegration = true;
|
||||
settings = {
|
||||
add_newline = true;
|
||||
|
||||
format = lib.concatStrings [
|
||||
"$nix_shell"
|
||||
"$hostname"
|
||||
"$directory"
|
||||
"$git_branch"
|
||||
"$git_state"
|
||||
"$git_status"
|
||||
"$line_break"
|
||||
"$character"
|
||||
];
|
||||
|
||||
directory = {
|
||||
truncation_length = 99;
|
||||
truncate_to_repo = false;
|
||||
};
|
||||
|
||||
nix_shell = {
|
||||
format = "[$symbol]($style) ";
|
||||
symbol = "🐚";
|
||||
style = "";
|
||||
};
|
||||
|
||||
git_status = {
|
||||
format = "[[(*$conflicted$untracked$modified$staged$renamed$deleted)](218)($ahead_behind$stashed)]($style)";
|
||||
style = "cyan";
|
||||
conflicted = "";
|
||||
renamed = "";
|
||||
deleted = "";
|
||||
stashed = "≡";
|
||||
};
|
||||
|
||||
git_state = {
|
||||
format = "([$state( $progress_current/$progress_total)]($style)) ";
|
||||
style = "bright-black";
|
||||
};
|
||||
|
||||
line_break = {
|
||||
disabled = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
programs.eza = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
programs.fzf = {
|
||||
enable = true;
|
||||
enableZshIntegration = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
14
modules/features/sops-password.nix
Normal file
14
modules/features/sops-password.nix
Normal file
@@ -0,0 +1,14 @@
|
||||
{ den, ... }:
|
||||
{
|
||||
lux.sops-password = den.lib.perUser (
|
||||
{ user, ... }:
|
||||
{
|
||||
nixos =
|
||||
{ config, ... }:
|
||||
{
|
||||
sops.secrets."hashed-password-${user.userName}".neededForUsers = true;
|
||||
users.users.${user.userName}.hashedPasswordFile = config.sops.secrets."hashed-password-${user.userName}".path;
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
27
modules/features/ssh.nix
Normal file
27
modules/features/ssh.nix
Normal file
@@ -0,0 +1,27 @@
|
||||
{ den, ... }:
|
||||
{
|
||||
lux.ssh = {
|
||||
homeManager =
|
||||
{ config, ... }:
|
||||
{
|
||||
programs.ssh = {
|
||||
enable = true;
|
||||
enableDefaultConfig = false;
|
||||
includes = [
|
||||
config.sops.templates."ssh-config-orion".path
|
||||
];
|
||||
};
|
||||
|
||||
sops.secrets."orion-ip" = { };
|
||||
sops.templates."ssh-config-orion".content = ''
|
||||
Host orion
|
||||
HostName ${config.sops.placeholder."orion-ip"}
|
||||
ForwardAgent yes
|
||||
'';
|
||||
};
|
||||
|
||||
nixos.security.sudo.extraConfig = ''
|
||||
Defaults env_keep+=SSH_AUTH_SOCK
|
||||
'';
|
||||
};
|
||||
}
|
||||
13
modules/features/steam.nix
Normal file
13
modules/features/steam.nix
Normal file
@@ -0,0 +1,13 @@
|
||||
{ ... }:
|
||||
{
|
||||
lux.steam = {
|
||||
nixos =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
programs.steam = {
|
||||
enable = true;
|
||||
protontricks.enable = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
56
modules/features/syncthing.nix
Normal file
56
modules/features/syncthing.nix
Normal file
@@ -0,0 +1,56 @@
|
||||
{
|
||||
den,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
meshDevices = lib.listToAttrs (
|
||||
lib.concatMap (
|
||||
host:
|
||||
lib.mapAttrsToList (
|
||||
userName: user:
|
||||
let
|
||||
name = "${userName}@${host.name}";
|
||||
in
|
||||
{
|
||||
inherit name;
|
||||
value = {
|
||||
inherit name;
|
||||
id = user.syncthingId;
|
||||
};
|
||||
}
|
||||
) (lib.filterAttrs (_: u: u.syncthingId != null) host.users)
|
||||
) (lib.attrValues den.hosts.x86_64-linux)
|
||||
);
|
||||
in
|
||||
{
|
||||
lux.syncthing = den.lib.perUser (
|
||||
{ host, user }:
|
||||
{
|
||||
homeManager = {
|
||||
services.syncthing = {
|
||||
enable = true;
|
||||
|
||||
overrideDevices = true;
|
||||
overrideFolders = true;
|
||||
|
||||
settings = {
|
||||
folders = {
|
||||
sync = {
|
||||
path = "~/sync";
|
||||
label = "sync";
|
||||
devices = lib.attrNames meshDevices;
|
||||
};
|
||||
calibre = {
|
||||
path = "~/calibre";
|
||||
label = "calibre";
|
||||
devices = lib.attrNames meshDevices;
|
||||
};
|
||||
};
|
||||
devices = meshDevices;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
10
modules/features/system-base.nix
Normal file
10
modules/features/system-base.nix
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
lux.system-base.nixos = {
|
||||
users.mutableUsers = false;
|
||||
|
||||
services.dbus.implementation = "broker";
|
||||
|
||||
programs.nix-ld.enable = true;
|
||||
environment.localBinInPath = true;
|
||||
};
|
||||
}
|
||||
82
modules/features/terminal.nix
Normal file
82
modules/features/terminal.nix
Normal file
@@ -0,0 +1,82 @@
|
||||
{ inputs, ... }:
|
||||
{
|
||||
lux.terminal = {
|
||||
homeManager =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
xdg.terminal-exec = {
|
||||
enable = true;
|
||||
settings.default = [ "kitty.desktop" ];
|
||||
};
|
||||
|
||||
programs.kitty = {
|
||||
enable = true;
|
||||
font = {
|
||||
name = "JetBrains Mono";
|
||||
size = 11;
|
||||
};
|
||||
settings = {
|
||||
# Fonts
|
||||
disable_ligatures = "always";
|
||||
|
||||
# Scrollback
|
||||
scrollback_lines = 10000;
|
||||
|
||||
# Terminal bell
|
||||
enable_audio_bell = false;
|
||||
|
||||
# Window layout
|
||||
confirm_os_window_close = 0;
|
||||
window_padding_width = 3;
|
||||
|
||||
# Advanced
|
||||
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
|
||||
|
||||
# Tabs
|
||||
active_tab_background #1F1F28
|
||||
active_tab_foreground #C8C093
|
||||
inactive_tab_background #1F1F28
|
||||
inactive_tab_foreground #727169
|
||||
#tab_bar_background #15161E
|
||||
|
||||
# normal
|
||||
color0 #16161D
|
||||
color1 #C34043
|
||||
color2 #76946A
|
||||
color3 #C0A36E
|
||||
color4 #7E9CD8
|
||||
color5 #957FB8
|
||||
color6 #6A9589
|
||||
color7 #C8C093
|
||||
|
||||
# bright
|
||||
color8 #727169
|
||||
color9 #E82424
|
||||
color10 #98BB6C
|
||||
color11 #E6C384
|
||||
color12 #7FB4CA
|
||||
color13 #938AA9
|
||||
color14 #7AA89F
|
||||
color15 #DCD7BA
|
||||
|
||||
# extended colors
|
||||
color16 #FFA066
|
||||
color17 #FF5D62
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
54
modules/features/theme.nix
Normal file
54
modules/features/theme.nix
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
lux.theme = {
|
||||
homeManager =
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
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 in nixpkgs is outdated
|
||||
package = pkgs.kanagawa-gtk-theme.overrideAttrs (oldAttrs: {
|
||||
version = "unstable-2025-10-23";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "Fausto-Korpsvart";
|
||||
repo = "Kanagawa-GKT-Theme";
|
||||
rev = "55ca4ba249eba21f861b9866b71ab41bb8930318";
|
||||
hash = "sha256-UdMoMx2DoovcxSp/zBZ3PRv/Qpj+prd0uPm1gmdak2E=";
|
||||
};
|
||||
});
|
||||
};
|
||||
gtk4.theme = {
|
||||
inherit (config.gtk.theme) name package;
|
||||
};
|
||||
iconTheme = {
|
||||
name = "Kanagawa";
|
||||
package = pkgs.kanagawa-icon-theme.overrideAttrs (oldAttrs: {
|
||||
version = "unstable-2025-10-23";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "Fausto-Korpsvart";
|
||||
repo = "Kanagawa-GKT-Theme";
|
||||
rev = "55ca4ba249eba21f861b9866b71ab41bb8930318";
|
||||
hash = "sha256-UdMoMx2DoovcxSp/zBZ3PRv/Qpj+prd0uPm1gmdak2E=";
|
||||
};
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
qt = {
|
||||
enable = true;
|
||||
platformTheme.name = "gtk3";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
73
modules/features/vicinae.nix
Normal file
73
modules/features/vicinae.nix
Normal file
@@ -0,0 +1,73 @@
|
||||
{ inputs, ... }:
|
||||
{
|
||||
lux.vicinae = {
|
||||
homeManager =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
programs.vicinae = {
|
||||
enable = true;
|
||||
systemd.enable = true;
|
||||
|
||||
themes = {
|
||||
kanagawa-wave = {
|
||||
meta = {
|
||||
version = 1;
|
||||
name = "Kanagawa Wave";
|
||||
description = "A dark theme inspired by the colors of the famous painting by Katsushika Hokusai.";
|
||||
variant = "dark";
|
||||
inherits = "vicinae-dark";
|
||||
};
|
||||
colors = {
|
||||
core = {
|
||||
background = "#1F1F28";
|
||||
foreground = "#DCD7BA";
|
||||
secondary_background = "#16161D";
|
||||
border = "#2A2A37";
|
||||
accent = "#7E9CD8";
|
||||
};
|
||||
accents = {
|
||||
blue = "#7E9CD8";
|
||||
green = "#98BB6C";
|
||||
magenta = "#D27E99";
|
||||
orange = "#FFA066";
|
||||
purple = "#957FB8";
|
||||
red = "#E82424";
|
||||
yellow = "#E6C384";
|
||||
cyan = "#7AA89F";
|
||||
};
|
||||
input = {
|
||||
border_focus = "colors.core.accent";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
settings = {
|
||||
theme = {
|
||||
light.name = "kanagawa-wave";
|
||||
dark.name = "kanagawa-wave";
|
||||
};
|
||||
};
|
||||
|
||||
extensions = with inputs.vicinae-extensions.packages.${pkgs.stdenv.hostPlatform.system}; [
|
||||
agenda
|
||||
#bluetooth
|
||||
brotab
|
||||
#dbus
|
||||
fuzzy-files
|
||||
github
|
||||
it-tools
|
||||
niri
|
||||
nix
|
||||
podman
|
||||
process-manager
|
||||
pulseaudio
|
||||
simple-bookmarks
|
||||
ssh
|
||||
#systemd
|
||||
];
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
}
|
||||
52
modules/features/xdg.nix
Normal file
52
modules/features/xdg.nix
Normal file
@@ -0,0 +1,52 @@
|
||||
{
|
||||
lux.xdg = {
|
||||
homeManager =
|
||||
{ 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";
|
||||
|
||||
# Organize into media folder
|
||||
music = "${mediaDir}/music";
|
||||
pictures = "${mediaDir}/images";
|
||||
videos = "${mediaDir}/videos";
|
||||
|
||||
# Hide these
|
||||
desktop = "${localDir}/desktop";
|
||||
publicShare = "${localDir}/public";
|
||||
templates = "${localDir}/templates";
|
||||
};
|
||||
|
||||
mimeApps = {
|
||||
enable = true;
|
||||
defaultApplicationPackages = with pkgs; [
|
||||
sioyek
|
||||
imv
|
||||
vivaldi
|
||||
neovim
|
||||
nautilus
|
||||
];
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
40
modules/hosts/orion/default.nix
Normal file
40
modules/hosts/orion/default.nix
Normal file
@@ -0,0 +1,40 @@
|
||||
{ lux, ... }:
|
||||
let
|
||||
lingerForUsers = {
|
||||
user.linger = true;
|
||||
};
|
||||
in
|
||||
{
|
||||
den.aspects.orion = {
|
||||
provides.to-users = lingerForUsers;
|
||||
|
||||
includes = with lux.services._; [
|
||||
caddy
|
||||
openssh
|
||||
vaultwarden
|
||||
radicale
|
||||
actual
|
||||
gitea
|
||||
];
|
||||
|
||||
nixos =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = [
|
||||
pkgs.kitty
|
||||
];
|
||||
|
||||
networking = {
|
||||
firewall.enable = true;
|
||||
firewall.allowPing = false;
|
||||
nftables.enable = true;
|
||||
};
|
||||
|
||||
# Use ssh authorization for sudo instead of password
|
||||
security.pam = {
|
||||
sshAgentAuth.enable = true;
|
||||
services.sudo.sshAgentAuth = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
63
modules/hosts/orion/disk.nix
Normal file
63
modules/hosts/orion/disk.nix
Normal file
@@ -0,0 +1,63 @@
|
||||
{ inputs, ... }:
|
||||
{
|
||||
den.aspects.orion = {
|
||||
nixos =
|
||||
{ lib, ... }:
|
||||
{
|
||||
imports = [ inputs.disko.nixosModules.disko ];
|
||||
|
||||
disko.devices = {
|
||||
disk.disk1 = {
|
||||
device = lib.mkDefault "/dev/sda";
|
||||
type = "disk";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
boot = {
|
||||
name = "boot";
|
||||
size = "1M";
|
||||
type = "EF02";
|
||||
};
|
||||
esp = {
|
||||
name = "ESP";
|
||||
size = "500M";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
};
|
||||
};
|
||||
root = {
|
||||
name = "root";
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "lvm_pv";
|
||||
vg = "pool";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
lvm_vg = {
|
||||
pool = {
|
||||
type = "lvm_vg";
|
||||
lvs = {
|
||||
root = {
|
||||
size = "100%FREE";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "ext4";
|
||||
mountpoint = "/";
|
||||
mountOptions = [
|
||||
"defaults"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
38
modules/hosts/orion/hardware.nix
Normal file
38
modules/hosts/orion/hardware.nix
Normal file
@@ -0,0 +1,38 @@
|
||||
# Do not modify this file! It was generated by 'nixos-generate-config'
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/system.nix instead.
|
||||
{ ... }:
|
||||
{
|
||||
den.aspects.orion = {
|
||||
nixos =
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/profiles/qemu-guest.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [
|
||||
"ata_piix"
|
||||
"uhci_hcd"
|
||||
"virtio_pci"
|
||||
"virtio_scsi"
|
||||
"sd_mod"
|
||||
"sr_mod"
|
||||
];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
};
|
||||
};
|
||||
}
|
||||
65
modules/hosts/polaris/default.nix
Normal file
65
modules/hosts/polaris/default.nix
Normal file
@@ -0,0 +1,65 @@
|
||||
{ inputs, lux, ... }:
|
||||
{
|
||||
den.aspects.polaris = {
|
||||
includes = [ lux.bundles._.local-session ];
|
||||
|
||||
provides.kiri = {
|
||||
includes = with lux; [
|
||||
bitwarden
|
||||
email
|
||||
pim
|
||||
mpv
|
||||
sops-password
|
||||
steam
|
||||
];
|
||||
};
|
||||
|
||||
nixos =
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = with inputs.nixos-hardware.nixosModules; [
|
||||
common-pc
|
||||
common-pc-ssd
|
||||
common-cpu-amd
|
||||
common-gpu-amd
|
||||
];
|
||||
|
||||
services.hardware.openrgb.enable = true;
|
||||
|
||||
boot = {
|
||||
loader = {
|
||||
efi.canTouchEfiVariables = true;
|
||||
systemd-boot = {
|
||||
enable = true;
|
||||
consoleMode = "auto";
|
||||
configurationLimit = 5;
|
||||
|
||||
# Convert boot entry to a more readable name.
|
||||
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;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
50
modules/hosts/polaris/hardware.nix
Normal file
50
modules/hosts/polaris/hardware.nix
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
den.aspects.polaris = {
|
||||
nixos =
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [
|
||||
"nvme"
|
||||
"xhci_pci"
|
||||
"ahci"
|
||||
"usbhid"
|
||||
"usb_storage"
|
||||
"sd_mod"
|
||||
];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-amd" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" = {
|
||||
device = "/dev/disk/by-uuid/bda7f8b9-2b3d-4190-8518-baa50490227e";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/disk/by-uuid/26FE-CA37";
|
||||
fsType = "vfat";
|
||||
options = [
|
||||
"fmask=0077"
|
||||
"dmask=0077"
|
||||
];
|
||||
};
|
||||
|
||||
swapDevices = [ ];
|
||||
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
};
|
||||
};
|
||||
}
|
||||
41
modules/hosts/zenith/default.nix
Normal file
41
modules/hosts/zenith/default.nix
Normal file
@@ -0,0 +1,41 @@
|
||||
{ inputs, lux, ... }:
|
||||
{
|
||||
den.aspects.zenith = {
|
||||
includes = [ lux.bundles._.local-session ];
|
||||
|
||||
provides.kiri = {
|
||||
includes = with lux; [
|
||||
bitwarden
|
||||
email
|
||||
pim
|
||||
mpv
|
||||
sops-password
|
||||
];
|
||||
};
|
||||
|
||||
nixos =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
imports = [
|
||||
inputs.nixos-hardware.nixosModules.lenovo-yoga-7-14ARH7-amdgpu
|
||||
];
|
||||
|
||||
boot = {
|
||||
loader = {
|
||||
efi.canTouchEfiVariables = true;
|
||||
systemd-boot = {
|
||||
enable = true;
|
||||
consoleMode = "auto";
|
||||
configurationLimit = 5;
|
||||
};
|
||||
};
|
||||
|
||||
tmp.cleanOnBoot = true;
|
||||
kernelPackages = pkgs.linuxPackages_latest;
|
||||
};
|
||||
|
||||
hardware.enableRedistributableFirmware = true;
|
||||
services.fwupd.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
46
modules/hosts/zenith/hardware.nix
Normal file
46
modules/hosts/zenith/hardware.nix
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
den.aspects.zenith = {
|
||||
nixos =
|
||||
{
|
||||
lib,
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [
|
||||
"nvme"
|
||||
"xhci_pci"
|
||||
"usb_storage"
|
||||
"sd_mod"
|
||||
];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-amd" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" = {
|
||||
device = "/dev/disk/by-uuid/6d8f6f33-c9d9-4e90-b496-d5b3ef5e9aeb";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/disk/by-uuid/8797-B47E";
|
||||
fsType = "vfat";
|
||||
options = [
|
||||
"fmask=0077"
|
||||
"dmask=0077"
|
||||
];
|
||||
};
|
||||
|
||||
swapDevices = [ ];
|
||||
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
};
|
||||
};
|
||||
}
|
||||
96
modules/infra.nix
Normal file
96
modules/infra.nix
Normal file
@@ -0,0 +1,96 @@
|
||||
let
|
||||
serviceDomain = "jelles.net";
|
||||
adminKeyPath = "/var/lib/sops-nix/admin-key.txt";
|
||||
|
||||
sharedIdentity = {
|
||||
realName = "Jelle Spreeuwenberg";
|
||||
authorizedSshKeys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAU2LydkXRTtNFY7oyX8JQURwXLVhB71DeK8XzrXeFX1 openpgp:0xA490D93A"
|
||||
];
|
||||
};
|
||||
|
||||
kiriAccount = sharedIdentity // {
|
||||
emails = {
|
||||
main = {
|
||||
address = "mail@jelles.net";
|
||||
primary = true;
|
||||
kind = "mxrouting";
|
||||
};
|
||||
old = {
|
||||
address = "mail@jellespreeuwenberg.nl";
|
||||
kind = "mxrouting";
|
||||
};
|
||||
uni = {
|
||||
address = "j.spreeuwenberg@student.tue.nl";
|
||||
kind = "office365";
|
||||
};
|
||||
work = {
|
||||
address = "jelle.spreeuwenberg@yookr.org";
|
||||
kind = "office365";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ergonAccount = sharedIdentity // {
|
||||
emails.work = {
|
||||
address = "jelle.spreeuwenberg@yookr.org";
|
||||
primary = true;
|
||||
kind = "office365";
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
den.hosts.x86_64-linux = {
|
||||
polaris = {
|
||||
inherit serviceDomain;
|
||||
sopsAdminKeyPath = adminKeyPath;
|
||||
sopsAdminKeyUsers = [
|
||||
"kiri"
|
||||
"ergon"
|
||||
];
|
||||
displays = {
|
||||
"LG Electronics LG ULTRAGEAR 103NTYT8R290" = {
|
||||
primary = true;
|
||||
position.x = 0;
|
||||
position.y = 0;
|
||||
};
|
||||
|
||||
"LG Electronics LG ULTRAGEAR 103NTJJ8R332" = {
|
||||
position.x = 2560;
|
||||
position.y = 0;
|
||||
};
|
||||
};
|
||||
users = {
|
||||
kiri = kiriAccount // {
|
||||
syncthingId = "6HBAKXB-DB3B4H2-BODCAXF-KD23H5W-6X5LGLC-ZJHZHLG-7U7YMGO-BB6IXQ3";
|
||||
};
|
||||
ergon = ergonAccount;
|
||||
};
|
||||
};
|
||||
|
||||
zenith = {
|
||||
inherit serviceDomain;
|
||||
sopsAdminKeyPath = adminKeyPath;
|
||||
sopsAdminKeyUsers = [
|
||||
"kiri"
|
||||
"ergon"
|
||||
];
|
||||
users = {
|
||||
kiri = kiriAccount;
|
||||
ergon = ergonAccount;
|
||||
};
|
||||
};
|
||||
|
||||
orion = {
|
||||
inherit serviceDomain;
|
||||
requiresSshRecovery = true;
|
||||
sshRecoveryUsers = [ "kiri" ];
|
||||
sopsHostSshKeyPath = "/etc/ssh/ssh_host_ed25519_key";
|
||||
sopsAdminKeyPath = adminKeyPath;
|
||||
sopsAdminKeyUsers = [ "kiri" ];
|
||||
users.kiri = kiriAccount // {
|
||||
syncthingId = "NNRNQKZ-OWPHSVA-B6KKBHE-SDYLSTV-7SVHGPR-NEWLKPL-4MWNJG4-G5FHUAI";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
135
modules/schema.nix
Normal file
135
modules/schema.nix
Normal file
@@ -0,0 +1,135 @@
|
||||
{ lib, ... }:
|
||||
{
|
||||
den.schema = {
|
||||
user =
|
||||
{ config, ... }:
|
||||
let
|
||||
primaryEmailCount = builtins.length (lib.filter (email: email.primary) (builtins.attrValues config.emails));
|
||||
in
|
||||
{
|
||||
options = {
|
||||
realName = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
};
|
||||
authorizedSshKeys = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
};
|
||||
emails = lib.mkOption {
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule (
|
||||
{ ... }:
|
||||
{
|
||||
options = {
|
||||
address = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
};
|
||||
primary = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
};
|
||||
kind = lib.mkOption {
|
||||
type = lib.types.enum [
|
||||
"mxrouting"
|
||||
"office365"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
default = { };
|
||||
};
|
||||
syncthingId = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
config = {
|
||||
assertions = [
|
||||
{
|
||||
assertion = primaryEmailCount == 1;
|
||||
message = "Each user must define exactly one primary email.";
|
||||
}
|
||||
];
|
||||
classes = lib.mkDefault [ "homeManager" ];
|
||||
};
|
||||
};
|
||||
host = {
|
||||
options = {
|
||||
serviceDomain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
};
|
||||
displays = lib.mkOption {
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule (
|
||||
{ ... }:
|
||||
{
|
||||
options = {
|
||||
position = lib.mkOption {
|
||||
type = lib.types.submodule {
|
||||
options = {
|
||||
x = lib.mkOption { type = lib.types.int; };
|
||||
y = lib.mkOption { type = lib.types.int; };
|
||||
};
|
||||
};
|
||||
};
|
||||
scale = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.oneOf [
|
||||
lib.types.int
|
||||
lib.types.float
|
||||
]);
|
||||
default = null;
|
||||
};
|
||||
primary = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
};
|
||||
mode = lib.mkOption {
|
||||
type = lib.types.nullOr (
|
||||
lib.types.submodule (
|
||||
{ ... }:
|
||||
{
|
||||
options = {
|
||||
width = lib.mkOption { type = lib.types.int; };
|
||||
height = lib.mkOption { type = lib.types.int; };
|
||||
refresh = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.float;
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
default = { };
|
||||
};
|
||||
requiresSshRecovery = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
};
|
||||
sshRecoveryUsers = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
};
|
||||
sopsHostSshKeyPath = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
};
|
||||
sopsAdminKeyPath = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
};
|
||||
sopsAdminKeyUsers = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
9
modules/secrets/.sops.yaml
Normal file
9
modules/secrets/.sops.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
keys:
|
||||
- &admin age122w85pqj508ukv0rd388mahecgfckmpgnsgz0zcyec37ljae2epsdnvxpl
|
||||
- &orion age1l49tm85prcpm4q8e0hxxetv08jqv3gfty3pvzte956dng4h0xaeq0he5yd
|
||||
creation_rules:
|
||||
- path_regex: secrets.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *admin
|
||||
- *orion
|
||||
32
modules/secrets/secrets.yaml
Normal file
32
modules/secrets/secrets.yaml
Normal file
@@ -0,0 +1,32 @@
|
||||
radicale-pass: ENC[AES256_GCM,data:3CpCnSibLWeZUJRBMuc=,iv:3J9x4ejcsYXCjRRGP5lOex+9EG8STLsbJ7FWesRpLIk=,tag:Pg1jIlnr2enuTsCvvWRWjg==,type:str]
|
||||
university-calendar-url: ENC[AES256_GCM,data:oGP1BdF3YxdRRr061LaC4HaaiPXoyZq7ZALqU+cv8wb2GgYT+jgshgx9LRjM3jsIjPXolkG5bCZi46r/rpEk3mWSskQ3YnCXcwM1BN+PPVapdtQgkRSWriAOUXPnRpaZzpMs5WaJTnkOrJJqfAoy+jGIE0Nhul/CRw5tOeRkwPbDxfA/dY9MT80ciHWHscHb1w9R,iv:1JqN80OnrIjOl4LGmk99LsJMmoT3hGjlCet6mYeRb5o=,tag:9GhVQIa1BXAEjdOxswHH/A==,type:str]
|
||||
ssh-config-orion: ENC[AES256_GCM,data:8vrbtuHCLlMDtMAfnJuf+DcWmPZwFFpyGag8l32JAFUMmWyEEEvDctNDHNahw8fiQzwN0+9atjY=,iv:UKWqjZ4D3+McASovEaE5jt4TAkmlwR26chFvWblgc1k=,tag:oZJKwLDPQEbfa4CPHn9lVQ==,type:str]
|
||||
orion-ip: ENC[AES256_GCM,data:S6fpCWnD8dvchvrHlEo=,iv:72+oRxHUEJ7imJ+sWjGbG+TUrSqYL8hbyHl3ChwFYwA=,tag:Rj6msje87+Ve+M6kcZd4Jw==,type:str]
|
||||
hashed-password-kiri: ENC[AES256_GCM,data:xubN5stH4RPlHYl+Jzcu2BCepz3Hra3TxjiSspktzjgpEWrU79h3NbcPMrYC0MSjsv3oaWio/S7nBV3Tes3WBlI9EC9vq+6tyTVPynUqpB7c9CvvYSmqc9bAHOnIOBb+gP2RR6JB395UoQ==,iv:uN83RNTfCJdBDhFhywV5NbVBp4xcptqzoKVAoAnaiQk=,tag:x9yufiPdSJwBADT6QymExA==,type:str]
|
||||
gemini-api-key-neovim: ENC[AES256_GCM,data:B8FeFt45FsU3aagyLDKXiwmx0mRrsw4C8RQ3EWXwZ+YfWLMvwJad,iv:1HqBD6vc07Ke/PMYXfHqFrWDGw/UMjiiBjLRN33/xHI=,tag:czcrYGbJFi41rYtIPM4qTQ==,type:str]
|
||||
booklore-db-pass: ENC[AES256_GCM,data:dlPGXQ24itEaBRJSJ9WOogWCdF3atFQ2ZtlLGyGq8Tin5OmSZI6lZUzSE+femBW5SBTIlKQvzHEPCs9MT5tyMIqetzGLm+mMN3FDW7si684Cuv9z9Uq5gjAZWh14KQMWYPI=,iv:oLnqu2EDFBVcBpswVRXXeF617YolPxOUx9CscHRRn/8=,tag:Si6gF1EXhcHalk11D3Exlw==,type:str]
|
||||
deluge-auth-file: ENC[AES256_GCM,data:uJME7CAC5OOJZLPdu9MNkg8ZDZZ64Wsytg==,iv:5l4eTSbdSKtOwjXGr7D1Teud5TON1+lcjWeI8W4bCuQ=,tag:ND8+cOUef1fwAGjmvWXEUQ==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age122w85pqj508ukv0rd388mahecgfckmpgnsgz0zcyec37ljae2epsdnvxpl
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMQXRVTlRjZDRMWksvc200
|
||||
T2lUN0d6eXZJZ2k2aXZHVUY4M2hSWFZEeVNBCkkxMTZQbGlZRFRHeW9wSFdwbXc0
|
||||
bHdWYVZucGlXTkYvSFRWNW83RUNCRDAKLS0tIG9ha2psQVhwY3NMS21mOUNkeEFx
|
||||
M3p6Nm9mY2RNVUp3ZW5KUGwvdm1rV2sKFygdzZgjTuG2JMzMnGuyE6qv4IvjHsIu
|
||||
Sv0PpSC9wgJQhoOCHUQVaPzn/Zv7llFlU3GBRqk8FLCj/IVaYVoc1g==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1l49tm85prcpm4q8e0hxxetv08jqv3gfty3pvzte956dng4h0xaeq0he5yd
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaWXVtMHBpMWtGOU03OGlH
|
||||
NW9WYVNkYWxBcEErUy91dW5VSWtBRGcxY2dNCm5ZTDhBT1U1TjZrdnBKVi85QkRD
|
||||
QkQwSDBock5MVGRwMmFkcjFxaXFZR0EKLS0tIHovWC9TREFxSjdTcjVTM3VnczJX
|
||||
aW8vM0IwQ243TnNPdnlkeHE4bTFLR00KaJhbOxdbIUJSzn4lOt2OO1HOTNaOoiSE
|
||||
+pKjsYZZQBdcYFPREjffEL+oiyxHwoLi95noHad9AGmygLqwboUkWg==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2026-03-09T12:12:17Z"
|
||||
mac: ENC[AES256_GCM,data:pEbPRbwpYbOibyFgysUVcGvZGTqEuvuLJizMzxvIgpn0B/jAsysRsi9aZd8HN6jOypRq0AaVVDmT6gDM6PBWXMPEx3Mlh83sW5omyc6+i2eN2HfB1xXr46PG23WJ+k3LTbuPjTW00U8S3uvhr4ouaZ7c9ZlJBPevgoQECYflYZE=,iv:ppdSkpBLmCEGIEioc5HeuiVAmvgkC2g4WIkWWSh9fL0=,tag:f2xn3GeZulFnG4Dqqh3gYA==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.12.1
|
||||
81
modules/secrets/sops.nix
Normal file
81
modules/secrets/sops.nix
Normal file
@@ -0,0 +1,81 @@
|
||||
{ den, inputs, lib, ... }:
|
||||
let
|
||||
sopsReadersGroup = "sops-users";
|
||||
in
|
||||
{
|
||||
den.ctx.host.includes = [
|
||||
(den.lib.perHost (
|
||||
{ host, ... }:
|
||||
let
|
||||
missingAdminUsers = lib.filter (userName: !(builtins.hasAttr userName host.users)) host.sopsAdminKeyUsers;
|
||||
adminKeyDir = if host.sopsAdminKeyPath == null then null else builtins.dirOf host.sopsAdminKeyPath;
|
||||
in
|
||||
{
|
||||
nixos = {
|
||||
imports = [ inputs.sops-nix.nixosModules.sops ];
|
||||
|
||||
sops = {
|
||||
defaultSopsFile = ./secrets.yaml;
|
||||
age =
|
||||
if host.sopsHostSshKeyPath != null then
|
||||
{
|
||||
sshKeyPaths = [ host.sopsHostSshKeyPath ];
|
||||
}
|
||||
else
|
||||
{
|
||||
keyFile = host.sopsAdminKeyPath;
|
||||
};
|
||||
};
|
||||
|
||||
users.groups = lib.optionalAttrs (host.sopsAdminKeyUsers != [ ]) {
|
||||
${sopsReadersGroup} = { };
|
||||
};
|
||||
|
||||
users.users = lib.genAttrs host.sopsAdminKeyUsers (_: {
|
||||
extraGroups = [ sopsReadersGroup ];
|
||||
});
|
||||
|
||||
systemd.tmpfiles.rules = lib.optionals (adminKeyDir != null) [
|
||||
"d ${adminKeyDir} 0750 root ${sopsReadersGroup} -"
|
||||
];
|
||||
|
||||
assertions = [
|
||||
{
|
||||
assertion = host.sopsAdminKeyUsers == [ ] || host.sopsAdminKeyPath != null;
|
||||
message = "Hosts with sopsAdminKeyUsers must set sopsAdminKeyPath.";
|
||||
}
|
||||
{
|
||||
assertion = missingAdminUsers == [ ];
|
||||
message =
|
||||
"All sopsAdminKeyUsers must exist on the host. Missing: "
|
||||
+ lib.concatStringsSep ", " missingAdminUsers;
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
))
|
||||
];
|
||||
|
||||
den.ctx.user.includes = [
|
||||
(den.lib.perUser (
|
||||
{ host, user, ... }:
|
||||
if builtins.elem user.userName host.sopsAdminKeyUsers then
|
||||
{
|
||||
homeManager =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
imports = [ inputs.sops-nix.homeManagerModules.sops ];
|
||||
|
||||
sops = {
|
||||
defaultSopsFile = ./secrets.yaml;
|
||||
age.keyFile = host.sopsAdminKeyPath;
|
||||
};
|
||||
|
||||
home.packages = [ pkgs.sops ];
|
||||
};
|
||||
}
|
||||
else
|
||||
{ }
|
||||
))
|
||||
];
|
||||
}
|
||||
19
modules/users/ergon.nix
Normal file
19
modules/users/ergon.nix
Normal file
@@ -0,0 +1,19 @@
|
||||
{ den, lux, ... }:
|
||||
{
|
||||
den.aspects.ergon = {
|
||||
includes = with lux; [
|
||||
(den._.user-shell "zsh")
|
||||
terminal
|
||||
shell
|
||||
neovim
|
||||
ssh
|
||||
bundles._.development
|
||||
({ user, ... }: {
|
||||
nixos.users.users.${user.userName}.extraGroups = [
|
||||
"wheel"
|
||||
"networkmanager"
|
||||
];
|
||||
})
|
||||
];
|
||||
};
|
||||
}
|
||||
15
modules/users/kiri.nix
Normal file
15
modules/users/kiri.nix
Normal file
@@ -0,0 +1,15 @@
|
||||
{ den, lux, ... }:
|
||||
{
|
||||
den.aspects.kiri = {
|
||||
includes = with lux; [
|
||||
den._.primary-user
|
||||
(den._.user-shell "zsh")
|
||||
syncthing
|
||||
terminal
|
||||
shell
|
||||
neovim
|
||||
ssh
|
||||
bundles._.development
|
||||
];
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user