diff --git a/.drone.yml b/.drone.yml
deleted file mode 100644
index b192230..0000000
--- a/.drone.yml
+++ /dev/null
@@ -1,27 +0,0 @@
----
-kind: pipeline
-type: exec
-name: NixOS config check
-
-steps:
-- name: nix flake check
- commands:
- - nix flake check
-
-- name: notifiy
- commands:
- - nix run .#matrix-notifier
- environment:
- ADDRESS:
- from_secret: matrix_homeserver
- ROOM:
- from_secret: matrix_roomid
- USER:
- from_secret: matrix_username
- PASS:
- from_secret: matrix_password
- when:
- status:
- - failure
- - success
-...
diff --git a/.envrc b/.envrc
index 4b297a5..95ed6fb 100644
--- a/.envrc
+++ b/.envrc
@@ -1,9 +1,10 @@
-use_flake() {
- watch_file flake.nix
- watch_file flake.lock
- eval "$(nix print-dev-env)"
-}
+if ! has nix_direnv_version || ! nix_direnv_version 2.2.1; then
+ source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.2.1/direnvrc" "sha256-zelF0vLbEl5uaqrfIzbgNzJWGmLzCmYAkInj/LNxvKs="
+fi
-ulimit -s unlimited # Bypass current bug in `nix` flakes evaluation
use flake
+
+watch_file ./flake/checks.nix
+watch_file ./flake/dev-shells.nix
+
eval "$shellHooks"
diff --git a/.stylua.toml b/.stylua.toml
new file mode 100644
index 0000000..394e884
--- /dev/null
+++ b/.stylua.toml
@@ -0,0 +1 @@
+indent_type = "Spaces"
diff --git a/.woodpecker/check.yml b/.woodpecker/check.yml
new file mode 100644
index 0000000..d7c5dff
--- /dev/null
+++ b/.woodpecker/check.yml
@@ -0,0 +1,26 @@
+labels:
+ backend: local
+
+pipeline:
+- name: nix flake check
+ image: bash
+ commands:
+ - nix flake check
+
+- name: notifiy
+ image: bash
+ secrets:
+ - source: matrix_homeserver
+ target: address
+ - source: matrix_roomid
+ target: room
+ - source: matrix_username
+ target: user
+ - source: matrix_password
+ target: pass
+ commands:
+ - nix run '.#matrix-notifier'
+ when:
+ status:
+ - failure
+ - success
diff --git a/bootstrap.sh b/bootstrap.sh
index df41c29..b1c418e 100755
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -1,5 +1,5 @@
#!/usr/bin/env nix-shell
-#! nix-shell -i bash -p bitwarden-cli git gnupg jq nixFlakes
+#! nix-shell -i bash -p bitwarden-cli git gnupg jq nix
# Command failure is script failure
set -e
@@ -58,8 +58,8 @@ get_ssh() {
get_doc "SysAdmin/SSH" "shared-key-public" "$HOME/.ssh/shared_rsa.pub" 644
get_doc "SysAdmin/SSH" "shared-key-private" "$HOME/.ssh/shared_rsa" 600
- get_doc "SysAdmin/SSH" "agenix-public" "$HOME/.ssh/id_ed25519.pub" 644
- get_doc "SysAdmin/SSH" "agenix-private" "$HOME/.ssh/id_ed25519" 600
+ get_doc "SysAdmin/SSH" "agenix-public" "$HOME/.ssh/agenix.pub" 644
+ get_doc "SysAdmin/SSH" "agenix-private" "$HOME/.ssh/agenix" 600
}
get_pgp() {
@@ -87,15 +87,6 @@ get_creds() {
get_pgp
}
-setup_gpg() {
- info 'Setting up loopback pinentry for GnuPG'
- echo "allow-loopback-pinentry" > ~/.gnupg/gpg-agent.conf
-
- info 'Signing dummy message to ensure GnuPG key is usable by `git-crypt`'
- echo whatever | gpg --clearsign --armor --pinentry loopback --output /dev/null
-}
-
[ -z "$NOCREDS" ] && get_creds
-[ -z "$NOGPG" ] && setup_gpg
nix --experimental-features 'nix-command flakes' develop
diff --git a/flake.lock b/flake.lock
index db60e45..b3c3e01 100644
--- a/flake.lock
+++ b/flake.lock
@@ -2,16 +2,20 @@
"nodes": {
"agenix": {
"inputs": {
+ "darwin": "darwin",
+ "home-manager": [
+ "home-manager"
+ ],
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
- "lastModified": 1646105662,
- "narHash": "sha256-jdXCZbGZL0SWWi29GnAOFHUh/QvvP0IyaVLv1ZTDkBI=",
+ "lastModified": 1690228878,
+ "narHash": "sha256-9Xe7JV0krp4RJC9W9W9WutZVlw6BlHTFMiUP/k48LQY=",
"owner": "ryantm",
"repo": "agenix",
- "rev": "297cd58b418249240b9f1f155d52b1b17f292884",
+ "rev": "d8c973fd228949736dedf61b7f8cc1ece3236792",
"type": "github"
},
"original": {
@@ -21,22 +25,105 @@
"type": "github"
}
},
- "futils": {
+ "darwin": {
+ "inputs": {
+ "nixpkgs": [
+ "agenix",
+ "nixpkgs"
+ ]
+ },
"locked": {
- "lastModified": 1644229661,
- "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=",
+ "lastModified": 1673295039,
+ "narHash": "sha256-AsdYgE8/GPwcelGgrntlijMg4t3hLFJFCRF3tL5WVjA=",
+ "owner": "lnl7",
+ "repo": "nix-darwin",
+ "rev": "87b9d090ad39b25b2400029c64825fc2a8868943",
+ "type": "github"
+ },
+ "original": {
+ "owner": "lnl7",
+ "ref": "master",
+ "repo": "nix-darwin",
+ "type": "github"
+ }
+ },
+ "flake-compat": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1673956053,
+ "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
+ "type": "github"
+ },
+ "original": {
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "type": "github"
+ }
+ },
+ "flake-parts": {
+ "inputs": {
+ "nixpkgs-lib": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1690933134,
+ "narHash": "sha256-ab989mN63fQZBFrkk4Q8bYxQCktuHmBIBqUG1jl6/FQ=",
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "rev": "59cf3f1447cfc75087e7273b04b31e689a8599fb",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "ref": "main",
+ "repo": "flake-parts",
+ "type": "github"
+ }
+ },
+ "futils": {
+ "inputs": {
+ "systems": "systems"
+ },
+ "locked": {
+ "lastModified": 1689068808,
+ "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=",
"owner": "numtide",
"repo": "flake-utils",
- "rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797",
+ "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4",
"type": "github"
},
"original": {
"owner": "numtide",
- "ref": "master",
+ "ref": "main",
"repo": "flake-utils",
"type": "github"
}
},
+ "gitignore": {
+ "inputs": {
+ "nixpkgs": [
+ "pre-commit-hooks",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1660459072,
+ "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=",
+ "owner": "hercules-ci",
+ "repo": "gitignore.nix",
+ "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "gitignore.nix",
+ "type": "github"
+ }
+ },
"home-manager": {
"inputs": {
"nixpkgs": [
@@ -44,11 +131,11 @@
]
},
"locked": {
- "lastModified": 1646559628,
- "narHash": "sha256-WDoqxH/IPTV8CkI15wwzvXYgXq9UPr8xd8WKziuaynw=",
+ "lastModified": 1691039228,
+ "narHash": "sha256-iPNZJ1LvfUf1Y456ewC0DXgf99TNssG8OLObOyqxO6M=",
"owner": "nix-community",
"repo": "home-manager",
- "rev": "afe96e7433c513bf82375d41473c57d1f66b4e68",
+ "rev": "86dd48d70a2e2c17e84e747ba4faa92453e68d4a",
"type": "github"
},
"original": {
@@ -60,11 +147,11 @@
},
"nixpkgs": {
"locked": {
- "lastModified": 1646497237,
- "narHash": "sha256-Ccpot1h/rV8MgcngDp5OrdmLTMaUTbStZTR5/sI7zW0=",
+ "lastModified": 1691006197,
+ "narHash": "sha256-DbtxVWPt+ZP5W0Usg7jAyTomIM//c3Jtfa59Ht7AV8s=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "062a0c5437b68f950b081bbfc8a699d57a4ee026",
+ "rev": "66aedfd010204949cb225cf749be08cb13ce1813",
"type": "github"
},
"original": {
@@ -76,11 +163,11 @@
},
"nur": {
"locked": {
- "lastModified": 1646721260,
- "narHash": "sha256-r8ZWtEwiRxLKOtsT2yvU9Rs1oqL/RsSkPkgupXsw1bU=",
+ "lastModified": 1691139289,
+ "narHash": "sha256-cZtqvYztpGwLtAsfrzY2VeTfFdW3HBwX7m1KV2Zy2nw=",
"owner": "nix-community",
"repo": "NUR",
- "rev": "25adb63e9381cb0342cdbe2d2d56266f4974a2c5",
+ "rev": "cb20b89d5b355c53a18dd149e7104a67381c7c17",
"type": "github"
},
"original": {
@@ -92,19 +179,24 @@
},
"pre-commit-hooks": {
"inputs": {
+ "flake-compat": "flake-compat",
"flake-utils": [
"futils"
],
+ "gitignore": "gitignore",
"nixpkgs": [
"nixpkgs"
+ ],
+ "nixpkgs-stable": [
+ "nixpkgs"
]
},
"locked": {
- "lastModified": 1646153636,
- "narHash": "sha256-AlWHMzK+xJ1mG267FdT8dCq/HvLCA6jwmx2ZUy5O8tY=",
+ "lastModified": 1691093055,
+ "narHash": "sha256-sjNWYpDHc6vx+/M0WbBZKltR0Avh2S43UiDbmYtfHt0=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
- "rev": "b6bc0b21e1617e2b07d8205e7fae7224036dfa4b",
+ "rev": "ebb43bdacd1af8954d04869c77bc3b61fde515e4",
"type": "github"
},
"original": {
@@ -117,12 +209,28 @@
"root": {
"inputs": {
"agenix": "agenix",
+ "flake-parts": "flake-parts",
"futils": "futils",
"home-manager": "home-manager",
"nixpkgs": "nixpkgs",
"nur": "nur",
"pre-commit-hooks": "pre-commit-hooks"
}
+ },
+ "systems": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
}
},
"root": "root",
diff --git a/flake.nix b/flake.nix
index 3b8c722..8e46ea3 100644
--- a/flake.nix
+++ b/flake.nix
@@ -7,15 +7,26 @@
repo = "agenix";
ref = "main";
inputs = {
+ home-manager.follows = "home-manager";
nixpkgs.follows = "nixpkgs";
};
};
+ flake-parts = {
+ type = "github";
+ owner = "hercules-ci";
+ repo = "flake-parts";
+ ref = "main";
+ inputs = {
+ nixpkgs-lib.follows = "nixpkgs";
+ };
+ };
+
futils = {
type = "github";
owner = "numtide";
repo = "flake-utils";
- ref = "master";
+ ref = "main";
};
home-manager = {
@@ -50,116 +61,11 @@
inputs = {
flake-utils.follows = "futils";
nixpkgs.follows = "nixpkgs";
+ nixpkgs-stable.follows = "nixpkgs";
};
};
};
- outputs =
- inputs @
- { self
- , agenix
- , futils
- , home-manager
- , nixpkgs
- , nur
- , pre-commit-hooks
- }:
- let
- inherit (futils.lib) eachDefaultSystem;
-
- lib = nixpkgs.lib.extend (self: super: {
- my = import ./lib { inherit inputs; pkgs = nixpkgs; lib = self; };
- });
-
- defaultModules = [
- ({ ... }: {
- # Let 'nixos-version --json' know about the Git revision
- system.configurationRevision = self.rev or "dirty";
- })
- {
- nixpkgs.overlays = (lib.attrValues self.overlays) ++ [
- nur.overlay
- ];
- }
- # Include generic settings
- ./modules
- # Include bundles of settings
- ./profiles
- ];
-
- buildHost = name: system: lib.nixosSystem {
- inherit system;
- modules = defaultModules ++ [
- (./. + "/machines/${name}")
- ];
- specialArgs = {
- # Use my extended lib in NixOS configuration
- inherit lib;
- # Inject inputs to use them in global registry
- inherit inputs;
- };
- };
- in
- eachDefaultSystem
- (system:
- let
- pkgs = nixpkgs.legacyPackages.${system};
- in
- rec {
- apps = {
- diff-flake = futils.lib.mkApp { drv = packages.diff-flake; };
- };
-
- checks = {
- pre-commit = pre-commit-hooks.lib.${system}.run {
- src = ./.;
-
- hooks = {
- nixpkgs-fmt = {
- enable = true;
- };
-
- shellcheck = {
- enable = true;
- };
- };
- };
- };
-
- defaultApp = apps.diff-flake;
-
- devShell = pkgs.mkShell {
- name = "NixOS-config";
-
- nativeBuildInputs = with pkgs; [
- gitAndTools.pre-commit
- nixpkgs-fmt
- ];
-
- inherit (self.checks.${system}.pre-commit) shellHook;
- };
-
- packages =
- let
- inherit (futils.lib) filterPackages flattenTree;
- packages = import ./pkgs { inherit pkgs; };
- flattenedPackages = flattenTree packages;
- finalPackages = filterPackages system flattenedPackages;
- in
- finalPackages;
- }) // {
- overlay = self.overlays.pkgs;
-
- overlays = import ./overlays // {
- lib = final: prev: { inherit lib; };
- pkgs = final: prev: {
- ambroisie = prev.recurseIntoAttrs (import ./pkgs { pkgs = prev; });
- };
- };
-
- nixosConfigurations = lib.mapAttrs buildHost {
- aramis = "x86_64-linux";
- porthos = "x86_64-linux";
- };
- };
+ # Can't eta-reduce a flake outputs...
+ outputs = inputs: import ./flake inputs;
}
diff --git a/flake/apps.nix b/flake/apps.nix
new file mode 100644
index 0000000..f8dc2de
--- /dev/null
+++ b/flake/apps.nix
@@ -0,0 +1,9 @@
+{ inputs, ... }:
+{
+ perSystem = { self', ... }: {
+ apps = {
+ diff-flake = inputs.futils.lib.mkApp { drv = self'.packages.diff-flake; };
+ default = self'.apps.diff-flake;
+ };
+ };
+}
diff --git a/flake/checks.nix b/flake/checks.nix
new file mode 100644
index 0000000..98e49bd
--- /dev/null
+++ b/flake/checks.nix
@@ -0,0 +1,33 @@
+{ inputs, ... }:
+{
+ imports = [
+ inputs.pre-commit-hooks.flakeModule
+ ];
+
+ perSystem = { ... }: {
+ pre-commit = {
+ # Add itself to `nix flake check`
+ check.enable = true;
+
+ settings = {
+ hooks = {
+ deadnix = {
+ enable = true;
+ };
+
+ nixpkgs-fmt = {
+ enable = true;
+ };
+
+ shellcheck = {
+ enable = true;
+ };
+
+ stylua = {
+ enable = true;
+ };
+ };
+ };
+ };
+ };
+}
diff --git a/flake/default.nix b/flake/default.nix
new file mode 100644
index 0000000..65102e1
--- /dev/null
+++ b/flake/default.nix
@@ -0,0 +1,22 @@
+{ flake-parts
+, futils
+, ...
+} @ inputs:
+let
+ mySystems = futils.lib.defaultSystems;
+in
+flake-parts.lib.mkFlake { inherit inputs; } {
+ systems = mySystems;
+
+ imports = [
+ ./apps.nix
+ ./checks.nix
+ ./dev-shells.nix
+ ./home-manager.nix
+ ./lib.nix
+ ./nixos.nix
+ ./overlays.nix
+ ./packages.nix
+ ./templates.nix
+ ];
+}
diff --git a/flake/dev-shells.nix b/flake/dev-shells.nix
new file mode 100644
index 0000000..d5f5989
--- /dev/null
+++ b/flake/dev-shells.nix
@@ -0,0 +1,19 @@
+{ ... }:
+{
+ perSystem = { config, pkgs, ... }: {
+ devShells = {
+ default = pkgs.mkShellNoCC {
+ name = "NixOS-config";
+
+ nativeBuildInputs = with pkgs; [
+ gitAndTools.pre-commit
+ nixpkgs-fmt
+ ];
+
+ shellHook = ''
+ ${config.pre-commit.installationScript}
+ '';
+ };
+ };
+ };
+}
diff --git a/flake/home-manager.nix b/flake/home-manager.nix
new file mode 100644
index 0000000..c55c8dd
--- /dev/null
+++ b/flake/home-manager.nix
@@ -0,0 +1,61 @@
+{ self, inputs, lib, ... }:
+let
+ defaultModules = [
+ # Include generic settings
+ "${self}/home"
+ {
+ # Basic user information defaults
+ home.username = lib.mkDefault "ambroisie";
+ home.homeDirectory = lib.mkDefault "/home/ambroisie";
+
+ # Make it a Linux installation by default
+ targets.genericLinux.enable = lib.mkDefault true;
+
+ # Enable home-manager
+ programs.home-manager.enable = true;
+ }
+ ];
+
+ mkHome = name: system: inputs.home-manager.lib.homeManagerConfiguration {
+ # Work-around for home-manager
+ # * not letting me set `lib` as an extraSpecialArgs
+ # * not respecting `nixpkgs.overlays` [1]
+ # [1]: https://github.com/nix-community/home-manager/issues/2954
+ pkgs = import inputs.nixpkgs {
+ inherit system;
+
+ overlays = (lib.attrValues self.overlays) ++ [
+ inputs.nur.overlay
+ ];
+ };
+
+ modules = defaultModules ++ [
+ "${self}/hosts/homes/${name}"
+ ];
+
+ extraSpecialArgs = {
+ # Inject inputs to use them in global registry
+ inherit inputs;
+ };
+ };
+
+ hosts = {
+ "ambroisie@ambroisie" = "x86_64-linux"; # Unfortunate naming here...
+ };
+in
+{
+ perSystem = { system, ... }: {
+ # Work-around for https://github.com/nix-community/home-manager/issues/3075
+ legacyPackages = {
+ homeConfigurations =
+ let
+ filteredHosts = lib.filterAttrs (_: v: v == system) hosts;
+ allHosts = filteredHosts // {
+ # Default configuration
+ ambroisie = system;
+ };
+ in
+ lib.mapAttrs mkHome allHosts;
+ };
+ };
+}
diff --git a/flake/lib.nix b/flake/lib.nix
new file mode 100644
index 0000000..12e89c3
--- /dev/null
+++ b/flake/lib.nix
@@ -0,0 +1,11 @@
+{ self, inputs, ... }:
+let
+ inherit (inputs) nixpkgs;
+
+ lib = nixpkgs.lib.extend (final: _: {
+ my = import "${self}/lib" { inherit inputs; pkgs = nixpkgs; lib = final; };
+ });
+in
+{
+ flake.lib = lib;
+}
diff --git a/flake/nixos.nix b/flake/nixos.nix
new file mode 100644
index 0000000..9eb6388
--- /dev/null
+++ b/flake/nixos.nix
@@ -0,0 +1,39 @@
+{ self, inputs, ... }:
+let
+ inherit (self) lib;
+
+ defaultModules = [
+ {
+ # Let 'nixos-version --json' know about the Git revision
+ system.configurationRevision = self.rev or "dirty";
+ }
+ {
+ nixpkgs.overlays = (lib.attrValues self.overlays) ++ [
+ inputs.nur.overlay
+ ];
+ }
+ # Include generic settings
+ "${self}/modules"
+ # Include bundles of settings
+ "${self}/profiles"
+ ];
+
+ buildHost = name: system: lib.nixosSystem {
+ inherit system;
+ modules = defaultModules ++ [
+ "${self}/hosts/nixos/${name}"
+ ];
+ specialArgs = {
+ # Use my extended lib in NixOS configuration
+ inherit lib;
+ # Inject inputs to use them in global registry
+ inherit inputs;
+ };
+ };
+in
+{
+ flake.nixosConfigurations = lib.mapAttrs buildHost {
+ aramis = "x86_64-linux";
+ porthos = "x86_64-linux";
+ };
+}
diff --git a/flake/overlays.nix b/flake/overlays.nix
new file mode 100644
index 0000000..0c47989
--- /dev/null
+++ b/flake/overlays.nix
@@ -0,0 +1,17 @@
+{ self, ... }:
+let
+ default-overlays = import "${self}/overlays";
+
+ additional-overlays = {
+ # Expose my expanded library
+ lib = _final: _prev: { inherit (self) lib; };
+
+ # Expose my custom packages
+ pkgs = _final: prev: {
+ ambroisie = prev.recurseIntoAttrs (import "${self}/pkgs" { pkgs = prev; });
+ };
+ };
+in
+{
+ flake.overlays = default-overlays // additional-overlays;
+}
diff --git a/flake/packages.nix b/flake/packages.nix
new file mode 100644
index 0000000..3515071
--- /dev/null
+++ b/flake/packages.nix
@@ -0,0 +1,13 @@
+{ self, inputs, ... }:
+{
+ perSystem = { pkgs, system, ... }: {
+ packages =
+ let
+ inherit (inputs.futils.lib) filterPackages flattenTree;
+ packages = import "${self}/pkgs" { inherit pkgs; };
+ flattenedPackages = flattenTree packages;
+ finalPackages = filterPackages system flattenedPackages;
+ in
+ finalPackages;
+ };
+}
diff --git a/flake/templates.nix b/flake/templates.nix
new file mode 100644
index 0000000..28e534e
--- /dev/null
+++ b/flake/templates.nix
@@ -0,0 +1,4 @@
+{ self, ... }:
+{
+ flake.templates = import "${self}/templates";
+}
diff --git a/home/aliases/default.nix b/home/aliases/default.nix
new file mode 100644
index 0000000..259f148
--- /dev/null
+++ b/home/aliases/default.nix
@@ -0,0 +1,26 @@
+{ config, lib, ... }:
+let
+ cfg = config.my.home.aliases;
+in
+{
+ options.my.home.aliases = with lib; {
+ enable = my.mkDisableOption "shell aliases configuration";
+ };
+
+ config = lib.mkIf cfg.enable {
+ home = {
+ shellAliases = {
+ # I like pretty colors
+ diff = "diff --color=auto";
+ grep = "grep --color=auto";
+ egrep = "egrep --color=auto";
+ fgrep = "fgrep --color=auto";
+ ls = "ls --color=auto";
+
+ # Well-known ls aliases
+ l = "ls -alh";
+ ll = "ls -l";
+ };
+ };
+ };
+}
diff --git a/home/atuin/default.nix b/home/atuin/default.nix
new file mode 100644
index 0000000..19a6fb9
--- /dev/null
+++ b/home/atuin/default.nix
@@ -0,0 +1,31 @@
+{ config, lib, ... }:
+let
+ cfg = config.my.home.atuin;
+in
+{
+ options.my.home.atuin = with lib; {
+ enable = my.mkDisableOption "atuin configuration";
+ };
+
+ config = lib.mkIf cfg.enable {
+ programs.atuin = {
+ enable = true;
+
+ flags = [
+ # I *despise* this hijacking of the up key, even though I use Ctrl-p
+ "--disable-up-arrow"
+ ];
+
+ settings = {
+ # The package is managed by Nix
+ update_check = false;
+ # I don't care for the fancy display
+ style = "compact";
+ # Get closer to fzf's fuzzy search
+ search_mode = "skim";
+ # Show long command lines at the bottom
+ show_preview = true;
+ };
+ };
+ };
+}
diff --git a/home/bat/default.nix b/home/bat/default.nix
index ac58c06..67d80c2 100644
--- a/home/bat/default.nix
+++ b/home/bat/default.nix
@@ -3,8 +3,8 @@ let
cfg = config.my.home.bat;
in
{
- options.my.home.bat = with lib.my; {
- enable = mkDisableOption "bat configuration";
+ options.my.home.bat = with lib; {
+ enable = my.mkDisableOption "bat configuration";
};
config.programs.bat = lib.mkIf cfg.enable {
diff --git a/home/bitwarden/default.nix b/home/bitwarden/default.nix
new file mode 100644
index 0000000..c709f7b
--- /dev/null
+++ b/home/bitwarden/default.nix
@@ -0,0 +1,27 @@
+{ config, lib, ... }:
+let
+ cfg = config.my.home.bitwarden;
+in
+{
+ options.my.home.bitwarden = with lib; {
+ enable = my.mkDisableOption "bitwarden configuration";
+
+ pinentry = mkOption {
+ type = types.str;
+ default = "tty";
+ example = "gtk2";
+ description = "Which pinentry interface to use";
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
+ programs.rbw = {
+ enable = true;
+
+ settings = {
+ email = lib.my.mkMailAddress "bruno" "belanyi.fr";
+ inherit (cfg) pinentry;
+ };
+ };
+ };
+}
diff --git a/home/calibre/default.nix b/home/calibre/default.nix
new file mode 100644
index 0000000..e0f2069
--- /dev/null
+++ b/home/calibre/default.nix
@@ -0,0 +1,15 @@
+{ config, lib, pkgs, ... }:
+let
+ cfg = config.my.home.calibre;
+in
+{
+ options.my.home.calibre = with lib; {
+ enable = mkEnableOption "calibre configuration";
+ };
+
+ config = lib.mkIf cfg.enable {
+ home.packages = with pkgs; [
+ calibre # NOTE: relies on my overlay to add necessary plug-in dependencies
+ ];
+ };
+}
diff --git a/home/default.nix b/home/default.nix
index 82d2cc3..8ba3a8d 100644
--- a/home/default.nix
+++ b/home/default.nix
@@ -1,15 +1,21 @@
{ ... }:
{
imports = [
+ ./aliases
+ ./atuin
./bat
+ ./bitwarden
./bluetooth
+ ./calibre
./comma
+ ./dircolors
./direnv
./discord
./documentation
./feh
./firefox
./flameshot
+ ./fzf
./gammastep
./gdb
./git
@@ -19,11 +25,14 @@
./jq
./mail
./mpv
+ ./nix
./nix-index
+ ./nixpkgs
./nm-applet
./packages
./pager
./power-alert
+ ./secrets
./ssh
./terminal
./tmux
diff --git a/home/dircolors/default.nix b/home/dircolors/default.nix
new file mode 100644
index 0000000..876b413
--- /dev/null
+++ b/home/dircolors/default.nix
@@ -0,0 +1,15 @@
+{ config, lib, ... }:
+let
+ cfg = config.my.home.dircolors;
+in
+{
+ options.my.home.dircolors = with lib; {
+ enable = my.mkDisableOption "dircolors configuration";
+ };
+
+ config = lib.mkIf cfg.enable {
+ programs.dircolors = {
+ enable = true;
+ };
+ };
+}
diff --git a/home/direnv/default.nix b/home/direnv/default.nix
index 86409f0..93a1f3b 100644
--- a/home/direnv/default.nix
+++ b/home/direnv/default.nix
@@ -3,15 +3,44 @@ let
cfg = config.my.home.direnv;
in
{
- options.my.home.direnv = with lib.my; {
- enable = mkDisableOption "direnv configuration";
+ options.my.home.direnv = with lib; {
+ enable = my.mkDisableOption "direnv configuration";
+
+ defaultFlake = mkOption {
+ type = types.str;
+ default = "pkgs";
+ example = "nixpkgs";
+ description = ''
+ Which flake from the registry should be used for
+ use pkgs by default.
+ '';
+ };
};
- config.programs.direnv = lib.mkIf cfg.enable {
- enable = true;
- nix-direnv = {
- # A better `use_nix`
+ config = lib.mkIf cfg.enable {
+ programs.direnv = {
enable = true;
+ nix-direnv = {
+ # A better `use_nix`
+ enable = true;
+ };
+ };
+
+ xdg.configFile =
+ let
+ libDir = ./lib;
+ contents = builtins.readDir libDir;
+ names = lib.attrNames contents;
+ files = lib.filter (name: contents.${name} == "regular") names;
+ linkLibFile = name:
+ lib.nameValuePair
+ "direnv/lib/${name}"
+ { source = libDir + "/${name}"; };
+ in
+ lib.my.genAttrs' files linkLibFile;
+
+ home.sessionVariables = {
+ DIRENV_DEFAULT_FLAKE = cfg.defaultFlake;
};
};
}
diff --git a/home/direnv/lib/nix.sh b/home/direnv/lib/nix.sh
new file mode 100644
index 0000000..2d40b20
--- /dev/null
+++ b/home/direnv/lib/nix.sh
@@ -0,0 +1,32 @@
+#shellcheck shell=bash
+
+use_pkgs() {
+ if ! has nix; then
+ # shellcheck disable=2016
+ log_error 'use_pkgs: `nix` is not in PATH'
+ return 1
+ fi
+
+ # Use user-provided default value, or fallback to nixpkgs
+ local DEFAULT_FLAKE="${DIRENV_DEFAULT_FLAKE:-nixpkgs}"
+
+ # Allow changing the default flake through a command line switch
+ if [ "$1" = "-f" ] || [ "$1" = "--flake" ]; then
+ DEFAULT_FLAKE="$2"
+ shift 2
+ fi
+
+
+ # Allow specifying a full installable, or just a package name and use the default flake
+ local packages=()
+ for pkg; do
+ if [[ $pkg =~ .*#.* ]]; then
+ packages+=("$pkg")
+ else
+ packages+=("$DEFAULT_FLAKE#$pkg")
+ fi
+ done
+
+ # shellcheck disable=2154
+ direnv_load nix shell "${packages[@]}" --command "$direnv" dump
+}
diff --git a/home/direnv/lib/postgres.sh b/home/direnv/lib/postgres.sh
new file mode 100644
index 0000000..c2e6a8f
--- /dev/null
+++ b/home/direnv/lib/postgres.sh
@@ -0,0 +1,22 @@
+#shellcheck shell=bash
+
+layout_postgres() {
+ if ! has postgres || ! has initdb; then
+ # shellcheck disable=2016
+ log_error 'layout_postgres: `postgres` and `initdb` are not in PATH'
+ return 1
+ fi
+
+ # shellcheck disable=2155
+ export PGDATA="$(direnv_layout_dir)/postgres"
+ export PGHOST="$PGDATA"
+
+ if [[ ! -d "$PGDATA" ]]; then
+ initdb
+ cat >> "$PGDATA/postgresql.conf" << EOF
+listen_addresses = ''
+unix_socket_directories = '$PGHOST'
+EOF
+ echo "CREATE DATABASE $USER;" | postgres --single -E postgres
+ fi
+}
diff --git a/home/direnv/lib/python.sh b/home/direnv/lib/python.sh
new file mode 100644
index 0000000..15a273f
--- /dev/null
+++ b/home/direnv/lib/python.sh
@@ -0,0 +1,25 @@
+#shellcheck shell=bash
+
+layout_poetry() {
+ if ! has poetry; then
+ # shellcheck disable=2016
+ log_error 'layout_poetry: `poetry` is not in PATH'
+ return 1
+ fi
+
+ if [[ ! -f pyproject.toml ]]; then
+ # shellcheck disable=2016
+ log_error 'layout_poetry: no pyproject.toml found. Use `poetry new` or `poetry init` to create one first'
+ return 1
+ fi
+
+ # create venv if it doesn't exist
+ poetry run true
+
+ # shellcheck disable=2155
+ export VIRTUAL_ENV=$(poetry env info --path)
+ export POETRY_ACTIVE=1
+ PATH_add "$VIRTUAL_ENV/bin"
+ watch_file pyproject.toml
+ watch_file poetry.lock
+}
diff --git a/home/documentation/default.nix b/home/documentation/default.nix
index e31665f..1a305e0 100644
--- a/home/documentation/default.nix
+++ b/home/documentation/default.nix
@@ -3,8 +3,8 @@ let
cfg = config.my.home.documentation;
in
{
- options.my.home.documentation = with lib.my; {
- enable = mkDisableOption "documentation integration";
+ options.my.home.documentation = with lib; {
+ enable = my.mkDisableOption "documentation integration";
};
# Add documentation for user packages
diff --git a/home/firefox/default.nix b/home/firefox/default.nix
index 41389b5..7374b63 100644
--- a/home/firefox/default.nix
+++ b/home/firefox/default.nix
@@ -57,28 +57,27 @@ in
"browser.newtabpage.activity-stream.section.highlights.includePocket" = false; # Disable pocket
"extensions.pocket.enabled" = false; # Disable pocket
"media.eme.enabled" = true; # Enable DRM
- "media.gmp-widevinecdm.visible" = true; # Enable DRM
"media.gmp-widevinecdm.enabled" = true; # Enable DRM
+ "media.gmp-widevinecdm.visible" = true; # Enable DRM
"signon.autofillForms" = false; # Disable built-in form-filling
"signon.rememberSignons" = false; # Disable built-in password manager
"ui.systemUsesDarkTheme" = true; # Dark mode
};
+
+ extensions = with pkgs.nur.repos.rycee.firefox-addons; ([
+ bitwarden
+ consent-o-matic
+ form-history-control
+ reddit-comment-collapser
+ reddit-enhancement-suite
+ refined-github
+ sponsorblock
+ ublock-origin
+ ]
+ ++ lib.optional (cfg.tridactyl.enable) tridactyl
+ ++ lib.optional (cfg.ff2mpv.enable) ff2mpv
+ );
};
};
-
- extensions = with pkgs.nur.repos.rycee.firefox-addons; ([
- bitwarden
- consent-o-matic
- form-history-control
- https-everywhere
- reddit-comment-collapser
- reddit-enhancement-suite
- refined-github
- sponsorblock
- ublock-origin
- ]
- ++ lib.optional (cfg.tridactyl.enable) tridactyl
- ++ lib.optional (cfg.ff2mpv.enable) ff2mpv
- );
};
}
diff --git a/home/firefox/tridactyl/default.nix b/home/firefox/tridactyl/default.nix
index fd8e3fb..35b58c2 100644
--- a/home/firefox/tridactyl/default.nix
+++ b/home/firefox/tridactyl/default.nix
@@ -1,9 +1,28 @@
-{ config, lib, ... }:
+{ config, lib, pkgs, ... }:
let
cfg = config.my.home.firefox.tridactyl;
+
+ term = config.my.home.terminal.program;
+
+ vimCommandLine = {
+ alacritty = ''-e "vim" "%f" "+normal!%lGzv%c|"'';
+ # Termite wants the whole command in a single argument...
+ termite = ''-e "vim %f '+normal!%lGzv%c|'"'';
+ };
in
{
config = lib.mkIf cfg.enable {
- xdg.configFile."tridactyl/tridactylrc".source = ./tridactylrc;
+ xdg.configFile."tridactyl/tridactylrc".source = pkgs.substituteAll {
+ src = ./tridactylrc;
+
+ editorcmd = lib.concatStringsSep " " [
+ # Use my configured terminal
+ term
+ # Make it easy to pick out with a window class name
+ "--class tridactyl_editor"
+ # Open vim with the cursor in the correct position
+ vimCommandLine.${term}
+ ];
+ };
};
}
diff --git a/home/firefox/tridactyl/tridactylrc b/home/firefox/tridactyl/tridactylrc
index dc59a2e..31d3cb7 100644
--- a/home/firefox/tridactyl/tridactylrc
+++ b/home/firefox/tridactyl/tridactylrc
@@ -5,14 +5,18 @@
colorscheme dark
" Make tridactyl open Vim in my prefered terminal
-" FIXME: make it follow my prefered terminal
-set editorcmd termite --class tridactyl_editor -e 'vim %f'
+set editorcmd @editorcmd@
+
+" Remove editor file after use
+alias editor_rm composite editor | jsb -p tri.native.run(`rm -f '${JS_ARG[0]}'`)
+bind --mode=insert editor_rm
+bind --mode=input editor_rm
" }}}
" Binds {{{
" Reddit et al. {{{
" Toggle comments on Reddit, Hacker News, Lobste.rs
-bind ;c hint -c [class*="expand"],[class*="togg"],[class="comment_folder"]
+bind ;c hint -Jc [class*="expand"],[class*="togg"],[class="comment_folder"]
" Make `gu` take me back to subreddit from comments
bindurl reddit.com gu urlparent 3
@@ -22,8 +26,8 @@ bindurl www.google.com f hint -Jc #search div:not(.action-menu) > a
bindurl www.google.com F hint -Jbc #search div:not(.action-menu) > a
" Only hint search results on DuckDuckGo
-bindurl ^https://duckduckgo.com f hint -Jc [class~=result__a]
-bindurl ^https://duckduckgo.com F hint -Jbc [class~=result__a]
+bindurl ^https://duckduckgo.com f hint -Jc [data-testid="result-title-a"]
+bindurl ^https://duckduckgo.com F hint -Jbc [data-testid="result-title-a"]
" Only hint item pages on Hacker News
bindurl news.ycombinator.com ;f hint -Jc .age > a
@@ -65,6 +69,8 @@ unbind
" Redirections {{{
" Always redirect Reddit to the old site
autocmd DocStart ^http(s?)://www.reddit.com js tri.excmds.urlmodify("-t", "www", "old")
+" Use a better Twitter front-end
+autocmd DocStart ^http(s?)://twitter.com js tri.excmds.urlmodify("-t", "twitter.com", "nitter.net")
" }}}
" Disabled websites {{{
diff --git a/home/fzf/default.nix b/home/fzf/default.nix
new file mode 100644
index 0000000..b7e308f
--- /dev/null
+++ b/home/fzf/default.nix
@@ -0,0 +1,15 @@
+{ config, lib, ... }:
+let
+ cfg = config.my.home.fzf;
+in
+{
+ options.my.home.fzf = with lib; {
+ enable = my.mkDisableOption "fzf configuration";
+ };
+
+ config = lib.mkIf cfg.enable {
+ programs.fzf = {
+ enable = true;
+ };
+ };
+}
diff --git a/home/gdb/default.nix b/home/gdb/default.nix
index f6db2e7..c498048 100644
--- a/home/gdb/default.nix
+++ b/home/gdb/default.nix
@@ -26,11 +26,7 @@ in
gdb
];
- # FIXME: waiting for commit 64aaad6349d2b2c45063a5383f877ce9a3a0c354
xdg.configFile."gdb/gdbinit".source = ./gdbinit;
-
- # FIXME: remove once `gdb` is updated from version 10.2
- home.file.".gdbinit".source = ./gdbinit;
})
(lib.mkIf cfg.rr.enable {
diff --git a/home/gdb/gdbinit b/home/gdb/gdbinit
index bdf7bfd..86e8c3c 100644
--- a/home/gdb/gdbinit
+++ b/home/gdb/gdbinit
@@ -19,6 +19,6 @@ set print demangle on
set auto-load python-scripts
# Allow autoloading project-local .gdbinit files
-set auto-load safe-path ~/git/
+add-auto-load-safe-path ~/git/
# Allow autoloading from the Nix store
-set auto-load safe-path /nix/store
+add-auto-load-safe-path /nix/store
diff --git a/home/git/default.ignore b/home/git/default.ignore
index 77aedcc..d80996e 100644
--- a/home/git/default.ignore
+++ b/home/git/default.ignore
@@ -28,3 +28,7 @@ compile_commands.json
# Direnv files
.envrc
.direnv/
+
+# Project-local neovim configuration files
+.nvim.lua
+.nvimrc
diff --git a/home/git/default.nix b/home/git/default.nix
index 6f4434b..4dba01e 100644
--- a/home/git/default.nix
+++ b/home/git/default.nix
@@ -5,14 +5,14 @@ let
inherit (lib.my) mkMailAddress;
in
{
- options.my.home.git = with lib.my; {
- enable = mkDisableOption "git configuration";
+ options.my.home.git = with lib; {
+ enable = my.mkDisableOption "git configuration";
};
- config.home.packages = with pkgs.gitAndTools; lib.mkIf cfg.enable [
- gitAndTools.git-absorb
- gitAndTools.git-revise
- gitAndTools.tig
+ config.home.packages = with pkgs; lib.mkIf cfg.enable [
+ git-absorb
+ git-revise
+ tig
];
config.programs.git = lib.mkIf cfg.enable {
@@ -23,7 +23,7 @@ in
userName = "Bruno BELANYI";
# I want the full experience
- package = pkgs.gitAndTools.gitFull;
+ package = pkgs.gitFull;
aliases = {
git = "!git";
@@ -35,6 +35,7 @@ in
pick = "log -p -G";
push-new = "!git push -u origin "
+ ''"$(git branch | grep '^* ' | cut -f2- -d' ')"'';
+ root = "git rev-parse --show-toplevel";
};
lfs.enable = true;
@@ -120,6 +121,15 @@ in
defaultBranch = "main";
};
+ # Local configuration, not-versioned
+ include = {
+ path = "config.local";
+ };
+
+ merge = {
+ conflictStyle = "zdiff3";
+ };
+
pull = {
# Avoid useless merge commits
rebase = true;
@@ -137,8 +147,8 @@ in
};
url = {
- "git@gitea.belanyi.fr:" = {
- insteadOf = "https://gitea.belanyi.fr/";
+ "git@git.belanyi.fr:" = {
+ insteadOf = "https://git.belanyi.fr/";
};
"git@github.com:" = {
@@ -162,6 +172,15 @@ in
};
};
}
+ {
+ condition = "gitdir:~/git/work/";
+ contents = {
+ user = {
+ name = "Bruno BELANYI";
+ email = mkMailAddress "ambroisie" "google.com";
+ };
+ };
+ }
];
ignores =
diff --git a/home/gpg/default.nix b/home/gpg/default.nix
index d48c200..7eadf48 100644
--- a/home/gpg/default.nix
+++ b/home/gpg/default.nix
@@ -27,5 +27,10 @@ in
allow-loopback-pinentry
'';
};
+
+ home.shellAliases = {
+ # Sometime `gpg-agent` errors out...
+ reset-agent = "gpg-connect-agent updatestartuptty /bye";
+ };
};
}
diff --git a/home/htop/default.nix b/home/htop/default.nix
index c4b33a9..570fa47 100644
--- a/home/htop/default.nix
+++ b/home/htop/default.nix
@@ -3,8 +3,8 @@ let
cfg = config.my.home.htop;
in
{
- options.my.home.htop = with lib.my; {
- enable = mkDisableOption "htop configuration";
+ options.my.home.htop = with lib; {
+ enable = my.mkDisableOption "htop configuration";
};
config.programs.htop = lib.mkIf cfg.enable {
diff --git a/home/jq/default.nix b/home/jq/default.nix
index d8bd59b..57e266f 100644
--- a/home/jq/default.nix
+++ b/home/jq/default.nix
@@ -3,8 +3,8 @@ let
cfg = config.my.home.jq;
in
{
- options.my.home.jq = with lib.my; {
- enable = mkDisableOption "jq configuration";
+ options.my.home.jq = with lib; {
+ enable = my.mkDisableOption "jq configuration";
};
config.programs.jq = lib.mkIf cfg.enable {
diff --git a/home/mail/accounts/default.nix b/home/mail/accounts/default.nix
index 80d95ae..e7663d8 100644
--- a/home/mail/accounts/default.nix
+++ b/home/mail/accounts/default.nix
@@ -8,7 +8,7 @@ let
realName = lib.mkDefault "Bruno BELANYI";
userName = lib.mkDefault (mkMailAddress address domain);
passwordCommand =
- lib.mkDefault [ "${pkgs.ambroisie.bw-pass}/bin/bw-pass" "Mail" passName ];
+ lib.mkDefault [ (lib.getExe pkgs.ambroisie.rbw-pass) "Mail" passName ];
address = mkMailAddress address domain;
aliases = builtins.map (lib.flip mkMailAddress domain) aliases;
@@ -17,6 +17,9 @@ let
himalaya = {
enable = cfg.himalaya.enable;
+ # FIXME: try to actually configure it at some point
+ backend = "imap";
+ sender = "smtp";
};
msmtp = {
@@ -51,21 +54,7 @@ let
};
office365Config = {
- imap = {
- host = "outlook.office365.com";
- port = 993;
- tls = {
- enable = true;
- };
- };
- smtp = {
- host = "outlook.office365.com";
- port = 587;
- tls = {
- enable = true;
- useStartTls = true;
- };
- };
+ flavor = "outlook.office365.com";
};
in
{
diff --git a/home/mail/default.nix b/home/mail/default.nix
index ac44593..14f086a 100644
--- a/home/mail/default.nix
+++ b/home/mail/default.nix
@@ -15,7 +15,7 @@ in
enable = my.mkDisableOption "email configuration";
himalaya = {
- enable = mkRelatedOption "himalaya configuration";
+ enable = mkEnableOption "himalaya configuration";
};
msmtp = {
diff --git a/home/mail/himalaya/default.nix b/home/mail/himalaya/default.nix
index c2d3b05..849a415 100644
--- a/home/mail/himalaya/default.nix
+++ b/home/mail/himalaya/default.nix
@@ -9,7 +9,7 @@ in
settings = {
notify-cmd =
let
- notify-send = "${pkgs.libnotify}/bin/notify-send";
+ notify-send = lib.getExe pkgs.libnotify;
in
pkgs.writeScript "mail-notifier" ''
SENDER="$1"
diff --git a/home/nix-index/default.nix b/home/nix-index/default.nix
index ae6f338..383621e 100644
--- a/home/nix-index/default.nix
+++ b/home/nix-index/default.nix
@@ -3,8 +3,8 @@ let
cfg = config.my.home.nix-index;
in
{
- options.my.home.nix-index = with lib.my; {
- enable = mkDisableOption "nix-index configuration";
+ options.my.home.nix-index = with lib; {
+ enable = my.mkDisableOption "nix-index configuration";
};
config.programs.nix-index = lib.mkIf cfg.enable {
diff --git a/home/nix/default.nix b/home/nix/default.nix
new file mode 100644
index 0000000..9ccbdc5
--- /dev/null
+++ b/home/nix/default.nix
@@ -0,0 +1,82 @@
+# Nix related settings
+{ config, inputs, lib, pkgs, ... }:
+let
+ cfg = config.my.home.nix;
+
+ channels = lib.my.merge [
+ {
+ # Allow me to use my custom package using `nix run self#pkg`
+ self = inputs.self;
+ # Add NUR to run some packages that are only present there
+ nur = inputs.nur;
+ # Use pinned nixpkgs when using `nix run pkgs#`
+ pkgs = inputs.nixpkgs;
+ }
+ (lib.optionalAttrs cfg.overrideNixpkgs {
+ # ... And with `nix run nixpkgs#`
+ nixpkgs = inputs.nixpkgs;
+ })
+ ];
+in
+{
+ options.my.home.nix = with lib; {
+ enable = my.mkDisableOption "nix configuration";
+
+ linkInputs = my.mkDisableOption "link inputs to `$XDG_CONFIG_HOME/nix/inputs`";
+
+ addToRegistry = my.mkDisableOption "add inputs and self to registry";
+
+ addToNixPath = my.mkDisableOption "add inputs and self to nix path";
+
+ overrideNixpkgs = my.mkDisableOption "point nixpkgs to pinned system version";
+ };
+
+ config = lib.mkIf cfg.enable (lib.mkMerge [
+ {
+ assertions = [
+ {
+ assertion = cfg.addToNixPath -> cfg.linkInputs;
+ message = ''
+ enabling `my.home.nix.addToNixPath` needs to have
+ `my.home.nix.linkInputs = true`
+ '';
+ }
+ ];
+ }
+
+ {
+ nix = {
+ package = lib.mkDefault pkgs.nix; # NixOS module sets it unconditionally
+
+ settings = {
+ experimental-features = [ "nix-command" "flakes" ];
+ };
+ };
+ }
+
+ (lib.mkIf cfg.addToRegistry {
+ nix.registry =
+ let
+ makeEntry = v: { flake = v; };
+ makeEntries = lib.mapAttrs (lib.const makeEntry);
+ in
+ makeEntries channels;
+ })
+
+ (lib.mkIf cfg.linkInputs {
+ xdg.configFile =
+ let
+ makeLink = n: v: {
+ name = "nix/inputs/${n}";
+ value = { source = v.outPath; };
+ };
+ makeLinks = lib.mapAttrs' makeLink;
+ in
+ makeLinks channels;
+ })
+
+ (lib.mkIf cfg.addToNixPath {
+ home.sessionVariables.NIX_PATH = "${config.xdg.configHome}/nix/inputs\${NIX_PATH:+:$NIX_PATH}";
+ })
+ ]);
+}
diff --git a/home/nixpkgs/default.nix b/home/nixpkgs/default.nix
new file mode 100644
index 0000000..720fc9b
--- /dev/null
+++ b/home/nixpkgs/default.nix
@@ -0,0 +1,20 @@
+{ config, lib, pkgs, ... }:
+let
+ cfg = config.my.home.nixpkgs;
+in
+{
+ options.my.home.nixpkgs = with lib; {
+ enable = mkEnableOption "nixpkgs configuration";
+ };
+
+ config = lib.mkIf cfg.enable {
+ home.packages = with pkgs; [
+ nixpkgs-review
+ ];
+
+ home.sessionVariables = {
+ GITHUB_TOKEN = ''$(cat "${config.age.secrets."github/token".path}")'';
+ GITHUB_API_TOKEN = ''$(cat "${config.age.secrets."github/token".path}")'';
+ };
+ };
+}
diff --git a/home/packages/default.nix b/home/packages/default.nix
index 434cb0d..0cfa3b3 100644
--- a/home/packages/default.nix
+++ b/home/packages/default.nix
@@ -22,7 +22,5 @@ in
file
mosh
ripgrep
- rr
- termite.terminfo
] ++ cfg.additionalPackages);
}
diff --git a/home/pager/default.nix b/home/pager/default.nix
index 00d29c0..aa72587 100644
--- a/home/pager/default.nix
+++ b/home/pager/default.nix
@@ -3,8 +3,8 @@ let
cfg = config.my.home.pager;
in
{
- options.my.home.pager = with lib.my; {
- enable = mkDisableOption "pager configuration";
+ options.my.home.pager = with lib; {
+ enable = my.mkDisableOption "pager configuration";
};
@@ -14,23 +14,8 @@ in
PAGER = "less";
# Clear the screen on start and exit
LESS = "-R -+X -c";
- };
-
- programs.zsh.localVariables = {
- # Colored man pages
- LESS_TERMCAP_mb = "$(tput bold; tput setaf 2)";
- LESS_TERMCAP_md = "$(tput bold; tput setaf 6)";
- LESS_TERMCAP_me = "$(tput sgr0)";
- LESS_TERMCAP_so = "$(tput bold; tput setaf 3; tput setab 4)";
- LESS_TERMCAP_se = "$(tput rmso; tput sgr0)";
- LESS_TERMCAP_us = "$(tput bold; tput setaf 2)";
- LESS_TERMCAP_ue = "$(tput rmul; tput sgr0)";
- LESS_TERMCAP_mr = "$(tput rev)";
- LESS_TERMCAP_mh = "$(tput dim)";
- LESS_TERMCAP_ZN = "$(tput ssubm)";
- LESS_TERMCAP_ZV = "$(tput rsubm)";
- LESS_TERMCAP_ZO = "$(tput ssupm)";
- LESS_TERMCAP_ZW = "$(tput rsupm)";
+ # Better XDG compliance
+ LESSHISTFILE = "${config.xdg.dataHome}/less/history";
};
};
}
diff --git a/home/secrets/default.nix b/home/secrets/default.nix
new file mode 100644
index 0000000..7c0c0a1
--- /dev/null
+++ b/home/secrets/default.nix
@@ -0,0 +1,25 @@
+{ config, inputs, lib, options, ... }:
+
+{
+ imports = [
+ inputs.agenix.homeManagerModules.age
+ ];
+
+ config.age = {
+ secrets =
+ let
+ toName = lib.removeSuffix ".age";
+ toSecret = name: { ... }: {
+ file = ./. + "/${name}";
+ };
+ convertSecrets = n: v: lib.nameValuePair (toName n) (toSecret n v);
+ secrets = import ./secrets.nix;
+ in
+ lib.mapAttrs' convertSecrets secrets;
+
+ # Add my usual agenix key to the defaults
+ identityPaths = options.age.identityPaths.default ++ [
+ "${config.home.homeDirectory}/.ssh/agenix"
+ ];
+ };
+}
diff --git a/home/secrets/github/token.age b/home/secrets/github/token.age
new file mode 100644
index 0000000..1d36ccd
Binary files /dev/null and b/home/secrets/github/token.age differ
diff --git a/home/secrets/secrets.nix b/home/secrets/secrets.nix
new file mode 100644
index 0000000..f474342
--- /dev/null
+++ b/home/secrets/secrets.nix
@@ -0,0 +1,9 @@
+# Common secrets
+let
+ keys = import ../../keys;
+
+ all = builtins.attrValues keys.users;
+in
+{
+ "github/token.age".publicKeys = all;
+}
diff --git a/home/ssh/default.nix b/home/ssh/default.nix
index cbfd30c..123190f 100644
--- a/home/ssh/default.nix
+++ b/home/ssh/default.nix
@@ -3,13 +3,18 @@ let
cfg = config.my.home.ssh;
in
{
- options.my.home.ssh = with lib.my; {
- enable = mkDisableOption "ssh configuration";
+ options.my.home.ssh = with lib; {
+ enable = my.mkDisableOption "ssh configuration";
};
config.programs.ssh = lib.mkIf cfg.enable {
enable = true;
+ includes = [
+ # Local configuration, not-versioned
+ "config.local"
+ ];
+
matchBlocks = {
"github.com" = {
hostname = "github.com";
@@ -29,8 +34,8 @@ in
user = "git";
};
- "gitea.belanyi.fr" = {
- hostname = "gitea.belanyi.fr";
+ "git.belanyi.fr" = {
+ hostname = "git.belanyi.fr";
identityFile = "~/.ssh/shared_rsa";
user = "git";
};
@@ -40,12 +45,6 @@ in
identityFile = "~/.ssh/shared_rsa";
user = "ambroisie";
};
-
- work = {
- hostname = "workspaces.dgexsol.fr";
- identityFile = "~/.ssh/shared_rsa";
- user = "bruno_belanyi";
- };
};
extraConfig = ''
diff --git a/home/terminal/alacritty/default.nix b/home/terminal/alacritty/default.nix
new file mode 100644
index 0000000..daf3e80
--- /dev/null
+++ b/home/terminal/alacritty/default.nix
@@ -0,0 +1,52 @@
+{ config, lib, ... }:
+let
+ cfg = config.my.home.terminal;
+in
+{
+ config = lib.mkIf (cfg.program == "alacritty") {
+ programs.alacritty = {
+ enable = true;
+
+ settings = {
+ font = {
+ size = 5.5;
+ };
+
+ colors = {
+ primary = {
+ background = cfg.colors.background;
+ foreground = cfg.colors.foreground;
+
+ bright_foreground = cfg.colors.foregroundBold;
+ };
+
+ cursor = {
+ cursor = cfg.colors.cursor;
+ };
+
+ normal = {
+ black = cfg.colors.black;
+ red = cfg.colors.red;
+ green = cfg.colors.green;
+ yellow = cfg.colors.yellow;
+ blue = cfg.colors.blue;
+ magenta = cfg.colors.magenta;
+ cyan = cfg.colors.cyan;
+ white = cfg.colors.white;
+ };
+
+ bright = {
+ black = cfg.colors.blackBold;
+ red = cfg.colors.redBold;
+ green = cfg.colors.greenBold;
+ yellow = cfg.colors.yellowBold;
+ blue = cfg.colors.blueBold;
+ magenta = cfg.colors.magentaBold;
+ cyan = cfg.colors.cyanBold;
+ white = cfg.colors.whiteBold;
+ };
+ };
+ };
+ };
+ };
+}
diff --git a/home/terminal/default.nix b/home/terminal/default.nix
index 68ff44e..20f36b5 100644
--- a/home/terminal/default.nix
+++ b/home/terminal/default.nix
@@ -10,13 +10,14 @@ let
in
{
imports = [
+ ./alacritty
./termite
];
options.my.home = with lib; {
terminal = {
program = mkOption {
- type = with types; nullOr (enum [ "termite" ]);
+ type = with types; nullOr (enum [ "alacritty" "termite" ]);
default = null;
example = "termite";
description = "Which terminal to use for home session";
diff --git a/home/tmux/default.nix b/home/tmux/default.nix
index f9b711c..70f037f 100644
--- a/home/tmux/default.nix
+++ b/home/tmux/default.nix
@@ -1,11 +1,16 @@
{ config, lib, pkgs, ... }:
let
cfg = config.my.home.tmux;
- hasGUI = config.my.home.x.enable || (config.my.home.wm != null);
+ hasGUI = lib.any lib.id [
+ config.my.home.x.enable
+ (config.my.home.wm.windowManager != null)
+ ];
in
{
- options.my.home.tmux = with lib.my; {
- enable = mkDisableOption "tmux terminal multiplexer";
+ options.my.home.tmux = with lib; {
+ enable = my.mkDisableOption "tmux terminal multiplexer";
+
+ enabledPassthrough = mkEnableOption "tmux DCS passthrough sequence";
};
config.programs.tmux = lib.mkIf cfg.enable {
@@ -24,7 +29,7 @@ in
pain-control
# Better session management
sessionist
- (lib.optionalAttrs hasGUI {
+ {
# X clipboard integration
plugin = yank;
extraConfig = ''
@@ -33,7 +38,7 @@ in
# Stay in copy mode after yanking
set -g @yank_action 'copy-pipe'
'';
- })
+ }
{
# Show when prefix has been pressed
plugin = prefix-highlight;
@@ -57,6 +62,19 @@ in
}
# Block selection in vim mode
bind-key -Tcopy-mode-vi 'C-v' send -X begin-selection \; send -X rectangle-toggle
+
+ # Allow any application to send OSC52 escapes to set the clipboard
+ set -s set-clipboard on
+
+ # Longer session names in status bar
+ set -g status-left-length 16
+
+ ${
+ lib.optionalString cfg.enabledPassthrough ''
+ # Allow any application to use the tmux DCS for passthrough
+ set -g allow-passthrough on
+ ''
+ }
'';
};
}
diff --git a/home/vim/after/ftplugin/pandoc.vim b/home/vim/after/ftplugin/markdown.vim
similarity index 100%
rename from home/vim/after/ftplugin/pandoc.vim
rename to home/vim/after/ftplugin/markdown.vim
diff --git a/home/vim/after/ftplugin/nix.vim b/home/vim/after/ftplugin/nix.vim
new file mode 100644
index 0000000..fb6126e
--- /dev/null
+++ b/home/vim/after/ftplugin/nix.vim
@@ -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 Nix files
+setlocal shiftwidth=2
+let b:undo_ftplugin.='|setlocal shiftwidth<'
diff --git a/home/vim/after/ftplugin/tiger.vim b/home/vim/after/ftplugin/tiger.vim
new file mode 100644
index 0000000..81c2cfc
--- /dev/null
+++ b/home/vim/after/ftplugin/tiger.vim
@@ -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 tiger files
+setlocal shiftwidth=2
+let b:undo_ftplugin.='|setlocal shiftwidth<'
diff --git a/home/vim/after/plugin/mappings/commentary.vim b/home/vim/after/plugin/mappings/commentary.lua
similarity index 94%
rename from home/vim/after/plugin/mappings/commentary.vim
rename to home/vim/after/plugin/mappings/commentary.lua
index 219d661..6ed3b89 100644
--- a/home/vim/after/plugin/mappings/commentary.vim
+++ b/home/vim/after/plugin/mappings/commentary.lua
@@ -1,4 +1,3 @@
-lua << EOF
local wk = require("which-key")
local keys = {
@@ -9,4 +8,3 @@ local keys = {
}
wk.register(keys, { prefix = "gc" })
-EOF
diff --git a/home/vim/after/plugin/mappings/misc.vim b/home/vim/after/plugin/mappings/misc.lua
similarity index 91%
rename from home/vim/after/plugin/mappings/misc.vim
rename to home/vim/after/plugin/mappings/misc.lua
index c7fcc8a..6aa25a2 100644
--- a/home/vim/after/plugin/mappings/misc.vim
+++ b/home/vim/after/plugin/mappings/misc.lua
@@ -1,4 +1,3 @@
-lua << EOF
local wk = require("which-key")
local keys = {
@@ -6,4 +5,3 @@ local keys = {
}
wk.register(keys, { prefix = "" })
-EOF
diff --git a/home/vim/after/plugin/mappings/telescope.vim b/home/vim/after/plugin/mappings/telescope.lua
similarity index 97%
rename from home/vim/after/plugin/mappings/telescope.vim
rename to home/vim/after/plugin/mappings/telescope.lua
index 98551f9..e0d38a7 100644
--- a/home/vim/after/plugin/mappings/telescope.vim
+++ b/home/vim/after/plugin/mappings/telescope.lua
@@ -1,4 +1,3 @@
-lua << EOF
local wk = require("which-key")
local telescope = require("telescope")
local telescope_builtin = require("telescope.builtin")
@@ -16,5 +15,3 @@ local keys = {
}
wk.register(keys, { prefix = "" })
-EOF
-
diff --git a/home/vim/after/plugin/mappings/tree-sitter-textobjects.vim b/home/vim/after/plugin/mappings/tree-sitter-textobjects.lua
similarity index 98%
rename from home/vim/after/plugin/mappings/tree-sitter-textobjects.vim
rename to home/vim/after/plugin/mappings/tree-sitter-textobjects.lua
index 9cabd91..631731c 100644
--- a/home/vim/after/plugin/mappings/tree-sitter-textobjects.vim
+++ b/home/vim/after/plugin/mappings/tree-sitter-textobjects.lua
@@ -1,4 +1,3 @@
-lua << EOF
local wk = require("which-key")
local motions = {
@@ -29,4 +28,3 @@ local objects = {
wk.register(motions, { mode = "n" })
wk.register(objects, { mode = "o" })
-EOF
diff --git a/home/vim/after/plugin/mappings/unimpaired.vim b/home/vim/after/plugin/mappings/unimpaired.lua
similarity index 83%
rename from home/vim/after/plugin/mappings/unimpaired.vim
rename to home/vim/after/plugin/mappings/unimpaired.lua
index c4bb35b..f502056 100644
--- a/home/vim/after/plugin/mappings/unimpaired.vim
+++ b/home/vim/after/plugin/mappings/unimpaired.lua
@@ -1,6 +1,7 @@
-lua << EOF
local wk = require("which-key")
+local lsp = require("ambroisie.lsp")
+
local keys = {
-- Edition and navigation mappins
["["] = {
@@ -31,7 +32,7 @@ local keys = {
x = "XML encode",
y = "C string encode",
-- Custom
- d = { vim.diagnostic.goto_prev, "Previous diagnostic" }
+ d = { lsp.goto_prev_diagnostic, "Previous diagnostic" },
},
["]"] = {
name = "Next",
@@ -61,7 +62,7 @@ local keys = {
x = "XML decode",
y = "C string decode",
-- Custom
- d = { vim.diagnostic.goto_next, "Next diagnostic" }
+ d = { lsp.goto_next_diagnostic, "Next diagnostic" },
},
-- Option mappings
@@ -70,13 +71,14 @@ local keys = {
b = "Light background",
c = "Cursor line",
d = "Diff",
- e = { "lwindow", "Location list" },
- f = { "cwindow", "Quickfix list" },
+ f = { "FormatEnable", "LSP Formatting" },
h = "Search high-lighting",
i = "Case insensitive search",
l = "List mode",
n = "Line numbers",
r = "Relative line numbers",
+ p = { "lwindow", "Location list" },
+ q = { "cwindow", "Quickfix list" },
u = "Cursor column",
v = "Virtual editing",
w = "Text wrapping",
@@ -88,12 +90,13 @@ local keys = {
b = "Light background",
c = "Cursor line",
d = "Diff",
- e = { "lclose", "Location list" },
- f = { "cclose", "Quickfix list" },
+ f = { "FormatDisable", "LSP Formatting" },
h = "Search high-lighting",
i = "Case insensitive search",
l = "List mode",
n = "Line numbers",
+ p = { "lclose", "Location list" },
+ q = { "cclose", "Quickfix list" },
r = "Relative line numbers",
u = "Cursor column",
v = "Virtual editing",
@@ -106,12 +109,13 @@ local keys = {
b = "Light background",
c = "Cursor line",
d = "Diff",
- e = { "(qf_loc_toggle)", "Location list" },
- f = { "(qf_qf_toggle)", "Quickfix list" },
+ f = { "FormatToggle", "LSP Formatting" },
h = "Search high-lighting",
i = "Case insensitive search",
l = "List mode",
n = "Line numbers",
+ p = { "(qf_loc_toggle)", "Location list" },
+ q = { "(qf_qf_toggle)", "Quickfix list" },
r = "Relative line numbers",
u = "Cursor column",
v = "Virtual editing",
@@ -122,4 +126,3 @@ local keys = {
}
wk.register(keys)
-EOF
diff --git a/home/vim/default.nix b/home/vim/default.nix
index 4bd1886..3bd2469 100644
--- a/home/vim/default.nix
+++ b/home/vim/default.nix
@@ -18,12 +18,16 @@ let
];
in
{
- options.my.home.vim = with lib.my; {
- enable = mkDisableOption "vim configuration";
+ options.my.home.vim = with lib; {
+ enable = my.mkDisableOption "vim configuration";
};
config.programs.neovim = lib.mkIf cfg.enable {
enable = true;
+
+ # This is the best editor
+ defaultEditor = true;
+
# All the aliases
viAlias = true;
vimAlias = true;
@@ -31,7 +35,7 @@ in
plugins = with pkgs.vimPlugins; [
# Theming
- vim-gruvbox8 # Nice dark theme
+ gruvbox-nvim # Nice dark theme
lualine-nvim # A lua-based status line
lualine-lsp-progress # Show progress for LSP servers
@@ -42,7 +46,6 @@ in
vim-git # Sane git syntax files
vim-repeat # Enanche '.' for plugins
vim-rsi # Readline mappings
- vim-surround # Deal with pairs
vim-unimpaired # Some ex command mappings
vim-vinegar # Better netrw
@@ -51,38 +54,41 @@ in
vim-beancount
vim-jsonnet
vim-nix
- vim-pandoc
- vim-pandoc-syntax
vim-toml
# General enhancements
vim-qf # Better quick-fix list
+ nvim-osc52 # Send clipboard data through terminal escape for SSH
# Other wrappers
git-messenger-vim # A simple blame window
# LSP and linting
+ nvim-lspconfig # Easy LSP configuration
+ lsp-format-nvim # Simplified formatting configuration
lsp_lines-nvim # Show diagnostics *over* regions
null-ls-nvim # LSP integration for linters and formatters
- (nvim-treesitter.withPlugins (_: pkgs.tree-sitter.allGrammars)) # Better highlighting
+ nvim-treesitter.withAllGrammars # Better highlighting
nvim-treesitter-textobjects # More textobjects
nvim-ts-context-commentstring # Comment string in nested language blocks
plenary-nvim # 'null-ls', 'telescope' dependency
# Completion
+ luasnip # Snippet manager compatible with LSP
+ friendly-snippets # LSP snippets collection
nvim-cmp # Completion engine
cmp-buffer # Words from open buffers
cmp-nvim-lsp # LSP suggestions
cmp-nvim-lua # NeoVim lua API
cmp-path # Path name suggestions
cmp-under-comparator # Sort items that start with '_' lower
- friendly-snippets # LSP snippets collection
- luasnip # Snippet manager compatible with LSP
+ cmp_luasnip # Snippet suggestions from LuaSnip
# UX improvements
dressing-nvim # Integrate native UI hooks with Telescope etc...
gitsigns-nvim # Fast git UI integration
nvim-notify # Better notification API
+ nvim-surround # Deal with pairs, now in Lua
telescope-fzf-native-nvim # Use 'fzf' fuzzy matching algorithm
telescope-lsp-handlers-nvim # Use 'telescope' for various LSP actions
telescope-nvim # Fuzzy finder interface
diff --git a/home/vim/ftdetect/automake.lua b/home/vim/ftdetect/automake.lua
new file mode 100644
index 0000000..cfa15d2
--- /dev/null
+++ b/home/vim/ftdetect/automake.lua
@@ -0,0 +1,6 @@
+-- Use Automake filetype for `local.am` files, explicit `set` to force override
+vim.filetype.add({
+ filename = {
+ ["local.am"] = "automake",
+ },
+})
diff --git a/home/vim/ftdetect/automake.vim b/home/vim/ftdetect/automake.vim
deleted file mode 100644
index 5cc73b0..0000000
--- a/home/vim/ftdetect/automake.vim
+++ /dev/null
@@ -1,2 +0,0 @@
-" Use Automake filetype for `local.am` files, explicit `set` to force override
-au BufNewFile,BufRead local.am set filetype=automake
diff --git a/home/vim/ftdetect/direnv.lua b/home/vim/ftdetect/direnv.lua
new file mode 100644
index 0000000..fba9748
--- /dev/null
+++ b/home/vim/ftdetect/direnv.lua
@@ -0,0 +1,6 @@
+-- Use bash filetype for `.envrc` files
+vim.filetype.add({
+ filename = {
+ [".envrc"] = "bash",
+ },
+})
diff --git a/home/vim/ftdetect/kbuild.lua b/home/vim/ftdetect/kbuild.lua
new file mode 100644
index 0000000..799570e
--- /dev/null
+++ b/home/vim/ftdetect/kbuild.lua
@@ -0,0 +1,6 @@
+-- Kbuild is just a Makefile under a different name
+vim.filetype.add({
+ filename = {
+ ["Kbuild"] = "make",
+ },
+})
diff --git a/home/vim/ftdetect/kconfig.lua b/home/vim/ftdetect/kconfig.lua
new file mode 100644
index 0000000..d51e964
--- /dev/null
+++ b/home/vim/ftdetect/kconfig.lua
@@ -0,0 +1,6 @@
+-- Mconfig is just Kconfig
+vim.filetype.add({
+ filename = {
+ ["Mconfig"] = "kconfig",
+ },
+})
diff --git a/home/vim/ftdetect/tiger.lua b/home/vim/ftdetect/tiger.lua
new file mode 100644
index 0000000..a261103
--- /dev/null
+++ b/home/vim/ftdetect/tiger.lua
@@ -0,0 +1,7 @@
+-- Use Tiger filetype for programs and header files
+vim.filetype.add({
+ extension = {
+ tig = "tiger",
+ tih = "tiger",
+ },
+})
diff --git a/home/vim/ftdetect/tikz.lua b/home/vim/ftdetect/tikz.lua
new file mode 100644
index 0000000..93b7db0
--- /dev/null
+++ b/home/vim/ftdetect/tikz.lua
@@ -0,0 +1,6 @@
+-- Use LaTeX filetype for TikZ files
+vim.filetype.add({
+ extension = {
+ tikz = "tex",
+ },
+})
diff --git a/home/vim/ftdetect/tikz.vim b/home/vim/ftdetect/tikz.vim
deleted file mode 100644
index 7327b11..0000000
--- a/home/vim/ftdetect/tikz.vim
+++ /dev/null
@@ -1,2 +0,0 @@
-" Use LaTeX filetype for TikZ files
-au BufNewFile,BufRead *.tikz setfiletype tex
diff --git a/home/vim/init.vim b/home/vim/init.vim
index ab5f648..bd63d25 100644
--- a/home/vim/init.vim
+++ b/home/vim/init.vim
@@ -66,6 +66,11 @@ set list
" Show a tab as an arrow, trailing spaces as ¤, non-breaking spaces as dots
set listchars=tab:>─,trail:·,nbsp:¤
+" Use patience diff
+set diffopt+=algorithm:patience
+" Align similar lines in each hunk
+set diffopt+=linematch:50
+
" Don't redraw when executing macros
set lazyredraw
@@ -75,15 +80,16 @@ set timeoutlen=500
" Timeout quickly for CursorHold events (and also swap file)
set updatetime=250
+" Disable all mouse integrations
+set mouse=
+
" Set dark mode by default
set background=dark
-" Include plug-in integration
-let g:gruvbox_plugin_hi_groups=1
-" Include filetype integration
-let g:gruvbox_filetype_hi_groups=1
+" 24 bit colors
+set termguicolors
" Use my preferred colorscheme
-colorscheme gruvbox8
+colorscheme gruvbox
" }}}
" Search parameters {{{
@@ -96,12 +102,10 @@ set ignorecase
set smartcase
" }}}
-" Import settings when inside a git repository {{{
+" Project-local settings {{{
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
-let git_settings=system("git config --get vim.settings")
-if strlen(git_settings)
- exe "set" git_settings
-endif
+" Securely read `.nvim.lua` or `.nvimrc`.
+set exrc
" }}}
" vim: foldmethod=marker
diff --git a/home/vim/lua/ambroisie/lsp.lua b/home/vim/lua/ambroisie/lsp.lua
index 27e5e44..7ef6e26 100644
--- a/home/vim/lua/ambroisie/lsp.lua
+++ b/home/vim/lua/ambroisie/lsp.lua
@@ -1,40 +1,51 @@
local M = {}
+-- Simplified LSP formatting configuration
+local lsp_format = require("lsp-format")
+
+-- Move to the next/previous diagnostic, automatically showing the diagnostics
+-- float if necessary.
+-- @param forward whether to go forward or backwards
+local function goto_diagnostic(forward)
+ vim.validate({
+ forward = { forward, "boolean" },
+ })
+
+ local opts = {
+ float = false,
+ }
+
+ -- Only show floating diagnostics if they are otherwise not displayed
+ local config = vim.diagnostic.config()
+ if not (config.virtual_text or config.virtual_lines) then
+ opts.float = true
+ end
+
+ if forward then
+ vim.diagnostic.goto_next(opts)
+ else
+ vim.diagnostic.goto_prev(opts)
+ end
+end
+
+-- Move to the next diagnostic, automatically showing the diagnostics float if
+-- necessary.
+M.goto_next_diagnostic = function()
+ goto_diagnostic(true)
+end
+
+-- Move to the previous diagnostic, automatically showing the diagnostics float
+-- if necessary.
+M.goto_prev_diagnostic = function()
+ goto_diagnostic(false)
+end
+
-- shared LSP configuration callback
-- @param client native client configuration
-- @param bufnr int? buffer number of the attched client
M.on_attach = function(client, bufnr)
- -- Diagnostics
- vim.diagnostic.config({
- -- Disable virtual test next to affected regions
- virtual_text = false,
- -- Show diagnostics signs
- signs = true,
- -- Underline offending regions
- underline = true,
- -- Do not bother me in the middle of insertion
- update_in_insert = false,
- -- Show highest severity first
- severity_sort = true,
- })
-
- vim.cmd([[
- augroup DiagnosticsHover
- autocmd! *
- " Show diagnostics on "hover"
- autocmd CursorHold,CursorHoldI lua vim.diagnostic.open_float(nil, {focus=false, scope="cursor"})
- augroup END
- ]])
-
-- Format on save
- if client.resolved_capabilities.document_formatting then
- vim.cmd([[
- augroup LspFormatting
- autocmd! *
- autocmd BufWritePre lua vim.lsp.buf.formatting_sync()
- augroup END
- ]])
- end
+ lsp_format.on_attach(client, bufnr)
-- Mappings
local wk = require("which-key")
@@ -44,16 +55,41 @@ M.on_attach = function(client, bufnr)
utils.dump(vim.lsp.buf.list_workspace_folders())
end
- local function show_line_diagnostics()
- vim.diagnostic.open_float(nil, { scope="line" })
+ local function cycle_diagnostics_display()
+ -- Cycle from:
+ -- * nothing displayed
+ -- * single diagnostic at the end of the line (`virtual_text`)
+ -- * full diagnostics using virtual text (`virtual_lines`)
+ local text = vim.diagnostic.config().virtual_text
+ local lines = vim.diagnostic.config().virtual_lines
+
+ -- Text -> Lines transition
+ if text then
+ text = false
+ lines = true
+ -- Lines -> Nothing transition
+ elseif lines then
+ text = false
+ lines = false
+ -- Nothing -> Text transition
+ else
+ text = true
+ lines = false
+ end
+
+ vim.diagnostic.config({
+ virtual_text = text,
+ virtual_lines = lines,
+ })
end
local function show_buffer_diagnostics()
- vim.diagnostic.open_float(nil, { scope="buffer" })
+ vim.diagnostic.open_float(nil, { scope = "buffer" })
end
local keys = {
K = { vim.lsp.buf.hover, "Show symbol information" },
+ [""] = { vim.lsp.buf.signature_help, "Show signature information" },
["gd"] = { vim.lsp.buf.definition, "Go to definition" },
["gD"] = { vim.lsp.buf.declaration, "Go to declaration" },
["gi"] = { vim.lsp.buf.implementation, "Go to implementation" },
@@ -62,7 +98,7 @@ M.on_attach = function(client, bufnr)
["c"] = {
name = "Code",
a = { vim.lsp.buf.code_action, "Code actions" },
- d = { show_line_diagnostics, "Show line diagnostics" },
+ d = { cycle_diagnostics_display, "Cycle diagnostics display" },
D = { show_buffer_diagnostics, "Show buffer diagnostics" },
r = { vim.lsp.buf.rename, "Rename symbol" },
s = { vim.lsp.buf.signature_help, "Show signature" },
@@ -79,5 +115,4 @@ M.on_attach = function(client, bufnr)
wk.register(keys, { buffer = bufnr })
end
-
return M
diff --git a/home/vim/lua/ambroisie/utils.lua b/home/vim/lua/ambroisie/utils.lua
index 88f3d27..984c730 100644
--- a/home/vim/lua/ambroisie/utils.lua
+++ b/home/vim/lua/ambroisie/utils.lua
@@ -17,7 +17,27 @@ end
---@param cmd string? command to check
---@return fun(cmd: string): boolean executable
M.is_executable_condition = function(cmd)
- return function() return M.is_executable(cmd) end
+ return function()
+ return M.is_executable(cmd)
+ end
+end
+
+-- whether or not we are currently in an SSH connection
+-- @return boolean ssh connection
+M.is_ssh = function()
+ local variables = {
+ "SSH_CONNECTION",
+ "SSH_CLIENT",
+ "SSH_TTY",
+ }
+
+ for _, var in ipairs(variables) do
+ if string.len(os.getenv(var) or "") ~= 0 then
+ return true
+ end
+ end
+
+ return false
end
-- list all active LSP clients for current buffer
diff --git a/home/vim/plugin/abbreviations.lua b/home/vim/plugin/abbreviations.lua
new file mode 100644
index 0000000..f6d6ac3
--- /dev/null
+++ b/home/vim/plugin/abbreviations.lua
@@ -0,0 +1,9 @@
+local abbreviations = {
+ -- A few things that are hard to write in ASCII
+ ["(R)"] = "©",
+ ["(TM)"] = "™",
+}
+
+for text, result in pairs(abbreviations) do
+ vim.cmd.abbreviate(text, result)
+end
diff --git a/home/vim/plugin/abbreviations.vim b/home/vim/plugin/abbreviations.vim
deleted file mode 100644
index 5d36434..0000000
--- a/home/vim/plugin/abbreviations.vim
+++ /dev/null
@@ -1,5 +0,0 @@
-" A few useful sets of abbreviations
-
-" A few things that are hard to write in ASCII
-abbreviate (R) ©
-abbreviate (TM) ™
diff --git a/home/vim/plugin/numbertoggle.lua b/home/vim/plugin/numbertoggle.lua
new file mode 100644
index 0000000..1f97fc8
--- /dev/null
+++ b/home/vim/plugin/numbertoggle.lua
@@ -0,0 +1,23 @@
+-- Show lines numbers
+vim.opt.number = true
+
+local numbertoggle = vim.api.nvim_create_augroup("numbertoggle", { clear = true })
+
+-- Toggle numbers between relative and absolute when changing buffers
+vim.api.nvim_create_autocmd({ "BufEnter", "FocusGained", "InsertLeave", "WinEnter" }, {
+ pattern = "*",
+ group = numbertoggle,
+ command = "if &nu | setlocal rnu | endif",
+})
+vim.api.nvim_create_autocmd({ "BufLeave", "FocusLost", "InsertEnter", "WinLeave" }, {
+ pattern = "*",
+ group = numbertoggle,
+ command = "if &nu | setlocal nornu | endif",
+})
+
+-- Never show the sign column in a terminal buffer
+vim.api.nvim_create_autocmd({ "TermOpen" }, {
+ pattern = "*",
+ group = numbertoggle,
+ command = "setlocal nonu nornu",
+})
diff --git a/home/vim/plugin/numbertoggle.vim b/home/vim/plugin/numbertoggle.vim
deleted file mode 100644
index d9a969d..0000000
--- a/home/vim/plugin/numbertoggle.vim
+++ /dev/null
@@ -1,13 +0,0 @@
-" Idea for toggling taken from jeffkreeftmeijer
-
-" Show line numbers
-set number
-
-augroup numbertoggle
- autocmd!
- " Toggle numbers between relative and absolute when changing buffers
- autocmd BufEnter,FocusGained,InsertLeave,WinEnter * if &nu | set rnu | endif
- autocmd BufLeave,FocusLost,InsertEnter,WinLeave * if &nu | set nornu | endif
- " Disable line numbers and relative line numbers in terminal
- autocmd TermOpen * setlocal nonu nornu
-augroup END
diff --git a/home/vim/plugin/settings/completion.vim b/home/vim/plugin/settings/completion.lua
similarity index 89%
rename from home/vim/plugin/settings/completion.vim
rename to home/vim/plugin/settings/completion.lua
index 9a3d7e6..2d150e8 100644
--- a/home/vim/plugin/settings/completion.vim
+++ b/home/vim/plugin/settings/completion.lua
@@ -1,7 +1,6 @@
-" Show completion menu in all cases, and don't select anything
-set completeopt=menu,menuone,noselect
+-- Show completion menu in all cases, and don't select anything
+vim.opt.completeopt = { "menu", "menuone", "noselect" }
-lua << EOF
local cmp = require("cmp")
local cmp_under_comparator = require("cmp-under-comparator")
local luasnip = require("luasnip")
@@ -29,7 +28,7 @@ cmp.setup({
end,
[""] = cmp.mapping(cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Insert }), { "i", "c" }),
[""] = cmp.mapping(cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }), { "i", "c" }),
- [""] = cmp.mapping.scroll_docs(-5),
+ [""] = cmp.mapping.scroll_docs(-5),
[""] = cmp.mapping.scroll_docs(5),
[""] = cmp.mapping.confirm({ behavior = cmp.ConfirmBehavior.Insert, select = false }),
[""] = cmp.mapping.abort(),
@@ -57,5 +56,7 @@ cmp.setup({
cmp.config.compare.order,
},
},
+ experimental = {
+ ghost_text = true,
+ },
})
-EOF
diff --git a/home/vim/plugin/settings/dressing.vim b/home/vim/plugin/settings/dressing.lua
similarity index 88%
rename from home/vim/plugin/settings/dressing.vim
rename to home/vim/plugin/settings/dressing.lua
index 9508126..3928a59 100644
--- a/home/vim/plugin/settings/dressing.vim
+++ b/home/vim/plugin/settings/dressing.lua
@@ -1,8 +1,6 @@
-lua << EOF
local dressing = require("dressing")
dressing.setup({
-- Use a relative prompt size
prefer_width = 0.4,
})
-EOF
diff --git a/home/vim/plugin/settings/fastfold.lua b/home/vim/plugin/settings/fastfold.lua
new file mode 100644
index 0000000..78ee937
--- /dev/null
+++ b/home/vim/plugin/settings/fastfold.lua
@@ -0,0 +1,5 @@
+-- Intercept all fold commands
+-- stylua: ignore
+vim.g.fastfold_fold_command_suffixes = {
+ "x", "X", "a", "A", "o", "O", "c", "C", "r", "R", "m", "M", "i", "n", "N",
+}
diff --git a/home/vim/plugin/settings/fastfold.vim b/home/vim/plugin/settings/fastfold.vim
deleted file mode 100644
index a1f1787..0000000
--- a/home/vim/plugin/settings/fastfold.vim
+++ /dev/null
@@ -1,5 +0,0 @@
-" Intercept all fold commands
-let g:fastfold_fold_command_suffixes=[
- \ 'x', 'X', 'a', 'A', 'o', 'O', 'c', 'C',
- \ 'r', 'R', 'm', 'M', 'i', 'n', 'N'
- \ ]
diff --git a/home/vim/plugin/settings/formatting.lua b/home/vim/plugin/settings/formatting.lua
new file mode 100644
index 0000000..1bb896b
--- /dev/null
+++ b/home/vim/plugin/settings/formatting.lua
@@ -0,0 +1,3 @@
+local lsp_format = require("lsp-format")
+
+lsp_format.setup({})
diff --git a/home/vim/plugin/settings/git.lua b/home/vim/plugin/settings/git.lua
new file mode 100644
index 0000000..4dbebca
--- /dev/null
+++ b/home/vim/plugin/settings/git.lua
@@ -0,0 +1,58 @@
+local gitsigns = require("gitsigns")
+local wk = require("which-key")
+
+gitsigns.setup({
+ current_line_blame_opts = {
+ -- Show the blame quickly
+ delay = 100,
+ },
+})
+
+local keys = {
+ -- Navigation
+ ["[c"] = { "&diff ? '[c' : 'Gitsigns prev_hunk'", "Previous hunk/diff", expr = true },
+ ["]c"] = { "&diff ? ']c' : 'Gitsigns next_hunk'", "Next hunk/diff", expr = true },
+
+ -- Commands
+ ["g"] = {
+ name = "Git",
+ -- Actions
+ b = { gitsigns.toggle_current_line_blame, "Toggle blame virtual text" },
+ d = { gitsigns.diffthis, "Diff buffer" },
+ -- stylua: ignore
+ D = { function() gitsigns.diffthis("~") end, "Diff buffer against last commit" },
+ g = { "Git", "Git status" },
+ h = { gitsigns.toggle_deleted, "Show deleted hunks" },
+ L = { ":spT:Gllog --follow -- %:p", "Current buffer log" },
+ m = { "(git-messenger)", "Current line blame" },
+ p = { gitsigns.preview_hunk, "Preview hunk" },
+ r = { gitsigns.reset_hunk, "Restore hunk" },
+ R = { gitsigns.reset_buffer, "Restore buffer" },
+ s = { gitsigns.stage_hunk, "Stage hunk" },
+ S = { gitsigns.stage_buffer, "Stage buffer" },
+ u = { gitsigns.undo_stage_hunk, "Undo stage hunk" },
+ ["["] = { gitsigns.prev_hunk, "Previous hunk" },
+ ["]"] = { gitsigns.next_hunk, "Next hunk" },
+ },
+}
+
+local objects = {
+ ["ih"] = { gitsigns.select_hunk, "Git hunk" },
+}
+
+local visual = {
+ ["ih"] = { gitsigns.select_hunk, "Git hunk" },
+
+ -- Only the actual command can make use of the visual selection...
+ ["g"] = {
+ name = "Git",
+ p = { ":Gitsigns preview_hunk", "Preview selection" },
+ r = { ":Gitsigns reset_hunk", "Restore selection" },
+ s = { ":Gitsigns stage_hunk", "Stage selection" },
+ u = { ":Gitsigns undo_stage_hunk", "Undo stage selection" },
+ },
+}
+
+wk.register(keys, { buffer = bufnr })
+wk.register(objects, { buffer = bufnr, mode = "o" })
+wk.register(visual, { buffer = bufnr, mode = "x" })
diff --git a/home/vim/plugin/settings/git.vim b/home/vim/plugin/settings/git.vim
deleted file mode 100644
index 0deba6a..0000000
--- a/home/vim/plugin/settings/git.vim
+++ /dev/null
@@ -1,66 +0,0 @@
-lua << EOF
-local gitsigns = require('gitsigns')
-
-gitsigns.setup({
- -- I dislike the full-green sign column when this happens
- attach_to_untracked = false,
-
- current_line_blame_opts = {
- -- Show the blame quickly
- delay = 100,
- },
-
- on_attach = function(bufnr)
- local wk = require("which-key")
-
- local keys = {
- -- Navigation
- ["[c"] = { "&diff ? '[c' : 'Gitsigns prev_hunk'", "Previous hunk/diff", expr = true },
- ["]c"] = { "&diff ? ']c' : 'Gitsigns next_hunk'", "Next hunk/diff", expr = true },
-
-
- -- Commands
- ["g"] = {
- name = "Git",
- -- Actions
- b = { gitsigns.toggle_current_line_blame, "Toggle blame virtual text" },
- d = { gitsigns.diffthis, "Diff buffer" },
- D = { function() gitsigns.diffthis("~") end, "Diff buffer against last commit" },
- g = { "Git", "Git status" },
- h = { gitsigns.toggle_deleted, "Show deleted hunks" },
- L = { ":spT:Gllog --follow -- %:p", "Current buffer log" },
- m = { "(git-messenger)", "Current line blame" },
- p = { gitsigns.preview_hunk, "Preview hunk" },
- r = { gitsigns.reset_hunk, "Restore hunk" },
- R = { gitsigns.reset_buffer, "Restore buffer" },
- s = { gitsigns.stage_hunk, "Stage hunk" },
- S = { gitsigns.stage_buffer, "Stage buffer" },
- u = { gitsigns.undo_stage_hunk, "Undo stage hunk" },
- ["["] = { gitsigns.prev_hunk, "Previous hunk" },
- ["]"] = { gitsigns.next_hunk, "Next hunk" },
- },
- }
-
- local objects = {
- ["ih"] = { gitsigns.select_hunk, "Git hunk" },
- }
-
- local visual = {
- ["ih"] = { gitsigns.select_hunk, "Git hunk" },
-
- -- Only the actual command can make use of the visual selection...
- ["g"] = {
- name = "Git",
- p = { ":Gitsigns preview_hunk", "Preview selection" },
- r = { ":Gitsigns reset_hunk", "Restore selection" },
- s = { ":Gitsigns stage_hunk", "Stage selection" },
- u = { ":Gitsigns undo_stage_hunk", "Undo stage selection" },
- },
- }
-
- wk.register(keys, { buffer = bufnr })
- wk.register(objects, { buffer = bufnr, mode = "o" })
- wk.register(visual, { buffer = bufnr, mode = "x" })
- end,
-})
-EOF
diff --git a/home/vim/plugin/settings/lsp-lines.lua b/home/vim/plugin/settings/lsp-lines.lua
new file mode 100644
index 0000000..9c79818
--- /dev/null
+++ b/home/vim/plugin/settings/lsp-lines.lua
@@ -0,0 +1,3 @@
+local lsp_lines = require("lsp_lines")
+
+lsp_lines.setup()
diff --git a/home/vim/plugin/settings/lspconfig.vim b/home/vim/plugin/settings/lspconfig.lua
similarity index 55%
rename from home/vim/plugin/settings/lspconfig.vim
rename to home/vim/plugin/settings/lspconfig.lua
index dc706cc..794a765 100644
--- a/home/vim/plugin/settings/lspconfig.vim
+++ b/home/vim/plugin/settings/lspconfig.lua
@@ -1,11 +1,25 @@
-lua << EOF
local lspconfig = require("lspconfig")
local lsp = require("ambroisie.lsp")
local utils = require("ambroisie.utils")
+-- Diagnostics
+vim.diagnostic.config({
+ -- Disable virtual test next to affected regions
+ virtual_text = false,
+ -- Also disable virtual diagnostics under the affected regions
+ virtual_lines = false,
+ -- Show diagnostics signs
+ signs = true,
+ -- Underline offending regions
+ underline = true,
+ -- Do not bother me in the middle of insertion
+ update_in_insert = false,
+ -- Show highest severity first
+ severity_sort = true,
+})
+
-- Inform servers we are able to do completion, snippets, etc...
-local capabilities = vim.lsp.protocol.make_client_capabilities()
-capabilities = require("cmp_nvim_lsp").update_capabilities(capabilities)
+local capabilities = require("cmp_nvim_lsp").default_capabilities()
-- C/C++
if utils.is_executable("clangd") then
@@ -16,6 +30,13 @@ if utils.is_executable("clangd") then
end
-- Nix
+if utils.is_executable("nil") then
+ lspconfig.nil_ls.setup({
+ capabilities = capabilities,
+ on_attach = lsp.on_attach,
+ })
+end
+
if utils.is_executable("rnix-lsp") then
lspconfig.rnix.setup({
capabilities = capabilities,
@@ -38,4 +59,3 @@ if utils.is_executable("rust-analyzer") then
on_attach = lsp.on_attach,
})
end
-EOF
diff --git a/home/vim/plugin/settings/lualine.vim b/home/vim/plugin/settings/lualine.lua
similarity index 97%
rename from home/vim/plugin/settings/lualine.vim
rename to home/vim/plugin/settings/lualine.lua
index 0273c78..fdaccda 100644
--- a/home/vim/plugin/settings/lualine.vim
+++ b/home/vim/plugin/settings/lualine.lua
@@ -1,4 +1,3 @@
-lua << EOF
local lualine = require("lualine")
local utils = require("ambroisie.utils")
@@ -31,7 +30,7 @@ lualine.setup({
{ "mode" },
},
lualine_b = {
- { "branch" },
+ { "FugitiveHead" },
{ "filename", symbols = { readonly = "🔒" } },
},
lualine_c = {
@@ -60,4 +59,3 @@ lualine.setup({
"quickfix",
},
})
-EOF
diff --git a/home/vim/plugin/settings/luasnip.lua b/home/vim/plugin/settings/luasnip.lua
new file mode 100644
index 0000000..80309d7
--- /dev/null
+++ b/home/vim/plugin/settings/luasnip.lua
@@ -0,0 +1 @@
+require("luasnip.loaders.from_vscode").lazy_load()
diff --git a/home/vim/plugin/settings/luasnip.vim b/home/vim/plugin/settings/luasnip.vim
deleted file mode 100644
index 9527d22..0000000
--- a/home/vim/plugin/settings/luasnip.vim
+++ /dev/null
@@ -1,3 +0,0 @@
-lua << EOF
-require("luasnip.loaders.from_vscode").load()
-EOF
diff --git a/home/vim/plugin/settings/notify.lua b/home/vim/plugin/settings/notify.lua
new file mode 100644
index 0000000..b68c90f
--- /dev/null
+++ b/home/vim/plugin/settings/notify.lua
@@ -0,0 +1,14 @@
+local notify = require("notify")
+
+notify.setup({
+ icons = {
+ DEBUG = "D",
+ ERROR = "E",
+ INFO = "I",
+ TRACE = "T",
+ WARN = "W",
+ },
+ stages = "slide",
+})
+
+vim.notify = notify
diff --git a/home/vim/plugin/settings/notify.vim b/home/vim/plugin/settings/notify.vim
deleted file mode 100644
index d60927f..0000000
--- a/home/vim/plugin/settings/notify.vim
+++ /dev/null
@@ -1,9 +0,0 @@
-lua << EOF
-local notify = require("notify")
-
-notify.setup({
- stages = "slide",
-})
-
-vim.notify = notify
-EOF
diff --git a/home/vim/plugin/settings/null-ls.vim b/home/vim/plugin/settings/null-ls.lua
similarity index 80%
rename from home/vim/plugin/settings/null-ls.vim
rename to home/vim/plugin/settings/null-ls.lua
index bec8124..0eaa55c 100644
--- a/home/vim/plugin/settings/null-ls.vim
+++ b/home/vim/plugin/settings/null-ls.lua
@@ -1,4 +1,3 @@
-lua << EOF
local null_ls = require("null-ls")
local lsp = require("ambroisie.lsp")
local utils = require("ambroisie.utils")
@@ -7,6 +6,18 @@ null_ls.setup({
on_attach = lsp.on_attach,
})
+-- Bazel
+null_ls.register({
+ null_ls.builtins.diagnostics.buildifier.with({
+ -- Only used if available
+ condition = utils.is_executable_condition("buildifier"),
+ }),
+ null_ls.builtins.formatting.buildifier.with({
+ -- Only used if available
+ condition = utils.is_executable_condition("buildifier"),
+ }),
+})
+
-- C, C++
null_ls.register({
null_ls.builtins.formatting.clang_format.with({
@@ -30,7 +41,9 @@ null_ls.register({
null_ls.builtins.formatting.nixpkgs_fmt.with({
-- Only used if available, but prefer rnix if available
condition = function()
- return utils.is_executable("nixpkgs-fmt") and not utils.is_executable("rnix-lsp")
+ return utils.is_executable("nixpkgs-fmt")
+ and not utils.is_executable("rnix-lsp")
+ and not utils.is_executable("nil")
end,
}),
})
@@ -38,8 +51,14 @@ null_ls.register({
-- Python
null_ls.register({
null_ls.builtins.diagnostics.flake8.with({
+ -- Only used if available, but prefer pflake8 if available
+ condition = function()
+ return utils.is_executable("flake8") and not utils.is_executable("pflake8")
+ end,
+ }),
+ null_ls.builtins.diagnostics.pyproject_flake8.with({
-- Only used if available
- condition = utils.is_executable_condition("flake8"),
+ condition = utils.is_executable_condition("pflake8"),
}),
null_ls.builtins.diagnostics.mypy.with({
-- Only used if available
@@ -60,7 +79,6 @@ null_ls.register({
}),
})
-
-- Shell (non-POSIX)
null_ls.register({
null_ls.builtins.code_actions.shellcheck.with({
@@ -93,7 +111,7 @@ null_ls.register({
-- Shell (POSIX)
null_ls.register({
null_ls.builtins.code_actions.shellcheck.with({
- -- Restrict to POSIX sh
+ -- Restrict to POSIX sh
filetypes = { "sh" },
-- Only used if available
condition = utils.is_executable_condition("shellcheck"),
@@ -112,8 +130,9 @@ null_ls.register({
-- 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"),
}),
})
-EOF
diff --git a/home/vim/plugin/settings/pandoc.vim b/home/vim/plugin/settings/pandoc.vim
deleted file mode 100644
index 71b750c..0000000
--- a/home/vim/plugin/settings/pandoc.vim
+++ /dev/null
@@ -1,20 +0,0 @@
-" Which code-block languages should I expect to be high-lighted.
-let g:pandoc#syntax#codeblocks#embeds#langs=[
- \ "bash=sh",
- \ "c",
- \ "cpp",
- \ "go",
- \ "haskell",
- \ "python",
- \ "rust",
- \ "sh",
- \ "vim",
- \ "yaml",
- \ "tex",
- \ "toml",
- \ "perl",
- \ "json",
- \ "latex=tex",
- \ "make",
- \ "makefile=make",
- \ ]
diff --git a/home/vim/plugin/settings/ssh.lua b/home/vim/plugin/settings/ssh.lua
new file mode 100644
index 0000000..992a707
--- /dev/null
+++ b/home/vim/plugin/settings/ssh.lua
@@ -0,0 +1,17 @@
+if not require("ambroisie.utils").is_ssh() then
+ return
+end
+
+local function copy(lines, _)
+ require("osc52").copy(table.concat(lines, "\n"))
+end
+
+local function paste()
+ return { vim.fn.split(vim.fn.getreg(""), "\n"), vim.fn.getregtype("") }
+end
+
+vim.g.clipboard = {
+ name = "osc52",
+ copy = { ["+"] = copy, ["*"] = copy },
+ paste = { ["+"] = paste, ["*"] = paste },
+}
diff --git a/home/vim/plugin/settings/surround.lua b/home/vim/plugin/settings/surround.lua
new file mode 100644
index 0000000..3585a12
--- /dev/null
+++ b/home/vim/plugin/settings/surround.lua
@@ -0,0 +1,3 @@
+require("nvim-surround").setup({
+ -- No configuration at the moment
+})
diff --git a/home/vim/plugin/settings/telescope.vim b/home/vim/plugin/settings/telescope.lua
similarity index 60%
rename from home/vim/plugin/settings/telescope.vim
rename to home/vim/plugin/settings/telescope.lua
index 084aeb4..ed8ebc7 100644
--- a/home/vim/plugin/settings/telescope.vim
+++ b/home/vim/plugin/settings/telescope.lua
@@ -1,7 +1,15 @@
-lua << EOF
local telescope = require("telescope")
telescope.setup({
+ defaults = {
+ mappings = {
+ i = {
+ [""] = "which_key",
+ -- I want the normal readline mappings rather than scrolling
+ [""] = false,
+ },
+ },
+ },
extensions = {
fzf = {
fuzzy = true,
@@ -15,4 +23,3 @@ telescope.setup({
telescope.load_extension("fzf")
telescope.load_extension("lsp_handlers")
telescope.load_extension("notify")
-EOF
diff --git a/home/vim/plugin/settings/tree-sitter.vim b/home/vim/plugin/settings/tree-sitter.lua
similarity index 99%
rename from home/vim/plugin/settings/tree-sitter.vim
rename to home/vim/plugin/settings/tree-sitter.lua
index 1204185..0d84abd 100644
--- a/home/vim/plugin/settings/tree-sitter.vim
+++ b/home/vim/plugin/settings/tree-sitter.lua
@@ -1,4 +1,3 @@
-lua << EOF
local ts_config = require("nvim-treesitter.configs")
ts_config.setup({
highlight = {
@@ -55,4 +54,3 @@ ts_config.setup({
},
},
})
-EOF
diff --git a/home/vim/plugin/settings/which-key.vim b/home/vim/plugin/settings/which-key.lua
similarity index 74%
rename from home/vim/plugin/settings/which-key.vim
rename to home/vim/plugin/settings/which-key.lua
index 505bdc4..2edfd70 100644
--- a/home/vim/plugin/settings/which-key.vim
+++ b/home/vim/plugin/settings/which-key.lua
@@ -1,4 +1,2 @@
-lua << EOF
local wk = require("which-key")
wk.setup()
-EOF
diff --git a/home/vim/plugin/signtoggle.lua b/home/vim/plugin/signtoggle.lua
new file mode 100644
index 0000000..d6a26e2
--- /dev/null
+++ b/home/vim/plugin/signtoggle.lua
@@ -0,0 +1,20 @@
+local signtoggle = vim.api.nvim_create_augroup("signtoggle", { clear = true })
+
+-- Only show sign column for the currently focused buffer
+vim.api.nvim_create_autocmd({ "BufEnter", "FocusGained", "WinEnter" }, {
+ pattern = "*",
+ group = signtoggle,
+ command = "setlocal signcolumn=yes",
+})
+vim.api.nvim_create_autocmd({ "BufLeave", "FocusLost", "WinLeave" }, {
+ pattern = "*",
+ group = signtoggle,
+ command = "setlocal signcolumn=yes",
+})
+
+-- Never show the sign column in a terminal buffer
+vim.api.nvim_create_autocmd({ "TermOpen" }, {
+ pattern = "*",
+ group = signtoggle,
+ command = "setlocal signcolumn=no",
+})
diff --git a/home/vim/plugin/signtoggle.vim b/home/vim/plugin/signtoggle.vim
deleted file mode 100644
index c2f0183..0000000
--- a/home/vim/plugin/signtoggle.vim
+++ /dev/null
@@ -1,8 +0,0 @@
-augroup signtoggle
- autocmd!
- " Only show the sign column for the current focused buffer
- autocmd BufEnter,FocusGained,WinEnter * set signcolumn=yes
- autocmd BufLeave,FocusLost,WinLeave * set signcolumn=no
- " Disable the sign column in terminal
- autocmd TermOpen * setlocal signcolumn=no
-augroup END
diff --git a/home/wm/cursor/default.nix b/home/wm/cursor/default.nix
new file mode 100644
index 0000000..9426232
--- /dev/null
+++ b/home/wm/cursor/default.nix
@@ -0,0 +1,23 @@
+{ config, lib, pkgs, ... }:
+let
+ cfg = config.my.home.wm.cursor;
+
+ cfg_x = config.my.home.x;
+ cfg_gtk = config.my.home.gtk;
+in
+{
+ config = lib.mkIf cfg.enable {
+ home.pointerCursor = {
+ package = pkgs.ambroisie.vimix-cursors;
+ name = "Vimix-cursors";
+
+ x11 = {
+ inherit (cfg_x) enable;
+ };
+
+ gtk = {
+ inherit (cfg_gtk) enable;
+ };
+ };
+ };
+}
diff --git a/home/wm/default.nix b/home/wm/default.nix
index 1d5a371..6a615e5 100644
--- a/home/wm/default.nix
+++ b/home/wm/default.nix
@@ -10,6 +10,7 @@ let
in
{
imports = [
+ ./cursor
./dunst
./i3
./i3bar
@@ -25,6 +26,10 @@ in
description = "Which window manager to use for home session";
};
+ cursor = {
+ enable = mkRelatedOption "dunst configuration" [ "i3" ];
+ };
+
dunst = {
enable = mkRelatedOption "dunst configuration" [ "i3" ];
};
@@ -42,8 +47,8 @@ in
command = mkOption {
type = types.str;
- default = "${pkgs.i3lock}/bin/i3lock -n -c 000000";
- example = "\${pkgs.i3lock}/bin/i3lock -n -i lock.png";
+ default = "${lib.getExe pkgs.i3lock} -n -c 000000";
+ example = "\${lib.getExe pkgs.i3lock} -n -i lock.png";
description = "Locker command to run";
};
diff --git a/home/wm/i3/default.nix b/home/wm/i3/default.nix
index c92285f..d1dbe2c 100644
--- a/home/wm/i3/default.nix
+++ b/home/wm/i3/default.nix
@@ -27,13 +27,13 @@ let
genMovementBindings = f: addVimKeyBindings (lib.my.genAttrs' movementKeys f);
# Used in multiple scripts to show messages through keybindings
- notify-send = "${pkgs.libnotify}/bin/notify-send";
+ notify-send = lib.getExe pkgs.libnotify;
# Screen backlight management
- changeBacklight = "${pkgs.ambroisie.change-backlight}/bin/change-backlight";
+ changeBacklight = lib.getExe pkgs.ambroisie.change-backlight;
# Audio and volume management
- changeAudio = "${pkgs.ambroisie.change-audio}/bin/change-audio";
+ changeAudio = lib.getExe pkgs.ambroisie.change-audio;
# Lock management
toggleXautolock =
@@ -61,8 +61,8 @@ in
ambroisie.dragger # drag-and-drop from the CLI
ambroisie.i3-get-window-criteria # little helper for i3 configuration
arandr # Used by a mapping
- pamixer # Used by a mapping
playerctl # Used by a mapping
+ xdotool # Used by 'rofi-rbw', in a mapping
];
xsession.windowManager.i3 = {
@@ -73,14 +73,12 @@ in
bars =
let
- barConfigPath =
- config.xdg.configFile."i3status-rust/config-top.toml".target;
- i3status-rs =
- "${config.programs.i3status-rust.package}/bin/i3status-rs";
+ i3status-rs = lib.getExe config.programs.i3status-rust.package;
in
+ assert [ "top" ] == lib.attrNames config.programs.i3status-rust.bars;
[
{
- statusCommand = "${i3status-rs} ${barConfigPath}";
+ statusCommand = "${i3status-rs} config-top.toml";
trayOutput = "primary";
position = "top";
@@ -175,6 +173,10 @@ in
"${modifier}+Control+space" = "floating toggle";
# Change focus between tiling/floating
"${modifier}+space" = "focus mode_toggle";
+ # Center floating window
+ "${modifier}+c" = "move absolute position center";
+ # Center floating window
+ "${modifier}+Shift+s" = "sticky toggle";
}
{
# Focus parent container
@@ -187,11 +189,12 @@ in
"${modifier}+d" = "exec rofi -show drun -disable-history";
"${modifier}+Shift+d" = "exec rofi -show run -disable-history";
"${modifier}+p" = "exec --no-startup-id flameshot gui";
+ "${modifier}+Ctrl+p" = "exec ${lib.getExe pkgs.rofi-rbw}";
"${modifier}+Shift+p" = "exec rofi -show emoji";
"${modifier}+b" =
let
inherit (config.my.home.bluetooth) enable;
- prog = "${pkgs.ambroisie.rofi-bluetooth}/bin/rofi-bluetooth";
+ prog = lib.getExe pkgs.rofi-bluetooth;
in
lib.mkIf enable "exec ${prog}";
})
@@ -370,6 +373,16 @@ in
# FIXME
# { commdand; always; notification; }
];
+
+ window = {
+ commands = [
+ # Make htop window bigger
+ {
+ criteria = { title = "^htop$"; };
+ command = "resize set 80 ppt 80 ppt, move position center";
+ }
+ ];
+ };
};
};
};
diff --git a/home/wm/i3bar/default.nix b/home/wm/i3bar/default.nix
index a330134..05b0f50 100644
--- a/home/wm/i3bar/default.nix
+++ b/home/wm/i3bar/default.nix
@@ -5,7 +5,7 @@ in
{
config = lib.mkIf cfg.enable {
home.packages = with pkgs; [
- alsaUtils # Used by `sound` block
+ alsa-utils # Used by `sound` block
lm_sensors # Used by `temperature` block
font-awesome # Icon font
];
@@ -20,28 +20,52 @@ in
blocks = builtins.filter (attr: attr != { }) [
{
block = "music";
- buttons = [ "prev" "play" "next" ];
- max_width = 50;
- dynamic_width = true;
- hide_when_empty = true;
+ # This format seems to remove the block when not playing, somehow
+ format = "{ $icon $combo.str(max_w:50,rot_interval:0.5) $prev $play $next |}";
+ click = [
+ {
+ button = "play";
+ action = "music_play";
+ }
+ {
+ button = "prev";
+ action = "music_prev";
+ }
+ {
+ button = "next";
+ action = "music_next";
+ }
+ ];
}
(lib.optionalAttrs config.my.home.bluetooth.enable {
block = "bluetooth";
mac = "4C:87:5D:06:40:D9";
- hide_disconnected = true;
- format = "Boson {percentage}";
+ format = " $icon Boson{ $percentage|} ";
+ disconnected_format = "";
+ })
+ (lib.optionalAttrs config.my.home.bluetooth.enable {
+ block = "bluetooth";
+ mac = "38:18:4C:BE:8E:97";
+ format = " $icon Muon{ $percentage|} ";
+ disconnected_format = "";
})
(lib.optionalAttrs config.my.home.bluetooth.enable {
block = "bluetooth";
mac = "94:DB:56:00:EE:93";
- hide_disconnected = true;
- format = "Protons {percentage}";
+ format = " $icon Protons{ $percentage|} ";
+ disconnected_format = "";
+ })
+ (lib.optionalAttrs config.my.home.bluetooth.enable {
+ block = "bluetooth";
+ mac = "88:C9:E8:6B:B7:55";
+ format = " $icon Quarks{ $percentage|} ";
+ disconnected_format = "";
})
(lib.optionalAttrs config.my.home.bluetooth.enable {
block = "bluetooth";
mac = "F7:78:BA:76:52:F7";
- hide_disconnected = true;
- format = "MX Ergo {percentage}";
+ format = " $icon MX Ergo{ $percentage|} ";
+ disconnected_format = "";
})
{
block = "cpu";
@@ -51,7 +75,7 @@ in
}
{
block = "net";
- format = "{ssid} {ip} {signal_strength}";
+ format = " $icon{| $ssid|} $ip{| $signal_strength|} ";
}
{
block = "backlight";
@@ -59,17 +83,19 @@ in
}
{
block = "battery";
- format = "{percentage} ({time})";
- full_format = "{percentage}";
+ format = " $icon $percentage{ ($time)|} ";
+ empty_format = " $icon $percentage{ ($time)|} ";
+ not_charging_format = " $icon $percentage ";
+ full_format = " $icon $percentage ";
}
{
block = "temperature";
- collapsed = false;
+ format_alt = " $icon ";
}
{
block = "sound";
device_kind = "source"; # Microphone status
- format = ""; # Only show icon
+ format = " $icon ";
}
{
block = "sound";
@@ -77,7 +103,8 @@ in
}
{
block = "time";
- format = "%F %T";
+ format = " $icon $timestamp.datetime(f:'%F %T') ";
+ interval = 5;
}
];
};
diff --git a/home/wm/screen-lock/default.nix b/home/wm/screen-lock/default.nix
index 95060b8..3b2ead6 100644
--- a/home/wm/screen-lock/default.nix
+++ b/home/wm/screen-lock/default.nix
@@ -5,7 +5,7 @@ let
notficationCmd =
let
duration = toString (cfg.notify.delay * 1000);
- notifyCmd = "${pkgs.libnotify}/bin/notify-send -u critical -t ${duration}";
+ notifyCmd = "${lib.getExe pkgs.libnotify} -u critical -t ${duration}";
in
# Needs to be surrounded by quotes for systemd to launch it correctly
''"${notifyCmd} -- 'Locking in ${toString cfg.notify.delay} seconds'"'';
diff --git a/home/x/cursor/default.nix b/home/x/cursor/default.nix
deleted file mode 100644
index 4762199..0000000
--- a/home/x/cursor/default.nix
+++ /dev/null
@@ -1,12 +0,0 @@
-{ config, lib, pkgs, ... }:
-let
- cfg = config.my.home.x;
-in
-{
- config = lib.mkIf cfg.enable {
- xsession.pointerCursor = {
- package = pkgs.ambroisie.vimix-cursors;
- name = "Vimix-cursors";
- };
- };
-}
diff --git a/home/x/default.nix b/home/x/default.nix
index ac66a50..0312bc4 100644
--- a/home/x/default.nix
+++ b/home/x/default.nix
@@ -4,7 +4,6 @@ let
in
{
imports = [
- ./cursor
./keyboard
];
diff --git a/home/xdg/default.nix b/home/xdg/default.nix
index 1aa69ac..3fd8dc9 100644
--- a/home/xdg/default.nix
+++ b/home/xdg/default.nix
@@ -3,8 +3,8 @@ let
cfg = config.my.home.xdg;
in
{
- options.my.home.xdg = with lib.my; {
- enable = mkDisableOption "XDG configuration";
+ options.my.home.xdg = with lib; {
+ enable = my.mkDisableOption "XDG configuration";
};
config.xdg = lib.mkIf cfg.enable {
@@ -38,6 +38,7 @@ in
# I want a tidier home
config.home.sessionVariables = with config.xdg; lib.mkIf cfg.enable {
+ ANDROID_HOME = "${dataHome}/android";
CARGO_HOME = "${dataHome}/cargo";
DOCKER_CONFIG = "${configHome}/docker";
GDBHISTFILE = "${dataHome}/gdb/gdb_history";
@@ -45,6 +46,8 @@ in
INPUTRC = "${configHome}/readline/inputrc";
LESSHISTFILE = "${dataHome}/less/history";
LESSKEY = "${configHome}/less/lesskey";
- WGETRC = "${configHome}/wgetrc";
+ PSQL_HISTORY = "${dataHome}/psql_history";
+ REDISCLI_HISTFILE = "${dataHome}/redis/rediscli_history";
+ XCOMPOSECACHE = "${dataHome}/X11/xcompose";
};
}
diff --git a/home/zsh/completion-styles.zsh b/home/zsh/completion-styles.zsh
index a0181a5..156bc2c 100644
--- a/home/zsh/completion-styles.zsh
+++ b/home/zsh/completion-styles.zsh
@@ -8,6 +8,8 @@ zstyle ':completion:*' menu select
zstyle ':completion:*' group-name ''
# Keep directories and files separated
zstyle ':completion:*' list-dirs-first true
+# Expand '//' to '/'
+zstyle ':completion:*' squeeze-slashes true
# Add colors to processes for kill completion
zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#)*=0=01;31'
diff --git a/home/zsh/default.nix b/home/zsh/default.nix
index 27ea8bc..4cadb57 100644
--- a/home/zsh/default.nix
+++ b/home/zsh/default.nix
@@ -1,10 +1,20 @@
{ config, pkgs, lib, ... }:
let
cfg = config.my.home.zsh;
+
+ # Have a nice relative path for XDG_CONFIG_HOME, without leading `/`
+ relativeXdgConfig =
+ let
+ noHome = lib.removePrefix config.home.homeDirectory;
+ noSlash = lib.removePrefix "/";
+ in
+ noSlash (noHome config.xdg.configHome);
in
{
- options.my.home.zsh = with lib.my; {
- enable = mkDisableOption "zsh configuration";
+ options.my.home.zsh = with lib; {
+ enable = my.mkDisableOption "zsh configuration";
+
+ launchTmux = mkEnableOption "auto launch tmux at shell start";
};
config = lib.mkIf cfg.enable {
@@ -14,20 +24,21 @@ in
programs.zsh = {
enable = true;
- dotDir = ".config/zsh"; # Don't clutter $HOME
+ dotDir = "${relativeXdgConfig}/zsh"; # Don't clutter $HOME
enableCompletion = true;
history = {
size = 500000;
save = 500000;
- extended = false;
+ extended = true;
+ expireDuplicatesFirst = true;
ignoreSpace = true;
ignoreDups = true;
share = false;
path = "${config.xdg.dataHome}/zsh/zsh_history";
};
- plugins = with pkgs; [
+ plugins = [
{
name = "fast-syntax-highlighting";
file = "share/zsh/site-functions/fast-syntax-highlighting.plugin.zsh";
@@ -35,12 +46,8 @@ in
}
{
name = "agkozak-zsh-prompt";
- src = fetchFromGitHub {
- owner = "agkozak";
- repo = "agkozak-zsh-prompt";
- rev = "v3.9.0";
- sha256 = "sha256-VTRL+8ph2eI7iPht15epkLggAgtLGxB3DORFTW5GrhE=";
- };
+ file = "share/zsh/site-functions/agkozak-zsh-prompt.plugin.zsh";
+ src = pkgs.agkozak-zsh-prompt;
}
];
@@ -48,20 +55,27 @@ in
defaultKeymap = "emacs";
# Make those happen early to avoid doing double the work
- initExtraFirst =
- lib.optionalString config.my.home.tmux.enable ''
- # Launch tmux unless already inside one
- if [ -z "$TMUX" ]; then
- exec tmux new-session
- fi
- ''
- ;
+ initExtraFirst = ''
+ ${
+ lib.optionalString cfg.launchTmux ''
+ # Launch tmux unless already inside one
+ if [ -z "$TMUX" ]; then
+ exec tmux new-session
+ fi
+ ''
+ }
+ '';
- initExtra = lib.concatMapStrings builtins.readFile [
- ./completion-styles.zsh
- ./extra-mappings.zsh
- ./options.zsh
- ];
+ initExtra = ''
+ source ${./completion-styles.zsh}
+ source ${./extra-mappings.zsh}
+ source ${./options.zsh}
+
+ # Source local configuration
+ if [ -f "$ZDOTDIR/zshrc.local" ]; then
+ source "$ZDOTDIR/zshrc.local"
+ fi
+ '';
localVariables = {
# I like having the full path
@@ -74,26 +88,8 @@ in
AGKOZAK_LEFT_PROMPT_ONLY = 1;
};
- shellAliases = {
- # Sometime `gpg-agent` errors out...
- reset-agent = "gpg-connect-agent updatestartuptty /bye";
- };
-
- # Enable VTE integration when using one of the affected shells
- enableVteIntegration =
- builtins.any (name: config.my.home.terminal.program == name) [
- "termite"
- ];
- };
-
- # Fuzzy-wuzzy
- programs.fzf = {
- enable = true;
- enableZshIntegration = true;
- };
-
- programs.dircolors = {
- enable = true;
+ # Enable VTE integration
+ enableVteIntegration = true;
};
};
}
diff --git a/home/zsh/extra-mappings.zsh b/home/zsh/extra-mappings.zsh
index 8f7cc4a..3456e13 100644
--- a/home/zsh/extra-mappings.zsh
+++ b/home/zsh/extra-mappings.zsh
@@ -1,8 +1,7 @@
-# Fix delete key not working
-bindkey "\e[3~" delete-char
+# shellcheck disable=2154
# Fix Ctrl+u killing from the cursor instead of the whole line
-bindkey \^U backward-kill-line
+bindkey '^u' backward-kill-line
# Use Ctrl+x-(Ctrl+)e to edit the current command line in VISUAL/EDITOR
autoload -U edit-command-line
@@ -10,5 +9,124 @@ zle -N edit-command-line
bindkey '^xe' edit-command-line
bindkey '^x^e' edit-command-line
+# The expression: (( ${+terminfo} )) should never fail, but does if we
+# don't have a tty, perhaps due to a bug in the zsh/terminfo module.
+if ! { [ "$TERM" != emacs ] && (( ${+terminfo} )) 2>/dev/null; }; then
+ return
+fi
+
+# Make sure that the terminal is in application mode when zle is active, since
+# only then values from $terminfo are valid
+if (( ${+terminfo[smkx]} )) && (( ${+terminfo[rmkx]} )); then
+ autoload -Uz add-zle-hook-widget
+
+ zle_application_mode_start() { echoti smkx; }
+ zle_application_mode_stop() { echoti rmkx; }
+
+ add-zle-hook-widget -Uz zle-line-init zle_application_mode_start
+ add-zle-hook-widget -Uz zle-line-finish zle_application_mode_stop
+fi
+
+
+# Fix delete key not working
+if [ -n "${terminfo[kdch1]}" ]; then
+ bindkey -M emacs "${terminfo[kdch1]}" delete-char
+ bindkey -M viins "${terminfo[kdch1]}" delete-char
+ bindkey -M vicmd "${terminfo[kdch1]}" delete-char
+else
+ bindkey -M emacs "^[[3~" delete-char
+ bindkey -M viins "^[[3~" delete-char
+ bindkey -M vicmd "^[[3~" delete-char
+
+ bindkey -M emacs "^[3;5~" delete-char
+ bindkey -M viins "^[3;5~" delete-char
+ bindkey -M vicmd "^[3;5~" delete-char
+fi
+
+# Ctrl-Delete to delete a whole word forward
+if [ -n "${terminfo[kdl1]}" ]; then
+ bindkey -M emacs "${terminfo[kdl1]}" kill-word
+ bindkey -M viins "${terminfo[kdl1]}" kill-word
+ bindkey -M vicmd "${terminfo[kdl1]}" kill-word
+else
+ bindkey -M emacs '^[[3;5~' kill-word
+ bindkey -M viins '^[[3;5~' kill-word
+ bindkey -M vicmd '^[[3;5~' kill-word
+fi
+
# Enable Shift-Tab to go backwards in completion list
-bindkey '^[[Z' reverse-menu-complete
+if [ -n "${terminfo[kcbt]}" ]; then
+ bindkey -M emacs "${terminfo[kcbt]}" reverse-menu-complete
+ bindkey -M viins "${terminfo[kcbt]}" reverse-menu-complete
+ bindkey -M vicmd "${terminfo[kcbt]}" reverse-menu-complete
+else
+ bindkey -M emacs '^[[Z' reverse-menu-complete
+ bindkey -M viins '^[[Z' reverse-menu-complete
+ bindkey -M vicmd '^[[Z' reverse-menu-complete
+fi
+
+# Ctrl-Left moves backward one word
+if [ -n "${terminfo[kLFT5]}" ]; then
+ bindkey -M emacs "${terminfo[kLFT5]}" backward-word
+ bindkey -M viins "${terminfo[kLFT5]}" backward-word
+ bindkey -M vicmd "${terminfo[kLFT5]}" backward-word
+else
+ bindkey -M emacs '^[[1;5D' backward-word
+ bindkey -M viins '^[[1;5D' backward-word
+ bindkey -M vicmd '^[[1;5D' backward-word
+fi
+
+# Ctrl-Right moves forward one word
+if [ -n "${terminfo[kRIT5]}" ]; then
+ bindkey -M emacs "${terminfo[kRIT5]}" forward-word
+ bindkey -M viins "${terminfo[kRIT5]}" forward-word
+ bindkey -M vicmd "${terminfo[kRIT5]}" forward-word
+else
+ bindkey -M emacs '^[[1;5C' forward-word
+ bindkey -M viins '^[[1;5C' forward-word
+ bindkey -M vicmd '^[[1;5C' forward-word
+fi
+
+# PageUp goes backwards in history
+if [ -n "${terminfo[kpp]}" ]; then
+ bindkey -M emacs "${terminfo[kpp]}" up-line-or-history
+ bindkey -M viins "${terminfo[kpp]}" up-line-or-history
+ bindkey -M vicmd "${terminfo[kpp]}" up-line-or-history
+else
+ bindkey -M emacs "^[[5~" up-line-or-history
+ bindkey -M viins "^[[5~" up-line-or-history
+ bindkey -M vicmd "^[[5~" up-line-or-history
+fi
+
+# PageDown goes forward in history
+if [ -n "${terminfo[knp]}" ]; then
+ bindkey -M emacs "${terminfo[knp]}" down-line-or-history
+ bindkey -M viins "${terminfo[knp]}" down-line-or-history
+ bindkey -M vicmd "${terminfo[knp]}" down-line-or-history
+else
+ bindkey -M emacs "^[[6~" down-line-or-history
+ bindkey -M viins "^[[6~" down-line-or-history
+ bindkey -M vicmd "^[[6~" down-line-or-history
+fi
+
+# Home goes to the beginning of the line
+if [ -n "${terminfo[khome]}" ]; then
+ bindkey -M emacs "${terminfo[khome]}" beginning-of-line
+ bindkey -M viins "${terminfo[khome]}" beginning-of-line
+ bindkey -M vicmd "${terminfo[khome]}" beginning-of-line
+else
+ bindkey -M emacs "^[[1~" beginning-of-line
+ bindkey -M viins "^[[1~" beginning-of-line
+ bindkey -M vicmd "^[[1~" beginning-of-line
+fi
+
+# End goes to the end of the line
+if [ -n "${terminfo[kend]}" ]; then
+ bindkey -M emacs "${terminfo[kend]}" end-of-line
+ bindkey -M viins "${terminfo[kend]}" end-of-line
+ bindkey -M vicmd "${terminfo[kend]}" end-of-line
+else
+ bindkey -M emacs "^[[4~" end-of-line
+ bindkey -M viins "^[[4~" end-of-line
+ bindkey -M vicmd "^[[4~" end-of-line
+fi
diff --git a/home/zsh/options.zsh b/home/zsh/options.zsh
index e1e31f4..82047ff 100644
--- a/home/zsh/options.zsh
+++ b/home/zsh/options.zsh
@@ -1,16 +1,18 @@
# Show an error when a globbing expansion doesn't find any match
setopt nomatch
# List on ambiguous completion and Insert first match immediately
-setopt autolist menucomplete
+setopt auto_list menu_complete
# Use pushd when cd-ing around
-setopt autopushd pushdminus pushdsilent
+setopt auto_pushd pushd_minus pushd_silent
# Use single quotes in string without the weird escape tricks
-setopt rcquotes
+setopt rc_quotes
# Single word commands can resume an existing job
-setopt autoresume
+setopt auto_resume
+# Show history expansion before running a command
+setopt hist_verify
# Append commands to history as they are exectuted
setopt inc_append_history_time
# Remove useless whitespace from commands
setopt hist_reduce_blanks
# Those options aren't wanted
-unsetopt beep extendedglob notify
+unsetopt beep extended_glob notify
diff --git a/hosts/homes/ambroisie/default.nix b/hosts/homes/ambroisie/default.nix
new file mode 100644
index 0000000..42ea5b8
--- /dev/null
+++ b/hosts/homes/ambroisie/default.nix
@@ -0,0 +1,5 @@
+# Default home-manager configuration
+{ ... }:
+{
+ # Default configuration, nothing to do
+}
diff --git a/hosts/homes/ambroisie@ambroisie/default.nix b/hosts/homes/ambroisie@ambroisie/default.nix
new file mode 100644
index 0000000..94efc09
--- /dev/null
+++ b/hosts/homes/ambroisie@ambroisie/default.nix
@@ -0,0 +1,17 @@
+# Google Cloudtop configuration
+{ lib, pkgs, ... }:
+{
+ # Google specific configuration
+ home.homeDirectory = "/usr/local/google/home/ambroisie";
+
+ # Some tooling (e.g: SSH) need to use this library
+ home.sessionVariables = {
+ LD_PRELOAD = "/lib/x86_64-linux-gnu/libnss_cache.so.2\${LD_PRELOAD:+:}$LD_PRELOAD";
+ };
+
+ systemd.user.sessionVariables = {
+ LD_PRELOAD = "/lib/x86_64-linux-gnu/libnss_cache.so.2\${LD_PRELOAD:+:}$LD_PRELOAD";
+ };
+
+ programs.git.package = lib.mkForce pkgs.emptyDirectory;
+}
diff --git a/machines/aramis/boot.nix b/hosts/nixos/aramis/boot.nix
similarity index 100%
rename from machines/aramis/boot.nix
rename to hosts/nixos/aramis/boot.nix
diff --git a/machines/aramis/default.nix b/hosts/nixos/aramis/default.nix
similarity index 89%
rename from machines/aramis/default.nix
rename to hosts/nixos/aramis/default.nix
index e2211f4..c72fb11 100644
--- a/machines/aramis/default.nix
+++ b/hosts/nixos/aramis/default.nix
@@ -12,15 +12,13 @@
./networking.nix
./profiles.nix
./programs.nix
+ ./secrets
./services.nix
./sound.nix
];
# Set your time zone.
- time.timeZone = "Europe/Paris";
-
- # Enable CUPS to print documents.
- services.printing.enable = true;
+ time.timeZone = "Europe/London";
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
diff --git a/machines/aramis/hardware.nix b/hosts/nixos/aramis/hardware.nix
similarity index 79%
rename from machines/aramis/hardware.nix
rename to hosts/nixos/aramis/hardware.nix
index 3ca556c..c66b426 100644
--- a/machines/aramis/hardware.nix
+++ b/hosts/nixos/aramis/hardware.nix
@@ -22,13 +22,19 @@
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
- hardware = {
- cpu.intel.updateMicrocode = true;
+ my.hardware = {
+ firmware = {
+ cpuFlavor = "intel";
+ };
+ };
+ hardware = {
trackpoint = {
enable = true;
emulateWheel = true; # Holding middle buttons allows scrolling
+
+ device = "TPPS/2 Elan TrackPoint"; # Use the correct device name
};
};
}
diff --git a/machines/aramis/home.nix b/hosts/nixos/aramis/home.nix
similarity index 78%
rename from machines/aramis/home.nix
rename to hosts/nixos/aramis/home.nix
index 1c816a7..66a0892 100644
--- a/machines/aramis/home.nix
+++ b/hosts/nixos/aramis/home.nix
@@ -1,6 +1,10 @@
{ pkgs, ... }:
{
my.home = {
+ # Use graphical pinentry
+ bitwarden.pinentry = "gtk2";
+ # Ebook library
+ calibre.enable = true;
# Some amount of social life
discord.enable = true;
# Image viewver
@@ -13,18 +17,17 @@
gpg.pinentry = "gtk2";
# Machine specific packages
packages.additionalPackages = with pkgs; [
+ element-desktop # Matrix client
jellyfin-media-player # Wraps the webui and mpv together
pavucontrol # Audio mixer GUI
- quasselClient # IRC client
- teams # Work requires it...
transgui # Transmission remote
];
# Minimal video player
mpv.enable = true;
# Network-Manager applet
nm-applet.enable = true;
- # Termite terminal
- terminal.program = "termite";
+ # Terminal
+ terminal.program = "alacritty";
# Zathura document viewer
zathura.enable = true;
};
diff --git a/machines/aramis/install.sh b/hosts/nixos/aramis/install.sh
similarity index 100%
rename from machines/aramis/install.sh
rename to hosts/nixos/aramis/install.sh
diff --git a/machines/aramis/networking.nix b/hosts/nixos/aramis/networking.nix
similarity index 84%
rename from machines/aramis/networking.nix
rename to hosts/nixos/aramis/networking.nix
index 2759e9c..fbf4c6b 100644
--- a/machines/aramis/networking.nix
+++ b/hosts/nixos/aramis/networking.nix
@@ -7,11 +7,6 @@
# Per-interface useDHCP will be mandatory in the future, so this generated config
# replicates the default behaviour.
useDHCP = false;
-
- interfaces = {
- enp0s31f6.useDHCP = true;
- wlp0s20f3.useDHCP = true;
- };
};
my.hardware.networking = {
diff --git a/machines/aramis/profiles.nix b/hosts/nixos/aramis/profiles.nix
similarity index 81%
rename from machines/aramis/profiles.nix
rename to hosts/nixos/aramis/profiles.nix
index 4d2ac7d..d86da5a 100644
--- a/machines/aramis/profiles.nix
+++ b/hosts/nixos/aramis/profiles.nix
@@ -9,6 +9,8 @@
gtk.enable = true;
# Laptop specific configuration
laptop.enable = true;
+ # Printers are hell, but so is the unability to print
+ printing.enable = true;
# i3 configuration
wm.windowManager = "i3";
# X configuration
diff --git a/machines/aramis/programs.nix b/hosts/nixos/aramis/programs.nix
similarity index 100%
rename from machines/aramis/programs.nix
rename to hosts/nixos/aramis/programs.nix
diff --git a/hosts/nixos/aramis/secrets/default.nix b/hosts/nixos/aramis/secrets/default.nix
new file mode 100644
index 0000000..c6f02dc
--- /dev/null
+++ b/hosts/nixos/aramis/secrets/default.nix
@@ -0,0 +1,25 @@
+{ config, lib, ... }:
+
+{
+ config.age = {
+ secrets =
+ let
+ toName = lib.removeSuffix ".age";
+ userExists = u: builtins.hasAttr u config.users.users;
+ # Only set the user if it exists, to avoid warnings
+ userIfExists = u: if userExists u then u else "root";
+ toSecret = name: { owner ? "root", ... }: {
+ file = ./. + "/${name}";
+ owner = lib.mkDefault (userIfExists owner);
+ };
+ convertSecrets = n: v: lib.nameValuePair (toName n) (toSecret n v);
+ secrets = import ./secrets.nix;
+ in
+ lib.mapAttrs' convertSecrets secrets;
+
+ identityPaths = [
+ # Due to being a laptop, this host does not itself have any SSH keys
+ "/home/ambroisie/.ssh/agenix"
+ ];
+ };
+}
diff --git a/hosts/nixos/aramis/secrets/secrets.nix b/hosts/nixos/aramis/secrets/secrets.nix
new file mode 100644
index 0000000..ce159a5
--- /dev/null
+++ b/hosts/nixos/aramis/secrets/secrets.nix
@@ -0,0 +1,13 @@
+# Host-specific secrets
+let
+ keys = import ../../../../keys;
+
+ all = [
+ # This host is a laptop, it does not have a host key
+ # Allow me to modify the secrets anywhere
+ keys.users.ambroisie
+ ];
+in
+{
+ "wireguard/private-key.age".publicKeys = all;
+}
diff --git a/modules/secrets/wireguard/aramis/private-key.age b/hosts/nixos/aramis/secrets/wireguard/private-key.age
similarity index 100%
rename from modules/secrets/wireguard/aramis/private-key.age
rename to hosts/nixos/aramis/secrets/wireguard/private-key.age
diff --git a/machines/aramis/services.nix b/hosts/nixos/aramis/services.nix
similarity index 100%
rename from machines/aramis/services.nix
rename to hosts/nixos/aramis/services.nix
diff --git a/machines/aramis/sound.nix b/hosts/nixos/aramis/sound.nix
similarity index 100%
rename from machines/aramis/sound.nix
rename to hosts/nixos/aramis/sound.nix
diff --git a/machines/porthos/boot.nix b/hosts/nixos/porthos/boot.nix
similarity index 84%
rename from machines/porthos/boot.nix
rename to hosts/nixos/porthos/boot.nix
index 3b56eb9..fbc5db7 100644
--- a/machines/porthos/boot.nix
+++ b/hosts/nixos/porthos/boot.nix
@@ -6,9 +6,8 @@
# Use the GRUB 2 boot loader.
loader.grub = {
enable = true;
- version = 2;
# Define on which hard drive you want to install Grub.
- device = "/dev/sda";
+ device = "/dev/disk/by-id/ata-HGST_HUS724020ALA640_PN2181P6J58M1P";
};
initrd = {
diff --git a/machines/porthos/default.nix b/hosts/nixos/porthos/default.nix
similarity index 96%
rename from machines/porthos/default.nix
rename to hosts/nixos/porthos/default.nix
index abfc01a..326d1cd 100644
--- a/machines/porthos/default.nix
+++ b/hosts/nixos/porthos/default.nix
@@ -5,7 +5,9 @@
imports = [
./boot.nix
./hardware.nix
+ ./home.nix
./networking.nix
+ ./secrets
./services.nix
./users.nix
];
diff --git a/machines/porthos/hardware.nix b/hosts/nixos/porthos/hardware.nix
similarity index 100%
rename from machines/porthos/hardware.nix
rename to hosts/nixos/porthos/hardware.nix
diff --git a/hosts/nixos/porthos/home.nix b/hosts/nixos/porthos/home.nix
new file mode 100644
index 0000000..53d5d25
--- /dev/null
+++ b/hosts/nixos/porthos/home.nix
@@ -0,0 +1,7 @@
+{ ... }:
+{
+ my.home = {
+ # Always start a tmux session when opening a shell session
+ zsh.launchTmux = true;
+ };
+}
diff --git a/machines/porthos/install.sh b/hosts/nixos/porthos/install.sh
similarity index 95%
rename from machines/porthos/install.sh
rename to hosts/nixos/porthos/install.sh
index 44ea787..de87aa7 100644
--- a/machines/porthos/install.sh
+++ b/hosts/nixos/porthos/install.sh
@@ -46,7 +46,7 @@ vim /mnt/etc/nixos/hardware-configuration.nix
mkdir -p /mnt/home/ambroisie/git/nix/config
cd /mnt/home/ambroisie/git/nix/config
-nix-env -iA nixos.git nixos.nixFlakes nixos.git-crypt
+nix-env -iA nixos.git nixos.nix nixos.git-crypt
git clone .
# Assuming you set up GPG key correctly
git crypt unlock
diff --git a/machines/porthos/networking.nix b/hosts/nixos/porthos/networking.nix
similarity index 100%
rename from machines/porthos/networking.nix
rename to hosts/nixos/porthos/networking.nix
diff --git a/modules/secrets/acme/dns-key.age b/hosts/nixos/porthos/secrets/acme/dns-key.age
similarity index 100%
rename from modules/secrets/acme/dns-key.age
rename to hosts/nixos/porthos/secrets/acme/dns-key.age
diff --git a/modules/secrets/backup/credentials.age b/hosts/nixos/porthos/secrets/backup/credentials.age
similarity index 100%
rename from modules/secrets/backup/credentials.age
rename to hosts/nixos/porthos/secrets/backup/credentials.age
diff --git a/modules/secrets/backup/password.age b/hosts/nixos/porthos/secrets/backup/password.age
similarity index 100%
rename from modules/secrets/backup/password.age
rename to hosts/nixos/porthos/secrets/backup/password.age
diff --git a/hosts/nixos/porthos/secrets/default.nix b/hosts/nixos/porthos/secrets/default.nix
new file mode 100644
index 0000000..83af695
--- /dev/null
+++ b/hosts/nixos/porthos/secrets/default.nix
@@ -0,0 +1,20 @@
+{ config, lib, ... }:
+
+{
+ config.age = {
+ secrets =
+ let
+ toName = lib.removeSuffix ".age";
+ userExists = u: builtins.hasAttr u config.users.users;
+ # Only set the user if it exists, to avoid warnings
+ userIfExists = u: if userExists u then u else "root";
+ toSecret = name: { owner ? "root", ... }: {
+ file = ./. + "/${name}";
+ owner = lib.mkDefault (userIfExists owner);
+ };
+ convertSecrets = n: v: lib.nameValuePair (toName n) (toSecret n v);
+ secrets = import ./secrets.nix;
+ in
+ lib.mapAttrs' convertSecrets secrets;
+ };
+}
diff --git a/hosts/nixos/porthos/secrets/drone/gitea.age b/hosts/nixos/porthos/secrets/drone/gitea.age
new file mode 100644
index 0000000..90ff83b
--- /dev/null
+++ b/hosts/nixos/porthos/secrets/drone/gitea.age
@@ -0,0 +1,10 @@
+age-encryption.org/v1
+-> ssh-ed25519 jPowng 3HjtINU02yfyvpaoTtCG/G3cgymFvKWf3qf/grw/+24
+G+KnHtrt5A3U1ICTpSceoE+FJSj6hAb4mjp2DkfDWr0
+-> ssh-ed25519 cKojmg CXrsCxJxWNIhvvwYjZ1rrSYTwLNMR3kWdPk5ExHEfFA
+OJi3tFcnpdGvxc8ETcGt4lbFJiUU+lR3AqN4Y8PItDk
+-> p-grease 7 AQO{DHzj j$B&+ dc
+Q7zhy6hOfkEh6XgYNHQrH3zma1BLxnEKDopPAOnBoPFRfi7c
+--- ZsL5zf7/jJ6yPor9j1V0iV/bXxgAsxlXsxDYwCqrLSk
+AO&z?;\1f*='!.VV=ιvzY"P ;)K0Bs}hR=O*M2o
\ No newline at end of file
diff --git a/modules/secrets/drone/secret.age b/hosts/nixos/porthos/secrets/drone/secret.age
similarity index 100%
rename from modules/secrets/drone/secret.age
rename to hosts/nixos/porthos/secrets/drone/secret.age
diff --git a/modules/secrets/drone/ssh/private-key.age b/hosts/nixos/porthos/secrets/drone/ssh/private-key.age
similarity index 100%
rename from modules/secrets/drone/ssh/private-key.age
rename to hosts/nixos/porthos/secrets/drone/ssh/private-key.age
diff --git a/hosts/nixos/porthos/secrets/gitea/mail-password.age b/hosts/nixos/porthos/secrets/gitea/mail-password.age
new file mode 100644
index 0000000..915f8e9
--- /dev/null
+++ b/hosts/nixos/porthos/secrets/gitea/mail-password.age
@@ -0,0 +1,9 @@
+age-encryption.org/v1
+-> ssh-ed25519 jPowng BkIjie2KrwDLaZYYIguCs7TPA/wQy+YPguikuhfye0M
+7viTA/EGYB/jRKQm6fFd86DMd4j+Jxsaw/xQ1T8ZKNo
+-> ssh-ed25519 cKojmg t1Y8bZvPccNAX8vWQLTfCyOJIBXN515vyfFrEI2EVww
+bJEjpIWrKeQrA/JfY7FRdB6hpHwR/aG4Vya1ChFNBKs
+-> jK/-grease Oz.R ?;)G ],
+AuHk9TcC9kl0dg8/L6UfHIk3e9fgGwSTJAJpVgInhok
+--- 47z9lol5MtpX0IsO/0ggLDMcNVfl4lNNvoHUSwOU/18
+)gЪeu!-
TYAM+GbMe@|A,&E!܆p=P=9P!Q|r
\ No newline at end of file
diff --git a/modules/secrets/lohr/secret.age b/hosts/nixos/porthos/secrets/lohr/secret.age
similarity index 100%
rename from modules/secrets/lohr/secret.age
rename to hosts/nixos/porthos/secrets/lohr/secret.age
diff --git a/modules/secrets/lohr/ssh-key.age b/hosts/nixos/porthos/secrets/lohr/ssh-key.age
similarity index 100%
rename from modules/secrets/lohr/ssh-key.age
rename to hosts/nixos/porthos/secrets/lohr/ssh-key.age
diff --git a/modules/secrets/matrix/mail.age b/hosts/nixos/porthos/secrets/matrix/mail.age
similarity index 100%
rename from modules/secrets/matrix/mail.age
rename to hosts/nixos/porthos/secrets/matrix/mail.age
diff --git a/hosts/nixos/porthos/secrets/matrix/secret.age b/hosts/nixos/porthos/secrets/matrix/secret.age
new file mode 100644
index 0000000..539c33e
Binary files /dev/null and b/hosts/nixos/porthos/secrets/matrix/secret.age differ
diff --git a/modules/secrets/miniflux/credentials.age b/hosts/nixos/porthos/secrets/miniflux/credentials.age
similarity index 100%
rename from modules/secrets/miniflux/credentials.age
rename to hosts/nixos/porthos/secrets/miniflux/credentials.age
diff --git a/modules/secrets/monitoring/password.age b/hosts/nixos/porthos/secrets/monitoring/password.age
similarity index 100%
rename from modules/secrets/monitoring/password.age
rename to hosts/nixos/porthos/secrets/monitoring/password.age
diff --git a/hosts/nixos/porthos/secrets/monitoring/secret-key.age b/hosts/nixos/porthos/secrets/monitoring/secret-key.age
new file mode 100644
index 0000000..4cef94f
Binary files /dev/null and b/hosts/nixos/porthos/secrets/monitoring/secret-key.age differ
diff --git a/modules/secrets/nextcloud/password.age b/hosts/nixos/porthos/secrets/nextcloud/password.age
similarity index 100%
rename from modules/secrets/nextcloud/password.age
rename to hosts/nixos/porthos/secrets/nextcloud/password.age
diff --git a/hosts/nixos/porthos/secrets/nix-serve/cache-key.age b/hosts/nixos/porthos/secrets/nix-serve/cache-key.age
new file mode 100644
index 0000000..e0fb5be
Binary files /dev/null and b/hosts/nixos/porthos/secrets/nix-serve/cache-key.age differ
diff --git a/modules/secrets/paperless/password.age b/hosts/nixos/porthos/secrets/paperless/password.age
similarity index 100%
rename from modules/secrets/paperless/password.age
rename to hosts/nixos/porthos/secrets/paperless/password.age
diff --git a/modules/secrets/paperless/secret-key.age b/hosts/nixos/porthos/secrets/paperless/secret-key.age
similarity index 100%
rename from modules/secrets/paperless/secret-key.age
rename to hosts/nixos/porthos/secrets/paperless/secret-key.age
diff --git a/modules/secrets/podgrab/password.age b/hosts/nixos/porthos/secrets/podgrab/password.age
similarity index 100%
rename from modules/secrets/podgrab/password.age
rename to hosts/nixos/porthos/secrets/podgrab/password.age
diff --git a/hosts/nixos/porthos/secrets/secrets.nix b/hosts/nixos/porthos/secrets/secrets.nix
new file mode 100644
index 0000000..498aebf
--- /dev/null
+++ b/hosts/nixos/porthos/secrets/secrets.nix
@@ -0,0 +1,77 @@
+# Host-specific secrets
+let
+ keys = import ../../../../keys;
+
+ all = [
+ # Host key
+ keys.hosts.porthos
+ # Allow me to modify the secrets anywhere
+ keys.users.ambroisie
+ ];
+in
+{
+ "acme/dns-key.age".publicKeys = all;
+
+ "backup/password.age".publicKeys = all;
+ "backup/credentials.age".publicKeys = all;
+
+ "drone/gitea.age".publicKeys = all;
+ "drone/secret.age".publicKeys = all;
+ "drone/ssh/private-key.age".publicKeys = all;
+
+ "gitea/mail-password.age" = {
+ owner = "git";
+ publicKeys = all;
+ };
+
+ "lohr/secret.age".publicKeys = all;
+ "lohr/ssh-key.age".publicKeys = all;
+
+ "matrix/mail.age" = {
+ owner = "matrix-synapse";
+ publicKeys = all;
+ };
+ "matrix/secret.age" = {
+ owner = "matrix-synapse";
+ publicKeys = all;
+ };
+
+ "miniflux/credentials.age".publicKeys = all;
+
+ "monitoring/password.age" = {
+ owner = "grafana";
+ publicKeys = all;
+ };
+ "monitoring/secret-key.age" = {
+ owner = "grafana";
+ publicKeys = all;
+ };
+
+ "nextcloud/password.age" = {
+ owner = "nextcloud";
+ publicKeys = all;
+ };
+
+ "nix-serve/cache-key.age".publicKeys = all;
+
+ "paperless/password.age".publicKeys = all;
+ "paperless/secret-key.age".publicKeys = all;
+
+ "podgrab/password.age".publicKeys = all;
+
+ "sso/auth-key.age".publicKeys = all;
+ "sso/ambroisie/password-hash.age".publicKeys = all;
+ "sso/ambroisie/totp-secret.age".publicKeys = all;
+
+ "tandoor-recipes/secret-key.age".publicKeys = all;
+
+ "transmission/credentials.age".publicKeys = all;
+
+ "vikunja/mail.age".publicKeys = all;
+
+ "wireguard/private-key.age".publicKeys = all;
+
+ "woodpecker/gitea.age".publicKeys = all;
+ "woodpecker/secret.age".publicKeys = all;
+ "woodpecker/ssh/private-key.age".publicKeys = all;
+}
diff --git a/modules/secrets/sso/ambroisie/password-hash.age b/hosts/nixos/porthos/secrets/sso/ambroisie/password-hash.age
similarity index 100%
rename from modules/secrets/sso/ambroisie/password-hash.age
rename to hosts/nixos/porthos/secrets/sso/ambroisie/password-hash.age
diff --git a/modules/secrets/sso/ambroisie/totp-secret.age b/hosts/nixos/porthos/secrets/sso/ambroisie/totp-secret.age
similarity index 100%
rename from modules/secrets/sso/ambroisie/totp-secret.age
rename to hosts/nixos/porthos/secrets/sso/ambroisie/totp-secret.age
diff --git a/modules/secrets/sso/auth-key.age b/hosts/nixos/porthos/secrets/sso/auth-key.age
similarity index 100%
rename from modules/secrets/sso/auth-key.age
rename to hosts/nixos/porthos/secrets/sso/auth-key.age
diff --git a/modules/secrets/sso/default.nix b/hosts/nixos/porthos/secrets/sso/default.nix
similarity index 100%
rename from modules/secrets/sso/default.nix
rename to hosts/nixos/porthos/secrets/sso/default.nix
diff --git a/hosts/nixos/porthos/secrets/tandoor-recipes/secret-key.age b/hosts/nixos/porthos/secrets/tandoor-recipes/secret-key.age
new file mode 100644
index 0000000..2ec147d
Binary files /dev/null and b/hosts/nixos/porthos/secrets/tandoor-recipes/secret-key.age differ
diff --git a/modules/secrets/transmission/credentials.age b/hosts/nixos/porthos/secrets/transmission/credentials.age
similarity index 100%
rename from modules/secrets/transmission/credentials.age
rename to hosts/nixos/porthos/secrets/transmission/credentials.age
diff --git a/hosts/nixos/porthos/secrets/vikunja/mail.age b/hosts/nixos/porthos/secrets/vikunja/mail.age
new file mode 100644
index 0000000..4c83acd
Binary files /dev/null and b/hosts/nixos/porthos/secrets/vikunja/mail.age differ
diff --git a/modules/secrets/wireguard/porthos/private-key.age b/hosts/nixos/porthos/secrets/wireguard/private-key.age
similarity index 100%
rename from modules/secrets/wireguard/porthos/private-key.age
rename to hosts/nixos/porthos/secrets/wireguard/private-key.age
diff --git a/hosts/nixos/porthos/secrets/woodpecker/gitea.age b/hosts/nixos/porthos/secrets/woodpecker/gitea.age
new file mode 100644
index 0000000..e6ede6c
Binary files /dev/null and b/hosts/nixos/porthos/secrets/woodpecker/gitea.age differ
diff --git a/hosts/nixos/porthos/secrets/woodpecker/secret.age b/hosts/nixos/porthos/secrets/woodpecker/secret.age
new file mode 100644
index 0000000..63a4862
--- /dev/null
+++ b/hosts/nixos/porthos/secrets/woodpecker/secret.age
@@ -0,0 +1,10 @@
+age-encryption.org/v1
+-> ssh-ed25519 jPowng yz0I+AazPmamF7NOnwYNrPE/ArarU01jd2mVDJUPSTY
+6Y/YQ7gb8cAZf3zT9SKOorvfUnU7kYff+gHh8fG2mY8
+-> ssh-ed25519 cKojmg 0FZU9v8eHsVeE+EoX9Y4IgfIj/8+45waPaSnSDb961I
+L6SzJoh5xqai45scoVAa6v9zslBGFYNnZY044d470uQ
+-> I[G-grease p
+AMRQY1alSzHi/PLL80kcvnM1Z9YNfoUo9u5alWXYMyzrRsg+vXjMuBvAXg3fmnzr
+wdOowTYMRV+jEG8vzkcQTsv+f7JIyo4DvOOaPyGfWMl1
+--- ih3IAFPcN1JP3FP1vcRGnPrfk91yrnIX0m/Szkbcf7Q
+mWr_\)Ͱ]QxMs/݃ݪ6kYxMyJG)i2_'֜HF.g_e5#utՠ7jP'Tޥ8\IWUK1ں9
\ No newline at end of file
diff --git a/hosts/nixos/porthos/secrets/woodpecker/ssh/private-key.age b/hosts/nixos/porthos/secrets/woodpecker/ssh/private-key.age
new file mode 100644
index 0000000..0211701
Binary files /dev/null and b/hosts/nixos/porthos/secrets/woodpecker/ssh/private-key.age differ
diff --git a/machines/porthos/services.nix b/hosts/nixos/porthos/services.nix
similarity index 77%
rename from machines/porthos/services.nix
rename to hosts/nixos/porthos/services.nix
index 4f3f345..e4cae5e 100644
--- a/machines/porthos/services.nix
+++ b/hosts/nixos/porthos/services.nix
@@ -1,5 +1,5 @@
# Deployed services
-{ config, ... }:
+{ config, lib, ... }:
let
secrets = config.age.secrets;
in
@@ -34,12 +34,24 @@ in
secretFile = secrets."drone/gitea".path;
sharedSecretFile = secrets."drone/secret".path;
};
+ # Auto-ban spammy bots and incorrect logins
+ fail2ban = {
+ enable = true;
+ };
# Flood UI for transmission
flood = {
enable = true;
};
# Gitea forge
- gitea.enable = true;
+ gitea = {
+ enable = true;
+ mail = {
+ enable = true;
+ host = "smtp.migadu.com:465";
+ user = lib.my.mkMailAddress "gitea" "belanyi.fr";
+ passwordFile = secrets."gitea/mail-password".path;
+ };
+ };
# Meta-indexers
indexers = {
prowlarr.enable = true;
@@ -57,7 +69,7 @@ in
enable = true;
mailConfigFile = secrets."matrix/mail".path;
# Only necessary when doing the initial registration
- # secret = "change-me";
+ secretFile = secrets."matrix/secret".path;
};
miniflux = {
enable = true;
@@ -68,6 +80,7 @@ in
enable = true;
grafana = {
passwordFile = secrets."monitoring/password".path;
+ secretKeyFile = secrets."monitoring/secret-key".path;
};
};
# FLOSS music streaming server
@@ -80,6 +93,10 @@ in
enable = true;
passwordFile = secrets."nextcloud/password".path;
};
+ nix-serve = {
+ enable = true;
+ secretKeyFile = secrets."nix-serve/cache-key".path;
+ };
nginx = {
enable = true;
acme = {
@@ -114,14 +131,17 @@ in
};
# Regular backups
postgresql-backup.enable = true;
- # An IRC client daemon
- quassel.enable = true;
# RSS provider for websites that do not provide any feeds
rss-bridge.enable = true;
# Usenet client
sabnzbd.enable = true;
# Because I stilll need to play sysadmin
ssh-server.enable = true;
+ # Recipe manager
+ tandoor-recipes = {
+ enable = true;
+ secretKeyFile = secrets."tandoor-recipes/secret-key".path;
+ };
# Torrent client and webui
transmission = {
enable = true;
@@ -132,5 +152,14 @@ in
enable = true;
startAtBoot = true; # Server must be started to ensure clients can connect
};
+ woodpecker = {
+ enable = true;
+ # Avoid clashes with drone
+ port = 3035;
+ rpcPort = 3036;
+ runners = [ "docker" "exec" ];
+ secretFile = secrets."woodpecker/gitea".path;
+ sharedSecretFile = secrets."woodpecker/secret".path;
+ };
};
}
diff --git a/machines/porthos/ssh/drone.pub b/hosts/nixos/porthos/ssh/drone.pub
similarity index 100%
rename from machines/porthos/ssh/drone.pub
rename to hosts/nixos/porthos/ssh/drone.pub
diff --git a/machines/porthos/users.nix b/hosts/nixos/porthos/users.nix
similarity index 100%
rename from machines/porthos/users.nix
rename to hosts/nixos/porthos/users.nix
diff --git a/keys/default.nix b/keys/default.nix
new file mode 100644
index 0000000..a538328
--- /dev/null
+++ b/keys/default.nix
@@ -0,0 +1,39 @@
+# Populate agenix keys from a central location
+let
+ inherit (builtins)
+ mapAttrs
+ readDir
+ readFile
+ stringLength
+ substring
+ ;
+
+ removeSuffix = suffix: str:
+ let
+ sufLen = stringLength suffix;
+ sLen = stringLength str;
+ in
+ if sufLen <= sLen && suffix == substring (sLen - sufLen) sufLen str then
+ substring 0 (sLen - sufLen) str
+ else
+ str;
+
+
+ readKeys = dir:
+ let
+ files = readDir dir;
+ readNoNewlines = f: removeSuffix "\n" (readFile f);
+ readKey = name: readNoNewlines (dir + "/${name}");
+ in
+ mapAttrs (n: _: readKey n) files;
+
+ hosts = readKeys ./hosts;
+ users = readKeys ./users;
+in
+{
+ inherit
+ hosts
+ users;
+
+ all = (builtins.attrValues hosts) ++ (builtins.attrValues users);
+}
diff --git a/keys/hosts/porthos b/keys/hosts/porthos
new file mode 100644
index 0000000..7156513
--- /dev/null
+++ b/keys/hosts/porthos
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICGzznQ3LSmBYHx6fXthgMDiTcU5i/Nvj020SbmhzAFb root@porthos
diff --git a/keys/users/ambroisie b/keys/users/ambroisie
new file mode 100644
index 0000000..cf08a3c
--- /dev/null
+++ b/keys/users/ambroisie
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMIVd6Oh08iUNb1vTULbxGpevnh++wxsWW9wqhaDryIq ambroisie@agenix
diff --git a/lib/attrs.nix b/lib/attrs.nix
index 75114b2..31686ac 100644
--- a/lib/attrs.nix
+++ b/lib/attrs.nix
@@ -26,6 +26,13 @@ in
# attrs
genAttrs' = values: f: listToAttrs (map f values);
+ # Merge a list of attrs non-recursively, later values override previous ones.
+ #
+ # merge ::
+ # [ attrs ]
+ # attrs
+ merge = foldl (a: b: a // b) { };
+
# Merge a list of attrs recursively, later values override previous ones.
#
# recursiveMerge ::
diff --git a/lib/default.nix b/lib/default.nix
index fa37c23..894e351 100644
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -15,6 +15,4 @@ let
mapModules ./. (file: import file { inherit self lib pkgs inputs; })
);
in
-mylib.extend (self: super:
- foldr (a: b: a // b) { } (attrValues super)
-)
+mylib.extend (_self: super: foldr (a: b: a // b) { } (attrValues super))
diff --git a/lib/ip.nix b/lib/ip.nix
index 2af3fef..fcafd72 100644
--- a/lib/ip.nix
+++ b/lib/ip.nix
@@ -100,7 +100,7 @@ rec {
# Pretty print a parsed subnet into a human readable form
prettySubnet4 = { baseIp, cidr, ... }: "${prettyIp4 baseIp}/${toString cidr}";
- # Get the nth address from an IPv4 range, without checking if it is in range
+ # Get the nth address from an IPv4 range
nthInRange4 = { from, to }: n:
let
carry = lhs: { carry, acc }:
@@ -112,8 +112,15 @@ rec {
acc = [ (mod totVal 256) ] ++ acc;
};
carried = foldr carry { carry = n; acc = [ ]; } from;
+ checkInRange =
+ if (to - from) < n
+ then
+ warn ''
+ nthInRange4: '${n}'-th address outside of range (${prettyIp4 from}, ${prettyIp4 to})
+ ''
+ else id;
in
- carried.acc;
+ checkInRange carried.acc;
# Convert an IPv4 range into a list of all its constituent addresses
rangeIp4 =
diff --git a/lib/strings.nix b/lib/strings.nix
index 2a3ec77..a1f74e4 100644
--- a/lib/strings.nix
+++ b/lib/strings.nix
@@ -1,6 +1,4 @@
{ ... }:
-let
-in
{
# Make an email address from the name and domain stems
#
diff --git a/modules/hardware/bluetooth/default.nix b/modules/hardware/bluetooth/default.nix
index ffe0fbe..2d840f9 100644
--- a/modules/hardware/bluetooth/default.nix
+++ b/modules/hardware/bluetooth/default.nix
@@ -25,41 +25,22 @@ in
package = pkgs.pulseaudioFull;
};
- services.pipewire = {
- media-session.config.bluez-monitor.rules = [
- {
- # Matches all cards
- matches = [{ "device.name" = "~bluez_card.*"; }];
- actions = {
- "update-props" = {
- "bluez5.reconnect-profiles" = [
- "hfp_hf"
- "hsp_hs"
- "a2dp_sink"
- ];
- # mSBC provides better audio + microphone
- "bluez5.msbc-support" = true;
- # SBC XQ provides better audio
- "bluez5.sbc-xq-support" = true;
- };
- };
+ environment.etc = {
+ "wireplumber/bluetooth.lua.d/51-bluez-config.lua".text = ''
+ 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 ]"
}
- {
- matches = [
- # Matches all sources
- {
- "node.name" = "~bluez_input.*";
- }
- # Matches all outputs
- {
- "node.name" = "~bluez_output.*";
- }
- ];
- actions = {
- "node.pause-on-idle" = false;
- };
- }
- ];
+ '';
};
})
diff --git a/modules/hardware/default.nix b/modules/hardware/default.nix
index 9ab5d40..2a686f7 100644
--- a/modules/hardware/default.nix
+++ b/modules/hardware/default.nix
@@ -5,6 +5,7 @@
imports = [
./bluetooth
./ergodox
+ ./firmware
./mx-ergo
./networking
./sound
diff --git a/modules/hardware/firmware/default.nix b/modules/hardware/firmware/default.nix
new file mode 100644
index 0000000..a77135c
--- /dev/null
+++ b/modules/hardware/firmware/default.nix
@@ -0,0 +1,38 @@
+{ config, lib, ... }:
+let
+ cfg = config.my.hardware.firmware;
+in
+{
+ options.my.hardware.firmware = with lib; {
+ enable = my.mkDisableOption "firmware configuration";
+
+ cpuFlavor = mkOption {
+ type = with types; nullOr (enum [ "intel" "amd" ]);
+ default = null;
+ example = "intel";
+ description = "Which kind of CPU to activate micro-code updates";
+ };
+ };
+
+ config = lib.mkIf cfg.enable (lib.mkMerge [
+ {
+ hardware = {
+ enableRedistributableFirmware = true;
+ };
+ }
+
+ # Intel CPU
+ (lib.mkIf (cfg.cpuFlavor == "intel") {
+ hardware = {
+ cpu.intel.updateMicrocode = true;
+ };
+ })
+
+ # AMD CPU
+ (lib.mkIf (cfg.cpuFlavor == "amd") {
+ hardware = {
+ cpu.amd.updateMicrocode = true;
+ };
+ })
+ ]);
+}
diff --git a/modules/home/default.nix b/modules/home/default.nix
index a287f35..1e0e0aa 100644
--- a/modules/home/default.nix
+++ b/modules/home/default.nix
@@ -7,7 +7,7 @@ let
in
{
imports = [
- inputs.home-manager.nixosModule # enable home-manager options
+ inputs.home-manager.nixosModules.home-manager # enable home-manager options
(lib.mkAliasOptionModule aliasPath actualPath) # simplify setting home options
];
diff --git a/modules/programs/steam/default.nix b/modules/programs/steam/default.nix
index dbdc0ce..0c7f9da 100644
--- a/modules/programs/steam/default.nix
+++ b/modules/programs/steam/default.nix
@@ -1,6 +1,8 @@
{ config, lib, pkgs, ... }:
let
cfg = config.my.programs.steam;
+
+ steam = pkgs.steam;
in
{
options.my.programs.steam = with lib; {
@@ -23,16 +25,14 @@ in
environment.systemPackages = builtins.map lib.hiPrio [
# Respect XDG conventions, leave my HOME alone
- (pkgs.writeScriptBin "steam" ''
- #!/bin/sh
+ (pkgs.writeShellScriptBin "steam" ''
mkdir -p "${cfg.dataDir}"
- HOME="${cfg.dataDir}" exec ${pkgs.steam}/bin/steam "$@"
+ HOME="${cfg.dataDir}" exec ${lib.getExe steam} "$@"
'')
# Same, for GOG and other such games
- (pkgs.writeScriptBin "steam-run" ''
- #!/bin/sh
+ (pkgs.writeShellScriptBin "steam-run" ''
mkdir -p "${cfg.dataDir}"
- HOME="${cfg.dataDir}" exec ${pkgs.steam-run-native}/bin/steam-run "$@"
+ HOME="${cfg.dataDir}" exec ${lib.getExe steam.run} "$@"
'')
];
};
diff --git a/modules/secrets/default.nix b/modules/secrets/default.nix
index e8cb866..c7d6f65 100644
--- a/modules/secrets/default.nix
+++ b/modules/secrets/default.nix
@@ -1,4 +1,4 @@
-{ config, inputs, lib, options, ... }:
+{ config, inputs, lib, ... }:
{
imports = [
@@ -20,10 +20,5 @@
secrets = import ./secrets.nix;
in
lib.mapAttrs' convertSecrets secrets;
-
- identityPaths = options.age.identityPaths.default ++ [
- # FIXME: hard-coded path, could be inexistent
- "/home/ambroisie/.ssh/id_ed25519"
- ];
};
}
diff --git a/modules/secrets/drone/gitea.age b/modules/secrets/drone/gitea.age
deleted file mode 100644
index d1c14e7..0000000
--- a/modules/secrets/drone/gitea.age
+++ /dev/null
@@ -1,10 +0,0 @@
-age-encryption.org/v1
--> ssh-ed25519 cKojmg vLLu1kbzyGxr5sU/Dl4xf0uGO+gVsvODiqEJU21lwyI
-LbJO4Go+8G7/UtFWjv+x7Nqhn7n+kge/oHP8dGCBnM8
--> ssh-ed25519 jPowng obxX4ojPwp/DaerFzVbK5hUnshebh/chriT3a7uqYEw
-x9jpbBefJZHz8o1lEkr48XhT7sVAM5tq3tZ8M91CDDo
--> eZ.G`B3W-grease 6k|.\v
-D0u3P4oCpPNnueqZAAYn71xEUGWlavwLTrEXJ+2tdYOX6BwwFReOlMZWIA+FikmZ
-8Pg7dHnbYPWc33jMjv3UnNsxCGUsDw9C9NkI5vfZSLvUxQ
---- Cea09ivsGZeoWif7xbdrvfoGsoiD+tRh7HQsOL75cqE
-tFa|G,o6$U"wi߹Swgh6^*=[g1%Vup-{`P(?&QV#KeX4dK:xt0LsbÆ6ޜ [ #E[>)|cwq+cw1$^I(wG9>jI(y!@OƉkEz]Pk
\ No newline at end of file
diff --git a/modules/secrets/matrix/secret.age b/modules/secrets/matrix/secret.age
deleted file mode 100644
index a287435..0000000
--- a/modules/secrets/matrix/secret.age
+++ /dev/null
@@ -1,9 +0,0 @@
-age-encryption.org/v1
--> ssh-ed25519 cKojmg ociW6AZww4nfW0Dw0DB0WNgQbJ3MNkHPPZlA0z+o/mI
-THAz89pjyrkxJB9tPQGgEwZrZX9OudWMnyzr0JiwzTA
--> ssh-ed25519 jPowng 1werbtuWK0DUFxq9mAWp/QzMHC1B8UfadutvK6+j9XE
-YmAwYo3X00gMB9AyQfOsR82CUPAtxfuzCzP4OyYFxjc
--> 8g-grease N9DR4 .U<
---- Cwh2hPrM2RzRroJRw3XrP1khcpL0leTXfJ+T7WG57To
-±jϰLDF xux1
-U/oGgo)*/d"L#RhWP
\ No newline at end of file
diff --git a/modules/secrets/secrets.nix b/modules/secrets/secrets.nix
index d8e289e..0e685d9 100644
--- a/modules/secrets/secrets.nix
+++ b/modules/secrets/secrets.nix
@@ -1,61 +1,10 @@
+# Common secrets
let
- # FIXME: read them from directories
- ambroisie = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMIVd6Oh08iUNb1vTULbxGpevnh++wxsWW9wqhaDryIq ambroisie@agenix";
- users = [ ambroisie ];
+ keys = import ../../keys;
- porthos = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICGzznQ3LSmBYHx6fXthgMDiTcU5i/Nvj020SbmhzAFb root@porthos";
- machines = [ porthos ];
-
- all = users ++ machines;
+ inherit (keys) all;
in
{
- "acme/dns-key.age".publicKeys = all;
-
- "backup/password.age".publicKeys = all;
- "backup/credentials.age".publicKeys = all;
-
- "drone/gitea.age".publicKeys = all;
- "drone/secret.age".publicKeys = all;
- "drone/ssh/private-key.age".publicKeys = all;
-
- "lohr/secret.age".publicKeys = all;
- "lohr/ssh-key.age".publicKeys = all;
-
- "matrix/mail.age" = {
- owner = "matrix-synapse";
- publicKeys = all;
- };
- "matrix/secret.age".publicKeys = all;
-
- "miniflux/credentials.age".publicKeys = all;
-
- "monitoring/password.age" = {
- owner = "grafana";
- publicKeys = all;
- };
-
- "nextcloud/password.age" = {
- # Must be readable by the service
- owner = "nextcloud";
- publicKeys = all;
- };
-
- "paperless/password.age".publicKeys = all;
- "paperless/secret-key.age".publicKeys = all;
-
- "podgrab/password.age".publicKeys = all;
-
- "sso/auth-key.age".publicKeys = all;
- "sso/ambroisie/password-hash.age".publicKeys = all;
- "sso/ambroisie/totp-secret.age".publicKeys = all;
-
- "transmission/credentials.age".publicKeys = all;
-
"users/ambroisie/hashed-password.age".publicKeys = all;
"users/root/hashed-password.age".publicKeys = all;
-
- "wireguard/aramis/private-key.age".publicKeys = all;
- "wireguard/milady/private-key.age".publicKeys = all;
- "wireguard/porthos/private-key.age".publicKeys = all;
- "wireguard/richelieu/private-key.age".publicKeys = all;
}
diff --git a/modules/secrets/wireguard/default.nix b/modules/secrets/wireguard/default.nix
deleted file mode 100644
index 1dbde9f..0000000
--- a/modules/secrets/wireguard/default.nix
+++ /dev/null
@@ -1,30 +0,0 @@
-{ lib, ... }:
-let
- peerSpec = {
- # "Server"
- porthos = {
- clientNum = 1;
- externalIp = "91.121.177.163";
- };
-
- # "Clients"
- aramis = {
- clientNum = 2;
- };
-
- richelieu = {
- clientNum = 3;
- };
- };
-
- makePeer = name: attrs: with lib; {
- inherit (attrs) clientNum;
- publicKey = fileContents (./. + "/${name}/public.key");
- privateKey = fileContents (./. + "/${name}/secret.key");
- } // optionalAttrs (attrs ? externalIp) {
- inherit (attrs) externalIp;
- };
-in
-{
- peers = builtins.mapAttrs makePeer peerSpec;
-}
diff --git a/modules/services/blog/default.nix b/modules/services/blog/default.nix
index 9149917..4b646c3 100644
--- a/modules/services/blog/default.nix
+++ b/modules/services/blog/default.nix
@@ -23,7 +23,20 @@ in
forceSSL = true;
useACMEHost = domain;
root = "/var/www/blog";
- default = true; # Redirect to my blog
+
+ # http://www.gnuterrypratchett.com/
+ extraConfig = ''
+ add_header X-Clacks-Overhead "GNU Terry Pratchett";
+ '';
+ };
+
+ # Dummy vhost to redirect all unknown (sub-)domains to my blog
+ "_" = {
+ forceSSL = true;
+ useACMEHost = domain;
+ default = true;
+
+ locations."/".return = "302 https://belanyi.fr$request_uri";
};
};
diff --git a/modules/services/calibre-web/default.nix b/modules/services/calibre-web/default.nix
index e6ba10d..858851c 100644
--- a/modules/services/calibre-web/default.nix
+++ b/modules/services/calibre-web/default.nix
@@ -53,5 +53,21 @@ in
cfg.libraryPath
];
};
+
+ services.fail2ban.jails = {
+ calibre-web = ''
+ enabled = true
+ filter = calibre-web
+ port = http,https
+ '';
+ };
+
+ environment.etc = {
+ "fail2ban/filter.d/calibre-web.conf".text = ''
+ [Definition]
+ failregex = ^.*Login failed for user ".*" IP-address: $
+ journalmatch = _SYSTEMD_UNIT=calibre-web.service
+ '';
+ };
};
}
diff --git a/modules/services/default.nix b/modules/services/default.nix
index 4ed40f0..86badf5 100644
--- a/modules/services/default.nix
+++ b/modules/services/default.nix
@@ -7,8 +7,10 @@
./blog
./calibre-web
./drone
+ ./fail2ban
./flood
./gitea
+ ./grocy
./indexers
./jellyfin
./lohr
@@ -18,17 +20,21 @@
./navidrome
./nextcloud
./nginx
+ ./nix-serve
./paperless
./pirate
./podgrab
- ./postgresql-backup
./postgresql
+ ./postgresql-backup
./quassel
./rss-bridge
./sabnzbd
./ssh-server
+ ./tandoor-recipes
./tlp
./transmission
+ ./vikunja
./wireguard
+ ./woodpecker
];
}
diff --git a/modules/services/drone/runner-docker/default.nix b/modules/services/drone/runner-docker/default.nix
index 0f2e3b3..e53c608 100644
--- a/modules/services/drone/runner-docker/default.nix
+++ b/modules/services/drone/runner-docker/default.nix
@@ -2,7 +2,6 @@
let
cfg = config.my.services.drone;
hasRunner = (name: builtins.elem name cfg.runners);
- dockerPkg = pkgs.drone-runner-docker;
in
{
config = lib.mkIf (cfg.enable && hasRunner "docker") {
@@ -25,14 +24,14 @@ in
EnvironmentFile = [
cfg.sharedSecretFile
];
- ExecStart = "${dockerPkg}/bin/drone-runner-docker";
+ ExecStart = lib.getExe pkgs.drone-runner-docker;
User = "drone-runner-docker";
Group = "drone-runner-docker";
};
};
# Make sure it is activated in that case
- virtualisation.docker.enable = true;
+ my.system.docker.enable = true;
users.users.drone-runner-docker = {
isSystemUser = true;
diff --git a/modules/services/drone/runner-exec/default.nix b/modules/services/drone/runner-exec/default.nix
index 6c776b4..a9bb563 100644
--- a/modules/services/drone/runner-exec/default.nix
+++ b/modules/services/drone/runner-exec/default.nix
@@ -2,7 +2,6 @@
let
cfg = config.my.services.drone;
hasRunner = (name: builtins.elem name cfg.runners);
- execPkg = pkgs.drone-runner-exec;
in
{
config = lib.mkIf (cfg.enable && hasRunner "exec") {
@@ -15,14 +14,14 @@ in
git
gnutar
bash
- nixUnstable
+ nix
gzip
];
path = with pkgs; [
git
gnutar
bash
- nixUnstable
+ nix
gzip
];
serviceConfig = {
@@ -53,7 +52,7 @@ in
EnvironmentFile = [
cfg.sharedSecretFile
];
- ExecStart = "${execPkg}/bin/drone-runner-exec";
+ ExecStart = lib.getExe pkgs.drone-runner-exec;
User = "drone-runner-exec";
Group = "drone-runner-exec";
};
diff --git a/modules/services/fail2ban/default.nix b/modules/services/fail2ban/default.nix
new file mode 100644
index 0000000..d62b9e2
--- /dev/null
+++ b/modules/services/fail2ban/default.nix
@@ -0,0 +1,37 @@
+# A minimalist, opinionated feed reader
+{ config, lib, ... }:
+let
+ cfg = config.my.services.fail2ban;
+ wgNetCfg = config.my.services.wireguard.net;
+in
+{
+ options.my.services.fail2ban = with lib; {
+ enable = mkEnableOption "fail2ban daemon";
+ };
+
+ config = lib.mkIf cfg.enable {
+ services.fail2ban = {
+ enable = true;
+
+ ignoreIP = [
+ # Wireguard IPs
+ "${wgNetCfg.v4.subnet}.0/${toString wgNetCfg.v4.mask}"
+ "${wgNetCfg.v6.subnet}::/${toString wgNetCfg.v6.mask}"
+ # Loopback addresses
+ "127.0.0.0/8"
+ ];
+
+ maxretry = 5;
+
+ bantime-increment = {
+ enable = true;
+ rndtime = "5m"; # Use 5 minute jitter to avoid unban evasion
+ };
+
+ jails.DEFAULT.settings = {
+ findtime = "4h";
+ bantime = "10m";
+ };
+ };
+ };
+}
diff --git a/modules/services/flood/default.nix b/modules/services/flood/default.nix
index ae8e219..ff5d941 100644
--- a/modules/services/flood/default.nix
+++ b/modules/services/flood/default.nix
@@ -30,7 +30,7 @@ in
serviceConfig = {
ExecStart = lib.concatStringsSep " " [
- "${pkgs.flood}/bin/flood"
+ (lib.getExe pkgs.flood)
"--port ${builtins.toString cfg.port}"
"--rundir /var/lib/${cfg.stateDir}"
];
diff --git a/modules/services/gitea/default.nix b/modules/services/gitea/default.nix
index 0ece12c..28a448d 100644
--- a/modules/services/gitea/default.nix
+++ b/modules/services/gitea/default.nix
@@ -12,29 +12,55 @@ in
example = 8080;
description = "Internal port";
};
+ mail = {
+ enable = mkEnableOption {
+ description = "mailer configuration";
+ };
+ host = mkOption {
+ type = types.str;
+ example = "smtp.example.com:465";
+ description = "Host for the mail account";
+ };
+ user = mkOption {
+ type = types.str;
+ example = "gitea@example.com";
+ description = "User for the mail account";
+ };
+ passwordFile = mkOption {
+ type = types.str;
+ example = "/run/secrets/gitea-mail-password.txt";
+ description = "Password for the mail account";
+ };
+ type = mkOption {
+ type = types.str;
+ default = "smtp";
+ example = "smtp";
+ description = "Password for the mail account";
+ };
+ tls = mkOption {
+ type = types.bool;
+ default = true;
+ example = false;
+ description = "Use TLS for connection";
+ };
+ };
};
config = lib.mkIf cfg.enable {
services.gitea =
let
- giteaDomain = "gitea.${config.networking.domain}";
+ inherit (config.networking) domain;
+ giteaDomain = "git.${domain}";
in
{
enable = true;
appName = "Ambroisie's forge";
- httpPort = cfg.port;
- domain = giteaDomain;
- rootUrl = "https://${giteaDomain}";
user = "git";
lfs.enable = true;
useWizard = false;
- disableRegistration = true;
-
- # only send cookies via HTTPS
- cookieSecure = true;
database = {
type = "postgres"; # Automatic setup
@@ -45,6 +71,34 @@ in
# but it produces a single .zip file that's not very backup friendly.
# I configure my backup system manually below.
dump.enable = false;
+
+ mailerPasswordFile = lib.mkIf cfg.mail.enable cfg.mail.passwordFile;
+
+ settings = {
+ server = {
+ HTTP_PORT = cfg.port;
+ DOMAIN = giteaDomain;
+ ROOT_URL = "https://${giteaDomain}";
+ };
+
+ mailer = lib.mkIf cfg.mail.enable {
+ ENABLED = true;
+ HOST = cfg.mail.host;
+ FROM = cfg.mail.user;
+ USER = cfg.mail.user;
+ MAILER_TYPE = cfg.mail.type;
+ IS_TLS_ENABLED = cfg.mail.tls;
+ };
+
+ service = {
+ DISABLE_REGISTRATION = true;
+ };
+
+ session = {
+ # only send cookies via HTTPS
+ COOKIE_SECURE = true;
+ };
+ };
};
users.users.git = {
@@ -61,11 +115,16 @@ in
};
users.groups.git = { };
- # Proxy to Gitea
my.services.nginx.virtualHosts = [
+ # Proxy to Gitea
+ {
+ subdomain = "git";
+ inherit (cfg) port;
+ }
+ # Redirect `gitea.` to actual forge subdomain
{
subdomain = "gitea";
- inherit (cfg) port;
+ redirect = config.services.gitea.settings.server.ROOT_URL;
}
];
@@ -75,5 +134,21 @@ in
config.services.gitea.repositoryRoot
];
};
+
+ services.fail2ban.jails = {
+ gitea = ''
+ enabled = true
+ filter = gitea
+ action = iptables-allports
+ '';
+ };
+
+ environment.etc = {
+ "fail2ban/filter.d/gitea.conf".text = ''
+ [Definition]
+ failregex = ^.*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from $
+ journalmatch = _SYSTEMD_UNIT=gitea.service
+ '';
+ };
};
}
diff --git a/modules/services/grocy/default.nix b/modules/services/grocy/default.nix
new file mode 100644
index 0000000..87927d6
--- /dev/null
+++ b/modules/services/grocy/default.nix
@@ -0,0 +1,40 @@
+# Groceries and household management
+{ config, lib, ... }:
+let
+ cfg = config.my.services.grocy;
+ grocyDomain = "grocy.${config.networking.domain}";
+in
+{
+ options.my.services.grocy = with lib; {
+ enable = mkEnableOption "Grocy household ERP";
+ };
+
+ config = lib.mkIf cfg.enable {
+ services.grocy = {
+ enable = true;
+
+ # The service sets up the reverse proxy automatically
+ hostName = grocyDomain;
+
+ # Configure SSL by hand
+ nginx = {
+ enableSSL = false;
+ };
+
+ settings = {
+ currency = "EUR";
+ culture = "en";
+ calendar = {
+ # Start on Monday
+ firstDayOfWeek = 1;
+ showWeekNumber = true;
+ };
+ };
+ };
+
+ services.nginx.virtualHosts."${grocyDomain}" = {
+ forceSSL = true;
+ useACMEHost = config.networking.domain;
+ };
+ };
+}
diff --git a/modules/services/lohr/default.nix b/modules/services/lohr/default.nix
index af218ac..245567c 100644
--- a/modules/services/lohr/default.nix
+++ b/modules/services/lohr/default.nix
@@ -4,8 +4,6 @@ let
cfg = config.my.services.lohr;
settingsFormat = pkgs.formats.yaml { };
- lohrPkg = pkgs.ambroisie.lohr;
-
lohrStateDirectory = "lohr";
lohrHome = "/var/lib/lohr/";
in
@@ -80,7 +78,7 @@ in
let
configFile = settingsFormat.generate "lohr-config.yaml" cfg.setting;
in
- "${lohrPkg}/bin/lohr --config ${configFile}";
+ "${lib.getExe pkgs.ambroisie.lohr} --config ${configFile}";
StateDirectory = lohrStateDirectory;
WorkingDirectory = lohrHome;
User = "lohr";
@@ -88,6 +86,7 @@ in
};
path = with pkgs; [
git
+ openssh
];
};
diff --git a/modules/services/matrix/default.nix b/modules/services/matrix/default.nix
index 6adcd00..c73afed 100644
--- a/modules/services/matrix/default.nix
+++ b/modules/services/matrix/default.nix
@@ -7,7 +7,6 @@
# [1]: https://github.com/alarsyo/nixos-config/blob/main/services/matrix.nix
{ config, lib, pkgs, ... }:
-with lib;
let
cfg = config.my.services.matrix;
@@ -56,7 +55,6 @@ in
public_baseurl = "https://matrix.${domain}";
enable_registration = false;
- # registration_shared_secret = cfg.secret; # FIXME: use a secret file for this
listeners = [
# Federation
@@ -150,7 +148,7 @@ in
};
# same as above, but listening on the federation port
- "matrix.${domain}_federation" = rec {
+ "matrix.${domain}_federation" = {
onlySSL = true;
serverName = "matrix.${domain}";
useACMEHost = domain;
@@ -165,7 +163,6 @@ in
{ addr = "0.0.0.0"; port = federationPort.public; ssl = true; }
{ addr = "[::]"; port = federationPort.public; ssl = true; }
];
-
};
"${domain}" = {
diff --git a/modules/services/monitoring/default.nix b/modules/services/monitoring/default.nix
index ba5adf3..829bfe0 100644
--- a/modules/services/monitoring/default.nix
+++ b/modules/services/monitoring/default.nix
@@ -27,6 +27,12 @@ in
example = "/var/lib/grafana/password.txt";
description = "Admin password stored in a file";
};
+
+ secretKeyFile = mkOption {
+ type = types.str;
+ example = "/var/lib/grafana/secret_key.txt";
+ description = "Secret key stored in a file";
+ };
};
prometheus = {
@@ -49,19 +55,26 @@ in
config = lib.mkIf cfg.enable {
services.grafana = {
enable = true;
- domain = "monitoring.${config.networking.domain}";
- port = cfg.grafana.port;
- addr = "127.0.0.1"; # Proxied through Nginx
- security = {
- adminUser = cfg.grafana.username;
- adminPasswordFile = cfg.grafana.passwordFile;
+ settings = {
+ server = {
+ domain = "monitoring.${config.networking.domain}";
+ root_url = "https://monitoring.${config.networking.domain}/";
+ http_port = cfg.grafana.port;
+ http_addr = "127.0.0.1"; # Proxied through Nginx
+ };
+
+ security = {
+ admin_user = cfg.grafana.username;
+ admin_password = "$__file{${cfg.grafana.passwordFile}}";
+ secret_key = "$__file{${cfg.grafana.secretKeyFile}}";
+ };
};
provision = {
enable = true;
- datasources = [
+ datasources.settings.datasources = [
{
name = "Prometheus";
type = "prometheus";
@@ -72,7 +85,7 @@ in
}
];
- dashboards = [
+ dashboards.settings.providers = [
{
name = "Node Exporter";
options.path = pkgs.nur.repos.alarsyo.grafanaDashboards.node-exporter;
diff --git a/modules/services/nextcloud/default.nix b/modules/services/nextcloud/default.nix
index 976d21f..1477c13 100644
--- a/modules/services/nextcloud/default.nix
+++ b/modules/services/nextcloud/default.nix
@@ -31,10 +31,12 @@ in
config = lib.mkIf cfg.enable {
services.nextcloud = {
enable = true;
- package = pkgs.nextcloud23;
+ package = pkgs.nextcloud27;
hostName = "nextcloud.${config.networking.domain}";
home = "/var/lib/nextcloud";
maxUploadSize = cfg.maxSize;
+ enableBrokenCiphersForSSE = false;
+ configureRedis = true;
config = {
adminuser = cfg.admin;
adminpassFile = cfg.passwordFile;
@@ -42,6 +44,12 @@ in
dbhost = "/run/postgresql";
overwriteProtocol = "https"; # Nginx only allows SSL
};
+
+ notify_push = {
+ enable = true;
+ # Allow using the push service without hard-coding my IP in the configuration
+ bendDomainToLocalhost = true;
+ };
};
services.postgresql = {
diff --git a/modules/services/nginx/default.nix b/modules/services/nginx/default.nix
index d99ff2d..dcaaa0f 100644
--- a/modules/services/nginx/default.nix
+++ b/modules/services/nginx/default.nix
@@ -3,6 +3,8 @@
let
cfg = config.my.services.nginx;
+ domain = config.networking.domain;
+
virtualHostOption = with lib; types.submodule {
options = {
subdomain = mkOption {
@@ -24,6 +26,15 @@ let
'';
};
+ redirect = mkOption {
+ type = with types; nullOr str;
+ default = null;
+ example = "https://example.com";
+ description = ''
+ Which domain to redirect to (301 response), for this virtual host.
+ '';
+ };
+
root = mkOption {
type = with types; nullOr path;
default = null;
@@ -34,6 +45,16 @@ let
'';
};
+ socket = mkOption {
+ type = with types; nullOr path;
+ default = null;
+ example = "FIXME";
+ description = ''
+ The UNIX socket for this virtual host. This option is incompatible
+ with `port`.
+ '';
+ };
+
sso = {
enable = mkEnableOption "SSO authentication";
};
@@ -174,7 +195,7 @@ in
assertions = [ ]
++ (lib.flip builtins.map cfg.virtualHosts ({ subdomain, ... } @ args:
let
- conflicts = [ "port" "root" ];
+ conflicts = [ "port" "root" "socket" "redirect" ];
optionsNotNull = builtins.map (v: args.${v} != null) conflicts;
optionsSet = lib.filter lib.id optionsNotNull;
in
@@ -222,10 +243,12 @@ in
enable = true;
statusPage = true; # For monitoring scraping.
+ recommendedBrotliSettings = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
- recommendedTlsSettings = true;
recommendedProxySettings = true;
+ recommendedTlsSettings = true;
+ recommendedZstdSettings = true;
virtualHosts =
let
@@ -247,6 +270,15 @@ in
(lib.optionalAttrs (args.root != null) {
inherit (args) root;
})
+ # Serve to UNIX socket
+ (lib.optionalAttrs (args.socket != null) {
+ locations."/".proxyPass =
+ "http://unix:${args.socket}";
+ })
+ # Redirect to a different domain
+ (lib.optionalAttrs (args.redirect != null) {
+ locations."/".return = "301 ${args.redirect}$request_uri";
+ })
# VHost specific configuration
args.extraConfig
# SSO configuration
@@ -392,10 +424,6 @@ in
acceptTerms = true;
# Use DNS wildcard certificate
certs =
- let
- domain = config.networking.domain;
- in
- with pkgs;
{
"${domain}" = {
extraDomainNames = [ "*.${domain}" ];
@@ -405,7 +433,16 @@ in
};
};
- services.grafana.provision.dashboards = lib.mkIf cfg.monitoring.enable [
+ systemd.services."acme-${domain}" = {
+ serviceConfig = {
+ Environment = [
+ # Since I do a "weird" setup with a wildcard CNAME
+ "LEGO_DISABLE_CNAME_SUPPORT=true"
+ ];
+ };
+ };
+
+ services.grafana.provision.dashboards.settings.providers = lib.mkIf cfg.monitoring.enable [
{
name = "NGINX";
options.path = pkgs.nur.repos.alarsyo.grafanaDashboards.nginx;
diff --git a/modules/services/nginx/sso/default.nix b/modules/services/nginx/sso/default.nix
index 13292ec..4a78282 100644
--- a/modules/services/nginx/sso/default.nix
+++ b/modules/services/nginx/sso/default.nix
@@ -59,8 +59,7 @@ in
StateDirectory = "nginx-sso";
WorkingDirectory = "/var/lib/nginx-sso";
# The files to be merged might not have the correct permissions
- ExecStartPre = ''+${pkgs.writeScript "merge-nginx-sso-config" ''
- #!${pkgs.bash}/bin/bash
+ ExecStartPre = ''+${pkgs.writeShellScript "merge-nginx-sso-config" ''
rm -f '${confPath}'
${utils.genJqSecretsReplacementSnippet cfg.configuration confPath}
@@ -70,7 +69,7 @@ in
''
}'';
ExecStart = lib.mkForce ''
- ${pkg}/bin/nginx-sso \
+ ${lib.getExe pkg} \
--config ${confPath} \
--frontend-dir ${pkg}/share/frontend
'';
diff --git a/modules/services/nix-serve/default.nix b/modules/services/nix-serve/default.nix
new file mode 100644
index 0000000..0cf1573
--- /dev/null
+++ b/modules/services/nix-serve/default.nix
@@ -0,0 +1,57 @@
+# Binary cache through nix-serve
+{ config, lib, pkgs, ... }:
+let
+ cfg = config.my.services.nix-serve;
+in
+{
+ options.my.services.nix-serve = with lib; {
+ enable = mkEnableOption "nix-serve binary cache";
+
+ port = mkOption {
+ type = types.port;
+ default = 5000;
+ example = 8080;
+ description = "Internal port for serving cache";
+ };
+
+ secretKeyFile = mkOption {
+ type = types.str;
+ example = "/run/secrets/nix-serve";
+ description = "Secret signing key for the cache";
+ };
+
+ priority = mkOption {
+ type = types.int;
+ default = 50;
+ example = 30;
+ description = ''
+ Which priority to assign to this cache. Lower number is higher priority.
+ The official nixpkgs hydra cache is priority 40.
+ '';
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
+ services.nix-serve = {
+ enable = true;
+
+ bindAddress = "127.0.0.1";
+
+ inherit (cfg)
+ port
+ secretKeyFile
+ ;
+
+ package = pkgs.nix-serve-ng;
+
+ extraParams = "--priority=${toString cfg.priority}";
+ };
+
+ my.services.nginx.virtualHosts = [
+ {
+ subdomain = "cache";
+ inherit (cfg) port;
+ }
+ ];
+ };
+}
diff --git a/modules/services/paperless/default.nix b/modules/services/paperless/default.nix
index e9ec6a3..c9d6220 100644
--- a/modules/services/paperless/default.nix
+++ b/modules/services/paperless/default.nix
@@ -45,7 +45,7 @@ in
};
config = lib.mkIf cfg.enable {
- services.paperless-ng = {
+ services.paperless = {
enable = true;
port = cfg.port;
@@ -83,16 +83,40 @@ in
};
systemd.services = {
- paperless-ng-server.serviceConfig = {
- EnvironmentFile = cfg.secretKeyFile;
+ paperless-scheduler = {
+ requires = [ "postgresql.service" ];
+ after = [ "postgresql.service" ];
+
+ serviceConfig = {
+ EnvironmentFile = cfg.secretKeyFile;
+ };
};
- paperless-ng-consumer.serviceConfig = {
- EnvironmentFile = cfg.secretKeyFile;
+ paperless-consumer = {
+ requires = [ "postgresql.service" ];
+ after = [ "postgresql.service" ];
+
+ serviceConfig = {
+ EnvironmentFile = cfg.secretKeyFile;
+ };
};
- paperless-ng-web.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;
+ };
};
};
@@ -111,13 +135,7 @@ in
# Set-up media group
users.groups.media = { };
- systemd.services.paperless-ng-server = {
- # Make sure the DB is available
- after = [ "postgresql.service" ];
- };
-
-
- users.users.${config.services.paperless-ng.user} = {
+ users.users.${config.services.paperless.user} = {
extraGroups = [ "media" ];
};
@@ -138,8 +156,8 @@ in
my.services.backup = {
paths = [
- config.services.paperless-ng.dataDir
- config.services.paperless-ng.mediaDir
+ config.services.paperless.dataDir
+ config.services.paperless.mediaDir
];
};
};
diff --git a/modules/services/sabnzbd/default.nix b/modules/services/sabnzbd/default.nix
index b9b99cf..7ab145f 100644
--- a/modules/services/sabnzbd/default.nix
+++ b/modules/services/sabnzbd/default.nix
@@ -24,5 +24,34 @@ in
inherit port;
}
];
+
+ services.fail2ban.jails = {
+ sabnzbd = ''
+ enabled = true
+ filter = sabnzbd
+ port = http,https
+ # Unfortunately, sabnzbd does not log to systemd journal
+ backend = auto
+ logpath = /var/lib/sabnzbd/logs/sabnzbd.log
+ '';
+ };
+
+ environment.etc = {
+ # FIXME: path to log file
+ "fail2ban/filter.d/sabnzbd.conf".text = ''
+ [Definition]
+ failregex = ^.*WARNING.*API Key incorrect, Use the api key from Config->General in your 3rd party program: .* \(X-Forwarded-For: \) .*$
+ ^.*WARNING.*API Key incorrect, Use the api key from Config->General in your 3rd party program: .*$
+ ^.*WARNING.*API Key missing, please enter the api key from Config->General into your 3rd party program: .* \(X-Forwarded-For: \) .*$
+ ^.*WARNING.*API Key missing, please enter the api key from Config->General into your 3rd party program: .*$
+ ^.*WARNING.*Refused connection from: .* \(X-Forwarded-For: \) .*$
+ ^.*WARNING.*Refused connection from: .*$
+ ^.*WARNING.*Refused connection with hostname ".*" from: .* \(X-Forwarded-For: \) .*$
+ ^.*WARNING.*Refused connection with hostname ".*" from: .*$
+ ^.*WARNING.*Unsuccessful login attempt from .* \(X-Forwarded-For: \) .*$
+ ^.*WARNING.*Unsuccessful login attempt from .*$
+ journalmatch = _SYSTEMD_UNIT=sabnzbd.service
+ '';
+ };
};
}
diff --git a/modules/services/ssh-server/default.nix b/modules/services/ssh-server/default.nix
index a41a673..9ae0fa8 100644
--- a/modules/services/ssh-server/default.nix
+++ b/modules/services/ssh-server/default.nix
@@ -12,9 +12,12 @@ in
services.openssh = {
# Enable the OpenSSH daemon.
enable = true;
- # Be more secure
- permitRootLogin = "no";
- passwordAuthentication = false;
+
+ settings = {
+ # Be more secure
+ PermitRootLogin = "no";
+ PasswordAuthentication = false;
+ };
};
# Opens the relevant UDP ports.
diff --git a/modules/services/tandoor-recipes/default.nix b/modules/services/tandoor-recipes/default.nix
new file mode 100644
index 0000000..d78bef3
--- /dev/null
+++ b/modules/services/tandoor-recipes/default.nix
@@ -0,0 +1,79 @@
+{ config, lib, ... }:
+let
+ cfg = config.my.services.tandoor-recipes;
+in
+{
+ options.my.services.tandoor-recipes = with lib; {
+ enable = mkEnableOption "Tandoor Recipes service";
+
+ port = mkOption {
+ type = types.port;
+ default = 4536;
+ example = 8080;
+ description = "Internal port for webui";
+ };
+
+ secretKeyFile = mkOption {
+ type = types.str;
+ example = "/var/lib/tandoor-recipes/secret-key.env";
+ description = ''
+ Secret key as an 'EnvironmentFile' (see `systemd.exec(5)`)
+ '';
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
+ services.tandoor-recipes = {
+ enable = true;
+
+ port = cfg.port;
+ extraConfig =
+ let
+ tandoorRecipesDomain = "recipes.${config.networking.domain}";
+ in
+ {
+ # Use PostgreSQL
+ DB_ENGINE = "django.db.backends.postgresql";
+ POSTGRES_HOST = "/run/postgresql";
+ POSTGRES_USER = "tandoor_recipes";
+ POSTGRES_DB = "tandoor_recipes";
+
+ # Security settings
+ ALLOWED_HOSTS = tandoorRecipesDomain;
+ CSRF_TRUSTED_ORIGINS = "https://${tandoorRecipesDomain}";
+
+ # Misc
+ TIMEZONE = config.time.timeZone;
+ };
+ };
+
+ systemd.services = {
+ tandoor-recipes = {
+ after = [ "postgresql.service" ];
+
+ serviceConfig = {
+ EnvironmentFile = cfg.secretKeyFile;
+ };
+ };
+ };
+
+ # Set-up database
+ services.postgresql = {
+ enable = true;
+ ensureDatabases = [ "tandoor_recipes" ];
+ ensureUsers = [
+ {
+ name = "tandoor_recipes";
+ ensurePermissions."DATABASE tandoor_recipes" = "ALL PRIVILEGES";
+ }
+ ];
+ };
+
+ my.services.nginx.virtualHosts = [
+ {
+ subdomain = "recipes";
+ inherit (cfg) port;
+ }
+ ];
+ };
+}
diff --git a/modules/services/transmission/default.nix b/modules/services/transmission/default.nix
index cac075f..dcba0aa 100644
--- a/modules/services/transmission/default.nix
+++ b/modules/services/transmission/default.nix
@@ -67,6 +67,13 @@ in
};
};
+ # Transmission wants to eat *all* my RAM if left to its own devices
+ systemd.services.transmission = {
+ serviceConfig = {
+ MemoryMax = "33%";
+ };
+ };
+
# Set-up media group
users.groups.media = { };
diff --git a/modules/services/vikunja/default.nix b/modules/services/vikunja/default.nix
new file mode 100644
index 0000000..1cdef5f
--- /dev/null
+++ b/modules/services/vikunja/default.nix
@@ -0,0 +1,123 @@
+# Todo and kanban app
+{ config, lib, ... }:
+let
+ cfg = config.my.services.vikunja;
+ subdomain = "todo";
+ vikunjaDomain = "${subdomain}.${config.networking.domain}";
+ socketPath = "/run/vikunja/vikunja.socket";
+in
+{
+ options.my.services.vikunja = with lib; {
+ enable = mkEnableOption "Vikunja todo app";
+
+ mail = {
+ enable = mkEnableOption {
+ description = "mailer configuration";
+ };
+
+ configFile = mkOption {
+ type = types.str;
+ example = "/run/secrets/vikunja-mail-config.env";
+ description = "Configuration for the mailer connection, using environment variables.";
+ };
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
+ services.vikunja = {
+ enable = true;
+
+ frontendScheme = "https";
+ frontendHostname = vikunjaDomain;
+
+ setupNginx = false;
+
+ database = {
+ type = "postgres";
+ user = "vikunja";
+ database = "vikunja";
+ host = "/run/postgresql";
+ };
+
+ settings = {
+ service = {
+ # Only allow registration of users through the CLI
+ enableregistration = false;
+ # Ues the host's timezone
+ timezone = config.time.timeZone;
+ # Use UNIX socket for serving the API
+ unixsocket = socketPath;
+ unixsocketmode = "0o660";
+ };
+
+ mailer = {
+ enabled = cfg.mail.enable;
+ };
+ };
+
+ environmentFiles = lib.optional cfg.mail.enable cfg.mail.configFile;
+ };
+
+ # This is a weird setup
+ my.services.nginx.virtualHosts = [
+ {
+ inherit subdomain;
+ # Serve the root for the web-ui
+ root = config.services.vikunja.package-frontend;
+
+ extraConfig = {
+ locations = {
+ "/" = {
+ tryFiles = "try_files $uri $uri/ /";
+ };
+
+ # Serve the API through a UNIX socket
+ "~* ^/(api|dav|\\.well-known)/" = {
+ proxyPass = "http://unix:${socketPath}";
+ extraConfig = ''
+ client_max_body_size 20M;
+ '';
+ };
+ };
+ };
+ }
+ ];
+
+ systemd.services.vikunja-api = {
+ serviceConfig = {
+ # Use a system user to simplify using the CLI
+ DynamicUser = lib.mkForce false;
+ # Set the user for postgres authentication
+ User = "vikunja";
+ # Create /run/vikunja/ to serve the UNIX socket
+ RuntimeDirectory = "vikunja";
+ };
+ };
+
+ users.users.vikunja = {
+ description = "Vikunja Service";
+ group = "vikunja";
+ isSystemUser = true;
+ };
+ users.groups.vikunja = { };
+
+ # Allow nginx to access the UNIX socket
+ users.users.nginx.extraGroups = [ "vikunja" ];
+
+ services.postgresql = {
+ ensureDatabases = [ "vikunja" ];
+ ensureUsers = [
+ {
+ name = "vikunja";
+ ensurePermissions = { "DATABASE vikunja" = "ALL PRIVILEGES"; };
+ }
+ ];
+ };
+
+ my.services.backup = {
+ paths = [
+ config.services.vikunja.settings.files.basepath
+ ];
+ };
+ };
+}
diff --git a/modules/services/wireguard/default.nix b/modules/services/wireguard/default.nix
index 656fdb2..fc5518d 100644
--- a/modules/services/wireguard/default.nix
+++ b/modules/services/wireguard/default.nix
@@ -8,40 +8,31 @@ let
secrets = config.age.secrets;
hostName = config.networking.hostName;
- peers =
- let
- mkPeer = name: attrs: {
- inherit (attrs) clientNum publicKey;
- privateKeyFile = secrets."wireguard/${name}/private-key".path;
- } // lib.optionalAttrs (attrs ? externalIp) {
- inherit (attrs) externalIp;
- };
- in
- lib.mapAttrs mkPeer {
- # "Server"
- porthos = {
- clientNum = 1;
- publicKey = "PLdgsizztddri0LYtjuNHr5r2E8D+yI+gM8cm5WDfHQ=";
- externalIp = "91.121.177.163";
- };
-
- # "Clients"
- aramis = {
- clientNum = 2;
- publicKey = "QJSWIBS1mXTpxYybLlKu/Y5wy0GFbUfn4yPzpF1DZDc=";
- };
-
- richelieu = {
- clientNum = 3;
- publicKey = "w4IADAj2Tt7Qe95a0RxDv9ovg/Dr/f3q1LrVOPF48Rk=";
- };
-
- # Sarah's iPhone
- milady = {
- clientNum = 4;
- publicKey = "3MKEu4F6o8kww54xeAao5Uet86fv8z/QsZ2L2mOzqDQ=";
- };
+ peers = {
+ # "Server"
+ porthos = {
+ clientNum = 1;
+ publicKey = "PLdgsizztddri0LYtjuNHr5r2E8D+yI+gM8cm5WDfHQ=";
+ externalIp = "91.121.177.163";
};
+
+ # "Clients"
+ aramis = {
+ clientNum = 2;
+ publicKey = "QJSWIBS1mXTpxYybLlKu/Y5wy0GFbUfn4yPzpF1DZDc=";
+ };
+
+ richelieu = {
+ clientNum = 3;
+ publicKey = "w4IADAj2Tt7Qe95a0RxDv9ovg/Dr/f3q1LrVOPF48Rk=";
+ };
+
+ # Sarah's iPhone
+ milady = {
+ clientNum = 4;
+ publicKey = "3MKEu4F6o8kww54xeAao5Uet86fv8z/QsZ2L2mOzqDQ=";
+ };
+ };
thisPeer = peers."${hostName}";
thisPeerIsServer = thisPeer ? externalIp;
# Only connect to clients from server, and only connect to server from clients
@@ -60,7 +51,7 @@ let
"${v4.subnet}.${toString thisPeer.clientNum}/${toString v4.mask}"
"${v6.subnet}::${toString thisPeer.clientNum}/${toHexString v6.mask}"
];
- inherit (thisPeer) privateKeyFile;
+ privateKeyFile = secrets."wireguard/private-key".path;
peers =
let
diff --git a/modules/secrets/wireguard/milady/private-key.age b/modules/services/wireguard/keys/milady/private-key.age
similarity index 100%
rename from modules/secrets/wireguard/milady/private-key.age
rename to modules/services/wireguard/keys/milady/private-key.age
diff --git a/modules/secrets/wireguard/richelieu/private-key.age b/modules/services/wireguard/keys/richelieu/private-key.age
similarity index 100%
rename from modules/secrets/wireguard/richelieu/private-key.age
rename to modules/services/wireguard/keys/richelieu/private-key.age
diff --git a/modules/services/wireguard/keys/secrets.nix b/modules/services/wireguard/keys/secrets.nix
new file mode 100644
index 0000000..3985477
--- /dev/null
+++ b/modules/services/wireguard/keys/secrets.nix
@@ -0,0 +1,15 @@
+# Extra wireguard keys that are not hosts NixOS hosts
+let
+ keys = import ../../../../keys;
+
+ all = [
+ keys.users.ambroisie
+ ];
+in
+{
+ # Sarah's iPhone
+ "milady/private-key.age".publicKeys = all;
+
+ # My Android phone
+ "richelieu/private-key.age".publicKeys = all;
+}
diff --git a/modules/services/woodpecker/agent-docker/default.nix b/modules/services/woodpecker/agent-docker/default.nix
new file mode 100644
index 0000000..b18d075
--- /dev/null
+++ b/modules/services/woodpecker/agent-docker/default.nix
@@ -0,0 +1,45 @@
+{ config, lib, ... }:
+let
+ cfg = config.my.services.woodpecker;
+
+ hasRunner = (name: builtins.elem name cfg.runners);
+in
+{
+ config = lib.mkIf (cfg.enable && hasRunner "docker") {
+ services.woodpecker-agents = {
+ agents.docker = {
+ enable = true;
+
+ environment = {
+ WOODPECKER_SERVER = "localhost:${toString cfg.rpcPort}";
+ WOODPECKER_MAX_WORKFLOWS = "10";
+ WOODPECKER_BACKEND = "docker";
+ WOODPECKER_FILTER_LABELS = "type=docker";
+ WOODPECKER_HEALTHCHECK = "false";
+ };
+
+ environmentFile = [ cfg.sharedSecretFile ];
+
+ extraGroups = [ "docker" ];
+ };
+ };
+
+ # Make sure it is activated in that case
+ my.system.docker.enable = true;
+
+ # FIXME: figure out the issue
+ services.unbound.resolveLocalQueries = false;
+
+ # Adjust runner service for nix usage
+ systemd.services.woodpecker-agent-docker = {
+ after = [ "docker.socket" ]; # Needs the socket to be available
+ # might break deployment
+ restartIfChanged = false;
+ serviceConfig = {
+ BindPaths = [
+ "/var/run/docker.sock"
+ ];
+ };
+ };
+ };
+}
diff --git a/modules/services/woodpecker/agent-exec/default.nix b/modules/services/woodpecker/agent-exec/default.nix
new file mode 100644
index 0000000..ad30188
--- /dev/null
+++ b/modules/services/woodpecker/agent-exec/default.nix
@@ -0,0 +1,64 @@
+{ config, lib, pkgs, ... }:
+let
+ cfg = config.my.services.woodpecker;
+
+ hasRunner = (name: builtins.elem name cfg.runners);
+in
+{
+ config = lib.mkIf (cfg.enable && hasRunner "exec") {
+ services.woodpecker-agents = {
+ agents.exec = {
+ enable = true;
+
+ environment = {
+ WOODPECKER_SERVER = "localhost:${toString cfg.rpcPort}";
+ WOODPECKER_MAX_WORKFLOWS = "10";
+ WOODPECKER_BACKEND = "local";
+ WOODPECKER_FILTER_LABELS = "type=exec";
+ WOODPECKER_HEALTHCHECK = "false";
+
+ NIX_REMOTE = "daemon";
+ PAGER = "cat";
+ };
+
+ environmentFile = [ cfg.sharedSecretFile ];
+ };
+ };
+
+ # Adjust runner service for nix usage
+ systemd.services.woodpecker-agent-exec = {
+ # Might break deployment
+ restartIfChanged = false;
+
+ path = with pkgs; [
+ woodpecker-plugin-git
+ bash
+ coreutils
+ git
+ git-lfs
+ gnutar
+ gzip
+ nix
+ ];
+
+ serviceConfig = {
+ # Same option as upstream, without @setuid
+ SystemCallFilter = lib.mkForce "~@clock @privileged @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap";
+
+ BindPaths = [
+ "/nix/var/nix/daemon-socket/socket"
+ "/run/nscd/socket"
+ ];
+ BindReadOnlyPaths = [
+ "/etc/passwd:/etc/passwd"
+ "/etc/group:/etc/group"
+ "/etc/nix:/etc/nix"
+ "${config.environment.etc."ssh/ssh_known_hosts".source}:/etc/ssh/ssh_known_hosts"
+ "/etc/machine-id"
+ # channels are dynamic paths in the nix store, therefore we need to bind mount the whole thing
+ "/nix/"
+ ];
+ };
+ };
+ };
+}
diff --git a/modules/services/woodpecker/default.nix b/modules/services/woodpecker/default.nix
new file mode 100644
index 0000000..34ffca6
--- /dev/null
+++ b/modules/services/woodpecker/default.nix
@@ -0,0 +1,46 @@
+{ lib, ... }:
+{
+ imports = [
+ ./agent-docker
+ ./agent-exec
+ ./server
+ ];
+
+ options.my.services.woodpecker = with lib; {
+ enable = mkEnableOption "Woodpecker CI";
+ runners = mkOption {
+ type = with types; listOf (enum [ "exec" "docker" ]);
+ default = [ ];
+ example = [ "exec" "docker" ];
+ description = "Types of runners to enable";
+ };
+ admin = mkOption {
+ type = types.str;
+ default = "ambroisie";
+ example = "admin";
+ description = "Name of the admin user";
+ };
+ port = mkOption {
+ type = types.port;
+ default = 3030;
+ example = 8080;
+ description = "Internal port of the Woodpecker UI";
+ };
+ rpcPort = mkOption {
+ type = types.port;
+ default = 3031;
+ example = 8080;
+ description = "Internal port of the Woodpecker UI";
+ };
+ secretFile = mkOption {
+ type = types.str;
+ example = "/run/secrets/woodpecker.env";
+ description = "Secrets to inject into Woodpecker server";
+ };
+ sharedSecretFile = mkOption {
+ type = types.str;
+ example = "/run/secrets/woodpecker.env";
+ description = "Shared RPC secret to inject into server and runners";
+ };
+ };
+}
diff --git a/modules/services/woodpecker/server/default.nix b/modules/services/woodpecker/server/default.nix
new file mode 100644
index 0000000..152e707
--- /dev/null
+++ b/modules/services/woodpecker/server/default.nix
@@ -0,0 +1,66 @@
+{ config, lib, ... }:
+let
+ cfg = config.my.services.woodpecker;
+in
+{
+ config = lib.mkIf cfg.enable {
+ services.woodpecker-server = {
+ enable = true;
+
+ environment = {
+ WOODPECKER_OPEN = "true";
+ WOODPECKER_HOST = "https://woodpecker.${config.networking.domain}";
+ WOODPECKER_DATABASE_DRIVER = "postgres";
+ WOODPECKER_DATABASE_DATASOURCE = "postgres:///woodpecker?host=/run/postgresql";
+ WOODPECKER_ADMIN = "${cfg.admin}";
+ WOODPECKER_SERVER_ADDR = ":${toString cfg.port}";
+ WOODPECKER_GRPC_ADDR = ":${toString cfg.rpcPort}";
+
+ WOODPECKER_GITEA = "true";
+ WOODPECKER_GITEA_URL = config.services.gitea.settings.server.ROOT_URL;
+
+ WOODPECKER_LOG_LEVEL = "debug";
+ };
+ };
+
+ systemd.services.woodpecker-server = {
+ serviceConfig = {
+ # Set username for DB access
+ User = "woodpecker";
+
+ BindPaths = [
+ # Allow access to DB path
+ "/run/postgresql"
+ ];
+
+ EnvironmentFile = [
+ cfg.secretFile
+ cfg.sharedSecretFile
+ ];
+ };
+ };
+
+ services.postgresql = {
+ enable = true;
+ ensureDatabases = [ "woodpecker" ];
+ ensureUsers = [{
+ name = "woodpecker";
+ ensurePermissions = {
+ "DATABASE woodpecker" = "ALL PRIVILEGES";
+ };
+ }];
+ };
+
+ my.services.nginx.virtualHosts = [
+ {
+ subdomain = "woodpecker";
+ inherit (cfg) port;
+ }
+ # I might want to be able to RPC from other hosts in the future
+ {
+ subdomain = "woodpecker-rpc";
+ port = cfg.rpcPort;
+ }
+ ];
+ };
+}
diff --git a/modules/system/boot/default.nix b/modules/system/boot/default.nix
index 0fed267..3d8495e 100644
--- a/modules/system/boot/default.nix
+++ b/modules/system/boot/default.nix
@@ -13,9 +13,11 @@ in
config = {
boot = {
- cleanTmpDir = cfg.tmp.clean;
+ tmp = {
+ cleanOnBoot = cfg.tmp.clean;
- tmpOnTmpfs = cfg.tmp.tmpfs;
+ useTmpfs = cfg.tmp.tmpfs;
+ };
};
};
}
diff --git a/modules/system/default.nix b/modules/system/default.nix
index 3c81cac..9fe3b57 100644
--- a/modules/system/default.nix
+++ b/modules/system/default.nix
@@ -4,6 +4,7 @@
{
imports = [
./boot
+ ./docker
./documentation
./language
./nix
diff --git a/modules/system/docker/default.nix b/modules/system/docker/default.nix
new file mode 100644
index 0000000..f051814
--- /dev/null
+++ b/modules/system/docker/default.nix
@@ -0,0 +1,27 @@
+# Podman related settings
+{ config, lib, ... }:
+let
+ cfg = config.my.system.docker;
+in
+{
+ options.my.system.docker = with lib; {
+ enable = mkEnableOption "docker configuration";
+ };
+
+ config = lib.mkIf cfg.enable {
+ virtualisation.docker = {
+ enable = true;
+
+ # Remove unused data on a weekly basis
+ autoPrune = {
+ enable = true;
+
+ dates = "weekly";
+
+ flags = [
+ "--all"
+ ];
+ };
+ };
+ };
+}
diff --git a/modules/system/documentation/default.nix b/modules/system/documentation/default.nix
index 74886ad..304c811 100644
--- a/modules/system/documentation/default.nix
+++ b/modules/system/documentation/default.nix
@@ -3,20 +3,20 @@ let
cfg = config.my.system.documentation;
in
{
- options.my.system.documentation = with lib.my; {
- enable = mkDisableOption "Documentation integration";
+ options.my.system.documentation = with lib; {
+ enable = my.mkDisableOption "Documentation integration";
- dev.enable = mkDisableOption "Documentation aimed at developers";
+ dev.enable = my.mkDisableOption "Documentation aimed at developers";
- info.enable = mkDisableOption "Documentation aimed at developers";
+ info.enable = my.mkDisableOption "Documentation aimed at developers";
man = {
- enable = mkDisableOption "Documentation aimed at developers";
+ enable = my.mkDisableOption "Documentation aimed at developers";
- linux = mkDisableOption "Linux man pages (section 2 & 3)";
+ linux = my.mkDisableOption "Linux man pages (section 2 & 3)";
};
- nixos.enable = mkDisableOption "NixOS documentation";
+ nixos.enable = my.mkDisableOption "NixOS documentation";
};
config = lib.mkIf cfg.enable {
diff --git a/modules/system/nix/default.nix b/modules/system/nix/default.nix
index 16db0b4..47d6499 100644
--- a/modules/system/nix/default.nix
+++ b/modules/system/nix/default.nix
@@ -2,20 +2,57 @@
{ config, inputs, lib, options, pkgs, ... }:
let
cfg = config.my.system.nix;
+
+ channels = lib.my.merge [
+ {
+ # Allow me to use my custom package using `nix run self#pkg`
+ self = inputs.self;
+ # Add NUR to run some packages that are only present there
+ nur = inputs.nur;
+ # Use pinned nixpkgs when using `nix run pkgs#`
+ pkgs = inputs.nixpkgs;
+ }
+ (lib.optionalAttrs cfg.inputs.overrideNixpkgs {
+ # ... And with `nix run nixpkgs#`
+ nixpkgs = inputs.nixpkgs;
+ })
+ ];
in
{
options.my.system.nix = with lib; {
enable = my.mkDisableOption "nix configuration";
- addToRegistry = my.mkDisableOption "add inputs and self to registry";
+ cache = {
+ selfHosted = my.mkDisableOption "self-hosted cache";
+ };
- addToNixPath = my.mkDisableOption "add inputs and self to nix path";
+ inputs = {
+ link = my.mkDisableOption "link inputs to `/etc/nix/inputs/`";
+
+ addToRegistry = my.mkDisableOption "add inputs and self to registry";
+
+ addToNixPath = my.mkDisableOption "add inputs and self to nix path";
+
+ overrideNixpkgs = my.mkDisableOption "point nixpkgs to pinned system version";
+ };
};
config = lib.mkIf cfg.enable (lib.mkMerge [
+ {
+ assertions = [
+ {
+ assertion = cfg.inputs.addToNixPath -> cfg.inputs.link;
+ message = ''
+ enabling `my.system.nix.inputs.addToNixPath` needs to have
+ `my.system.nix.inputs.link = true`
+ '';
+ }
+ ];
+ }
+
{
nix = {
- package = pkgs.nixFlakes;
+ package = pkgs.nix;
settings = {
experimental-features = [ "nix-command" "flakes" ];
@@ -23,23 +60,48 @@ in
};
}
- (lib.mkIf cfg.addToRegistry {
- nix.registry = {
- # Allow me to use my custom package using `nix run self#pkg`
- self.flake = inputs.self;
- # Use pinned nixpkgs when using `nix run pkgs#`
- pkgs.flake = inputs.nixpkgs;
- # Add NUR to run some packages that are only present there
- nur.flake = inputs.nur;
+ (lib.mkIf cfg.cache.selfHosted {
+ nix = {
+ settings = {
+ # The NixOS module adds the official Hydra cache by default
+ # No need to use `extra-*` options.
+ substituters = [
+ "https://cache.belanyi.fr/"
+ ];
+
+ trusted-public-keys = [
+ "cache.belanyi.fr:LPhrTqufwfxTceg1nRWueDWf7/2zSVY9K00pq2UI7tw="
+ ];
+ };
};
})
- (lib.mkIf cfg.addToNixPath {
- nix.nixPath = options.nix.nixPath.default ++ [
- "self=${inputs.self}"
- "pkgs=${inputs.nixpkgs}"
- "nur=${inputs.nur}"
- ];
+ (lib.mkIf cfg.inputs.addToRegistry {
+ nix.registry =
+ let
+ makeEntry = v: { flake = v; };
+ makeEntries = lib.mapAttrs (lib.const makeEntry);
+ in
+ makeEntries channels;
+ })
+
+ (lib.mkIf cfg.inputs.link {
+ environment.etc =
+ let
+ makeLink = n: v: {
+ name = "nix/inputs/${n}";
+ value = { source = v.outPath; };
+ };
+ makeLinks = lib.mapAttrs' makeLink;
+ in
+ makeLinks channels;
+ })
+
+ (lib.mkIf cfg.inputs.addToNixPath {
+ nix.nixPath = [
+ "/etc/nix/inputs"
+ ]
+ ++ options.nix.nixPath.default;
})
]);
}
diff --git a/modules/system/packages/default.nix b/modules/system/packages/default.nix
index ceb85dd..5c29aa0 100644
--- a/modules/system/packages/default.nix
+++ b/modules/system/packages/default.nix
@@ -7,6 +7,8 @@ in
options.my.system.packages = with lib; {
enable = my.mkDisableOption "packages configuration";
+ allowAliases = mkEnableOption "allow package aliases";
+
allowUnfree = my.mkDisableOption "allow unfree packages";
};
@@ -27,7 +29,7 @@ in
};
nixpkgs.config = {
- allowUnfree = cfg.allowUnfree; # Because I don't care *that* much.
+ inherit (cfg) allowAliases allowUnfree;
};
};
}
diff --git a/modules/system/podman/default.nix b/modules/system/podman/default.nix
index c267ec6..52630c7 100644
--- a/modules/system/podman/default.nix
+++ b/modules/system/podman/default.nix
@@ -1,5 +1,5 @@
# Podman related settings
-{ config, inputs, lib, options, pkgs, ... }:
+{ config, lib, ... }:
let
cfg = config.my.system.podman;
in
@@ -9,6 +9,16 @@ in
};
config = lib.mkIf cfg.enable {
+ assertions = [
+ {
+ assertion = cfg.enable -> !config.my.system.docker.enable;
+ message = ''
+ `config.my.system.podman` is incompatible with
+ `config.my.system.docker`.
+ '';
+ }
+ ];
+
virtualisation.podman = {
enable = true;
@@ -19,7 +29,20 @@ in
dockerSocket.enable = true;
# Allow DNS resolution in the default network
- defaultNetwork.dnsname.enable = true;
+ defaultNetwork.settings = {
+ dns_enabled = true;
+ };
+
+ # Remove unused data on a weekly basis
+ autoPrune = {
+ enable = true;
+
+ dates = "weekly";
+
+ flags = [
+ "--all"
+ ];
+ };
};
};
}
diff --git a/modules/system/users/default.nix b/modules/system/users/default.nix
index 3fa5b2e..27557bd 100644
--- a/modules/system/users/default.nix
+++ b/modules/system/users/default.nix
@@ -27,6 +27,7 @@ in
shell = pkgs.zsh;
extraGroups = groupsIfExist [
"audio" # sound control
+ "docker" # usage of `docker` socket
"media" # access to media files
"networkmanager" # wireless configuration
"plugdev" # usage of ZSA keyboard tools
diff --git a/overlays/default.nix b/overlays/default.nix
index 3f5a246..683e021 100644
--- a/overlays/default.nix
+++ b/overlays/default.nix
@@ -1,5 +1,6 @@
-{
- sabnzbd-fix-missing-packages = import ./sabnzbd-fix-missing-dependencies;
-
- transgui-fix-duplicate-status = import ./transgui-fix-duplicate-status;
-}
+# Automatically import all overlays in the directory
+let
+ files = builtins.readDir ./.;
+ overlays = builtins.removeAttrs files [ "default.nix" ];
+in
+builtins.mapAttrs (name: _: import "${./.}/${name}") overlays
diff --git a/overlays/sabnzbd-fix-missing-dependencies/default.nix b/overlays/sabnzbd-fix-missing-dependencies/default.nix
deleted file mode 100644
index e2e8eec..0000000
--- a/overlays/sabnzbd-fix-missing-dependencies/default.nix
+++ /dev/null
@@ -1,4 +0,0 @@
-final: prev:
-{
- sabnzbd = final.callPackage ./sabnzbd.nix { };
-}
diff --git a/overlays/sabnzbd-fix-missing-dependencies/sabnzbd.nix b/overlays/sabnzbd-fix-missing-dependencies/sabnzbd.nix
deleted file mode 100644
index 3da9b28..0000000
--- a/overlays/sabnzbd-fix-missing-dependencies/sabnzbd.nix
+++ /dev/null
@@ -1,60 +0,0 @@
-{ lib
-, stdenv
-, fetchFromGitHub
-, python3
-, par2cmdline
-, unzip
-, unrar
-, p7zip
-, makeWrapper
-}:
-
-let
- pythonEnv = python3.withPackages (ps: with ps; [
- chardet
- cheetah3
- cherrypy
- configobj
- cryptography
- feedparser
- guessit
- puremagic
- sabyenc3
- ]);
- path = lib.makeBinPath [ par2cmdline unrar unzip p7zip ];
-in
-stdenv.mkDerivation rec {
- version = "3.4.0";
- pname = "sabnzbd";
-
- src = fetchFromGitHub {
- owner = pname;
- repo = pname;
- rev = version;
- sha256 = "sha256-zax+PuvCmYOlEhRmiCp7UOd9VI0i8dbgTPyTtqLuGUM=";
- };
-
- nativeBuildInputs = [ makeWrapper ];
- buildInputs = [ pythonEnv ];
-
- installPhase = ''
- runHook preInstall
-
- mkdir -p $out
- cp -R * $out/
- mkdir $out/bin
- echo "${pythonEnv}/bin/python $out/SABnzbd.py \$*" > $out/bin/sabnzbd
- chmod +x $out/bin/sabnzbd
- wrapProgram $out/bin/sabnzbd --set PATH ${path}
-
- runHook postInstall
- '';
-
- meta = with lib; {
- description = "Usenet NZB downloader, par2 repairer and auto extracting server";
- homepage = "https://sabnzbd.org";
- license = licenses.gpl2Plus;
- platforms = platforms.linux;
- maintainers = with lib.maintainers; [ fridh ];
- };
-}
diff --git a/overlays/transgui-fix-duplicate-status/default.nix b/overlays/transgui-fix-duplicate-status/default.nix
deleted file mode 100644
index 85036ce..0000000
--- a/overlays/transgui-fix-duplicate-status/default.nix
+++ /dev/null
@@ -1,11 +0,0 @@
-final: prev:
-{
- transgui = prev.transgui.overrideAttrs (oldAttrs: {
- patches = (oldAttrs.patches or [ ]) ++ [
- (final.fetchpatch {
- url = "https://patch-diff.githubusercontent.com/raw/transmission-remote-gui/transgui/pull/1354.patch";
- sha256 = "sha256-Q4DAduqnTtNI0Zw9NIWpE8L0G8RusvPbZ3iW29k7XXA=";
- })
- ];
- });
-}
diff --git a/pkgs/bw-pass/default.nix b/pkgs/bw-pass/default.nix
index b11e7ea..9b959f5 100644
--- a/pkgs/bw-pass/default.nix
+++ b/pkgs/bw-pass/default.nix
@@ -1,20 +1,17 @@
-{ lib, bitwarden-cli, coreutils, jq, keyutils, makeWrapper, rofi, shellcheck, stdenvNoCC }:
+{ lib, bitwarden-cli, coreutils, jq, keyutils, makeWrapper, rofi, stdenvNoCC }:
stdenvNoCC.mkDerivation rec {
pname = "bw-pass";
version = "0.1.0";
src = ./bw-pass;
- buildInputs = [
+ nativeBuildInputs = [
makeWrapper
- shellcheck
];
dontUnpack = true;
- buildPhase = ''
- shellcheck $src
- '';
+ dontBuild = true;
installPhase = ''
mkdir -p $out/bin
@@ -37,9 +34,10 @@ stdenvNoCC.mkDerivation rec {
meta = with lib; {
description = "A simple script to query a password from bitwarden";
- homepage = "https://gitea.belanyi.fr/ambroisie/nix-config";
+ homepage = "https://git.belanyi.fr/ambroisie/nix-config";
license = with licenses; [ mit ];
- platforms = platforms.linux;
+ mainProgram = "bw-pass";
maintainers = with maintainers; [ ambroisie ];
+ platforms = platforms.linux;
};
}
diff --git a/pkgs/change-audio/default.nix b/pkgs/change-audio/default.nix
index d2e76b0..12814e1 100644
--- a/pkgs/change-audio/default.nix
+++ b/pkgs/change-audio/default.nix
@@ -1,20 +1,17 @@
-{ lib, libnotify, makeWrapper, pamixer, shellcheck, stdenvNoCC }:
+{ lib, libnotify, makeWrapper, pamixer, stdenvNoCC }:
stdenvNoCC.mkDerivation rec {
pname = "change-audio";
version = "0.3.0";
src = ./change-audio;
- buildInputs = [
+ nativeBuildInputs = [
makeWrapper
- shellcheck
];
dontUnpack = true;
- buildPhase = ''
- shellcheck $src
- '';
+ dontBuild = true;
installPhase = ''
mkdir -p $out/bin
@@ -36,9 +33,10 @@ stdenvNoCC.mkDerivation rec {
description = ''
A script to change the volume and notify about it
'';
- homepage = "https://gitea.belanyi.fr/ambroisie/nix-config";
+ homepage = "https://git.belanyi.fr/ambroisie/nix-config";
license = with licenses; [ mit ];
- platforms = platforms.linux;
+ mainProgram = "change-audio";
maintainers = with maintainers; [ ambroisie ];
+ platforms = platforms.linux;
};
}
diff --git a/pkgs/change-backlight/default.nix b/pkgs/change-backlight/default.nix
index 799c814..1f8c88c 100644
--- a/pkgs/change-backlight/default.nix
+++ b/pkgs/change-backlight/default.nix
@@ -1,20 +1,17 @@
-{ lib, brightnessctl, libnotify, makeWrapper, shellcheck, stdenvNoCC }:
+{ lib, brightnessctl, libnotify, makeWrapper, stdenvNoCC }:
stdenvNoCC.mkDerivation rec {
pname = "change-backlight";
version = "0.1.0";
src = ./change-backlight;
- buildInputs = [
+ nativeBuildInputs = [
makeWrapper
- shellcheck
];
dontUnpack = true;
- buildPhase = ''
- shellcheck $src
- '';
+ dontBuild = true;
installPhase = ''
mkdir -p $out/bin
@@ -36,9 +33,10 @@ stdenvNoCC.mkDerivation rec {
description = ''
A script to change a screen's brightness and notify about it
'';
- homepage = "https://gitea.belanyi.fr/ambroisie/nix-config";
+ homepage = "https://git.belanyi.fr/ambroisie/nix-config";
license = with licenses; [ mit ];
- platforms = platforms.linux;
+ mainProgram = "change-backlight";
maintainers = with maintainers; [ ambroisie ];
+ platforms = platforms.linux;
};
}
diff --git a/pkgs/comma/default.nix b/pkgs/comma/default.nix
index 1c10eb2..32e09d0 100644
--- a/pkgs/comma/default.nix
+++ b/pkgs/comma/default.nix
@@ -1,20 +1,17 @@
-{ lib, fzf, makeWrapper, nix-index, shellcheck, stdenvNoCC }:
+{ lib, fzf, makeWrapper, nix-index, stdenvNoCC }:
stdenvNoCC.mkDerivation rec {
pname = "comma";
version = "0.1.0";
src = ./comma;
- buildInputs = [
+ nativeBuildInputs = [
makeWrapper
- shellcheck
];
dontUnpack = true;
- buildPhase = ''
- shellcheck $src
- '';
+ dontBuild = true;
installPhase = ''
mkdir -p $out/bin
@@ -33,11 +30,11 @@ stdenvNoCC.mkDerivation rec {
'';
meta = with lib; {
- mainProgram = ",";
description = "A simple script inspired by Shopify's comma, for modern Nix";
- homepage = "https://gitea.belanyi.fr/ambroisie/nix-config";
+ homepage = "https://git.belanyi.fr/ambroisie/nix-config";
license = with licenses; [ mit ];
- platforms = platforms.unix;
+ mainProgram = ",";
maintainers = with maintainers; [ ambroisie ];
+ platforms = platforms.unix;
};
}
diff --git a/pkgs/default.nix b/pkgs/default.nix
index af39384..c9e755a 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -12,23 +12,21 @@ pkgs.lib.makeScope pkgs.newScope (pkgs: {
dragger = pkgs.callPackage ./dragger { };
+ drone-rsync = pkgs.callPackage ./drone-rsync { };
+
drone-scp = pkgs.callPackage ./drone-scp { };
ff2mpv-go = pkgs.callPackage ./ff2mpv-go { };
- havm = pkgs.callPackage ./havm { };
-
i3-get-window-criteria = pkgs.callPackage ./i3-get-window-criteria { };
lohr = pkgs.callPackage ./lohr { };
matrix-notifier = pkgs.callPackage ./matrix-notifier { };
- nolimips = pkgs.callPackage ./nolimips { };
+ osc52 = pkgs.callPackage ./osc52 { };
- psst = pkgs.callPackage ./psst { };
-
- rofi-bluetooth = pkgs.callPackage ./rofi-bluetooth { };
+ rbw-pass = pkgs.callPackage ./rbw-pass { };
unbound-zones-adblock = pkgs.callPackage ./unbound-zones-adblock { };
@@ -37,4 +35,6 @@ pkgs.lib.makeScope pkgs.newScope (pkgs: {
vimix-cursors = pkgs.callPackage ./vimix-cursors { };
volantes-cursors = pkgs.callPackage ./volantes-cursors { };
+
+ wifi-qr = pkgs.callPackage ./wifi-qr { };
})
diff --git a/pkgs/diff-flake/default.nix b/pkgs/diff-flake/default.nix
index c085e67..9cccd20 100644
--- a/pkgs/diff-flake/default.nix
+++ b/pkgs/diff-flake/default.nix
@@ -1,20 +1,17 @@
-{ lib, coreutils, git, gnused, makeWrapper, shellcheck, stdenvNoCC }:
+{ lib, coreutils, git, gnused, makeWrapper, stdenvNoCC }:
stdenvNoCC.mkDerivation rec {
pname = "diff-flake";
- version = "0.1.0";
+ version = "0.4.0";
src = ./diff-flake;
- buildInputs = [
+ nativeBuildInputs = [
makeWrapper
- shellcheck
];
dontUnpack = true;
- buildPhase = ''
- shellcheck $src
- '';
+ dontBuild = true;
installPhase = ''
mkdir -p $out/bin
@@ -35,9 +32,10 @@ stdenvNoCC.mkDerivation rec {
meta = with lib; {
description = "Nix flake helper to visualize changes in closures";
- homepage = "https://gitea.belanyi.fr/ambroisie/nix-config";
+ homepage = "https://git.belanyi.fr/ambroisie/nix-config";
license = with licenses; [ mit ];
- platforms = platforms.unix;
+ mainProgram = "diff-flake";
maintainers = with maintainers; [ ambroisie ];
+ platforms = platforms.unix;
};
}
diff --git a/pkgs/diff-flake/diff-flake b/pkgs/diff-flake/diff-flake
index ef03122..0572b4e 100755
--- a/pkgs/diff-flake/diff-flake
+++ b/pkgs/diff-flake/diff-flake
@@ -20,19 +20,21 @@ sanitize_output() {
fi
}
-add_shell() {
- local SYSTEM
- if [ $# -gt 0 ] && [ -n "$1" ]; then
- SYSTEM="$1"
- else
- SYSTEM="$(nix eval --raw --impure --expr 'builtins.currentSystem')"
- fi
- # Use 'inputDerivation' attribute to make sure that it is build-able
- FLAKE_OUTPUTS+=("devShell.$SYSTEM.inputDerivation")
+current_system() {
+ nix eval --raw --impure --expr 'builtins.currentSystem'
+}
+
+add_home() {
+ FLAKE_OUTPUTS+=("homeConfigurations.\"$1\".activationPackage")
}
add_host() {
- FLAKE_OUTPUTS+=("nixosConfigurations.$1.config.system.build.toplevel")
+ FLAKE_OUTPUTS+=("nixosConfigurations.\"$1\".config.system.build.toplevel")
+}
+
+add_shell() {
+ # Use 'inputDerivation' attribute to make sure that it is build-able
+ FLAKE_OUTPUTS+=("devShells.\"$(current_system)\".\"$1\".inputDerivation")
}
usage() {
@@ -52,17 +54,21 @@ usage() {
print_err " -p, --previous-rev"
print_err " which git revision should be considered the 'previous' state,"
print_err " defaults to HEAD~"
+ print_err " --home [name]"
+ print_err " specify the name of a home-manager output configuration whose"
+ print_err " closure should be diffed, can be used multiple times"
+ print_err " if no configuration name is given, defaults to current username"
print_err " --host [name]"
print_err " specify the name of a NixOS output configuration whose"
print_err " closure should be diffed, can be used multiple times"
print_err " if no host name is given, defaults to current hostname"
- print_err " --shell [system]"
- print_err " specify a specific system's devShell output whose closure"
+ print_err " --shell [name]"
+ print_err " specify a specific devShell configuration name whose closure"
print_err " should be diffed, can be used multiple times"
- print_err " if no system is given, defaults to current system"
+ print_err " if no name is given, defaults to 'default'"
print_err ""
print_err "when no flake outputs are specified, automatically queries for"
- print_err "all NixOS configurations, and devShell for current system"
+ print_err "all NixOS configurations, and devShells for current system"
}
is_option() {
@@ -95,6 +101,14 @@ parse_args() {
PREVIOUS_REV="$(git rev-parse "$1")"
shift
;;
+ --home)
+ if [ $# -gt 0 ] && ! is_option "$1"; then
+ add_home "$1"
+ shift
+ else
+ add_home "$USER"
+ fi
+ ;;
--host)
if [ $# -gt 0 ] && ! is_option "$1"; then
add_host "$1"
@@ -108,7 +122,7 @@ parse_args() {
add_shell "$1"
shift
else
- add_shell
+ add_shell "default"
fi
;;
--)
@@ -124,12 +138,24 @@ parse_args() {
done
}
+list_home_configurations() {
+ nix eval '.#homeConfigurations' \
+ --apply 'attrs: with builtins; concatStringsSep "\n" (attrNames attrs)' \
+ --raw
+}
+
list_nixos_configurations() {
nix eval '.#nixosConfigurations' \
--apply 'attrs: with builtins; concatStringsSep "\n" (attrNames attrs)' \
--raw
}
+list_dev_shells() {
+ nix eval ".#devShells.\"$(current_system)\"" \
+ --apply 'attrs: with builtins; concatStringsSep "\n" (attrNames attrs)' \
+ --raw
+}
+
diff_output() {
local PREV NEW;
PREV="$(mktemp --dry-run)"
@@ -149,10 +175,15 @@ diff_output() {
parse_args "$@"
if [ "${#FLAKE_OUTPUTS[@]}" -eq 0 ]; then
+ for home in $(list_home_configurations); do
+ add_home "$home"
+ done
for host in $(list_nixos_configurations); do
add_host "$host"
done
- add_shell
+ for shell in $(list_dev_shells); do
+ add_shell "$shell"
+ done
fi
for out in "${FLAKE_OUTPUTS[@]}"; do
diff --git a/pkgs/dragger/default.nix b/pkgs/dragger/default.nix
index cd0d453..9eda7df 100644
--- a/pkgs/dragger/default.nix
+++ b/pkgs/dragger/default.nix
@@ -7,7 +7,7 @@ qt5.mkDerivation rec {
owner = "ambroisie";
repo = "dragger";
rev = "v${version}";
- sha256 = "sha256-WAC720DxfkQxy1BeeGzE6IerFb4ejoMRAPEJv5HGDHM=";
+ hash = "sha256-WAC720DxfkQxy1BeeGzE6IerFb4ejoMRAPEJv5HGDHM=";
};
configurePhase = ''
@@ -21,9 +21,10 @@ qt5.mkDerivation rec {
meta = with lib; {
description = "A CLI drag-and-drop tool";
- homepage = "https://gitea.belanyi.fr/ambroisie/dragger";
+ homepage = "https://git.belanyi.fr/ambroisie/dragger";
license = licenses.mit;
- maintainers = [ ambroisie ];
+ mainProgram = "dragger";
+ maintainers = with maintainers; [ ambroisie ];
platforms = platforms.linux;
};
}
diff --git a/pkgs/drone-rsync/default.nix b/pkgs/drone-rsync/default.nix
new file mode 100644
index 0000000..a7c2cbc
--- /dev/null
+++ b/pkgs/drone-rsync/default.nix
@@ -0,0 +1,41 @@
+{ lib, makeWrapper, openssh, rsync, sshpass, stdenvNoCC }:
+stdenvNoCC.mkDerivation rec {
+ pname = "drone-rsync";
+ version = "0.1.0";
+
+ src = ./drone-rsync;
+
+ nativeBuildInputs = [
+ makeWrapper
+ ];
+
+ dontUnpack = true;
+
+ dontBuild = true;
+
+ installPhase = ''
+ mkdir -p $out/bin
+ cp $src $out/bin/${pname}
+ chmod a+x $out/bin/${pname}
+ '';
+
+ wrapperPath = lib.makeBinPath [
+ openssh
+ rsync
+ sshpass
+ ];
+
+ fixupPhase = ''
+ patchShebangs $out/bin/${pname}
+ wrapProgram $out/bin/${pname} --prefix PATH : "${wrapperPath}"
+ '';
+
+ meta = with lib; {
+ description = "Helper script to run rsync in a CI pipeline";
+ homepage = "https://git.belanyi.fr/ambroisie/nix-config";
+ license = with licenses; [ mit ];
+ mainProgram = "drone-rsync";
+ maintainers = with maintainers; [ ambroisie ];
+ platforms = platforms.unix;
+ };
+}
diff --git a/pkgs/drone-rsync/drone-rsync b/pkgs/drone-rsync/drone-rsync
new file mode 100755
index 0000000..b6491e7
--- /dev/null
+++ b/pkgs/drone-rsync/drone-rsync
@@ -0,0 +1,31 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+ARGS=(
+ # Show readable progress in log
+ --verbose
+ --human-readable
+ --progress
+ # Have a one-to-one copy
+ --archive
+ --compress
+ --recursive
+ --delete
+ # Configure ssh client
+ --rsh "ssh -p ${SYNC_PORT:-22} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
+)
+
+eval "$(ssh-agent)"
+SSHPASS="${SYNC_PASSPHRASE:-}" sshpass -P 'passphrase' -v -e ssh-add <(echo "${SYNC_KEY}")
+
+if [ -n "${SYNC_DRY_RUN:-}" ]; then
+ ARGS+=(--dry-run)
+fi
+
+# shellcheck disable=2086
+# FIXME: have a safer way to allow globbing the source
+rsync \
+ "${ARGS[@]}" \
+ ${SYNC_SOURCE} \
+ "${SYNC_USERNAME}@${SYNC_HOST}:${SYNC_TARGET}"
diff --git a/pkgs/drone-scp/default.nix b/pkgs/drone-scp/default.nix
index 863befd..7437b06 100644
--- a/pkgs/drone-scp/default.nix
+++ b/pkgs/drone-scp/default.nix
@@ -1,16 +1,16 @@
{ lib, buildGoModule, fetchFromGitHub }:
buildGoModule rec {
pname = "drone-scp";
- version = "1.6.2";
+ version = "1.6.3";
src = fetchFromGitHub {
owner = "appleboy";
repo = "drone-scp";
rev = "v${version}";
- sha256 = "sha256-PNy1HA2qW4RY/VRHhuj/tIrdTuB7COr0Cuzurku+DZw=";
+ hash = "sha256-ELjPqoRR4O6gmc/PgthQuSXuSTQNzBZoAUT80zVVbV0=";
};
- vendorSha256 = "sha256-7Aro6g3Tka0Cbi9LpqvKpQXlbxnHQWsMOkkNpENKh0U=";
+ vendorHash = "sha256-/c103hTJ/Qdz2KTkdl/ACvAaSSTKcl1DQY3+Us6OxaI=";
doCheck = false; # Needs a specific user...
@@ -20,5 +20,6 @@ buildGoModule rec {
'';
homepage = "https://github.com/appleboy/drone-scp";
license = licenses.mit;
+ mainProgram = "drone-scp";
};
}
diff --git a/pkgs/ff2mpv-go/default.nix b/pkgs/ff2mpv-go/default.nix
index 3dc229c..8c59bf5 100644
--- a/pkgs/ff2mpv-go/default.nix
+++ b/pkgs/ff2mpv-go/default.nix
@@ -6,13 +6,13 @@ buildGoModule rec {
src = fetchgit {
url = "https://git.clsr.net/util/ff2mpv-go/";
rev = "v${version}";
- sha256 = "sha256-e/AuOA3isFTyBf97Zwtr16yo49UdYzvktV5PKB/eH/s=";
+ hash = "sha256-e/AuOA3isFTyBf97Zwtr16yo49UdYzvktV5PKB/eH/s=";
};
- vendorSha256 = "sha256-pQpattmS9VmO3ZIQUFn66az8GSmB4IvYhTTCFn6SUmo=";
+ vendorHash = null;
postPatch = ''
- sed -i -e 's,"mpv","${mpv}/bin/mpv",' ff2mpv.go
+ sed -i -e 's,"mpv","${lib.getExe mpv}",' ff2mpv.go
'';
postInstall = ''
@@ -26,5 +26,6 @@ buildGoModule rec {
'';
homepage = "https://git.clsr.net/util/ff2mpv-go/";
license = licenses.publicDomain;
+ mainProgram = "ff2mpv-go";
};
}
diff --git a/pkgs/havm/default.nix b/pkgs/havm/default.nix
deleted file mode 100644
index 51eb9f0..0000000
--- a/pkgs/havm/default.nix
+++ /dev/null
@@ -1,34 +0,0 @@
-{ lib, fetchurl, ghc, stdenv, which }:
-stdenv.mkDerivation rec {
- pname = "havm";
- version = "0.28";
-
- src = fetchurl {
- url = "https://www.lrde.epita.fr/~tiger/download/${pname}-${version}.tar.gz";
- sha256 = "sha256-FDi4FZ8rjGqRkFlROtcJsv+mks7MmIXQGV4bZrwkQrA=";
- };
-
- nativeBuildInputs = [
- ghc
- ];
-
- checkInputs = [
- which
- ];
-
- doCheck = true;
-
- meta = with lib; {
- description = "A simple virtual machine to execute Andrew Appel's HIR/LIR";
- longDescription = ''
- HAVM is a virtual machine designed to execute simple register based high
- level intermediate code. It is based on the intermediate representations
- ("canonicalized" or not) defined by Andrew Appel in his "Modern Compiler
- Implementation".
- '';
- homepage = "https://www.lrde.epita.fr/wiki/Havm";
- license = licenses.gpl2Plus;
- platforms = platforms.all;
- maintainers = with maintainers; [ ambroisie ];
- };
-}
diff --git a/pkgs/i3-get-window-criteria/default.nix b/pkgs/i3-get-window-criteria/default.nix
index acfde93..2fc840d 100644
--- a/pkgs/i3-get-window-criteria/default.nix
+++ b/pkgs/i3-get-window-criteria/default.nix
@@ -1,20 +1,17 @@
-{ lib, coreutils, gnused, makeWrapper, shellcheck, stdenvNoCC, xorg }:
+{ lib, coreutils, gnused, makeWrapper, stdenvNoCC, xorg }:
stdenvNoCC.mkDerivation rec {
pname = "i3-get-window-criteria";
version = "0.1.0";
src = ./i3-get-window-criteria;
- buildInputs = [
+ nativeBuildInputs = [
makeWrapper
- shellcheck
];
dontUnpack = true;
- buildPhase = ''
- shellcheck $src
- '';
+ dontBuild = true;
installPhase = ''
mkdir -p $out/bin
@@ -36,9 +33,10 @@ stdenvNoCC.mkDerivation rec {
meta = with lib; {
description = "Helper script to query i3 window criterions";
- homepage = "https://gitea.belanyi.fr/ambroisie/nix-config";
+ homepage = "https://git.belanyi.fr/ambroisie/nix-config";
license = with licenses; [ mit ];
- platforms = platforms.unix;
+ mainProgram = "i3-get-window-criteria";
maintainers = with maintainers; [ ambroisie ];
+ platforms = platforms.unix;
};
}
diff --git a/pkgs/lohr/default.nix b/pkgs/lohr/default.nix
index c71dbd0..a83b092 100644
--- a/pkgs/lohr/default.nix
+++ b/pkgs/lohr/default.nix
@@ -1,22 +1,23 @@
{ lib, fetchFromGitHub, rustPlatform }:
rustPlatform.buildRustPackage rec {
pname = "lohr";
- version = "0.4.0";
+ version = "0.4.2";
src = fetchFromGitHub {
owner = "alarsyo";
repo = "lohr";
rev = "v${version}";
- sha256 = "sha256-MplTVJG+SoeLMXQP+ix/zM3OSHuQmZnunn900YnyCBw=";
+ hash = "sha256-2pN/Me5fCdE++TzBUswPXzjuUIIB7Uck+Scp361JgE4=";
};
- cargoSha256 = "sha256-iuMJj8tqetlmdfsrfudnU1afwUzjls/UdYLq1u0gr+g=";
+ cargoHash = "sha256-YHg4b6rKcnVJSDoWh9/o+p40NBog65Gd2/UwIDXiUe0=";
meta = with lib; {
description = "Git mirroring daemon";
homepage = "https://github.com/alarsyo/lohr";
license = with licenses; [ mit asl20 ];
- platforms = platforms.unix;
+ mainProgram = "lohr";
maintainers = with maintainers; [ ambroisie ];
+ platforms = platforms.unix;
};
}
diff --git a/pkgs/matrix-notifier/default.nix b/pkgs/matrix-notifier/default.nix
index 76765a7..a96cb61 100644
--- a/pkgs/matrix-notifier/default.nix
+++ b/pkgs/matrix-notifier/default.nix
@@ -1,13 +1,13 @@
{ lib, curl, jq, fetchFromGitHub, makeWrapper, pandoc, stdenvNoCC }:
stdenvNoCC.mkDerivation rec {
pname = "matrix-notifier";
- version = "0.2.0";
+ version = "0.3.0";
src = fetchFromGitHub {
owner = "ambroisie";
repo = "matrix-notifier";
rev = "v${version}";
- sha256 = "sha256-JiKPDrr9wyD2q5Vsac+OkFdvrDkx6mj/oC7XDVnka74=";
+ hash = "sha256-NE9RO0ep2ibrT9EUPGTnUE3ofdNTCHwelxnX9tCflg0=";
};
nativeBuildInputs = [
@@ -36,9 +36,10 @@ stdenvNoCC.mkDerivation rec {
A very simple bash script that can be used to send a message to
a Matrix room
'';
- homepage = "https://gitea.belanyi.fr/ambroisie/${pname}";
+ homepage = "https://git.belanyi.fr/ambroisie/${pname}";
license = licenses.mit;
- platforms = platforms.unix;
+ mainProgram = "matrix-notifier";
maintainers = with maintainers; [ ambroisie ];
+ platforms = platforms.unix;
};
}
diff --git a/pkgs/nolimips/default.nix b/pkgs/nolimips/default.nix
deleted file mode 100644
index 65d847d..0000000
--- a/pkgs/nolimips/default.nix
+++ /dev/null
@@ -1,24 +0,0 @@
-{ lib, fetchurl, stdenv }:
-stdenv.mkDerivation rec {
- pname = "nolimips";
- version = "0.11";
-
- src = fetchurl {
- url = "https://www.lrde.epita.fr/~tiger/download/${pname}-${version}.tar.gz";
- sha256 = "sha256-OjbfcBwCZtFP0usz8YXA0lN8xs0jS4I19mkh9p7VHc8=";
- };
-
- doCheck = true;
-
- meta = with lib; {
- description = "A basic MIPS architecture simulator";
- longDescription = ''
- A basic MIPS architecture simulator, which implements a few system calls
- and supports an arbitrary number of registers.
- '';
- homepage = "https://www.lrde.epita.fr/wiki/Nolimips";
- license = licenses.gpl2;
- platforms = platforms.all;
- maintainers = with maintainers; [ ambroisie ];
- };
-}
diff --git a/pkgs/osc52/default.nix b/pkgs/osc52/default.nix
new file mode 100644
index 0000000..d4b0c08
--- /dev/null
+++ b/pkgs/osc52/default.nix
@@ -0,0 +1,41 @@
+{ lib, coreutils, makeWrapper, stdenvNoCC }:
+stdenvNoCC.mkDerivation rec {
+ pname = "osc52";
+ version = "0.1.0";
+
+ src = ./osc52;
+
+ nativeBuildInputs = [
+ makeWrapper
+ ];
+
+ dontUnpack = true;
+
+ dontBuild = true;
+
+ installPhase = ''
+ mkdir -p $out/bin
+ cp $src $out/bin/osc52
+ chmod a+x $out/bin/osc52
+ '';
+
+ wrapperPath = lib.makeBinPath [
+ coreutils
+ ];
+
+ fixupPhase = ''
+ patchShebangs $out/bin/osc52
+ wrapProgram $out/bin/osc52 --prefix PATH : "${wrapperPath}"
+ '';
+
+ meta = with lib; {
+ description = ''
+ A script to copy strings using the OSC52 escape sequence
+ '';
+ homepage = "https://git.belanyi.fr/ambroisie/nix-config";
+ license = with licenses; [ mit ];
+ mainProgram = "osc52";
+ maintainers = with maintainers; [ ambroisie ];
+ platforms = platforms.linux;
+ };
+}
diff --git a/pkgs/osc52/osc52 b/pkgs/osc52/osc52
new file mode 100755
index 0000000..f64ccb6
--- /dev/null
+++ b/pkgs/osc52/osc52
@@ -0,0 +1,153 @@
+#!/usr/bin/env bash
+
+# Max length of the OSC 52 sequence.
+: "${OSC52_MAX_SEQUENCE:=100000}"
+# Whether to disable tmux/screen DCS escape sequences
+: "${OSC52_NO_DCS:=0}"
+
+die() {
+ echo "ERROR: $*"
+ exit 1
+}
+
+usage() {
+ if [ $# -gt 0 ]; then
+ exec 1>&2
+ fi
+
+ cat << EOF
+Usage: $0 [options] [string]
+Send an arbitrary string to the terminal clipboard using the OSC 52 escape
+sequence as specified in xterm:
+ https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
+ Section "Operating System Commands", Ps => 52.
+The data can either be read from stdin:
+ $ echo "hello world" | $0
+Or specified on the command line:
+ $ $0 "hello world"
+Options:
+ -h, --help This screen.
+ -d, --no-dcs Disable tmux/screen specific DCS sequences, only use OSC 52
+ -f, --force Ignore max byte limit (${OSC52_MAX_SEQUENCE})
+ -- Stop options processing
+EOF
+
+ if [ $# -gt 0 ]; then
+ echo
+ die "$@"
+ else
+ exit 0
+ fi
+}
+
+tmux_seq() {
+ # shellcheck disable=1003
+ printf '\033Ptmux;\033%s\033\\' "$1"
+}
+
+screen_seq() {
+ # Screen limits the length of string sequences, so we have to break it up.
+ # Going by the screen history:
+ # (v4.2.1) Apr 2014 - today: 768 bytes
+ # Aug 2008 - Apr 2014 (v4.2.0): 512 bytes
+ # ??? - Aug 2008 (v4.0.3): 256 bytes
+ local limit=768
+ # We go 4 bytes under the limit because we're going to insert two bytes
+ # before (\eP) and 2 bytes after (\e\) each string.
+ printf '%s' "$1" |
+ sed -E "s:.{$((limit - 4))}:&\n:g" |
+ sed -E -e 's:^:\x1bP:' -e 's:$:\x1b\\:' |
+ tr -d '\n'
+}
+
+osc52_seq() {
+ printf '%s' "$1"
+}
+
+print_seq() {
+ local seq="$1"
+
+ if [ "${OSC52_NO_DCS}" != 0 ]; then
+ # Override TERM to avoid tmux/screen DCS escape logic
+ TERM=dummy
+ fi
+
+ case ${TERM-} in
+ screen*)
+ # Since tmux defaults to setting TERM=screen, special case it.
+ if [ -n "${TMUX-}" ]; then
+ tmux_seq "${seq}"
+ else
+ screen_seq "${seq}"
+ fi
+ ;;
+ tmux*)
+ tmux_seq "${seq}"
+ ;;
+ *)
+ osc52_seq "${seq}"
+ ;;
+ esac
+}
+
+b64enc() {
+ base64 | tr -d '\n'
+}
+
+copy() {
+ local str
+ if [ $# -eq 0 ]; then
+ str="$(b64enc)"
+ else
+ str="$(printf '%s' "$1" | b64enc)"
+ fi
+
+ if [ "${OSC52_MAX_SEQUENCE}" -gt 0 ]; then
+ local len=${#str}
+ if [ "${len}" -gt "${OSC52_MAX_SEQUENCE}" ]; then
+ die "selection too long to send to terminal:" \
+ "${OSC52_MAX_SEQUENCE} limit, ${len} attempted"
+ fi
+ fi
+
+ print_seq "$(printf '\033]52;c;%s\a' "${str}")"
+}
+
+main() {
+ set -e
+
+ local args=()
+ while [ $# -gt 0 ]; do
+ case $1 in
+ -h | --help)
+ usage
+ ;;
+ -f | --force)
+ OSC52_MAX_SEQUENCE=0
+ ;;
+ -d | --no-dcs)
+ OSC52_NO_DCS=1
+ ;;
+ --)
+ shift
+ args+=("$@")
+ break
+ ;;
+ -*)
+ usage "Unknown option: $1"
+ ;;
+ *)
+ args+=("$1")
+ ;;
+ esac
+ shift
+ done
+
+ if [ "${#args[@]}" -gt 1 ]; then
+ usage "Only supply one argument"
+ fi
+
+ copy "${args[@]}"
+}
+
+main "$@"
diff --git a/pkgs/psst/default.nix b/pkgs/psst/default.nix
deleted file mode 100644
index 6eca44b..0000000
--- a/pkgs/psst/default.nix
+++ /dev/null
@@ -1,34 +0,0 @@
-{ lib, alsa-lib, cairo, dbus, fetchFromGitHub, gtk3, openssl, pkg-config, rustPlatform }:
-rustPlatform.buildRustPackage rec {
- pname = "psst";
- version = "unstable-2022-01-13";
-
- src = fetchFromGitHub {
- owner = "jpochyla";
- repo = "psst";
- rev = "8f142a3232a706537c8477bff43d2e52309f6b78";
- sha256 = "sha256-YA9p6KHuZXt43OrfShO5d3Cj8L8GPpczRQlncJqM7QI=";
- };
-
- nativeBuildInputs = [
- pkg-config
- ];
-
- buildInputs = [
- alsa-lib
- cairo
- dbus
- gtk3
- openssl
- ];
-
- cargoSha256 = "sha256-iA/ja7B73JyiXQ9kBzk1C5wtX+HPBrngCS+8rFDHbcs=";
-
- meta = with lib; {
- description = "Fast and multi-platform Spotify client with native GUI";
- homepage = "https://github.com/jpochyla/psst";
- platforms = platforms.linux;
- license = with licenses; [ mit ];
- maintainers = with maintainers; [ ambroisie ];
- };
-}
diff --git a/pkgs/rbw-pass/default.nix b/pkgs/rbw-pass/default.nix
new file mode 100644
index 0000000..6f9ff0a
--- /dev/null
+++ b/pkgs/rbw-pass/default.nix
@@ -0,0 +1,41 @@
+{ lib, coreutils, makeWrapper, rbw, rofi, stdenvNoCC }:
+stdenvNoCC.mkDerivation rec {
+ pname = "rbw-pass";
+ version = "0.1.0";
+
+ src = ./rbw-pass;
+
+ nativeBuildInputs = [
+ makeWrapper
+ ];
+
+ dontUnpack = true;
+
+ dontBuild = true;
+
+ installPhase = ''
+ mkdir -p $out/bin
+ cp $src $out/bin/${pname}
+ chmod a+x $out/bin/${pname}
+ '';
+
+ wrapperPath = lib.makeBinPath [
+ rbw
+ coreutils
+ rofi
+ ];
+
+ fixupPhase = ''
+ patchShebangs $out/bin/${pname}
+ wrapProgram $out/bin/${pname} --prefix PATH : "${wrapperPath}"
+ '';
+
+ meta = with lib; {
+ description = "A simple script to query a password from rbw";
+ homepage = "https://git.belanyi.fr/ambroisie/nix-config";
+ license = with licenses; [ mit ];
+ mainProgram = "rbw-pass";
+ maintainers = with maintainers; [ ambroisie ];
+ platforms = platforms.linux;
+ };
+}
diff --git a/pkgs/rbw-pass/rbw-pass b/pkgs/rbw-pass/rbw-pass
new file mode 100755
index 0000000..90e916c
--- /dev/null
+++ b/pkgs/rbw-pass/rbw-pass
@@ -0,0 +1,43 @@
+#!/usr/bin/env bash
+
+usage() {
+ printf '%s\n' "Usage: bw-pass [directory name] " >&2
+}
+
+error_out() {
+ printf '%s\n' "$1" >&2
+ rofi -dmenu -no-fixed-num-lines -p "$1"
+ exit 1
+}
+
+ensure_logged_in() {
+ rbw login
+}
+
+query_password() {
+ # Either use with `query_password
+ # Or `query_password ` when the account has no directory
+
+ local FOLDER_ARGS=()
+ local PASSWORD
+
+ # FIXME: no way to enforce filering by "no folder"
+ if [ $# -eq 2 ]; then
+ FOLDER_ARGS+=(--folder "$1")
+ shift
+ fi
+ PASSWORD="$(rbw get "${FOLDER_ARGS[@]}" "$1")"
+
+ if [ -z "$PASSWORD" ]; then
+ error_out "Did not find password for '$1'"
+ fi
+ printf '%s\n' "$PASSWORD"
+}
+
+if [ $# -lt 1 ] || [ $# -gt 2 ]; then
+ usage
+ exit 1
+fi
+
+ensure_logged_in
+query_password "$@"
diff --git a/pkgs/rofi-bluetooth/default.nix b/pkgs/rofi-bluetooth/default.nix
deleted file mode 100644
index 2ff40a1..0000000
--- a/pkgs/rofi-bluetooth/default.nix
+++ /dev/null
@@ -1,40 +0,0 @@
-{ lib, bluez, fetchFromGitHub, makeWrapper, rofi, stdenvNoCC }:
-stdenvNoCC.mkDerivation rec {
- pname = "rofi-bluetooth";
- version = "unstable-2021-10-15";
-
- src = fetchFromGitHub {
- owner = "nickclyde";
- repo = "rofi-bluetooth";
- rev = "893db1f2b549e7bc0e9c62e7670314349a29cdf2";
- sha256 = "sha256-3oROJKEQCuSnLfbJ+JSSc9hcmJTPrLHRQJsrUcaOMss=";
- };
-
- buildInputs = [
- makeWrapper
- ];
-
- installPhase = ''
- mkdir -p $out/bin
- cp $src/rofi-bluetooth $out/bin/
- chmod a+x $out/bin/rofi-bluetooth
- '';
-
- wrapperPath = lib.makeBinPath [
- rofi
- bluez
- ];
-
- fixupPhase = ''
- patchShebangs $out/bin/${pname}
- wrapProgram $out/bin/${pname} --prefix PATH : "${wrapperPath}"
- '';
-
- meta = with lib; {
- description = "A rofi menu for managing bluetooth connections";
- homepage = "https://github.com/nickclyde/rofi-bluetooth/commit/";
- license = with licenses; [ gpl3Only ];
- platforms = platforms.linux;
- maintainers = with maintainers; [ ambroisie ];
- };
-}
diff --git a/pkgs/unbound-zones-adblock/default.nix b/pkgs/unbound-zones-adblock/default.nix
index ecec917..b8392ae 100644
--- a/pkgs/unbound-zones-adblock/default.nix
+++ b/pkgs/unbound-zones-adblock/default.nix
@@ -1,5 +1,5 @@
{ lib, gawk, stdenvNoCC, unified-hosts-lists }:
-stdenvNoCC.mkDerivation rec {
+stdenvNoCC.mkDerivation {
name = "unbound-zones-adblock";
version = unified-hosts-lists.version;
@@ -10,7 +10,7 @@ stdenvNoCC.mkDerivation rec {
installPhase =
let
gawkCmd = lib.concatStringsSep " " [
- ''${gawk}/bin/awk''
+ (lib.getExe gawk)
'''{sub(/\r$/,"")}''
''{sub(/^127\.0\.0\.1/,"0.0.0.0")}''
''BEGIN { OFS = "" }''
@@ -32,7 +32,7 @@ stdenvNoCC.mkDerivation rec {
'';
homepage = "https://github.com/StevenBlack/hosts";
license = licenses.mit;
- platforms = platforms.all;
maintainers = with maintainers; [ ambroisie ];
+ platforms = platforms.all;
};
}
diff --git a/pkgs/unified-hosts-lists/default.nix b/pkgs/unified-hosts-lists/default.nix
index 4b0e0c6..06d24ac 100644
--- a/pkgs/unified-hosts-lists/default.nix
+++ b/pkgs/unified-hosts-lists/default.nix
@@ -1,13 +1,13 @@
{ lib, fetchFromGitHub, stdenvNoCC }:
stdenvNoCC.mkDerivation rec {
pname = "unified-hosts-lists";
- version = "3.9.11";
+ version = "3.12.15";
src = fetchFromGitHub {
owner = "StevenBlack";
repo = "hosts";
rev = version;
- sha256 = "sha256-JFz6M0Mkwoby7I6LLWx0QfvZMzwET2FEQ1OGKQnFfho=";
+ hash = "sha256-HoNX57lCoIr36B/7HMuazWSWeAPPfWY1oZf6dXnxYIE=";
};
dontUnpack = true;
@@ -28,7 +28,7 @@ stdenvNoCC.mkDerivation rec {
'';
homepage = "https://github.com/StevenBlack/hosts";
license = licenses.mit;
- platforms = platforms.all;
maintainers = with maintainers; [ ambroisie ];
+ platforms = platforms.all;
};
}
diff --git a/pkgs/vimix-cursors/default.nix b/pkgs/vimix-cursors/default.nix
index 1bbbe4e..80424de 100644
--- a/pkgs/vimix-cursors/default.nix
+++ b/pkgs/vimix-cursors/default.nix
@@ -10,7 +10,7 @@ stdenvNoCC.mkDerivation rec {
owner = "vinceliuice";
repo = pname;
rev = "27ebb1935944bc986bf8ae85ee3343b8351d9823";
- sha256 = "sha256-bIPRrKaNQ2Eo+T6zv7qeA1z7uRHXezM0yxh+uqA01Gs=";
+ hash = "sha256-bIPRrKaNQ2Eo+T6zv7qeA1z7uRHXezM0yxh+uqA01Gs=";
};
nativeBuildInputs = [
@@ -38,7 +38,7 @@ stdenvNoCC.mkDerivation rec {
description = "An X cursor theme inspired by Materia design";
homepage = "https://github.com/vinceliuice/Vimix-cursors";
license = licenses.gpl3Only;
- platforms = platforms.linux;
maintainers = with maintainers; [ ambroisie ];
+ platforms = platforms.linux;
};
}
diff --git a/pkgs/volantes-cursors/default.nix b/pkgs/volantes-cursors/default.nix
index e300a36..b2c7865 100644
--- a/pkgs/volantes-cursors/default.nix
+++ b/pkgs/volantes-cursors/default.nix
@@ -7,7 +7,7 @@ stdenvNoCC.mkDerivation rec {
owner = "varlesh";
repo = pname;
rev = "d1d290ff42cc4fa643716551bd0b02582b90fd2f";
- sha256 = "sha256-irMN/enoo90nYLfvSOScZoYdvhZKvqqp+grZB2BQD9o=";
+ hash = "sha256-irMN/enoo90nYLfvSOScZoYdvhZKvqqp+grZB2BQD9o=";
};
nativeBuildInputs = [
@@ -38,7 +38,7 @@ stdenvNoCC.mkDerivation rec {
description = "Classic cursor with a flying style";
homepage = "https://github.com/varlesh/volantes-cursors";
license = licenses.gpl2Only;
- platforms = platforms.linux;
maintainers = with maintainers; [ ambroisie ];
+ platforms = platforms.linux;
};
}
diff --git a/pkgs/wifi-qr/default.nix b/pkgs/wifi-qr/default.nix
new file mode 100644
index 0000000..88164e5
--- /dev/null
+++ b/pkgs/wifi-qr/default.nix
@@ -0,0 +1,81 @@
+{ lib
+, fetchFromGitHub
+, gnome
+, installShellFiles
+, makeWrapper
+, networkmanager
+, qrencode
+, stdenvNoCC
+, xdg-utils
+, zbar
+}:
+stdenvNoCC.mkDerivation rec {
+ pname = "wifi-qr";
+ version = "unstable-2023-04-19";
+
+ outputs = [ "out" "man" ];
+
+ src = fetchFromGitHub {
+ owner = "kokoye2007";
+ repo = "wifi-qr";
+ rev = "b81d4a44257252f07e745464879aa5618ae3d434";
+ hash = "sha256-oGTAr+raJGpK4PV4GdBxX8fIUE8gcbXw7W0SvQJAee0=";
+ };
+
+ nativeBuildInputs = [
+ installShellFiles
+ makeWrapper
+ ];
+
+ dontBuild = true;
+
+ dontConfigure = true;
+
+ postPatch = ''
+ substituteInPlace wifi-qr.desktop \
+ --replace "Exec=sh -c 'wifi-qr g'" "Exec=$out/bin/wifi-qr g" \
+ --replace "Exec=sh -c 'wifi-qr q'" "Exec=$out/bin/wifi-qr q" \
+ --replace "Exec=sh -c 'wifi-qr p'" "Exec=$out/bin/wifi-qr p" \
+ --replace "Exec=sh -c 'wifi-qr c'" "Exec=$out/bin/wifi-qr c" \
+ --replace "Icon=wifi-qr.svg" "Icon=wifi-qr"
+ '';
+
+ installPhase = ''
+ runHook preInstall
+
+ install -Dm755 wifi-qr $out/bin/wifi-qr
+
+ install -Dm644 wifi-qr.desktop $out/share/applications/wifi-qr.desktop
+ install -Dm644 wifi-qr.svg $out/share/icons/hicolor/scalable/apps/wifi-qr.svg
+
+ installManPage wifi-qr.1
+
+ runHook postInstall
+ '';
+
+ wrapperPath = lib.makeBinPath [
+ gnome.zenity
+ networkmanager
+ qrencode
+ xdg-utils
+ zbar
+ ];
+
+ fixupPhase = ''
+ runHook preFixup
+
+ patchShebangs $out/bin/wifi-qr
+ wrapProgram $out/bin/wifi-qr --suffix PATH : "${wrapperPath}"
+
+ runHook postFixup
+ '';
+
+ meta = with lib; {
+ description = "WiFi password sharing via QR codes";
+ homepage = "https://github.com/kokoye2007/wifi-qr";
+ license = with licenses; [ gpl3Plus ];
+ mainProgram = "wifi-qr";
+ maintainers = with maintainers; [ ambroisie ];
+ platforms = platforms.linux;
+ };
+}
diff --git a/profiles/default.nix b/profiles/default.nix
index 43d5a84..f7914a1 100644
--- a/profiles/default.nix
+++ b/profiles/default.nix
@@ -6,6 +6,7 @@
./devices
./gtk
./laptop
+ ./printing
./wm
./x
];
diff --git a/profiles/devices/default.nix b/profiles/devices/default.nix
index 54088b3..7dbd299 100644
--- a/profiles/devices/default.nix
+++ b/profiles/devices/default.nix
@@ -13,5 +13,8 @@ in
mx-ergo.enable = true;
};
+
+ # MTP devices auto-mount via file explorers
+ services.gvfs.enable = true;
};
}
diff --git a/profiles/gtk/default.nix b/profiles/gtk/default.nix
index 61a3edc..a8d6d9a 100644
--- a/profiles/gtk/default.nix
+++ b/profiles/gtk/default.nix
@@ -4,7 +4,7 @@ let
in
{
options.my.profiles.gtk = with lib; {
- enable = mkEnableOption "bluetooth profile";
+ enable = mkEnableOption "gtk profile";
};
config = lib.mkIf cfg.enable {
diff --git a/profiles/printing/default.nix b/profiles/printing/default.nix
new file mode 100644
index 0000000..9965797
--- /dev/null
+++ b/profiles/printing/default.nix
@@ -0,0 +1,69 @@
+{ config, lib, pkgs, ... }:
+let
+ cfg = config.my.profiles.printing;
+in
+{
+ options.my.profiles.printing = with lib; {
+ enable = mkEnableOption "printing profile";
+
+ papersize = mkOption {
+ type = with types; either str (enum [
+ "a3"
+ "a4"
+ "a5"
+ "b5"
+ "letter"
+ "legal"
+ "executive"
+ "note"
+ "11x17"
+ ]);
+ default = "a4";
+ example = "paper";
+ description = "preferred paper size";
+ };
+
+ usb = {
+ enable = my.mkDisableOption "USB printers";
+ };
+
+ network = {
+ enable = my.mkDisableOption "network printers";
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
+ # Setup CUPS
+ services.printing = {
+ enable = true;
+
+ # Drivers are deprecated, but just in case
+ drivers = with pkgs; [
+ gutenprint # Base set of drivers
+ brlaser # Brother drivers
+
+ # Brother MFC-L3770CDW
+ mfcl3770cdwlpr
+ mfcl3770cdwcupswrapper
+ ];
+ };
+
+ # Setup paper size
+ systemd.services.cups.serviceConfig.Environment = [
+ "PAPERSIZE=${cfg.papersize}"
+ ];
+
+ # Allow using USB printers
+ services.ipp-usb = lib.mkIf cfg.usb.enable {
+ enable = true;
+ };
+
+ # Allow using WiFi printers
+ services.avahi = lib.mkIf cfg.network.enable {
+ enable = true;
+ openFirewall = true;
+ # Allow resolution of '.local' addresses
+ nssmdns = true;
+ };
+ };
+}
diff --git a/profiles/wm/default.nix b/profiles/wm/default.nix
index 473d49d..c227328 100644
--- a/profiles/wm/default.nix
+++ b/profiles/wm/default.nix
@@ -22,6 +22,8 @@ in
my.home.flameshot.enable = true;
# Auto disk mounter
my.home.udiskie.enable = true;
+ # udiskie fails if it can't find this dbus service
+ services.udisks2.enable = true;
})
];
}
diff --git a/profiles/x/default.nix b/profiles/x/default.nix
index e9d9cfd..ea77939 100644
--- a/profiles/x/default.nix
+++ b/profiles/x/default.nix
@@ -13,7 +13,7 @@ in
# Nice wallpaper
services.xserver.displayManager.lightdm.background =
let
- wallpapers = "${pkgs.plasma-workspace-wallpapers}/share/wallpapers";
+ wallpapers = "${pkgs.plasma5Packages.plasma-workspace-wallpapers}/share/wallpapers";
in
"${wallpapers}/summer_1am/contents/images/2560x1600.jpg";
diff --git a/templates/c++-cmake/.clang-format b/templates/c++-cmake/.clang-format
new file mode 100644
index 0000000..19c58aa
--- /dev/null
+++ b/templates/c++-cmake/.clang-format
@@ -0,0 +1,23 @@
+# vim: ft=yaml
+---
+BasedOnStyle: LLVM
+IndentWidth: 4
+---
+Language: Cpp
+# Force pointers to the type for C++.
+DerivePointerAlignment: false
+PointerAlignment: Left
+
+# Short functions should not be on a single line, unless empty
+AllowShortFunctionsOnASingleLine: Empty
+
+# Make them level
+AccessModifierOffset: -4
+
+# It makes more sense this way
+BreakBeforeBinaryOperators: All
+BreakBeforeTernaryOperators: true
+
+# Aesthetic
+AlignOperands: AlignAfterOperator
+---
diff --git a/templates/c++-cmake/.envrc b/templates/c++-cmake/.envrc
new file mode 100644
index 0000000..95ed6fb
--- /dev/null
+++ b/templates/c++-cmake/.envrc
@@ -0,0 +1,10 @@
+if ! has nix_direnv_version || ! nix_direnv_version 2.2.1; then
+ source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.2.1/direnvrc" "sha256-zelF0vLbEl5uaqrfIzbgNzJWGmLzCmYAkInj/LNxvKs="
+fi
+
+use flake
+
+watch_file ./flake/checks.nix
+watch_file ./flake/dev-shells.nix
+
+eval "$shellHooks"
diff --git a/templates/c++-cmake/.gitignore b/templates/c++-cmake/.gitignore
new file mode 100644
index 0000000..09ba440
--- /dev/null
+++ b/templates/c++-cmake/.gitignore
@@ -0,0 +1,7 @@
+# CMake build directories
+/build
+/build-*
+
+# Nix generated files
+/.pre-commit-config.yaml
+/result
diff --git a/templates/c++-cmake/.woodpecker/check.yml b/templates/c++-cmake/.woodpecker/check.yml
new file mode 100644
index 0000000..c3b00ef
--- /dev/null
+++ b/templates/c++-cmake/.woodpecker/check.yml
@@ -0,0 +1,26 @@
+labels:
+ type: exec
+
+pipeline:
+- name: nix flake check
+ image: bash
+ commands:
+ - nix flake check
+
+- name: notifiy
+ image: bash
+ secrets:
+ - source: matrix_homeserver
+ target: address
+ - source: matrix_roomid
+ target: room
+ - source: matrix_username
+ target: user
+ - source: matrix_password
+ target: pass
+ commands:
+ - nix run '.#matrix-notifier'
+ when:
+ status:
+ - failure
+ - success
diff --git a/templates/c++-cmake/CMakeLists.txt b/templates/c++-cmake/CMakeLists.txt
new file mode 100644
index 0000000..122d8b3
--- /dev/null
+++ b/templates/c++-cmake/CMakeLists.txt
@@ -0,0 +1,18 @@
+cmake_minimum_required(VERSION 3.10)
+project(project VERSION 0.0.0 LANGUAGES CXX)
+enable_testing()
+
+add_library(common_options INTERFACE)
+target_compile_features(common_options INTERFACE
+ cxx_std_20
+)
+target_compile_options(common_options INTERFACE
+ -Wall
+ -Wextra
+)
+target_include_directories(common_options INTERFACE
+ src
+)
+
+add_subdirectory(src)
+add_subdirectory(tests)
diff --git a/templates/c++-cmake/flake.nix b/templates/c++-cmake/flake.nix
new file mode 100644
index 0000000..cb468e7
--- /dev/null
+++ b/templates/c++-cmake/flake.nix
@@ -0,0 +1,112 @@
+{
+ description = "A C++ project";
+
+ inputs = {
+ futils = {
+ type = "github";
+ owner = "numtide";
+ repo = "flake-utils";
+ ref = "main";
+ };
+
+ nixpkgs = {
+ type = "github";
+ owner = "NixOS";
+ repo = "nixpkgs";
+ ref = "nixos-unstable";
+ };
+
+ pre-commit-hooks = {
+ type = "github";
+ owner = "cachix";
+ repo = "pre-commit-hooks.nix";
+ ref = "master";
+ inputs = {
+ flake-utils.follows = "futils";
+ nixpkgs.follows = "nixpkgs";
+ };
+ };
+ };
+
+ outputs = { self, futils, nixpkgs, pre-commit-hooks }:
+ {
+ overlays = {
+ default = final: _prev: {
+ project = with final; stdenv.mkDerivation {
+ pname = "project";
+ version = "0.0.0";
+
+ src = self;
+
+ nativeBuildInputs = with pkgs; [
+ cmake
+ ninja
+ pkg-config
+ ];
+
+ checkInputs = with pkgs; [
+ gtest
+ ];
+
+ doCheck = true;
+
+ meta = with lib; {
+ description = "A C++ project";
+ homepage = "https://gitea.belanyi.fr/ambroisie/project";
+ license = licenses.mit;
+ maintainers = with maintainers; [ ambroisie ];
+ platforms = platforms.unix;
+ };
+ };
+ };
+ };
+ } // futils.lib.eachDefaultSystem (system:
+ let
+ pkgs = import nixpkgs {
+ inherit system;
+ overlays = [
+ self.overlays.default
+ ];
+ };
+
+ pre-commit = pre-commit-hooks.lib.${system}.run {
+ src = self;
+
+ hooks = {
+ nixpkgs-fmt = {
+ enable = true;
+ };
+
+ clang-format = {
+ enable = true;
+ };
+ };
+ };
+ in
+ {
+ checks = {
+ inherit (self.packages.${system}) project;
+
+ inherit pre-commit;
+ };
+
+ devShells = {
+ default = pkgs.mkShell {
+ inputsFrom = with self.packages.${system}; [
+ project
+ ];
+
+ packages = with pkgs; [
+ clang-tools
+ ];
+
+ inherit (pre-commit) shellHook;
+ };
+ };
+
+ packages = futils.lib.flattenTree {
+ default = pkgs.project;
+ inherit (pkgs) project;
+ };
+ });
+}
diff --git a/templates/c++-cmake/src/CMakeLists.txt b/templates/c++-cmake/src/CMakeLists.txt
new file mode 100644
index 0000000..d91cef1
--- /dev/null
+++ b/templates/c++-cmake/src/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_executable(project main.cc)
+target_link_libraries(project PRIVATE common_options)
+
+install(TARGETS project)
diff --git a/templates/c++-cmake/src/main.cc b/templates/c++-cmake/src/main.cc
new file mode 100644
index 0000000..5eb9e4a
--- /dev/null
+++ b/templates/c++-cmake/src/main.cc
@@ -0,0 +1,5 @@
+#include
+
+int main() {
+ std::cout << "Hello World!\n";
+}
diff --git a/templates/c++-cmake/tests/CMakeLists.txt b/templates/c++-cmake/tests/CMakeLists.txt
new file mode 100644
index 0000000..269aea0
--- /dev/null
+++ b/templates/c++-cmake/tests/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(unit)
diff --git a/templates/c++-cmake/tests/unit/CMakeLists.txt b/templates/c++-cmake/tests/unit/CMakeLists.txt
new file mode 100644
index 0000000..bb94448
--- /dev/null
+++ b/templates/c++-cmake/tests/unit/CMakeLists.txt
@@ -0,0 +1,15 @@
+find_package(GTest)
+
+if (${GTest_FOUND})
+include(GoogleTest)
+
+add_executable(dummy_test dummy_test.cc)
+target_link_libraries(dummy_test PRIVATE common_options)
+
+target_link_libraries(dummy_test PRIVATE
+ GTest::gtest
+ GTest::gtest_main
+)
+
+gtest_discover_tests(dummy_test)
+endif (${GTest_FOUND})
diff --git a/templates/c++-cmake/tests/unit/dummy_test.cc b/templates/c++-cmake/tests/unit/dummy_test.cc
new file mode 100644
index 0000000..4573678
--- /dev/null
+++ b/templates/c++-cmake/tests/unit/dummy_test.cc
@@ -0,0 +1,5 @@
+#include
+
+TEST(misc, passing) {
+ ASSERT_EQ(1, 1);
+}
diff --git a/templates/c++-meson/.clang-format b/templates/c++-meson/.clang-format
new file mode 100644
index 0000000..19c58aa
--- /dev/null
+++ b/templates/c++-meson/.clang-format
@@ -0,0 +1,23 @@
+# vim: ft=yaml
+---
+BasedOnStyle: LLVM
+IndentWidth: 4
+---
+Language: Cpp
+# Force pointers to the type for C++.
+DerivePointerAlignment: false
+PointerAlignment: Left
+
+# Short functions should not be on a single line, unless empty
+AllowShortFunctionsOnASingleLine: Empty
+
+# Make them level
+AccessModifierOffset: -4
+
+# It makes more sense this way
+BreakBeforeBinaryOperators: All
+BreakBeforeTernaryOperators: true
+
+# Aesthetic
+AlignOperands: AlignAfterOperator
+---
diff --git a/templates/c++-meson/.envrc b/templates/c++-meson/.envrc
new file mode 100644
index 0000000..95ed6fb
--- /dev/null
+++ b/templates/c++-meson/.envrc
@@ -0,0 +1,10 @@
+if ! has nix_direnv_version || ! nix_direnv_version 2.2.1; then
+ source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.2.1/direnvrc" "sha256-zelF0vLbEl5uaqrfIzbgNzJWGmLzCmYAkInj/LNxvKs="
+fi
+
+use flake
+
+watch_file ./flake/checks.nix
+watch_file ./flake/dev-shells.nix
+
+eval "$shellHooks"
diff --git a/templates/c++-meson/.gitignore b/templates/c++-meson/.gitignore
new file mode 100644
index 0000000..09ba440
--- /dev/null
+++ b/templates/c++-meson/.gitignore
@@ -0,0 +1,7 @@
+# CMake build directories
+/build
+/build-*
+
+# Nix generated files
+/.pre-commit-config.yaml
+/result
diff --git a/templates/c++-meson/.woodpecker/check.yml b/templates/c++-meson/.woodpecker/check.yml
new file mode 100644
index 0000000..c3b00ef
--- /dev/null
+++ b/templates/c++-meson/.woodpecker/check.yml
@@ -0,0 +1,26 @@
+labels:
+ type: exec
+
+pipeline:
+- name: nix flake check
+ image: bash
+ commands:
+ - nix flake check
+
+- name: notifiy
+ image: bash
+ secrets:
+ - source: matrix_homeserver
+ target: address
+ - source: matrix_roomid
+ target: room
+ - source: matrix_username
+ target: user
+ - source: matrix_password
+ target: pass
+ commands:
+ - nix run '.#matrix-notifier'
+ when:
+ status:
+ - failure
+ - success
diff --git a/templates/c++-meson/flake.nix b/templates/c++-meson/flake.nix
new file mode 100644
index 0000000..9cfed0d
--- /dev/null
+++ b/templates/c++-meson/flake.nix
@@ -0,0 +1,112 @@
+{
+ description = "A C++ project";
+
+ inputs = {
+ futils = {
+ type = "github";
+ owner = "numtide";
+ repo = "flake-utils";
+ ref = "main";
+ };
+
+ nixpkgs = {
+ type = "github";
+ owner = "NixOS";
+ repo = "nixpkgs";
+ ref = "nixos-unstable";
+ };
+
+ pre-commit-hooks = {
+ type = "github";
+ owner = "cachix";
+ repo = "pre-commit-hooks.nix";
+ ref = "master";
+ inputs = {
+ flake-utils.follows = "futils";
+ nixpkgs.follows = "nixpkgs";
+ };
+ };
+ };
+
+ outputs = { self, futils, nixpkgs, pre-commit-hooks }:
+ {
+ overlays = {
+ default = final: _prev: {
+ project = with final; stdenv.mkDerivation {
+ pname = "project";
+ version = "0.0.0";
+
+ src = self;
+
+ nativeBuildInputs = with pkgs; [
+ meson
+ ninja
+ pkg-config
+ ];
+
+ checkInputs = with pkgs; [
+ gtest
+ ];
+
+ doCheck = true;
+
+ meta = with lib; {
+ description = "A C++ project";
+ homepage = "https://gitea.belanyi.fr/ambroisie/project";
+ license = licenses.mit;
+ maintainers = with maintainers; [ ambroisie ];
+ platforms = platforms.unix;
+ };
+ };
+ };
+ };
+ } // futils.lib.eachDefaultSystem (system:
+ let
+ pkgs = import nixpkgs {
+ inherit system;
+ overlays = [
+ self.overlays.default
+ ];
+ };
+
+ pre-commit = pre-commit-hooks.lib.${system}.run {
+ src = self;
+
+ hooks = {
+ nixpkgs-fmt = {
+ enable = true;
+ };
+
+ clang-format = {
+ enable = true;
+ };
+ };
+ };
+ in
+ {
+ checks = {
+ inherit (self.packages.${system}) project;
+
+ inherit pre-commit;
+ };
+
+ devShells = {
+ default = pkgs.mkShell {
+ inputsFrom = with self.packages.${system}; [
+ project
+ ];
+
+ packages = with pkgs; [
+ clang-tools
+ ];
+
+ inherit (pre-commit) shellHook;
+ };
+ };
+
+ packages = futils.lib.flattenTree {
+ default = pkgs.project;
+ inherit (pkgs) project;
+ };
+ });
+}
diff --git a/templates/c++-meson/meson.build b/templates/c++-meson/meson.build
new file mode 100644
index 0000000..bc228c6
--- /dev/null
+++ b/templates/c++-meson/meson.build
@@ -0,0 +1,13 @@
+project(
+ 'project',
+ 'cpp',
+ version : '0.0.0',
+ license: 'MIT',
+ default_options : [
+ 'cpp_std=c++20',
+ 'warning_level=3',
+ ],
+)
+
+subdir('src')
+subdir('tests')
diff --git a/templates/c++-meson/src/main.cc b/templates/c++-meson/src/main.cc
new file mode 100644
index 0000000..5eb9e4a
--- /dev/null
+++ b/templates/c++-meson/src/main.cc
@@ -0,0 +1,5 @@
+#include
+
+int main() {
+ std::cout << "Hello World!\n";
+}
diff --git a/templates/c++-meson/src/meson.build b/templates/c++-meson/src/meson.build
new file mode 100644
index 0000000..4b2ff23
--- /dev/null
+++ b/templates/c++-meson/src/meson.build
@@ -0,0 +1,8 @@
+sources = files(
+ 'main.cc',
+)
+
+executable(
+ 'project',
+ sources : sources,
+)
diff --git a/templates/c++-meson/tests/meson.build b/templates/c++-meson/tests/meson.build
new file mode 100644
index 0000000..082b746
--- /dev/null
+++ b/templates/c++-meson/tests/meson.build
@@ -0,0 +1 @@
+subdir('unit')
diff --git a/templates/c++-meson/tests/unit/dummy_test.cc b/templates/c++-meson/tests/unit/dummy_test.cc
new file mode 100644
index 0000000..4573678
--- /dev/null
+++ b/templates/c++-meson/tests/unit/dummy_test.cc
@@ -0,0 +1,5 @@
+#include
+
+TEST(misc, passing) {
+ ASSERT_EQ(1, 1);
+}
diff --git a/templates/c++-meson/tests/unit/meson.build b/templates/c++-meson/tests/unit/meson.build
new file mode 100644
index 0000000..44c8a92
--- /dev/null
+++ b/templates/c++-meson/tests/unit/meson.build
@@ -0,0 +1,13 @@
+gtest_dep = dependency(
+ 'gtest',
+ main : true,
+ required : false,
+)
+
+dummy_test = executable(
+ 'dummy_test',
+ 'dummy_test.cc',
+ dependencies : gtest_dep,
+)
+
+test('dummy test', dummy_test)
diff --git a/templates/default.nix b/templates/default.nix
new file mode 100644
index 0000000..f58fd72
--- /dev/null
+++ b/templates/default.nix
@@ -0,0 +1,10 @@
+{
+ "c++-cmake" = {
+ path = ./c++-cmake;
+ description = "A C++ project using CMake";
+ };
+ "c++-meson" = {
+ path = ./c++-meson;
+ description = "A C++ project using CMake";
+ };
+}