Compare commits

..

1 commit

Author SHA1 Message Date
Bruno BELANYI 06cc34dc1c WIP: Bazel template
All checks were successful
ci/woodpecker/push/check Pipeline was successful
WIP: use new MODULE.bazel system.
WIP: use `.bazel` extension on BUILD files.
2024-05-13 10:56:08 +00:00
120 changed files with 1191 additions and 1146 deletions

View file

@ -7,7 +7,7 @@ steps:
commands: commands:
- nix flake check - nix flake check
- name: notify - name: notifiy
image: bash image: bash
environment: environment:
ADDRESS: ADDRESS:

View file

@ -14,11 +14,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1723293904, "lastModified": 1714136352,
"narHash": "sha256-b+uqzj+Wa6xgMS9aNbX4I+sXeb5biPDi39VgvSFqFvU=", "narHash": "sha256-BtWQ2Th/jamO1SlD+2ASSW5Jaf7JhA/JLpQHk0Goqpg=",
"owner": "ryantm", "owner": "ryantm",
"repo": "agenix", "repo": "agenix",
"rev": "f6291c5935fdc4e0bef208cfc0dcab7e3f7a1c41", "rev": "24a7ea390564ccd5b39b7884f597cfc8d7f6f44e",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -73,11 +73,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1733312601, "lastModified": 1714641030,
"narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=", "narHash": "sha256-yzcRNDoyVP7+SCNX0wmuDju1NUCt8Dz9+lyUXEI0dbI=",
"owner": "hercules-ci", "owner": "hercules-ci",
"repo": "flake-parts", "repo": "flake-parts",
"rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9", "rev": "e5d10a24b66c3ea8f150e47dfdb0416ab7c3390e",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -94,11 +94,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1731533236, "lastModified": 1710146030,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -136,11 +136,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1734808199, "lastModified": 1714679908,
"narHash": "sha256-MxlUcLjE8xLbrI1SJ2B2jftlg4wdutEILa3fgqwA98I=", "narHash": "sha256-KzcXzDvDJjX34en8f3Zimm396x6idbt+cu4tWDVS2FI=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "f342df3ad938f205a913973b832f52c12546aac6", "rev": "9036fe9ef8e15a819fa76f47a8b1f287903fb848",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -152,11 +152,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1734424634, "lastModified": 1714635257,
"narHash": "sha256-cHar1vqHOOyC7f1+tVycPoWTfKIaqkoe1Q6TnKzuti4=", "narHash": "sha256-4cPymbty65RvF1DWQfc+Bc8B233A1BWxJnNULJKQ1EY=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "d3c42f187194c26d9f0309a8ecc469d6c878ce33", "rev": "63c3a29ca82437c87573e4c6919b09a24ea61b0f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -167,21 +167,12 @@
} }
}, },
"nur": { "nur": {
"inputs": {
"flake-parts": [
"flake-parts"
],
"nixpkgs": [
"nixpkgs"
],
"treefmt-nix": "treefmt-nix"
},
"locked": { "locked": {
"lastModified": 1734810357, "lastModified": 1714825428,
"narHash": "sha256-Oa6d+y1/PVaPrZ/GYwvmTK9kSrc5Qx/8D3DFN2TzpVA=", "narHash": "sha256-6U4cppyR0u6sqSSVr3GMrnIXhP2YGR0knfgrUGtr/1Y=",
"owner": "nix-community", "owner": "nix-community",
"repo": "NUR", "repo": "NUR",
"rev": "e7b7b92a7c97a91f1465ab433bbdf6d00df1db8e", "rev": "5847f3365c16afafc10c56994beadd4cdc8552ee",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -194,6 +185,9 @@
"pre-commit-hooks": { "pre-commit-hooks": {
"inputs": { "inputs": {
"flake-compat": "flake-compat", "flake-compat": "flake-compat",
"flake-utils": [
"futils"
],
"gitignore": "gitignore", "gitignore": "gitignore",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
@ -203,11 +197,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1734797603, "lastModified": 1714478972,
"narHash": "sha256-ulZN7ps8nBV31SE+dwkDvKIzvN6hroRY8sYOT0w+E28=", "narHash": "sha256-q//cgb52vv81uOuwz1LaXElp3XAe1TqrABXODAEF6Sk=",
"owner": "cachix", "owner": "cachix",
"repo": "pre-commit-hooks.nix", "repo": "pre-commit-hooks.nix",
"rev": "f0f0dc4920a903c3e08f5bdb9246bb572fcae498", "rev": "2849da033884f54822af194400f8dff435ada242",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -244,27 +238,6 @@
"repo": "default", "repo": "default",
"type": "github" "type": "github"
} }
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"nur",
"nixpkgs"
]
},
"locked": {
"lastModified": 1733222881,
"narHash": "sha256-JIPcz1PrpXUCbaccEnrcUS8jjEb/1vJbZz5KkobyFdM=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "49717b5af6f80172275d47a418c9719a31a78b53",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
} }
}, },
"root": "root", "root": "root",

View file

@ -55,10 +55,6 @@
owner = "nix-community"; owner = "nix-community";
repo = "NUR"; repo = "NUR";
ref = "master"; ref = "master";
inputs = {
flake-parts.follows = "flake-parts";
nixpkgs.follows = "nixpkgs";
};
}; };
pre-commit-hooks = { pre-commit-hooks = {
@ -67,6 +63,7 @@
repo = "pre-commit-hooks.nix"; repo = "pre-commit-hooks.nix";
ref = "master"; ref = "master";
inputs = { inputs = {
flake-utils.follows = "futils";
nixpkgs.follows = "nixpkgs"; nixpkgs.follows = "nixpkgs";
nixpkgs-stable.follows = "nixpkgs"; nixpkgs-stable.follows = "nixpkgs";
}; };

View file

@ -25,7 +25,7 @@ let
inherit system; inherit system;
overlays = (lib.attrValues self.overlays) ++ [ overlays = (lib.attrValues self.overlays) ++ [
inputs.nur.overlays.default inputs.nur.overlay
]; ];
}; };

View file

@ -7,7 +7,7 @@ let
} }
{ {
nixpkgs.overlays = (lib.attrValues self.overlays) ++ [ nixpkgs.overlays = (lib.attrValues self.overlays) ++ [
inputs.nur.overlays.default inputs.nur.overlay
]; ];
} }
# Include generic settings # Include generic settings

View file

@ -1,9 +1,8 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 cKojmg Ec0xt1uJTva8MxUdoTVX5m3uWaIiRlodf345FEM7Uzs -> ssh-ed25519 cKojmg bQFr9oAnbo1rI/MpUV8wQz/Xj7iZY4ZU+Swf0nSIQFw
aJIneWFJPB5HVeoUGp57agXih9YeZ6xMEbyQ+zJtWQY zama2XJ0gdvUlD2GHMhmZqHSxHe+dKSfXnHoWDcSw7Y
-> ssh-ed25519 jPowng B5XotRgv7s/FUegGhceBj7EoukewNUOIFl4TFRQf1EQ -> ssh-ed25519 jPowng gitUwSKTNKWLSxnwa185O7x/u0ul93g8wPESdZaKRk8
PgGCBd/Pqwp7ayqi7okHBGF1SfFpwT4KlHJ/np6p2uQ uvBIfAUkZp5sg6rfeEGvL5ZDV8m2uSEotW02kjPN3Hw
--- AeLgwGz6k3OABb53cXNaCU/sgI4FlU1s6p8PhAaFOlg --- SZxe5f/CUZBvPQa2Sz/UBY3L68rMkIGGRuZPk7YE+Vg
1ÌÉCÔ¹ð¤ŽULfI1¸Hm»Ûòb}m” ÁÅ¡ìg•ß0¦¢–¤`X<16>G>\>¹8rŽz+ŠY ™¼`—Ê¢.JBUÏ!z¸Z50ú*õ¡ÙŸ¤×ÖÇ®I<C2AE>ôÔ]¹Ïå I ¾r ú&…¥‹{~v?¨}=Ä
ĵ<18>¿oÒÛ°…g„®„ÒêÁ³Â¿Ÿt©nƒºãcz[»{ }+ ¿SQM[²]Œ±k MÒAàtŒÃmMë/£µLsü|Þ…m©CÀñiYC}ƒŽ‡çxŽ€
jçå&ÁõõNæ°Nÿo{õš½‚ -eP¾=L‰™ 6¦.SP:»e¶

View file

@ -0,0 +1,8 @@
age-encryption.org/v1
-> ssh-ed25519 cKojmg xRtF3XVc7yPicAV/E4U7mn0itvD0h1BWBTjwunuoe2E
OkB9sjGB3ulH4Feuyj3Ed0DBG4+mghW/Qpum9oXL/8c
-> ssh-ed25519 jPowng 1r8drqhz1yZdTq0Kvqya+ArU1C2fkN7Gg9LiWWfeUFg
cjbxntVwHvqLaJpiKs/Y8ojeb6e3/cLFcsoeuoobfFg
--- B1qA2PylJBrdZxZtCzlU2kRPvxLM+IrXTvR+ERxVtTY
"W9<57>Äbg¸©~Ì/áÕb4ãÕ†ú³ÜÔIÊ
Û}ð §ËÅË-³²ªNó±”ÑC7vWœbºØ?¦8=œÉwÆB ÃUpJClï²OÈ™³œnOÁ\

View file

@ -1,8 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 cKojmg VYlHgHSLpfKb5bn1XA3aCpfX7M23DgbraLxxOfo9PDk
Rj+mDvAsWX3WwpuhTrOubmo17j/aud5+P87df5bosBA
-> ssh-ed25519 jPowng o9ZFaYrITZ6DjWw07Vk/+TkuU187/ytlEK4sw7G32G4
zmxlpDvDDEgQFqBVARXeX1ABhvfJ4uAHfa6mIxXzjAY
--- k/d9FWW8/OSo8EllwOBV74pZyX918u54jEljGk3ATUc
ü4+ø2{hE7!Ò­GA`×<>_@Íß—´¡R_ý§6J„ñL4v,6%ô‡øó#^® Ù¹ åB­§OøF|7ܽÉL]œÙj
BþóÛ¾éaòs]xS<78>Î pbÞo#¬J1QŸ=t}5Õ>Oï{+¼. M"7e»yý÷—

View file

@ -48,6 +48,9 @@ in
owner = "matrix-synapse"; owner = "matrix-synapse";
publicKeys = all; publicKeys = all;
}; };
"matrix/sliding-sync-secret.age" = {
publicKeys = all;
};
"mealie/mail.age" = { "mealie/mail.age" = {
publicKeys = all; publicKeys = all;
@ -74,24 +77,13 @@ in
"paperless/password.age".publicKeys = all; "paperless/password.age".publicKeys = all;
"paperless/secret-key.age".publicKeys = all; "paperless/secret-key.age".publicKeys = all;
"pdf-edit/login.age".publicKeys = all;
"podgrab/password.age".publicKeys = all; "podgrab/password.age".publicKeys = all;
"pyload/credentials.age".publicKeys = all; "pyload/credentials.age".publicKeys = all;
"sso/auth-key.age" = { "sso/auth-key.age".publicKeys = all;
owner = "nginx-sso"; "sso/ambroisie/password-hash.age".publicKeys = all;
publicKeys = all; "sso/ambroisie/totp-secret.age".publicKeys = all;
};
"sso/ambroisie/password-hash.age" = {
owner = "nginx-sso";
publicKeys = all;
};
"sso/ambroisie/totp-secret.age" = {
owner = "nginx-sso";
publicKeys = all;
};
"tandoor-recipes/secret-key.age".publicKeys = all; "tandoor-recipes/secret-key.age".publicKeys = all;

View file

@ -69,6 +69,9 @@ in
mailConfigFile = secrets."matrix/mail".path; mailConfigFile = secrets."matrix/mail".path;
# Only necessary when doing the initial registration # Only necessary when doing the initial registration
secretFile = secrets."matrix/secret".path; secretFile = secrets."matrix/secret".path;
slidingSync = {
secretFile = secrets."matrix/sliding-sync-secret".path;
};
}; };
mealie = { mealie = {
enable = true; enable = true;
@ -95,9 +98,6 @@ in
nextcloud = { nextcloud = {
enable = true; enable = true;
passwordFile = secrets."nextcloud/password".path; passwordFile = secrets."nextcloud/password".path;
collabora = {
enable = true;
};
}; };
nix-cache = { nix-cache = {
enable = true; enable = true;
@ -127,10 +127,20 @@ in
passwordFile = secrets."paperless/password".path; passwordFile = secrets."paperless/password".path;
secretKeyFile = secrets."paperless/secret-key".path; secretKeyFile = secrets."paperless/secret-key".path;
}; };
# Sometimes, editing PDFs is useful # The whole *arr software suite
pdf-edit = { pirate = {
enable = true; enable = true;
loginFile = secrets."pdf-edit/login".path; # ... But not Lidarr because I don't care for music that much
lidarr = {
enable = false;
};
};
# Podcast automatic downloader
podgrab = {
enable = true;
passwordFile = secrets."podgrab/password".path;
dataDir = "/data/media/podcasts";
port = 9598;
}; };
# Regular backups # Regular backups
postgresql-backup.enable = true; postgresql-backup.enable = true;
@ -142,16 +152,13 @@ in
rss-bridge.enable = true; rss-bridge.enable = true;
# Usenet client # Usenet client
sabnzbd.enable = true; sabnzbd.enable = true;
# The whole *arr software suite # Because I stilll need to play sysadmin
servarr = {
enable = true;
# ... But not Lidarr because I don't care for music that much
lidarr = {
enable = false;
};
};
# Because I still need to play sysadmin
ssh-server.enable = true; ssh-server.enable = true;
# Recipe manager
tandoor-recipes = {
enable = true;
secretKeyFile = secrets."tandoor-recipes/secret-key".path;
};
# Torrent client and webui # Torrent client and webui
transmission = { transmission = {
enable = true; enable = true;

View file

@ -1,19 +1,15 @@
{ config, lib, pkgs, ... }: { config, lib, ... }:
let let
cfg = config.my.home.atuin; cfg = config.my.home.atuin;
in in
{ {
options.my.home.atuin = with lib; { options.my.home.atuin = with lib; {
enable = my.mkDisableOption "atuin configuration"; enable = my.mkDisableOption "atuin configuration";
# I want the full experience by default
package = mkPackageOption pkgs "atuin" { };
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
programs.atuin = { programs.atuin = {
enable = true; enable = true;
inherit (cfg) package;
flags = [ flags = [
# I *despise* this hijacking of the up key, even though I use Ctrl-p # I *despise* this hijacking of the up key, even though I use Ctrl-p

View file

@ -5,13 +5,11 @@ in
{ {
options.my.home.calibre = with lib; { options.my.home.calibre = with lib; {
enable = mkEnableOption "calibre configuration"; enable = mkEnableOption "calibre configuration";
package = mkPackageOption pkgs "calibre" { };
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
home.packages = with pkgs; [ home.packages = with pkgs; [
cfg.package calibre
]; ];
}; };
} }

View file

@ -1,4 +1,4 @@
# shellcheck shell=bash #shellcheck shell=bash
# shellcheck disable=2155 # shellcheck disable=2155
use_android() { use_android() {
@ -32,16 +32,10 @@ use_android() {
-b|--build-tools) -b|--build-tools)
build_tools_version="$2" build_tools_version="$2"
shift 2 shift 2
if ! [ -e "$ANDROID_HOME/build-tools/$build_tools_version" ]; then
log_error "use_android: build-tools version '$build_tools_version' does not exist"
fi
;; ;;
-n|--ndk) -n|--ndk)
ndk_version="$2" ndk_version="$2"
shift 2 shift 2
if ! [ -e "$ANDROID_HOME/ndk/$ndk_version" ]; then
log_error "use_android: NDK version '$ndk_version' does not exist"
fi
;; ;;
--) --)
shift shift

View file

@ -1,4 +1,4 @@
# shellcheck shell=bash #shellcheck shell=bash
use_pkgs() { use_pkgs() {
if ! has nix; then if ! has nix; then

View file

@ -1,4 +1,4 @@
# shellcheck shell=bash #shellcheck shell=bash
layout_postgres() { layout_postgres() {
if ! has postgres || ! has initdb; then if ! has postgres || ! has initdb; then

View file

@ -1,4 +1,4 @@
# shellcheck shell=bash #shellcheck shell=bash
layout_poetry() { layout_poetry() {
if ! has poetry; then if ! has poetry; then
@ -9,12 +9,12 @@ layout_poetry() {
if [[ ! -f pyproject.toml ]]; then if [[ ! -f pyproject.toml ]]; then
# shellcheck disable=2016 # shellcheck disable=2016
log_error 'layout_poetry: no pyproject.toml found. Use `poetry init` to create one first' log_error 'layout_poetry: no pyproject.toml found. Use `poetry new` or `poetry init` to create one first'
return 1 return 1
fi fi
# create venv if it doesn't exist # create venv if it doesn't exist
poetry run -q -- true poetry run true
# shellcheck disable=2155 # shellcheck disable=2155
export VIRTUAL_ENV=$(poetry env info --path) export VIRTUAL_ENV=$(poetry env info --path)
@ -23,35 +23,3 @@ layout_poetry() {
watch_file pyproject.toml watch_file pyproject.toml
watch_file poetry.lock watch_file poetry.lock
} }
layout_uv() {
if ! has uv; then
# shellcheck disable=2016
log_error 'layout_uv: `uv` is not in PATH'
return 1
fi
if [[ ! -f pyproject.toml ]]; then
# shellcheck disable=2016
log_error 'layout_uv: no pyproject.toml found. Use `uv init` to create one first'
return 1
fi
local default_venv="$PWD/.venv"
: "${VIRTUAL_ENV:=$default_venv}"
# Use non-default venv path if required
if [ "$VIRTUAL_ENV" != "$default_venv" ]; then
export UV_PROJECT_ENVIRONMENT="$VIRTUAL_ENV"
fi
# create venv if it doesn't exist
uv venv -q
export VIRTUAL_ENV
export UV_ACTIVE=1
PATH_add "$VIRTUAL_ENV/bin"
watch_file pyproject.toml
watch_file uv.lock
watch_file .python-version
}

View file

@ -7,13 +7,11 @@ in
{ {
options.my.home.discord = with lib; { options.my.home.discord = with lib; {
enable = mkEnableOption "discord configuration"; enable = mkEnableOption "discord configuration";
package = mkPackageOption pkgs "discord" { };
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
home.packages = with pkgs; [ home.packages = with pkgs; [
cfg.package discord
]; ];
xdg.configFile."discord/settings.json".source = xdg.configFile."discord/settings.json".source =

View file

@ -4,7 +4,7 @@
" Use dark color scheme " Use dark color scheme
colorscheme dark colorscheme dark
" Make tridactyl open Vim in my preferred terminal " Make tridactyl open Vim in my prefered terminal
set editorcmd @editorcmd@ set editorcmd @editorcmd@
" Remove editor file after use " Remove editor file after use
@ -15,8 +15,8 @@ bind --mode=input <C-i> editor_rm
" Binds {{{ " Binds {{{
" Reddit et al. {{{ " Reddit et al. {{{
" Toggle comments on Reddit, Hacker News, Lobste.rs, LWN " Toggle comments on Reddit, Hacker News, Lobste.rs
bind ;c hint -Jc [class*="expand"],[class*="togg"],[class="comment_folder"],[class="CommentTitle"] bind ;c hint -Jc [class*="expand"],[class*="togg"],[class="comment_folder"]
" Make `gu` take me back to subreddit from comments " Make `gu` take me back to subreddit from comments
bindurl reddit.com gu urlparent 3 bindurl reddit.com gu urlparent 3
@ -26,8 +26,8 @@ bindurl www.google.com f hint -Jc #search a
bindurl www.google.com F hint -Jbc #search a bindurl www.google.com F hint -Jbc #search a
" Only hint search results on DuckDuckGo " Only hint search results on DuckDuckGo
bindurl ^https://duckduckgo.com f hint -Jc [data-testid="result"] bindurl ^https://duckduckgo.com f hint -Jc [data-testid="result-title-a"]
bindurl ^https://duckduckgo.com F hint -Jbc [data-testid="result"] bindurl ^https://duckduckgo.com F hint -Jbc [data-testid="result-title-a"]
" Only hint item pages on Hacker News " Only hint item pages on Hacker News
bindurl news.ycombinator.com ;f hint -Jc .age > a bindurl news.ycombinator.com ;f hint -Jc .age > a

View file

@ -6,28 +6,33 @@ in
options.my.home.gdb = with lib; { options.my.home.gdb = with lib; {
enable = my.mkDisableOption "gdb configuration"; enable = my.mkDisableOption "gdb configuration";
package = mkPackageOption pkgs "gdb" { };
rr = { rr = {
enable = my.mkDisableOption "rr configuration"; enable = my.mkDisableOption "rr configuration";
package = mkPackageOption pkgs "rr" { }; package = mkOption {
type = types.package;
default = pkgs.rr;
defaultText = literalExample "pkgs.rr";
description = ''
Package providing rr
'';
};
}; };
}; };
config = lib.mkIf cfg.enable (lib.mkMerge [ config = lib.mkIf cfg.enable (lib.mkMerge [
{ {
home.packages = with pkgs; [ home.packages = with pkgs; [
cfg.package gdb
]; ];
xdg = { xdg = {
configFile."gdb/gdbinit".source = ./gdbinit; configFile."gdb/gdbinit".source = ./gdbinit;
stateFile."gdb/.keep".text = ""; dataFile. "gdb/.keep".text = "";
}; };
home.sessionVariables = { home.sessionVariables = {
GDBHISTFILE = "${config.xdg.stateHome}/gdb/gdb_history"; GDBHISTFILE = "${config.xdg.dataHome}/gdb/gdb_history";
}; };
} }

View file

@ -21,12 +21,12 @@ in
}; };
iconTheme = { iconTheme = {
package = pkgs.gnome-themes-extra; package = pkgs.gnome.gnome-themes-extra;
name = "Adwaita"; name = "Adwaita";
}; };
theme = { theme = {
package = pkgs.gnome-themes-extra; package = pkgs.gnome.gnome-themes-extra;
name = "Adwaita"; name = "Adwaita";
}; };
}; };

View file

@ -58,7 +58,7 @@ in
{ {
config.accounts.email.accounts = { config.accounts.email.accounts = {
personal = lib.mkMerge [ personal = lib.mkMerge [
# Common configuration # Common configuraton
(mkConfig { (mkConfig {
domain = "belanyi.fr"; domain = "belanyi.fr";
address = "bruno"; address = "bruno";
@ -70,7 +70,7 @@ in
]; ];
gmail = lib.mkMerge [ gmail = lib.mkMerge [
# Common configuration # Common configuraton
(mkConfig { (mkConfig {
domain = "gmail.com"; domain = "gmail.com";
address = "brunobelanyi"; address = "brunobelanyi";

View file

@ -22,16 +22,12 @@ in
options.my.home.nix = with lib; { options.my.home.nix = with lib; {
enable = my.mkDisableOption "nix configuration"; enable = my.mkDisableOption "nix configuration";
gc = {
enable = my.mkDisableOption "nix GC configuration";
};
cache = { cache = {
selfHosted = my.mkDisableOption "self-hosted cache"; selfHosted = my.mkDisableOption "self-hosted cache";
}; };
inputs = { inputs = {
link = my.mkDisableOption "link inputs to `$XDG_CONFIG_HOME/nix/inputs/`"; link = my.mkDisableOption "link inputs to `/etc/nix/inputs/`";
addToRegistry = my.mkDisableOption "add inputs and self to registry"; addToRegistry = my.mkDisableOption "add inputs and self to registry";
@ -64,22 +60,6 @@ in
}; };
} }
(lib.mkIf cfg.gc.enable {
nix.gc = {
automatic = true;
# Every week, with some wiggle room
frequency = "weekly";
randomizedDelaySec = "10min";
# Use a persistent timer for e.g: laptops
persistent = true;
# Delete old profiles automatically after 15 days
options = "--delete-older-than 15d";
};
})
(lib.mkIf cfg.cache.selfHosted { (lib.mkIf cfg.cache.selfHosted {
nix = { nix = {
settings = { settings = {
@ -116,7 +96,7 @@ in
}) })
(lib.mkIf cfg.inputs.addToNixPath { (lib.mkIf cfg.inputs.addToNixPath {
nix.nixPath = [ "${config.xdg.configHome}/nix/inputs" ]; home.sessionVariables.NIX_PATH = "${config.xdg.configHome}/nix/inputs\${NIX_PATH:+:$NIX_PATH}";
}) })
]); ]);
} }

View file

@ -26,7 +26,6 @@ in
fd fd
file file
ripgrep ripgrep
tree
] ++ cfg.additionalPackages); ] ++ cfg.additionalPackages);
nixpkgs.config = { nixpkgs.config = {

View file

@ -15,7 +15,7 @@ in
# Clear the screen on start and exit # Clear the screen on start and exit
LESS = "-R -+X -c"; LESS = "-R -+X -c";
# Better XDG compliance # Better XDG compliance
LESSHISTFILE = "${config.xdg.stateHome}/less/history"; LESSHISTFILE = "${config.xdg.dataHome}/less/history";
LESSKEY = "${config.xdg.configHome}/less/lesskey"; LESSKEY = "${config.xdg.configHome}/less/lesskey";
}; };
}; };

View file

@ -30,7 +30,7 @@ in
}); });
default = { ${config.my.home.terminal.program} = { }; }; default = { ${config.my.home.terminal.program} = { }; };
defaultText = literalExpression '' defaultText = litteralExpression ''
{ ''${config.my.home.terminal.program} = { }; }; { ''${config.my.home.terminal.program} = { }; };
''; '';
example = { xterm-256color = { }; }; example = { xterm-256color = { }; };
@ -47,8 +47,6 @@ in
clock24 = true; # I'm one of those heathens clock24 = true; # I'm one of those heathens
escapeTime = 0; # Let vim do its thing instead escapeTime = 0; # Let vim do its thing instead
historyLimit = 100000; # Bigger buffer historyLimit = 100000; # Bigger buffer
mouse = false; # I dislike mouse support
focusEvents = true; # Report focus events
terminal = "tmux-256color"; # I want accurate termcap info terminal = "tmux-256color"; # I want accurate termcap info
plugins = with pkgs.tmuxPlugins; [ plugins = with pkgs.tmuxPlugins; [
@ -82,13 +80,6 @@ in
]; ];
extraConfig = '' extraConfig = ''
# Refresh configuration
bind-key -N "Source tmux.conf" R source-file ${config.xdg.configHome}/tmux/tmux.conf \; display-message "Sourced tmux.conf!"
# Accept sloppy Ctrl key when switching windows, on top of default mapping
bind-key -N "Select the previous window" C-p previous-window
bind-key -N "Select the next window" C-n next-window
# Better vim mode # Better vim mode
bind-key -T copy-mode-vi 'v' send -X begin-selection bind-key -T copy-mode-vi 'v' send -X begin-selection
${ ${

View file

@ -0,0 +1,7 @@
" Create the `b:undo_ftplugin` variable if it doesn't exist
call ftplugined#check_undo_ft()
" Add comment format
setlocal comments=b://,s1:/*,mb:*,ex:*/
setlocal commentstring=//\ %s
let b:undo_ftplugin.='|setlocal comments< commentstring<'

View file

@ -0,0 +1,6 @@
" Create the `b:undo_ftplugin` variable if it doesn't exist
call ftplugined#check_undo_ft()
" Don't show Netrw in buffer list
setlocal bufhidden=delete
let b:undo_ftplugin='|setlocal bufhidden<'

View file

@ -0,0 +1,10 @@
local wk = require("which-key")
local keys = {
name = "Comment/uncomment",
c = "Current line",
u = "Uncomment the current and adjacent commented lines",
["gc"] = "Uncomment the current and adjacent commented lines",
}
wk.register(keys, { prefix = "gc" })

View file

@ -0,0 +1,7 @@
local wk = require("which-key")
local keys = {
["<leader>"] = { "<cmd>nohls<CR>", "Clear search highlight" },
}
wk.register(keys, { prefix = "<leader>" })

View file

@ -0,0 +1,15 @@
local wk = require("which-key")
local telescope_builtin = require("telescope.builtin")
local keys = {
f = {
name = "Fuzzy finder",
b = { telescope_builtin.buffers, "Open buffers" },
f = { telescope_builtin.git_files, "Git tracked files" },
F = { telescope_builtin.find_files, "Files" },
g = { telescope_builtin.live_grep, "Grep string" },
G = { telescope_builtin.grep_string, "Grep string under cursor" },
},
}
wk.register(keys, { prefix = "<leader>" })

View file

@ -0,0 +1,30 @@
local wk = require("which-key")
local motions = {
["]m"] = "Next method start",
["]M"] = "Next method end",
["]S"] = "Next statement start",
["]]"] = "Next class start",
["]["] = "Next class end",
["[m"] = "Previous method start",
["[M"] = "Previous method end",
["[S"] = "Previous statement start",
["[["] = "Previous class start",
["[]"] = "Previous class end",
}
local objects = {
["aa"] = "a parameter",
["ia"] = "inner parameter",
["ab"] = "a block",
["ib"] = "inner block",
["ac"] = "a class",
["ic"] = "inner class",
["af"] = "a function",
["if"] = "inner function",
["ak"] = "a comment",
["aS"] = "a statement",
}
wk.register(motions, { mode = "n" })
wk.register(objects, { mode = "o" })

View file

@ -3,124 +3,126 @@ local wk = require("which-key")
local lsp = require("ambroisie.lsp") local lsp = require("ambroisie.lsp")
local keys = { local keys = {
-- Previous -- Edition and navigation mappins
{ "[", group = "Previous" }, ["["] = {
-- Edition and navigation mappings name = "Previous",
{ "[<space>", desc = "Insert blank line above" }, ["<space>"] = "Insert blank line above",
{ "[<C-L>", desc = "Previous location list file" }, ["<C-L>"] = "Previous location list file",
{ "[<C-Q>", desc = "Previous quickfix list file" }, ["<C-Q>"] = "Previous quickfix list file",
{ "[<C-T>", desc = "Previous tag in preview window" }, ["<C-T>"] = "Previous tag in preview window",
{ "[a", desc = "Previous argument" }, a = "Previous argument",
{ "[A", desc = "First argument" }, A = "First argument",
{ "[b", desc = "Previous buffer" }, b = "Previous buffer",
{ "[B", desc = "First buffer" }, B = "First buffer",
{ "[e", desc = "Exchange previous line" }, e = "Exchange previous line",
{ "[f", desc = "Previous file in directory" }, f = "Previous file in directory",
{ "[l", desc = "Previous location list entry" }, l = "Previous location list entry",
{ "[L", desc = "First Location list entry" }, L = "First Location list entry",
{ "[n", desc = "Previous conflict marker/diff hunk" }, n = "Previous conflict marker/diff hunk",
{ "[p", desc = "Paste line above" }, p = "Paste line above",
{ "[P", desc = "Paste line above" }, P = "Paste line above",
{ "[q", desc = "Previous quickfix list entry" }, q = "Previous quickfix list entry",
{ "[Q", desc = "First quickfix list entry" }, Q = "First quickfix list entry",
{ "[t", desc = "Previous matching tag" }, t = "Previous matching tag",
{ "[T", desc = "First matching tag" }, T = "First matching tag",
{ "[z", desc = "Previous fold" }, z = "Previous fold",
-- Encoding -- Encoding
{ "[C", desc = "C string encode" }, C = "C string encode",
{ "[u", desc = "URL encode" }, u = "URL encode",
{ "[x", desc = "XML encode" }, x = "XML encode",
{ "[y", desc = "C string encode" }, y = "C string encode",
-- Custom -- Custom
{ "[d", lsp.goto_prev_diagnostic, desc = "Previous diagnostic" }, d = { lsp.goto_prev_diagnostic, "Previous diagnostic" },
},
-- Next ["]"] = {
{ "]", group = "Next" }, name = "Next",
-- Edition and navigation mappings ["<space>"] = "Insert blank line below",
{ "]<space>", desc = "Insert blank line below" }, ["<C-L>"] = "Next location list file",
{ "]<C-L>", desc = "Next location list file" }, ["<C-Q>"] = "Next quickfix list file",
{ "]<C-Q>", desc = "Next quickfix list file" }, ["<C-T>"] = "Next tag in preview window",
{ "]<C-T>", desc = "Next tag in preview window" }, a = "Next argument",
{ "]a", desc = "Next argument" }, A = "Last argument",
{ "]A", desc = "Last argument" }, b = "Next buffer",
{ "]b", desc = "Next buffer" }, B = "Last buffer",
{ "]B", desc = "Last buffer" }, e = "Exchange next line",
{ "]e", desc = "Exchange next line" }, f = "Next file in directory",
{ "]f", desc = "Next file in directory" }, l = "Next location list entry",
{ "]l", desc = "Next location list entry" }, L = "Last Location list entry",
{ "]L", desc = "Last Location list entry" }, n = "Next conflict marker/diff hunk",
{ "]n", desc = "Next conflict marker/diff hunk" }, p = "Paste line below",
{ "]p", desc = "Paste line below" }, P = "Paste line below",
{ "]P", desc = "Paste line below" }, q = "Next quickfix list entry",
{ "]q", desc = "Next quickfix list entry" }, Q = "Last quickfix list entry",
{ "]Q", desc = "Last quickfix list entry" }, t = "Next matching tag",
{ "]t", desc = "Next matching tag" }, T = "Last matching tag",
{ "]T", desc = "Last matching tag" }, z = "Next fold",
{ "]z", desc = "Next fold" },
-- Decoding -- Decoding
{ "]C", desc = "C string decode" }, C = "C string decode",
{ "]u", desc = "URL decode" }, u = "URL decode",
{ "]x", desc = "XML decode" }, x = "XML decode",
{ "]y", desc = "C string decode" }, y = "C string decode",
-- Custom -- Custom
{ "]d", lsp.goto_next_diagnostic, desc = "Next diagnostic" }, d = { lsp.goto_next_diagnostic, "Next diagnostic" },
},
-- Enable option -- Option mappings
{ "[o", group = "Enable option" }, ["[o"] = {
{ "[ob", desc = "Light background" }, name = "Enable option",
{ "[oc", desc = "Cursor line" }, b = "Light background",
{ "[od", desc = "Diff" }, c = "Cursor line",
{ "[of", "<cmd>FormatEnable<CR>", desc = "LSP Formatting" }, d = "Diff",
{ "[oh", desc = "Search high-lighting" }, f = { "<cmd>FormatEnable<CR>", "LSP Formatting" },
{ "[oi", desc = "Case insensitive search" }, h = "Search high-lighting",
{ "[ol", desc = "List mode" }, i = "Case insensitive search",
{ "[on", desc = "Line numbers" }, l = "List mode",
{ "[or", desc = "Relative line numbers" }, n = "Line numbers",
{ "[op", "<cmd>lwindow<CR>", desc = "Location list" }, r = "Relative line numbers",
{ "[oq", "<cmd>cwindow<CR>", desc = "Quickfix list" }, p = { "<cmd>lwindow<CR>", "Location list" },
{ "[ou", desc = "Cursor column" }, q = { "<cmd>cwindow<CR>", "Quickfix list" },
{ "[ov", desc = "Virtual editing" }, u = "Cursor column",
{ "[ow", desc = "Text wrapping" }, v = "Virtual editing",
{ "[ox", desc = "Cursor line and column" }, w = "Text wrapping",
{ "[oz", desc = "Spell checking" }, x = "Cursor line and column",
z = "Spell checking",
-- Disable option },
{ "]o", group = "Disable option" }, ["]o"] = {
{ "]ob", desc = "Light background" }, name = "Option off",
{ "]oc", desc = "Cursor line" }, b = "Light background",
{ "]od", desc = "Diff" }, c = "Cursor line",
{ "]of", "<cmd>FormatDisable<CR>", desc = "LSP Formatting" }, d = "Diff",
{ "]oh", desc = "Search high-lighting" }, f = { "<cmd>FormatDisable<CR>", "LSP Formatting" },
{ "]oi", desc = "Case insensitive search" }, h = "Search high-lighting",
{ "]ol", desc = "List mode" }, i = "Case insensitive search",
{ "]on", desc = "Line numbers" }, l = "List mode",
{ "]op", "<cmd>lclose<CR>", desc = "Location list" }, n = "Line numbers",
{ "]oq", "<cmd>cclose<CR>", desc = "Quickfix list" }, p = { "<cmd>lclose<CR>", "Location list" },
{ "]or", desc = "Relative line numbers" }, q = { "<cmd>cclose<CR>", "Quickfix list" },
{ "]ou", desc = "Cursor column" }, r = "Relative line numbers",
{ "]ov", desc = "Virtual editing" }, u = "Cursor column",
{ "]ow", desc = "Text wrapping" }, v = "Virtual editing",
{ "]ox", desc = "Cursor line and column" }, w = "Text wrapping",
{ "]oz", desc = "Spell checking" }, x = "Cursor line and column",
z = "Spell checking",
-- Toggle option },
{ "yo", group = "Toggle option" }, ["yo"] = {
{ "yob", desc = "Light background" }, name = "Option toggle",
{ "yoc", desc = "Cursor line" }, b = "Light background",
{ "yod", desc = "Diff" }, c = "Cursor line",
{ "yof", "<cmd>FormatToggle<CR>", desc = "LSP Formatting" }, d = "Diff",
{ "yoh", desc = "Search high-lighting" }, f = { "<cmd>FormatToggle<CR>", "LSP Formatting" },
{ "yoi", desc = "Case insensitive search" }, h = "Search high-lighting",
{ "yol", desc = "List mode" }, i = "Case insensitive search",
{ "yon", desc = "Line numbers" }, l = "List mode",
{ "yop", "<Plug>(qf_loc_toggle)", desc = "Location list" }, n = "Line numbers",
{ "yoq", "<Plug>(qf_qf_toggle)", desc = "Quickfix list" }, p = { "<Plug>(qf_loc_toggle)", "Location list" },
{ "yor", desc = "Relative line numbers" }, q = { "<Plug>(qf_qf_toggle)", "Quickfix list" },
{ "you", desc = "Cursor column" }, r = "Relative line numbers",
{ "yov", desc = "Virtual editing" }, u = "Cursor column",
{ "yow", desc = "Text wrapping" }, v = "Virtual editing",
{ "yox", desc = "Cursor line and column" }, w = "Text wrapping",
{ "yoz", desc = "Spell checking" }, x = "Cursor line and column",
z = "Spell checking",
},
} }
wk.add(keys) wk.register(keys)

View file

@ -1,5 +0,0 @@
; extends
; I want to the line added/removed markers to be the correct color
"+" @diff.plus
"-" @diff.minus

View file

@ -40,18 +40,25 @@ in
lualine-lsp-progress # Show progress for LSP servers lualine-lsp-progress # Show progress for LSP servers
# tpope essentials # tpope essentials
vim-commentary # Easy comments
vim-eunuch # UNIX integrations vim-eunuch # UNIX integrations
vim-fugitive # A 'git' wrapper vim-fugitive # A 'git' wrapper
vim-git # Sane git syntax files vim-git # Sane git syntax files
vim-repeat # Enanche '.' for plugins vim-repeat # Enanche '.' for plugins
vim-rsi # Readline mappings vim-rsi # Readline mappings
vim-unimpaired # Some ex command mappings vim-unimpaired # Some ex command mappings
vim-vinegar # Better netrw
# Languages # Languages
rust-vim
vim-beancount vim-beancount
vim-jsonnet
vim-nix
vim-toml
# General enhancements # General enhancements
vim-qf # Better quick-fix list vim-qf # Better quick-fix list
nvim-osc52 # Send clipboard data through terminal escape for SSH
# Other wrappers # Other wrappers
git-messenger-vim # A simple blame window git-messenger-vim # A simple blame window
@ -63,6 +70,7 @@ in
none-ls-nvim # LSP integration for linters and formatters none-ls-nvim # LSP integration for linters and formatters
nvim-treesitter.withAllGrammars # Better highlighting nvim-treesitter.withAllGrammars # Better highlighting
nvim-treesitter-textobjects # More textobjects nvim-treesitter-textobjects # More textobjects
nvim-ts-context-commentstring # Comment string in nested language blocks
plenary-nvim # 'null-ls', 'telescope' dependency plenary-nvim # 'null-ls', 'telescope' dependency
# Completion # Completion
@ -80,7 +88,6 @@ in
dressing-nvim # Integrate native UI hooks with Telescope etc... dressing-nvim # Integrate native UI hooks with Telescope etc...
gitsigns-nvim # Fast git UI integration gitsigns-nvim # Fast git UI integration
nvim-surround # Deal with pairs, now in Lua nvim-surround # Deal with pairs, now in Lua
oil-nvim # Better alternative to NetrW
telescope-fzf-native-nvim # Use 'fzf' fuzzy matching algorithm telescope-fzf-native-nvim # Use 'fzf' fuzzy matching algorithm
telescope-lsp-handlers-nvim # Use 'telescope' for various LSP actions telescope-lsp-handlers-nvim # Use 'telescope' for various LSP actions
telescope-nvim # Fuzzy finder interface telescope-nvim # Fuzzy finder interface
@ -98,11 +105,8 @@ in
nixpkgs-fmt nixpkgs-fmt
# Shell # Shell
bash-language-server nodePackages.bash-language-server
shfmt shfmt
# Generic
typos-lsp
]; ];
}; };

View file

@ -0,0 +1,6 @@
-- Use `bp` filetype for Blueprint files
vim.filetype.add({
extension = {
bp = "bp",
},
})

View file

@ -0,0 +1,7 @@
-- Use GN filetype for Chromium Generate Ninja files
vim.filetype.add({
extension = {
gn = "gn",
gni = "gn",
},
})

View file

@ -0,0 +1,6 @@
-- Kbuild is just a Makefile under a different name
vim.filetype.add({
filename = {
["Kbuild"] = "make",
},
})

View file

@ -0,0 +1,6 @@
-- Use LaTeX filetype for TikZ files
vim.filetype.add({
extension = {
tikz = "tex",
},
})

View file

@ -1,4 +1,4 @@
" Basic configuration {{{ " Basic configuraion {{{
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Use UTF-8 " Use UTF-8
set encoding=utf-8 set encoding=utf-8
@ -38,10 +38,10 @@ set tabstop=8
" File parameters {{{ " File parameters {{{
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Disable swap files " Disable backups, we have source control for that
set nobackup
" Disable swapfiles too
set noswapfile set noswapfile
" Enable undo files
set undofile
" }}} " }}}
" UI and UX parameters {{{ " UI and UX parameters {{{
@ -86,6 +86,8 @@ set mouse=
" Set dark mode by default " Set dark mode by default
set background=dark set background=dark
" 24 bit colors
set termguicolors
" Setup some overrides for gruvbox " Setup some overrides for gruvbox
lua << EOF lua << EOF
local gruvbox = require("gruvbox") local gruvbox = require("gruvbox")
@ -100,13 +102,7 @@ gruvbox.setup({
DiffChange = { fg = colors.aqua, bg = "NONE" }, DiffChange = { fg = colors.aqua, bg = "NONE" },
DiffDelete = { fg = colors.red, bg = "NONE" }, DiffDelete = { fg = colors.red, bg = "NONE" },
DiffText = { fg = colors.yellow, bg = colors.bg0 }, DiffText = { fg = colors.yellow, bg = colors.bg0 },
-- Directories "pop" better in blue }
Directory = { link = "GruvboxBlueBold" },
},
italic = {
-- Comments should not be italic, for e.g: box drawing
comments = false,
},
}) })
EOF EOF
" Use my preferred colorscheme " Use my preferred colorscheme

View file

@ -5,7 +5,7 @@ local lsp_format = require("lsp-format")
--- Move to the next/previous diagnostic, automatically showing the diagnostics --- Move to the next/previous diagnostic, automatically showing the diagnostics
--- float if necessary. --- float if necessary.
--- @param forward bool whether to go forward or backwards --- @param forward whether to go forward or backwards
local function goto_diagnostic(forward) local function goto_diagnostic(forward)
vim.validate({ vim.validate({
forward = { forward, "boolean" }, forward = { forward, "boolean" },
@ -42,7 +42,7 @@ end
--- shared LSP configuration callback --- shared LSP configuration callback
--- @param client native client configuration --- @param client native client configuration
--- @param bufnr int? buffer number of the attached client --- @param bufnr int? buffer number of the attched client
M.on_attach = function(client, bufnr) M.on_attach = function(client, bufnr)
-- Format on save -- Format on save
lsp_format.on_attach(client, bufnr) lsp_format.on_attach(client, bufnr)
@ -87,30 +87,31 @@ M.on_attach = function(client, bufnr)
end end
local keys = { local keys = {
buffer = bufnr, K = { vim.lsp.buf.hover, "Show symbol information" },
-- LSP navigation ["<C-k>"] = { vim.lsp.buf.signature_help, "Show signature information" },
{ "K", vim.lsp.buf.hover, desc = "Show symbol information" }, ["gd"] = { vim.lsp.buf.definition, "Go to definition" },
{ "<C-k>", vim.lsp.buf.signature_help, desc = "Show signature information" }, ["gD"] = { vim.lsp.buf.declaration, "Go to declaration" },
{ "gd", vim.lsp.buf.definition, desc = "Go to definition" }, ["gi"] = { vim.lsp.buf.implementation, "Go to implementation" },
{ "gD", vim.lsp.buf.declaration, desc = "Go to declaration" }, ["gr"] = { vim.lsp.buf.references, "List all references" },
{ "gi", vim.lsp.buf.implementation, desc = "Go to implementation" },
{ "gr", vim.lsp.buf.references, desc = "List all references" }, ["<leader>c"] = {
-- Code name = "Code",
{ "<leader>c", group = "Code" }, a = { vim.lsp.buf.code_action, "Code actions" },
{ "<leader>ca", vim.lsp.buf.code_action, desc = "Code actions" }, d = { cycle_diagnostics_display, "Cycle diagnostics display" },
{ "<leader>cd", cycle_diagnostics_display, desc = "Cycle diagnostics display" }, D = { show_buffer_diagnostics, "Show buffer diagnostics" },
{ "<leader>cD", show_buffer_diagnostics, desc = "Show buffer diagnostics" }, r = { vim.lsp.buf.rename, "Rename symbol" },
{ "<leader>cr", vim.lsp.buf.rename, desc = "Rename symbol" }, s = { vim.lsp.buf.signature_help, "Show signature" },
{ "<leader>cs", vim.lsp.buf.signature_help, desc = "Show signature" }, t = { vim.lsp.buf.type_definition, "Go to type definition" },
{ "<leader>ct", vim.lsp.buf.type_definition, desc = "Go to type definition" }, w = {
-- Workspace name = "Workspace",
{ "<leader>cw", group = "Workspace" }, a = { vim.lsp.buf.add_workspace_folder, "Add folder to workspace" },
{ "<leader>cwa", vim.lsp.buf.add_workspace_folder, desc = "Add folder to workspace" }, l = { list_workspace_folders, "List folders in workspace" },
{ "<leader>cwl", list_workspace_folders, desc = "List folders in workspace" }, r = { vim.lsp.buf.remove_workspace_folder, "Remove folder from workspace" },
{ "<leader>cwr", vim.lsp.buf.remove_workspace_folder, desc = "Remove folder from workspace" }, },
},
} }
wk.add(keys) wk.register(keys, { buffer = bufnr })
end end
return M return M

View file

@ -48,22 +48,4 @@ M.list_lsp_clients = function(bufnr)
return names return names
end end
--- partially apply a function with given arguments
M.partial = function(f, ...)
local a = { ... }
local a_len = select("#", ...)
return function(...)
local tmp = { ... }
local tmp_len = select("#", ...)
-- Merge arg lists
for i = 1, tmp_len do
a[a_len + i] = tmp[i]
end
return f(unpack(a, 1, a_len + tmp_len))
end
end
return M return M

View file

@ -7,28 +7,17 @@ local numbertoggle = vim.api.nvim_create_augroup("numbertoggle", { clear = true
vim.api.nvim_create_autocmd({ "BufEnter", "FocusGained", "InsertLeave", "WinEnter" }, { vim.api.nvim_create_autocmd({ "BufEnter", "FocusGained", "InsertLeave", "WinEnter" }, {
pattern = "*", pattern = "*",
group = numbertoggle, group = numbertoggle,
callback = function() command = "if &nu | setlocal rnu | endif",
if vim.opt.number:get() then
vim.opt.relativenumber = true
end
end,
}) })
vim.api.nvim_create_autocmd({ "BufLeave", "FocusLost", "InsertEnter", "WinLeave" }, { vim.api.nvim_create_autocmd({ "BufLeave", "FocusLost", "InsertEnter", "WinLeave" }, {
pattern = "*", pattern = "*",
group = numbertoggle, group = numbertoggle,
callback = function() command = "if &nu | setlocal nornu | endif",
if vim.opt.number:get() then
vim.opt.relativenumber = false
end
end,
}) })
-- Never show the sign column in a terminal buffer -- Never show the sign column in a terminal buffer
vim.api.nvim_create_autocmd({ "TermOpen" }, { vim.api.nvim_create_autocmd({ "TermOpen" }, {
pattern = "*", pattern = "*",
group = numbertoggle, group = numbertoggle,
callback = function() command = "setlocal nonu nornu",
vim.opt.number = false
vim.opt.relativenumber = false
end,
}) })

View file

@ -1,75 +1,58 @@
local gitsigns = require("gitsigns") local gitsigns = require("gitsigns")
local utils = require("ambroisie.utils")
local wk = require("which-key") local wk = require("which-key")
--- Transform `f` into a function which acts on the current visual selection
local function make_visual(f)
return function()
local first = vim.fn.line("v")
local last = vim.fn.line(".")
f({ first, last })
end
end
local function nav_hunk(dir)
if vim.wo.diff then
local map = {
prev = "[c",
next = "]c",
}
vim.cmd.normal({ map[dir], bang = true })
else
gitsigns.nav_hunk(dir)
end
end
gitsigns.setup({ gitsigns.setup({
current_line_blame_opts = { current_line_blame_opts = {
-- Show the blame quickly -- Show the blame quickly
delay = 100, delay = 100,
}, },
-- Work-around for https://github.com/lewis6991/gitsigns.nvim/issues/929
signs_staged_enable = false,
}) })
local keys = { local keys = {
-- Navigation -- Navigation
{ "[c", utils.partial(nav_hunk, "prev"), desc = "Previous hunk/diff" }, ["[c"] = { "&diff ? '[c' : '<cmd>Gitsigns prev_hunk<CR>'", "Previous hunk/diff", expr = true },
{ "]c", utils.partial(nav_hunk, "next"), desc = "Next hunk/diff" }, ["]c"] = { "&diff ? ']c' : '<cmd>Gitsigns next_hunk<CR>'", "Next hunk/diff", expr = true },
-- Commands -- Commands
{ "<leader>g", group = "Git" }, ["<leader>g"] = {
{ "<leader>gb", gitsigns.toggle_current_line_blame, desc = "Toggle blame virtual text" }, name = "Git",
{ "<leader>gd", gitsigns.diffthis, desc = "Diff buffer" }, -- Actions
{ "<leader>gD", utils.partial(gitsigns.diffthis, "~"), desc = "Diff buffer against last commit" }, b = { gitsigns.toggle_current_line_blame, "Toggle blame virtual text" },
{ "<leader>gg", "<cmd>Git<CR>", desc = "Git status" }, d = { gitsigns.diffthis, "Diff buffer" },
{ "<leader>gh", gitsigns.toggle_deleted, desc = "Show deleted hunks" }, -- stylua: ignore
{ "<leader>gL", "<cmd>:sp<CR><C-w>T:Gllog --follow -- %:p<CR>", desc = "Current buffer log" }, D = { function() gitsigns.diffthis("~") end, "Diff buffer against last commit" },
{ "<leader>gm", "<Plug>(git-messenger)", desc = "Current line blame" }, g = { "<cmd>Git<CR>", "Git status" },
{ "<leader>gp", gitsigns.preview_hunk, desc = "Preview hunk" }, h = { gitsigns.toggle_deleted, "Show deleted hunks" },
{ "<leader>gr", gitsigns.reset_hunk, desc = "Restore hunk" }, L = { "<cmd>:sp<CR><C-w>T:Gllog --follow -- %:p<CR>", "Current buffer log" },
{ "<leader>gR", gitsigns.reset_buffer, desc = "Restore buffer" }, m = { "<Plug>(git-messenger)", "Current line blame" },
{ "<leader>gs", gitsigns.stage_hunk, desc = "Stage hunk" }, p = { gitsigns.preview_hunk, "Preview hunk" },
{ "<leader>gS", gitsigns.stage_buffer, desc = "Stage buffer" }, r = { gitsigns.reset_hunk, "Restore hunk" },
{ "<leader>gu", gitsigns.undo_stage_hunk, desc = "Undo stage hunk" }, R = { gitsigns.reset_buffer, "Restore buffer" },
{ "<leader>g[", utils.partial(gitsigns.nav_hunk, "prev"), desc = "Previous hunk" }, s = { gitsigns.stage_hunk, "Stage hunk" },
{ "<leader>g]", utils.partial(gitsigns.nav_hunk, "next"), desc = "Next hunk" }, S = { gitsigns.stage_buffer, "Stage buffer" },
u = { gitsigns.undo_stage_hunk, "Undo stage hunk" },
["["] = { gitsigns.prev_hunk, "Previous hunk" },
["]"] = { gitsigns.next_hunk, "Next hunk" },
},
} }
local objects = { local objects = {
mode = "o", ["ih"] = { gitsigns.select_hunk, "Git hunk" },
{ "ih", gitsigns.select_hunk, desc = "Git hunk" },
}
-- Visual
local visual = {
mode = { "x" },
{ "ih", gitsigns.select_hunk, desc = "Git hunk" },
{ "<leader>g", group = "Git" },
{ "<leader>gp", gitsigns.preview_hunk, desc = "Preview selection" },
{ "<leader>gr", make_visual(gitsigns.reset_hunk), desc = "Restore selection" },
{ "<leader>gs", make_visual(gitsigns.stage_hunk), desc = "Stage selection" },
{ "<leader>gu", gitsigns.undo_stage_hunk, desc = "Undo stage selection" },
} }
wk.add(keys) local visual = {
wk.add(objects) ["ih"] = { gitsigns.select_hunk, "Git hunk" },
wk.add(visual)
-- Only the actual command can make use of the visual selection...
["<leader>g"] = {
name = "Git",
p = { ":Gitsigns preview_hunk<CR>", "Preview selection" },
r = { ":Gitsigns reset_hunk<CR>", "Restore selection" },
s = { ":Gitsigns stage_hunk<CR>", "Stage selection" },
u = { ":Gitsigns undo_stage_hunk<CR>", "Undo stage selection" },
},
}
wk.register(keys, { buffer = bufnr })
wk.register(objects, { buffer = bufnr, mode = "o" })
wk.register(visual, { buffer = bufnr, mode = "x" })

View file

@ -53,8 +53,8 @@ if utils.is_executable("pyright") then
}) })
end end
if utils.is_executable("ruff") then if utils.is_executable("ruff-lsp") then
lspconfig.ruff.setup({ lspconfig.ruff_lsp.setup({
capabilities = capabilities, capabilities = capabilities,
on_attach = lsp.on_attach, on_attach = lsp.on_attach,
}) })
@ -74,31 +74,5 @@ if utils.is_executable("bash-language-server") then
filetypes = { "bash", "sh", "zsh" }, filetypes = { "bash", "sh", "zsh" },
capabilities = capabilities, capabilities = capabilities,
on_attach = lsp.on_attach, on_attach = lsp.on_attach,
settings = {
bashIde = {
shfmt = {
-- Simplify the code
simplifyCode = true,
-- Indent switch cases
caseIndent = true,
},
},
},
})
end
-- Starlark
if utils.is_executable("starpls") then
lspconfig.starpls.setup({
capabilities = capabilities,
on_attach = lsp.on_attach,
})
end
-- Generic
if utils.is_executable("typos-lsp") then
lspconfig.typos_lsp.setup({
capabilities = capabilities,
on_attach = lsp.on_attach,
}) })
end end

View file

@ -18,6 +18,16 @@ null_ls.register({
}), }),
}) })
-- C, C++
null_ls.register({
null_ls.builtins.formatting.clang_format.with({
-- Only used if available, but prefer clangd formatting if available
condition = function()
return utils.is_executable("clang-format") and not utils.is_executable("clangd")
end,
}),
})
-- Nix -- Nix
null_ls.register({ null_ls.register({
null_ls.builtins.formatting.nixpkgs_fmt.with({ null_ls.builtins.formatting.nixpkgs_fmt.with({
@ -46,3 +56,29 @@ null_ls.register({
condition = utils.is_executable_condition("isort"), condition = utils.is_executable_condition("isort"),
}), }),
}) })
-- Shell (non-POSIX)
null_ls.register({
null_ls.builtins.formatting.shfmt.with({
-- Indent with 4 spaces, simplify the code, indent switch cases,
-- add space after redirection, use bash dialect
extra_args = { "-i", "4", "-s", "-ci", "-sr", "-ln", "bash" },
-- Restrict to bash and zsh
filetypes = { "bash", "zsh" },
-- Only used if available
condition = utils.is_executable_condition("shfmt"),
}),
})
-- Shell (POSIX)
null_ls.register({
null_ls.builtins.formatting.shfmt.with({
-- Indent with 4 spaces, simplify the code, indent switch cases,
-- add space after redirection, use POSIX
extra_args = { "-i", "4", "-s", "-ci", "-sr", "-ln", "posix" },
-- Restrict to POSIX sh
filetypes = { "sh" },
-- Only used if available
condition = utils.is_executable_condition("shfmt"),
}),
})

View file

@ -1,34 +0,0 @@
local oil = require("oil")
local wk = require("which-key")
local detail = false
oil.setup({
view_options = {
-- Show files and directories that start with "." by default
show_hidden = true,
-- But never '..'
is_always_hidden = function(name, bufnr)
return name == ".."
end,
},
keymaps = {
["gd"] = {
desc = "Toggle file detail view",
callback = function()
detail = not detail
if detail then
oil.set_columns({ "icon", "permissions", "size", "mtime" })
else
oil.set_columns({ "icon" })
end
end,
},
},
})
local keys = {
{ "-", oil.open, desc = "Open parent directory" },
}
wk.add(keys)

View file

@ -0,0 +1,17 @@
if not require("ambroisie.utils").is_ssh() then
return
end
local function copy(lines, _)
require("osc52").copy(table.concat(lines, "\n"))
end
local function paste()
return { vim.fn.split(vim.fn.getreg(""), "\n"), vim.fn.getregtype("") }
end
vim.g.clipboard = {
name = "osc52",
copy = { ["+"] = copy, ["*"] = copy },
paste = { ["+"] = paste, ["*"] = paste },
}

View file

@ -1,6 +1,4 @@
local telescope = require("telescope") local telescope = require("telescope")
local telescope_builtin = require("telescope.builtin")
local wk = require("which-key")
telescope.setup({ telescope.setup({
defaults = { defaults = {
@ -24,14 +22,3 @@ telescope.setup({
telescope.load_extension("fzf") telescope.load_extension("fzf")
telescope.load_extension("lsp_handlers") telescope.load_extension("lsp_handlers")
local keys = {
{ "<leader>f", group = "Fuzzy finder" },
{ "<leader>fb", telescope_builtin.buffers, desc = "Open buffers" },
{ "<leader>ff", telescope_builtin.git_files, desc = "Git tracked files" },
{ "<leader>fF", telescope_builtin.find_files, desc = "Files" },
{ "<leader>fg", telescope_builtin.live_grep, desc = "Grep string" },
{ "<leader>fG", telescope_builtin.grep_string, desc = "Grep string under cursor" },
}
wk.add(keys)

View file

@ -1,5 +1,4 @@
local ts_config = require("nvim-treesitter.configs") local ts_config = require("nvim-treesitter.configs")
ts_config.setup({ ts_config.setup({
highlight = { highlight = {
enable = true, enable = true,
@ -15,16 +14,16 @@ ts_config.setup({
-- Jump to matching text objects -- Jump to matching text objects
lookahead = true, lookahead = true,
keymaps = { keymaps = {
["aa"] = { query = "@parameter.outer", desc = "a parameter" }, ["aa"] = "@parameter.outer",
["ia"] = { query = "@parameter.inner", desc = "inner parameter" }, ["ia"] = "@parameter.inner",
["ab"] = { query = "@block.outer", desc = "a block" }, ["ab"] = "@block.outer",
["ib"] = { query = "@block.inner", desc = "inner block" }, ["ib"] = "@block.inner",
["ac"] = { query = "@class.outer", desc = "a class" }, ["ac"] = "@class.outer",
["ic"] = { query = "@class.inner", desc = "inner class" }, ["ic"] = "@class.inner",
["af"] = { query = "@function.outer", desc = "a function" }, ["af"] = "@function.outer",
["if"] = { query = "@function.inner", desc = "inner function" }, ["if"] = "@function.inner",
["ak"] = { query = "@comment.outer", desc = "a comment" }, ["ak"] = "@comment.outer",
["aS"] = { query = "@statement.outer", desc = "a statement" }, ["aS"] = "@statement.outer",
}, },
}, },
move = { move = {
@ -32,22 +31,22 @@ ts_config.setup({
-- Add to jump list -- Add to jump list
set_jumps = true, set_jumps = true,
goto_next_start = { goto_next_start = {
["]m"] = { query = "@function.outer", desc = "Next method start" }, ["]m"] = "@function.outer",
["]S"] = { query = "@statement.outer", desc = "Next statement start" }, ["]S"] = "@statement.outer",
["]]"] = { query = "@class.outer", desc = "Next class start" }, ["]]"] = "@class.outer",
}, },
goto_next_end = { goto_next_end = {
["]M"] = { query = "@function.outer", desc = "Next method end" }, ["]M"] = "@function.outer",
["]["] = { query = "@class.outer", desc = "Next class end" }, ["]["] = "@class.outer",
}, },
goto_previous_start = { goto_previous_start = {
["[m"] = { query = "@function.outer", desc = "Previous method start" }, ["[m"] = "@function.outer",
["[S"] = { query = "@statement.outer", desc = "Previous statement start" }, ["[S"] = "@statement.outer",
["[["] = { query = "@class.outer", desc = "Previous class start" }, ["[["] = "@class.outer",
}, },
goto_previous_end = { goto_previous_end = {
["[M"] = { query = "@function.outer", desc = "Previous method end" }, ["[M"] = "@function.outer",
["[]"] = { query = "@class.outer", desc = "Previous class end" }, ["[]"] = "@class.outer",
}, },
}, },
}, },

View file

@ -1,33 +1,2 @@
local wk = require("which-key") local wk = require("which-key")
wk.setup({ wk.setup()
icons = {
-- I don't like icons
mappings = false,
breadcrumb = "»",
separator = "",
group = "+",
ellipsis = "",
keys = {
Up = "",
Down = "",
Left = "",
Right = "",
C = "<C>",
M = "<M>",
D = "<D>",
S = "<S>",
CR = "<CR>",
Esc = "<Esc> ",
NL = "<NL>",
BS = "<BS>",
Space = "<space>",
Tab = "<Tab> ",
},
},
})
local keys = {
{ "<leader><leader>", vim.cmd.nohlsearch, desc = "Clear search highlight" },
}
wk.add(keys)

View file

@ -4,23 +4,17 @@ local signtoggle = vim.api.nvim_create_augroup("signtoggle", { clear = true })
vim.api.nvim_create_autocmd({ "BufEnter", "FocusGained", "WinEnter" }, { vim.api.nvim_create_autocmd({ "BufEnter", "FocusGained", "WinEnter" }, {
pattern = "*", pattern = "*",
group = signtoggle, group = signtoggle,
callback = function() command = "setlocal signcolumn=yes",
vim.opt.signcolumn = "yes"
end,
}) })
vim.api.nvim_create_autocmd({ "BufLeave", "FocusLost", "WinLeave" }, { vim.api.nvim_create_autocmd({ "BufLeave", "FocusLost", "WinLeave" }, {
pattern = "*", pattern = "*",
group = signtoggle, group = signtoggle,
callback = function() command = "setlocal signcolumn=yes",
vim.opt.signcolumn = "no"
end,
}) })
-- Never show the sign column in a terminal buffer -- Never show the sign column in a terminal buffer
vim.api.nvim_create_autocmd({ "TermOpen" }, { vim.api.nvim_create_autocmd({ "TermOpen" }, {
pattern = "*", pattern = "*",
group = signtoggle, group = signtoggle,
callback = function() command = "setlocal signcolumn=no",
vim.opt.signcolumn = "no"
end,
}) })

View file

@ -20,7 +20,7 @@ in
}; };
xdg.configFile."wgetrc".text = '' xdg.configFile."wgetrc".text = ''
hsts-file = ${config.xdg.stateHome}/wget-hsts hsts-file = ${config.xdg.dataHome}/wget-hsts
''; '';
}; };
} }

View file

@ -58,7 +58,7 @@ in
service = "some-service-name"; service = "some-service-name";
} }
]; ];
description = "list of block configurations, merged with the defaults"; description = "list of block configurations, merged with the defauls";
}; };
}; };
}; };

View file

@ -127,10 +127,9 @@ in
{ class = "^Blueman-.*$"; } { class = "^Blueman-.*$"; }
{ title = "^htop$"; } { title = "^htop$"; }
{ class = "^Thunderbird$"; instance = "Mailnews"; window_role = "filterlist"; } { class = "^Thunderbird$"; instance = "Mailnews"; window_role = "filterlist"; }
{ class = "^pavucontrol.*$"; } { class = "^Pavucontrol.*$"; }
{ class = "^Arandr$"; } { class = "^Arandr$"; }
{ class = "^\\.blueman-manager-wrapped$"; } { class = ".?blueman-manager.*$"; }
{ class = "^\\.arandr-wrapped$"; }
]; ];
}; };
@ -372,7 +371,8 @@ in
}; };
startup = [ startup = [
# NOTE: rely on systemd user services instead... # FIXME
# { commdand; always; notification; }
]; ];
window = { window = {

View file

@ -2,7 +2,7 @@
let let
cfg = config.my.home.wm.screen-lock; cfg = config.my.home.wm.screen-lock;
notificationCmd = notficationCmd =
let let
duration = toString (cfg.notify.delay * 1000); duration = toString (cfg.notify.delay * 1000);
notifyCmd = "${lib.getExe pkgs.libnotify} -u critical -t ${duration}"; notifyCmd = "${lib.getExe pkgs.libnotify} -u critical -t ${duration}";
@ -48,7 +48,7 @@ in
"-notify" "-notify"
"${toString cfg.notify.delay}" "${toString cfg.notify.delay}"
"-notifier" "-notifier"
notificationCmd notficationCmd
]; ];
}; };
}; };

View file

@ -11,7 +11,7 @@ in
enable = true; enable = true;
# File types # File types
mime.enable = true; mime.enable = true;
# File associations # File associatons
mimeApps = { mimeApps = {
enable = true; enable = true;
}; };
@ -30,11 +30,9 @@ in
}; };
# A tidy home is a tidy mind # A tidy home is a tidy mind
dataFile = { dataFile = {
"tig/.keep".text = ""; # `tig` uses `XDG_DATA_HOME` specifically...
};
stateFile = {
"bash/.keep".text = ""; "bash/.keep".text = "";
"python/.keep".text = ""; "gdb/.keep".text = "";
"tig/.keep".text = "";
}; };
}; };
@ -45,13 +43,13 @@ in
CARGO_HOME = "${dataHome}/cargo"; CARGO_HOME = "${dataHome}/cargo";
DOCKER_CONFIG = "${configHome}/docker"; DOCKER_CONFIG = "${configHome}/docker";
GRADLE_USER_HOME = "${dataHome}/gradle"; GRADLE_USER_HOME = "${dataHome}/gradle";
HISTFILE = "${stateHome}/bash/history"; HISTFILE = "${dataHome}/bash/history";
INPUTRC = "${configHome}/readline/inputrc"; INPUTRC = "${configHome}/readline/inputrc";
PSQL_HISTORY = "${stateHome}/psql_history"; PSQL_HISTORY = "${dataHome}/psql_history";
PYTHONPYCACHEPREFIX = "${cacheHome}/python/"; PYTHONPYCACHEPREFIX = "${cacheHome}/python/";
PYTHONUSERBASE = "${dataHome}/python/"; PYTHONUSERBASE = "${dataHome}/python/";
PYTHON_HISTORY = "${stateHome}/python/history"; PYTHON_HISTORY = "${stateHome}/python/history";
REDISCLI_HISTFILE = "${stateHome}/redis/rediscli_history"; REDISCLI_HISTFILE = "${dataHome}/redis/rediscli_history";
REPO_CONFIG_DIR = "${configHome}/repo"; REPO_CONFIG_DIR = "${configHome}/repo";
XCOMPOSECACHE = "${dataHome}/X11/xcompose"; XCOMPOSECACHE = "${dataHome}/X11/xcompose";
_JAVA_OPTIONS = "-Djava.util.prefs.userRoot=${configHome}/java"; _JAVA_OPTIONS = "-Djava.util.prefs.userRoot=${configHome}/java";

View file

@ -68,7 +68,7 @@ in
ignoreSpace = true; ignoreSpace = true;
ignoreDups = true; ignoreDups = true;
share = false; share = false;
path = "${config.xdg.stateHome}/zsh/zsh_history"; path = "${config.xdg.dataHome}/zsh/zsh_history";
}; };
plugins = [ plugins = [

View file

@ -12,7 +12,7 @@ setopt rc_quotes
setopt auto_resume setopt auto_resume
# Show history expansion before running a command # Show history expansion before running a command
setopt hist_verify setopt hist_verify
# Append commands to history as they are executed # Append commands to history as they are exectuted
setopt inc_append_history_time setopt inc_append_history_time
# Remove useless whitespace from commands # Remove useless whitespace from commands
setopt hist_reduce_blanks setopt hist_reduce_blanks

View file

@ -24,6 +24,24 @@ in
extraModules = [ pkgs.pulseaudio-modules-bt ]; extraModules = [ pkgs.pulseaudio-modules-bt ];
package = pkgs.pulseaudioFull; package = pkgs.pulseaudioFull;
}; };
services.pipewire.wireplumber.configPackages = [
(pkgs.writeTextDir "share/wireplumber/bluetooth.lua.d/51-bluez-config.lua" ''
bluez_monitor.properties = {
-- SBC XQ provides better audio
["bluez5.enable-sbc-xq"] = true,
-- mSBC provides better audio + microphone
["bluez5.enable-msbc"] = true,
-- Synchronize volume with bluetooth device
["bluez5.enable-hw-volume"] = true,
-- FIXME: Some devices may now support both hsp_ag and hfp_ag
["bluez5.headset-roles"] = "[ hsp_hs hsp_ag hfp_hf hfp_ag ]"
}
'')
];
}) })
# Support for A2DP audio profile # Support for A2DP audio profile

View file

@ -26,30 +26,28 @@ in
config = lib.mkIf cfg.enable (lib.mkMerge [ config = lib.mkIf cfg.enable (lib.mkMerge [
{ {
hardware.graphics = { hardware.opengl = {
enable = true; enable = true;
}; };
} }
# AMD GPU # AMD GPU
(lib.mkIf (cfg.gpuFlavor == "amd") { (lib.mkIf (cfg.gpuFlavor == "amd") {
hardware.amdgpu = { boot.initrd.kernelModules = lib.mkIf cfg.amd.enableKernelModule [ "amdgpu" ];
initrd.enable = cfg.amd.enableKernelModule;
# Vulkan
amdvlk = lib.mkIf cfg.amd.amdvlk {
enable = true;
support32Bit = {
enable = true;
};
};
};
hardware.graphics = { hardware.opengl = {
extraPackages = with pkgs; [ extraPackages = with pkgs; [
# OpenCL # OpenCL
rocmPackages.clr rocmPackages.clr
rocmPackages.clr.icd rocmPackages.clr.icd
]; ]
++ lib.optional cfg.amd.amdvlk amdvlk
;
extraPackages32 = with pkgs; [
]
++ lib.optional cfg.amd.amdvlk driversi686Linux.amdvlk
;
}; };
}) })
@ -61,7 +59,7 @@ in
VDPAU_DRIVER = "va_gl"; VDPAU_DRIVER = "va_gl";
}; };
hardware.graphics = { hardware.opengl = {
extraPackages = with pkgs; [ extraPackages = with pkgs; [
# Open CL # Open CL
intel-compute-runtime intel-compute-runtime
@ -71,13 +69,6 @@ in
intel-vaapi-driver intel-vaapi-driver
libvdpau-va-gl libvdpau-va-gl
]; ];
extraPackages32 = with pkgs.driversi686Linux; [
# VA API
intel-media-driver
intel-vaapi-driver
libvdpau-va-gl
];
}; };
}) })
]); ]);

View file

@ -54,6 +54,9 @@ in
# Pulseaudio setup # Pulseaudio setup
(lib.mkIf cfg.pulse.enable { (lib.mkIf cfg.pulse.enable {
# ALSA
sound.enable = true;
hardware.pulseaudio.enable = true; hardware.pulseaudio.enable = true;
}) })
]); ]);

View file

@ -11,7 +11,7 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
services.xserver = { services.xserver = {
# This section must be *after* the one configured by `libinput` # This section must be *after* the one configured by `libinput`
# for the `ScrollMethod` configuration to not be overridden # for the `ScrollMethod` configuration to not be overriden
inputClassSections = lib.mkAfter [ inputClassSections = lib.mkAfter [
# MX Ergo # MX Ergo
'' ''

View file

@ -1,4 +1,4 @@
# Configuration that spans across system and home, or are almagations of modules # Configuration that spans accross system and home, or are almagations of modules
{ ... }: { ... }:
{ {
imports = [ imports = [

View file

@ -65,7 +65,9 @@ in
aria-rpc = { aria-rpc = {
port = cfg.rpcPort; port = cfg.rpcPort;
# Proxy websockets for RPC # Proxy websockets for RPC
websocketsLocations = [ "/" ]; extraConfig = {
locations."/".proxyWebsockets = true;
};
}; };
}; };

View file

@ -30,24 +30,10 @@ in
audiobookshelf = { audiobookshelf = {
inherit (cfg) port; inherit (cfg) port;
# Proxy websockets for RPC # Proxy websockets for RPC
websocketsLocations = [ "/" ]; extraConfig = {
locations."/".proxyWebsockets = true;
}; };
}; };
services.fail2ban.jails = {
audiobookshelf = ''
enabled = true
filter = audiobookshelf
port = http,https
'';
};
environment.etc = {
"fail2ban/filter.d/audiobookshelf.conf".text = ''
[Definition]
failregex = ^.*ERROR: \[Auth\] Failed login attempt for username ".*" from ip <ADDR>
journalmatch = _SYSTEMD_UNIT=audiobookshelf.service
'';
}; };
}; };
} }

View file

@ -16,7 +16,6 @@
./grocy ./grocy
./indexers ./indexers
./jellyfin ./jellyfin
./komga
./lohr ./lohr
./matrix ./matrix
./mealie ./mealie
@ -27,7 +26,7 @@
./nginx ./nginx
./nix-cache ./nix-cache
./paperless ./paperless
./pdf-edit ./pirate
./podgrab ./podgrab
./postgresql ./postgresql
./postgresql-backup ./postgresql-backup
@ -35,7 +34,6 @@
./quassel ./quassel
./rss-bridge ./rss-bridge
./sabnzbd ./sabnzbd
./servarr
./ssh-server ./ssh-server
./tandoor-recipes ./tandoor-recipes
./tlp ./tlp

View file

@ -1,5 +1,5 @@
# A nice UI for various torrent clients # A nice UI for various torrent clients
{ config, lib, ... }: { config, lib, pkgs, ... }:
let let
cfg = config.my.services.flood; cfg = config.my.services.flood;
in in
@ -13,13 +13,31 @@ in
example = 3000; example = 3000;
description = "Internal port for Flood UI"; description = "Internal port for Flood UI";
}; };
stateDir = mkOption {
type = types.str;
default = "flood";
example = "floodUI";
description = "Directory under `/var/run` for storing Flood's files";
};
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
services.flood = { systemd.services.flood = {
enable = true; description = "Flood torrent UI";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
inherit (cfg) port; serviceConfig = {
ExecStart = lib.concatStringsSep " " [
(lib.getExe pkgs.flood)
"--port ${builtins.toString cfg.port}"
"--rundir /var/lib/${cfg.stateDir}"
];
DynamicUser = true;
StateDirectory = cfg.stateDir;
ReadWritePaths = "";
};
}; };
my.services.nginx.virtualHosts = { my.services.nginx.virtualHosts = {
@ -27,7 +45,5 @@ in
inherit (cfg) port; inherit (cfg) port;
}; };
}; };
# NOTE: unfortunately flood does not log connection failures for fail2ban
}; };
} }

View file

@ -1,4 +1,4 @@
# A low-resource, full-featured git forge. # A low-ressource, full-featured git forge.
{ config, lib, ... }: { config, lib, ... }:
let let
cfg = config.my.services.forgejo; cfg = config.my.services.forgejo;
@ -83,11 +83,7 @@ in
# I configure my backup system manually below. # I configure my backup system manually below.
dump.enable = false; dump.enable = false;
secrets = { mailerPasswordFile = lib.mkIf cfg.mail.enable cfg.mail.passwordFile;
mailer = lib.mkIf cfg.mail.enable {
PASSWD = cfg.mail.passwordFile;
};
};
settings = { settings = {
DEFAULT = { DEFAULT = {

View file

@ -1,4 +1,4 @@
# A low-resource, full-featured git forge. # A low-ressource, full-featured git forge.
{ config, lib, ... }: { config, lib, ... }:
let let
cfg = config.my.services.gitea; cfg = config.my.services.gitea;

View file

@ -36,7 +36,5 @@ in
forceSSL = true; forceSSL = true;
useACMEHost = config.networking.domain; useACMEHost = config.networking.domain;
}; };
# NOTE: unfortunately grocy does not log connection failures for fail2ban
}; };
} }

View file

@ -27,31 +27,19 @@ in
my.services.nginx.virtualHosts = { my.services.nginx.virtualHosts = {
jellyfin = { jellyfin = {
port = 8096; port = 8096;
websocketsLocations = [ "/socket" ];
extraConfig = { extraConfig = {
locations."/" = { locations."/" = {
extraConfig = '' extraConfig = ''
proxy_buffering off; proxy_buffering off;
''; '';
}; };
# Too bad for the repetition...
locations."/socket" = {
proxyPass = "http://127.0.0.1:8096/";
proxyWebsockets = true;
}; };
}; };
}; };
services.fail2ban.jails = {
jellyfin = ''
enabled = true
filter = jellyfin
port = http,https
'';
};
environment.etc = {
"fail2ban/filter.d/jellyfin.conf".text = ''
[Definition]
failregex = ^.*Authentication request for .* has been denied \(IP: "?<ADDR>"?\)\.
journalmatch = _SYSTEMD_UNIT=jellyfin.service
'';
}; };
}; };
} }

View file

@ -1,55 +0,0 @@
# A Comics/Manga media server
{ config, lib, ... }:
let
cfg = config.my.services.komga;
in
{
options.my.services.komga = with lib; {
enable = mkEnableOption "Komga comics server";
port = mkOption {
type = types.port;
default = 4584;
example = 8080;
description = "Internal port for webui";
};
};
config = lib.mkIf cfg.enable {
services.komga = {
enable = true;
inherit (cfg) port;
group = "media";
};
systemd.services.komga.environment = {
LOGGING_LEVEL_ORG_GOTSON_KOMGA = "DEBUG"; # Needed for fail2ban
};
# Set-up media group
users.groups.media = { };
my.services.nginx.virtualHosts = {
komga = {
inherit (cfg) port;
};
};
services.fail2ban.jails = {
komga = ''
enabled = true
filter = komga
port = http,https
'';
};
environment.etc = {
"fail2ban/filter.d/komga.conf".text = ''
[Definition]
failregex = ^.* ip=<HOST>,.*Bad credentials.*$
journalmatch = _SYSTEMD_UNIT=komga.service
'';
};
};
}

View file

@ -26,6 +26,21 @@ in
description = "Shared secret to register users"; description = "Shared secret to register users";
}; };
slidingSync = {
port = mkOption {
type = types.port;
default = 8009;
example = 8084;
description = "Port used by sliding sync server";
};
secretFile = mkOption {
type = types.str;
example = "/var/lib/matrix/sliding-sync-secret-file.env";
description = "Secret file which contains SYNCV3_SECRET definition";
};
};
mailConfigFile = mkOption { mailConfigFile = mkOption {
type = types.str; type = types.str;
example = "/var/lib/matrix/email-config.yaml"; example = "/var/lib/matrix/email-config.yaml";
@ -91,6 +106,17 @@ in
] ++ lib.optional (cfg.secretFile != null) cfg.secretFile; ] ++ lib.optional (cfg.secretFile != null) cfg.secretFile;
}; };
services.matrix-sliding-sync = {
enable = true;
settings = {
SYNCV3_SERVER = "https://${matrixDomain}";
SYNCV3_BINDADDR = "127.0.0.1:${toString cfg.slidingSync.port}";
};
environmentFile = cfg.slidingSync.secretFile;
};
my.services.nginx.virtualHosts = { my.services.nginx.virtualHosts = {
# Element Web app deployment # Element Web app deployment
chat = { chat = {
@ -104,6 +130,9 @@ in
"m.identity_server" = { "m.identity_server" = {
"base_url" = "https://vector.im"; "base_url" = "https://vector.im";
}; };
"org.matrix.msc3575.proxy" = {
"url" = "https://matrix-sync.${domain}";
};
}; };
showLabsSettings = true; showLabsSettings = true;
defaultCountryCode = "FR"; # cocorico defaultCountryCode = "FR"; # cocorico
@ -123,6 +152,10 @@ in
matrix-client = { matrix-client = {
port = clientPort.private; port = clientPort.private;
}; };
# Sliding sync
matrix-sync = {
inherit (cfg.slidingSync) port;
};
}; };
# Those are too complicated to use my wrapper... # Those are too complicated to use my wrapper...
@ -145,6 +178,11 @@ in
"/_matrix" = proxyToClientPort; "/_matrix" = proxyToClientPort;
"/_synapse/client" = proxyToClientPort; "/_synapse/client" = proxyToClientPort;
# Sliding sync
"~ ^/(client/|_matrix/client/unstable/org.matrix.msc3575/sync)" = {
proxyPass = "http://${config.services.matrix-sliding-sync.settings.SYNCV3_BINDADDR}";
};
}; };
listen = [ listen = [
@ -190,6 +228,7 @@ in
client = { client = {
"m.homeserver" = { "base_url" = "https://${matrixDomain}"; }; "m.homeserver" = { "base_url" = "https://${matrixDomain}"; };
"m.identity_server" = { "base_url" = "https://vector.im"; }; "m.identity_server" = { "base_url" = "https://vector.im"; };
"org.matrix.msc3575.proxy" = { "url" = "https://matrix-sync.${domain}"; };
}; };
# ACAO required to allow element-web on any URL to request this json file # ACAO required to allow element-web on any URL to request this json file
in in

View file

@ -35,8 +35,12 @@ in
# Use PostgreSQL # Use PostgreSQL
DB_ENGINE = "postgres"; DB_ENGINE = "postgres";
# Make it work with socket auth POSTGRES_USER = "mealie";
POSTGRES_URL_OVERRIDE = "postgresql://mealie:@/mealie?host=/run/postgresql"; POSTGRES_PASSWORD = "";
POSTGRES_SERVER = "/run/postgresql";
# Pydantic and/or mealie doesn't handle the URI correctly, hijack it
# with query parameters...
POSTGRES_DB = "mealie?host=/run/postgresql&dbname=mealie";
}; };
}; };
@ -71,21 +75,5 @@ in
}; };
}; };
}; };
services.fail2ban.jails = {
mealie = ''
enabled = true
filter = mealie
port = http,https
'';
};
environment.etc = {
"fail2ban/filter.d/mealie.conf".text = ''
[Definition]
failregex = ^.*ERROR.*Incorrect username or password from <HOST>
journalmatch = _SYSTEMD_UNIT=mealie.service
'';
};
}; };
} }

View file

@ -48,21 +48,5 @@ in
inherit (cfg) port; inherit (cfg) port;
}; };
}; };
services.fail2ban.jails = {
miniflux = ''
enabled = true
filter = miniflux
port = http,https
'';
};
environment.etc = {
"fail2ban/filter.d/miniflux.conf".text = ''
[Definition]
failregex = ^.*msg="[^"]*(Incorrect|Invalid) username or password[^"]*".*client_ip=<ADDR>
journalmatch = _SYSTEMD_UNIT=miniflux.service
'';
};
}; };
} }

View file

@ -52,21 +52,5 @@ in
inherit (cfg) port; inherit (cfg) port;
}; };
}; };
services.fail2ban.jails = {
navidrome = ''
enabled = true
filter = navidrome
port = http,https
'';
};
environment.etc = {
"fail2ban/filter.d/navidrome.conf".text = ''
[Definition]
failregex = ^.*msg="Unsuccessful login".*X-Real-Ip:\[<HOST>\]
journalmatch = _SYSTEMD_UNIT=navidrome.service
'';
};
}; };
} }

View file

@ -1,50 +0,0 @@
# Document editor with Nextcloud
{ config, lib, ... }:
let
cfg = config.my.services.nextcloud.collabora;
in
{
options.my.services.nextcloud.collabora = with lib; {
enable = mkEnableOption "Collabora integration";
port = mkOption {
type = types.port;
default = 9980;
example = 8080;
description = "Internal port for API";
};
};
config = lib.mkIf cfg.enable {
services.collabora-online = {
enable = true;
inherit (cfg) port;
aliasGroups = [
{
host = "https://collabora.${config.networking.domain}";
# Allow using from nextcloud
aliases = [ "https://${config.services.nextcloud.hostName}" ];
}
];
settings = {
# Rely on reverse proxy for SSL
ssl = {
enable = false;
termination = true;
};
};
};
my.services.nginx.virtualHosts = {
collabora = {
inherit (cfg) port;
websocketsLocations = [
"~ ^/cool/(.*)/ws$"
"^~ /cool/adminws"
];
};
};
};
}

View file

@ -4,10 +4,6 @@ let
cfg = config.my.services.nextcloud; cfg = config.my.services.nextcloud;
in in
{ {
imports = [
./collabora.nix
];
options.my.services.nextcloud = with lib; { options.my.services.nextcloud = with lib; {
enable = mkEnableOption "Nextcloud"; enable = mkEnableOption "Nextcloud";
maxSize = mkOption { maxSize = mkOption {
@ -35,7 +31,7 @@ in
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
services.nextcloud = { services.nextcloud = {
enable = true; enable = true;
package = pkgs.nextcloud30; package = pkgs.nextcloud29;
hostName = "nextcloud.${config.networking.domain}"; hostName = "nextcloud.${config.networking.domain}";
home = "/var/lib/nextcloud"; home = "/var/lib/nextcloud";
maxUploadSize = cfg.maxSize; maxUploadSize = cfg.maxSize;
@ -91,25 +87,5 @@ in
"${config.services.nextcloud.home}/data/appdata_*/preview" "${config.services.nextcloud.home}/data/appdata_*/preview"
]; ];
}; };
services.fail2ban.jails = {
nextcloud = ''
enabled = true
filter = nextcloud
port = http,https
'';
};
environment.etc = {
"fail2ban/filter.d/nextcloud.conf".text = ''
[Definition]
_groupsre = (?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*)
datepattern = ,?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?"
failregex = ^[^{]*\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Login failed:
^[^{]*\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Trusted domain error.
^[^{]*\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Two-factor challenge failed:
journalmatch = _SYSTEMD_UNIT=phpfpm-nextcloud.service
'';
};
}; };
} }

View file

@ -17,16 +17,6 @@ let
''; '';
}; };
websocketsLocations = mkOption {
type = with types; listOf str;
default = [ ];
example = [ "/socket" ];
description = ''
Which locations on this virtual host should be configured for
websockets.
'';
};
port = mkOption { port = mkOption {
type = with types; nullOr port; type = with types; nullOr port;
default = null; default = null;
@ -69,15 +59,14 @@ let
extraConfig = mkOption { extraConfig = mkOption {
type = types.attrs; # FIXME: forward type of virtualHosts type = types.attrs; # FIXME: forward type of virtualHosts
example = { example = litteralExample ''
extraConfig = '' {
add_header X-Clacks-Overhead "GNU Terry Pratchett"; locations."/socket" = {
''; proxyPass = "http://127.0.0.1:8096/";
proxyWebsockets = true;
locations."/".extraConfig = ''
client_max_body_size 1G;
'';
}; };
}
'';
default = { }; default = { };
description = '' description = ''
Any extra configuration that should be applied to this virtual host. Any extra configuration that should be applied to this virtual host.
@ -99,7 +88,7 @@ in
type = types.str; type = types.str;
example = "/var/lib/acme/creds.env"; example = "/var/lib/acme/creds.env";
description = '' description = ''
OVH API key file as an 'EnvironmentFile' (see `systemd.exec(5)`) Gandi API key file as an 'EnvironmentFile' (see `systemd.exec(5)`)
''; '';
}; };
}; };
@ -111,7 +100,8 @@ in
virtualHosts = mkOption { virtualHosts = mkOption {
type = types.attrsOf virtualHostOption; type = types.attrsOf virtualHostOption;
default = { }; default = { };
example = { example = litteralExample ''
{
gitea = { gitea = {
subdomain = "git"; subdomain = "git";
port = 8080; port = 8080;
@ -121,9 +111,15 @@ in
}; };
jellyfin = { jellyfin = {
port = 8096; port = 8096;
websocketsLocations = [ "/socket" ]; extraConfig = {
locations."/socket" = {
proxyPass = "http://127.0.0.1:8096/";
proxyWebsockets = true;
}; };
}; };
};
}
'';
description = '' description = ''
List of virtual hosts to set-up using default settings. List of virtual hosts to set-up using default settings.
''; '';
@ -167,21 +163,25 @@ in
}; };
}; };
}); });
example = { example = litteralExample ''
{
alice = { alice = {
passwordHashFile = "/var/lib/nginx-sso/alice/password-hash.txt"; passwordHashFile = "/var/lib/nginx-sso/alice/password-hash.txt";
totpSecretFile = "/var/lib/nginx-sso/alice/totp-secret.txt"; totpSecretFile = "/var/lib/nginx-sso/alice/totp-secret.txt";
}; };
}; }
'';
description = "Definition of users"; description = "Definition of users";
}; };
groups = mkOption { groups = mkOption {
type = with types; attrsOf (listOf str); type = with types; attrsOf (listOf str);
example = { example = litteralExample ''
{
root = [ "alice" ]; root = [ "alice" ];
users = [ "alice" "bob" ]; users = [ "alice" "bob" ];
}; }
'';
description = "Groups of users"; description = "Groups of users";
}; };
}; };
@ -203,19 +203,6 @@ in
} configured. } configured.
''; '';
})) }))
++ (lib.flip lib.mapAttrsToList cfg.virtualHosts (_: { subdomain, ... } @ args:
let
proxyPass = [ "port" "socket" ];
proxyPassUsed = lib.any (v: args.${v} != null) proxyPass;
in
{
assertion = args.websocketsLocations != [ ] -> proxyPassUsed;
message = ''
Subdomain '${subdomain}' can only use 'websocketsLocations' with one of ${
lib.concatStringsSep ", " (builtins.map (v: "'${v}'") proxyPass)
}.
'';
}))
++ ( ++ (
let let
ports = lib.my.mapFilter ports = lib.my.mapFilter
@ -262,14 +249,6 @@ in
virtualHosts = virtualHosts =
let let
domain = config.networking.domain; domain = config.networking.domain;
mkProxyPass = { websocketsLocations, ... }: proxyPass:
let
websockets = lib.genAttrs websocketsLocations (_: {
inherit proxyPass;
proxyWebsockets = true;
});
in
{ "/" = { inherit proxyPass; }; } // websockets;
mkVHost = ({ subdomain, ... } @ args: lib.nameValuePair mkVHost = ({ subdomain, ... } @ args: lib.nameValuePair
"${subdomain}.${domain}" "${subdomain}.${domain}"
(lib.my.recursiveMerge [ (lib.my.recursiveMerge [
@ -280,7 +259,8 @@ in
} }
# Proxy to port # Proxy to port
(lib.optionalAttrs (args.port != null) { (lib.optionalAttrs (args.port != null) {
locations = mkProxyPass args "http://127.0.0.1:${toString args.port}"; locations."/".proxyPass =
"http://127.0.0.1:${toString args.port}";
}) })
# Serve filesystem content # Serve filesystem content
(lib.optionalAttrs (args.root != null) { (lib.optionalAttrs (args.root != null) {
@ -288,7 +268,8 @@ in
}) })
# Serve to UNIX socket # Serve to UNIX socket
(lib.optionalAttrs (args.socket != null) { (lib.optionalAttrs (args.socket != null) {
locations = mkProxyPass args "http://unix:${args.socket}"; locations."/".proxyPass =
"http://unix:${args.socket}";
}) })
# Redirect to a different domain # Redirect to a different domain
(lib.optionalAttrs (args.redirect != null) { (lib.optionalAttrs (args.redirect != null) {
@ -308,7 +289,6 @@ in
locations."/" = { locations."/" = {
extraConfig = extraConfig =
# FIXME: check that X-User is dropped otherwise
(args.extraConfig.locations."/".extraConfig or "") + '' (args.extraConfig.locations."/".extraConfig or "") + ''
# Use SSO # Use SSO
auth_request /sso-auth; auth_request /sso-auth;
@ -442,8 +422,7 @@ in
{ {
"${domain}" = { "${domain}" = {
extraDomainNames = [ "*.${domain}" ]; extraDomainNames = [ "*.${domain}" ];
dnsProvider = "ovh"; dnsProvider = "gandiv5";
dnsPropagationCheck = false; # OVH is slow
inherit (cfg.acme) credentialsFile; inherit (cfg.acme) credentialsFile;
}; };
}; };

View file

@ -59,10 +59,15 @@ in
StateDirectory = "nginx-sso"; StateDirectory = "nginx-sso";
WorkingDirectory = "/var/lib/nginx-sso"; WorkingDirectory = "/var/lib/nginx-sso";
# The files to be merged might not have the correct permissions # The files to be merged might not have the correct permissions
ExecStartPre = pkgs.writeShellScript "merge-nginx-sso-config" '' ExecStartPre = ''+${pkgs.writeShellScript "merge-nginx-sso-config" ''
rm -f '${confPath}' rm -f '${confPath}'
${utils.genJqSecretsReplacementSnippet cfg.configuration confPath} ${utils.genJqSecretsReplacementSnippet cfg.configuration confPath}
'';
# Fix permissions
chown nginx-sso:nginx-sso ${confPath}
chmod 0600 ${confPath}
''
}'';
ExecStart = lib.mkForce '' ExecStart = lib.mkForce ''
${lib.getExe pkg} \ ${lib.getExe pkg} \
--config ${confPath} \ --config ${confPath} \

View file

@ -40,7 +40,7 @@ in
inherit (cfg) priority; inherit (cfg) priority;
}; };
signKeyPaths = [ cfg.secretKeyFile ]; signKeyPath = cfg.secretKeyFile;
}; };
my.services.nginx.virtualHosts = { my.services.nginx.virtualHosts = {

View file

@ -1,4 +1,4 @@
{ config, lib, ... }: { config, lib, pkgs, ... }:
let let
cfg = config.my.services.paperless; cfg = config.my.services.paperless;
in in
@ -61,6 +61,11 @@ in
PAPERLESS_ENABLE_HTTP_REMOTE_USER = true; PAPERLESS_ENABLE_HTTP_REMOTE_USER = true;
PAPERLESS_HTTP_REMOTE_USER_HEADER_NAME = "HTTP_X_USER"; PAPERLESS_HTTP_REMOTE_USER_HEADER_NAME = "HTTP_X_USER";
# Use PostgreSQL
PAPERLESS_DBHOST = "/run/postgresql";
PAPERLESS_DBUSER = "paperless";
PAPERLESS_DBNAME = "paperless";
# Security settings # Security settings
PAPERLESS_ALLOWED_HOSTS = paperlessDomain; PAPERLESS_ALLOWED_HOSTS = paperlessDomain;
PAPERLESS_CORS_ALLOWED_HOSTS = "https://${paperlessDomain}"; PAPERLESS_CORS_ALLOWED_HOSTS = "https://${paperlessDomain}";
@ -75,18 +80,63 @@ in
# Misc # Misc
PAPERLESS_TIME_ZONE = config.time.timeZone; PAPERLESS_TIME_ZONE = config.time.timeZone;
PAPERLESS_ADMIN_USER = cfg.username; PAPERLESS_ADMIN_USER = cfg.username;
# Fix classifier hangs
LD_LIBRARY_PATH = "${lib.getLib pkgs.mkl}/lib";
}; };
# Admin password # Admin password
passwordFile = cfg.passwordFile; passwordFile = cfg.passwordFile;
# Secret key
environmentFile = cfg.secretKeyFile;
# Automatic PostgreSQL provisioning
database = {
createLocally = true;
}; };
systemd.services = {
paperless-scheduler = {
requires = [ "postgresql.service" ];
after = [ "postgresql.service" ];
serviceConfig = {
EnvironmentFile = cfg.secretKeyFile;
};
};
paperless-consumer = {
requires = [ "postgresql.service" ];
after = [ "postgresql.service" ];
serviceConfig = {
EnvironmentFile = cfg.secretKeyFile;
};
};
paperless-web = {
requires = [ "postgresql.service" ];
after = [ "postgresql.service" ];
serviceConfig = {
EnvironmentFile = cfg.secretKeyFile;
};
};
paperless-task-queue = {
requires = [ "postgresql.service" ];
after = [ "postgresql.service" ];
serviceConfig = {
EnvironmentFile = cfg.secretKeyFile;
};
};
};
# Set-up database
services.postgresql = {
enable = true;
ensureDatabases = [ "paperless" ];
ensureUsers = [
{
name = "paperless";
ensureDBOwnership = true;
}
];
}; };
# Set-up media group # Set-up media group
@ -102,7 +152,11 @@ in
sso = { sso = {
enable = true; enable = true;
}; };
websocketsLocations = [ "/" ];
# Enable websockets on root
extraConfig = {
locations."/".proxyWebsockets = true;
};
}; };
}; };

View file

@ -1,73 +0,0 @@
{ config, lib, ... }:
let
cfg = config.my.services.pdf-edit;
in
{
options.my.services.pdf-edit = with lib; {
enable = mkEnableOption "PDF edition service";
port = mkOption {
type = types.port;
default = 8089;
example = 8080;
description = "Internal port for webui";
};
loginFile = mkOption {
type = types.str;
example = "/run/secrets/pdf-edit/login.env";
description = ''
`SECURITY_INITIALLOGIN_USERNAME` and `SECURITY_INITIALLOGIN_PASSWORD`
defined in the format of 'EnvironmentFile' (see `systemd.exec(5)`).
'';
};
};
config = lib.mkIf cfg.enable {
services.stirling-pdf = lib.mkIf cfg.enable {
enable = true;
environment = {
SERVER_PORT = cfg.port;
SECURITY_CSRFDISABLED = "false";
SYSTEM_SHOWUPDATE = "false"; # We don't care about update notifications
INSTALL_BOOK_AND_ADVANCED_HTML_OPS = "true"; # Installed by the module
SECURITY_ENABLELOGIN = "true";
SECURITY_LOGINATTEMPTCOUNT = "-1"; # Rely on fail2ban instead
};
environmentFiles = [ cfg.loginFile ];
};
my.services.nginx.virtualHosts = {
pdf-edit = {
inherit (cfg) port;
extraConfig = {
# Allow upload of PDF files up to 1G
locations."/".extraConfig = ''
client_max_body_size 1G;
'';
};
};
};
services.fail2ban.jails = {
stirling-pdf = ''
enabled = true
filter = stirling-pdf
port = http,https
'';
};
environment.etc = {
"fail2ban/filter.d/stirling-pdf.conf".text = ''
[Definition]
failregex = ^.*Failed login attempt from IP: <HOST>$
journalmatch = _SYSTEMD_UNIT=stirling-pdf.service
'';
};
};
}

View file

@ -4,13 +4,12 @@
# [1]: https://youtu.be/I26Ql-uX6AM # [1]: https://youtu.be/I26Ql-uX6AM
{ config, lib, ... }: { config, lib, ... }:
let let
cfg = config.my.services.servarr; cfg = config.my.services.pirate;
ports = { ports = {
bazarr = 6767; bazarr = 6767;
lidarr = 8686; lidarr = 8686;
radarr = 7878; radarr = 7878;
readarr = 8787;
sonarr = 8989; sonarr = 8989;
}; };
@ -53,7 +52,7 @@ let
]); ]);
in in
{ {
options.my.services.servarr = { options.my.services.pirate = {
enable = lib.mkEnableOption "Media automation"; enable = lib.mkEnableOption "Media automation";
bazarr = { bazarr = {
@ -68,10 +67,6 @@ in
enable = lib.my.mkDisableOption "Radarr"; enable = lib.my.mkDisableOption "Radarr";
}; };
readarr = {
enable = lib.my.mkDisableOption "Readarr";
};
sonarr = { sonarr = {
enable = lib.my.mkDisableOption "Sonarr"; enable = lib.my.mkDisableOption "Sonarr";
}; };
@ -90,21 +85,8 @@ in
# Radarr for movies # Radarr for movies
(mkFullConfig "radarr") (mkFullConfig "radarr")
(mkFail2Ban "radarr") (mkFail2Ban "radarr")
# Readarr for books
(mkFullConfig "readarr")
(mkFail2Ban "readarr")
# Sonarr for shows # Sonarr for shows
(mkFullConfig "sonarr") (mkFullConfig "sonarr")
(mkFail2Ban "sonarr") (mkFail2Ban "sonarr")
# HACK: until https://github.com/NixOS/nixpkgs/issues/360592 is resolved
(lib.mkIf cfg.sonarr.enable {
nixpkgs.config.permittedInsecurePackages = [
"aspnetcore-runtime-6.0.36"
"aspnetcore-runtime-wrapped-6.0.36"
"dotnet-sdk-6.0.428"
"dotnet-sdk-wrapped-6.0.428"
];
})
]); ]);
} }

View file

@ -13,7 +13,7 @@ in
example = "/run/secrets/password.env"; example = "/run/secrets/password.env";
description = '' description = ''
The path to a file containing the PASSWORD environment variable The path to a file containing the PASSWORD environment variable
definition for Podgrab's authentication. definition for Podgrab's authentification.
''; '';
}; };

View file

@ -14,7 +14,7 @@ in
# Let other services enable postgres when they need it # Let other services enable postgres when they need it
(lib.mkIf cfg.enable { (lib.mkIf cfg.enable {
services.postgresql = { services.postgresql = {
package = pkgs.postgresql_17; package = pkgs.postgresql_13;
}; };
}) })
@ -23,15 +23,15 @@ in
environment.systemPackages = environment.systemPackages =
let let
pgCfg = config.services.postgresql; pgCfg = config.services.postgresql;
newPackage' = pkgs.postgresql_17; newPackage' = pkgs.postgresql_13;
oldPackage = if pgCfg.enableJIT then pgCfg.package.withJIT else pgCfg.package; oldPackage = if pgCfg.enableJIT then pgCfg.package.withJIT else pgCfg.package;
oldData = pgCfg.dataDir; oldData = pgCfg.dataDir;
oldBin = "${if pgCfg.extensions == [] then oldPackage else oldPackage.withPackages pgCfg.extensions}/bin"; oldBin = "${if pgCfg.extraPlugins == [] then oldPackage else oldPackage.withPackages pgCfg.extraPlugins}/bin";
newPackage = if pgCfg.enableJIT then newPackage'.withJIT else newPackage'; newPackage = if pgCfg.enableJIT then newPackage'.withJIT else newPackage';
newData = "/var/lib/postgresql/${newPackage.psqlSchema}"; newData = "/var/lib/postgresql/${newPackage.psqlSchema}";
newBin = "${if pgCfg.extensions == [] then newPackage else newPackage.withPackages pgCfg.extensions}/bin"; newBin = "${if pgCfg.extraPlugins == [] then newPackage else newPackage.withPackages pgCfg.extraPlugins}/bin";
in in
[ [
(pkgs.writeScriptBin "upgrade-pg-cluster" '' (pkgs.writeScriptBin "upgrade-pg-cluster" ''

View file

@ -53,20 +53,6 @@ in
}; };
}; };
services.fail2ban.jails = { # FIXME: fail2ban
pyload = ''
enabled = true
filter = pyload
port = http,https
'';
};
environment.etc = {
"fail2ban/filter.d/pyload.conf".text = ''
[Definition]
failregex = ^.*Login failed for user '<F-USER>.*</F-USER>' \[CLIENT: <HOST>\]$
journalmatch = _SYSTEMD_UNIT=pyload.service
'';
};
}; };
} }

View file

@ -82,7 +82,5 @@ in
}; };
}; };
}; };
# NOTE: unfortunately tandoor-recipes does not log connection failures for fail2ban
}; };
} }

View file

@ -90,7 +90,5 @@ in
allowedTCPPorts = [ cfg.peerPort ]; allowedTCPPorts = [ cfg.peerPort ];
allowedUDPPorts = [ cfg.peerPort ]; allowedUDPPorts = [ cfg.peerPort ];
}; };
# NOTE: unfortunately transmission does not log connection failures for fail2ban
}; };
} }

View file

@ -41,7 +41,7 @@ in
service = { service = {
# Only allow registration of users through the CLI # Only allow registration of users through the CLI
enableregistration = false; enableregistration = false;
# Use the host's timezone # Ues the host's timezone
timezone = config.time.timeZone; timezone = config.time.timeZone;
# Use UNIX socket for serving the API # Use UNIX socket for serving the API
unixsocket = socketPath; unixsocket = socketPath;
@ -99,7 +99,5 @@ in
config.services.vikunja.settings.files.basepath config.services.vikunja.settings.files.basepath
]; ];
}; };
# NOTE: unfortunately vikunja does not log connection failures for fail2ban
}; };
} }

View file

@ -206,7 +206,7 @@ in
]; ];
} }
# Additional interface is only used to get access to "LAN" from wireguard # Additional inteface is only used to get access to "LAN" from wireguard
(lib.mkIf cfg.internal.enable { (lib.mkIf cfg.internal.enable {
networking.wg-quick.interfaces."${cfg.internal.name}" = mkInterface [ networking.wg-quick.interfaces."${cfg.internal.name}" = mkInterface [
"${cfg.net.v4.subnet}.0/${toString cfg.net.v4.mask}" "${cfg.net.v4.subnet}.0/${toString cfg.net.v4.mask}"

View file

@ -22,10 +22,6 @@ in
options.my.system.nix = with lib; { options.my.system.nix = with lib; {
enable = my.mkDisableOption "nix configuration"; enable = my.mkDisableOption "nix configuration";
gc = {
enable = my.mkDisableOption "nix GC configuration";
};
cache = { cache = {
selfHosted = my.mkDisableOption "self-hosted cache"; selfHosted = my.mkDisableOption "self-hosted cache";
}; };
@ -66,22 +62,6 @@ in
}; };
} }
(lib.mkIf cfg.gc.enable {
nix.gc = {
automatic = true;
# Every week, with some wiggle room
dates = "weekly";
randomizedDelaySec = "10min";
# Use a persistent timer for e.g: laptops
persistent = true;
# Delete old profiles automatically after 15 days
options = "--delete-older-than 15d";
};
})
(lib.mkIf cfg.cache.selfHosted { (lib.mkIf cfg.cache.selfHosted {
nix = { nix = {
settings = { settings = {

View file

@ -1,5 +1,5 @@
# Common packages # Common packages
{ config, lib, ... }: { config, lib, pkgs, ... }:
let let
cfg = config.my.system.packages; cfg = config.my.system.packages;
in in
@ -13,11 +13,13 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [
vim
wget
];
programs = { programs = {
vim = { vim.defaultEditor = true; # Modal editing is life
enable = true;
defaultEditor = true; # Modal editing is life
};
zsh = { zsh = {
enable = true; # Use integrations enable = true; # Use integrations

View file

@ -1,14 +0,0 @@
self: prev:
{
transmission_4 = prev.transmission_4.overrideAttrs (_: {
version = "4.0.5";
src = self.fetchFromGitHub {
owner = "transmission";
repo = "transmission";
rev = "4.0.5";
hash = "sha256-gd1LGAhMuSyC/19wxkoE2mqVozjGPfupIPGojKY0Hn4=";
fetchSubmodules = true;
};
});
}

View file

@ -1,4 +0,0 @@
self: prev:
{
vimPlugins = prev.vimPlugins.extend (self.callPackage ./generated.nix { });
}

View file

@ -1,14 +0,0 @@
{ fetchpatch, ... }:
_final: prev: {
lsp-format-nvim = prev.lsp-format-nvim.overrideAttrs (oa: {
patches = (oa.patches or [ ]) ++ [
# https://github.com/lukas-reineke/lsp-format.nvim/issues/94
(fetchpatch {
name = "use-effective-indentation";
url = "https://github.com/liskin/lsp-format.nvim/commit/3757ac443bdf5bd166673833794553229ee8d939.patch";
hash = "sha256-Dv+TvXrU/IrrPxz2MSPbLmRxch+qkHbI3AyFMj/ssDk=";
})
];
});
}

View file

@ -62,7 +62,7 @@ do_toggle() {
} }
case "$1" in case "$1" in
up | down) up|down)
do_change_volume "$@" do_change_volume "$@"
;; ;;
toggle) toggle)

View file

@ -81,23 +81,23 @@ parse_args() {
shift shift
case "$opt" in case "$opt" in
-h | --help) -h|--help)
usage usage
exit exit
;; ;;
-f | --flake-output) -f|--flake-output)
FLAKE_OUTPUTS+=("$1") FLAKE_OUTPUTS+=("$1")
shift shift
;; ;;
-o | --output) -o|--output)
OUTPUT_FILE="$1" OUTPUT_FILE="$1"
shift shift
;; ;;
-n | --new-rev) -n|--new-rev)
NEW_REV="$(git rev-parse "$1")" NEW_REV="$(git rev-parse "$1")"
shift shift
;; ;;
-p | --previous-rev) -p|--previous-rev)
PREVIOUS_REV="$(git rev-parse "$1")" PREVIOUS_REV="$(git rev-parse "$1")"
shift shift
;; ;;
@ -157,7 +157,7 @@ list_dev_shells() {
} }
diff_output() { diff_output() {
local PREV NEW local PREV NEW;
PREV="$(mktemp --dry-run)" PREV="$(mktemp --dry-run)"
NEW="$(mktemp --dry-run)" NEW="$(mktemp --dry-run)"
@ -169,7 +169,7 @@ diff_output() {
printf 'Closure diff for `%s`:\n```\n' "$1" printf 'Closure diff for `%s`:\n```\n' "$1"
nix store diff-closures "$PREV" "$NEW" | sanitize_output nix store diff-closures "$PREV" "$NEW" | sanitize_output
printf '```\n\n' printf '```\n\n'
} >>"$OUTPUT_FILE" } >> "$OUTPUT_FILE"
} }
parse_args "$@" parse_args "$@"

View file

@ -1,16 +1,16 @@
{ lib, fetchFromGitHub, rustPlatform }: { lib, fetchFromGitHub, rustPlatform }:
rustPlatform.buildRustPackage rec { rustPlatform.buildRustPackage rec {
pname = "lohr"; pname = "lohr";
version = "0.4.6"; version = "0.4.5";
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "alarsyo"; owner = "alarsyo";
repo = "lohr"; repo = "lohr";
rev = "v${version}"; rev = "v${version}";
hash = "sha256-dunQgtap+XCK5LoSyOqIY/6p6HizBeiyPWNuCffwjDU="; hash = "sha256-p6E/r+OxFTpxDpOKSlacOxvRLfHSKg1mHNAfTytfqDY=";
}; };
cargoHash = "sha256-EUhyrhPe+mUgMmm4o+bxRIiSNReJRfw+/O1fPr8r7lo="; cargoHash = "sha256-hext0S0o9D9pN9epzXtD5dwAYMPCLpBBOBT4FX0mTMk=";
meta = with lib; { meta = with lib; {
description = "Git mirroring daemon"; description = "Git mirroring daemon";

View file

@ -15,7 +15,7 @@ usage() {
exec 1>&2 exec 1>&2
fi fi
cat <<EOF cat << EOF
Usage: $0 [options] [string] Usage: $0 [options] [string]
Send an arbitrary string to the terminal clipboard using the OSC 52 escape Send an arbitrary string to the terminal clipboard using the OSC 52 escape
sequence as specified in xterm: sequence as specified in xterm:

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