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