Compare commits
195 commits
nvim-lua-l
...
main
Author | SHA1 | Date | |
---|---|---|---|
Bruno BELANYI | 5cae5632d3 | ||
Bruno BELANYI | b7b6705391 | ||
Bruno BELANYI | ead8101b8d | ||
Bruno BELANYI | c75a307c58 | ||
Bruno BELANYI | f4f1aad1c0 | ||
Bruno BELANYI | 322fbc970b | ||
Bruno BELANYI | 92e5fbe7df | ||
Bruno BELANYI | 747b344b76 | ||
Bruno BELANYI | dec5dabf02 | ||
Bruno BELANYI | b2d2ff1798 | ||
Bruno BELANYI | c5a375d165 | ||
Bruno BELANYI | cb5eb68d35 | ||
Bruno BELANYI | 19120bca29 | ||
Bruno BELANYI | 35c547a090 | ||
Bruno BELANYI | ad1cfbd6f0 | ||
Bruno BELANYI | baa853477d | ||
Bruno BELANYI | 3ac85b8762 | ||
Bruno BELANYI | c74acda957 | ||
Bruno BELANYI | 98c90d77c5 | ||
Bruno BELANYI | b38658405a | ||
Bruno BELANYI | da3c29bbaf | ||
Bruno BELANYI | 8b61af1ac3 | ||
Bruno BELANYI | e8a41187e7 | ||
Bruno BELANYI | 83da7ba9c8 | ||
Bruno BELANYI | f2168378fc | ||
Bruno BELANYI | e39fef275c | ||
Bruno BELANYI | fe49e47026 | ||
Bruno BELANYI | 6a5c4a627a | ||
Bruno BELANYI | 7f0cd6612e | ||
Bruno BELANYI | 2ffbc13513 | ||
Bruno BELANYI | 60050113bc | ||
Bruno BELANYI | 6a1a35a384 | ||
Bruno BELANYI | e9d96138d5 | ||
Bruno BELANYI | ae230b5df7 | ||
Bruno BELANYI | 138d4d2bd9 | ||
Bruno BELANYI | ab8a5daefe | ||
Bruno BELANYI | 7b42368e2f | ||
Bruno BELANYI | 46bd23ff07 | ||
Bruno BELANYI | 62de2772a4 | ||
Bruno BELANYI | 8475d92314 | ||
Bruno BELANYI | 07552f3070 | ||
Bruno BELANYI | 5b66145be3 | ||
Bruno BELANYI | 67eb7bdd4b | ||
Bruno BELANYI | 6d2ac0c473 | ||
Bruno BELANYI | 46df8b5b5b | ||
Bruno BELANYI | cf1aeaf088 | ||
Bruno BELANYI | a09cef76c5 | ||
Bruno BELANYI | 0547ebc33c | ||
Bruno BELANYI | 8e81d148bd | ||
Bruno BELANYI | b10d936c0a | ||
Bruno BELANYI | eec65dc6b3 | ||
Bruno BELANYI | 09f763bc16 | ||
Bruno BELANYI | 79f08ea5a1 | ||
Bruno BELANYI | 38f3ac0ce5 | ||
Bruno BELANYI | 898523d079 | ||
Bruno BELANYI | cbba752b54 | ||
Bruno BELANYI | 20db71996c | ||
Bruno BELANYI | b0029448c6 | ||
Bruno BELANYI | 3aab65d9ea | ||
Bruno BELANYI | b6279108e0 | ||
Bruno BELANYI | 0f3c5d1d63 | ||
Bruno BELANYI | 1f40ac4a9f | ||
Bruno BELANYI | 2b64a00dc9 | ||
Bruno BELANYI | 1aa3385e13 | ||
Bruno BELANYI | a059828a58 | ||
Bruno BELANYI | 96e1a54638 | ||
Bruno BELANYI | f24cf2e16d | ||
Bruno BELANYI | cedac6bbf4 | ||
Bruno BELANYI | 129d4b3a5a | ||
Bruno BELANYI | c1eab0edee | ||
Bruno BELANYI | 4a38757db9 | ||
Bruno BELANYI | 8d344b5d51 | ||
Bruno BELANYI | 8a6af0e5b7 | ||
Bruno BELANYI | 4f73945e28 | ||
Bruno BELANYI | 6529bea6bb | ||
Bruno BELANYI | e67b055a7b | ||
Bruno BELANYI | fbd3b70d61 | ||
Bruno BELANYI | f91286d13b | ||
Bruno BELANYI | 90dcf3a164 | ||
Bruno BELANYI | a713913eef | ||
Bruno BELANYI | 9b7bab8e83 | ||
Bruno BELANYI | 0d2b9c9699 | ||
Bruno BELANYI | 6f00036b79 | ||
Bruno BELANYI | 52197a4f96 | ||
Bruno BELANYI | fb4047b2b3 | ||
Bruno BELANYI | 445cb43cb4 | ||
Bruno BELANYI | 10727f9eea | ||
Bruno BELANYI | 44c11fc431 | ||
Bruno BELANYI | e94bdef690 | ||
Bruno BELANYI | 483c5d23e0 | ||
Bruno BELANYI | 8ed69de4be | ||
Bruno BELANYI | f240730c4f | ||
Bruno BELANYI | 93dfe04114 | ||
Bruno BELANYI | 1e2872c5c7 | ||
Bruno BELANYI | 9ed2dcefde | ||
Bruno BELANYI | 0d820cc2f4 | ||
Bruno BELANYI | ace266b02c | ||
Bruno BELANYI | 6b7510cfd9 | ||
Bruno BELANYI | 58760280be | ||
Bruno BELANYI | 4de7886950 | ||
Bruno BELANYI | d04de7d213 | ||
Bruno BELANYI | b5216a6a50 | ||
Bruno BELANYI | 442eef0482 | ||
Bruno BELANYI | 997f208d30 | ||
Bruno BELANYI | 326f9d039a | ||
Bruno BELANYI | abaa7119e7 | ||
Bruno BELANYI | c6735f3912 | ||
Bruno BELANYI | 3438290e32 | ||
Bruno BELANYI | 82f49f1389 | ||
Bruno BELANYI | 5918a0b9e6 | ||
Bruno BELANYI | a7c542784c | ||
Bruno BELANYI | 280829b54f | ||
Bruno BELANYI | 5ffe2653c0 | ||
Bruno BELANYI | 5592a120a4 | ||
Bruno BELANYI | bcd9a31bb8 | ||
Bruno BELANYI | 966934a8bc | ||
Bruno BELANYI | 88e4d72366 | ||
Bruno BELANYI | 16d68022eb | ||
Bruno BELANYI | 0de9966127 | ||
Bruno BELANYI | 452399ee4c | ||
Bruno BELANYI | 6a6f3aed63 | ||
Bruno BELANYI | 04de570926 | ||
Bruno BELANYI | 1644e95243 | ||
Bruno BELANYI | abb78d63e2 | ||
Bruno BELANYI | 4943df69ef | ||
Bruno BELANYI | f11cdb3675 | ||
Bruno BELANYI | dc90e14e60 | ||
Bruno BELANYI | b895265537 | ||
Bruno BELANYI | fc5cb1a47d | ||
Bruno BELANYI | a15f7ec270 | ||
Bruno BELANYI | 105e0fbfd0 | ||
Bruno BELANYI | b73f6af5e0 | ||
Bruno BELANYI | c2362795d8 | ||
Bruno BELANYI | 468eaa9ed4 | ||
Bruno BELANYI | eb94fca939 | ||
Bruno BELANYI | 9ab49e06f9 | ||
Bruno BELANYI | 7c61d6dffc | ||
Bruno BELANYI | 64331981d0 | ||
Bruno BELANYI | 6a9ac77b0c | ||
Bruno BELANYI | d37c767a2f | ||
Bruno BELANYI | 10a7111f1c | ||
Bruno BELANYI | 7ea10f7823 | ||
Bruno BELANYI | c08c8c79d3 | ||
Bruno BELANYI | 82a0c65901 | ||
Bruno BELANYI | 5af0230c58 | ||
Bruno BELANYI | 442d267ca2 | ||
Bruno BELANYI | b90da603b1 | ||
Bruno BELANYI | e0b66e89f9 | ||
Bruno BELANYI | 212f280d92 | ||
Bruno BELANYI | cc82d7575f | ||
Bruno BELANYI | a60287f8cf | ||
Bruno BELANYI | 201fabbc14 | ||
Bruno BELANYI | 89056e3d5d | ||
Bruno BELANYI | ccab4d0952 | ||
Bruno BELANYI | 9e89b4dd36 | ||
Bruno BELANYI | 1cba7b609d | ||
Bruno BELANYI | 811a9f44c5 | ||
Bruno BELANYI | f6c476a07f | ||
Bruno BELANYI | 0745e450b9 | ||
Bruno BELANYI | 48beb9f1fe | ||
Bruno BELANYI | 6162f4f4d5 | ||
Bruno BELANYI | 8d2cf7f2c0 | ||
Bruno BELANYI | df79f36c87 | ||
Bruno BELANYI | 929c8ea9b0 | ||
Bruno BELANYI | 2dedb41a47 | ||
Bruno BELANYI | 7ebbb10568 | ||
Bruno BELANYI | 5df0574f41 | ||
Bruno BELANYI | c18054cad7 | ||
Bruno BELANYI | f9db06a6d4 | ||
Bruno BELANYI | b735eb4b98 | ||
Bruno BELANYI | 6a22a80d42 | ||
Bruno BELANYI | 06b760e3ee | ||
Bruno BELANYI | e43cdbfa65 | ||
Bruno BELANYI | 7e0cb867de | ||
Bruno BELANYI | a4ede5f6f4 | ||
Bruno BELANYI | 95c688766f | ||
Bruno BELANYI | 3e6b9f7161 | ||
Bruno BELANYI | 6efe2c12ba | ||
Bruno BELANYI | 6b51b4e2ab | ||
Bruno BELANYI | 10a3e684c8 | ||
Bruno BELANYI | 8f120e2129 | ||
Bruno BELANYI | f729f6a098 | ||
Bruno BELANYI | 8a4fdf6a56 | ||
Bruno BELANYI | d97da124ee | ||
Bruno BELANYI | 96aa934bec | ||
Bruno BELANYI | 4b5a19a8fa | ||
Bruno BELANYI | 06c64c1a78 | ||
Bruno BELANYI | 15d0e6bb38 | ||
Bruno BELANYI | 607aa5351c | ||
Bruno BELANYI | 61fa35093c | ||
Bruno BELANYI | 4a01a50532 | ||
Bruno BELANYI | 41e1ad3265 | ||
Bruno BELANYI | 10b4e6ce2d | ||
Bruno BELANYI | c0ef5c9275 | ||
Bruno BELANYI | 0ff8366105 |
18
.nvim.lua
18
.nvim.lua
|
@ -1,18 +0,0 @@
|
||||||
local lspconfig = require("lspconfig")
|
|
||||||
|
|
||||||
-- FIXME: https://github.com/folke/neodev.nvim ?
|
|
||||||
lspconfig.lua_ls.setup({
|
|
||||||
settings = {
|
|
||||||
Lua = {
|
|
||||||
runtime = {
|
|
||||||
version = "LuaJIT",
|
|
||||||
},
|
|
||||||
workspace = {
|
|
||||||
checkThirdParty = false,
|
|
||||||
library = {
|
|
||||||
vim.env.VIMRUNTIME,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
|
@ -7,17 +7,17 @@ steps:
|
||||||
commands:
|
commands:
|
||||||
- nix flake check
|
- nix flake check
|
||||||
|
|
||||||
- name: notifiy
|
- name: notify
|
||||||
image: bash
|
image: bash
|
||||||
secrets:
|
environment:
|
||||||
- source: matrix_homeserver
|
ADDRESS:
|
||||||
target: address
|
from_secret: matrix_homeserver
|
||||||
- source: matrix_roomid
|
ROOM:
|
||||||
target: room
|
from_secret: matrix_roomid
|
||||||
- source: matrix_username
|
USER:
|
||||||
target: user
|
from_secret: matrix_username
|
||||||
- source: matrix_password
|
PASS:
|
||||||
target: pass
|
from_secret: matrix_password
|
||||||
commands:
|
commands:
|
||||||
- nix run '.#matrix-notifier'
|
- nix run '.#matrix-notifier'
|
||||||
when:
|
when:
|
||||||
|
|
81
flake.lock
81
flake.lock
|
@ -14,11 +14,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1707830867,
|
"lastModified": 1723293904,
|
||||||
"narHash": "sha256-PAdwm5QqdlwIqGrfzzvzZubM+FXtilekQ/FA0cI49/o=",
|
"narHash": "sha256-b+uqzj+Wa6xgMS9aNbX4I+sXeb5biPDi39VgvSFqFvU=",
|
||||||
"owner": "ryantm",
|
"owner": "ryantm",
|
||||||
"repo": "agenix",
|
"repo": "agenix",
|
||||||
"rev": "8cb01a0e717311680e0cbca06a76cbceba6f3ed6",
|
"rev": "f6291c5935fdc4e0bef208cfc0dcab7e3f7a1c41",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -73,11 +73,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1709336216,
|
"lastModified": 1733312601,
|
||||||
"narHash": "sha256-Dt/wOWeW6Sqm11Yh+2+t0dfEWxoMxGBvv3JpIocFl9E=",
|
"narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=",
|
||||||
"owner": "hercules-ci",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-parts",
|
"repo": "flake-parts",
|
||||||
"rev": "f7b3c975cf067e56e7cda6cb098ebe3fb4d74ca2",
|
"rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -94,11 +94,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1709126324,
|
"lastModified": 1731533236,
|
||||||
"narHash": "sha256-q6EQdSeUZOG26WelxqkmR7kArjgWCdw5sfJVHPH/7j8=",
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "flake-utils",
|
"repo": "flake-utils",
|
||||||
"rev": "d465f4819400de7c8d874d50b982301f28a84605",
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -116,11 +116,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1703887061,
|
"lastModified": 1709087332,
|
||||||
"narHash": "sha256-gGPa9qWNc6eCXT/+Z5/zMkyYOuRZqeFZBDbopNZQkuY=",
|
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
|
||||||
"owner": "hercules-ci",
|
"owner": "hercules-ci",
|
||||||
"repo": "gitignore.nix",
|
"repo": "gitignore.nix",
|
||||||
"rev": "43e1aa1308018f37118e34d3a9cb4f5e75dc11d5",
|
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -136,11 +136,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1709988192,
|
"lastModified": 1734808199,
|
||||||
"narHash": "sha256-qxwIkl85P0I1/EyTT+NJwzbXdOv86vgZxcv4UKicjK8=",
|
"narHash": "sha256-MxlUcLjE8xLbrI1SJ2B2jftlg4wdutEILa3fgqwA98I=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "b0b0c3d94345050a7f86d1ebc6c56eea4389d030",
|
"rev": "f342df3ad938f205a913973b832f52c12546aac6",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -152,11 +152,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1709703039,
|
"lastModified": 1734424634,
|
||||||
"narHash": "sha256-6hqgQ8OK6gsMu1VtcGKBxKQInRLHtzulDo9Z5jxHEFY=",
|
"narHash": "sha256-cHar1vqHOOyC7f1+tVycPoWTfKIaqkoe1Q6TnKzuti4=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "9df3e30ce24fd28c7b3e2de0d986769db5d6225d",
|
"rev": "d3c42f187194c26d9f0309a8ecc469d6c878ce33",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -167,12 +167,21 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nur": {
|
"nur": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-parts": [
|
||||||
|
"flake-parts"
|
||||||
|
],
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"treefmt-nix": "treefmt-nix"
|
||||||
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1710013455,
|
"lastModified": 1734810357,
|
||||||
"narHash": "sha256-qzOpU4APTso6JLA+/F4zlO/yL8++n/CsUpmxbQAsy/4=",
|
"narHash": "sha256-Oa6d+y1/PVaPrZ/GYwvmTK9kSrc5Qx/8D3DFN2TzpVA=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "NUR",
|
"repo": "NUR",
|
||||||
"rev": "cf1e9b0e085368cc489c765f285f1d07c2ec8d36",
|
"rev": "e7b7b92a7c97a91f1465ab433bbdf6d00df1db8e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -185,9 +194,6 @@
|
||||||
"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"
|
||||||
|
@ -197,11 +203,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1708018599,
|
"lastModified": 1734797603,
|
||||||
"narHash": "sha256-M+Ng6+SePmA8g06CmUZWi1AjG2tFBX9WCXElBHEKnyM=",
|
"narHash": "sha256-ulZN7ps8nBV31SE+dwkDvKIzvN6hroRY8sYOT0w+E28=",
|
||||||
"owner": "cachix",
|
"owner": "cachix",
|
||||||
"repo": "pre-commit-hooks.nix",
|
"repo": "pre-commit-hooks.nix",
|
||||||
"rev": "5df5a70ad7575f6601d91f0efec95dd9bc619431",
|
"rev": "f0f0dc4920a903c3e08f5bdb9246bb572fcae498",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -238,6 +244,27 @@
|
||||||
"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",
|
||||||
|
|
|
@ -55,6 +55,10 @@
|
||||||
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 = {
|
||||||
|
@ -63,7 +67,6 @@
|
||||||
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";
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
nativeBuildInputs = with pkgs; [
|
nativeBuildInputs = with pkgs; [
|
||||||
gitAndTools.pre-commit
|
gitAndTools.pre-commit
|
||||||
lua-language-server
|
|
||||||
nixpkgs-fmt
|
nixpkgs-fmt
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ let
|
||||||
inherit system;
|
inherit system;
|
||||||
|
|
||||||
overlays = (lib.attrValues self.overlays) ++ [
|
overlays = (lib.attrValues self.overlays) ++ [
|
||||||
inputs.nur.overlay
|
inputs.nur.overlays.default
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ let
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
nixpkgs.overlays = (lib.attrValues self.overlays) ++ [
|
nixpkgs.overlays = (lib.attrValues self.overlays) ++ [
|
||||||
inputs.nur.overlay
|
inputs.nur.overlays.default
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
# Include generic settings
|
# Include generic settings
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
{
|
{
|
||||||
my.home = {
|
my.home = {
|
||||||
# Use graphical pinentry
|
# Use graphical pinentry
|
||||||
bitwarden.pinentry = "gtk2";
|
bitwarden.pinentry = pkgs.pinentry-gtk2;
|
||||||
# Ebook library
|
# Ebook library
|
||||||
calibre.enable = true;
|
calibre.enable = true;
|
||||||
# Some amount of social life
|
# Some amount of social life
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
# Blue light filter
|
# Blue light filter
|
||||||
gammastep.enable = true;
|
gammastep.enable = true;
|
||||||
# Use a small popup to enter passwords
|
# Use a small popup to enter passwords
|
||||||
gpg.pinentry = "gtk2";
|
gpg.pinentry = pkgs.pinentry-gtk2;
|
||||||
# Machine specific packages
|
# Machine specific packages
|
||||||
packages.additionalPackages = with pkgs; [
|
packages.additionalPackages = with pkgs; [
|
||||||
element-desktop # Matrix client
|
element-desktop # Matrix client
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
age-encryption.org/v1
|
age-encryption.org/v1
|
||||||
-> ssh-ed25519 cKojmg bQFr9oAnbo1rI/MpUV8wQz/Xj7iZY4ZU+Swf0nSIQFw
|
-> ssh-ed25519 cKojmg Ec0xt1uJTva8MxUdoTVX5m3uWaIiRlodf345FEM7Uzs
|
||||||
zama2XJ0gdvUlD2GHMhmZqHSxHe+dKSfXnHoWDcSw7Y
|
aJIneWFJPB5HVeoUGp57agXih9YeZ6xMEbyQ+zJtWQY
|
||||||
-> ssh-ed25519 jPowng gitUwSKTNKWLSxnwa185O7x/u0ul93g8wPESdZaKRk8
|
-> ssh-ed25519 jPowng B5XotRgv7s/FUegGhceBj7EoukewNUOIFl4TFRQf1EQ
|
||||||
uvBIfAUkZp5sg6rfeEGvL5ZDV8m2uSEotW02kjPN3Hw
|
PgGCBd/Pqwp7ayqi7okHBGF1SfFpwT4KlHJ/np6p2uQ
|
||||||
--- SZxe5f/CUZBvPQa2Sz/UBY3L68rMkIGGRuZPk7YE+Vg
|
--- AeLgwGz6k3OABb53cXNaCU/sgI4FlU1s6p8PhAaFOlg
|
||||||
¾r ú&…¥‹{~v?¨}=Ä
|
1ÌÉCÔ¹ð¤ŽULfI1¸Hm»Ûòb}m”” ÁÅ¡ìg•ß0¦¢–¤`X<16>G>\>¹8rŽz+Š›Y ™¼`—Ê¢.JBUÏ!z¸Z50ú*õ¡ÙŸ¤×ÖÇ®I<C2AE>ôÔ]¹‹ÏåI
|
||||||
}+
¿SQ’M[²]Œ±kMÒAàtŒÃmMë/£µLsü|Þ…m©CÀñiYC}ƒŽ‡çxŽ€
|
ĵ<18>¿–oÒÛ°…g„®„ÒêÁ³Â¿Ÿt’©nƒºãcz[»{
|
||||||
|
jçå&ÁõõNæ°Nÿo{õš½‚
-eP¾=L‰™
6¦.SP:»e¶–
|
|
@ -1,8 +0,0 @@
|
||||||
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Á\
|
|
8
hosts/nixos/porthos/secrets/pdf-edit/login.age
Normal file
8
hosts/nixos/porthos/secrets/pdf-edit/login.age
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
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]œÙjR¨
|
||||||
|
BþóÛ¾éaòs]xS<78>Î pbÞo#¬J1QŸ=t}5Õ>Oï‘{+¼.
M"7e»yý÷—
|
|
@ -31,8 +31,14 @@ in
|
||||||
publicKeys = all;
|
publicKeys = all;
|
||||||
};
|
};
|
||||||
|
|
||||||
"lohr/secret.age".publicKeys = all;
|
"lohr/secret.age" = {
|
||||||
"lohr/ssh-key.age".publicKeys = all;
|
owner = "lohr";
|
||||||
|
publicKeys = all;
|
||||||
|
};
|
||||||
|
"lohr/ssh-key.age" = {
|
||||||
|
owner = "lohr";
|
||||||
|
publicKeys = all;
|
||||||
|
};
|
||||||
|
|
||||||
"matrix/mail.age" = {
|
"matrix/mail.age" = {
|
||||||
owner = "matrix-synapse";
|
owner = "matrix-synapse";
|
||||||
|
@ -42,9 +48,6 @@ 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;
|
||||||
|
@ -71,13 +74,24 @@ 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".publicKeys = all;
|
"sso/auth-key.age" = {
|
||||||
"sso/ambroisie/password-hash.age".publicKeys = all;
|
owner = "nginx-sso";
|
||||||
"sso/ambroisie/totp-secret.age".publicKeys = all;
|
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;
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,11 @@ in
|
||||||
adblock = {
|
adblock = {
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
|
# Audiobook and podcast library
|
||||||
|
audiobookshelf = {
|
||||||
|
enable = true;
|
||||||
|
port = 9599;
|
||||||
|
};
|
||||||
# Backblaze B2 backup
|
# Backblaze B2 backup
|
||||||
backup = {
|
backup = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -64,9 +69,6 @@ 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;
|
||||||
|
@ -93,6 +95,9 @@ 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;
|
||||||
|
@ -122,19 +127,10 @@ in
|
||||||
passwordFile = secrets."paperless/password".path;
|
passwordFile = secrets."paperless/password".path;
|
||||||
secretKeyFile = secrets."paperless/secret-key".path;
|
secretKeyFile = secrets."paperless/secret-key".path;
|
||||||
};
|
};
|
||||||
# The whole *arr software suite
|
# Sometimes, editing PDFs is useful
|
||||||
pirate = {
|
pdf-edit = {
|
||||||
enable = true;
|
enable = true;
|
||||||
# ... But not Lidarr because I don't care for music that much
|
loginFile = secrets."pdf-edit/login".path;
|
||||||
lidarr = {
|
|
||||||
enable = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# Podcast automatic downloader
|
|
||||||
podgrab = {
|
|
||||||
enable = true;
|
|
||||||
passwordFile = secrets."podgrab/password".path;
|
|
||||||
port = 9598;
|
|
||||||
};
|
};
|
||||||
# Regular backups
|
# Regular backups
|
||||||
postgresql-backup.enable = true;
|
postgresql-backup.enable = true;
|
||||||
|
@ -146,13 +142,16 @@ in
|
||||||
rss-bridge.enable = true;
|
rss-bridge.enable = true;
|
||||||
# Usenet client
|
# Usenet client
|
||||||
sabnzbd.enable = true;
|
sabnzbd.enable = true;
|
||||||
# Because I stilll need to play sysadmin
|
# The whole *arr software suite
|
||||||
ssh-server.enable = true;
|
servarr = {
|
||||||
# Recipe manager
|
|
||||||
tandoor-recipes = {
|
|
||||||
enable = true;
|
enable = true;
|
||||||
secretKeyFile = secrets."tandoor-recipes/secret-key".path;
|
# ... 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;
|
||||||
# Torrent client and webui
|
# Torrent client and webui
|
||||||
transmission = {
|
transmission = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
{ config, lib, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
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
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, lib, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
let
|
let
|
||||||
cfg = config.my.home.bitwarden;
|
cfg = config.my.home.bitwarden;
|
||||||
in
|
in
|
||||||
|
@ -6,12 +6,7 @@ in
|
||||||
options.my.home.bitwarden = with lib; {
|
options.my.home.bitwarden = with lib; {
|
||||||
enable = my.mkDisableOption "bitwarden configuration";
|
enable = my.mkDisableOption "bitwarden configuration";
|
||||||
|
|
||||||
pinentry = mkOption {
|
pinentry = mkPackageOption pkgs "pinentry" { default = [ "pinentry-tty" ]; };
|
||||||
type = types.str;
|
|
||||||
default = "tty";
|
|
||||||
example = "gtk2";
|
|
||||||
description = "Which pinentry interface to use";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
|
|
|
@ -5,11 +5,13 @@ 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; [
|
||||||
calibre
|
cfg.package
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,9 @@ in
|
||||||
enable = my.mkDisableOption "direnv configuration";
|
enable = my.mkDisableOption "direnv configuration";
|
||||||
|
|
||||||
defaultFlake = mkOption {
|
defaultFlake = mkOption {
|
||||||
type = types.str;
|
type = with types; nullOr str;
|
||||||
default = "pkgs";
|
default = null;
|
||||||
example = "nixpkgs";
|
example = "pkgs";
|
||||||
description = ''
|
description = ''
|
||||||
Which flake from the registry should be used for
|
Which flake from the registry should be used for
|
||||||
<command>use pkgs</command> by default.
|
<command>use pkgs</command> by default.
|
||||||
|
@ -39,7 +39,7 @@ in
|
||||||
in
|
in
|
||||||
lib.my.genAttrs' files linkLibFile;
|
lib.my.genAttrs' files linkLibFile;
|
||||||
|
|
||||||
home.sessionVariables = {
|
home.sessionVariables = lib.mkIf (cfg.defaultFlake != null) {
|
||||||
DIRENV_DEFAULT_FLAKE = cfg.defaultFlake;
|
DIRENV_DEFAULT_FLAKE = cfg.defaultFlake;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#shellcheck shell=bash
|
# shellcheck shell=bash
|
||||||
|
|
||||||
# shellcheck disable=2155
|
# shellcheck disable=2155
|
||||||
use_android() {
|
use_android() {
|
||||||
|
@ -32,10 +32,16 @@ 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
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#shellcheck shell=bash
|
# shellcheck shell=bash
|
||||||
|
|
||||||
use_pkgs() {
|
use_pkgs() {
|
||||||
if ! has nix; then
|
if ! has nix; then
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 new` or `poetry init` to create one first'
|
log_error 'layout_poetry: no pyproject.toml found. Use `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 true
|
poetry run -q -- true
|
||||||
|
|
||||||
# shellcheck disable=2155
|
# shellcheck disable=2155
|
||||||
export VIRTUAL_ENV=$(poetry env info --path)
|
export VIRTUAL_ENV=$(poetry env info --path)
|
||||||
|
@ -23,3 +23,35 @@ 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
|
||||||
|
}
|
||||||
|
|
|
@ -7,11 +7,13 @@ 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; [
|
||||||
discord
|
cfg.package
|
||||||
];
|
];
|
||||||
|
|
||||||
xdg.configFile."discord/settings.json".source =
|
xdg.configFile."discord/settings.json".source =
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
" Use dark color scheme
|
" Use dark color scheme
|
||||||
colorscheme dark
|
colorscheme dark
|
||||||
|
|
||||||
" Make tridactyl open Vim in my prefered terminal
|
" Make tridactyl open Vim in my preferred 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
|
" Toggle comments on Reddit, Hacker News, Lobste.rs, LWN
|
||||||
bind ;c hint -Jc [class*="expand"],[class*="togg"],[class="comment_folder"]
|
bind ;c hint -Jc [class*="expand"],[class*="togg"],[class="comment_folder"],[class="CommentTitle"]
|
||||||
|
|
||||||
" 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-title-a"]
|
bindurl ^https://duckduckgo.com f hint -Jc [data-testid="result"]
|
||||||
bindurl ^https://duckduckgo.com F hint -Jbc [data-testid="result-title-a"]
|
bindurl ^https://duckduckgo.com F hint -Jbc [data-testid="result"]
|
||||||
|
|
||||||
" 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
|
||||||
|
|
|
@ -6,33 +6,28 @@ 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 = mkOption {
|
package = mkPackageOption pkgs "rr" { };
|
||||||
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; [
|
||||||
gdb
|
cfg.package
|
||||||
];
|
];
|
||||||
|
|
||||||
xdg = {
|
xdg = {
|
||||||
configFile."gdb/gdbinit".source = ./gdbinit;
|
configFile."gdb/gdbinit".source = ./gdbinit;
|
||||||
dataFile. "gdb/.keep".text = "";
|
stateFile."gdb/.keep".text = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
home.sessionVariables = {
|
home.sessionVariables = {
|
||||||
GDBHISTFILE = "${config.xdg.dataHome}/gdb/gdb_history";
|
GDBHISTFILE = "${config.xdg.stateHome}/gdb/gdb_history";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, lib, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
let
|
let
|
||||||
cfg = config.my.home.gpg;
|
cfg = config.my.home.gpg;
|
||||||
in
|
in
|
||||||
|
@ -6,12 +6,7 @@ in
|
||||||
options.my.home.gpg = with lib; {
|
options.my.home.gpg = with lib; {
|
||||||
enable = my.mkDisableOption "gpg configuration";
|
enable = my.mkDisableOption "gpg configuration";
|
||||||
|
|
||||||
pinentry = mkOption {
|
pinentry = mkPackageOption pkgs "pinentry" { default = [ "pinentry-tty" ]; };
|
||||||
type = types.str;
|
|
||||||
default = "tty";
|
|
||||||
example = "gtk2";
|
|
||||||
description = "Which pinentry interface to use";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
|
@ -22,7 +17,7 @@ in
|
||||||
services.gpg-agent = {
|
services.gpg-agent = {
|
||||||
enable = true;
|
enable = true;
|
||||||
enableSshSupport = true; # One agent to rule them all
|
enableSshSupport = true; # One agent to rule them all
|
||||||
pinentryFlavor = cfg.pinentry;
|
pinentryPackage = cfg.pinentry;
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
allow-loopback-pinentry
|
allow-loopback-pinentry
|
||||||
'';
|
'';
|
||||||
|
|
|
@ -21,12 +21,12 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
iconTheme = {
|
iconTheme = {
|
||||||
package = pkgs.gnome.gnome-themes-extra;
|
package = pkgs.gnome-themes-extra;
|
||||||
name = "Adwaita";
|
name = "Adwaita";
|
||||||
};
|
};
|
||||||
|
|
||||||
theme = {
|
theme = {
|
||||||
package = pkgs.gnome.gnome-themes-extra;
|
package = pkgs.gnome-themes-extra;
|
||||||
name = "Adwaita";
|
name = "Adwaita";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -58,7 +58,7 @@ in
|
||||||
{
|
{
|
||||||
config.accounts.email.accounts = {
|
config.accounts.email.accounts = {
|
||||||
personal = lib.mkMerge [
|
personal = lib.mkMerge [
|
||||||
# Common configuraton
|
# Common configuration
|
||||||
(mkConfig {
|
(mkConfig {
|
||||||
domain = "belanyi.fr";
|
domain = "belanyi.fr";
|
||||||
address = "bruno";
|
address = "bruno";
|
||||||
|
@ -70,7 +70,7 @@ in
|
||||||
];
|
];
|
||||||
|
|
||||||
gmail = lib.mkMerge [
|
gmail = lib.mkMerge [
|
||||||
# Common configuraton
|
# Common configuration
|
||||||
(mkConfig {
|
(mkConfig {
|
||||||
domain = "gmail.com";
|
domain = "gmail.com";
|
||||||
address = "brunobelanyi";
|
address = "brunobelanyi";
|
||||||
|
|
|
@ -22,12 +22,16 @@ 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 `/etc/nix/inputs/`";
|
link = my.mkDisableOption "link inputs to `$XDG_CONFIG_HOME/nix/inputs/`";
|
||||||
|
|
||||||
addToRegistry = my.mkDisableOption "add inputs and self to registry";
|
addToRegistry = my.mkDisableOption "add inputs and self to registry";
|
||||||
|
|
||||||
|
@ -60,6 +64,22 @@ 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 = {
|
||||||
|
@ -96,7 +116,7 @@ in
|
||||||
})
|
})
|
||||||
|
|
||||||
(lib.mkIf cfg.inputs.addToNixPath {
|
(lib.mkIf cfg.inputs.addToNixPath {
|
||||||
home.sessionVariables.NIX_PATH = "${config.xdg.configHome}/nix/inputs\${NIX_PATH:+:$NIX_PATH}";
|
nix.nixPath = [ "${config.xdg.configHome}/nix/inputs" ];
|
||||||
})
|
})
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ in
|
||||||
fd
|
fd
|
||||||
file
|
file
|
||||||
ripgrep
|
ripgrep
|
||||||
|
tree
|
||||||
] ++ cfg.additionalPackages);
|
] ++ cfg.additionalPackages);
|
||||||
|
|
||||||
nixpkgs.config = {
|
nixpkgs.config = {
|
||||||
|
|
|
@ -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.dataHome}/less/history";
|
LESSHISTFILE = "${config.xdg.stateHome}/less/history";
|
||||||
LESSKEY = "${config.xdg.configHome}/less/lesskey";
|
LESSKEY = "${config.xdg.configHome}/less/lesskey";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,7 +30,7 @@ in
|
||||||
});
|
});
|
||||||
|
|
||||||
default = { ${config.my.home.terminal.program} = { }; };
|
default = { ${config.my.home.terminal.program} = { }; };
|
||||||
defaultText = litteralExpression ''
|
defaultText = literalExpression ''
|
||||||
{ ''${config.my.home.terminal.program} = { }; };
|
{ ''${config.my.home.terminal.program} = { }; };
|
||||||
'';
|
'';
|
||||||
example = { xterm-256color = { }; };
|
example = { xterm-256color = { }; };
|
||||||
|
@ -47,6 +47,8 @@ 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; [
|
||||||
|
@ -80,6 +82,13 @@ 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
|
||||||
${
|
${
|
||||||
|
|
6
modules/home/vim/after/ftplugin/json.vim
Normal file
6
modules/home/vim/after/ftplugin/json.vim
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
" Create the `b:undo_ftplugin` variable if it doesn't exist
|
||||||
|
call ftplugined#check_undo_ft()
|
||||||
|
|
||||||
|
" Use a small indentation value on JSON files
|
||||||
|
setlocal shiftwidth=2
|
||||||
|
let b:undo_ftplugin.='|setlocal shiftwidth<'
|
|
@ -1,6 +0,0 @@
|
||||||
" 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<'
|
|
|
@ -1,10 +0,0 @@
|
||||||
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" })
|
|
|
@ -1,7 +0,0 @@
|
||||||
local wk = require("which-key")
|
|
||||||
|
|
||||||
local keys = {
|
|
||||||
["<leader>"] = { "<cmd>nohls<CR>", "Clear search highlight" },
|
|
||||||
}
|
|
||||||
|
|
||||||
wk.register(keys, { prefix = "<leader>" })
|
|
|
@ -1,15 +0,0 @@
|
||||||
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>" })
|
|
|
@ -1,30 +0,0 @@
|
||||||
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" })
|
|
|
@ -3,126 +3,124 @@ local wk = require("which-key")
|
||||||
local lsp = require("ambroisie.lsp")
|
local lsp = require("ambroisie.lsp")
|
||||||
|
|
||||||
local keys = {
|
local keys = {
|
||||||
-- Edition and navigation mappins
|
-- Previous
|
||||||
["["] = {
|
{ "[", group = "Previous" },
|
||||||
name = "Previous",
|
-- Edition and navigation mappings
|
||||||
["<space>"] = "Insert blank line above",
|
{ "[<space>", desc = "Insert blank line above" },
|
||||||
["<C-L>"] = "Previous location list file",
|
{ "[<C-L>", desc = "Previous location list file" },
|
||||||
["<C-Q>"] = "Previous quickfix list file",
|
{ "[<C-Q>", desc = "Previous quickfix list file" },
|
||||||
["<C-T>"] = "Previous tag in preview window",
|
{ "[<C-T>", desc = "Previous tag in preview window" },
|
||||||
a = "Previous argument",
|
{ "[a", desc = "Previous argument" },
|
||||||
A = "First argument",
|
{ "[A", desc = "First argument" },
|
||||||
b = "Previous buffer",
|
{ "[b", desc = "Previous buffer" },
|
||||||
B = "First buffer",
|
{ "[B", desc = "First buffer" },
|
||||||
e = "Exchange previous line",
|
{ "[e", desc = "Exchange previous line" },
|
||||||
f = "Previous file in directory",
|
{ "[f", desc = "Previous file in directory" },
|
||||||
l = "Previous location list entry",
|
{ "[l", desc = "Previous location list entry" },
|
||||||
L = "First Location list entry",
|
{ "[L", desc = "First Location list entry" },
|
||||||
n = "Previous conflict marker/diff hunk",
|
{ "[n", desc = "Previous conflict marker/diff hunk" },
|
||||||
p = "Paste line above",
|
{ "[p", desc = "Paste line above" },
|
||||||
P = "Paste line above",
|
{ "[P", desc = "Paste line above" },
|
||||||
q = "Previous quickfix list entry",
|
{ "[q", desc = "Previous quickfix list entry" },
|
||||||
Q = "First quickfix list entry",
|
{ "[Q", desc = "First quickfix list entry" },
|
||||||
t = "Previous matching tag",
|
{ "[t", desc = "Previous matching tag" },
|
||||||
T = "First matching tag",
|
{ "[T", desc = "First matching tag" },
|
||||||
z = "Previous fold",
|
{ "[z", desc = "Previous fold" },
|
||||||
-- Encoding
|
-- Encoding
|
||||||
C = "C string encode",
|
{ "[C", desc = "C string encode" },
|
||||||
u = "URL encode",
|
{ "[u", desc = "URL encode" },
|
||||||
x = "XML encode",
|
{ "[x", desc = "XML encode" },
|
||||||
y = "C string encode",
|
{ "[y", desc = "C string encode" },
|
||||||
-- Custom
|
-- Custom
|
||||||
d = { lsp.goto_prev_diagnostic, "Previous diagnostic" },
|
{ "[d", lsp.goto_prev_diagnostic, desc = "Previous diagnostic" },
|
||||||
},
|
|
||||||
["]"] = {
|
|
||||||
name = "Next",
|
|
||||||
["<space>"] = "Insert blank line below",
|
|
||||||
["<C-L>"] = "Next location list file",
|
|
||||||
["<C-Q>"] = "Next quickfix list file",
|
|
||||||
["<C-T>"] = "Next tag in preview window",
|
|
||||||
a = "Next argument",
|
|
||||||
A = "Last argument",
|
|
||||||
b = "Next buffer",
|
|
||||||
B = "Last buffer",
|
|
||||||
e = "Exchange next line",
|
|
||||||
f = "Next file in directory",
|
|
||||||
l = "Next location list entry",
|
|
||||||
L = "Last Location list entry",
|
|
||||||
n = "Next conflict marker/diff hunk",
|
|
||||||
p = "Paste line below",
|
|
||||||
P = "Paste line below",
|
|
||||||
q = "Next quickfix list entry",
|
|
||||||
Q = "Last quickfix list entry",
|
|
||||||
t = "Next matching tag",
|
|
||||||
T = "Last matching tag",
|
|
||||||
z = "Next fold",
|
|
||||||
-- Decoding
|
|
||||||
C = "C string decode",
|
|
||||||
u = "URL decode",
|
|
||||||
x = "XML decode",
|
|
||||||
y = "C string decode",
|
|
||||||
-- Custom
|
|
||||||
d = { lsp.goto_next_diagnostic, "Next diagnostic" },
|
|
||||||
},
|
|
||||||
|
|
||||||
-- Option mappings
|
-- Next
|
||||||
["[o"] = {
|
{ "]", group = "Next" },
|
||||||
name = "Enable option",
|
-- Edition and navigation mappings
|
||||||
b = "Light background",
|
{ "]<space>", desc = "Insert blank line below" },
|
||||||
c = "Cursor line",
|
{ "]<C-L>", desc = "Next location list file" },
|
||||||
d = "Diff",
|
{ "]<C-Q>", desc = "Next quickfix list file" },
|
||||||
f = { "<cmd>FormatEnable<CR>", "LSP Formatting" },
|
{ "]<C-T>", desc = "Next tag in preview window" },
|
||||||
h = "Search high-lighting",
|
{ "]a", desc = "Next argument" },
|
||||||
i = "Case insensitive search",
|
{ "]A", desc = "Last argument" },
|
||||||
l = "List mode",
|
{ "]b", desc = "Next buffer" },
|
||||||
n = "Line numbers",
|
{ "]B", desc = "Last buffer" },
|
||||||
r = "Relative line numbers",
|
{ "]e", desc = "Exchange next line" },
|
||||||
p = { "<cmd>lwindow<CR>", "Location list" },
|
{ "]f", desc = "Next file in directory" },
|
||||||
q = { "<cmd>cwindow<CR>", "Quickfix list" },
|
{ "]l", desc = "Next location list entry" },
|
||||||
u = "Cursor column",
|
{ "]L", desc = "Last Location list entry" },
|
||||||
v = "Virtual editing",
|
{ "]n", desc = "Next conflict marker/diff hunk" },
|
||||||
w = "Text wrapping",
|
{ "]p", desc = "Paste line below" },
|
||||||
x = "Cursor line and column",
|
{ "]P", desc = "Paste line below" },
|
||||||
z = "Spell checking",
|
{ "]q", desc = "Next quickfix list entry" },
|
||||||
},
|
{ "]Q", desc = "Last quickfix list entry" },
|
||||||
["]o"] = {
|
{ "]t", desc = "Next matching tag" },
|
||||||
name = "Option off",
|
{ "]T", desc = "Last matching tag" },
|
||||||
b = "Light background",
|
{ "]z", desc = "Next fold" },
|
||||||
c = "Cursor line",
|
-- Decoding
|
||||||
d = "Diff",
|
{ "]C", desc = "C string decode" },
|
||||||
f = { "<cmd>FormatDisable<CR>", "LSP Formatting" },
|
{ "]u", desc = "URL decode" },
|
||||||
h = "Search high-lighting",
|
{ "]x", desc = "XML decode" },
|
||||||
i = "Case insensitive search",
|
{ "]y", desc = "C string decode" },
|
||||||
l = "List mode",
|
-- Custom
|
||||||
n = "Line numbers",
|
{ "]d", lsp.goto_next_diagnostic, desc = "Next diagnostic" },
|
||||||
p = { "<cmd>lclose<CR>", "Location list" },
|
|
||||||
q = { "<cmd>cclose<CR>", "Quickfix list" },
|
-- Enable option
|
||||||
r = "Relative line numbers",
|
{ "[o", group = "Enable option" },
|
||||||
u = "Cursor column",
|
{ "[ob", desc = "Light background" },
|
||||||
v = "Virtual editing",
|
{ "[oc", desc = "Cursor line" },
|
||||||
w = "Text wrapping",
|
{ "[od", desc = "Diff" },
|
||||||
x = "Cursor line and column",
|
{ "[of", "<cmd>FormatEnable<CR>", desc = "LSP Formatting" },
|
||||||
z = "Spell checking",
|
{ "[oh", desc = "Search high-lighting" },
|
||||||
},
|
{ "[oi", desc = "Case insensitive search" },
|
||||||
["yo"] = {
|
{ "[ol", desc = "List mode" },
|
||||||
name = "Option toggle",
|
{ "[on", desc = "Line numbers" },
|
||||||
b = "Light background",
|
{ "[or", desc = "Relative line numbers" },
|
||||||
c = "Cursor line",
|
{ "[op", "<cmd>lwindow<CR>", desc = "Location list" },
|
||||||
d = "Diff",
|
{ "[oq", "<cmd>cwindow<CR>", desc = "Quickfix list" },
|
||||||
f = { "<cmd>FormatToggle<CR>", "LSP Formatting" },
|
{ "[ou", desc = "Cursor column" },
|
||||||
h = "Search high-lighting",
|
{ "[ov", desc = "Virtual editing" },
|
||||||
i = "Case insensitive search",
|
{ "[ow", desc = "Text wrapping" },
|
||||||
l = "List mode",
|
{ "[ox", desc = "Cursor line and column" },
|
||||||
n = "Line numbers",
|
{ "[oz", desc = "Spell checking" },
|
||||||
p = { "<Plug>(qf_loc_toggle)", "Location list" },
|
|
||||||
q = { "<Plug>(qf_qf_toggle)", "Quickfix list" },
|
-- Disable option
|
||||||
r = "Relative line numbers",
|
{ "]o", group = "Disable option" },
|
||||||
u = "Cursor column",
|
{ "]ob", desc = "Light background" },
|
||||||
v = "Virtual editing",
|
{ "]oc", desc = "Cursor line" },
|
||||||
w = "Text wrapping",
|
{ "]od", desc = "Diff" },
|
||||||
x = "Cursor line and column",
|
{ "]of", "<cmd>FormatDisable<CR>", desc = "LSP Formatting" },
|
||||||
z = "Spell checking",
|
{ "]oh", desc = "Search high-lighting" },
|
||||||
},
|
{ "]oi", desc = "Case insensitive search" },
|
||||||
|
{ "]ol", desc = "List mode" },
|
||||||
|
{ "]on", desc = "Line numbers" },
|
||||||
|
{ "]op", "<cmd>lclose<CR>", desc = "Location list" },
|
||||||
|
{ "]oq", "<cmd>cclose<CR>", desc = "Quickfix list" },
|
||||||
|
{ "]or", desc = "Relative line numbers" },
|
||||||
|
{ "]ou", desc = "Cursor column" },
|
||||||
|
{ "]ov", desc = "Virtual editing" },
|
||||||
|
{ "]ow", desc = "Text wrapping" },
|
||||||
|
{ "]ox", desc = "Cursor line and column" },
|
||||||
|
{ "]oz", desc = "Spell checking" },
|
||||||
|
|
||||||
|
-- Toggle option
|
||||||
|
{ "yo", group = "Toggle option" },
|
||||||
|
{ "yob", desc = "Light background" },
|
||||||
|
{ "yoc", desc = "Cursor line" },
|
||||||
|
{ "yod", desc = "Diff" },
|
||||||
|
{ "yof", "<cmd>FormatToggle<CR>", desc = "LSP Formatting" },
|
||||||
|
{ "yoh", desc = "Search high-lighting" },
|
||||||
|
{ "yoi", desc = "Case insensitive search" },
|
||||||
|
{ "yol", desc = "List mode" },
|
||||||
|
{ "yon", desc = "Line numbers" },
|
||||||
|
{ "yop", "<Plug>(qf_loc_toggle)", desc = "Location list" },
|
||||||
|
{ "yoq", "<Plug>(qf_qf_toggle)", desc = "Quickfix list" },
|
||||||
|
{ "yor", desc = "Relative line numbers" },
|
||||||
|
{ "you", desc = "Cursor column" },
|
||||||
|
{ "yov", desc = "Virtual editing" },
|
||||||
|
{ "yow", desc = "Text wrapping" },
|
||||||
|
{ "yox", desc = "Cursor line and column" },
|
||||||
|
{ "yoz", desc = "Spell checking" },
|
||||||
}
|
}
|
||||||
|
|
||||||
wk.register(keys)
|
wk.add(keys)
|
||||||
|
|
5
modules/home/vim/after/queries/diff/highlights.scm
Normal file
5
modules/home/vim/after/queries/diff/highlights.scm
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
; extends
|
||||||
|
|
||||||
|
; I want to the line added/removed markers to be the correct color
|
||||||
|
"+" @diff.plus
|
||||||
|
"-" @diff.minus
|
|
@ -40,25 +40,18 @@ 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
|
||||||
|
@ -70,7 +63,6 @@ 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
|
||||||
|
@ -88,6 +80,7 @@ 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
|
||||||
|
@ -105,8 +98,11 @@ in
|
||||||
nixpkgs-fmt
|
nixpkgs-fmt
|
||||||
|
|
||||||
# Shell
|
# Shell
|
||||||
nodePackages.bash-language-server
|
bash-language-server
|
||||||
shfmt
|
shfmt
|
||||||
|
|
||||||
|
# Generic
|
||||||
|
typos-lsp
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
-- Use GN filetype for Chromium Generate Ninja files
|
|
||||||
vim.filetype.add({
|
|
||||||
extension = {
|
|
||||||
gn = "gn",
|
|
||||||
gni = "gn",
|
|
||||||
},
|
|
||||||
})
|
|
|
@ -1,6 +0,0 @@
|
||||||
-- Kbuild is just a Makefile under a different name
|
|
||||||
vim.filetype.add({
|
|
||||||
filename = {
|
|
||||||
["Kbuild"] = "make",
|
|
||||||
},
|
|
||||||
})
|
|
|
@ -1,6 +0,0 @@
|
||||||
-- Use LaTeX filetype for TikZ files
|
|
||||||
vim.filetype.add({
|
|
||||||
extension = {
|
|
||||||
tikz = "tex",
|
|
||||||
},
|
|
||||||
})
|
|
|
@ -1,4 +1,4 @@
|
||||||
" Basic configuraion {{{
|
" Basic configuration {{{
|
||||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||||
" 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 backups, we have source control for that
|
" Disable swap files
|
||||||
set nobackup
|
|
||||||
" Disable swapfiles too
|
|
||||||
set noswapfile
|
set noswapfile
|
||||||
|
" Enable undo files
|
||||||
|
set undofile
|
||||||
" }}}
|
" }}}
|
||||||
|
|
||||||
" UI and UX parameters {{{
|
" UI and UX parameters {{{
|
||||||
|
@ -86,8 +86,29 @@ set mouse=
|
||||||
" Set dark mode by default
|
" Set dark mode by default
|
||||||
set background=dark
|
set background=dark
|
||||||
|
|
||||||
" 24 bit colors
|
" Setup some overrides for gruvbox
|
||||||
set termguicolors
|
lua << EOF
|
||||||
|
local gruvbox = require("gruvbox")
|
||||||
|
local colors = gruvbox.palette
|
||||||
|
|
||||||
|
gruvbox.setup({
|
||||||
|
overrides = {
|
||||||
|
-- Only URLs should be underlined
|
||||||
|
["@string.special.path"] = { link = "GruvboxOrange" },
|
||||||
|
-- Revert back to the better diff highlighting
|
||||||
|
DiffAdd = { fg = colors.green, bg = "NONE" },
|
||||||
|
DiffChange = { fg = colors.aqua, bg = "NONE" },
|
||||||
|
DiffDelete = { fg = colors.red, bg = "NONE" },
|
||||||
|
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
|
||||||
" Use my preferred colorscheme
|
" Use my preferred colorscheme
|
||||||
colorscheme gruvbox
|
colorscheme gruvbox
|
||||||
" }}}
|
" }}}
|
||||||
|
|
|
@ -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 whether to go forward or backwards
|
--- @param forward bool 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 attched client
|
--- @param bufnr int? buffer number of the attached 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,31 +87,30 @@ M.on_attach = function(client, bufnr)
|
||||||
end
|
end
|
||||||
|
|
||||||
local keys = {
|
local keys = {
|
||||||
K = { vim.lsp.buf.hover, "Show symbol information" },
|
buffer = bufnr,
|
||||||
["<C-k>"] = { vim.lsp.buf.signature_help, "Show signature information" },
|
-- LSP navigation
|
||||||
["gd"] = { vim.lsp.buf.definition, "Go to definition" },
|
{ "K", vim.lsp.buf.hover, desc = "Show symbol information" },
|
||||||
["gD"] = { vim.lsp.buf.declaration, "Go to declaration" },
|
{ "<C-k>", vim.lsp.buf.signature_help, desc = "Show signature information" },
|
||||||
["gi"] = { vim.lsp.buf.implementation, "Go to implementation" },
|
{ "gd", vim.lsp.buf.definition, desc = "Go to definition" },
|
||||||
["gr"] = { vim.lsp.buf.references, "List all references" },
|
{ "gD", vim.lsp.buf.declaration, desc = "Go to declaration" },
|
||||||
|
{ "gi", vim.lsp.buf.implementation, desc = "Go to implementation" },
|
||||||
["<leader>c"] = {
|
{ "gr", vim.lsp.buf.references, desc = "List all references" },
|
||||||
name = "Code",
|
-- Code
|
||||||
a = { vim.lsp.buf.code_action, "Code actions" },
|
{ "<leader>c", group = "Code" },
|
||||||
d = { cycle_diagnostics_display, "Cycle diagnostics display" },
|
{ "<leader>ca", vim.lsp.buf.code_action, desc = "Code actions" },
|
||||||
D = { show_buffer_diagnostics, "Show buffer diagnostics" },
|
{ "<leader>cd", cycle_diagnostics_display, desc = "Cycle diagnostics display" },
|
||||||
r = { vim.lsp.buf.rename, "Rename symbol" },
|
{ "<leader>cD", show_buffer_diagnostics, desc = "Show buffer diagnostics" },
|
||||||
s = { vim.lsp.buf.signature_help, "Show signature" },
|
{ "<leader>cr", vim.lsp.buf.rename, desc = "Rename symbol" },
|
||||||
t = { vim.lsp.buf.type_definition, "Go to type definition" },
|
{ "<leader>cs", vim.lsp.buf.signature_help, desc = "Show signature" },
|
||||||
w = {
|
{ "<leader>ct", vim.lsp.buf.type_definition, desc = "Go to type definition" },
|
||||||
name = "Workspace",
|
-- Workspace
|
||||||
a = { vim.lsp.buf.add_workspace_folder, "Add folder to workspace" },
|
{ "<leader>cw", group = "Workspace" },
|
||||||
l = { list_workspace_folders, "List folders in workspace" },
|
{ "<leader>cwa", vim.lsp.buf.add_workspace_folder, desc = "Add folder to workspace" },
|
||||||
r = { vim.lsp.buf.remove_workspace_folder, "Remove folder from workspace" },
|
{ "<leader>cwl", list_workspace_folders, desc = "List folders in workspace" },
|
||||||
},
|
{ "<leader>cwr", vim.lsp.buf.remove_workspace_folder, desc = "Remove folder from workspace" },
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wk.register(keys, { buffer = bufnr })
|
wk.add(keys)
|
||||||
end
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
|
@ -48,4 +48,22 @@ 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
|
||||||
|
|
|
@ -7,17 +7,28 @@ 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,
|
||||||
command = "if &nu | setlocal rnu | endif",
|
callback = function()
|
||||||
|
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,
|
||||||
command = "if &nu | setlocal nornu | endif",
|
callback = function()
|
||||||
|
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,
|
||||||
command = "setlocal nonu nornu",
|
callback = function()
|
||||||
|
vim.opt.number = false
|
||||||
|
vim.opt.relativenumber = false
|
||||||
|
end,
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,58 +1,75 @@
|
||||||
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"] = { "&diff ? '[c' : '<cmd>Gitsigns prev_hunk<CR>'", "Previous hunk/diff", expr = true },
|
{ "[c", utils.partial(nav_hunk, "prev"), desc = "Previous hunk/diff" },
|
||||||
["]c"] = { "&diff ? ']c' : '<cmd>Gitsigns next_hunk<CR>'", "Next hunk/diff", expr = true },
|
{ "]c", utils.partial(nav_hunk, "next"), desc = "Next hunk/diff" },
|
||||||
|
|
||||||
-- Commands
|
-- Commands
|
||||||
["<leader>g"] = {
|
{ "<leader>g", group = "Git" },
|
||||||
name = "Git",
|
{ "<leader>gb", gitsigns.toggle_current_line_blame, desc = "Toggle blame virtual text" },
|
||||||
-- Actions
|
{ "<leader>gd", gitsigns.diffthis, desc = "Diff buffer" },
|
||||||
b = { gitsigns.toggle_current_line_blame, "Toggle blame virtual text" },
|
{ "<leader>gD", utils.partial(gitsigns.diffthis, "~"), desc = "Diff buffer against last commit" },
|
||||||
d = { gitsigns.diffthis, "Diff buffer" },
|
{ "<leader>gg", "<cmd>Git<CR>", desc = "Git status" },
|
||||||
-- stylua: ignore
|
{ "<leader>gh", gitsigns.toggle_deleted, desc = "Show deleted hunks" },
|
||||||
D = { function() gitsigns.diffthis("~") end, "Diff buffer against last commit" },
|
{ "<leader>gL", "<cmd>:sp<CR><C-w>T:Gllog --follow -- %:p<CR>", desc = "Current buffer log" },
|
||||||
g = { "<cmd>Git<CR>", "Git status" },
|
{ "<leader>gm", "<Plug>(git-messenger)", desc = "Current line blame" },
|
||||||
h = { gitsigns.toggle_deleted, "Show deleted hunks" },
|
{ "<leader>gp", gitsigns.preview_hunk, desc = "Preview hunk" },
|
||||||
L = { "<cmd>:sp<CR><C-w>T:Gllog --follow -- %:p<CR>", "Current buffer log" },
|
{ "<leader>gr", gitsigns.reset_hunk, desc = "Restore hunk" },
|
||||||
m = { "<Plug>(git-messenger)", "Current line blame" },
|
{ "<leader>gR", gitsigns.reset_buffer, desc = "Restore buffer" },
|
||||||
p = { gitsigns.preview_hunk, "Preview hunk" },
|
{ "<leader>gs", gitsigns.stage_hunk, desc = "Stage hunk" },
|
||||||
r = { gitsigns.reset_hunk, "Restore hunk" },
|
{ "<leader>gS", gitsigns.stage_buffer, desc = "Stage buffer" },
|
||||||
R = { gitsigns.reset_buffer, "Restore buffer" },
|
{ "<leader>gu", gitsigns.undo_stage_hunk, desc = "Undo stage hunk" },
|
||||||
s = { gitsigns.stage_hunk, "Stage hunk" },
|
{ "<leader>g[", utils.partial(gitsigns.nav_hunk, "prev"), desc = "Previous hunk" },
|
||||||
S = { gitsigns.stage_buffer, "Stage buffer" },
|
{ "<leader>g]", utils.partial(gitsigns.nav_hunk, "next"), desc = "Next hunk" },
|
||||||
u = { gitsigns.undo_stage_hunk, "Undo stage hunk" },
|
|
||||||
["["] = { gitsigns.prev_hunk, "Previous hunk" },
|
|
||||||
["]"] = { gitsigns.next_hunk, "Next hunk" },
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
local objects = {
|
local objects = {
|
||||||
["ih"] = { gitsigns.select_hunk, "Git hunk" },
|
mode = "o",
|
||||||
|
{ "ih", gitsigns.select_hunk, desc = "Git hunk" },
|
||||||
}
|
}
|
||||||
|
-- Visual
|
||||||
local visual = {
|
local visual = {
|
||||||
["ih"] = { gitsigns.select_hunk, "Git hunk" },
|
mode = { "x" },
|
||||||
|
{ "ih", gitsigns.select_hunk, desc = "Git hunk" },
|
||||||
-- Only the actual command can make use of the visual selection...
|
{ "<leader>g", group = "Git" },
|
||||||
["<leader>g"] = {
|
{ "<leader>gp", gitsigns.preview_hunk, desc = "Preview selection" },
|
||||||
name = "Git",
|
{ "<leader>gr", make_visual(gitsigns.reset_hunk), desc = "Restore selection" },
|
||||||
p = { ":Gitsigns preview_hunk<CR>", "Preview selection" },
|
{ "<leader>gs", make_visual(gitsigns.stage_hunk), desc = "Stage selection" },
|
||||||
r = { ":Gitsigns reset_hunk<CR>", "Restore selection" },
|
{ "<leader>gu", gitsigns.undo_stage_hunk, desc = "Undo stage selection" },
|
||||||
s = { ":Gitsigns stage_hunk<CR>", "Stage selection" },
|
|
||||||
u = { ":Gitsigns undo_stage_hunk<CR>", "Undo stage selection" },
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wk.register(keys, { buffer = bufnr })
|
wk.add(keys)
|
||||||
wk.register(objects, { buffer = bufnr, mode = "o" })
|
wk.add(objects)
|
||||||
wk.register(visual, { buffer = bufnr, mode = "x" })
|
wk.add(visual)
|
||||||
|
|
|
@ -53,8 +53,8 @@ if utils.is_executable("pyright") then
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
if utils.is_executable("ruff-lsp") then
|
if utils.is_executable("ruff") then
|
||||||
lspconfig.ruff_lsp.setup({
|
lspconfig.ruff.setup({
|
||||||
capabilities = capabilities,
|
capabilities = capabilities,
|
||||||
on_attach = lsp.on_attach,
|
on_attach = lsp.on_attach,
|
||||||
})
|
})
|
||||||
|
@ -74,5 +74,31 @@ 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
|
||||||
|
|
|
@ -18,16 +18,6 @@ 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({
|
||||||
|
@ -56,29 +46,3 @@ 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"),
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
|
|
34
modules/home/vim/plugin/settings/oil.lua
Normal file
34
modules/home/vim/plugin/settings/oil.lua
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
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)
|
|
@ -1,17 +0,0 @@
|
||||||
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 },
|
|
||||||
}
|
|
|
@ -1,4 +1,6 @@
|
||||||
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 = {
|
||||||
|
@ -22,3 +24,14 @@ 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)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
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,
|
||||||
|
@ -14,16 +15,16 @@ ts_config.setup({
|
||||||
-- Jump to matching text objects
|
-- Jump to matching text objects
|
||||||
lookahead = true,
|
lookahead = true,
|
||||||
keymaps = {
|
keymaps = {
|
||||||
["aa"] = "@parameter.outer",
|
["aa"] = { query = "@parameter.outer", desc = "a parameter" },
|
||||||
["ia"] = "@parameter.inner",
|
["ia"] = { query = "@parameter.inner", desc = "inner parameter" },
|
||||||
["ab"] = "@block.outer",
|
["ab"] = { query = "@block.outer", desc = "a block" },
|
||||||
["ib"] = "@block.inner",
|
["ib"] = { query = "@block.inner", desc = "inner block" },
|
||||||
["ac"] = "@class.outer",
|
["ac"] = { query = "@class.outer", desc = "a class" },
|
||||||
["ic"] = "@class.inner",
|
["ic"] = { query = "@class.inner", desc = "inner class" },
|
||||||
["af"] = "@function.outer",
|
["af"] = { query = "@function.outer", desc = "a function" },
|
||||||
["if"] = "@function.inner",
|
["if"] = { query = "@function.inner", desc = "inner function" },
|
||||||
["ak"] = "@comment.outer",
|
["ak"] = { query = "@comment.outer", desc = "a comment" },
|
||||||
["aS"] = "@statement.outer",
|
["aS"] = { query = "@statement.outer", desc = "a statement" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
move = {
|
move = {
|
||||||
|
@ -31,22 +32,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"] = "@function.outer",
|
["]m"] = { query = "@function.outer", desc = "Next method start" },
|
||||||
["]S"] = "@statement.outer",
|
["]S"] = { query = "@statement.outer", desc = "Next statement start" },
|
||||||
["]]"] = "@class.outer",
|
["]]"] = { query = "@class.outer", desc = "Next class start" },
|
||||||
},
|
},
|
||||||
goto_next_end = {
|
goto_next_end = {
|
||||||
["]M"] = "@function.outer",
|
["]M"] = { query = "@function.outer", desc = "Next method end" },
|
||||||
["]["] = "@class.outer",
|
["]["] = { query = "@class.outer", desc = "Next class end" },
|
||||||
},
|
},
|
||||||
goto_previous_start = {
|
goto_previous_start = {
|
||||||
["[m"] = "@function.outer",
|
["[m"] = { query = "@function.outer", desc = "Previous method start" },
|
||||||
["[S"] = "@statement.outer",
|
["[S"] = { query = "@statement.outer", desc = "Previous statement start" },
|
||||||
["[["] = "@class.outer",
|
["[["] = { query = "@class.outer", desc = "Previous class start" },
|
||||||
},
|
},
|
||||||
goto_previous_end = {
|
goto_previous_end = {
|
||||||
["[M"] = "@function.outer",
|
["[M"] = { query = "@function.outer", desc = "Previous method end" },
|
||||||
["[]"] = "@class.outer",
|
["[]"] = { query = "@class.outer", desc = "Previous class end" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,2 +1,33 @@
|
||||||
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)
|
||||||
|
|
|
@ -4,17 +4,23 @@ 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,
|
||||||
command = "setlocal signcolumn=yes",
|
callback = function()
|
||||||
|
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,
|
||||||
command = "setlocal signcolumn=yes",
|
callback = function()
|
||||||
|
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,
|
||||||
command = "setlocal signcolumn=no",
|
callback = function()
|
||||||
|
vim.opt.signcolumn = "no"
|
||||||
|
end,
|
||||||
})
|
})
|
||||||
|
|
|
@ -20,7 +20,7 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
xdg.configFile."wgetrc".text = ''
|
xdg.configFile."wgetrc".text = ''
|
||||||
hsts-file = ${config.xdg.dataHome}/wget-hsts
|
hsts-file = ${config.xdg.stateHome}/wget-hsts
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ in
|
||||||
service = "some-service-name";
|
service = "some-service-name";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
description = "list of block configurations, merged with the defauls";
|
description = "list of block configurations, merged with the defaults";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -127,9 +127,10 @@ 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.*$"; }
|
{ class = "^\\.blueman-manager-wrapped$"; }
|
||||||
|
{ class = "^\\.arandr-wrapped$"; }
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -371,8 +372,7 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
startup = [
|
startup = [
|
||||||
# FIXME
|
# NOTE: rely on systemd user services instead...
|
||||||
# { commdand; always; notification; }
|
|
||||||
];
|
];
|
||||||
|
|
||||||
window = {
|
window = {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
let
|
let
|
||||||
cfg = config.my.home.wm.screen-lock;
|
cfg = config.my.home.wm.screen-lock;
|
||||||
|
|
||||||
notficationCmd =
|
notificationCmd =
|
||||||
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"
|
||||||
notficationCmd
|
notificationCmd
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,7 +11,7 @@ in
|
||||||
enable = true;
|
enable = true;
|
||||||
# File types
|
# File types
|
||||||
mime.enable = true;
|
mime.enable = true;
|
||||||
# File associatons
|
# File associations
|
||||||
mimeApps = {
|
mimeApps = {
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
|
@ -30,9 +30,11 @@ 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 = "";
|
||||||
"gdb/.keep".text = "";
|
"python/.keep".text = "";
|
||||||
"tig/.keep".text = "";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -43,13 +45,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 = "${dataHome}/bash/history";
|
HISTFILE = "${stateHome}/bash/history";
|
||||||
INPUTRC = "${configHome}/readline/inputrc";
|
INPUTRC = "${configHome}/readline/inputrc";
|
||||||
PSQL_HISTORY = "${dataHome}/psql_history";
|
PSQL_HISTORY = "${stateHome}/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 = "${dataHome}/redis/rediscli_history";
|
REDISCLI_HISTFILE = "${stateHome}/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";
|
||||||
|
|
|
@ -68,7 +68,7 @@ in
|
||||||
ignoreSpace = true;
|
ignoreSpace = true;
|
||||||
ignoreDups = true;
|
ignoreDups = true;
|
||||||
share = false;
|
share = false;
|
||||||
path = "${config.xdg.dataHome}/zsh/zsh_history";
|
path = "${config.xdg.stateHome}/zsh/zsh_history";
|
||||||
};
|
};
|
||||||
|
|
||||||
plugins = [
|
plugins = [
|
||||||
|
|
|
@ -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 exectuted
|
# Append commands to history as they are executed
|
||||||
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
|
||||||
|
|
|
@ -24,24 +24,6 @@ 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
|
||||||
|
|
|
@ -26,28 +26,30 @@ in
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable (lib.mkMerge [
|
config = lib.mkIf cfg.enable (lib.mkMerge [
|
||||||
{
|
{
|
||||||
hardware.opengl = {
|
hardware.graphics = {
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
# AMD GPU
|
# AMD GPU
|
||||||
(lib.mkIf (cfg.gpuFlavor == "amd") {
|
(lib.mkIf (cfg.gpuFlavor == "amd") {
|
||||||
boot.initrd.kernelModules = lib.mkIf cfg.amd.enableKernelModule [ "amdgpu" ];
|
hardware.amdgpu = {
|
||||||
|
initrd.enable = cfg.amd.enableKernelModule;
|
||||||
|
# Vulkan
|
||||||
|
amdvlk = lib.mkIf cfg.amd.amdvlk {
|
||||||
|
enable = true;
|
||||||
|
support32Bit = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
hardware.opengl = {
|
hardware.graphics = {
|
||||||
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
|
|
||||||
;
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -59,7 +61,7 @@ in
|
||||||
VDPAU_DRIVER = "va_gl";
|
VDPAU_DRIVER = "va_gl";
|
||||||
};
|
};
|
||||||
|
|
||||||
hardware.opengl = {
|
hardware.graphics = {
|
||||||
extraPackages = with pkgs; [
|
extraPackages = with pkgs; [
|
||||||
# Open CL
|
# Open CL
|
||||||
intel-compute-runtime
|
intel-compute-runtime
|
||||||
|
@ -69,6 +71,13 @@ 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
|
||||||
|
];
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -54,9 +54,6 @@ 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;
|
||||||
})
|
})
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -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 overriden
|
# for the `ScrollMethod` configuration to not be overridden
|
||||||
inputClassSections = lib.mkAfter [
|
inputClassSections = lib.mkAfter [
|
||||||
# MX Ergo
|
# MX Ergo
|
||||||
''
|
''
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Configuration that spans accross system and home, or are almagations of modules
|
# Configuration that spans across system and home, or are almagations of modules
|
||||||
{ ... }:
|
{ ... }:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
|
|
|
@ -9,7 +9,7 @@ in
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
# Enable touchpad support
|
# Enable touchpad support
|
||||||
services.xserver.libinput.enable = true;
|
services.libinput.enable = true;
|
||||||
|
|
||||||
# Enable TLP power management
|
# Enable TLP power management
|
||||||
my.services.tlp.enable = true;
|
my.services.tlp.enable = true;
|
||||||
|
|
|
@ -65,9 +65,7 @@ in
|
||||||
aria-rpc = {
|
aria-rpc = {
|
||||||
port = cfg.rpcPort;
|
port = cfg.rpcPort;
|
||||||
# Proxy websockets for RPC
|
# Proxy websockets for RPC
|
||||||
extraConfig = {
|
websocketsLocations = [ "/" ];
|
||||||
locations."/".proxyWebsockets = true;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
53
modules/nixos/services/audiobookshelf/default.nix
Normal file
53
modules/nixos/services/audiobookshelf/default.nix
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
# Audiobook and podcast library
|
||||||
|
{ config, lib, ... }:
|
||||||
|
let
|
||||||
|
cfg = config.my.services.audiobookshelf;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.my.services.audiobookshelf = with lib; {
|
||||||
|
enable = mkEnableOption "Audiobookshelf, a self-hosted podcast manager";
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 8000;
|
||||||
|
example = 4242;
|
||||||
|
description = "The port on which Audiobookshelf will listen for incoming HTTP traffic.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
services.audiobookshelf = {
|
||||||
|
enable = true;
|
||||||
|
inherit (cfg) port;
|
||||||
|
|
||||||
|
group = "media";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Set-up media group
|
||||||
|
users.groups.media = { };
|
||||||
|
|
||||||
|
my.services.nginx.virtualHosts = {
|
||||||
|
audiobookshelf = {
|
||||||
|
inherit (cfg) port;
|
||||||
|
# Proxy websockets for RPC
|
||||||
|
websocketsLocations = [ "/" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
imports = [
|
imports = [
|
||||||
./adblock
|
./adblock
|
||||||
./aria
|
./aria
|
||||||
|
./audiobookshelf
|
||||||
./backup
|
./backup
|
||||||
./blog
|
./blog
|
||||||
./calibre-web
|
./calibre-web
|
||||||
|
@ -15,6 +16,7 @@
|
||||||
./grocy
|
./grocy
|
||||||
./indexers
|
./indexers
|
||||||
./jellyfin
|
./jellyfin
|
||||||
|
./komga
|
||||||
./lohr
|
./lohr
|
||||||
./matrix
|
./matrix
|
||||||
./mealie
|
./mealie
|
||||||
|
@ -25,7 +27,7 @@
|
||||||
./nginx
|
./nginx
|
||||||
./nix-cache
|
./nix-cache
|
||||||
./paperless
|
./paperless
|
||||||
./pirate
|
./pdf-edit
|
||||||
./podgrab
|
./podgrab
|
||||||
./postgresql
|
./postgresql
|
||||||
./postgresql-backup
|
./postgresql-backup
|
||||||
|
@ -33,6 +35,7 @@
|
||||||
./quassel
|
./quassel
|
||||||
./rss-bridge
|
./rss-bridge
|
||||||
./sabnzbd
|
./sabnzbd
|
||||||
|
./servarr
|
||||||
./ssh-server
|
./ssh-server
|
||||||
./tandoor-recipes
|
./tandoor-recipes
|
||||||
./tlp
|
./tlp
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# A nice UI for various torrent clients
|
# A nice UI for various torrent clients
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, ... }:
|
||||||
let
|
let
|
||||||
cfg = config.my.services.flood;
|
cfg = config.my.services.flood;
|
||||||
in
|
in
|
||||||
|
@ -13,31 +13,13 @@ 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 {
|
||||||
systemd.services.flood = {
|
services.flood = {
|
||||||
description = "Flood torrent UI";
|
enable = true;
|
||||||
after = [ "network.target" ];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
|
|
||||||
serviceConfig = {
|
inherit (cfg) port;
|
||||||
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 = {
|
||||||
|
@ -45,5 +27,7 @@ in
|
||||||
inherit (cfg) port;
|
inherit (cfg) port;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# NOTE: unfortunately flood does not log connection failures for fail2ban
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# A low-ressource, full-featured git forge.
|
# A low-resource, full-featured git forge.
|
||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
let
|
let
|
||||||
cfg = config.my.services.forgejo;
|
cfg = config.my.services.forgejo;
|
||||||
|
@ -83,7 +83,11 @@ in
|
||||||
# I configure my backup system manually below.
|
# I configure my backup system manually below.
|
||||||
dump.enable = false;
|
dump.enable = false;
|
||||||
|
|
||||||
mailerPasswordFile = lib.mkIf cfg.mail.enable cfg.mail.passwordFile;
|
secrets = {
|
||||||
|
mailer = lib.mkIf cfg.mail.enable {
|
||||||
|
PASSWD = cfg.mail.passwordFile;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
DEFAULT = {
|
DEFAULT = {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# A low-ressource, full-featured git forge.
|
# A low-resource, full-featured git forge.
|
||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
let
|
let
|
||||||
cfg = config.my.services.gitea;
|
cfg = config.my.services.gitea;
|
||||||
|
|
|
@ -36,5 +36,7 @@ in
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
useACMEHost = config.networking.domain;
|
useACMEHost = config.networking.domain;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# NOTE: unfortunately grocy does not log connection failures for fail2ban
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,19 +27,31 @@ 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
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
55
modules/nixos/services/komga/default.nix
Normal file
55
modules/nixos/services/komga/default.nix
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
# 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
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -99,7 +99,7 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
"${lohrHome}/.ssh/id_ed25519" = {
|
"${lohrHome}/.ssh/id_ed25519" = {
|
||||||
"f+" = {
|
"L+" = {
|
||||||
user = "lohr";
|
user = "lohr";
|
||||||
group = "lohr";
|
group = "lohr";
|
||||||
mode = "0700";
|
mode = "0700";
|
||||||
|
|
|
@ -26,21 +26,6 @@ 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";
|
||||||
|
@ -106,17 +91,6 @@ 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 = {
|
||||||
|
@ -130,9 +104,6 @@ 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
|
||||||
|
@ -152,10 +123,6 @@ 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...
|
||||||
|
@ -178,11 +145,6 @@ 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 = [
|
||||||
|
@ -228,7 +190,6 @@ 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
|
||||||
|
|
|
@ -35,12 +35,8 @@ in
|
||||||
|
|
||||||
# Use PostgreSQL
|
# Use PostgreSQL
|
||||||
DB_ENGINE = "postgres";
|
DB_ENGINE = "postgres";
|
||||||
POSTGRES_USER = "mealie";
|
# Make it work with socket auth
|
||||||
POSTGRES_PASSWORD = "";
|
POSTGRES_URL_OVERRIDE = "postgresql://mealie:@/mealie?host=/run/postgresql";
|
||||||
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";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -66,7 +62,30 @@ in
|
||||||
my.services.nginx.virtualHosts = {
|
my.services.nginx.virtualHosts = {
|
||||||
mealie = {
|
mealie = {
|
||||||
inherit (cfg) port;
|
inherit (cfg) port;
|
||||||
|
|
||||||
|
extraConfig = {
|
||||||
|
# Allow bulk upload of recipes for import/export
|
||||||
|
locations."/".extraConfig = ''
|
||||||
|
client_max_body_size 0;
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,5 +48,21 @@ 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
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,5 +52,21 @@ 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
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
50
modules/nixos/services/nextcloud/collabora.nix
Normal file
50
modules/nixos/services/nextcloud/collabora.nix
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
# 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"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -4,6 +4,10 @@ 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 {
|
||||||
|
@ -31,7 +35,7 @@ in
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
services.nextcloud = {
|
services.nextcloud = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.nextcloud28;
|
package = pkgs.nextcloud30;
|
||||||
hostName = "nextcloud.${config.networking.domain}";
|
hostName = "nextcloud.${config.networking.domain}";
|
||||||
home = "/var/lib/nextcloud";
|
home = "/var/lib/nextcloud";
|
||||||
maxUploadSize = cfg.maxSize;
|
maxUploadSize = cfg.maxSize;
|
||||||
|
@ -87,5 +91,25 @@ 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
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,16 @@ 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;
|
||||||
|
@ -59,14 +69,15 @@ let
|
||||||
|
|
||||||
extraConfig = mkOption {
|
extraConfig = mkOption {
|
||||||
type = types.attrs; # FIXME: forward type of virtualHosts
|
type = types.attrs; # FIXME: forward type of virtualHosts
|
||||||
example = litteralExample ''
|
example = {
|
||||||
{
|
extraConfig = ''
|
||||||
locations."/socket" = {
|
add_header X-Clacks-Overhead "GNU Terry Pratchett";
|
||||||
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.
|
||||||
|
@ -88,7 +99,7 @@ in
|
||||||
type = types.str;
|
type = types.str;
|
||||||
example = "/var/lib/acme/creds.env";
|
example = "/var/lib/acme/creds.env";
|
||||||
description = ''
|
description = ''
|
||||||
Gandi API key file as an 'EnvironmentFile' (see `systemd.exec(5)`)
|
OVH API key file as an 'EnvironmentFile' (see `systemd.exec(5)`)
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -100,8 +111,7 @@ in
|
||||||
virtualHosts = mkOption {
|
virtualHosts = mkOption {
|
||||||
type = types.attrsOf virtualHostOption;
|
type = types.attrsOf virtualHostOption;
|
||||||
default = { };
|
default = { };
|
||||||
example = litteralExample ''
|
example = {
|
||||||
{
|
|
||||||
gitea = {
|
gitea = {
|
||||||
subdomain = "git";
|
subdomain = "git";
|
||||||
port = 8080;
|
port = 8080;
|
||||||
|
@ -111,15 +121,9 @@ in
|
||||||
};
|
};
|
||||||
jellyfin = {
|
jellyfin = {
|
||||||
port = 8096;
|
port = 8096;
|
||||||
extraConfig = {
|
websocketsLocations = [ "/socket" ];
|
||||||
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.
|
||||||
'';
|
'';
|
||||||
|
@ -163,25 +167,21 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
example = litteralExample ''
|
example = {
|
||||||
{
|
|
||||||
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 = litteralExample ''
|
example = {
|
||||||
{
|
|
||||||
root = [ "alice" ];
|
root = [ "alice" ];
|
||||||
users = [ "alice" "bob" ];
|
users = [ "alice" "bob" ];
|
||||||
}
|
};
|
||||||
'';
|
|
||||||
description = "Groups of users";
|
description = "Groups of users";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -203,6 +203,19 @@ 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
|
||||||
|
@ -249,6 +262,14 @@ 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 [
|
||||||
|
@ -259,8 +280,7 @@ in
|
||||||
}
|
}
|
||||||
# Proxy to port
|
# Proxy to port
|
||||||
(lib.optionalAttrs (args.port != null) {
|
(lib.optionalAttrs (args.port != null) {
|
||||||
locations."/".proxyPass =
|
locations = mkProxyPass args "http://127.0.0.1:${toString args.port}";
|
||||||
"http://127.0.0.1:${toString args.port}";
|
|
||||||
})
|
})
|
||||||
# Serve filesystem content
|
# Serve filesystem content
|
||||||
(lib.optionalAttrs (args.root != null) {
|
(lib.optionalAttrs (args.root != null) {
|
||||||
|
@ -268,8 +288,7 @@ in
|
||||||
})
|
})
|
||||||
# Serve to UNIX socket
|
# Serve to UNIX socket
|
||||||
(lib.optionalAttrs (args.socket != null) {
|
(lib.optionalAttrs (args.socket != null) {
|
||||||
locations."/".proxyPass =
|
locations = mkProxyPass args "http://unix:${args.socket}";
|
||||||
"http://unix:${args.socket}";
|
|
||||||
})
|
})
|
||||||
# Redirect to a different domain
|
# Redirect to a different domain
|
||||||
(lib.optionalAttrs (args.redirect != null) {
|
(lib.optionalAttrs (args.redirect != null) {
|
||||||
|
@ -289,6 +308,7 @@ 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;
|
||||||
|
@ -422,7 +442,8 @@ in
|
||||||
{
|
{
|
||||||
"${domain}" = {
|
"${domain}" = {
|
||||||
extraDomainNames = [ "*.${domain}" ];
|
extraDomainNames = [ "*.${domain}" ];
|
||||||
dnsProvider = "gandiv5";
|
dnsProvider = "ovh";
|
||||||
|
dnsPropagationCheck = false; # OVH is slow
|
||||||
inherit (cfg.acme) credentialsFile;
|
inherit (cfg.acme) credentialsFile;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -59,15 +59,10 @@ 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} \
|
||||||
|
|
|
@ -40,7 +40,7 @@ in
|
||||||
inherit (cfg) priority;
|
inherit (cfg) priority;
|
||||||
};
|
};
|
||||||
|
|
||||||
signKeyPath = cfg.secretKeyFile;
|
signKeyPaths = [ cfg.secretKeyFile ];
|
||||||
};
|
};
|
||||||
|
|
||||||
my.services.nginx.virtualHosts = {
|
my.services.nginx.virtualHosts = {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, ... }:
|
||||||
let
|
let
|
||||||
cfg = config.my.services.paperless;
|
cfg = config.my.services.paperless;
|
||||||
in
|
in
|
||||||
|
@ -61,11 +61,6 @@ 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}";
|
||||||
|
@ -80,65 +75,20 @@ 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;
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services = {
|
# Secret key
|
||||||
paperless-scheduler = {
|
environmentFile = cfg.secretKeyFile;
|
||||||
requires = [ "postgresql.service" ];
|
|
||||||
after = [ "postgresql.service" ];
|
|
||||||
|
|
||||||
serviceConfig = {
|
# Automatic PostgreSQL provisioning
|
||||||
EnvironmentFile = cfg.secretKeyFile;
|
database = {
|
||||||
|
createLocally = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
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
|
||||||
users.groups.media = { };
|
users.groups.media = { };
|
||||||
|
|
||||||
|
@ -152,11 +102,7 @@ in
|
||||||
sso = {
|
sso = {
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
|
websocketsLocations = [ "/" ];
|
||||||
# Enable websockets on root
|
|
||||||
extraConfig = {
|
|
||||||
locations."/".proxyWebsockets = true;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
73
modules/nixos/services/pdf-edit/default.nix
Normal file
73
modules/nixos/services/pdf-edit/default.nix
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
{ 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
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -13,7 +13,16 @@ 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 authentification.
|
definition for Podgrab's authentication.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
dataDir = mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
default = null;
|
||||||
|
example = "/mnt/podgrab";
|
||||||
|
description = ''
|
||||||
|
Path to the directory to store the podcasts. Use default if null
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -29,8 +38,14 @@ in
|
||||||
services.podgrab = {
|
services.podgrab = {
|
||||||
enable = true;
|
enable = true;
|
||||||
inherit (cfg) passwordFile port;
|
inherit (cfg) passwordFile port;
|
||||||
|
|
||||||
|
group = "media";
|
||||||
|
dataDirectory = lib.mkIf (cfg.dataDir != null) cfg.dataDir;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Set-up media group
|
||||||
|
users.groups.media = { };
|
||||||
|
|
||||||
my.services.nginx.virtualHosts = {
|
my.services.nginx.virtualHosts = {
|
||||||
podgrab = {
|
podgrab = {
|
||||||
inherit (cfg) port;
|
inherit (cfg) port;
|
||||||
|
|
|
@ -14,30 +14,34 @@ 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_13;
|
package = pkgs.postgresql_17;
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
# Taken from the manual
|
# Taken from the manual
|
||||||
(lib.mkIf cfg.upgradeScript {
|
(lib.mkIf cfg.upgradeScript {
|
||||||
containers.temp-pg.config.services.postgresql = {
|
|
||||||
enable = true;
|
|
||||||
package = pkgs.postgresql_13;
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.systemPackages =
|
environment.systemPackages =
|
||||||
let
|
let
|
||||||
newpg = config.containers.temp-pg.config.services.postgresql;
|
pgCfg = config.services.postgresql;
|
||||||
|
newPackage' = pkgs.postgresql_17;
|
||||||
|
|
||||||
|
oldPackage = if pgCfg.enableJIT then pgCfg.package.withJIT else pgCfg.package;
|
||||||
|
oldData = pgCfg.dataDir;
|
||||||
|
oldBin = "${if pgCfg.extensions == [] then oldPackage else oldPackage.withPackages pgCfg.extensions}/bin";
|
||||||
|
|
||||||
|
newPackage = if pgCfg.enableJIT then newPackage'.withJIT else newPackage';
|
||||||
|
newData = "/var/lib/postgresql/${newPackage.psqlSchema}";
|
||||||
|
newBin = "${if pgCfg.extensions == [] then newPackage else newPackage.withPackages pgCfg.extensions}/bin";
|
||||||
in
|
in
|
||||||
[
|
[
|
||||||
(pkgs.writeScriptBin "upgrade-pg-cluster" ''
|
(pkgs.writeScriptBin "upgrade-pg-cluster" ''
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -x
|
set -eux
|
||||||
export OLDDATA="${config.services.postgresql.dataDir}"
|
export OLDDATA="${oldData}"
|
||||||
export NEWDATA="${newpg.dataDir}"
|
export NEWDATA="${newData}"
|
||||||
export OLDBIN="${config.services.postgresql.package}/bin"
|
export OLDBIN="${oldBin}"
|
||||||
export NEWBIN="${newpg.package}/bin"
|
export NEWBIN="${newBin}"
|
||||||
|
|
||||||
if [ "$OLDDATA" -ef "$NEWDATA" ]; then
|
if [ "$OLDDATA" -ef "$NEWDATA" ]; then
|
||||||
echo "Cannot migrate to same data directory" >&2
|
echo "Cannot migrate to same data directory" >&2
|
||||||
|
@ -46,14 +50,21 @@ in
|
||||||
|
|
||||||
install -d -m 0700 -o postgres -g postgres "$NEWDATA"
|
install -d -m 0700 -o postgres -g postgres "$NEWDATA"
|
||||||
cd "$NEWDATA"
|
cd "$NEWDATA"
|
||||||
sudo -u postgres $NEWBIN/initdb -D "$NEWDATA"
|
sudo -u postgres "$NEWBIN/initdb" -D "$NEWDATA"
|
||||||
|
|
||||||
systemctl stop postgresql # old one
|
systemctl stop postgresql # old one
|
||||||
|
|
||||||
sudo -u postgres $NEWBIN/pg_upgrade \
|
sudo -u postgres "$NEWBIN/pg_upgrade" \
|
||||||
--old-datadir "$OLDDATA" --new-datadir "$NEWDATA" \
|
--old-datadir "$OLDDATA" --new-datadir "$NEWDATA" \
|
||||||
--old-bindir $OLDBIN --new-bindir $NEWBIN \
|
--old-bindir "$OLDBIN" --new-bindir "$NEWBIN" \
|
||||||
"$@"
|
"$@"
|
||||||
|
|
||||||
|
cat << EOF
|
||||||
|
Run the following commands after setting:
|
||||||
|
services.postgresql.package = pkgs.postgresql_${lib.versions.major newPackage.version}
|
||||||
|
sudo -u postgres vacuumdb --all --analyze-in-stages
|
||||||
|
${newData}/delete_old_cluster.sh
|
||||||
|
EOF
|
||||||
'')
|
'')
|
||||||
];
|
];
|
||||||
})
|
})
|
||||||
|
|
|
@ -53,6 +53,20 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# FIXME: fail2ban
|
services.fail2ban.jails = {
|
||||||
|
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
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,9 @@ in
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
services.rss-bridge = {
|
services.rss-bridge = {
|
||||||
enable = true;
|
enable = true;
|
||||||
whitelist = [ "*" ]; # Whitelist all
|
config = {
|
||||||
|
system.enabled_bridges = [ "*" ]; # Whitelist all
|
||||||
|
};
|
||||||
virtualHost = "rss-bridge.${config.networking.domain}";
|
virtualHost = "rss-bridge.${config.networking.domain}";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,13 @@
|
||||||
# [1]: https://youtu.be/I26Ql-uX6AM
|
# [1]: https://youtu.be/I26Ql-uX6AM
|
||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
let
|
let
|
||||||
cfg = config.my.services.pirate;
|
cfg = config.my.services.servarr;
|
||||||
|
|
||||||
ports = {
|
ports = {
|
||||||
bazarr = 6767;
|
bazarr = 6767;
|
||||||
lidarr = 8686;
|
lidarr = 8686;
|
||||||
radarr = 7878;
|
radarr = 7878;
|
||||||
|
readarr = 8787;
|
||||||
sonarr = 8989;
|
sonarr = 8989;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ let
|
||||||
]);
|
]);
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.my.services.pirate = {
|
options.my.services.servarr = {
|
||||||
enable = lib.mkEnableOption "Media automation";
|
enable = lib.mkEnableOption "Media automation";
|
||||||
|
|
||||||
bazarr = {
|
bazarr = {
|
||||||
|
@ -67,6 +68,10 @@ 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";
|
||||||
};
|
};
|
||||||
|
@ -85,8 +90,21 @@ 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"
|
||||||
|
];
|
||||||
|
})
|
||||||
]);
|
]);
|
||||||
}
|
}
|
|
@ -73,7 +73,16 @@ in
|
||||||
my.services.nginx.virtualHosts = {
|
my.services.nginx.virtualHosts = {
|
||||||
recipes = {
|
recipes = {
|
||||||
inherit (cfg) port;
|
inherit (cfg) port;
|
||||||
|
|
||||||
|
extraConfig = {
|
||||||
|
# Allow bulk upload of recipes for import/export
|
||||||
|
locations."/".extraConfig = ''
|
||||||
|
client_max_body_size 0;
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# NOTE: unfortunately tandoor-recipes does not log connection failures for fail2ban
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,5 +90,7 @@ in
|
||||||
allowedTCPPorts = [ cfg.peerPort ];
|
allowedTCPPorts = [ cfg.peerPort ];
|
||||||
allowedUDPPorts = [ cfg.peerPort ];
|
allowedUDPPorts = [ cfg.peerPort ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# NOTE: unfortunately transmission does not log connection failures for fail2ban
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
# Ues the host's timezone
|
# Use 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,5 +99,7 @@ in
|
||||||
config.services.vikunja.settings.files.basepath
|
config.services.vikunja.settings.files.basepath
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# NOTE: unfortunately vikunja does not log connection failures for fail2ban
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,7 +206,7 @@ in
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
# Additional inteface is only used to get access to "LAN" from wireguard
|
# Additional interface 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}"
|
||||||
|
|
|
@ -44,6 +44,8 @@ in
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
# Same option as upstream, without @setuid
|
# Same option as upstream, without @setuid
|
||||||
SystemCallFilter = lib.mkForce "~@clock @privileged @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap";
|
SystemCallFilter = lib.mkForce "~@clock @privileged @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap";
|
||||||
|
# NodeJS requires RWX memory...
|
||||||
|
MemoryDenyWriteExecute = lib.mkForce false;
|
||||||
|
|
||||||
BindPaths = [
|
BindPaths = [
|
||||||
"/nix/var/nix/daemon-socket/socket"
|
"/nix/var/nix/daemon-socket/socket"
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue