This commit is contained in:
2026-03-03 16:30:58 +01:00
parent 5f34d32807
commit 6a49646d5e
34 changed files with 1229 additions and 1044 deletions

View File

@@ -1,27 +1,51 @@
# Gemini Context & Project Guidelines
# Den Configuration Framework: Core Concepts & Guidelines
This file serves as persistent contextual memory for the Gemini CLI when working on this NixOS configuration project.
## Overview
This NixOS configuration uses `den`, a declarative pipeline framework that shifts away from static module wiring to a system of **Context Transformation** and **Context-Aware Aspects**.
## Architecture: The `den` Framework
This repository manages NixOS and Home Manager configurations using the `den` framework. The approach here drastically differs from standard NixOS setups.
**Important Resource:** The `den` repository is vendored at `_ref/den/` and its official documentation can be found at `_ref/den/docs`. Use these resources (via `read_file`, `grep_search`, or `list_directory`) anytime you need to gain a deeper understanding of den's internal behavior or available features.
### Core Concepts & Rules
1. **Freeform Schemas over Custom Options:** Do not use legacy Nix module options (`lib.mkOption`, `lib.mkIf`) to define simple user/host properties (like email addresses, domains, or names). Instead, attach properties directly to the host or user definition objects in `hosts/<name>/default.nix` or `users/<name>.nix`. Den's freeform entity schemas will pass these through the context pipeline automatically.
2. **Parametric Aspects:** When a module requires access to host or user variables (like `user.email` or `host.domain`), the aspect MUST be wrapped in `den.lib.parametric`.
* *Example:* `lux.myapp = den.lib.parametric { includes = [ ({ user, ... }: { ... }) ]; };`
3. **Decentralized Host & User Definitions:** Do not centralize host definitions in a single file. Follow the `quasigod` reference structure:
* **Hosts** declare themselves in `modules/hosts/<hostname>/default.nix` (e.g., `den.hosts.x86_64-linux.orion = { ... }`).
* **Users** bind themselves to hosts in their own user files in `modules/users/<username>.nix` (e.g., `den.hosts.x86_64-linux.orion.users.kiri = userAccount // { ... }`).
4. **App Categories & Naming:**
* `/modules/desktop/`: GUI, Wayland, display managers, WMs.
* `/modules/dev/`: Developer tools, terminal, neovim.
* `/modules/apps/`: User-level software (PIM, Bitwarden, MPV, Email). Note: `pim.nix` stands for Personal Information Management and is an app, not a user definition.
* `/modules/services/`: System-level daemons (Caddy, Gitea, Vaultwarden).
* `/modules/profiles/`: Aggregations (like workstation/server).
## 1. Core Principles
* **Aspects (`__functor` pattern):** Configurations are functions of context, not static sets. An aspect (e.g., `{ host, user, ... }: { ... }`) inspects the context it receives and produces configs across domains (`nixos`, `homeManager`, `darwin`) simultaneously.
* **Context (`den.ctx`):** Attribute sets containing data (like `host` or `user`). Contexts are *named* (e.g., `ctx.hm-host` vs `ctx.host`) to provide guarantees (e.g., `hm-host` proves Home Manager detection passed).
* **The Pipeline (`into`):** Data flows through a defined pipeline. One context transforms `into` others (e.g., a single `ctx.host` fans out into multiple `ctx.user` contexts).
* **Providers (`provides`):** Aspects use `provides` to declare sub-aspects or inject configurations across contexts.
### Common Pitfalls & Lessons Learned
* **`home-manager` vs `homeManager`:** When defining class configurations inside a parametric function, the key for Home Manager is strictly `homeManager` (camelCase). Writing `home-manager.programs...` will cause evaluation errors because `home-manager` is not the class name used by the schema.
* **`user` is an Object:** In context parameters (`{ user, ... }:`), `user` is an attribute set, not a string. Do not interpolate it directly as a string (`"${user}"`); use `${user.name}`.
* **Namespace Inclusion:** The project uses the `lux` namespace. When an aspect needs to pull in other aspects, use `with lux; [ ... ]` rather than writing out `den.ful.lux...` repeatedly.
* **Abstracting Paths:** Never hardcode `/home/<username>`. Inside `homeManager` modules, use `config.home.homeDirectory`. Inside `nixos` modules (like SOPS), use `/home/${user.name}` where `user` is provided by the parametric context.
* **Git Status dependency:** When moving, creating, or renaming files (`mv`, `mkdir`), they must be staged in Git (`git add <file>`) before running `nix flake check`, otherwise the flake evaluator will not see the changes and will throw "undefined variable" or "path does not exist" errors.
## 2. Idiomatic Structure
* **Declaration vs. Configuration:** `den.hosts` and `den.homes` declare *what* exists (hosts, architectures, users). `den.aspects` define *how* they are configured.
* **Domain Spanning:** A single aspect file handles all relevant domains (e.g., a `git` aspect defines both `nixos.environment.systemPackages` and `homeManager.programs.git`).
* **Composition:** High-level aspects `include` lower-level aspect functions.
## 3. The Context Pipeline
1. **`ctx.host` `{ host }`:** Resolves the host's primary aspect (`den.aspects.<hostname>`).
2. **`ctx.default` `{ host }`:** Activates global defaults for the host.
3. **`ctx.user` `{ host, user }`:** Fans out to create a context for each user on the host. Resolves user aspects (`den.aspects.<username>`). *Crucially, host aspects can configure users here, and user aspects can configure the host.*
4. **`ctx.default` `{ host, user }`:** Activates global defaults for the user.
5. **`ctx.hm-host` `{ host }`:** If the host supports Home Manager and has HM users, this safely imports the HM module.
6. **`ctx.hm-user` `{ host, user }`:** For HM users, their config is forwarded into the host's `home-manager.users.<name>`.
## 4. Configuration Placement
* **Host Aspect (`den.aspects.<hostname>`):** Hardware, networking, system services. Can define default `homeManager` settings for all its users.
* **User Aspect (`den.aspects.<username>`):** Dotfiles, user packages, shell preferences. Can define required `nixos` settings for every host the user is on.
* **Global Defaults (`den.ctx.default`):** Universal settings (e.g., `stateVersion`, `den._.define-user`). **Note:** Prefer using more specific contexts (like `den.ctx.host` or `den.ctx.user`) over `den.ctx.default` whenever possible. Always write it as `den.ctx.default` rather than `den.default` to make it clear it is a context.
* **Feature Aspects:** Granular aspects included conditionally via `<den/lib> take.exactly` (or `den.lib.take.exactly`).
## 5. Common Pitfalls
* **The "Lax Context" Duplicate Config Bug:** A function like `({ host, ... }: { ... })` in `den.default.includes` runs at both the `ctx.host` and `ctx.user` stages, causing duplicate config errors.
* **Fix:** Use `<den/lib> take.exactly ({ host }: ...)` to run only at the host stage.
* **Missing `parametric` Wrapper:** Custom aspect trees (not auto-created by Den) that fail to forward context to their includes will throw `error: function 'anonymous lambda' called without required argument`.
* **Fix:** Wrap the custom aspect in `<den/lib> parametric`.
* **Home Manager Silent Failures:** If the detection gate fails (wrong OS, missing `"homeManager"` class on user, or missing `inputs.home-manager`), HM configs won't generate.
## 6. Essential Library Functions (`den.lib.*` & Batteries)
* `take.exactly`: Executes only if context matches arguments exactly.
* `take.atLeast`: Executes if context has at least the requested arguments.
* `parametric`: Wrapper to make an aspect forward context to its `includes`.
* `_.forward`: Translates config from one domain (e.g., custom class) to another.
* **Batteries (`den._.*`):** Built-in parametric aspects (e.g., `define-user`, `user-shell`, `tty-autologin`, `unfree`).
## 7. Useful Commands
* **`nix-search-tv`:** Use this command to look up docs for relevant options.
* Examples: `nix-search-tv preview "home-manager/ home.packages"`, `nix-search-tv preview "nixos/ environment.systemPackages"`.
* Prefix with `nixpkgs/` for nixpkgs docs.
* Use `nix-search-tv print` to print all available options and packages (filter output to avoid bloating context).

Submodule _ref/den deleted from 311d77a3af

Submodule _ref/quasigod-nixconfig deleted from e8204cf923

99
flake.lock generated
View File

@@ -83,6 +83,24 @@
}
},
"flake-parts_2": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib_2"
},
"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_3": {
"inputs": {
"nixpkgs-lib": [
"nvf",
@@ -136,6 +154,25 @@
"type": "github"
}
},
"lux-pkgs": {
"inputs": {
"flake-parts": "flake-parts_2",
"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,
@@ -177,7 +214,7 @@
"inputs": {
"niri-stable": "niri-stable",
"niri-unstable": "niri-unstable",
"nixpkgs": "nixpkgs_3",
"nixpkgs": "nixpkgs_4",
"nixpkgs-stable": "nixpkgs-stable",
"xwayland-satellite-stable": "xwayland-satellite-stable",
"xwayland-satellite-unstable": "xwayland-satellite-unstable"
@@ -231,7 +268,7 @@
},
"nix-wrapper-modules": {
"inputs": {
"nixpkgs": "nixpkgs_4"
"nixpkgs": "nixpkgs_5"
},
"locked": {
"lastModified": 1772285008,
@@ -294,6 +331,21 @@
"type": "github"
}
},
"nixpkgs-lib_2": {
"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": 1772047000,
@@ -327,6 +379,22 @@
}
},
"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": 1771848320,
"narHash": "sha256-0MAd+0mun3K/Ns8JATeHT1sX28faLII5hVLq0L3BdZU=",
@@ -342,7 +410,7 @@
"type": "github"
}
},
"nixpkgs_4": {
"nixpkgs_5": {
"locked": {
"lastModified": 1771207753,
"narHash": "sha256-b9uG8yN50DRQ6A7JdZBfzq718ryYrlmGgqkRm9OOwCE=",
@@ -358,7 +426,7 @@
"type": "github"
}
},
"nixpkgs_5": {
"nixpkgs_6": {
"locked": {
"lastModified": 1772173633,
"narHash": "sha256-BHKMR414WpfUddNyUtx2GR1VPl0R9sWGQs/opgYm9rc=",
@@ -371,7 +439,7 @@
"url": "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz"
}
},
"nixpkgs_6": {
"nixpkgs_7": {
"locked": {
"lastModified": 1771848320,
"narHash": "sha256-0MAd+0mun3K/Ns8JATeHT1sX28faLII5hVLq0L3BdZU=",
@@ -387,7 +455,7 @@
"type": "github"
}
},
"nixpkgs_7": {
"nixpkgs_8": {
"locked": {
"lastModified": 1771008912,
"narHash": "sha256-gf2AmWVTs8lEq7z/3ZAsgnZDhWIckkb+ZnAo5RzSxJg=",
@@ -403,7 +471,7 @@
"type": "github"
}
},
"nixpkgs_8": {
"nixpkgs_9": {
"locked": {
"lastModified": 1771207753,
"narHash": "sha256-b9uG8yN50DRQ6A7JdZBfzq718ryYrlmGgqkRm9OOwCE=",
@@ -421,15 +489,15 @@
},
"noctalia": {
"inputs": {
"nixpkgs": "nixpkgs_6",
"nixpkgs": "nixpkgs_7",
"noctalia-qs": "noctalia-qs"
},
"locked": {
"lastModified": 1772283575,
"narHash": "sha256-Avh/W7rFoyx9JAgwkMfpQG7J9+AtytZ6EmqFLtADPh4=",
"lastModified": 1772316133,
"narHash": "sha256-5fiLc9OwZ5GaPRRhuOPo0MOVNiszmLaEp8t+2iNOx9Y=",
"owner": "noctalia-dev",
"repo": "noctalia-shell",
"rev": "d886dd7861b8e6ff53dad320c53f665930396b02",
"rev": "cb9d6c3e2a4e716d6eb986439b19007387a2f6c1",
"type": "github"
},
"original": {
@@ -462,10 +530,10 @@
"nvf": {
"inputs": {
"flake-compat": "flake-compat",
"flake-parts": "flake-parts_2",
"flake-parts": "flake-parts_3",
"mnw": "mnw",
"ndg": "ndg",
"nixpkgs": "nixpkgs_7",
"nixpkgs": "nixpkgs_8",
"systems": "systems"
},
"locked": {
@@ -490,10 +558,11 @@
"flake-parts": "flake-parts",
"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_5",
"nixpkgs": "nixpkgs_6",
"noctalia": "noctalia",
"nvf": "nvf",
"sops-nix": "sops-nix"
@@ -501,7 +570,7 @@
},
"sops-nix": {
"inputs": {
"nixpkgs": "nixpkgs_8"
"nixpkgs": "nixpkgs_9"
},
"locked": {
"lastModified": 1772048434,

View File

@@ -15,6 +15,8 @@
noctalia.url = "github:noctalia-dev/noctalia-shell";
nvf.url = "github:notashelf/nvf";
sops-nix.url = "github:Mic92/sops-nix";
lux-pkgs.url = "git+ssh://gitea@orion/kiri/lux-pkgs";
};
outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } (inputs.import-tree ./modules);

View File

@@ -24,7 +24,7 @@
programs.rbw = {
enable = true;
settings = {
pinentry = pkgs.pinentry-qt;
pinentry = pkgs.pinentry-gnome3;
};
};
};

View File

@@ -1,8 +1,6 @@
{ den, ... }:
{
lux.email = den.lib.parametric {
includes = [
(
lux.email = den.lib.take.atLeast (
{ user, ... }:
{
homeManager =
@@ -115,7 +113,5 @@
};
};
}
)
];
};
);
}

10
modules/apps/gemini.nix Normal file
View File

@@ -0,0 +1,10 @@
{
lux.gemini = {
homeManager = {
programs.gemini-cli.enable = true;
# Needed for extensions
programs.npm.enable = true;
};
};
}

View File

@@ -1,12 +0,0 @@
{ ... }:
{
lux.helium = {
homeManager =
{ pkgs, ... }:
{
home.packages = [
(pkgs.callPackage ../../programs/helium.nix { })
];
};
};
}

53
modules/apps/vicinae.nix Normal file
View File

@@ -0,0 +1,53 @@
{ ... }:
{
lux.vicinae = {
homeManager = {
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";
};
};
};
};
};
}

View File

@@ -2,7 +2,7 @@
{
lux.xdg = {
homeManager =
{ config, ... }:
{ config, pkgs, ... }:
let
homeDir = config.home.homeDirectory;
localDir = "${homeDir}/.local";
@@ -34,6 +34,24 @@
publicShare = "${localDir}/public";
templates = "${localDir}/templates";
};
mimeApps = {
enable = true;
defaultApplicationPackages = with pkgs; [
sioyek
vivaldi
neovim
];
};
terminal-exec = {
enable = true;
settings = {
default = [
"kitty.desktop"
];
};
};
};
};
};

View 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 = [];
};
}

View File

@@ -9,42 +9,76 @@
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;
};
homeManager =
{ config, pkgs, ... }:
{
# Needed for file picker
dconf.settings = {
"org/gnome/desktop/interface" = {
color-scheme = "prefer-dark";
};
};
home.packages = with pkgs; [
playerctl
nautilus
brightnessctl
];
programs.niri = {
settings = {
spawn-at-startup = [
{ command = [ "noctalia-shell" ]; }
];
prefer-no-csd = true;
hotkey-overlay.skip-at-startup = true;
screenshot-path = "${config.xdg.userDirs.pictures}/screenshots/%Y-%m-%dT%H:%M:%S.png";
# -----------------------------------------------------------------
# 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 = 16;
focus-ring.width = 3;
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 = 15.0;
radius = 10.0;
in
{
bottom-left = radius;
@@ -56,6 +90,10 @@
}
];
# -----------------------------------------------------------------
# System & Input
# -----------------------------------------------------------------
debug = {
honor-xdg-activation-with-invalid-serial = true;
};
@@ -81,33 +119,39 @@
position.y = 0;
};
# -----------------------------------------------------------------
# Keybinds
# -----------------------------------------------------------------
binds = {
"Mod+Space".action.spawn-sh = "noctalia-shell ipc call launcher toggle";
# --- Helpful Overlays & Launchers ---
"Mod+Shift+Slash".action.show-hotkey-overlay = [ ];
# --- Applications & Launchers ---
"Mod+Return" = {
action.spawn = "kitty";
hotkey-overlay.title = "Open a Terminal";
hotkey-overlay.title = "Terminal";
};
"Mod+B" = {
action.spawn = "brave";
hotkey-overlay.title = "Open a Browser";
action.spawn = "vivaldi";
hotkey-overlay.title = "Browser";
};
"Mod+Space" = {
repeat = false;
action.spawn = [
"vicinae"
"toggle"
];
hotkey-overlay.title = "App Launcher";
};
"Mod+D" = {
action.spawn = "fuzzel";
hotkey-overlay.title = "Run an Application: fuzzel";
hotkey-overlay.title = "App Launcher (Fallback)";
};
"Mod+Alt+S" = {
action.spawn-sh = "pkill orca || exec orca";
allow-when-locked = true;
hotkey-overlay.hidden = true; # Equivalent to hotkey-overlay-title=null
hotkey-overlay.hidden = true;
};
# --- Audio & Media Controls ---
# --- Media & Brightness Controls ---
"XF86AudioPlay" = {
action.spawn-sh = "playerctl play-pause";
allow-when-locked = true;
@@ -140,6 +184,33 @@
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 ---
"Print".action.screenshot = [ ];
"Ctrl+Print".action.screenshot-screen = [ ];
"Alt+Print".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" = {
@@ -151,11 +222,11 @@
repeat = false;
};
# Focus Movement
"Mod+H".action.focus-column-left = [ ];
# 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-right = [ ];
"Mod+L".action.focus-column-or-monitor-right = [ ];
# Window Movement
"Mod+Ctrl+Left".action.move-column-left = [ ];
@@ -233,7 +304,6 @@
"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 = [ ];
@@ -284,21 +354,6 @@
"Mod+V".action.toggle-window-floating = [ ];
"Mod+Shift+V".action.switch-focus-between-floating-and-tiling = [ ];
"Mod+W".action.toggle-column-tabbed-display = [ ];
# --- Screenshots ---
"Print".action.screenshot = [ ];
"Ctrl+Print".action.screenshot-screen = [ ];
"Alt+Print".action.screenshot-window = [ ];
# --- System & Session ---
"Mod+Escape" = {
action.toggle-keyboard-shortcuts-inhibit = [ ];
allow-inhibiting = false;
};
"Mod+Shift+E".action.quit = [ ];
"Ctrl+Alt+Delete".action.quit = [ ];
"Mod+Shift+P".action.power-off-monitors = [ ];
};
};
};

View File

@@ -16,552 +16,7 @@
calendarSupport = true;
};
systemd.enable = true;
settings = {
settingsVersion = 53;
bar = {
barType = "simple";
position = "top";
monitors = [ ];
density = "default";
showOutline = false;
showCapsule = true;
capsuleOpacity = 1;
capsuleColorKey = "none";
backgroundOpacity = 0.93;
useSeparateOpacity = false;
floating = false;
marginVertical = 4;
marginHorizontal = 4;
frameThickness = 8;
frameRadius = 12;
outerCorners = true;
hideOnOverview = false;
displayMode = "always_visible";
autoHideDelay = 500;
autoShowDelay = 150;
widgets = {
left = [
{
icon = "rocket";
iconColor = "none";
id = "Launcher";
}
{
clockColor = "none";
customFont = "";
formatHorizontal = "HH:mm ddd, MMM dd";
formatVertical = "HH mm - dd MM";
id = "Clock";
tooltipFormat = "HH:mm ddd, MMM dd";
useCustomFont = false;
}
{
characterCount = 2;
colorizeIcons = false;
emptyColor = "secondary";
enableScrollWheel = true;
focusedColor = "primary";
followFocusedScreen = false;
groupedBorderOpacity = 1;
hideUnoccupied = false;
iconScale = 0.8;
id = "Workspace";
labelMode = "index";
occupiedColor = "secondary";
pillSize = 0.6;
reverseScroll = false;
showApplications = false;
showBadge = true;
showLabelsOnlyWhenOccupied = true;
unfocusedIconsOpacity = 1;
}
];
center = [
{
colorizeIcons = false;
hideMode = "hidden";
id = "ActiveWindow";
maxWidth = 400;
scrollingMode = "hover";
showIcon = true;
textColor = "none";
useFixedWidth = false;
}
];
right = [
{
compactMode = false;
compactShowAlbumArt = true;
compactShowVisualizer = false;
hideMode = "hidden";
hideWhenIdle = false;
id = "MediaMini";
maxWidth = 145;
panelShowAlbumArt = true;
panelShowVisualizer = true;
scrollingMode = "hover";
showAlbumArt = true;
showArtistFirst = true;
showProgressRing = true;
showVisualizer = false;
textColor = "none";
useFixedWidth = false;
visualizerType = "linear";
}
{
blacklist = [ ];
chevronColor = "none";
colorizeIcons = false;
drawerEnabled = true;
hidePassive = false;
id = "Tray";
pinned = [ ];
}
{
hideWhenZero = false;
hideWhenZeroUnread = false;
iconColor = "none";
id = "NotificationHistory";
showUnreadBadge = true;
unreadBadgeColor = "primary";
}
{
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 = "${config.home.homeDirectory}/.face";
dimmerOpacity = 0;
showScreenCorners = false;
forceBlackScreenCorners = false;
scaleRatio = 1;
radiusRatio = 1;
iRadiusRatio = 1;
boxRadiusRatio = 1;
screenRadiusRatio = 1;
animationSpeed = 1;
animationDisabled = false;
compactLockScreen = false;
lockScreenAnimations = false;
lockOnSuspend = true;
showSessionButtonsOnLockScreen = true;
showHibernateOnLockScreen = 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";
lockScreenMonitors = [ ];
lockScreenBlur = 0;
lockScreenTint = 0;
keybinds = {
keyUp = [
"Up"
];
keyDown = [
"Down"
];
keyLeft = [
"Left"
];
keyRight = [
"Right"
];
keyEnter = [
"Return"
];
keyEscape = [
"Esc"
];
keyRemove = [
"Del"
];
};
};
ui = {
fontDefault = "Comfortaa Medium";
fontFixed = "FiraCode Nerd Font";
fontDefaultScale = 1;
fontFixedScale = 1;
tooltipsEnabled = true;
panelBackgroundOpacity = 1;
panelsAttachedToBar = true;
settingsPanelMode = "attached";
wifiDetailsViewMode = "grid";
bluetoothDetailsViewMode = "grid";
networkPanelView = "wifi";
bluetoothHideUnnamedDevices = false;
boxBorderEnabled = false;
};
location = {
name = "Meterik, Limburg";
weatherEnabled = true;
weatherShowEffects = true;
useFahrenheit = false;
use12hourFormat = false;
showWeekNumberInCalendar = true;
showCalendarEvents = true;
showCalendarWeather = true;
analogClockInCalendar = false;
firstDayOfWeek = -1;
hideWeatherTimezone = 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 = "${config.home.homeDirectory}/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 = 0.05;
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 = "auto_hide";
backgroundOpacity = 1;
floatingRatio = 1;
size = 1;
onlySameOutput = true;
monitors = [ ];
pinnedApps = [ ];
colorizeIcons = false;
pinnedStatic = false;
inactiveIndicators = false;
deadOpacity = 0.6;
animationSpeed = 1;
};
network = {
wifiEnabled = true;
airplaneModeEnabled = false;
bluetoothRssiPollingEnabled = false;
bluetoothRssiPollIntervalMs = 60000;
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";
enabled = true;
keybind = "1";
}
{
action = "suspend";
enabled = true;
keybind = "2";
}
{
action = "hibernate";
enabled = true;
keybind = "3";
}
{
action = "reboot";
enabled = true;
keybind = "4";
}
{
action = "logout";
enabled = true;
keybind = "5";
}
{
action = "shutdown";
enabled = true;
keybind = "6";
}
];
};
notifications = {
enabled = true;
density = "default";
monitors = [ ];
location = "top_right";
overlayLayer = true;
backgroundOpacity = 1;
respectExpireTimeout = false;
lowUrgencyDuration = 3;
normalUrgencyDuration = 8;
criticalUrgencyDuration = 15;
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;
};
brightness = {
brightnessStep = 5;
enforceMinimum = true;
enableDdcSupport = false;
};
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;
};
desktopWidgets = {
enabled = false;
gridSnap = false;
monitorWidgets = [ ];
};
};
settings = import ./_noctalia-config.nix;
};
};
}

44
modules/desktop/theme.nix Normal file
View File

@@ -0,0 +1,44 @@
{
lux.theme = {
homeManager =
{ pkgs, ... }:
{
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=";
};
});
};
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";
};
};
};
}

View File

@@ -23,6 +23,14 @@
enableZshIntegration = true;
nix-direnv.enable = true;
};
programs.lazygit = {
enable = true;
# TODO: Figure out how to handle this flag. Set it in shell.nix or here?
# Maybe set it conditionally on if zsh is enabled?
# Might be relevant: lib.hm.shell.mkZshIntegrationOption
enableZshIntegration = true;
};
};
};
}

View File

@@ -47,7 +47,6 @@
rustc
rust-analyzer
rustfmt
markdownlint-cli2
astro-language-server
tinymist
typstyle

View File

@@ -14,9 +14,6 @@ require("lz.n").load({
event = { "BufReadPre", "BufNewFile" },
after = function()
local lint = require("lint")
lint.linters_by_ft = {
markdown = { "markdownlint-cli2" },
}
-- Create autocommand which carries out the actual linting
-- on the specified events.

10
modules/dev/podman.nix Normal file
View File

@@ -0,0 +1,10 @@
{ ... }:
{
lux.podman = {
homeManager = {
services.podman = {
enable = true;
};
};
};
}

View File

@@ -7,7 +7,7 @@
# 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*'
rm -f "${config.programs.zsh.dotDir}"/.zcompdump*
'';
};
@@ -17,20 +17,16 @@
enableCompletion = true;
completionInit = ''
setopt EXTENDED_GLOB
autoload -U compinit
local dump_path="${config.programs.zsh.dotDir}/.zcompdump"
local cache_check=( $dump_path(#qN.mh-24) )
if (( $#cache_check )); then
# Array has items: File exists and is new
compinit -C
else
# Array is empty: File is older than 24 hours OR doesn't exist
compinit
zcompile "$dump_path" &
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;

View File

@@ -22,7 +22,7 @@
# Window layout
confirm_os_window_close = 0;
window_padding_width = 5;
window_padding_width = 3;
# Advanced
update_check_interval = 0;

View File

@@ -1,10 +1,6 @@
{ den, ... }:
{
lux.ssh = den.lib.parametric {
includes = [
(
{ user, ... }:
{
lux.ssh = {
homeManager =
{ config, pkgs, ... }:
{
@@ -17,7 +13,7 @@
enable = true;
enableSshSupport = true;
enableZshIntegration = true;
pinentry.package = pkgs.pinentry-qt;
pinentry.package = pkgs.pinentry-gnome3;
sshKeys = [
"CD848796822630B280FC6DFA55F24A20040F22B5"
"B8FBDFBD7F42C444C17E086E0EE2E34FB43A7187"
@@ -28,12 +24,17 @@
enable = true;
enableDefaultConfig = false;
includes = [
"${config.home.homeDirectory}/.ssh/ssh-config-orion"
"${config.sops.secrets.ssh-config-orion.path}"
];
};
sops.secrets.ssh-config-orion = { };
};
}
)
];
# Forward ssh agent to root when using sudo
# Useful for nixos-rebuild when pulling private repos
nixos.security.sudo.extraConfig = ''
Defaults env_keep+=SSH_AUTH_SOCK
'';
};
}

View File

@@ -1,4 +1,9 @@
{ lux, den, ... }:
{
lux,
den,
inputs,
...
}:
{
lux.workstation = den.lib.parametric {
includes = with lux; [
@@ -6,7 +11,9 @@
greeter
niri
vicinae
xdg
theme
# GUI Applications & Dev Tools
bitwarden
@@ -15,7 +22,8 @@
noctalia
pim
mpv
helium
podman
gemini
];
homeManager =
@@ -23,14 +31,35 @@
{
home.packages = with pkgs; [
brave
vivaldi
localsend
postman
wl-clipboard
spotify
gemini-cli
qbittorrent
calcure
planify
(pkgs.writeShellApplication {
name = "ns";
runtimeInputs = [
fzf
nix-search-tv
];
text = builtins.readFile "${pkgs.nix-search-tv.src}/nixpkgs.sh";
})
];
programs.sioyek.enable = true;
programs.television = {
enable = true;
enableZshIntegration = true;
};
programs.nix-search-tv = {
enable = true;
enableTelevisionIntegration = true;
};
programs.ripgrep.enable = true;
programs.uv.enable = true;
@@ -38,7 +67,7 @@
home.pointerCursor = {
name = "phinger-cursors-light";
package = pkgs.phinger-cursors;
size = 32;
size = 24;
gtk.enable = true;
};
@@ -46,7 +75,7 @@
home.sessionVariables = {
NIXOS_OZONE_WL = "1";
BROWSER = "brave";
BROWSER = "vivaldi";
EDITOR = "nvim";
VISUAL = "nvim";

View File

@@ -1,7 +1,7 @@
radicale_pass: ENC[AES256_GCM,data:zdUxtJKNPC8SzajhFKo=,iv:H55GWMiQLJvZx6rAufkk807lZflg0sepxoq6z0XJ/q4=,tag:MoDOuF37PeF7QEpUxBntEg==,type:str]
university_calendar_url: ENC[AES256_GCM,data:y5UtZVC0KJPUz//6S0QsrNeFGQshc88zieQgmlur75VFw9y5CJpnZRpdhLnYva00z5HBkxYQelLqS/I5GrXexWtC7Y7d1dCcQ+IZ0K7GGJ5NrYtjNXfMhzNSlhqjvl5lBGb+S565kel3VsCTyo/YRxdbBN6FA/oQNsx8/AvTgtsPeFkQRDGlGkybFRfWHWuTIDLL,iv:rZK9utRrm/KAkVRUjC3VR09MvDZjpoLx7BgaidzQo3o=,tag:tGWGoQCsS3zZh818OKixPw==,type:str]
ssh_config_orion: ENC[AES256_GCM,data:P2jH5BDIzeHSIwTBcZwTOXKes727xK0Xoj9W64GmEszEPZw8vA==,iv:hSY9mFdC82pBbOjMFuzoR2eufhjY2MGERJ4ODmcogbA=,tag:ejF535LrQwwH66nQG3qLGw==,type:str]
orion_ip: ENC[AES256_GCM,data:RCK6EKOEDaTu1uR2d/8=,iv:5JhIkVQEELB6MoPh49xq+0CrbPjI/6+qfqUHRqCza5s=,tag:+00T4+pWOWRj7R1ft39HAw==,type:str]
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:VEe6VSnrpySOdEJ+Sxcc2K6bL/eh/3PjAUNLBjvG7ceJcVnvdA==,iv:yJEhPQ3rYcCn+V7mzC8bPFjkW2GYDArjDJDI8vC1D70=,tag:n49AfsnZZgPuKO8MtAzVtg==,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]
sops:
age:
@@ -32,7 +32,7 @@ sops:
YlZ4VGIzaE5kQ3ZSczI2Wk5IU1UvOXcKqkj/OYP37+60Gr2xJmPE9O7HB7LCu4Tp
AvvoMQLkkvVJ30Y03pfEzIMnvJHKREy9zDOScfqUflDk79mcDaDhvg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-02-16T13:53:22Z"
mac: ENC[AES256_GCM,data:DuGE9Ovae5Y2Qpm5v8OYgFC2/u/Yzprv+ImmX1OVsh5KjGS26HaX1HLbzGu7NZCMfg2ZrJ5BeFNCO3UaZ7tXNoWGKxQZRNYpAH8PjI225l+GWozcva0on6S0UD2MhtKkpFPFUg1uEDSzqwMoXgPbWoB1W0VeAOkfAhKM9j/tggs=,iv:/Hsh9JvdcZMy7v4tLGaBwDlMIf5HBta3GeZC5gDUO9k=,tag:mtwqk41SA9qzIw+cVDSgQg==,type:str]
lastmodified: "2026-03-01T17:21:02Z"
mac: ENC[AES256_GCM,data:O3SPxEu8M7au3NF2jZvqqzj4yK44dH7ccb04n59tZmx5lDQfa6nRTJUrlEnwRPUMYmta1WyYZDSje+Yf9hNLSj9ARKMx9Ot/gfBRISOdDQ5FyeHNEU8aq8/HeRkf2CHJYqbNi8wn27IKrMXOG6TktNUXaqb8v4POo3K0qbJ5Z6s=,iv:Aw4G8VXbr48yWWqVhUa5KQ61y1o6ST8VHRECc9s0f5U=,tag:EP218k82eh7itHYO+iNTwQ==,type:str]
unencrypted_suffix: _unencrypted
version: 3.11.0
version: 3.12.1

View File

@@ -1,29 +1,27 @@
{ inputs, den, ... }:
{ inputs, ... }:
let
sopsConfig = {
# TODO: Should this be user owned or root-owned?
# How do we determine the keys location without hardcoding?
# TODO: Take a look at quasigod
age.keyFile = "/home/kiri/.config/sops/age/keys.txt";
defaultSopsFile = ./secrets.yaml;
};
in
{
den.default.includes = [
(
{ host, ... }:
{
nixos =
# TODO: Do we need both modules?
den.ctx.host.nixos = {
imports = [ inputs.sops-nix.nixosModules.sops ];
sops = sopsConfig;
};
den.ctx.user.homeManager =
{ pkgs, ... }:
{
imports = [ inputs.sops-nix.nixosModules.sops ];
imports = [ inputs.sops-nix.homeManagerModules.sops ];
sops = sopsConfig;
sops = {
age.keyFile = "/home/${(builtins.head (builtins.attrValues host.users)).name}/.config/sops/age/keys.txt";
defaultSopsFile = ./secrets.yaml;
secrets = {
hashed-password-kiri.neededForUsers = true;
home.packages = [ pkgs.sops ];
};
};
environment.systemPackages = with pkgs; [
sops
age
];
};
}
)
];
}

View File

@@ -1,8 +1,6 @@
{ den, ... }:
{
lux.services._.actual = den.lib.exactly {
includes = [
(
lux.services._.actual = den.lib.take.exactly (
{ host, ... }:
{
nixos =
@@ -20,7 +18,5 @@
"reverse_proxy :${toString config.services.actual.settings.port}";
};
}
)
];
};
);
}

View File

@@ -1,19 +1,10 @@
{ den, lib, ... }:
{
lux.services._.caddy = den.lib.parametric {
includes = [
(
{ host, ... }:
{
nixos = {
services.caddy = {
lux.services._.caddy = den.lib.take.atLeast ({ host, ... }: {
nixos.services.caddy = {
enable = true;
email = "mail@jelles.net";
openFirewall = true;
};
};
}
)
];
};
});
}

View File

@@ -1,9 +1,7 @@
{ den, ... }:
{
lux.services._.gitea = den.lib.parametric {
includes = [
(
den.lib.take.exactly({ host }:
lux.services._.gitea = den.lib.take.exactly (
{ host }:
{
nixos =
{ config, ... }:
@@ -28,13 +26,11 @@
};
};
services.openssh.settings.AllowUsers = [ "git" ];
services.openssh.settings.AllowUsers = [ "gitea" ];
services.caddy.virtualHosts."git.${host.domain}".extraConfig =
"reverse_proxy :${toString config.services.gitea.settings.server.HTTP_PORT}";
};
}
))
];
};
);
}

View File

@@ -1,11 +1,7 @@
{ den, lib, ... }:
{
lux.services._.openssh = den.lib.parametric.exactly {
includes = [
(
{ host }:
{
nixos.services.openssh.settings.nixos.services.openssh = {
lux.services._.openssh = den.lib.take.exactly ({ host }: {
nixos.services.openssh = {
enable = true;
settings = {
PermitRootLogin = "no";
@@ -13,9 +9,5 @@
AllowUsers = lib.attrNames host.users;
};
};
}
)
];
};
});
}

View File

@@ -1,6 +1,6 @@
{ den, ... }:
{
lux.services._.radicale = den.lib.exactly {
lux.services._.radicale = den.lib.parametric.exactly {
includes = [
(
{ host, ... }:
@@ -15,7 +15,7 @@
auth = {
type = "htpasswd";
htpasswd_filename = config.sops.secrets.radicale-users.path;
htpasswd_filename = "/var/lib/radicale/users";
htpasswd_encryption = "bcrypt";
};

View File

@@ -1,13 +1,7 @@
{ den, ... }:
{
lux.services._.vaultwarden = den.lib.parametric.exactly {
includes = [
(
{ host }:
{
nixos =
{ config, ... }:
{
lux.services._.vaultwarden = den.lib.take.exactly ({ host }: {
nixos = { config, ... }: {
services.vaultwarden = {
enable = true;
backupDir = "/var/backup/vaultwarden";
@@ -22,8 +16,5 @@
services.caddy.virtualHosts."vault.${host.domain}".extraConfig =
"reverse_proxy :${toString config.services.vaultwarden.config.ROCKET_PORT}";
};
}
)
];
};
});
}

View File

@@ -45,6 +45,11 @@ in
nixos =
{ config, ... }:
{
# TODO: Do we event want this?
# What is standard on a VPS?
sops.secrets.hashed-password-kiri = {
neededForUsers = true;
};
users.users.kiri.hashedPasswordFile = config.sops.secrets.hashed-password-kiri.path;
};
};

View File

@@ -1,101 +0,0 @@
{
lib,
unzip,
autoPatchelfHook,
stdenv,
fetchurl,
libxcb,
libx11,
libxcomposite,
libxdamage,
libxext,
libxfixes,
libxrandr,
libgbm,
cairo,
libudev-zero,
libxkbcommon,
nspr,
nss,
libcupsfilters,
pango,
qt5,
alsa-lib,
atk,
at-spi2-core,
at-spi2-atk,
}:
stdenv.mkDerivation rec {
name = "Helium";
version = "0.8.4.1";
src = fetchurl {
url = "https://github.com/imputnet/helium-linux/releases/download/${version}/helium-${version}-x86_64_linux.tar.xz";
sha256 = "sha256-M/1wGewl500vJsoYfhbgXHQ4vlI6d0PRGGGGsRol6sc=";
};
nativeBuildInputs = [
unzip
autoPatchelfHook
];
autoPatchelfIgnoreMissingDeps = [
"libQt6Core.so.6"
"libQt6Gui.so.6"
"libQt6Widgets.so.6"
];
runtimeDependencies = [ ];
buildInputs = [
unzip
libxcb
libx11
libxcomposite
libxdamage
libxext
libxfixes
libxrandr
libgbm
cairo
pango
libudev-zero
libxkbcommon
nspr
nss
libcupsfilters
alsa-lib
atk
at-spi2-core
at-spi2-atk
qt5.qtbase
qt5.qttools
qt5.qtx11extras
qt5.wrapQtAppsHook
];
installPhase = ''
runHook preInstall
mkdir -p $out/bin
mv * $out/bin/
mv $out/bin/helium $out/bin/${name}
mkdir -p $out/share/applications
cat <<INI> $out/share/applications/${name}.desktop
[Desktop Entry]
Name=${name}
GenericName=Web Browser
Terminal=false
Icon=$out/bin/product_logo_256.png
Exec=$out/bin/${name}
Type=Application
Categories=Network;WebBrowser;
INI
'';
meta = with lib; {
homepage = "https://github.com/imputnet/helium-linux";
description = "A description of your application";
platforms = platforms.linux;
};
}

1
result Symbolic link
View File

@@ -0,0 +1 @@
/nix/store/azqhlhavafg5fq8skwkq40ibjxhr5ld8-kanagawa-icon-theme-0-unstable-2023-07-03