1

Compare commits

..

19 Commits

Author SHA1 Message Date
714e3e0683 Config/Neovim: Add bundler script to generate portable neovim config 2026-02-10 18:11:01 +01:00
a8d7d1e666 Modules/Impermanence: Persist tiddl config 2026-02-10 14:54:51 +01:00
40bcc14304 Modules/Neovim: Add justfile support 2026-02-09 18:55:41 +01:00
fa5bd0eefd Modules/Neovim: Display whitespace in visual mode 2026-02-09 15:50:46 +01:00
6182ada581 Modules/Neovim: Add makefile formatter 2026-02-09 15:50:24 +01:00
4acddcec09 Modules/Firefox: Add godbolt bookmark 2026-02-09 14:00:05 +01:00
5c14817464 Config/Navi: Add tiddl cheat 2026-02-04 20:23:40 +01:00
38920bd3d7 Derivations/Tiddle: Add tiddl derivation 2026-02-04 20:16:54 +01:00
b89934d13f Services/Kiwix: Init kiwix at v3.8.1 2026-02-03 11:28:16 +01:00
734dfcadfc Services/Immich: Update to v2.5.2 2026-02-03 11:28:00 +01:00
2c959fdc0c Services/Nginx: Expose hytale port 2026-01-29 16:33:45 +01:00
e00c4f49f5 Modules/Impermanence: Persist jellyfin-tui settings 2026-01-26 13:44:42 +01:00
61131ca598 Home: Add jellyfin-tui 2026-01-26 13:44:34 +01:00
9c1a39d699 Modules/Firefox: Disable darkmode plugin 2026-01-26 13:19:43 +01:00
32de6e24b7 Modules/Neovim: Enable autotools-language-server 2026-01-25 23:01:07 +01:00
78e554cc30 Modules/Impermanence: Persist feishin config 2026-01-25 19:23:15 +01:00
f65617deed Home: Add feishing 2026-01-25 19:14:11 +01:00
aa3a881d58 Derivations/TidalDL: Fix derivation after original repo got nuked 2026-01-24 19:46:42 +01:00
7f99b73635 System/Nixinator: Enable IPv6 networking 2026-01-24 19:22:11 +01:00
19 changed files with 465 additions and 43 deletions

1
.gitignore vendored
View File

@ -11,3 +11,4 @@ config/neovim/store
home/modules/ags/config/types
home/modules/ags/config/tsconfig.json
system/modules/agenix/secrets.nix
config/neovim/nvim_bundle

View File

@ -210,6 +210,10 @@ Convert line endings to dos format
unix2dos <file>
$ file: eza -1
% tiddl
Download stuff from tidal
tiddl download --track-quality max --path ~/Downloads/Beet/Albums --videos none url "<url>"
; ===========================
; SECRETS
; ===========================

204
config/neovim/bundle.py Normal file
View File

@ -0,0 +1,204 @@
#!/usr/bin/env python3
import argparse
import os
import re
import shutil
import subprocess
from typing import cast
from urllib.request import urlretrieve
INIT_LUA: str = "/home/christoph/.config/nvim/init.lua"
def patch_paths(text: str, mappings: dict[str, str]) -> str:
"""Patches /nix/store paths in init.lua"""
patched = text
for old, new in mappings.items():
print(f"Patching init.lua: {old} -> {new}")
patched = patched.replace(old, new)
return patched
def patch_various(text: str) -> str:
"""Patches various incompatibilities with NixVim init.lua"""
# Install lazy
print("Patching init.lua: Bootstrap lazy.nvim")
patched = (
"""-- Bootstrap lazy.nvim
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not (vim.uv or vim.loop).fs_stat(lazypath) then
local lazyrepo = "https://github.com/folke/lazy.nvim.git"
local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath })
if vim.v.shell_error ~= 0 then
vim.api.nvim_echo({
{ "Failed to clone lazy.nvim:\\n", "ErrorMsg" },
{ out, "WarningMsg" },
{ "\\nPress any key to exit..." },
}, true, {})
vim.fn.getchar()
os.exit(1)
end
end
vim.opt.rtp:prepend(lazypath)
"""
+ text
)
# print("Patching init.lua: Disabling vim.loader")
# patched = patched.replace("vim.loader.enable(true)", "vim.loader.enable(false)")
return patched
def copy_plugins(text: str, path: str) -> dict[str, str]:
"""Copies NeoVim plugins from the Nix Store"""
os.makedirs(path, exist_ok=True)
plugins_path: str = re.findall(r"\"(/nix/store/.*-lazy-plugins)\"", text)[0]
print(f"Copying: {plugins_path} -> {path}/plugins")
_ = shutil.copytree(plugins_path, f"{path}/plugins")
treesitter_path: str = re.findall(
r"\"(/nix/store/.*-vimplugin-nvim-treesitter.*)\"", text
)[0]
print(f"Copying: {treesitter_path} -> {path}/treesitter")
_ = shutil.copytree(treesitter_path, f"{path}/treesitter")
parsers_path: str = re.findall(r"\"(/nix/store/.*-treesitter-parsers)\"", text)[0]
print(f"Copying: {parsers_path} -> {path}/parsers")
_ = shutil.copytree(parsers_path, f"{path}/parsers")
return {
plugins_path: "./plugins",
treesitter_path: "./treesitter",
parsers_path: "./parsers",
}
def write_file(text: str, path: str) -> None:
"""Write text to a file"""
with open(path, "w") as file:
_ = file.write(text)
# TODO: Could add etc. nvim/lsp/formatter/linter binaries here
# TODO: Needs "install recipe", as in most cases the download will be an archive
DOWNLOADS: list[tuple[str, str]] = [
# (
# "https://github.com/neovim/neovim/releases/download/v0.11.6/nvim-linux-x86_64.tar.gz",
# "nvim",
# ),
]
def download_binaries(path: str, urls: list[tuple[str, str]]) -> None:
"""Download required binaries"""
os.makedirs(f"{path}/bin", exist_ok=True)
def download(url: str, path: str) -> None:
"""Download from URL"""
print(f"Downloading: {url}")
_ = urlretrieve(url, path)
for url, name in urls:
download(url, f"{path}/bin/{name}")
def build_nvim(path: str) -> None:
"""Builds a static nvim binary against musl"""
# TODO: Build etc. is working, but on the target system there are
# lua-ffi errors from noice.nvim with the static binary.
# This does not happen with nvim from system package repository.
def run(command: list[str]) -> None:
"""Run a subprocess"""
print(f"Running: {' '.join(command)}")
_ = subprocess.run(command)
os.makedirs(f"{path}/nvim-build", exist_ok=True)
with open(f"{path}/nvim-build/build-nvim.sh", "w") as file:
_ = file.write(
"\n".join(
[
"#!/bin/sh",
"git clone https://github.com/neovim/neovim",
"cd neovim",
"git checkout stable",
'make -j$(nproc) CMAKE_BUILD_TYPE=Release CMAKE_EXTRA_FLAGS="-DSTATIC_BUILD=1"',
"make CMAKE_INSTALL_PREFIX=/workdir/install install",
]
)
)
run(
[
"docker",
"run",
"--rm",
"-it",
"-v",
f"{os.path.abspath(path)}/nvim-build:/workdir",
"-w",
"/workdir",
"alpine:3.23.3",
"/bin/sh",
"-c",
"apk add build-base cmake coreutils curl gettext-tiny-dev git && chmod +x ./build-nvim.sh && ./build-nvim.sh",
]
)
_ = shutil.copytree(f"{path}/nvim-build/install/bin", f"{path}/bin")
_ = shutil.copytree(f"{path}/nvim-build/install/lib", f"{path}/lib")
_ = shutil.copytree(f"{path}/nvim-build/install/share", f"{path}/share")
_ = shutil.rmtree(f"{path}/nvim-build")
def bundle() -> None:
"""Creates a standalone NeoVim bundle from the NixVim configuration"""
parser = argparse.ArgumentParser()
_ = parser.add_argument(
"--config",
type=str,
default=INIT_LUA,
help="init.lua or other config file",
)
_ = parser.add_argument(
"--out",
type=str,
default="./nvim_bundle",
help="destination folder",
)
args = parser.parse_args()
args.config = cast(str, args.config)
args.out = cast(str, args.out)
with open(args.config, "r") as file:
patched_init_lua: str = file.read()
path_mappings = copy_plugins(patched_init_lua, args.out)
patched_init_lua = patch_paths(patched_init_lua, path_mappings)
patched_init_lua = patch_various(patched_init_lua)
write_file(patched_init_lua, f"{args.out}/init.lua")
# build_nvim(args.out)
# download_binaries(args.out, DOWNLOADS)
if __name__ == "__main__":
bundle()

6
config/neovim/info.md Normal file
View File

@ -0,0 +1,6 @@
# NeoVim Portable
## Requirements
- Base packages: `sudo apt install neovim git direnv ripgrep curl fzf`
- Link or copy the generated `nvim_bundle` to `~/.config/nvim` on the target machine

View File

@ -9,4 +9,5 @@
msty = pkgs.callPackage ./msty {};
unityhub = pkgs.callPackage ./unityhub {};
tidal-dl-ng = pkgs.callPackage ./tidal-dl-ng {};
tiddl = pkgs.callPackage ./tiddl {};
}

View File

@ -38,7 +38,7 @@
# sha256 = "sha256-Gq9klAMXk+SHb7C6z6apErVRz0PB5jyADfixqGZyDDc=";
# };
# });
#
# rich_14_2_0 = pkgs.python313Packages.rich.overridePythonAttrs (old: {
# version = "14.2.0";
# src = pkgs.python313Packages.fetchPypi {
@ -49,22 +49,12 @@
# doCheck = false;
# });
# rich_14_2_0 = pkgs.python313Packages.rich.overridePythonAttrs (old: {
# version = "14.2.0";
# src = pkgs.fetchFromGitHub {
# owner = "Textualize";
# repo = "rich";
# tag = "v14.2.0";
# hash = "sha256-oQbxRbZnVr/Ln+i/hpBw5FlpUp3gcp/7xsxi6onPkn8=";
# };
# });
tidalDlNg = pythonPkgs.buildPythonApplication rec {
pname = "tidal-dl-ng";
version = "0.31.3";
pname = "tidal_dl_ng_for_dj";
version = "0.33.2";
format = "pyproject";
# TODO: The official repo was deleted, find the new one once it pops up
# The official repo was deleted
# src = pkgs.fetchFromGitHub {
# owner = "exislow";
# repo = "tidal-dl-ng";
@ -72,16 +62,20 @@
# sha256 = "sha256-PUT0anx1yivgXwW21jah7Rv1/BabOT+KPoW446NFNyg=";
# };
src = pkgs.fetchFromGitHub {
owner = "rodvicj";
repo = "tidal_dl_ng-Project";
rev = "4573142c76ef045ebf8e80c34657dd2bec96f17d";
sha256 = "sha256-3sO2qj8V4KXOWK7vQsFAOYeTZo2rsc/M36SwRnC0oVg=";
# Package now also deleted from PyPi
# src = pythonPkgs.fetchPypi {
# inherit pname version;
# sha256 = "sha256-rOMyxnT7uVnMbn678DFtqAu4+Uc5VFGcqGI0jxplnpc=";
# };
# TODO: Borked
# "For DJ"-Fork
src = pythonPkgs.fetchPypi {
inherit pname version;
sha256 = "sha256-605cgBqZV6L7sxWtEa4Ki+9hBqX4m3Rk+X5oY5bv/FQ=";
};
doCheck = false;
catchConflicts = false;
strictDeps = false;
dontCheckRuntimeDeps = true;
nativeBuildInputs = with pythonPkgs; [poetry-core setuptools];
@ -134,7 +128,7 @@
tidal-dl-ng-gui-desktopfile = pkgs.stdenv.mkDerivation {
pname = "tdng";
version = "0.31.3";
version = "0.33.2";
dontUnpack = true;
nativeBuildInputs = [pkgs.makeWrapper];

View File

@ -0,0 +1,60 @@
{
lib,
stdenv,
pkgs,
}: let
pythonPkgs = pkgs.python314Packages.overrideScope (self: super: {
typer = super.typer.overridePythonAttrs (old: {
version = "0.20.1";
src = pkgs.fetchPypi {
pname = "typer";
version = "0.20.0";
sha256 = "sha256-Gq9klAMXk+SHb7C6z6apErVRz0PB5jyADfixqGZyDDc=";
};
});
aiofiles = super.aiofiles.overridePythonAttrs (old: {
version = "25.1.0";
src = pkgs.fetchFromGitHub {
owner = "Tinche";
repo = "aiofiles";
tag = "v25.1.0";
hash = "sha256-NBmzoUb2una3+eWqR1HraVPibaRb9I51aYwskrjxskQ=";
};
# Build system changed in this version
build-system = with pythonPkgs; [
hatchling
hatch-vcs
];
});
});
in
pythonPkgs.buildPythonApplication rec {
pname = "tiddl";
version = "3.2.0";
format = "pyproject";
src = pythonPkgs.fetchPypi {
inherit pname version;
sha256 = "sha256-uLkGyIScYPqFgQdPAOYJDJG0jp+nDAwIl2kFkaJZFco=";
};
dontCheckRuntimeDeps = true;
build-system = with pythonPkgs; [
poetry-core
setuptools
];
propagatedBuildInputs = with pythonPkgs; [
# Nixpkgs
aiofiles
aiohttp
m3u8
mutagen
pydantic
requests
requests-cache
typer
];
}

View File

@ -478,6 +478,7 @@ in
systemctl-tui
restic # Backups
gnumake
just
# Hardware/Software info
pciutils # lspci
@ -499,7 +500,7 @@ in
imagemagick # Convert image (magic)
mp3val # Validate mp3 files
flac # Validate flac files
spotdl
# spotdl
# Document utils
poppler-utils # pdfunite
@ -560,6 +561,8 @@ in
audacity
ferdium
gparted
# feishin # electron :(
jellyfin-tui
# Office
kdePackages.wacomtablet # For xournalpp/krita

View File

@ -133,6 +133,7 @@
godot_4
(obs-studio.override {cudaSupport = true;})
kdePackages.kdenlive
# davinci-resolve
krita
makemkv
lrcget
@ -142,6 +143,7 @@
jellyfin-mpv-shim
# tidal-hifi
# tidal-dl-ng # TODO: Borked
tiddl
picard
handbrake
teamspeak6-client

View File

@ -69,6 +69,7 @@ in [
(mkBm "Rust" "https://doc.rust-lang.org/stable/book/ch03-00-common-programming-concepts.html")
(mkBm "RustOS" "https://os.phil-opp.com/")
(mkBm "Interpreters" "https://craftinginterpreters.com/contents.html")
(mkBm "Godbolt" "https://godbolt.org")
];
}
{

View File

@ -243,7 +243,7 @@ in {
# catppuccin-web-file-icons
clearurls
# cookie-autodelete
dark-background-light-text
# dark-background-light-text
display-_anchors # Easier linking to specific website parts
don-t-fuck-with-paste
# enhancer-for-youtube # Discontinued, use tweaks-for-youtube

View File

@ -49,6 +49,8 @@ in {
tinymist
typescript
vscode-langservers-extracted # includes nodejs
autotools-language-server
just-lsp
# Linters
checkstyle # java
@ -73,6 +75,8 @@ in {
rustfmt
stylua
typstyle
mbake
just-formatter
])
[
@ -512,8 +516,10 @@ in {
html = ["prettierd" "prettier"];
java = ["google-java-format"];
javascript = ["prettierd" "prettier"];
just = ["just"];
latex = ["tex-fmt"];
lua = ["stylua"];
make = ["bake"];
markdown = ["prettierd" "prettier"];
nix = ["alejandra"];
python = ["black"];
@ -877,6 +883,7 @@ in {
{name = "cmake";}
{name = "cssls";}
{name = "html";} # vscode-langservers-extracted
{name = "just-lsp";} # TODO: Doesn't autostart?
{name = "lua_ls";}
{
name = "ltex";
@ -887,6 +894,7 @@ in {
};
};
}
{name = "autotools-language-server";}
# {name = "nil_ls";}
{
name = "nixd";
@ -1985,6 +1993,39 @@ in {
'';
};
visual-whitespace = rec {
name = "visual-whitespace";
pkg = pkgs.vimPlugins.visual-whitespace-nvim;
event = ["ModeChanged *:[vV\22]"];
config = mkDefaultConfig name;
opts = {
enabled = true;
highlight = {
link = "Visual";
default = true;
};
match_types = {
space = true;
tab = true;
nbsp = true;
lead = false;
trail = false;
};
list_chars = {
space = "·";
tab = "";
nbsp = "";
lead = "";
trail = "";
};
fileformat_chars = {
unix = "";
mac = "";
dos = "";
};
};
};
# wakatime = {
# name = "wakatime";
# pkg = pkgs.vimPlugins.vim-wakatime;
@ -2166,6 +2207,7 @@ in {
typst-preview # Typst support
ufo # Code folding
vimtex # LaTeX support
visual-whitespace
# wakatime # Time tracking
web-devicons # Icons for many plugins
which-key # Live keybinding help

View File

@ -85,6 +85,9 @@
ip,
router,
nameserver ? "8.8.8.8;8.8.4.4;",
ip6,
router6,
nameserver6 ? "2001:4860:4860::8888;2001:4860:4860::8844;",
autoconnect ? true,
priority ? 0,
}: {
@ -103,7 +106,12 @@
};
ipv6 = {
method = "disabled";
method = "auto";
addr-gen-mode = "stable-privacy";
ignore-auto-dns = "true";
address1 = ip6;
gateway = router6;
dns = nameserver6;
};
};
}

View File

@ -27,23 +27,65 @@
useNetworkManager = true;
# Systemd-networkd configs
networks = {
networks = let
# TODO: mylib.networking.mkStaticSystemdNetwork needs improvement to accomodate for this
mkConfig = name: routable: rec {
enable = true;
# See man systemd.link, man systemd.netdev, man systemd.network
matchConfig = {
# This corresponds to the [MATCH] section
Name = name; # Match ethernet interface
};
# Static IP + DNS + Gateway
address = ["192.168.86.50/24"];
gateway = ["192.168.86.5"]; # Don't add "fd00::5", rely on router advertisement instead
dns = ["129.168.86.26" "fd00::1a" "8.8.8.8" "8.8.4.4" "2001:4860:4860::8888" "2001:4860:4860::8844"];
routes = builtins.map (r: {Gateway = r;}) gateway;
# See man systemd.network
networkConfig = {
# This corresponds to the [NETWORK] section
DHCP = "no";
IPv6AcceptRA = "yes"; # Accept Router Advertisements
# MulticastDNS = "no";
# LLMNR = "no";
# LinkLocalAddressing = "ipv6";
};
addresses = [
{
# Don't add this to address, we don't want to create any routes with this
Address = "fd00::32/64"; # IPv6 Unique-Local Address (ULA)
}
];
linkConfig = {
# This corresponds to the [LINK] section
RequiredForOnline = routable;
};
};
in {
# "10-ether-2_5G" = mylib.networking.mkStaticSystemdNetwork {
# interface = "enp8s0";
# ips = ["192.168.86.50/24"];
# routers = ["192.168.86.5"];
# nameservers = ["192.168.86.26" "8.8.8.8"];
# routable = true;
# };
# "10-ether-1G" = mylib.networking.mkStaticSystemdNetwork {
# interface = "enp5s0";
# ips = ["192.168.86.50/24"];
# routers = ["192.168.86.5"];
# nameservers = ["192.168.86.26" "8.8.8.8"];
# routable = false;
# };
# This should override the default network 50-ether
"10-ether-2_5G" = mylib.networking.mkStaticSystemdNetwork {
interface = "enp8s0";
ips = ["192.168.86.50/24"];
routers = ["192.168.86.5"];
nameservers = ["192.168.86.26" "8.8.8.8"];
routable = true;
};
"10-ether-1G" = mylib.networking.mkStaticSystemdNetwork {
interface = "enp5s0";
ips = ["192.168.86.50/24"];
routers = ["192.168.86.5"];
nameservers = ["192.168.86.26" "8.8.8.8"];
routable = false;
};
# "10-ether-1G" = mylib.networking.mkStaticSystemdNetwork {...};
"10-ether-1G" = mkConfig "enp5s0" "no";
"10-ether-2_5G" = mkConfig "enp8s0" "routable";
};
# NetworkManager profiles
@ -56,6 +98,9 @@
ip = "192.168.86.50/24";
router = "192.168.86.5";
nameserver = "192.168.86.26;8.8.8.8;";
ip6 = "fd00::32/64";
router6 = "fd00::5";
nameserver6 = "2001:4860:4860::8888;2001:4860:4860::8844;";
priority = 10; # Rather connect to 2.5G than to 1G
};
"10-ether-1G" = mylib.networking.mkStaticNetworkManagerProfile {
@ -64,6 +109,9 @@
ip = "192.168.86.50/24";
router = "192.168.86.5";
nameserver = "192.168.86.26;8.8.8.8;";
ip6 = "fd00::32/64";
router6 = "fd00::5";
nameserver6 = "2001:4860:4860::8888;2001:4860:4860::8844;";
};
};

View File

@ -28,6 +28,7 @@
../services/gitea.nix
../services/immich.nix
../services/jellyfin.nix
../services/kiwix.nix
../services/kopia.nix
../services/nextcloud.nix
../services/nginx-proxy-manager.nix

View File

@ -6,7 +6,7 @@
}: let
vectorchordVersion = "0.4.2";
pgvectorsVersion = "0.2.0";
immichVersion = "2.3.1";
immichVersion = "2.5.2";
in {
virtualisation.oci-containers.containers = {
immich-database = {

40
system/services/kiwix.nix Normal file
View File

@ -0,0 +1,40 @@
{
config,
lib,
pkgs,
...
}: let
kiwixVersion = "3.8.1";
in {
virtualisation.oci-containers.containers = {
kiwix = {
image = "ghcr.io/kiwix/kiwix-serve:${kiwixVersion}";
autoStart = true;
dependsOn = [];
ports = [
# "8080:80"
];
volumes = [
# TODO: Add network location for .zim files
"kiwix_data:/data"
];
environment = {
PUID = "1000";
PGID = "1000";
TZ = "Europe/Berlin";
};
cmd = ["*.zim"];
extraOptions = [
# "--privileged"
# "--device=nvidia.com/gpu=all"
"--net=behind-nginx"
];
};
};
}

View File

@ -26,6 +26,9 @@ in {
"80:80"
# "81:81" # Web interface
"443:443"
# TODO: Should probably split the nginx configs for ServeNix and ThinkNix
"5520:5520" # HyTale
];
volumes = [

View File

@ -126,6 +126,7 @@ in {
# (mkUDir ".nv" m755) # Unity
(mkUDir ".ollama" m755)
# (mkUDir ".plastic4" m755) # Unity
(mkUDir ".tiddl" m755)
(mkUDir ".var/app" m755)
(mkUDir ".vim/undo" m755)
(mkUDir ".zotero" m755)
@ -142,9 +143,11 @@ in {
(mkUDir ".config/blender" m755)
(mkUDir ".config/chromium" m755) # TODO: Remove this someday
(mkUDir ".config/Ferdium" m755)
(mkUDir ".config/feishin" m755)
(mkUDir ".config/fish/completions" m755)
(mkUDir ".config/impermanence" m755)
(mkUDir ".config/jellyfin-mpv-shim" m755)
(mkUDir ".config/jellyfin-tui" m755) # TODO: Generate this config file, have to use sops because it includes the password in cleartext
(mkUDir ".config/JetBrains" m755)
(mkUDir ".config/kdeconnect" m755)
(mkUDir ".config/keepassxc" m755)
@ -171,6 +174,7 @@ in {
(mkUDir ".local/share/fish" m755)
(mkUDir ".local/share/flatpak" m755)
(mkUDir ".local/share/jellyfin-desktop" m755)
(mkUDir ".local/share/jellyfin-tui" m755)
(mkUDir ".local/share/JetBrains" m755) # Unity
(mkUDir ".local/share/hyprland" m755)
(mkUDir ".local/share/keyrings" m755) # m700