Compare commits

...

46 commits

Author SHA1 Message Date
1d61c985de home: jujutsu: explicitly create 'conf.d'
All checks were successful
ci/woodpecker/push/check Pipeline was successful
This is to serve as a reminder of _how_ to add a local configuration
file.
2025-04-11 15:05:44 +00:00
3491fd5f58 WIP: ADD NOTE FOR FUTURE SELF 2025-04-11 15:05:44 +00:00
52ed16ece6 home: jj: use verbose draft commit messages 2025-04-11 15:05:44 +00:00
05cc22af2a WIP: add jujutsu (w/ Delta) 2025-04-11 15:05:44 +00:00
989f694611 home: git: extract 'delta' configuration
I want to be able to re-use it between different source control systems
(e.g: `jj`).

As a first step, extract it to a proper module so that I can have it
live in a single space.
2025-04-11 15:02:38 +00:00
bd55ecc016 hosts: nixos: porthos: services: enable homebox
All checks were successful
ci/woodpecker/push/check Pipeline was successful
2025-04-09 12:29:27 +02:00
1dd1dbb917 nixos: services: homebox: proxy websockets
Should avoid a bunch of error logs, and ensure that e.g: adding a label
does not require a refresh to show it in a list.
2025-04-09 12:29:27 +02:00
439a6bc930 nixos: services: homebox: use postgres 2025-04-09 12:29:27 +02:00
e5bf5a3ba1 flake: bump inputs 2025-04-09 12:29:27 +02:00
a1cab7f606 flake: home-manager: set overlays in module
All checks were successful
ci/woodpecker/push/check Pipeline was successful
I need to inherit `lib` to make sure it picks up my version, not the one
from `pkgs`.

I can't use `extraSpecialArgs` like NixOS, due to it missing from
upstream [1].

[1]: https://github.com/nix-community/home-manager/pull/3969
2025-04-07 16:16:41 +00:00
0152907536 flake: nixos: use 'self.dirtyRev' if available
All checks were successful
ci/woodpecker/push/check Pipeline was successful
2025-04-07 10:19:30 +00:00
08f7c2bd79 nixos: services: nextcloud: bump to 31
All checks were successful
ci/woodpecker/push/check Pipeline was successful
2025-04-05 20:24:21 +02:00
b8c649d5bf hosts: nixos: porthos: services: enable autobrr
All checks were successful
ci/woodpecker/push/check Pipeline was successful
2025-04-05 20:22:27 +02:00
979814e9de hosts: nixos: porthos: secrets: add autobrr 2025-04-05 20:22:27 +02:00
215eb4c91a nixos: services: servarr: add autobrr 2025-04-05 20:22:27 +02:00
3510264186 flake: bump inputs
All checks were successful
ci/woodpecker/push/check Pipeline was successful
2025-04-05 20:11:43 +02:00
ec965800e4 nixos: services: servarr: nzbhydra: fix websockets
From what I could read, NZBHydra2 *might* require proxying websockets in
new versions (better safe than sorry).
2025-04-05 20:07:47 +02:00
b1ade72383 nixos: services: servarr: migrate nzbhydra 2025-04-05 20:07:47 +02:00
c823edf584 nixos: services: servarr: jackett: add 'port' 2025-04-05 20:07:47 +02:00
950cf4dd05 nixos: services: servarr: migrate jackett 2025-04-05 20:07:47 +02:00
f825d047b5 nixos: services: servarr: migrate prowlarr
The configuration doesn't have `group`, so it's a slightly different
configuration to the rest of the *arr services.

I also want to move the other two indexer modules under `servarr`, as
they are all closely related.
2025-04-05 20:07:47 +02:00
d783b5f5ee nixos: services: servarr: starr: add 'port'
Now that declarative configurations are supported for those
applications.
2025-04-05 20:07:47 +02:00
8e6be43817 nixox: services: servarr: refactor starr config
Makes it slightly DRY-er and more readable.
2025-04-05 20:07:47 +02:00
1f876d3e21 nixos: services: servarr: bazarr: add 'port' 2025-04-05 20:07:46 +02:00
860c13ab1f nixos: services: servarr: extract bazarr
It's not an actual *arr package, but closely related to them. Extract
its configuration to a sub-module.
2025-04-05 20:07:46 +02:00
7791ad0907 nixos: services: servarr: fix 'enableAll' logic
I renamed the option and refactored how it worked to make it more
explicit that it enables the entire suite by default, with explicit
opt-out of individual components (or fine-grained opt-in as an
alternative).
2025-04-05 20:07:46 +02:00
ca98b8367c templates: add python-uv 2025-04-05 19:00:10 +01:00
62ddec5c23 templates: remove unused 'follows' 2025-04-05 18:57:18 +01:00
418494004b templates: use 'pre-commit.enabledPackages' 2025-04-05 18:57:18 +01:00
53569f17a6 treewide: pre-commit-hooks.nix renaming 2025-04-05 18:33:37 +01:00
d48d5c45e0 home: vim: remove 'friendly-snippets'
I never use them...
2025-04-04 19:06:19 +01:00
36aa641ec0 home: vim: rely on built-in diagnostic jump config
This reduces the surface area of my configuration.
2025-04-03 22:04:44 +01:00
2583cc6c12 home: vim: lua: lsp: add count to diagnostic maps 2025-04-03 22:04:44 +01:00
262dc48425 home: vim: use default 'diffopt:linematch'
It's now been defaulted to `linematch:40` on v0.11.
2025-04-03 22:04:44 +01:00
c1efc4316d home: vim: lualine: add custom 'oil' extension
I don't like the built-in one.
2025-04-03 22:04:44 +01:00
4ef1b08f4e home: vim: lualine: use built-in 'branch'
It now supports worktrees correctly (or at least I can't figure out
which issue I used to have with it...).

As a bonus, it also supports showing the correct branch for an `oil`
buffer.

This reverts commit 481d5f6f53.
2025-04-03 22:04:44 +01:00
274d143031 home: vim: fix deprecated calls 2025-04-03 22:04:44 +01:00
dfb3c353ec home: vim: remove 'lsp_lines'
It's been upstreamed!
2025-04-03 22:04:44 +01:00
37e88c2707 flake: bump inputs
And fix the small `jq` breakage.
2025-04-03 22:04:44 +01:00
1841ff391d flake: dev-shells: remove redundant 'pre-commit'
All checks were successful
ci/woodpecker/push/check Pipeline was successful
It's already being installed by the shell hook.
2025-04-02 20:42:40 +01:00
458ea144c4 home: vim: remove 'fastfold' configuration
I missed it in the original commit that removed the plug-in from my
configuration...
2025-04-02 20:42:40 +01:00
abec0dd226 home: git: remove 'ignoreRevsFile'
I remember why I didn't set it globally now, it's because `git blame`
complains and errors out, rather than silently ignoring the setting,
when the file doesn't exist in a repo...

This reverts commit 5ae2eacd49.
2025-04-02 20:42:40 +01:00
b2758839e8 home: vim: lspconfig: add 'harper'
All checks were successful
ci/woodpecker/push/check Pipeline was successful
Support for more languages is upcoming, I also need to check how to
handle custom words/dictionaries.
2025-03-24 16:51:52 +00:00
6fc81e45e9 home: zsh: migrate to 'initContent'
All checks were successful
ci/woodpecker/push/check Pipeline was successful
This also fixes a small ordering issue: my alias definitions used to be
defined at the very end of the file, they're now slotted _before_ the
`zshrc.local` import.
2025-03-24 11:58:59 +00:00
9156a8211d flake: bump inputs 2025-03-24 11:47:59 +00:00
5ae2eacd49 home: git: add 'ignoreRevsFile'
All checks were successful
ci/woodpecker/push/check Pipeline was successful
I'm surprised I hadn't configured it already.

`.git-blame-ignore-revs` is the usual name, as most forges automatically
detect and use it.
2025-03-19 11:45:07 +00:00
46 changed files with 842 additions and 352 deletions

68
flake.lock generated
View file

@ -73,11 +73,11 @@
]
},
"locked": {
"lastModified": 1741352980,
"narHash": "sha256-+u2UunDA4Cl5Fci3m7S643HzKmIDAe+fiXrLqYsR2fs=",
"lastModified": 1743550720,
"narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "f4330d22f1c5d2ba72d3d22df5597d123fdb60a9",
"rev": "c621e8422220273271f52058f618c94e405bb0f5",
"type": "github"
},
"original": {
@ -108,10 +108,33 @@
"type": "github"
}
},
"git-hooks": {
"inputs": {
"flake-compat": "flake-compat",
"gitignore": "gitignore",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1742649964,
"narHash": "sha256-DwOTp7nvfi8mRfuL1escHDXabVXFGT1VlPD1JHrtrco=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "dcf5072734cb576d2b0c59b2ac44f5050b5eac82",
"type": "github"
},
"original": {
"owner": "cachix",
"ref": "master",
"repo": "git-hooks.nix",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"pre-commit-hooks",
"git-hooks",
"nixpkgs"
]
},
@ -136,11 +159,11 @@
]
},
"locked": {
"lastModified": 1741955947,
"narHash": "sha256-2lbURKclgKqBNm7hVRtWh0A7NrdsibD0EaWhahUVhhY=",
"lastModified": 1743869639,
"narHash": "sha256-Xhe3whfRW/Ay05z9m1EZ1/AkbV1yo0tm1CbgjtCi4rQ=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "4e12151c9e014e2449e0beca2c0e9534b96a26b4",
"rev": "d094c6763c6ddb860580e7d3b4201f8f496a6836",
"type": "github"
},
"original": {
@ -152,11 +175,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1742069588,
"narHash": "sha256-C7jVfohcGzdZRF6DO+ybyG/sqpo1h6bZi9T56sxLy+k=",
"lastModified": 1744174375,
"narHash": "sha256-oxI9TLgnQbQ/WL0tIwVSIooLbXq4PW1QUhf5aQmXFgk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c80f6a7e10b39afcc1894e02ef785b1ad0b0d7e5",
"rev": "ef3a956f697525883b77192cbe208233ea0f8f79",
"type": "github"
},
"original": {
@ -191,38 +214,15 @@
"type": "github"
}
},
"pre-commit-hooks": {
"inputs": {
"flake-compat": "flake-compat",
"gitignore": "gitignore",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1742058297,
"narHash": "sha256-b4SZc6TkKw8WQQssbN5O2DaCEzmFfvSTPYHlx/SFW9Y=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "59f17850021620cd348ad2e9c0c64f4e6325ce2a",
"type": "github"
},
"original": {
"owner": "cachix",
"ref": "master",
"repo": "pre-commit-hooks.nix",
"type": "github"
}
},
"root": {
"inputs": {
"agenix": "agenix",
"flake-parts": "flake-parts",
"futils": "futils",
"git-hooks": "git-hooks",
"home-manager": "home-manager",
"nixpkgs": "nixpkgs",
"nur": "nur",
"pre-commit-hooks": "pre-commit-hooks",
"systems": "systems"
}
},

View file

@ -61,10 +61,10 @@
};
};
pre-commit-hooks = {
git-hooks = {
type = "github";
owner = "cachix";
repo = "pre-commit-hooks.nix";
repo = "git-hooks.nix";
ref = "master";
inputs = {
nixpkgs.follows = "nixpkgs";

View file

@ -1,7 +1,7 @@
{ inputs, ... }:
{
imports = [
inputs.pre-commit-hooks.flakeModule
inputs.git-hooks.flakeModule
];
perSystem = { ... }: {

View file

@ -6,7 +6,6 @@
name = "NixOS-config";
nativeBuildInputs = with pkgs; [
gitAndTools.pre-commit
nixpkgs-fmt
];

View file

@ -3,6 +3,11 @@ let
defaultModules = [
# Include generic settings
"${self}/modules/home"
{
nixpkgs.overlays = (lib.attrValues self.overlays) ++ [
inputs.nur.overlays.default
];
}
{
# Basic user information defaults
home.username = lib.mkDefault "ambroisie";
@ -21,18 +26,15 @@ let
# * not letting me set `lib` as an extraSpecialArgs
# * not respecting `nixpkgs.overlays` [1]
# [1]: https://github.com/nix-community/home-manager/issues/2954
pkgs = import inputs.nixpkgs {
inherit system;
overlays = (lib.attrValues self.overlays) ++ [
inputs.nur.overlays.default
];
};
pkgs = inputs.nixpkgs.legacyPackages.${system};
modules = defaultModules ++ [
"${self}/hosts/homes/${name}"
];
# Use my extended lib in NixOS configuration
inherit (self) lib;
extraSpecialArgs = {
# Inject inputs to use them in global registry
inherit inputs;

View file

@ -3,7 +3,7 @@ let
defaultModules = [
{
# Let 'nixos-version --json' know about the Git revision
system.configurationRevision = self.rev or "dirty";
system.configurationRevision = self.rev or self.dirtyRev or "dirty";
}
{
nixpkgs.overlays = (lib.attrValues self.overlays) ++ [

View file

@ -80,6 +80,8 @@ in
"pyload/credentials.age".publicKeys = all;
"servarr/autobrr/session-secret.age".publicKeys = all;
"sso/auth-key.age" = {
owner = "nginx-sso";
publicKeys = all;

View file

@ -0,0 +1,7 @@
age-encryption.org/v1
-> ssh-ed25519 cKojmg bu09lB+fjaPP31cUQZP6EqSPuseucgNK7k9vAS08iS0
+NGL+b2QD/qGo6hqHvosAXzHZtDvfodmPdcgnrKlD1o
-> ssh-ed25519 jPowng QDCdRBGWhtdvvMCiDH52cZHz1/W7aomhTatZ4+9IKwI
Ou3jjV/O55G1CPgGS33l3eWhhYWrVdwVNPSiE14d5rE
--- q0ssmpG50OX1WaNSInc2hbtH3DbTwQGDU74VGEoMh94
 ¯mCùº<C3B9>Æ'hK.Ðì/™Xu(€«Õ×g$½'¼šM{fK˜ !ÛMZ²oR÷®ˆüÎÕ<C38E>ÍŸö;yb

View file

@ -51,9 +51,9 @@ in
passwordFile = secrets."forgejo/mail-password".path;
};
};
# Meta-indexers
indexers = {
prowlarr.enable = true;
# Home inventory
homebox = {
enable = true;
};
# Jellyfin media server
jellyfin.enable = true;
@ -144,11 +144,21 @@ in
sabnzbd.enable = true;
# The whole *arr software suite
servarr = {
enable = true;
enableAll = true;
autobrr = {
sessionSecretFile = secrets."servarr/autobrr/session-secret".path;
};
# ... But not Lidarr because I don't care for music that much
lidarr = {
enable = false;
};
# I only use Prowlarr nowadays
jackett = {
enable = false;
};
nzbhydra = {
enable = false;
};
};
# Because I still need to play sysadmin
ssh-server.enable = true;

View file

@ -8,6 +8,7 @@
./bluetooth
./calibre
./comma
./delta
./dircolors
./direnv
./discord
@ -23,6 +24,7 @@
./gtk
./htop
./jq
./jujutsu
./keyboard
./mail
./mpv

View file

@ -0,0 +1,85 @@
{ config, pkgs, lib, ... }:
let
cfg = config.my.home.delta;
in
{
options.my.home.delta = with lib; {
enable = my.mkDisableOption "delta configuration";
package = mkPackageOption pkgs "delta" { };
git = {
enable = my.mkDisableOption "git integration";
};
jujutsu = {
enable = my.mkDisableOption "jujutsu integration";
};
};
config = lib.mkIf cfg.enable {
assertions = [
{
# For its configuration
assertion = cfg.jujutsu.enable -> cfg.git.enable;
message = ''
`config.my.home.delta.jujutsu` relies on `config.my.home.delta.git`
being enabled.
'';
}
];
home.packages = [ cfg.package ];
programs.git = lib.mkIf cfg.git.enable {
delta = {
enable = true;
inherit (cfg) package;
options = {
features = "diff-highlight decorations";
# Less jarring style for `diff-highlight` emulation
diff-highlight = {
minus-style = "red";
minus-non-emph-style = "red";
minus-emph-style = "bold red 52";
plus-style = "green";
plus-non-emph-style = "green";
plus-emph-style = "bold green 22";
whitespace-error-style = "reverse red";
};
# Personal preference for easier reading
decorations = {
commit-style = "raw"; # Do not recolor meta information
keep-plus-minus-markers = true;
paging = "always";
};
};
};
};
programs.jujutsu = lib.mkIf cfg.jujutsu.enable {
settings = {
merge-tools = {
delta = {
# Errors are signaled with exit codes greater or equal to 2
diff-expected-exit-codes = [ 0 1 ];
};
};
ui = {
diff = {
# Delta expects a `git diff` input
format = "git";
};
pager = "delta";
};
};
};
};
}

View file

@ -42,34 +42,6 @@ in
lfs.enable = true;
delta = {
enable = true;
options = {
features = "diff-highlight decorations";
# Less jarring style for `diff-highlight` emulation
diff-highlight = {
minus-style = "red";
minus-non-emph-style = "red";
minus-emph-style = "bold red 52";
plus-style = "green";
plus-non-emph-style = "green";
plus-emph-style = "bold green 22";
whitespace-error-style = "reverse red";
};
# Personal preference for easier reading
decorations = {
commit-style = "raw"; # Do not recolor meta information
keep-plus-minus-markers = true;
paging = "always";
};
};
};
# There's more
extraConfig = {
# Makes it a bit more readable

View file

@ -17,6 +17,7 @@ in
strings = "0;32";
arrays = "1;39";
objects = "1;39";
objectKeys = "1;34";
};
};
}

View file

@ -0,0 +1,128 @@
{ config, pkgs, lib, ... }:
let
cfg = config.my.home.jujutsu;
inherit (lib.my) mkMailAddress;
in
{
options.my.home.jujutsu = with lib; {
enable = my.mkDisableOption "jujutsu configuration";
package = mkPackageOption pkgs "jujutsu" { };
};
config = lib.mkIf cfg.enable {
assertions = [
{
# For `jj git` commands
assertion = cfg.enable -> config.my.home.git.enable;
message = ''
`config.my.home.jujutsu` relies on `config.my.home.git` being enabled.
'';
}
];
programs.jujutsu = {
enable = true;
inherit (cfg) package;
settings = {
# Who am I?
user = {
name = "Bruno BELANYI";
email = mkMailAddress "bruno" "belanyi.fr";
};
aliases = {
jj = [ "util" "exec" "--" "jj" ];
# FIXME:
# * topo sort by default (I think? test it)
# * still not a big fan of the template
lol = [ "log" "-r" "..@" "-T" "builtin_log_oneline" ];
lola = [ "lol" "-r" "all()" ];
# TODO:
# * `pick` (https://github.com/jj-vcs/jj/issues/5446): [ "util" "exec" "--" "bash" "-c" "jj log -p -r \"diff_contains($1)\"" ]
# * `root`: `jj workspace root` (barely necessary then)
};
# FIXME: git equivalents
# blame = {
# coloring = "repeatedLines";
# markIgnoredLines = true;
# markUnblamables = true;
# };
# FIXME: log colors should probably match git
# FIXME: patience diff?
# FIXME: fetch prune/pruneTags?
# FIXME: pull.rebase=true? Probably true TBH
# FIXME: push.default=simple? Probably true TBH
# FIXME: conflict style? ui.conflict-marker-style=git is diff3/zdiff3
# FIXME: from ma_9's config, plus my own stuff
# snapshot = {
# auto-track = "none()";
# };
#
# ui = {
# diff-editor = ":builtin"; # To silence hints
# movement = {
# edit = false;
# };
# };
templates = {
# Equivalent to `commit.verbose = true` in Git
draft_commit_description = "commit_description_verbose(self)";
};
template-aliases = {
"commit_description_verbose(commit)" = ''
concat(
commit_description(commit),
"JJ: ignore-rest\n",
diff.git(),
)
'';
# FIXME: use `diff.summary()` instead? Supported by syntax highlighting
# See https://github.com/jj-vcs/jj/issues/1946#issuecomment-2572986485
# FIXME: tree-sitter grammar isn't in `nvim-treesitter` (https://github.com/kareigu/tree-sitter-jjdescription)
"commit_description(commit)" = ''
concat(
commit.description(), "\n",
"JJ: This commit contains the following changes:\n",
indent("JJ: ", diff.stat(72)),
)
'';
};
"--scope" = [
# Multiple identities
{
"--when" = {
repositories = [ "~/git/EPITA/" ];
};
user = {
name = "Bruno BELANYI";
email = mkMailAddress "bruno.belanyi" "epita.fr";
};
}
{
"--when" = {
repositories = [ "~/git/work/" ];
};
user = {
name = "Bruno BELANYI";
email = mkMailAddress "ambroisie" "google.com";
};
}
];
};
};
# To drop in a `local.toml` configuration, not-versioned
xdg.configFile = {
"jj/conf.d/.keep".text = "";
};
};
}

View file

@ -31,8 +31,6 @@ local keys = {
{ "[u", desc = "URL encode" },
{ "[x", desc = "XML encode" },
{ "[y", desc = "C string encode" },
-- Custom
{ "[d", lsp.goto_prev_diagnostic, desc = "Previous diagnostic" },
-- Next
{ "]", group = "Next" },
@ -62,8 +60,6 @@ local keys = {
{ "]u", desc = "URL decode" },
{ "]x", desc = "XML decode" },
{ "]y", desc = "C string decode" },
-- Custom
{ "]d", lsp.goto_next_diagnostic, desc = "Next diagnostic" },
-- Enable option
{ "[o", group = "Enable option" },

View file

@ -59,7 +59,6 @@ in
# LSP and linting
nvim-lspconfig # Easy LSP configuration
lsp-format-nvim # Simplified formatting configuration
lsp_lines-nvim # Show diagnostics *over* regions
none-ls-nvim # LSP integration for linters and formatters
nvim-treesitter.withAllGrammars # Better highlighting
nvim-treesitter-textobjects # More textobjects
@ -67,7 +66,6 @@ in
# Completion
luasnip # Snippet manager compatible with LSP
friendly-snippets # LSP snippets collection
nvim-cmp # Completion engine
cmp-async-path # More responsive path completion
cmp-buffer # Words from open buffers

View file

@ -68,8 +68,6 @@ set listchars=tab:>─,trail:·,nbsp:¤
" Use patience diff
set diffopt+=algorithm:patience
" Align similar lines in each hunk
set diffopt+=linematch:50
" Don't redraw when executing macros
set lazyredraw

View file

@ -3,43 +3,6 @@ local M = {}
-- Simplified LSP formatting configuration
local lsp_format = require("lsp-format")
--- Move to the next/previous diagnostic, automatically showing the diagnostics
--- float if necessary.
--- @param forward bool whether to go forward or backwards
local function goto_diagnostic(forward)
vim.validate({
forward = { forward, "boolean" },
})
local opts = {
float = false,
}
-- Only show floating diagnostics if they are otherwise not displayed
local config = vim.diagnostic.config()
if not (config.virtual_text or config.virtual_lines) then
opts.float = true
end
if forward then
vim.diagnostic.goto_next(opts)
else
vim.diagnostic.goto_prev(opts)
end
end
--- Move to the next diagnostic, automatically showing the diagnostics float if
--- necessary.
M.goto_next_diagnostic = function()
goto_diagnostic(true)
end
--- Move to the previous diagnostic, automatically showing the diagnostics float
--- if necessary.
M.goto_prev_diagnostic = function()
goto_diagnostic(false)
end
--- shared LSP configuration callback
--- @param client native client configuration
--- @param bufnr int? buffer number of the attached client
@ -79,6 +42,10 @@ M.on_attach = function(client, bufnr)
vim.diagnostic.config({
virtual_text = text,
virtual_lines = lines,
jump = {
-- Show float on jump if no diagnostic text is otherwise shown
float = not (text or lines),
},
})
end

View file

@ -38,7 +38,7 @@ end
--- @param bufnr int? buffer number
--- @return table all active LSP client names
M.list_lsp_clients = function(bufnr)
local clients = vim.lsp.get_active_clients({ bufnr = bufnr })
local clients = vim.lsp.get_clients({ bufnr = bufnr })
local names = {}
for _, client in ipairs(clients) do

View file

@ -1,5 +0,0 @@
-- Intercept all fold commands
-- stylua: ignore
vim.g.fastfold_fold_command_suffixes = {
"x", "X", "a", "A", "o", "O", "c", "C", "r", "R", "m", "M", "i", "n", "N",
}

View file

@ -1,3 +0,0 @@
local lsp_lines = require("lsp_lines")
lsp_lines.setup()

View file

@ -16,6 +16,10 @@ vim.diagnostic.config({
update_in_insert = false,
-- Show highest severity first
severity_sort = true,
jump = {
-- Show float on diagnostic jumps
float = true,
},
})
-- Inform servers we are able to do completion, snippets, etc...
@ -96,6 +100,13 @@ if utils.is_executable("starpls") then
end
-- Generic
if utils.is_executable("harper-ls") then
lspconfig.harper_ls.setup({
capabilities = capabilities,
on_attach = lsp.on_attach,
})
end
if utils.is_executable("typos-lsp") then
lspconfig.typos_lsp.setup({
capabilities = capabilities,

View file

@ -1,4 +1,5 @@
local lualine = require("lualine")
local oil = require("oil")
local utils = require("ambroisie.utils")
local function list_spell_languages()
@ -30,7 +31,7 @@ lualine.setup({
{ "mode" },
},
lualine_b = {
{ "FugitiveHead" },
{ "branch" },
{ "filename", symbols = { readonly = "🔒" } },
},
lualine_c = {
@ -57,5 +58,21 @@ lualine.setup({
extensions = {
"fugitive",
"quickfix",
{
sections = {
lualine_a = {
{ "mode" },
},
lualine_b = {
{ "branch" },
},
lualine_c = {
function()
return vim.fn.fnamemodify(oil.get_current_dir(), ":~")
end,
},
},
filetypes = { "oil" },
},
},
})

View file

@ -1 +0,0 @@
require("luasnip.loaders.from_vscode").lazy_load()

View file

@ -87,28 +87,26 @@ in
# Modal editing is life, but CLI benefits from emacs gymnastics
defaultKeymap = "emacs";
# Make those happen early to avoid doing double the work
initExtraFirst = lib.mkBefore ''
${
lib.optionalString cfg.launchTmux ''
# Launch tmux unless already inside one
if [ -z "$TMUX" ]; then
exec tmux new-session
fi
''
}
'';
initContent = lib.mkMerge [
# Make those happen early to avoid doing double the work
(lib.mkBefore (lib.optionalString cfg.launchTmux ''
# Launch tmux unless already inside one
if [ -z "$TMUX" ]; then
exec tmux new-session
fi
''))
initExtra = lib.mkAfter ''
source ${./completion-styles.zsh}
source ${./extra-mappings.zsh}
source ${./options.zsh}
(lib.mkAfter ''
source ${./completion-styles.zsh}
source ${./extra-mappings.zsh}
source ${./options.zsh}
# Source local configuration
if [ -f "$ZDOTDIR/zshrc.local" ]; then
source "$ZDOTDIR/zshrc.local"
fi
'';
# Source local configuration
if [ -f "$ZDOTDIR/zshrc.local" ]; then
source "$ZDOTDIR/zshrc.local"
fi
'')
];
localVariables = {
# I like having the full path
@ -151,7 +149,7 @@ in
};
# Use OSC-777 to send the notification through SSH
initExtra = lib.mkIf cfg.notify.ssh.useOsc777 ''
initContent = lib.mkIf cfg.notify.ssh.useOsc777 ''
done_send_notification() {
local exit_status="$1"
local title="$2"

View file

@ -15,7 +15,6 @@
./gitea
./grocy
./homebox
./indexers
./jellyfin
./komga
./lohr

View file

@ -19,6 +19,11 @@ in
services.homebox = {
enable = true;
# Automatic PostgreSQL provisioning
database = {
createLocally = true;
};
settings = {
# FIXME: mailer?
HBOX_WEB_PORT = toString cfg.port;
@ -28,6 +33,7 @@ in
my.services.nginx.virtualHosts = {
homebox = {
inherit (cfg) port;
websocketsLocations = [ "/api" ];
};
};

View file

@ -1,78 +0,0 @@
# Torrent and usenet meta-indexers
{ config, lib, ... }:
let
cfg = config.my.services.indexers;
jackettPort = 9117;
nzbhydraPort = 5076;
prowlarrPort = 9696;
in
{
options.my.services.indexers = with lib; {
jackett.enable = mkEnableOption "Jackett torrent meta-indexer";
nzbhydra.enable = mkEnableOption "NZBHydra2 usenet meta-indexer";
prowlarr.enable = mkEnableOption "Prowlarr torrent & usenet meta-indexer";
};
config = lib.mkMerge [
(lib.mkIf cfg.jackett.enable {
services.jackett = {
enable = true;
};
# Jackett wants to eat *all* my RAM if left to its own devices
systemd.services.jackett = {
serviceConfig = {
MemoryHigh = "15%";
MemoryMax = "25%";
};
};
my.services.nginx.virtualHosts = {
jackett = {
port = jackettPort;
};
};
})
(lib.mkIf cfg.nzbhydra.enable {
services.nzbhydra2 = {
enable = true;
};
my.services.nginx.virtualHosts = {
nzbhydra = {
port = nzbhydraPort;
};
};
})
(lib.mkIf cfg.prowlarr.enable {
services.prowlarr = {
enable = true;
};
my.services.nginx.virtualHosts = {
prowlarr = {
port = prowlarrPort;
};
};
services.fail2ban.jails = {
prowlarr = ''
enabled = true
filter = prowlarr
action = iptables-allports
'';
};
environment.etc = {
"fail2ban/filter.d/prowlarr.conf".text = ''
[Definition]
failregex = ^.*\|Warn\|Auth\|Auth-Failure ip <HOST> username .*$
journalmatch = _SYSTEMD_UNIT=prowlarr.service
'';
};
})
];
}

View file

@ -35,7 +35,7 @@ in
config = lib.mkIf cfg.enable {
services.nextcloud = {
enable = true;
package = pkgs.nextcloud30;
package = pkgs.nextcloud31;
hostName = "nextcloud.${config.networking.domain}";
home = "/var/lib/nextcloud";
maxUploadSize = cfg.maxSize;

View file

@ -0,0 +1,62 @@
# IRC-based
{ config, lib, ... }:
let
cfg = config.my.services.servarr.autobrr;
in
{
options.my.services.servarr.autobrr = with lib; {
enable = mkEnableOption "autobrr IRC announce tracker" // {
default = config.my.services.servarr.enableAll;
};
port = mkOption {
type = types.port;
default = 7474;
example = 8080;
description = "Internal port for webui";
};
sessionSecretFile = mkOption {
type = types.str;
example = "/run/secrets/autobrr-secret.txt";
description = ''
File containing the session secret.
'';
};
};
config = lib.mkIf cfg.enable {
services.autobrr = {
enable = true;
settings = {
inherit (cfg) port;
checkForUpdates = false;
};
secretFile = cfg.sessionSecretFile;
};
my.services.nginx.virtualHosts = {
autobrr = {
inherit (cfg) port;
};
};
services.fail2ban.jails = {
autobrr = ''
enabled = true
filter = autobrr
action = iptables-allports
'';
};
environment.etc = {
"fail2ban/filter.d/autobrr.conf".text = ''
[Definition]
failregex = ^.*Auth: invalid login \[.*\] from: <HOST>$
journalmatch = _SYSTEMD_UNIT=autobrr.service
'';
};
};
}

View file

@ -0,0 +1,37 @@
{ config, lib, ... }:
let
cfg = config.my.services.servarr.bazarr;
in
{
options.my.services.servarr.bazarr = with lib; {
enable = lib.mkEnableOption "Bazarr" // {
default = config.my.services.servarr.enableAll;
};
port = mkOption {
type = types.port;
default = 6767;
example = 8080;
description = "Internal port for webui";
};
};
config = lib.mkIf cfg.enable {
services.bazarr = {
enable = true;
group = "media";
listenPort = cfg.port;
};
# Set-up media group
users.groups.media = { };
my.services.nginx.virtualHosts = {
bazarr = {
inherit (cfg) port;
};
};
# Bazarr does not log authentication failures...
};
}

View file

@ -2,99 +2,21 @@
# Relevant link [1].
#
# [1]: https://youtu.be/I26Ql-uX6AM
{ config, lib, ... }:
let
cfg = config.my.services.servarr;
ports = {
bazarr = 6767;
lidarr = 8686;
radarr = 7878;
readarr = 8787;
sonarr = 8989;
};
mkService = service: {
services.${service} = {
enable = true;
group = "media";
};
};
mkRedirection = service: {
my.services.nginx.virtualHosts = {
${service} = {
port = ports.${service};
};
};
};
mkFail2Ban = service: lib.mkIf cfg.${service}.enable {
services.fail2ban.jails = {
${service} = ''
enabled = true
filter = ${service}
action = iptables-allports
'';
};
environment.etc = {
"fail2ban/filter.d/${service}.conf".text = ''
[Definition]
failregex = ^.*\|Warn\|Auth\|Auth-Failure ip <HOST> username .*$
journalmatch = _SYSTEMD_UNIT=${service}.service
'';
};
};
mkFullConfig = service: lib.mkIf cfg.${service}.enable (lib.mkMerge [
(mkService service)
(mkRedirection service)
]);
in
{ lib, ... }:
{
imports = [
./autobrr.nix
./bazarr.nix
./jackett.nix
./nzbhydra.nix
./prowlarr.nix
(import ./starr.nix "lidarr")
(import ./starr.nix "radarr")
(import ./starr.nix "readarr")
(import ./starr.nix "sonarr")
];
options.my.services.servarr = {
enable = lib.mkEnableOption "Media automation";
bazarr = {
enable = lib.my.mkDisableOption "Bazarr";
};
lidarr = {
enable = lib.my.mkDisableOption "Lidarr";
};
radarr = {
enable = lib.my.mkDisableOption "Radarr";
};
readarr = {
enable = lib.my.mkDisableOption "Readarr";
};
sonarr = {
enable = lib.my.mkDisableOption "Sonarr";
};
enableAll = lib.mkEnableOption "media automation suite";
};
config = lib.mkIf cfg.enable (lib.mkMerge [
{
# Set-up media group
users.groups.media = { };
}
# Bazarr does not log authentication failures...
(mkFullConfig "bazarr")
# Lidarr for music
(mkFullConfig "lidarr")
(mkFail2Ban "lidarr")
# Radarr for movies
(mkFullConfig "radarr")
(mkFail2Ban "radarr")
# Readarr for books
(mkFullConfig "readarr")
(mkFail2Ban "readarr")
# Sonarr for shows
(mkFullConfig "sonarr")
(mkFail2Ban "sonarr")
]);
}

View file

@ -0,0 +1,41 @@
{ config, lib, ... }:
let
cfg = config.my.services.servarr.jackett;
in
{
options.my.services.servarr.jackett = with lib; {
enable = lib.mkEnableOption "Jackett" // {
default = config.my.services.servarr.enableAll;
};
port = mkOption {
type = types.port;
default = 9117;
example = 8080;
description = "Internal port for webui";
};
};
config = lib.mkIf cfg.enable {
services.jackett = {
enable = true;
inherit (cfg) port;
};
# Jackett wants to eat *all* my RAM if left to its own devices
systemd.services.jackett = {
serviceConfig = {
MemoryHigh = "15%";
MemoryMax = "25%";
};
};
my.services.nginx.virtualHosts = {
jackett = {
inherit (cfg) port;
};
};
# Jackett does not log authentication failures...
};
}

View file

@ -0,0 +1,26 @@
{ config, lib, ... }:
let
cfg = config.my.services.servarr.nzbhydra;
in
{
options.my.services.servarr.nzbhydra = with lib; {
enable = lib.mkEnableOption "NZBHydra2" // {
default = config.my.services.servarr.enableAll;
};
};
config = lib.mkIf cfg.enable {
services.nzbhydra2 = {
enable = true;
};
my.services.nginx.virtualHosts = {
nzbhydra = {
port = 5076;
websocketsLocations = [ "/" ];
};
};
# NZBHydra2 does not log authentication failures...
};
}

View file

@ -0,0 +1,53 @@
# Torrent and NZB indexer
{ config, lib, ... }:
let
cfg = config.my.services.servarr.prowlarr;
in
{
options.my.services.servarr.prowlarr = with lib; {
enable = lib.mkEnableOption "Prowlarr" // {
default = config.my.services.servarr.enableAll;
};
port = mkOption {
type = types.port;
default = 9696;
example = 8080;
description = "Internal port for webui";
};
};
config = lib.mkIf cfg.enable {
services.prowlarr = {
enable = true;
settings = {
server = {
port = cfg.port;
};
};
};
my.services.nginx.virtualHosts = {
prowlarr = {
inherit (cfg) port;
};
};
services.fail2ban.jails = {
prowlarr = ''
enabled = true
filter = prowlarr
action = iptables-allports
'';
};
environment.etc = {
"fail2ban/filter.d/prowlarr.conf".text = ''
[Definition]
failregex = ^.*\|Warn\|Auth\|Auth-Failure ip <HOST> username .*$
journalmatch = _SYSTEMD_UNIT=prowlarr.service
'';
};
};
}

View file

@ -0,0 +1,64 @@
# Templated *arr configuration
starr:
{ config, lib, ... }:
let
cfg = config.my.services.servarr.${starr};
ports = {
lidarr = 8686;
radarr = 7878;
readarr = 8787;
sonarr = 8989;
};
in
{
options.my.services.servarr.${starr} = with lib; {
enable = lib.mkEnableOption (lib.toSentenceCase starr) // {
default = config.my.services.servarr.enableAll;
};
port = mkOption {
type = types.port;
default = ports.${starr};
example = 8080;
description = "Internal port for webui";
};
};
config = lib.mkIf cfg.enable {
services.${starr} = {
enable = true;
group = "media";
settings = {
server = {
port = cfg.port;
};
};
};
# Set-up media group
users.groups.media = { };
my.services.nginx.virtualHosts = {
${starr} = {
port = cfg.port;
};
};
services.fail2ban.jails = {
${starr} = ''
enabled = true
filter = ${starr}
action = iptables-allports
'';
};
environment.etc = {
"fail2ban/filter.d/${starr}.conf".text = ''
[Definition]
failregex = ^.*\|Warn\|Auth\|Auth-Failure ip <HOST> username .*$
journalmatch = _SYSTEMD_UNIT=${starr}.service
'';
};
};
}

View file

@ -16,19 +16,18 @@
ref = "nixos-unstable";
};
pre-commit-hooks = {
git-hooks = {
type = "github";
owner = "cachix";
repo = "pre-commit-hooks.nix";
repo = "git-hooks.nix";
ref = "master";
inputs = {
flake-utils.follows = "futils";
nixpkgs.follows = "nixpkgs";
};
};
};
outputs = { self, futils, nixpkgs, pre-commit-hooks }:
outputs = { self, futils, nixpkgs, git-hooks }:
{
overlays = {
default = final: _prev: {
@ -69,7 +68,7 @@
];
};
pre-commit = pre-commit-hooks.lib.${system}.run {
pre-commit = git-hooks.lib.${system}.run {
src = self;
hooks = {
@ -92,12 +91,12 @@
devShells = {
default = pkgs.mkShell {
inputsFrom = with self.packages.${system}; [
project
inputsFrom = [
self.packages.${system}.project
];
packages = with pkgs; [
clang-tools
self.checks.${system}.pre-commit.enabledPackages
];
inherit (pre-commit) shellHook;

View file

@ -16,19 +16,18 @@
ref = "nixos-unstable";
};
pre-commit-hooks = {
git-hooks = {
type = "github";
owner = "cachix";
repo = "pre-commit-hooks.nix";
repo = "git-hooks.nix";
ref = "master";
inputs = {
flake-utils.follows = "futils";
nixpkgs.follows = "nixpkgs";
};
};
};
outputs = { self, futils, nixpkgs, pre-commit-hooks }:
outputs = { self, futils, nixpkgs, git-hooks }:
{
overlays = {
default = final: _prev: {
@ -69,7 +68,7 @@
];
};
pre-commit = pre-commit-hooks.lib.${system}.run {
pre-commit = git-hooks.lib.${system}.run {
src = self;
hooks = {
@ -92,12 +91,12 @@
devShells = {
default = pkgs.mkShell {
inputsFrom = with self.packages.${system}; [
project
inputsFrom = [
self.packages.${system}.project
];
packages = with pkgs; [
clang-tools
self.checks.${system}.pre-commit.enabledPackages
];
inherit (pre-commit) shellHook;

View file

@ -7,6 +7,10 @@
path = ./c++-meson;
description = "A C++ project using Meson";
};
"python-uv" = {
path = ./python-uv;
description = "A Python project using uv";
};
"rust-cargo" = {
path = ./rust-cargo;
description = "A Rust project using Cargo";

View file

@ -0,0 +1,6 @@
# shellcheck shell=bash
if ! has nix_direnv_version || ! nix_direnv_version 3.0.0; then
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.0/direnvrc" "sha256-21TMnI2xWX7HkSTjFFri2UaohXVj854mgvWapWrxRXg="
fi
use flake

6
templates/python-uv/.gitignore vendored Normal file
View file

@ -0,0 +1,6 @@
# Virtual environments
.venv
# Nix generated files
/.pre-commit-config.yaml
/result

View file

@ -0,0 +1,31 @@
labels:
backend: local
steps:
- name: pre-commit check
image: bash
commands:
- nix develop --command pre-commit run --all
- name: nix flake check
image: bash
commands:
- nix flake check
- name: notify
image: bash
environment:
ADDRESS:
from_secret: matrix_homeserver
ROOM:
from_secret: matrix_roomid
USER:
from_secret: matrix_username
PASS:
from_secret: matrix_password
commands:
- nix run github:ambroisie/matrix-notifier
when:
status:
- failure
- success

View file

@ -0,0 +1,112 @@
{
description = "A Python project";
inputs = {
futils = {
type = "github";
owner = "numtide";
repo = "flake-utils";
ref = "main";
};
nixpkgs = {
type = "github";
owner = "NixOS";
repo = "nixpkgs";
ref = "nixos-unstable";
};
git-hooks = {
type = "github";
owner = "cachix";
repo = "git-hooks.nix";
ref = "master";
inputs = {
nixpkgs.follows = "nixpkgs";
};
};
};
outputs = { self, futils, nixpkgs, git-hooks }:
{
overlays = {
default = final: _prev: {
project = with final; python3.pkgs.buildPythonApplication {
pname = "project";
version = (final.lib.importTOML ./pyproject.toml).project.version;
pyproject = true;
src = self;
build-system = with python3.pkgs; [ setuptools ];
pythonImportsCheck = [ "project" ];
meta = with lib; {
description = "A Python project";
homepage = "https://git.belanyi.fr/ambroisie/project";
license = licenses.mit;
maintainers = with maintainers; [ ambroisie ];
};
};
};
};
} // futils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [
self.overlays.default
];
};
pre-commit = git-hooks.lib.${system}.run {
src = self;
hooks = {
mypy = {
enable = true;
};
nixpkgs-fmt = {
enable = true;
};
ruff = {
enable = true;
};
ruff-format = {
enable = true;
};
};
};
in
{
checks = {
inherit (self.packages.${system}) project;
inherit pre-commit;
};
devShells = {
default = pkgs.mkShell {
inputsFrom = [
self.packages.${system}.project
];
packages = with pkgs; [
uv
self.checks.${system}.pre-commit.enabledPackages
];
inherit (pre-commit) shellHook;
};
};
packages = futils.lib.flattenTree {
default = pkgs.project;
inherit (pkgs) project;
};
});
}

View file

@ -0,0 +1,17 @@
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
[project]
name = "project"
version = "0.0.0"
description = "project description"
requires-python = ">=3.12"
dependencies = []
[project.scripts]
project = "project:main"
[dependency-groups]
dev = []

View file

@ -0,0 +1,2 @@
def main() -> None:
print("Hello, world!")

View file

@ -16,19 +16,18 @@
ref = "nixos-unstable";
};
pre-commit-hooks = {
git-hooks = {
type = "github";
owner = "cachix";
repo = "pre-commit-hooks.nix";
repo = "git-hooks.nix";
ref = "master";
inputs = {
flake-utils.follows = "futils";
nixpkgs.follows = "nixpkgs";
};
};
};
outputs = { self, futils, nixpkgs, pre-commit-hooks }:
outputs = { self, futils, nixpkgs, git-hooks }:
{
overlays = {
default = final: _prev: {
@ -60,7 +59,7 @@
];
};
pre-commit = pre-commit-hooks.lib.${system}.run {
pre-commit = git-hooks.lib.${system}.run {
src = self;
hooks = {
@ -88,14 +87,13 @@
devShells = {
default = pkgs.mkShell {
inputsFrom = with self.packages.${system}; [
project
inputsFrom = [
self.packages.${system}.project
];
packages = with pkgs; [
clippy
rust-analyzer
rustfmt
self.checks.${system}.pre-commit.enabledPackages
];
RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";